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] [Unit]
Description=HomeAgent - 24/7 AI Butler Description=HologramAgent - 24/7 AI Butler
Documentation=https://github.com/trueagent/HomeAgent Documentation=https://github.com/trueagent/HologramAgent
After=network-online.target docker.service After=network-online.target docker.service
Wants=network-online.target Wants=network-online.target
@ -28,9 +28,9 @@ Wants=network-online.target
Type=exec Type=exec
# ★ guard 模式(与本机生产实例一致)。 # ★ guard 模式(与本机生产实例一致)。
# 数据目录默认 /var/lib/homeagent(Debian 惯例);迁移到别的目录时 # 数据目录默认 /var/lib/hologram(Debian 惯例);迁移到别的目录时
# 必须**同时**改这里和 core.daemon.data_dir —— 两者不等价,见 README。 # 必须**同时**改这里和 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 Restart=always
RestartSec=10 RestartSec=10
@ -58,11 +58,11 @@ TimeoutStopSec=25s
# 一起收,双保险不留孤儿进程。 # 一起收,双保险不留孤儿进程。
KillMode=control-group KillMode=control-group
WorkingDirectory=/var/lib/homeagent WorkingDirectory=/var/lib/hologram
StateDirectory=homeagent StateDirectory=hologram
Environment=HOME=/root Environment=HOME=/root
# onnx 运行库随包安装(不在 /opt,见 packaging/package-linux.sh) # onnx 运行库随包安装(不在 /opt,见 packaging/package-linux.sh)
Environment=ONNXRUNTIME_DIR=/usr/lib/homeagent/onnxruntime Environment=ONNXRUNTIME_DIR=/usr/lib/hologram/onnxruntime
# ★ 主密钥生产注入(security/key.go) # ★ 主密钥生产注入(security/key.go)
# #
@ -74,8 +74,8 @@ Environment=ONNXRUNTIME_DIR=/usr/lib/homeagent/onnxruntime
# 不在磁盘留副本、也不进 environ。 # 不在磁盘留副本、也不进 environ。
# #
# 生成密钥(一次性,然后妥善保管): # 生成密钥(一次性,然后妥善保管):
# head -c 32 /dev/urandom | xxd -p -c 64 | sudo tee /etc/homeagent/security.key # head -c 32 /dev/urandom | xxd -p -c 64 | sudo tee /etc/hologram/security.key
# sudo chmod 600 /etc/homeagent/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), # 内核支持"磁盘钥 + 内嵌钥"并存解密(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 # Security hardening
NoNewPrivileges=true NoNewPrivileges=true
@ -97,9 +97,9 @@ PrivateTmp=true
PrivateDevices=false PrivateDevices=false
DevicePolicy=closed DevicePolicy=closed
# 只允许读主密钥所在目录,其余系统路径保持只读 # 只允许读主密钥所在目录,其余系统路径保持只读
ReadOnlyPaths=/etc/homeagent ReadOnlyPaths=/etc/hologram
# 插件需要写自己目录 + 数据目录 + 插件沙箱 # 插件需要写自己目录 + 数据目录 + 插件沙箱
ReadWritePaths=/var/lib/homeagent ReadWritePaths=/var/lib/hologram
# Audio devices # Audio devices
DeviceAllow=/dev/snd rw DeviceAllow=/dev/snd rw
DeviceAllow=/dev/dsp rw DeviceAllow=/dev/dsp rw

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -16,6 +16,23 @@
set -euo pipefail set -euo pipefail
PROJECT_ROOT="$(cd "$(dirname "$0")/../.." && pwd)" 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 里构建,而这个脚本本身 # 三个目录都可覆盖:发布件常在 tag 的干净 worktree 里构建,而这个脚本本身
# 可能只存在于 main(例如刚补的驱动脚本还没进 tag)——那种情况下用主仓的脚本 + # 可能只存在于 main(例如刚补的驱动脚本还没进 tag)——那种情况下用主仓的脚本 +
# DIST_LINUX/BUILD_DIR/DIST_RELEASE 指向 worktree,避免"脚本不存在"或产物错位。 # DIST_LINUX/BUILD_DIR/DIST_RELEASE 指向 worktree,避免"脚本不存在"或产物错位。
@ -34,13 +51,30 @@ fi
VARIANT="${1:-server}" VARIANT="${1:-server}"
ARCH="${2:-amd64}" 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}" VERSION="${VERSION#v}"
case "$VERSION" in
[0-9]*) ;;
*) echo "[FAIL] VERSION='$VERSION' 必须以数字开头(deb/rpm 与 DisplayVersion 都要求)。" >&2; exit 1 ;;
esac
case "$VARIANT" in case "$VARIANT" in
server) DEB_GLOB="homeagent-server_${VERSION}_${ARCH}.deb"; SUFFIX="Server"; WANT_GUI=0; WANT_WAITER=0 ;; server) DEB_GLOB="hologramagent-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 ;; full) DEB_GLOB="hologramagent-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 ;; 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 ;; *) echo "用法: $0 <server|client|full> [arch]" >&2; exit 2 ;;
esac esac
@ -54,14 +88,37 @@ fi
# client/full 还要带 Windows GUI(HAS_GUI=1)。本机缺 electron-builder,若 build/ 下 # client/full 还要带 Windows GUI(HAS_GUI=1)。本机缺 electron-builder,若 build/ 下
# 没有可用的 win32-x64 payload 就**明确失败**,不产出"装完没有界面"的半残包。 # 没有可用的 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 [ "$WANT_GUI" = 1 ]; then
if [ -z "$(ls -1 "$BUILD_DIR"/homeagent-gui-win32-x64/*.exe 2>/dev/null | head -1 || true)" ]; then GUI_PAYLOAD=""
echo "[FAIL] 变体 $VARIANT 需要 Windows GUI payload(build/homeagent-gui-win32-x64/*.exe)" >&2 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 " 本机无 electron-builder:npm i -g electron-builder &&" >&2
echo " bash deploy/packaging/build.sh windows/amd64 gui" >&2 echo " bash deploy/packaging/build.sh windows/amd64 gui" >&2
echo " (只装内核+CLI 的 WSL 场景请用 server 变体)" >&2 echo " (只装内核+CLI 的 WSL 场景请用 server 变体)" >&2
exit 1 exit 1
fi 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 fi
if [ "$WANT_WAITER" = 1 ]; then if [ "$WANT_WAITER" = 1 ]; then
@ -83,7 +140,7 @@ fi
echo "[BUILD] makensis -DVARIANT=$VARIANT -DPRODUCT_VERSION=$VERSION(nsi: $NSI)" echo "[BUILD] makensis -DVARIANT=$VARIANT -DPRODUCT_VERSION=$VERSION(nsi: $NSI)"
makensis -V2 -DVARIANT="$VARIANT" -DPRODUCT_VERSION="$VERSION" "$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 if [ ! -f "$OUT" ]; then
echo "[FAIL] 未找到产物 $OUT" >&2 echo "[FAIL] 未找到产物 $OUT" >&2
exit 1 exit 1

View File

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

View File

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

View File

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