Merge pull request #13 from JianFeeeee/refactor/rename-batch2-packaging

refactor(deploy): 改名批 2 · 打包发行(deploy/ 品牌落地)
This commit is contained in:
JianFeeeee
2026-10-21 16:10:42 +08:00
committed by GitHub
16 changed files with 410 additions and 212 deletions

View File

@ -1,6 +1,6 @@
[Unit]
Description=HomeAgent - 24/7 AI Butler
Documentation=https://github.com/trueagent/HomeAgent
Description=HologramAgent - 24/7 AI Butler
Documentation=https://github.com/trueagent/HologramAgent
After=network-online.target docker.service
Wants=network-online.target
@ -28,9 +28,9 @@ Wants=network-online.target
Type=exec
# ★ guard 模式(与本机生产实例一致)。
# 数据目录默认 /var/lib/homeagent(Debian 惯例);迁移到别的目录时
# 数据目录默认 /var/lib/hologram(Debian 惯例);迁移到别的目录时
# 必须**同时**改这里和 core.daemon.data_dir —— 两者不等价,见 README。
ExecStart=/usr/bin/homed --role=guard --data /var/lib/homeagent
ExecStart=/usr/bin/homed --role=guard --data /var/lib/hologram
Restart=always
RestartSec=10
@ -58,11 +58,11 @@ TimeoutStopSec=25s
# 一起收,双保险不留孤儿进程。
KillMode=control-group
WorkingDirectory=/var/lib/homeagent
StateDirectory=homeagent
WorkingDirectory=/var/lib/hologram
StateDirectory=hologram
Environment=HOME=/root
# onnx 运行库随包安装(不在 /opt,见 packaging/package-linux.sh)
Environment=ONNXRUNTIME_DIR=/usr/lib/homeagent/onnxruntime
Environment=ONNXRUNTIME_DIR=/usr/lib/hologram/onnxruntime
# ★ 主密钥生产注入(security/key.go)
#
@ -74,8 +74,8 @@ Environment=ONNXRUNTIME_DIR=/usr/lib/homeagent/onnxruntime
# 不在磁盘留副本、也不进 environ。
#
# 生成密钥(一次性,然后妥善保管):
# head -c 32 /dev/urandom | xxd -p -c 64 | sudo tee /etc/homeagent/security.key
# sudo chmod 600 /etc/homeagent/security.key
# head -c 32 /dev/urandom | xxd -p -c 64 | sudo tee /etc/hologram/security.key
# sudo chmod 600 /etc/hologram/security.key
#
# ⚠ 该文件就是数据的主密钥:**丢了它,已加密的变量全部解不开**(响亮失败,
# 不会静默重建)。请与备份一并保管。
@ -83,11 +83,11 @@ Environment=ONNXRUNTIME_DIR=/usr/lib/homeagent/onnxruntime
# ⚠ 未配置时**不要**留一个空文件 —— 凭据目录一旦被设置而凭据缺失,内核会
# **拒绝启动**(不静默回退到磁盘密钥)。若要用磁盘密钥路径,删掉下面这行。
#
# ⚠ 从旧版(/var/lib/homeagent/security.key 磁盘钥)升级时:
# ⚠ 从旧版(/var/lib/homeagent/security.key,改名前的路径)升级时:
# 内核支持"磁盘钥 + 内嵌钥"并存解密(AdditionalDecryptKeys),
# 所以先放 /etc/homeagent/security.key 与旧磁盘钥**同一份内容**再启用本行,
# 所以先放 /etc/hologram/security.key 与旧磁盘钥**同一份内容**再启用本行,
# 否则旧密文解不开。
LoadCredential=homed_security_key:/etc/homeagent/security.key
LoadCredential=homed_security_key:/etc/hologram/security.key
# Security hardening
NoNewPrivileges=true
@ -97,9 +97,9 @@ PrivateTmp=true
PrivateDevices=false
DevicePolicy=closed
# 只允许读主密钥所在目录,其余系统路径保持只读
ReadOnlyPaths=/etc/homeagent
ReadOnlyPaths=/etc/hologram
# 插件需要写自己目录 + 数据目录 + 插件沙箱
ReadWritePaths=/var/lib/homeagent
ReadWritePaths=/var/lib/hologram
# Audio devices
DeviceAllow=/dev/snd rw
DeviceAllow=/dev/dsp rw

View File

@ -8,8 +8,8 @@
!define VARIANT "full"
!endif
!define PRODUCT_NAME "HomeAgent"
!define PRODUCT_PUBLISHER "HomeAgent Team"
!define PRODUCT_NAME "HologramAgent"
!define PRODUCT_PUBLISHER "HologramAgent Team"
# 版本号由 makensis -DPRODUCT_VERSION=X.Y.Z 注入;缺省值仅供本地手工构建。
# 此前硬编码 0.8.0 而 release 已到 1.0.0,装出来的包在「添加/删除程序」里
# 会显示错误版本(DisplayVersion 也取自这个宏)。
@ -18,22 +18,22 @@
!endif
!if "${VARIANT}" == "full"
!define PRODUCT_DISPLAY_NAME "HomeAgent 完整版"
!define OUTPUT_FILE "HomeAgent_v${PRODUCT_VERSION}_Full_win64.exe"
!define PRODUCT_DISPLAY_NAME "HologramAgent 完整版"
!define OUTPUT_FILE "HologramAgent_v${PRODUCT_VERSION}_Full_win64.exe"
!define HAS_CORE 1
!define HAS_WAITER 1
!define HAS_GUI 1
!define HAS_CREDENTIALS 1
!else if "${VARIANT}" == "server"
!define PRODUCT_DISPLAY_NAME "HomeAgent 服务端"
!define OUTPUT_FILE "HomeAgent_v${PRODUCT_VERSION}_Server_win64.exe"
!define PRODUCT_DISPLAY_NAME "HologramAgent 服务端"
!define OUTPUT_FILE "HologramAgent_v${PRODUCT_VERSION}_Server_win64.exe"
!define HAS_CORE 1
!define HAS_WAITER 0
!define HAS_GUI 0
!define HAS_CREDENTIALS 1
!else if "${VARIANT}" == "client"
!define PRODUCT_DISPLAY_NAME "HomeAgent 客户端"
!define OUTPUT_FILE "HomeAgent_v${PRODUCT_VERSION}_Client_win64.exe"
!define PRODUCT_DISPLAY_NAME "HologramAgent 客户端"
!define OUTPUT_FILE "HologramAgent_v${PRODUCT_VERSION}_Client_win64.exe"
!define HAS_CORE 0
!define HAS_WAITER 1
!define HAS_GUI 1
@ -47,7 +47,7 @@ OutFile "..\..\build\${OUTPUT_FILE}"
InstallDir "$PROGRAMFILES64\${PRODUCT_NAME}"
InstallDirRegKey HKLM "Software\${PRODUCT_NAME}" ""
RequestExecutionLevel admin
BrandingText "HomeAgent Installer"
BrandingText "HologramAgent Installer"
SetCompressor /SOLID lzma
ShowInstDetails show
ShowUninstDetails show
@ -68,7 +68,7 @@ Function GenKey
Pop $0
Pop $1
${If} $1 == ""
StrCpy $1 "homeagent"
StrCpy $1 "hologram"
${Else}
StrCpy $1 $1 32
${EndIf}
@ -111,13 +111,13 @@ FunctionEnd
!if "${HAS_CORE}" == "1"
Function pageStartupOptions
!insertmacro MUI_HEADER_TEXT "启动选项" "设置 HomeAgent 后端的启动方式"
!insertmacro MUI_HEADER_TEXT "启动选项" "设置 HologramAgent 后端的启动方式"
nsDialogs::Create 1018
Pop $0
${If} $0 == error
Abort
${EndIf}
${NSD_CreateLabel} 0 5u 100% 20u "HomeAgent 后端 (homed) 是持续运行的服务进程。$\r$\n请选择启动方式:"
${NSD_CreateLabel} 0 5u 100% 20u "HologramAgent 后端 (homed) 是持续运行的服务进程。$\r$\n请选择启动方式:"
Pop $0
${NSD_CreateCheckBox} 10u 35u 100% 12u "开机自动启动后端 (添加到注册表启动项)"
Pop $hwndAutoStart
@ -190,7 +190,7 @@ Function pageCredentialsLeave
${NSD_GetText} $hwndUsername $webuiUsername
${NSD_GetText} $hwndPassword $webuiPassword
${If} $webuiPassword == ""
StrCpy $webuiPassword "homeagent"
StrCpy $webuiPassword "hologram"
${EndIf}
FunctionEnd
@ -244,15 +244,15 @@ Section "Install" SEC_INSTALL
!endif
!if "${HAS_GUI}" == "1"
SetOutPath "$INSTDIR\homeagent-gui-win32-x64"
File /r "..\..\build\homeagent-gui-win32-x64\*.*"
SetOutPath "$INSTDIR\hologram-gui-win32-x64"
File /r "..\..\build\hologram-gui-win32-x64\*.*"
SetOutPath "$INSTDIR"
!endif
!if "${HAS_CORE}" == "1"
; 在 WSL2 里安装 homed。凭据(页面上收的那三个)透传进去,避免
; 「界面显示一份、config.db 里另一份」导致登录不上。
DetailPrint "检测 WSL 并在其中安装 HomeAgent..."
DetailPrint "检测 WSL 并在其中安装 HologramAgent..."
nsExec::ExecToStack 'powershell -NoProfile -ExecutionPolicy Bypass -File "$INSTDIR\install-via-wsl.ps1" -PayloadDir "$PLUGINSDIR\linux-payload" -ApiKey "$apiKey" -WebUIUser "$webuiUsername" -WebUIPass "$webuiPassword"'
Pop $0
Pop $1
@ -267,19 +267,19 @@ Section "Install" SEC_INSTALL
MessageBox MB_ICONEXCLAMATION|MB_OK "WSL 内安装失败(退出码 $0)。$\r$\n$\r$\n可进入 WSL 手动排查:wsl -d Ubuntu$\r$\n安装脚本输出见上方日志。"
${EndIf}
${Else}
DetailPrint "HomeAgent 已在 WSL2 内安装完成"
DetailPrint "HologramAgent 已在 WSL2 内安装完成"
${EndIf}
!endif
!if "${HAS_GUI}" == "1"
DetailPrint "配置 GUI 连接..."
CreateDirectory "$APPDATA\homeagent-gui"
FileOpen $0 "$APPDATA\homeagent-gui\connections.json" w
CreateDirectory "$APPDATA\hologram-gui"
FileOpen $0 "$APPDATA\hologram-gui\connections.json" w
FileWrite $0 '{$\r$\n "connections": [$\r$\n {$\r$\n "id": "local",$\r$\n "name": "本地",$\r$\n "url": "http://localhost:8080",$\r$\n "apiKey": "$apiKey"$\r$\n }$\r$\n ],$\r$\n "currentId": "local"$\r$\n}'
FileClose $0
; 同时写入 GUI 包目录作为备用(适配 UAC 提升后 $APPDATA 异常的情况)
CreateDirectory "$INSTDIR\homeagent-gui-win32-x64\resources\app"
FileOpen $0 "$INSTDIR\homeagent-gui-win32-x64\resources\app\connections.json" w
CreateDirectory "$INSTDIR\hologram-gui-win32-x64\resources\app"
FileOpen $0 "$INSTDIR\hologram-gui-win32-x64\resources\app\connections.json" w
FileWrite $0 '{$\r$\n "connections": [$\r$\n {$\r$\n "id": "local",$\r$\n "name": "本地",$\r$\n "url": "http://localhost:8080",$\r$\n "apiKey": "$apiKey"$\r$\n }$\r$\n ],$\r$\n "currentId": "local"$\r$\n}'
FileClose $0
!endif
@ -294,23 +294,23 @@ Section "Install" SEC_INSTALL
DetailPrint "创建快捷方式..."
CreateDirectory "$SMPROGRAMS\${PRODUCT_NAME}"
!if "${HAS_CORE}" == "1"
CreateShortCut "$SMPROGRAMS\${PRODUCT_NAME}\HomeAgent Server.lnk" "$INSTDIR\homed.exe" '-data "$INSTDIR\data"' "$INSTDIR\homed.exe" 0
CreateShortCut "$SMPROGRAMS\${PRODUCT_NAME}\HologramAgent Server.lnk" "$INSTDIR\homed.exe" '-data "$INSTDIR\data"' "$INSTDIR\homed.exe" 0
!endif
!if "${HAS_WAITER}" == "1"
CreateShortCut "$SMPROGRAMS\${PRODUCT_NAME}\HomeAgent CLI.lnk" "$INSTDIR\waiter.exe" "" "$INSTDIR\waiter.exe" 0
CreateShortCut "$SMPROGRAMS\${PRODUCT_NAME}\HologramAgent CLI.lnk" "$INSTDIR\waiter.exe" "" "$INSTDIR\waiter.exe" 0
!endif
!if "${HAS_GUI}" == "1"
CreateShortCut "$SMPROGRAMS\${PRODUCT_NAME}\HomeAgent GUI.lnk" "$INSTDIR\homeagent-gui-win32-x64\homeagent-gui.exe" "" "$INSTDIR\homeagent-gui-win32-x64\homeagent-gui.exe" 0
CreateShortCut "$SMPROGRAMS\${PRODUCT_NAME}\HologramAgent GUI.lnk" "$INSTDIR\hologram-gui-win32-x64\hologram-gui.exe" "" "$INSTDIR\hologram-gui-win32-x64\hologram-gui.exe" 0
!endif
DetailPrint "设置环境变量..."
WriteRegStr HKLM "SYSTEM\CurrentControlSet\Control\Session Manager\Environment" "HOMEAGENT_DATA" "$INSTDIR\data"
WriteRegStr HKLM "SYSTEM\CurrentControlSet\Control\Session Manager\Environment" "HOMEAGENT_SOCKET" "$INSTDIR\data\cli.sock"
WriteRegStr HKLM "SYSTEM\CurrentControlSet\Control\Session Manager\Environment" "HOLOGRAM_DATA" "$INSTDIR\data"
WriteRegStr HKLM "SYSTEM\CurrentControlSet\Control\Session Manager\Environment" "HOLOGRAM_SOCKET" "$INSTDIR\data\cli.sock"
!if "${HAS_CORE}" == "1"
${If} $autoStart == "1"
DetailPrint "设置开机自启动..."
WriteRegStr HKCU "Software\Microsoft\Windows\CurrentVersion\Run" "HomeAgent" '"$INSTDIR\homed.exe" -data "$INSTDIR\data"'
WriteRegStr HKCU "Software\Microsoft\Windows\CurrentVersion\Run" "HologramAgent" '"$INSTDIR\homed.exe" -data "$INSTDIR\data"'
${EndIf}
!endif
@ -328,7 +328,7 @@ Section "Install" SEC_INSTALL
!if "${HAS_CORE}" == "1"
${If} $startNow == "1"
DetailPrint "启动 HomeAgent 后端..."
DetailPrint "启动 HologramAgent 后端..."
Exec '"$INSTDIR\homed.exe" -data "$INSTDIR\data"'
${EndIf}
!endif
@ -336,7 +336,7 @@ SectionEnd
Section "Uninstall"
!if "${HAS_CORE}" == "1"
DeleteRegValue HKCU "Software\Microsoft\Windows\CurrentVersion\Run" "HomeAgent"
DeleteRegValue HKCU "Software\Microsoft\Windows\CurrentVersion\Run" "HologramAgent"
!endif
Delete "$INSTDIR\Uninstall.exe"
Delete "$INSTDIR\initconfig.exe"
@ -344,14 +344,14 @@ Section "Uninstall"
Delete "$INSTDIR\waiter.exe"
Delete "$INSTDIR\waiter.yaml"
RMDir /r "$INSTDIR\data"
RMDir /r "$INSTDIR\homeagent-gui-win32-x64"
RMDir /r "$INSTDIR\hologram-gui-win32-x64"
RMDir "$INSTDIR"
Delete "$SMPROGRAMS\${PRODUCT_NAME}\HomeAgent Server.lnk"
Delete "$SMPROGRAMS\${PRODUCT_NAME}\HomeAgent CLI.lnk"
Delete "$SMPROGRAMS\${PRODUCT_NAME}\HomeAgent GUI.lnk"
Delete "$SMPROGRAMS\${PRODUCT_NAME}\HologramAgent Server.lnk"
Delete "$SMPROGRAMS\${PRODUCT_NAME}\HologramAgent CLI.lnk"
Delete "$SMPROGRAMS\${PRODUCT_NAME}\HologramAgent GUI.lnk"
RMDir "$SMPROGRAMS\${PRODUCT_NAME}"
DeleteRegValue HKLM "SYSTEM\CurrentControlSet\Control\Session Manager\Environment" "HOMEAGENT_DATA"
DeleteRegValue HKLM "SYSTEM\CurrentControlSet\Control\Session Manager\Environment" "HOMEAGENT_SOCKET"
DeleteRegValue HKLM "SYSTEM\CurrentControlSet\Control\Session Manager\Environment" "HOLOGRAM_DATA"
DeleteRegValue HKLM "SYSTEM\CurrentControlSet\Control\Session Manager\Environment" "HOLOGRAM_SOCKET"
DeleteRegKey HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${PRODUCT_NAME}"
DeleteRegKey HKLM "Software\${PRODUCT_NAME}"
SectionEnd

View File

@ -1,18 +1,18 @@
Package: homeagent-client
Package: hologramagent-client
Version: VERSION_PLACEHOLDER
Architecture: ARCH_PLACEHOLDER
Maintainer: HomeAgent Team <team@homeagent.ai>
Maintainer: HologramAgent Team <team@hologramagent.ai>
Installed-Size: INSTALLED_SIZE_PLACEHOLDER
Depends: libc6 (>= 2.28)
Section: utils
Priority: optional
Homepage: https://github.com/trueagent/HomeAgent
Description: HomeAgent Client (CLI + GUI, no daemon)
HomeAgent is a personal AI home assistant that integrates
Homepage: https://github.com/trueagent/HologramAgent
Description: HologramAgent Client (CLI + GUI, no daemon)
HologramAgent is a personal AI home assistant that integrates
large language models with system automation.
.
This package includes the client components:
- waiter: command-line client
- homeagent-gui: desktop graphical interface
- hologram-gui: desktop graphical interface
.
This variant connects to a remote HomeAgent server.
This variant connects to a remote HologramAgent server.

View File

@ -1,17 +1,17 @@
Package: homeagent-full
Package: hologramagent-full
Version: VERSION_PLACEHOLDER
Architecture: ARCH_PLACEHOLDER
Maintainer: HomeAgent Team <team@homeagent.ai>
Maintainer: HologramAgent Team <team@hologramagent.ai>
Installed-Size: INSTALLED_SIZE_PLACEHOLDER
Depends: libc6 (>= 2.28), libstdc++6, libgcc-s1
Section: utils
Priority: optional
Homepage: https://github.com/trueagent/HomeAgent
Description: HomeAgent Full Installation (Daemon + CLI + GUI)
HomeAgent is a personal AI home assistant that integrates
Homepage: https://github.com/trueagent/HologramAgent
Description: HologramAgent Full Installation (Daemon + CLI + GUI)
HologramAgent is a personal AI home assistant that integrates
large language models with system automation.
.
This package includes the full suite:
- homed: the core daemon (background service)
- waiter: command-line client
- homeagent-gui: desktop graphical interface
- hologram-gui: desktop graphical interface

View File

@ -1,14 +1,14 @@
Package: homeagent-server
Package: hologramagent-server
Version: VERSION_PLACEHOLDER
Architecture: ARCH_PLACEHOLDER
Maintainer: HomeAgent Team <team@homeagent.ai>
Maintainer: HologramAgent Team <team@hologramagent.ai>
Installed-Size: INSTALLED_SIZE_PLACEHOLDER
Depends: libc6 (>= 2.28), libstdc++6, libgcc-s1
Section: utils
Priority: optional
Homepage: https://github.com/trueagent/HomeAgent
Description: HomeAgent Server (Daemon + CLI, no GUI)
HomeAgent is a personal AI home assistant that integrates
Homepage: https://github.com/trueagent/HologramAgent
Description: HologramAgent Server (Daemon + CLI, no GUI)
HologramAgent is a personal AI home assistant that integrates
large language models with system automation.
.
This package includes the server components:

View File

@ -1,14 +1,14 @@
Package: homeagent-toolchain
Package: hologramagent-toolchain
Version: VERSION_PLACEHOLDER
Architecture: ARCH_PLACEHOLDER
Maintainer: HomeAgent Team <team@homeagent.ai>
Maintainer: HologramAgent Team <team@hologramagent.ai>
Installed-Size: INSTALLED_SIZE_PLACEHOLDER
Depends: libc6 (>= 2.28), libstdc++6, libgcc-s1
Section: utils
Priority: optional
Homepage: https://github.com/trueagent/HomeAgent
Description: HomeAgent Toolchain (Daemon + CLI + Plugin Toolchain + SDK)
HomeAgent is a personal AI home assistant that integrates
Homepage: https://github.com/trueagent/HologramAgent
Description: HologramAgent Toolchain (Daemon + CLI + Plugin Toolchain + SDK)
HologramAgent is a personal AI home assistant that integrates
large language models with system automation.
.
This package includes the full development toolchain:
@ -16,7 +16,7 @@ Description: HomeAgent Toolchain (Daemon + CLI + Plugin Toolchain + SDK)
- depgraph.bin: kernel startup dependency graph (MUST sit next to homed)
- waiter: command-line client
- hmapdev: plugin build toolchain (init/build/package .hmap)
- the matching HomeAgent SDK (sdk/, tools/, skills/, meta/, docs/)
- the matching HologramAgent SDK (sdk/, tools/, skills/, meta/, docs/)
.
Installs the SDK under /usr/lib/homeagent/sdk so that hmapdev can resolve
Installs the SDK under /usr/lib/hologram/sdk so that hmapdev can resolve
plugins against a known-good SDK without network access.

View File

@ -1,10 +1,10 @@
#!/bin/sh
set -e
SERVICE_NAME="homeagent"
SERVICE_NAME="hologramagent"
HOMED_BIN="/usr/bin/homed"
DATA_DIR="/var/lib/homeagent"
SETUP_SH="/usr/lib/homeagent/setup.sh"
DATA_DIR="/var/lib/hologram"
SETUP_SH="/usr/lib/hologram/setup.sh"
# unit 由本包装到 /etc/systemd/system/,而旧 postinst 只查
# /lib/systemd/system/(merged-usr 下等于 /usr/lib/systemd/system,那里没有
@ -34,9 +34,9 @@ case "$1" in
# credentials.txt、没进数据库),用户拿它登录必然失败,安装却一声不响。
# 失败必须看得见,并给出可直接执行的补救命令。
if [ -x "$SETUP_SH" ]; then
if ! HOMEAGENT_DATA="$DATA_DIR" "$SETUP_SH"; then
echo "E: homeagent 初始化失败——凭据可能未写入 config.db。" >&2
echo "E: 请手动重试:HOMEAGENT_DATA=$DATA_DIR $SETUP_SH" >&2
if ! HOLOGRAM_DATA="$DATA_DIR" "$SETUP_SH"; then
echo "E: hologramagent 初始化失败——凭据可能未写入 config.db。" >&2
echo "E: 请手动重试:HOLOGRAM_DATA=$DATA_DIR $SETUP_SH" >&2
fi
else
echo "W: 未找到 $SETUP_SH,跳过凭据初始化。" >&2
@ -51,10 +51,10 @@ case "$1" in
# (仅 enable 不会让已在运行的进程换用新文件)。
if [ -z "${2:-}" ]; then
systemctl start "$SERVICE_NAME" 2>/dev/null || \
echo "W: homeagent 服务未能启动,请检查:systemctl status $SERVICE_NAME" >&2
echo "W: hologramagent 服务未能启动,请检查:systemctl status $SERVICE_NAME" >&2
else
systemctl restart "$SERVICE_NAME" 2>/dev/null || \
echo "W: homeagent 服务未能重启,请检查:systemctl status $SERVICE_NAME" >&2
echo "W: hologramagent 服务未能重启,请检查:systemctl status $SERVICE_NAME" >&2
fi
else
echo "W: 未找到 ${SERVICE_NAME}.service,未启用服务。" >&2

View File

@ -1,7 +1,7 @@
#!/bin/sh
set -e
SERVICE_NAME="homeagent"
SERVICE_NAME="hologramagent"
case "$1" in
remove|deconfigure)

View File

@ -1,27 +1,27 @@
# HomeAgent RPM Spec
# Build: rpmbuild -ba homeagent.spec
# HologramAgent RPM Spec
# Build: rpmbuild -ba hologramagent.spec
#
# Define variant at build time:
# rpmbuild -ba --define "variant full" homeagent.spec
# rpmbuild -ba --define "variant server" homeagent.spec
# rpmbuild -ba --define "variant client" homeagent.spec
# rpmbuild -ba --define "variant full" hologramagent.spec
# rpmbuild -ba --define "variant server" hologramagent.spec
# rpmbuild -ba --define "variant client" hologramagent.spec
%define _prefix /usr
%define _bindir %{_prefix}/bin
%define _unitdir %{_prefix}/lib/systemd/system
%define _datadir %{_prefix}/share/homeagent
%define _varlibdir /var/lib/homeagent
%define _datadir %{_prefix}/share/hologramagent
%define _varlibdir /var/lib/hologram
%if %{undefined variant}
%define variant full
%endif
Name: homeagent-%{variant}
Name: hologramagent-%{variant}
Version: %{_version}
Release: 1%{?dist}
Summary: HomeAgent - Personal AI Home Assistant
Summary: HologramAgent - Personal AI Home Assistant
License: Proprietary
URL: https://github.com/trueagent/HomeAgent
URL: https://github.com/trueagent/HologramAgent
Group: System Environment/Daemons
BuildArch: %{_arch}
@ -36,19 +36,19 @@ Requires: libX11, libxcb, libdrm, mesa-libGL, nss, nspr, atk, at-spi2-atk, cairo
%endif
%description
HomeAgent is a personal AI home assistant that integrates large language
HologramAgent is a personal AI home assistant that integrates large language
models with system automation.
%if "%{variant}" == "full"
This package includes the full suite: homed (daemon), waiter (CLI),
and homeagent-gui (desktop GUI).
and hologram-gui (desktop GUI).
%else
%if "%{variant}" == "server"
This package includes the server components: homed (daemon) and waiter (CLI).
%else
%if "%{variant}" == "client"
This package includes the client components: waiter (CLI) and
homeagent-gui (desktop GUI). Connects to a remote HomeAgent server.
hologram-gui (desktop GUI). Connects to a remote HologramAgent server.
%endif
%endif
%endif
@ -60,7 +60,7 @@ mkdir -p %{buildroot}%{_varlibdir}
%if "%{variant}" == "full" || "%{variant}" == "server"
install -m 755 %{_sourcedir}/homed %{buildroot}%{_bindir}/homed
install -m 644 %{_sourcedir}/homeagent.service %{buildroot}%{_unitdir}/homeagent.service
install -m 644 %{_sourcedir}/hologramagent.service %{buildroot}%{_unitdir}/hologramagent.service
%endif
# waiter 三个变体都要:server 也含 CLI(对齐 deb 的 stage_variant
@ -68,8 +68,8 @@ install -m 644 %{_sourcedir}/homeagent.service %{buildroot}%{_unitdir}/homeagent
install -m 755 %{_sourcedir}/waiter %{buildroot}%{_bindir}/waiter
%if "%{variant}" == "full" || "%{variant}" == "client"
mkdir -p %{buildroot}%{_datadir}/homeagent-gui
cp -r %{_sourcedir}/homeagent-gui-linux-*/* %{buildroot}%{_datadir}/homeagent-gui/
mkdir -p %{buildroot}%{_datadir}/hologram-gui
cp -r %{_sourcedir}/hologram-gui-linux-*/* %{buildroot}%{_datadir}/hologram-gui/
%endif
%files
@ -77,33 +77,33 @@ cp -r %{_sourcedir}/homeagent-gui-linux-*/* %{buildroot}%{_datadir}/homeagent-gu
%if "%{variant}" == "full" || "%{variant}" == "server"
%{_bindir}/homed
%{_unitdir}/homeagent.service
%{_unitdir}/hologramagent.service
%dir %{_varlibdir}
%endif
%{_bindir}/waiter
%if "%{variant}" == "full" || "%{variant}" == "client"
%dir %{_datadir}/homeagent-gui
%{_datadir}/homeagent-gui/*
%dir %{_datadir}/hologram-gui
%{_datadir}/hologram-gui/*
%endif
%post
%if "%{variant}" == "full" || "%{variant}" == "server"
mkdir -p %{_varlibdir}
%systemd_post homeagent.service
%systemd_post hologramagent.service
%endif
%preun
%if "%{variant}" == "full" || "%{variant}" == "server"
%systemd_preun homeagent.service
%systemd_preun hologramagent.service
%endif
%postun
%if "%{variant}" == "full" || "%{variant}" == "server"
%systemd_postun_with_restart homeagent.service
%systemd_postun_with_restart hologramagent.service
%endif
%changelog
* Mon Jul 20 2026 HomeAgent Team <team@homeagent.ai> - %{version}-1
* Mon Jul 20 2026 HologramAgent Team <team@hologramagent.ai> - %{version}-1
- Initial Linux packaging

View File

@ -1,14 +1,14 @@
#!/usr/bin/env bash
# HomeAgent 首次初始化脚本
# HologramAgent 首次初始化脚本
# 在安装后执行,生成凭据并初始化数据库
set -e
DATA_DIR="${HOMEAGENT_DATA:-/var/lib/homeagent}"
DATA_DIR="${HOLOGRAM_DATA:-/var/lib/hologram}"
CRED_FILE="${DATA_DIR}/credentials.txt"
CONFIG_DB="${DATA_DIR}/config.db"
WAITER_CONF="${DATA_DIR}/waiter.yaml"
INITCONFIG_BIN="/usr/bin/initconfig"
BUNDLED_MODEL_DIR="/usr/lib/homeagent/models/chinese-clip-vit-b16-onnx"
BUNDLED_MODEL_DIR="/usr/lib/hologram/models/chinese-clip-vit-b16-onnx"
MODEL_LINK="${DATA_DIR}/models/chinese-clip-vit-b16-onnx"
# 模型随 server/full 包安装到只读的 /usr/lib;配置默认仍指向 dataDir/models。
@ -33,9 +33,9 @@ mkdir -p "$DATA_DIR"
# 允许环境变量覆盖:安装器(包括 Windows 上的 WSL 引导安装)已经在界面上
# 向用户收过这些值,若不接受传入就只能两个地方各生成一份,用户看到的那份
# 与实际写入 config.db 的那份不一致——那种错会直接表现为「登录不上」。
API_KEY="${HOMEAGENT_API_KEY:-$(cat /proc/sys/kernel/random/uuid 2>/dev/null | tr -d '-' || echo "homeagent$(date +%s)")}"
API_KEY="${HOLOGRAM_API_KEY:-$(cat /proc/sys/kernel/random/uuid 2>/dev/null | tr -d '-' || echo "hologram$(date +%s)")}"
WEBUI_USER="${WEBUI_USER:-admin}"
WEBUI_PASS="${WEBUI_PASS:-$(openssl rand -hex 12 2>/dev/null || echo "homeagent")}"
WEBUI_PASS="${WEBUI_PASS:-$(openssl rand -hex 12 2>/dev/null || echo "hologram")}"
# 初始化数据库
if [ -x "$INITCONFIG_BIN" ]; then
@ -49,7 +49,7 @@ fi
# 保存凭据
cat > "$CRED_FILE" << CRED
===================================
HomeAgent 初始配置信息
HologramAgent 初始配置信息
请妥善保管,安装后仅此一份
===================================
WebUI 地址: http://localhost:8080
@ -74,6 +74,6 @@ WAITER
echo ""
echo "============================================"
echo " HomeAgent 初始化完成"
echo " HologramAgent 初始化完成"
echo "============================================"
cat "$CRED_FILE"

View File

@ -86,7 +86,7 @@ case "$ARCH" in
*) echo "Unknown arch: $ARCH (use amd64 or arm64)"; exit 1 ;;
esac
echo "=== HomeAgent Linux Packager ==="
echo "=== HologramAgent Linux Packager ==="
echo "Version: $VERSION"
[ "$PKG_VERSION" = "$VERSION" ] || echo "Package: $PKG_VERSION (normalized for deb/rpm)"
echo "Arch: $ARCH"
@ -198,7 +198,7 @@ build_go() {
# 一道强制校验:架构不符就删掉目录并跳过 GUI,宁可不发也不发坏包。
build_gui() {
local gui_dir="$PROJECT_ROOT/cmd/gui"
local gui_out="$BUILD_DIR/homeagent-gui-linux-${TAR_ARCH}"
local gui_out="$BUILD_DIR/hologram-gui-linux-${TAR_ARCH}"
if [ -d "$gui_out" ]; then
echo ">>> GUI already built at $gui_out (delete to rebuild)"
@ -343,11 +343,11 @@ print(m.group(1) if m else '')
fi
# create desktop entry and symlink
cat > "$gui_out/resources/app/homeagent-gui.desktop" << DESKTOP
cat > "$gui_out/resources/app/hologram-gui.desktop" << DESKTOP
[Desktop Entry]
Name=HomeAgent
Comment=HomeAgent Desktop GUI
Exec=$gui_out/homeagent-gui
Name=HologramAgent
Comment=HologramAgent Desktop GUI
Exec=$gui_out/hologram-gui
Terminal=false
Type=Application
Categories=Utility;
@ -355,12 +355,12 @@ Icon=$gui_out/resources/app/icon.svg
DESKTOP
# create launcher script
cat > "$gui_out/homeagent-gui" << 'LAUNCHER'
cat > "$gui_out/hologram-gui" << 'LAUNCHER'
#!/bin/sh
DIR="$(cd "$(dirname "$0")" && pwd)"
exec "$DIR/electron" "$DIR/resources/app" "$@"
LAUNCHER
chmod +x "$gui_out/homeagent-gui"
chmod +x "$gui_out/hologram-gui"
chmod +x "$gui_out/electron"
# 最后一道强制校验:electron 二进制的实际架构必须匹配目标架构。
@ -398,7 +398,7 @@ stage_variant() {
mkdir -p "$staging/usr/bin"
mkdir -p "$staging/etc/systemd/system"
mkdir -p "$staging/var/lib/homeagent"
mkdir -p "$staging/var/lib/hologram"
local initconfig_bin="$BUILD_DIR/initconfig_$suffix"
@ -457,7 +457,7 @@ stage_variant() {
stage_sdk() {
local staging="$1"
local sdk_src="$PROJECT_ROOT/third_party/homeagent-sdk"
local sdk_dst="$staging/usr/lib/homeagent/sdk"
local sdk_dst="$staging/usr/lib/hologram/sdk"
[ -d "$sdk_src" ] || { echo "ERROR: 找不到 SDK 源码 $sdk_src" >&2; return 1; }
mkdir -p "$sdk_dst"
for item in go.mod go.sum LICENSE README.md sdk meta tools skills; do
@ -475,7 +475,7 @@ stage_variant() {
cp "$BUILD_DIR/homed_$suffix" "$staging/usr/bin/homed"
cp "$BUILD_DIR/waiter_$suffix" "$staging/usr/bin/waiter"
stage_depgraph "$staging"
cp "$PROJECT_ROOT/deploy/homeagent.service" "$staging/etc/systemd/system/homeagent.service"
cp "$PROJECT_ROOT/deploy/hologramagent.service" "$staging/etc/systemd/system/hologramagent.service"
[ -f "$initconfig_bin" ] && cp "$initconfig_bin" "$staging/usr/bin/initconfig"
stage_setup "$staging"
stage_license "$staging"
@ -486,7 +486,7 @@ stage_variant() {
cp "$BUILD_DIR/homed_$suffix" "$staging/usr/bin/homed"
cp "$BUILD_DIR/waiter_$suffix" "$staging/usr/bin/waiter"
stage_depgraph "$staging"
cp "$PROJECT_ROOT/deploy/homeagent.service" "$staging/etc/systemd/system/homeagent.service"
cp "$PROJECT_ROOT/deploy/hologramagent.service" "$staging/etc/systemd/system/hologramagent.service"
[ -f "$initconfig_bin" ] && cp "$initconfig_bin" "$staging/usr/bin/initconfig"
stage_setup "$staging"
stage_license "$staging"
@ -499,7 +499,7 @@ stage_variant() {
stage_depgraph "$staging"
stage_hmapdev "$staging"
stage_sdk "$staging"
cp "$PROJECT_ROOT/deploy/homeagent.service" "$staging/etc/systemd/system/homeagent.service"
cp "$PROJECT_ROOT/deploy/hologramagent.service" "$staging/etc/systemd/system/hologramagent.service"
[ -f "$initconfig_bin" ] && cp "$initconfig_bin" "$staging/usr/bin/initconfig"
stage_setup "$staging"
stage_license "$staging"
@ -520,15 +520,15 @@ stage_variant() {
stage_gui() {
local staging="$1"
local gui_src="$BUILD_DIR/homeagent-gui-linux-${TAR_ARCH}"
local gui_src="$BUILD_DIR/hologram-gui-linux-${TAR_ARCH}"
if [ -d "$gui_src" ]; then
mkdir -p "$staging/usr/lib/homeagent-gui"
cp -r "$gui_src"/* "$staging/usr/lib/homeagent-gui/"
cat > "$staging/usr/bin/homeagent-gui" << 'SCRIPT'
mkdir -p "$staging/usr/lib/hologram-gui"
cp -r "$gui_src"/* "$staging/usr/lib/hologram-gui/"
cat > "$staging/usr/bin/hologram-gui" << 'SCRIPT'
#!/bin/sh
exec /usr/lib/homeagent-gui/homeagent-gui "$@"
exec /usr/lib/hologram-gui/hologram-gui "$@"
SCRIPT
chmod 755 "$staging/usr/bin/homeagent-gui"
chmod 755 "$staging/usr/bin/hologram-gui"
else
echo " WARNING: GUI not built, skipping GUI staging"
fi
@ -538,30 +538,30 @@ stage_setup() {
local staging="$1"
local setup_src="$PROJECT_ROOT/deploy/packaging/linux/setup.sh"
if [ -f "$setup_src" ]; then
mkdir -p "$staging/usr/lib/homeagent"
cp "$setup_src" "$staging/usr/lib/homeagent/setup.sh"
chmod 755 "$staging/usr/lib/homeagent/setup.sh"
mkdir -p "$staging/usr/lib/hologram"
cp "$setup_src" "$staging/usr/lib/hologram/setup.sh"
chmod 755 "$staging/usr/lib/hologram/setup.sh"
fi
}
# 项目自身的许可:**所有变体**都要带(client 也分发 waiter 与 GUI)。
#
# deb 按 Debian 惯例给 /usr/share/doc/homeagent/copyright(DEP-5 机器可读格式),
# deb 按 Debian 惯例给 /usr/share/doc/hologramagent/copyright(DEP-5 机器可读格式),
# 同时把 LICENSE 全文放进去;rpm 的许可走 fpm 的 --license 元数据。
# 与 stage_multimodal_assets 的 licenses/ 分工:那里放**第三方**(模型/运行库)的
# 许可全文,这里放本项目自己的。
stage_license() {
local staging="$1"
local docdir="$staging/usr/share/doc/homeagent"
local docdir="$staging/usr/share/doc/hologramagent"
mkdir -p "$docdir"
cp "$PROJECT_ROOT/LICENSE" "$docdir/LICENSE"
cat > "$docdir/copyright" <<'EOF'
Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/
Upstream-Name: HomeAgent
Source: https://github.com/JianFeeeee/HomeAgent
Upstream-Name: HologramAgent
Source: https://github.com/JianFeeeee/HologramAgent
Files: *
Copyright: HomeAgent contributors
Copyright: HologramAgent contributors
License: AGPL-3.0-only
This program is free software: you can redistribute it and/or modify it under
the terms of the GNU Affero General Public License as published by the Free
@ -579,18 +579,18 @@ License: AGPL-3.0-only
clause (§13 Remote Network Interaction) — offering modified versions of this
software to users over a network also requires offering them the source.
.
Full text: /usr/share/doc/homeagent/LICENSE
Full text: /usr/share/doc/hologramagent/LICENSE
Files: usr/lib/homeagent/models/chinese-clip-vit-b16-onnx/*
Files: usr/lib/hologram/models/chinese-clip-vit-b16-onnx/*
Copyright: OFA-Sys / Chinese-CLIP authors
License: Apache-2.0
Full text: /usr/share/doc/homeagent/licenses/Chinese-CLIP-Apache-2.0.txt
Full text: /usr/share/doc/hologramagent/licenses/Chinese-CLIP-Apache-2.0.txt
Comment: pre-trained model artifacts; NOT covered by this package's AGPL grant
Files: usr/lib/homeagent/onnxruntime/*
Files: usr/lib/hologram/onnxruntime/*
Copyright: Microsoft Corporation
License: MIT
Full text: /usr/share/doc/homeagent/licenses/ONNX-Runtime-MIT.txt
Full text: /usr/share/doc/hologramagent/licenses/ONNX-Runtime-MIT.txt
Comment: license texts and third-party notices under licenses/ONNX-Runtime-*
EOF
chmod 644 "$docdir/LICENSE" "$docdir/copyright"
@ -600,9 +600,9 @@ EOF
# 只要打 server/full 包,两者缺一就失败。client 包不运行 homed,故不携带。
stage_multimodal_assets() {
local staging="$1"
local model_dst="$staging/usr/lib/homeagent/models/chinese-clip-vit-b16-onnx"
local ort_dst="$staging/usr/lib/homeagent/onnxruntime"
local licenses="$staging/usr/share/doc/homeagent/licenses"
local model_dst="$staging/usr/lib/hologram/models/chinese-clip-vit-b16-onnx"
local ort_dst="$staging/usr/lib/hologram/onnxruntime"
local licenses="$staging/usr/share/doc/hologramagent/licenses"
if [ ! -d "$CHINESECLIP_BUNDLE_DIR" ]; then
echo "ERROR: Chinese-CLIP 产物目录不存在:$CHINESECLIP_BUNDLE_DIR" >&2
@ -672,7 +672,7 @@ build_deb() {
local deb_dir="${DIST_DIR}/deb"
mkdir -p "$deb_dir"
local pkg_name="homeagent-${variant}_${PKG_VERSION}_${DEB_ARCH}.deb"
local pkg_name="hologramagent-${variant}_${PKG_VERSION}_${DEB_ARCH}.deb"
local deb_root
deb_root="$(mktemp -d "$STAGE_TMP/deb.XXXXXX")"
@ -711,13 +711,13 @@ build_tar() {
local tar_dir="${DIST_DIR}/tar"
mkdir -p "$tar_dir"
local archive_name="homeagent_${PKG_VERSION}_linux_${TAR_ARCH}.tar.gz"
local archive_dir="homeagent-${PKG_VERSION}-linux-${TAR_ARCH}"
local archive_name="hologramagent_${PKG_VERSION}_linux_${TAR_ARCH}.tar.gz"
local archive_dir="hologramagent-${PKG_VERSION}-linux-${TAR_ARCH}"
# build combined staging
local staging
staging="$(mktemp -d "$STAGE_TMP/tar.XXXXXX")"
mkdir -p "$staging/usr/bin" "$staging/usr/lib/homeagent" "$staging/etc/systemd/system"
mkdir -p "$staging/usr/bin" "$staging/usr/lib/hologram" "$staging/etc/systemd/system"
# copy all available binaries
for bin in homed waiter initconfig; do
@ -727,21 +727,21 @@ build_tar() {
# setup script
local setup_src="$PROJECT_ROOT/deploy/packaging/linux/setup.sh"
[ -f "$setup_src" ] && cp "$setup_src" "$staging/usr/lib/homeagent/setup.sh"
cp "$PROJECT_ROOT/deploy/homeagent.service" "$staging/etc/systemd/system/homeagent.service"
[ -f "$setup_src" ] && cp "$setup_src" "$staging/usr/lib/hologram/setup.sh"
cp "$PROJECT_ROOT/deploy/hologramagent.service" "$staging/etc/systemd/system/hologramagent.service"
stage_license "$staging"
stage_multimodal_assets "$staging"
# GUI if available
local gui_src="$BUILD_DIR/homeagent-gui-linux-${TAR_ARCH}"
local gui_src="$BUILD_DIR/hologram-gui-linux-${TAR_ARCH}"
if [ -d "$gui_src" ]; then
mkdir -p "$staging/usr/lib/homeagent-gui"
cp -r "$gui_src"/* "$staging/usr/lib/homeagent-gui/"
cat > "$staging/usr/bin/homeagent-gui" << 'SCRIPT'
mkdir -p "$staging/usr/lib/hologram-gui"
cp -r "$gui_src"/* "$staging/usr/lib/hologram-gui/"
cat > "$staging/usr/bin/hologram-gui" << 'SCRIPT'
#!/bin/sh
exec /usr/lib/homeagent-gui/homeagent-gui "$@"
exec /usr/lib/hologram-gui/hologram-gui "$@"
SCRIPT
chmod 755 "$staging/usr/bin/homeagent-gui"
chmod 755 "$staging/usr/bin/hologram-gui"
fi
chmod 755 "$staging/usr/bin/"* 2>/dev/null || true
@ -759,7 +759,7 @@ build_rpm() {
local rpm_dir="${DIST_DIR}/rpm"
mkdir -p "$rpm_dir"
local pkg_name="homeagent-${variant}-${PKG_VERSION}-1.${RPM_ARCH}.rpm"
local pkg_name="hologramagent-${variant}-${PKG_VERSION}-1.${RPM_ARCH}.rpm"
# find fpm
local fpm_bin="$(command -v fpm 2>/dev/null || true)"
@ -770,7 +770,7 @@ build_rpm() {
if [ -z "$fpm_bin" ]; then
echo " SKIP .rpm: fpm not installed. Install it with: gem install fpm"
echo " Alternatively, build RPM on Fedora/RHEL using:"
echo " rpmbuild -ba deploy/packaging/linux/homeagent.spec"
echo " rpmbuild -ba deploy/packaging/linux/hologramagent.spec"
return
fi
@ -804,12 +804,12 @@ build_rpm() {
echo ">>> Building .rpm via fpm: $pkg_name"
"$fpm_bin" -s dir -t rpm \
-n "homeagent-${variant}" \
-n "hologramagent-${variant}" \
-v "$VERSION" \
--iteration 1 \
-a "$RPM_ARCH" \
--description "HomeAgent ${variant^} package" \
--url "https://github.com/trueagent/HomeAgent" \
--description "HologramAgent ${variant^} package" \
--url "https://github.com/trueagent/HologramAgent" \
--license "AGPL-3.0-only" \
-C "$staging" \
-p "$rpm_dir/$pkg_name" \
@ -874,7 +874,7 @@ main() {
# 只列**本批**产物:dist/ 会跨多次构建累积,用 find 全目录会让清单/SHA256SUMS
# 带上历史版本的文件名——用户下载那种清单后 `sha256sum -c` 必然报缺失。
# (v1.2.2 构建时就出现过:清单里混进了 1.2.0/1.2.1 的包名。)按本批版本号过滤。
mapfile -t release_files < <(find "$DIST_DIR" -type f \( -name "*${PKG_VERSION}*.deb" -o -name "homeagent_${PKG_VERSION}_*.tar.gz" -o -name "*${PKG_VERSION}*.rpm" \) 2>/dev/null | sort)
mapfile -t release_files < <(find "$DIST_DIR" -type f \( -name "*${PKG_VERSION}*.deb" -o -name "hologramagent_${PKG_VERSION}_*.tar.gz" -o -name "*${PKG_VERSION}*.rpm" \) 2>/dev/null | sort)
for f in "${release_files[@]}"; do
echo " $(du -h "$f" | cut -f1) $f"
done

View File

@ -16,6 +16,23 @@
set -euo pipefail
PROJECT_ROOT="$(cd "$(dirname "$0")/../.." && pwd)"
# ★ 版本号的**解析规则**必须与 package-linux.sh / build.sh 同源(2026-10-17 统一)。
# 原先这里直接 `git describe --tags`,在无 tag 分支上会拿到分支名
# (backup/pre-identity-rewrite-...-g<sha>-dirty),于是:
# · 这个脚本拿它当 VERSION 去拼 DEB_GLOB ⇒ 找不到 Linux 包,报"[FAIL] 找不到"
# 看上去像"Linux 包没打出来",实际是版本号被解析成分支名;
# · 就算找到了,安装器的 DisplayVersion 也会变成那串东西。
# 统一为:git describe 只在形如 vX.Y.Z 时采用,否则回退 meta.Version。
_meta_version() {
local mv
mv="$(sed -n 's/^[[:space:]]*Version[[:space:]]*=[[:space:]]*"\([^"]*\)".*/\1/p' \
"$PROJECT_ROOT/internal/meta/meta.go" 2>/dev/null | head -1)"
case "$mv" in
[0-9]*.[0-9]*.[0-9]*) printf '%s' "$mv"; return 0 ;;
esac
return 1
}
# 三个目录都可覆盖:发布件常在 tag 的干净 worktree 里构建,而这个脚本本身
# 可能只存在于 main(例如刚补的驱动脚本还没进 tag)——那种情况下用主仓的脚本 +
# DIST_LINUX/BUILD_DIR/DIST_RELEASE 指向 worktree,避免"脚本不存在"或产物错位。
@ -34,13 +51,30 @@ fi
VARIANT="${1:-server}"
ARCH="${2:-amd64}"
VERSION="${VERSION:-$(git -C "$PROJECT_ROOT" describe --tags 2>/dev/null || echo 0.0.0)}"
if [ -z "${VERSION:-}" ]; then
_gd="$(git -C "$PROJECT_ROOT" describe --tags --dirty 2>/dev/null || true)"
case "$_gd" in
v[0-9]*.[0-9]*.[0-9]*) VERSION="${_gd#v}" ;;
*)
if VERSION="$(_meta_version)"; then
[ -n "$_gd" ] && echo "[PKG] warn: git describe 给出非版本串($_gd),改用 meta.Version=$VERSION" >&2
else
echo "[FAIL] 拿不到合法版本号(git describe=$_gd)。请显式传 VERSION=x.y.z。" >&2
exit 1
fi
;;
esac
fi
VERSION="${VERSION#v}"
case "$VERSION" in
[0-9]*) ;;
*) echo "[FAIL] VERSION='$VERSION' 必须以数字开头(deb/rpm 与 DisplayVersion 都要求)。" >&2; exit 1 ;;
esac
case "$VARIANT" in
server) DEB_GLOB="homeagent-server_${VERSION}_${ARCH}.deb"; SUFFIX="Server"; WANT_GUI=0; WANT_WAITER=0 ;;
full) DEB_GLOB="homeagent-full_${VERSION}_${ARCH}.deb"; SUFFIX="Full"; WANT_GUI=1; WANT_WAITER=1 ;;
client) DEB_GLOB="homeagent-client_${VERSION}_${ARCH}.deb"; SUFFIX="Client"; WANT_GUI=1; WANT_WAITER=1 ;;
server) DEB_GLOB="hologramagent-server_${VERSION}_${ARCH}.deb"; SUFFIX="Server"; WANT_GUI=0; WANT_WAITER=0 ;;
full) DEB_GLOB="hologramagent-full_${VERSION}_${ARCH}.deb"; SUFFIX="Full"; WANT_GUI=1; WANT_WAITER=1 ;;
client) DEB_GLOB="hologramagent-client_${VERSION}_${ARCH}.deb"; SUFFIX="Client"; WANT_GUI=1; WANT_WAITER=1 ;;
*) echo "用法: $0 <server|client|full> [arch]" >&2; exit 2 ;;
esac
@ -54,14 +88,37 @@ fi
# client/full 还要带 Windows GUI(HAS_GUI=1)。本机缺 electron-builder,若 build/ 下
# 没有可用的 win32-x64 payload 就**明确失败**,不产出"装完没有界面"的半残包。
#
# ★ payload 目录名有两个可能来源,必须都认:
# 1. electron-builder(deploy/packaging/build.sh 的 build_gui,productName=HomeAgent)
# ⇒ build/homeagent-gui-win32-x64
# 2. electron-packager(Makefile:331,GUI_BINARY=homeagent-gui)
# ⇒ build/homeagent-gui-win32-x64 之外的名字
# 而 installer.nsi(本仓已改名)期望的是 hologram-gui-win32-x64。
# 生产 GUI 产物的命名归 Makefile / cmd/gui(本批范围外),所以这里**不假设**
# 上游已改名:找到哪个就用哪个,并统一 stage 成 .nsi 期望的名字。
# 漏了这一步,改名后 Windows 包会以"[FAIL] 需要 GUI payload"失败——或者更糟,
# 若哪天有人把检查放宽成"有 .exe 就行",打出的安装器会 File 一个不存在的目录。
if [ "$WANT_GUI" = 1 ]; then
if [ -z "$(ls -1 "$BUILD_DIR"/homeagent-gui-win32-x64/*.exe 2>/dev/null | head -1 || true)" ]; then
echo "[FAIL] 变体 $VARIANT 需要 Windows GUI payload(build/homeagent-gui-win32-x64/*.exe)" >&2
GUI_PAYLOAD=""
for cand in "$BUILD_DIR"/hologram-gui-win32-x64 "$BUILD_DIR"/homeagent-gui-win32-x64 "$BUILD_DIR"/homeagent-gui-win32-*; do
if [ -n "$(ls -1 "$cand"/*.exe 2>/dev/null | head -1 || true)" ]; then
GUI_PAYLOAD="$cand"
break
fi
done
if [ -z "$GUI_PAYLOAD" ]; then
echo "[FAIL] 变体 $VARIANT 需要 Windows GUI payload(build/{hologram,homeagent}-gui-win32-x64/*.exe)" >&2
echo " 本机无 electron-builder:npm i -g electron-builder &&" >&2
echo " bash deploy/packaging/build.sh windows/amd64 gui" >&2
echo " (只装内核+CLI 的 WSL 场景请用 server 变体)" >&2
exit 1
fi
if [ "$(basename "$GUI_PAYLOAD")" != "hologram-gui-win32-x64" ]; then
echo "[STAGE] GUI payload $(basename "$GUI_PAYLOAD") → hologram-gui-win32-x64(.nsi 期望的名字)"
rm -rf "$BUILD_DIR/hologram-gui-win32-x64"
cp -a "$GUI_PAYLOAD" "$BUILD_DIR/hologram-gui-win32-x64"
fi
fi
if [ "$WANT_WAITER" = 1 ]; then
@ -83,7 +140,7 @@ fi
echo "[BUILD] makensis -DVARIANT=$VARIANT -DPRODUCT_VERSION=$VERSION(nsi: $NSI)"
makensis -V2 -DVARIANT="$VARIANT" -DPRODUCT_VERSION="$VERSION" "$NSI"
OUT="$BUILD_DIR/HomeAgent_v${VERSION}_${SUFFIX}_win64.exe"
OUT="$BUILD_DIR/HologramAgent_v${VERSION}_${SUFFIX}_win64.exe"
if [ ! -f "$OUT" ]; then
echo "[FAIL] 未找到产物 $OUT" >&2
exit 1

View File

@ -168,9 +168,150 @@ func TestToolchainVariantHasControlFile(t *testing.T) {
t.Fatal("★ 缺 control-toolchain —— toolchain 变体打不出来")
}
c := string(b)
for _, kw := range []string{"homeagent-toolchain", "hmapdev", "SDK", "depgraph"} {
for _, kw := range []string{"hologramagent-toolchain", "hmapdev", "SDK", "depgraph"} {
if !strings.Contains(c, kw) {
t.Errorf("control-toolchain 的描述里应提到 %s(让 apt show 能说清装了什么)", kw)
}
}
}
// ★★★ 判据:打包产物里的**安装路径与单元名**必须已随品牌改名(批 2)。
//
// 这条守的是"改一半就静默失效"那一类:包能打出来、退出码 0,但内容里
// 还写着旧路径 —— 装上去之后 systemd 找不到单元、数据目录对不上、
// ONNX 运行库指向空目录,而且没有任何一步报错。
//
// 只扫**产物布局相关**的旧串,不扫 module 路径(那是批 1 的地盘,
// 见 TestPackagingLdflagsUseCurrentModulePath)。
func TestPackagingUsesRenamedInstallPaths(t *testing.T) {
src := readOrSkip(t, pkgLinux)
// 安装路径 / 单元文件:一个都不许留旧值。
for _, stale := range []string{
"/var/lib/homeagent",
"/usr/lib/homeagent",
"/usr/share/doc/homeagent",
"deploy/homeagent.service",
"/etc/systemd/system/homeagent.service",
"/usr/bin/homeagent-gui",
"/usr/lib/homeagent-gui",
`pkg_name="homeagent-`,
} {
if strings.Contains(src, stale) {
t.Errorf("★ package-linux.sh 仍含旧安装路径/包名 %q —— "+
"打出的包会装到旧位置(日志全绿,装完路径对不上)", stale)
}
}
// 新值必须真的出现(否则上面的"无旧值"可能只是整段被删了)。
for _, want := range []string{
"/var/lib/hologram",
"/usr/lib/hologram",
"/usr/share/doc/hologramagent",
"deploy/hologramagent.service",
"/etc/systemd/system/hologramagent.service",
"/usr/bin/hologram-gui",
"/usr/lib/hologram-gui",
`pkg_name="hologramagent-`,
} {
if !strings.Contains(src, want) {
t.Errorf("★ package-linux.sh 缺少 %q —— 改名没落到位", want)
}
}
}
// ★★★ 判据:deb 的 postinst / prerm 必须操作**新**单元名。
//
// postinst 的 SERVICE_NAME 若还是旧名,装完 systemctl enable 找不到单元:
// 它带 `|| true`,所以一声不响地什么也没启用 —— 装完不会开机自启。
func TestDebMaintainerScriptsUseRenamedService(t *testing.T) {
for _, p := range []string{
"../../deploy/packaging/linux/deb/postinst",
"../../deploy/packaging/linux/deb/prerm",
} {
b, err := os.ReadFile(p)
if err != nil {
t.Skipf("读不到 %s: %v", p, err)
}
s := string(b)
if !strings.Contains(s, `SERVICE_NAME="hologramagent"`) {
t.Errorf("★ %s 的 SERVICE_NAME 不是 hologramagent —— "+
"systemctl enable/stop 会作用在不存在的单元上(|| true 吞掉失败)", p)
}
if strings.Contains(s, `SERVICE_NAME="homeagent"`) {
t.Errorf("★ %s 仍用旧 SERVICE_NAME=homeagent", p)
}
if strings.Contains(s, "/var/lib/homeagent") || strings.Contains(s, "/usr/lib/homeagent") {
t.Errorf("★ %s 仍含旧安装路径", p)
}
}
}
// ★★★ 判据:四个 deb control 的包名与 SDK 安装路径必须已改。
//
// `dpkg-deb -f <pkg> Package` 的输出就是这里的 Package 字段;
// 旧名会让 apt 认为是另一个包(升级路径直接断成"装了第二个包")。
func TestDebControlFilesUseRenamedPackage(t *testing.T) {
for _, variant := range []string{"client", "server", "full", "toolchain"} {
p := "../../deploy/packaging/linux/deb/control-" + variant
b, err := os.ReadFile(p)
if err != nil {
t.Fatalf("读不到 %s: %v", p, err)
}
s := string(b)
want := "Package: hologramagent-" + variant + "\n"
if !strings.Contains(s, want) {
t.Errorf("★ %s 缺少 %q", p, strings.TrimSpace(want))
}
if strings.Contains(s, "Package: homeagent-") {
t.Errorf("★ %s 的 Package 仍是旧的 homeagent-*", p)
}
if strings.Contains(s, "/usr/lib/homeagent") {
t.Errorf("★ %s 的 SDK 安装路径仍是 /usr/lib/homeagent", p)
}
}
if b, err := os.ReadFile("../../deploy/packaging/linux/deb/control-toolchain"); err == nil {
if !strings.Contains(string(b), "/usr/lib/hologram/sdk") {
t.Error("★ control-toolchain 没把 SDK 装到 /usr/lib/hologram/sdk")
}
}
}
// ★★★ 判据:systemd 单元文件本身(deploy/hologramagent.service)。
//
// 文件名改了、内容没改是最典型的一半:ExecStart 仍写旧数据目录,
// 于是 StateDirectory / ReadWritePaths 与实际 --data 不一致,
// 内核起得来但写到只读路径上(或反之)—— 取决于 sandbox 设置,难查。
func TestSystemdUnitUsesRenamedPaths(t *testing.T) {
b, err := os.ReadFile("../../deploy/hologramagent.service")
if err != nil {
t.Fatalf("★ 缺 deploy/hologramagent.service: %v", err)
}
s := string(b)
for _, want := range []string{
"--data /var/lib/hologram",
"WorkingDirectory=/var/lib/hologram",
"StateDirectory=hologram",
"ReadWritePaths=/var/lib/hologram",
"ReadOnlyPaths=/etc/hologram",
"ONNXRUNTIME_DIR=/usr/lib/hologram/onnxruntime",
"LoadCredential=homed_security_key:/etc/hologram/security.key",
} {
if !strings.Contains(s, want) {
t.Errorf("★ hologramagent.service 缺 %q", want)
}
}
// 注释里可以留旧路径(升级说明),但**指令行**不能有。
for _, line := range strings.Split(s, "\n") {
trimmed := strings.TrimSpace(line)
if trimmed == "" || strings.HasPrefix(trimmed, "#") {
continue
}
if strings.Contains(trimmed, "/var/lib/homeagent") || strings.Contains(trimmed, "/usr/lib/homeagent") {
t.Errorf("★ hologramagent.service 指令行仍含旧路径: %s", trimmed)
}
}
if _, err := os.Stat("../../deploy/homeagent.service"); err == nil {
t.Error("★ deploy/homeagent.service 仍然存在 —— 旧单元文件没删,两个单元会打架")
}
}

View File

@ -1,6 +1,6 @@
<#
.SYNOPSIS
在 WSL2 中安装 HomeAgent(homed + 插件 + WebUI)。
在 WSL2 中安装 HologramAgent(homed + 插件 + WebUI)。
.DESCRIPTION
Windows 不再提供 homed 的原生安装。原因见 cmd/homed/platform_windows.go:
@ -23,7 +23,7 @@
目标发行版名。省略则用默认发行版;没有发行版时引导安装 Ubuntu。
.PARAMETER DataDir
WSL 内的数据目录。默认 /var/lib/homeagent(与 Linux 原生安装一致)。
WSL 内的数据目录。默认 /var/lib/hologram(与 Linux 原生安装一致)。
不建议放 /mnt/c/...:跨文件系统 IO 慢,且 inotify 语义受限。
.NOTES
@ -35,7 +35,7 @@
param(
[Parameter(Mandatory = $true)][string]$PayloadDir,
[string]$Distro = "",
[string]$DataDir = "/var/lib/homeagent",
[string]$DataDir = "/var/lib/hologram",
[string]$ApiKey = "",
[string]$WebUIUser = "",
[string]$WebUIPass = "",
@ -160,19 +160,19 @@ $winPath = (Resolve-Path $pkg).Path
$mntPath = "/mnt/" + $winPath.Substring(0, 1).ToLower() + ($winPath.Substring(2) -replace '\\', '/')
Write-Host " 源:$mntPath"
& wsl.exe -d $script:DistroName -u root -- bash -lc "mkdir -p /tmp/homeagent-install"
& wsl.exe -d $script:DistroName -u root -- bash -lc "mkdir -p /tmp/hologramagent-install"
if ($LASTEXITCODE -ne 0) { Fail "无法在 WSL 内创建临时目录" "确认发行版可正常启动:wsl -d $($script:DistroName)" }
& wsl.exe -d $script:DistroName -u root -- bash -lc "cp '$mntPath' /tmp/homeagent-install/"
& wsl.exe -d $script:DistroName -u root -- bash -lc "cp '$mntPath' /tmp/hologramagent-install/"
if ($LASTEXITCODE -ne 0) { Fail "复制安装包失败" }
Write-Ok "已送到 /tmp/homeagent-install/"
Write-Ok "已送到 /tmp/hologramagent-install/"
# ── 5. 在 WSL 内安装 ───────────────────────────────────────────────────────
Write-Stage "在 WSL 内安装 homed"
# 凭据经环境变量传给 setup.sh(它已支持 HOMEAGENT_API_KEY / WEBUI_USER / WEBUI_PASS)。
# 凭据经环境变量传给 setup.sh(它已支持 HOLOGRAM_API_KEY / WEBUI_USER / WEBUI_PASS)。
# 不传的话就会「界面显示一份、config.db 里另一份」,用户直接登录不上。
$credEnv = ""
if ($ApiKey) { $credEnv += "export HOMEAGENT_API_KEY='$ApiKey'; " }
if ($ApiKey) { $credEnv += "export HOLOGRAM_API_KEY='$ApiKey'; " }
if ($WebUIUser) { $credEnv += "export WEBUI_USER='$WebUIUser'; " }
if ($WebUIPass) { $credEnv += "export WEBUI_PASS='$WebUIPass'; " }
@ -180,34 +180,34 @@ if ($WebUIPass) { $credEnv += "export WEBUI_PASS='$WebUIPass'; " }
# tar 则解包到你同一套布局再执行同一份 setup.sh。刻意不在这里重写安装步骤——
# 「WSL 里就是普通 linux/amd64」必须保持成立,否则等于又开了第三个平台。
if ($pkgKind -eq "deb") {
$inWslPkg = "/tmp/homeagent-install/" + (Split-Path $pkg -Leaf)
$inWslPkg = "/tmp/hologramagent-install/" + (Split-Path $pkg -Leaf)
& wsl.exe -d $script:DistroName -u root -- bash -lc @"
set -e
$credEnv
export HOMEAGENT_DATA='$DataDir'
export HOLOGRAM_DATA='$DataDir'
apt-get update -qq
DEBIAN_FRONTEND=noninteractive apt-get install -y -qq '$inWslPkg'
"@
} else {
$inWslPkg = "/tmp/homeagent-install/" + (Split-Path $pkg -Leaf)
$inWslPkg = "/tmp/hologramagent-install/" + (Split-Path $pkg -Leaf)
& wsl.exe -d $script:DistroName -u root -- bash -lc @"
set -e
$credEnv
mkdir -p /opt/homeagent /tmp/homeagent-extract
tar -xzf '$inWslPkg' -C /tmp/homeagent-extract
cd /tmp/homeagent-extract
# 与 deb 完全相同的布局:/usr/bin/homed + /usr/lib/homeagent/setup.sh。
mkdir -p /opt/hologramagent /tmp/hologramagent-extract
tar -xzf '$inWslPkg' -C /tmp/hologramagent-extract
cd /tmp/hologramagent-extract
# 与 deb 完全相同的布局:/usr/bin/homed + /usr/lib/hologram/setup.sh。
# 两套安装若落到不同路径,之后的升级/排障就会出现「按文档找不到文件」。
install -m 0755 homed /usr/bin/homed
install -m 0755 waiter /usr/bin/waiter
[ -f initconfig ] && install -m 0755 initconfig /usr/bin/initconfig
if [ -f homeagent.service ]; then
install -m 0644 homeagent.service /etc/systemd/system/homeagent.service
if [ -f hologramagent.service ]; then
install -m 0644 hologramagent.service /etc/systemd/system/hologramagent.service
fi
mkdir -p /usr/lib/homeagent
if [ -f setup.sh ]; then install -m 0755 setup.sh /usr/lib/homeagent/setup.sh; fi
export HOMEAGENT_DATA='$DataDir'
if [ -x /usr/lib/homeagent/setup.sh ]; then bash /usr/lib/homeagent/setup.sh; fi
mkdir -p /usr/lib/hologram
if [ -f setup.sh ]; then install -m 0755 setup.sh /usr/lib/hologram/setup.sh; fi
export HOLOGRAM_DATA='$DataDir'
if [ -x /usr/lib/hologram/setup.sh ]; then bash /usr/lib/hologram/setup.sh; fi
"@
}
if ($LASTEXITCODE -ne 0) {
@ -219,14 +219,14 @@ Write-Ok "安装完成"
Write-Stage "启动 homed 与自启配置"
& wsl.exe -d $script:DistroName -u root -- bash -lc @"
if command -v systemctl >/dev/null 2>&1 && systemctl list-unit-files 2>/dev/null | grep -q homeagent; then
systemctl enable homeagent 2>/dev/null || true
systemctl restart homeagent
echo ' ✓ systemd 服务 homeagent 已启动并设为自启'
if command -v systemctl >/dev/null 2>&1 && systemctl list-unit-files 2>/dev/null | grep -q hologramagent; then
systemctl enable hologramagent 2>/dev/null || true
systemctl restart hologramagent
echo ' ✓ systemd 服务 hologramagent 已启动并设为自启'
else
# 没有 systemd(WSL2 默认可能没开):用 nohup 起,并把自启交给 Windows 侧的计划任务。
pkill -f '/usr/bin/homed' 2>/dev/null || true
nohup /usr/bin/homed -data '$DataDir' > /var/log/homeagent-boot.log 2>&1 &
nohup /usr/bin/homed -data '$DataDir' > /var/log/hologram-boot.log 2>&1 &
echo ' ✓ 已用 nohup 启动(未检测到 systemd)'
fi
"@
@ -235,7 +235,7 @@ $creds = & wsl.exe -d $script:DistroName -u root -- bash -lc "cat '$DataDir/cred
Write-Host ""
Write-Host "============================================================" -ForegroundColor Green
Write-Host " HomeAgent 已在 WSL2($($script:DistroName))内安装完成" -ForegroundColor Green
Write-Host " HologramAgent 已在 WSL2($($script:DistroName))内安装完成" -ForegroundColor Green
Write-Host "============================================================" -ForegroundColor Green
Write-Host ""
Write-Host " WebUI:http://localhost:8080" -ForegroundColor White
@ -250,10 +250,10 @@ if ($creds) {
Write-Host ""
Write-Host " 常用操作(在 PowerShell 中):"
Write-Host " 进入 WSL : wsl -d $($script:DistroName)"
Write-Host " 查看日志 : wsl -d $($script:DistroName) -u root -- journalctl -u homeagent -f"
Write-Host " 重启服务 : wsl -d $($script:DistroName) -u root -- systemctl restart homeagent"
Write-Host " 查看日志 : wsl -d $($script:DistroName) -u root -- journalctl -u hologramagent -f"
Write-Host " 重启服务 : wsl -d $($script:DistroName) -u root -- systemctl restart hologramagent"
Write-Host ""
Write-Host " 注意:WSL 实例不会随 Windows 启动而自动拉起。若需要开机自启,"
Write-Host " 可创建一个登录时触发的计划任务执行:"
Write-Host " wsl -d $($script:DistroName) -u root -- systemctl start homeagent"
Write-Host " wsl -d $($script:DistroName) -u root -- systemctl start hologramagent"
exit 0

View File

@ -1,13 +1,13 @@
#!/usr/bin/env bash
set -euo pipefail
# HomeAgent 部署脚本
# HologramAgent 部署脚本
# 用法: cd <project-root> && sudo bash deploy/scripts/deploy.sh
PROJECT_ROOT="$(cd "$(dirname "$0")/../.." && pwd)"
BIN_DIR="/usr/local/bin"
DATA_DIR="/home/newqqagent"
SERVICE_FILE="/etc/systemd/system/homeagent.service"
SERVICE_FILE="/etc/systemd/system/hologramagent.service"
echo "=== 构建 homed / waiter ==="
cd "$PROJECT_ROOT"
@ -30,16 +30,16 @@ if [ -d "$PROJECT_ROOT/plugins/qq" ]; then
fi
echo "=== 安装 systemd 服务 ==="
cp "$(dirname "$0")/homeagent.service" "$SERVICE_FILE"
cp "$(dirname "$0")/hologramagent.service" "$SERVICE_FILE"
systemctl daemon-reload
echo ""
echo "=== 部署完成 ==="
echo ""
echo "启动: systemctl start homeagent"
echo "状态: systemctl status homeagent"
echo "日志: journalctl -u homeagent -f"
echo "停止: systemctl stop homeagent"
echo "启动: systemctl start hologramagent"
echo "状态: systemctl status hologramagent"
echo "日志: journalctl -u hologramagent -f"
echo "停止: systemctl stop hologramagent"
echo "WebUI: http://localhost:8080"
echo "CLI: /home/newqqagent/cli.sock"
echo ""

View File

@ -1,5 +1,5 @@
[Unit]
Description=Jina v5-omni-nano Embedding Sidecar for HomeAgent
Description=Jina v5-omni-nano Embedding Sidecar for HologramAgent
After=network.target
[Service]