Files
HomeAgent/deploy/packaging/installer.nsi
JianFeeeee 5e10f012cb docs(license): 核心仓采用 AGPL-3.0-only,并写进包内与安装器
本仓此前**没有任何许可文件**,README 里也没有许可声明,而 rpm 元数据里甚至写着
`--license "Proprietary"`(与我们实际的分发意图相反)。

## 选择了什么

`LICENSE`:GNU Affero 通用公共许可证第 3 版官方全文(gnu.org 正本,
661 行 / 34523 字节,
sha256 0d96a4ff68ad6d4b6f1f30f713b18d5184912ba8dd389f86aa7710db079abcb0)。

选 AGPL-3.0-only 的理由:GPL 家族里**传染性最强**的一档,并且不允许选后续版本。
它比 GPL-3.0 多出 §13(Remote Network Interaction)——通过网络提供服务时也要向
使用者提供源码。这正是「最严格」在 GPL 家族里的落点。

依赖许可已核对为全部宽松且兼容:go-sqlite3 / gojieba / gopher-lua / bubbletea /
bubbles / lipgloss / yaml.v3(MIT)、golang.org/x/{sys,text}(BSD-3)、
Chinese-CLIP 产物(Apache-2.0,与 GPLv3+/AGPLv3 双向兼容)、ONNX Runtime(MIT)。
没有 GPL-2.0-only 这类与 AGPL 不兼容的依赖。

## 落在哪些地方

- `README.md` / `README_EN.md`:新增「许可 / License」章节,写明 §13 的含义、
  插件因**静态链接 SDK 源码**而成为衍生作品须同许可发布、以及随包第三方组件清单
- `deploy/packaging/package-linux.sh`:
  · 新增 `stage_license()`,**四个变体(full/server/client/tar)全带**
    `/usr/share/doc/homeagent/{LICENSE,copyright}`(copyright 为 DEP-5 机器可读格式,
    含第三方条目)
  · fpm 的 `--license "Proprietary"` → `"AGPL-3.0-only"`
- `deploy/packaging/installer.nsi`:新增 MUI 许可页
  (`..\..\LICENSE`,NSIS 以 .nsi 所在目录解析相对路径)
- `third_party/homeagent-sdk/LICENSE`:vendored SDK 的许可一并入库 —— 本仓
  `.gitignore` 有意不镜像 SDK 的 README/tools/package/example,但依赖的许可
  应当随依赖可见

## 待办(下一步)

README 的「项目状态」仍停在 v1.1.1,且写着已被 v1.2.0 **删除**的机制
(引用计数式 GC、`[<mime> <digest>] <描述>` 描述式索引)——单独一个提交修。
2026-09-12 09:17:03 +08:00

358 lines
13 KiB
NSIS
Raw Permalink Blame History

This file contains ambiguous Unicode characters

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

!include "MUI2.nsh"
!include "nsDialogs.nsh"
!include "LogicLib.nsh"
!include "WinVer.nsh"
!include "x64.nsh"
!ifndef VARIANT
!define VARIANT "full"
!endif
!define PRODUCT_NAME "HomeAgent"
!define PRODUCT_PUBLISHER "HomeAgent Team"
# 版本号由 makensis -DPRODUCT_VERSION=X.Y.Z 注入;缺省值仅供本地手工构建。
# 此前硬编码 0.8.0 而 release 已到 1.0.0,装出来的包在「添加/删除程序」里
# 会显示错误版本DisplayVersion 也取自这个宏)。
!ifndef PRODUCT_VERSION
!define PRODUCT_VERSION "1.0.0"
!endif
!if "${VARIANT}" == "full"
!define PRODUCT_DISPLAY_NAME "HomeAgent 完整版"
!define OUTPUT_FILE "HomeAgent_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 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 HAS_CORE 0
!define HAS_WAITER 1
!define HAS_GUI 1
!define HAS_CREDENTIALS 0
!else
!error "Unknown variant: ${VARIANT}"
!endif
Name "${PRODUCT_DISPLAY_NAME}"
OutFile "..\..\build\${OUTPUT_FILE}"
InstallDir "$PROGRAMFILES64\${PRODUCT_NAME}"
InstallDirRegKey HKLM "Software\${PRODUCT_NAME}" ""
RequestExecutionLevel admin
BrandingText "HomeAgent Installer"
SetCompressor /SOLID lzma
ShowInstDetails show
ShowUninstDetails show
Var apiKey
Var webuiUsername
Var webuiPassword
Var hwndApiKey
Var hwndUsername
Var hwndPassword
Var autoStart
Var startNow
Var hwndAutoStart
Var hwndStartNow
Function GenKey
nsExec::ExecToStack 'powershell -NoProfile -C "[System.Guid]::NewGuid().ToString($\'N$\')"'
Pop $0
Pop $1
${If} $1 == ""
StrCpy $1 "homeagent"
${Else}
StrCpy $1 $1 32
${EndIf}
Push $1
FunctionEnd
!insertmacro MUI_PAGE_WELCOME
; 许可页AGPL-3.0-only全文在仓库根 LICENSE
; NSIS 的 File/!insertmacro 相对路径以**本 .nsi 所在目录**为基准解析,
; 而本文件在 deploy/packaging/,故仓库根是 ..\..\ 。
!insertmacro MUI_PAGE_LICENSE "..\..\LICENSE"
!insertmacro MUI_PAGE_DIRECTORY
!if "${HAS_CREDENTIALS}" == "1"
Page custom pageApiKeys pageApiKeysLeave
Page custom pageCredentials pageCredentialsLeave
!endif
!if "${HAS_CORE}" == "1"
Page custom pageStartupOptions pageStartupOptionsLeave
!endif
!insertmacro MUI_PAGE_INSTFILES
Page custom pageFinishSummary
!insertmacro MUI_LANGUAGE "SimpChinese"
!insertmacro MUI_LANGUAGE "English"
Function .onInit
!insertmacro MUI_LANGDLL_DISPLAY
StrCpy $autoStart "1"
StrCpy $startNow "1"
!if "${HAS_CREDENTIALS}" == "0"
Call GenKey
Pop $apiKey
!endif
FunctionEnd
!if "${HAS_CORE}" == "1"
Function pageStartupOptions
!insertmacro MUI_HEADER_TEXT "启动选项" "设置 HomeAgent 后端的启动方式"
nsDialogs::Create 1018
Pop $0
${If} $0 == error
Abort
${EndIf}
${NSD_CreateLabel} 0 5u 100% 20u "HomeAgent 后端 (homed) 是持续运行的服务进程。$\r$\n请选择启动方式:"
Pop $0
${NSD_CreateCheckBox} 10u 35u 100% 12u "开机自动启动后端 (添加到注册表启动项)"
Pop $hwndAutoStart
${If} $autoStart == "1"
${NSD_Check} $hwndAutoStart
${EndIf}
${NSD_CreateCheckBox} 10u 55u 100% 12u "安装完成后立即启动后端"
Pop $hwndStartNow
${If} $startNow == "1"
${NSD_Check} $hwndStartNow
${EndIf}
${NSD_CreateLabel} 10u 80u 100% 20u "如果选择开机自启动homed 将在每次登录 Windows 时自动运行。$\r$\n你也可以稍后从开始菜单手动启动。"
Pop $0
nsDialogs::Show
FunctionEnd
Function pageStartupOptionsLeave
${NSD_GetState} $hwndAutoStart $autoStart
${NSD_GetState} $hwndStartNow $startNow
FunctionEnd
!endif
!if "${HAS_CREDENTIALS}" == "1"
Function pageApiKeys
!insertmacro MUI_HEADER_TEXT "生成 API 密钥" "请复制此密钥,安装完成后将无法再次查看"
nsDialogs::Create 1018
Pop $0
${If} $0 == error
Abort
${EndIf}
Call GenKey
Pop $apiKey
${NSD_CreateLabel} 0 5u 100% 12u "API Key (用于 WebUI 和 GUI 认证):"
Pop $0
${NSD_CreateText} 0 20u 300u 12u $apiKey
Pop $hwndApiKey
${NSD_CreateLabel} 0 45u 100% 30u "请用鼠标选中文本框中的密钥并复制 (Ctrl+C)。$\r$\n此密钥同时用于:$\r$\n • Web 管理界面 (http://localhost:8080) 的 API 认证$\r$\n • 桌面 GUI 应用的自动连接配置"
Pop $0
nsDialogs::Show
FunctionEnd
Function pageApiKeysLeave
${NSD_GetText} $hwndApiKey $apiKey
FunctionEnd
Function pageCredentials
!insertmacro MUI_HEADER_TEXT "WebUI 登录设置" "设置 Web 管理界面的登录账号和密码"
nsDialogs::Create 1018
Pop $0
${If} $0 == error
Abort
${EndIf}
StrCpy $webuiUsername "admin"
${NSD_CreateLabel} 0 5u 70u 12u "用户名:"
Pop $0
${NSD_CreateText} 85u 5u 180u 12u $webuiUsername
Pop $hwndUsername
${NSD_CreateLabel} 0 25u 70u 12u "密码:"
Pop $0
${NSD_CreatePassword} 85u 25u 180u 12u ""
Pop $hwndPassword
${NSD_CreateLabel} 0 50u 100% 20u "这些凭证用于登录 Web 管理界面 http://localhost:8080"
Pop $0
nsDialogs::Show
FunctionEnd
Function pageCredentialsLeave
${NSD_GetText} $hwndUsername $webuiUsername
${NSD_GetText} $hwndPassword $webuiPassword
${If} $webuiPassword == ""
StrCpy $webuiPassword "homeagent"
${EndIf}
FunctionEnd
!endif
Function pageFinishSummary
!insertmacro MUI_HEADER_TEXT "安装完成" "以下为安装的关键信息,请截图或记录"
nsDialogs::Create 1018
Pop $0
${If} $0 == error
Abort
${EndIf}
${NSD_CreateLabel} 0 5u 100% 12u "API Key: $apiKey"
Pop $0
${NSD_CreateLabel} 0 20u 100% 12u "GUI 预配置: 已自动写入连接配置"
Pop $0
${NSD_CreateLabel} 0 35u 100% 12u "WebUI 地址: http://localhost:8080"
Pop $0
!if "${HAS_CREDENTIALS}" == "1"
${NSD_CreateLabel} 0 50u 100% 12u "WebUI 用户名: $webuiUsername"
Pop $0
${NSD_CreateLabel} 0 65u 100% 12u "WebUI 密码: $webuiPassword"
Pop $0
!endif
nsDialogs::Show
FunctionEnd
Section "Install" SEC_INSTALL
SetOutPath "$INSTDIR"
; WSL 引导脚本随安装包分发(它负责检测/引导 WSL 并把 Linux 包装进发行版)
File "..\..\deploy\packaging\windows\install-via-wsl.ps1"
CreateDirectory "$INSTDIR\data"
CreateDirectory "$INSTDIR\data\log"
CreateDirectory "$INSTDIR\data\plugins"
CreateDirectory "$INSTDIR\data\adapters"
; homed **不再装到 Windows**:插件体系依赖 fd 继承与统一共享内存区的段内偏移
; 解引用Windows 的句柄模型无法表达(见 cmd/homed/platform_windows.go
; Windows 侧改为引导到 WSL2把 **Linux 包**送进发行版里按 Linux 的方式安装。
; 所以这里带的是 linux/amd64 的 payload不是 homed.exe。
!if "${HAS_CORE}" == "1"
SetOutPath "$PLUGINSDIR\linux-payload"
File /r "..\..\build\linux-payload\*.*"
SetOutPath "$INSTDIR"
!endif
!if "${HAS_WAITER}" == "1"
; waiter 是 CLI 客户端WSL 侧会装上 Linux 版Windows 侧仍可保留原生版
; (它只是个客户端,不走插件体系)。
File "..\..\build\waiter.exe"
!endif
!if "${HAS_GUI}" == "1"
SetOutPath "$INSTDIR\homeagent-gui-win32-x64"
File /r "..\..\build\homeagent-gui-win32-x64\*.*"
SetOutPath "$INSTDIR"
!endif
!if "${HAS_CORE}" == "1"
; 在 WSL2 里安装 homed。凭据页面上收的那三个透传进去避免
; 「界面显示一份、config.db 里另一份」导致登录不上。
DetailPrint "检测 WSL 并在其中安装 HomeAgent..."
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
${If} $0 != 0
; 退出码含义见 install-via-wsl.ps120/21 是「WSL 或发行版缺失,需要先装」,
; 属于可指引的用户动作,不当成安装失败来恐吓人。
${If} $0 == 20
MessageBox MB_ICONINFORMATION|MB_OK "未检测到 WSL。$\r$\n$\r$\n请在管理员 PowerShell 中执行:$\r$\n wsl --install$\r$\n$\r$\n然后重启 Windows再重新运行本安装程序。"
${ElseIf} $0 == 21
MessageBox MB_ICONINFORMATION|MB_OK "WSL 已安装,但还没有发行版。$\r$\n$\r$\n请先执行$\r$\n wsl --install -d Ubuntu$\r$\n$\r$\n完成首次初始化后再重新运行本安装程序。"
${Else}
MessageBox MB_ICONEXCLAMATION|MB_OK "WSL 内安装失败(退出码 $0。$\r$\n$\r$\n可进入 WSL 手动排查wsl -d Ubuntu$\r$\n安装脚本输出见上方日志。"
${EndIf}
${Else}
DetailPrint "HomeAgent 已在 WSL2 内安装完成"
${EndIf}
!endif
!if "${HAS_GUI}" == "1"
DetailPrint "配置 GUI 连接..."
CreateDirectory "$APPDATA\homeagent-gui"
FileOpen $0 "$APPDATA\homeagent-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
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
!if "${HAS_WAITER}" == "1"
DetailPrint "配置 CLI 连接..."
FileOpen $0 "$INSTDIR\waiter.yaml" w
FileWrite $0 "socket: $\"$INSTDIR\data\cli.sock$\"$\r$\napi_key: $apiKey$\r$\ndefault: local$\r$\nconnections:$\r$\n - name: local$\r$\n socket: $\"$INSTDIR\data\cli.sock$\"$\r$\n api_key: $apiKey$\r$\n"
FileClose $0
!endif
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
!endif
!if "${HAS_WAITER}" == "1"
CreateShortCut "$SMPROGRAMS\${PRODUCT_NAME}\HomeAgent 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
!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"
!if "${HAS_CORE}" == "1"
${If} $autoStart == "1"
DetailPrint "设置开机自启动..."
WriteRegStr HKCU "Software\Microsoft\Windows\CurrentVersion\Run" "HomeAgent" '"$INSTDIR\homed.exe" -data "$INSTDIR\data"'
${EndIf}
!endif
DetailPrint "写入注册表..."
WriteRegStr HKLM "Software\${PRODUCT_NAME}" "" "$INSTDIR"
WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${PRODUCT_NAME}" "DisplayName" "${PRODUCT_DISPLAY_NAME}"
WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${PRODUCT_NAME}" "UninstallString" "$INSTDIR\Uninstall.exe"
WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${PRODUCT_NAME}" "InstallLocation" "$INSTDIR"
WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${PRODUCT_NAME}" "Publisher" "${PRODUCT_PUBLISHER}"
WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${PRODUCT_NAME}" "DisplayVersion" "${PRODUCT_VERSION}"
WriteRegDWORD HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${PRODUCT_NAME}" "NoModify" 1
WriteRegDWORD HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${PRODUCT_NAME}" "NoRepair" 1
WriteUninstaller "$INSTDIR\Uninstall.exe"
!if "${HAS_CORE}" == "1"
${If} $startNow == "1"
DetailPrint "启动 HomeAgent 后端..."
Exec '"$INSTDIR\homed.exe" -data "$INSTDIR\data"'
${EndIf}
!endif
SectionEnd
Section "Uninstall"
!if "${HAS_CORE}" == "1"
DeleteRegValue HKCU "Software\Microsoft\Windows\CurrentVersion\Run" "HomeAgent"
!endif
Delete "$INSTDIR\Uninstall.exe"
Delete "$INSTDIR\initconfig.exe"
Delete "$INSTDIR\homed.exe"
Delete "$INSTDIR\waiter.exe"
Delete "$INSTDIR\waiter.yaml"
RMDir /r "$INSTDIR\data"
RMDir /r "$INSTDIR\homeagent-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"
RMDir "$SMPROGRAMS\${PRODUCT_NAME}"
DeleteRegValue HKLM "SYSTEM\CurrentControlSet\Control\Session Manager\Environment" "HOMEAGENT_DATA"
DeleteRegValue HKLM "SYSTEM\CurrentControlSet\Control\Session Manager\Environment" "HOMEAGENT_SOCKET"
DeleteRegKey HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${PRODUCT_NAME}"
DeleteRegKey HKLM "Software\${PRODUCT_NAME}"
SectionEnd