Files
HomeAgent/deploy/packaging/package-windows.sh
JianFeeeee f256098c9f refactor: 全面改名为 HologramAgent + 提示词技术内容下沉到 skill/工具描述 + 修 21 处乱码
## ① 全面改名 HomeAgent → HologramAgent

仓库已改名,但代码与文档里仍有大量旧名。本次按"用户能看到的优先"全量替换:

- 用户可见:登录页标题/页脚、默认人格第一句、CLI 状态输出、启动日志、
  plugin_install 的工具描述、AI 图片插件的 User-Agent
- 文档与脚本:README、assets/docs、docs/zh、deploy/*.sh、.github/workflows
- 鸿蒙工程:cmd/ohos/HomeAgent → cmd/ohos/HologramAgent(git mv)
  目录内的 module/app 描述同步;**证书路径原样保留**
  (default_HomeAgent_xxx.cer/p7b/p12 是签名材料的实际文件名,改了会找不到证书)
- 插件元数据:plugin.json 的 author

★ 必须保持原样的两处(改了会坏):
  · legacySeededPromptSignature = "你是 HomeAgent 的看板娘「小宅」…"
    —— 那是识别历史播种人格卡的**原文锚点**,改了就识别不出旧数据
  · 公开 SDK 的 ProxyAuthHomeAgent = "homeagent"
    —— 那是 SDK 契约里的值,属独立仓库,本仓不改

## ② 修 21 处乱码(U+FFFD)

这些是历史编辑留下的编码破坏,全在注释里,例如:
  「赌注重下���遍」→「赌注重下一遍」
  「「不��滤」」  →「「不过滤」」
  「**待��退场**」→「**待退场**」

★ 保留 providers/chineseclip/tokenizer.go 里的 2 处:那是**故意**用
  U+FFFD 演示"非法 UTF-8 字节被归一成 U+FFFD",不是乱码。

## ③ 提示词技术内容下沉(用户:技术性内容应该收敛到 skill 与 -help 中)

实测系统提示词 2309 字,其中两段几乎全是**模型无法据以行动的实现细节**:

  【工具执行顺序】1272 字(ParallelSafe 声明、批内降级、batchRunnable 判据…)
  【三层记忆】   1069 字(L1/L2/L3 编号、消费式删除、向量空间、指纹…)

收敛后 **2309 → 1723 字(-25%)**,保留的全是"模型据此做什么不同的事":

  工具顺序:默认并行 / 不要依赖先后 / 同通道保序 / 写类工具可能串行
  三层记忆:时序里能看最近 / doc_query 把历史事件按原始时间戳插回时序 /
           关系用 memory_recall / 成文知识用 knowledge_search

判断口径写进判据:新加一段提示词前先问"模型会据此做什么不同的事",
答不上来就该进 skill 或工具描述。

## 判据

prompt_memory_test.go 新增 2 条:
- TestSystemPromptHasNoImplementationJargon
  黑名单:ParallelSafe / batchRunnable / 消费式 / DenseCosine / fingerprint /
  向量空间 / 批内降级 / 自激
- TestSystemPromptStaysCompact:上限 2000 字(当前 1723)

变异:把 "ParallelSafe 声明、批内降级" 加回工具顺序段 ⇒ 第一条立刻红。

## 验证

- go build ./... / go vet ./... 干净
- go test ./... -count=1:58 包 0 失败
- make check-client-versions:客户端与内核版本一致
2026-10-22 20:49:44 +08:00

152 lines
7.5 KiB
Bash
Raw 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.

#!/usr/bin/env bash
# 构建 Windows 安装器(NSIS)。
#
# ❗安装器**不往 Windows 装 homed**:homed 依赖 fd 继承与统一共享内存区的段内偏移
# 解引用,Windows 句柄模型无法表达(见 cmd/homed/platform_windows.go)。所以安装器的
# 职责是**引导 WSL2,并把 Linux 包送进发行版里按 Linux 方式安装**
# (deploy/packaging/windows/install-via-wsl.ps1)。
#
# 用法: VERSION=1.3.10 bash deploy/packaging/package-windows.sh <server|client|full> [arch]
# 前置: 先产出对应的 Linux 包(VERSION=x bash deploy/packaging/package-linux.sh amd64)
#
# 为什么不复用 build.sh 的 stage_linux_payload:那一段把 dist/linux 下**所有** deb+tar
# 都塞进 payload,而 server/full 的 deb 各带 ~719MB 的 Chinese-CLIP 模型 ⇒ 任何变体的
# 安装器都会膨胀到 ~2.4GB。WSL 侧脚本只取 payload 里的**第一个** .deb
# (install-via-wsl.ps1:141),所以这里按变体只放对应的那一个包。
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,避免"脚本不存在"或产物错位。
BUILD_DIR="${BUILD_DIR:-$PROJECT_ROOT/build}"
DIST_LINUX="${DIST_LINUX:-$PROJECT_ROOT/dist/linux}"
DIST_RELEASE="${DIST_RELEASE:-$PROJECT_ROOT/dist/release}"
# ❗NSIS 的 `File` 路径是**相对 .nsi 所在目录**解析的:在 tag 的 worktree 里构建时,
# 必须用**该 tag 里的** installer.nsi,否则它会去主仓的 build/linux-payload 找载荷
# (实测报 `File: "..\..\build\linux-payload\*.*" -> no files found`)。
# 用 tag 里的 .nsi 也正是"发布件与当时的脚本同源"的正确做法。
NSI="${NSI:-$PROJECT_ROOT/deploy/packaging/installer.nsi}"
if [ ! -f "$NSI" ]; then
echo "[FAIL] 找不到 NSIS 脚本: $NSI" >&2
exit 1
fi
VARIANT="${1:-server}"
ARCH="${2:-amd64}"
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="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
DEB="$(ls -1 "$DIST_LINUX/deb/$DEB_GLOB" "$DIST_LINUX/$DEB_GLOB" 2>/dev/null | head -1 || true)"
if [ -z "$DEB" ]; then
echo "[FAIL] 找不到 $DEB_GLOB" >&2
echo " 先产出 Linux 包:VERSION=$VERSION bash deploy/packaging/package-linux.sh $ARCH" >&2
echo " (安装器的作用是把 Linux 包送进 WSL2,所以必须先有 Linux 包)" >&2
exit 1
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=HologramAgent)
# ⇒ 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
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
echo "[BUILD] waiter.exe(Windows 侧 CLI;CGO 关闭,跨平台安全)"
( cd "$PROJECT_ROOT" && GOOS=windows GOARCH="$ARCH" CGO_ENABLED=0 \
go build -buildvcs=false -trimpath -o "$BUILD_DIR/waiter.exe" ./cmd/waiter )
fi
# ---- 变体定向 payload:只放本变体那一个 Linux 包 ----
rm -rf "$BUILD_DIR/linux-payload"
mkdir -p "$BUILD_DIR/linux-payload"
cp "$DEB" "$BUILD_DIR/linux-payload/"
echo "[STAGE] payload ← $(basename "$DEB")($(du -h "$DEB" | cut -f1))"
if [ -z "$(ls -1 "$BUILD_DIR/linux-payload" 2>/dev/null | head -1 || true)" ]; then
echo "[FAIL] payload 为空:$BUILD_DIR/linux-payload" >&2
exit 1
fi
echo "[BUILD] makensis -DVARIANT=$VARIANT -DPRODUCT_VERSION=$VERSION(nsi: $NSI)"
makensis -V2 -DVARIANT="$VARIANT" -DPRODUCT_VERSION="$VERSION" "$NSI"
OUT="$BUILD_DIR/HologramAgent_v${VERSION}_${SUFFIX}_win64.exe"
if [ ! -f "$OUT" ]; then
echo "[FAIL] 未找到产物 $OUT" >&2
exit 1
fi
mkdir -p "$DIST_RELEASE"
cp "$OUT" "$DIST_RELEASE/"
echo "[OK] $(basename "$OUT")($(du -h "$OUT" | cut -f1))→ $DIST_RELEASE/"
echo " 它会在 Windows 侧引导 WSL2,并把 $(basename "$DEB") 送进去安装(homed 跑在 WSL 里)。"