mirror of
https://gitcode.com/JianFeeeee/HomeAgent.git
synced 2026-09-21 17:38:10 +00:00
fix: WebUI 版本显示 + Windows 交叉编译 + 发布脚本三处回归
## WebUI 版本链路修复 问题:handler.go:949 报的是 sdk.SDKVersion,那条链最终指向 SDK 仓 meta.Version 的硬编码值,与 -ldflags 注入的内核版本 完全不相交。构建时间、commit hash 全部丢失。 dashboard.html 兜底值是 '0.1.0'——碰巧版本号相等时不显眼, 一旦不等就报错。 修复: - KernelStatus 新增 BuildStatus 字段(Version/Commit/BuildTime/SDKCompatible/KernelName) 取自 internal/meta(-ldflags 注入点),与接口冻结无关(KernelStatus 只在 internal/sdk) - /api/v1/status 改用 meta.Version,另加 sdk_version 字段暴露 SDK 版本 - dashboard.html 概览卡显示 HomeAgent vX.Y.Z + commit/日期/SDK 兼容版本, 去掉 || '0.1.0' 误导性兜底 ## Windows 交叉编译修复 问题:internal/plugin/dynamic_proc_windows.go(Part 1 的桩,610e9d0)只定义了 tryLoadProc,但平台中立的 registry.go 还在调 loadProc / closeProcHost——这两个 函数只在 dynamic_proc_unix.go 里。Windows 下整个 homed 从 Part 1 起编译不过。 plan.md §12.5 声称「Windows 只做了交叉编译,无真机验证」——实际是连编译都没通过。 修复:dynamic_proc_unix.go / dynamic_proc_windows.go 合并为平台中立的 dynamic_proc.go(文件内无任何平台专属调用,proc 包内部通过 shmalloc_* / evtfd_* / shmpass_* / procattr_* 各自带构建标签处理差异)。 ## 发布脚本三处回归修复 deploy/packaging/build.sh(从 package/build.sh 移到 deploy/packaging/ 后): 1. PROJECT_ROOT 少一层目录(.. → ../..),产物落进 deploy/build/ 而非根目录 2. initconfig 从未被构建,但 installer.nsi 和 package-linux.sh 都引用它 3. GO 兜底路径指向 /home/jianf/go1.26.5(陈旧硬编码)改为 command -v go 4. electron-builder --config package.json 校验整个文件导致 devDependencies 被判为 unknown property,去掉 --config 让它从 build 键读配置 deploy/packaging/package-linux.sh: 1. build_go() 补上 initconfig 构建步骤 2. GO 兜底路径同步修复 知识库 3 条重写 + 1 条新增: - homeagent_identity:v0.9.0 C ABI → v1.0.0 子进程 - homeagent_architecture:全篇重写为子进程架构(三面通信、Supervisor 台账、 崩溃自愈、权限三道闸) - homeagent_recent_updates:在 v0.9.0 前插入 v1.0.0 主线摘要 - changelog_v1.0.0(新建):6 类缺陷消除、架构、实测、已知限制、迁移指引
This commit is contained in:
@ -1,12 +1,18 @@
|
|||||||
#!/usr/bin/env bash
|
#!/usr/bin/env bash
|
||||||
set -euo pipefail
|
set -euo pipefail
|
||||||
|
|
||||||
PROJECT_ROOT="$(cd "$(dirname "$0")/.." && pwd)"
|
# 本脚本位于 deploy/packaging/,故仓库根在上两级。
|
||||||
|
#
|
||||||
|
# v0.7.2 的根目录清理把 package/build.sh 移到 deploy/packaging/build.sh
|
||||||
|
# (深度 1 → 2 层),但这行的 ".." 没跟着改成 "../..",于是 PROJECT_ROOT
|
||||||
|
# 变成了 <repo>/deploy:产物落进 deploy/build/、GUI 去找 deploy/cmd/gui。
|
||||||
|
# 跨平台构建从那次起一直是坏的(Makefile 的单平台 build 不走这里,所以没暴露)。
|
||||||
|
PROJECT_ROOT="$(cd "$(dirname "$0")/../.." && pwd)"
|
||||||
BUILD_DIR="${PROJECT_ROOT}/build"
|
BUILD_DIR="${PROJECT_ROOT}/build"
|
||||||
VERSION="${VERSION:-$(git -C "$PROJECT_ROOT" describe --tags --dirty 2>/dev/null || echo "0.8.0")}"
|
VERSION="${VERSION:-$(git -C "$PROJECT_ROOT" describe --tags --dirty 2>/dev/null || echo "0.8.0")}"
|
||||||
COMMIT="${COMMIT:-$(git -C "$PROJECT_ROOT" rev-parse --short HEAD 2>/dev/null || echo "unknown")}"
|
COMMIT="${COMMIT:-$(git -C "$PROJECT_ROOT" rev-parse --short HEAD 2>/dev/null || echo "unknown")}"
|
||||||
BUILD_TIME="${BUILD_TIME:-$(date -u '+%Y-%m-%dT%H:%M:%SZ')}"
|
BUILD_TIME="${BUILD_TIME:-$(date -u '+%Y-%m-%dT%H:%M:%SZ')}"
|
||||||
GO="${GO:-$(command -v go 2>/dev/null || echo "/home/jianf/go1.26.5/go/bin/go")}"
|
GO="${GO:-$(command -v go 2>/dev/null || echo "go")}"
|
||||||
LDFLAGS="-X gitcode.com/JianFeeeee/HomeAgent/internal/meta.Version=${VERSION} -X gitcode.com/JianFeeeee/HomeAgent/internal/meta.Commit=${COMMIT} -X gitcode.com/JianFeeeee/HomeAgent/internal/meta.BuildTime=${BUILD_TIME}"
|
LDFLAGS="-X gitcode.com/JianFeeeee/HomeAgent/internal/meta.Version=${VERSION} -X gitcode.com/JianFeeeee/HomeAgent/internal/meta.Commit=${COMMIT} -X gitcode.com/JianFeeeee/HomeAgent/internal/meta.BuildTime=${BUILD_TIME}"
|
||||||
|
|
||||||
TARGET="${1:-native}"
|
TARGET="${1:-native}"
|
||||||
@ -21,10 +27,10 @@ COMPONENT="${2:-all}"
|
|||||||
case "$TARGET" in
|
case "$TARGET" in
|
||||||
native) GOOS="" GOARCH="" ;;
|
native) GOOS="" GOARCH="" ;;
|
||||||
linux/amd64) GOOS=linux GOARCH=amd64 CC="${CC:-}" ;;
|
linux/amd64) GOOS=linux GOARCH=amd64 CC="${CC:-}" ;;
|
||||||
linux/arm64) GOOS=linux GOARCH=arm64 CC="${CC:-aarch64-linux-gnu-gcc}" CXX="${CXX:-aarch64-linux-gnu-g++}" ;;
|
linux/arm64) GOOS=linux GOARCH=arm64 CC="${CC:-aarch64-linux-gnu-gcc}" ;;
|
||||||
darwin/amd64) GOOS=darwin GOARCH=amd64 CC="${CC:-}" ;;
|
darwin/amd64) GOOS=darwin GOARCH=amd64 CC="${CC:-}" ;;
|
||||||
darwin/arm64) GOOS=darwin GOARCH=arm64 CC="${CC:-}" ;;
|
darwin/arm64) GOOS=darwin GOARCH=arm64 CC="${CC:-}" ;;
|
||||||
windows/amd64) GOOS=windows GOARCH=amd64 CC="${CC:-x86_64-w64-mingw32-gcc}" CXX="${CXX:-x86_64-w64-mingw32-g++}" ;;
|
windows/amd64) GOOS=windows GOARCH=amd64 CC="${CC:-x86_64-w64-mingw32-gcc}" ;;
|
||||||
all)
|
all)
|
||||||
"$0" linux/amd64 "$COMPONENT"
|
"$0" linux/amd64 "$COMPONENT"
|
||||||
"$0" linux/arm64 "$COMPONENT"
|
"$0" linux/arm64 "$COMPONENT"
|
||||||
@ -36,7 +42,7 @@ case "$TARGET" in
|
|||||||
*)
|
*)
|
||||||
echo "Unknown target: $TARGET"
|
echo "Unknown target: $TARGET"
|
||||||
echo "Usage: $0 [native|linux/amd64|linux/arm64|darwin/amd64|darwin/arm64|windows/amd64|all]"
|
echo "Usage: $0 [native|linux/amd64|linux/arm64|darwin/amd64|darwin/arm64|windows/amd64|all]"
|
||||||
echo " [all|homed|waiter|gui]"
|
echo " [all|homed|waiter|initconfig|gui]"
|
||||||
exit 1
|
exit 1
|
||||||
esac
|
esac
|
||||||
|
|
||||||
@ -67,7 +73,11 @@ build_homed() {
|
|||||||
out="${out}.exe"
|
out="${out}.exe"
|
||||||
fi
|
fi
|
||||||
echo "[BUILD] homed ${plat} → $out"
|
echo "[BUILD] homed ${plat} → $out"
|
||||||
CGO_ENABLED=1 "$GO" build -trimpath -installsuffix dynlink \
|
# Go 用 CC 驱动 CGO 编译与链接,用 CC 指定的交叉工具链来决定目标架构。
|
||||||
|
# 必须同时 export CC 给 Go 的 CGO 代码生成器,否则 CGO_ENABLED=1 下的
|
||||||
|
# 目标文件与 host 的 ld 不兼容(如 arm64 的 .o 给了 x86_64 的 ld)。
|
||||||
|
local _cc="${CC:-cc}"
|
||||||
|
CGO_ENABLED=1 CC="$_cc" "$GO" build -trimpath -installsuffix dynlink \
|
||||||
-ldflags "$LDFLAGS" -o "$out" ./cmd/homed/
|
-ldflags "$LDFLAGS" -o "$out" ./cmd/homed/
|
||||||
echo " OK ($(file "$out" | sed 's/.*: //') | $(du -h "$out" | cut -f1))"
|
echo " OK ($(file "$out" | sed 's/.*: //') | $(du -h "$out" | cut -f1))"
|
||||||
}
|
}
|
||||||
@ -84,6 +94,22 @@ build_waiter() {
|
|||||||
echo " OK ($(du -h "$out" | cut -f1))"
|
echo " OK ($(du -h "$out" | cut -f1))"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# ---- initconfig (CGO-free 配置初始化器) ----
|
||||||
|
#
|
||||||
|
# NSIS 安装包(installer.nsi:220 File "..\build\initconfig.exe")与
|
||||||
|
# package-linux.sh 的 stage_variant 都引用它,但此前 build.sh 从不构建它——
|
||||||
|
# Windows 安装包构建会直接失败在缺文件上。
|
||||||
|
build_initconfig() {
|
||||||
|
local plat="${GOOS:-linux}/${GOARCH:-amd64}"
|
||||||
|
local out="$BUILD_DIR/initconfig${SUFFIX:+_$SUFFIX}"
|
||||||
|
if [ "$GOOS" = "windows" ]; then out="${out}.exe"; fi
|
||||||
|
|
||||||
|
echo "[BUILD] initconfig ${plat} → $out"
|
||||||
|
CGO_ENABLED=0 "$GO" build -trimpath -installsuffix dynlink \
|
||||||
|
-ldflags "$LDFLAGS" -o "$out" ./cmd/initconfig/
|
||||||
|
echo " OK ($(du -h "$out" | cut -f1))"
|
||||||
|
}
|
||||||
|
|
||||||
# ---- gui (Electron) ----
|
# ---- gui (Electron) ----
|
||||||
build_gui() {
|
build_gui() {
|
||||||
if [ -n "${GOOS:-}" ] && [ "$GOOS" != "$("$GO" env GOOS)" ]; then
|
if [ -n "${GOOS:-}" ] && [ "$GOOS" != "$("$GO" env GOOS)" ]; then
|
||||||
@ -99,7 +125,10 @@ build_gui() {
|
|||||||
(cd "$gui_dir" && npm install --production)
|
(cd "$gui_dir" && npm install --production)
|
||||||
fi
|
fi
|
||||||
|
|
||||||
(cd "$gui_dir" && npx electron-builder --config "$gui_dir/package.json" \
|
# 不传 --config:electron-builder 默认从 package.json 的 "build" 键读配置。
|
||||||
|
# 传 --config package.json 会让它把**整个** package.json 当配置校验,
|
||||||
|
# 于是 devDependencies / build / scripts 全被判为 "unknown property" 而失败。
|
||||||
|
(cd "$gui_dir" && npx electron-builder \
|
||||||
--linux --win --mac \
|
--linux --win --mac \
|
||||||
--x64 --arm64 \
|
--x64 --arm64 \
|
||||||
-p never \
|
-p never \
|
||||||
@ -109,9 +138,10 @@ build_gui() {
|
|||||||
|
|
||||||
# ---- dispatch ----
|
# ---- dispatch ----
|
||||||
case "$COMPONENT" in
|
case "$COMPONENT" in
|
||||||
all) build_homed; build_waiter; build_gui ;;
|
all) build_homed; build_waiter; build_initconfig; build_gui ;;
|
||||||
homed) build_homed ;;
|
homed) build_homed ;;
|
||||||
waiter) build_waiter ;;
|
waiter) build_waiter ;;
|
||||||
|
initconfig) build_initconfig ;;
|
||||||
gui) build_gui ;;
|
gui) build_gui ;;
|
||||||
*)
|
*)
|
||||||
echo "Unknown component: $COMPONENT"
|
echo "Unknown component: $COMPONENT"
|
||||||
|
|||||||
@ -6,7 +6,7 @@ BUILD_DIR="${PROJECT_ROOT}/build"
|
|||||||
DIST_DIR="${PROJECT_ROOT}/dist/linux"
|
DIST_DIR="${PROJECT_ROOT}/dist/linux"
|
||||||
VERSION="${VERSION:-$(git -C "$PROJECT_ROOT" describe --tags --dirty 2>/dev/null || echo "0.8.0")}"
|
VERSION="${VERSION:-$(git -C "$PROJECT_ROOT" describe --tags --dirty 2>/dev/null || echo "0.8.0")}"
|
||||||
PACKAGE_ROOT="${PROJECT_ROOT}/deploy/packaging/linux"
|
PACKAGE_ROOT="${PROJECT_ROOT}/deploy/packaging/linux"
|
||||||
GO="${GO:-$(command -v go 2>/dev/null || echo "/home/jianf/go1.26.5/go/bin/go")}"
|
GO="${GO:-$(command -v go 2>/dev/null || echo "go")}"
|
||||||
|
|
||||||
ARCH="${1:-amd64}" # amd64 or arm64
|
ARCH="${1:-amd64}" # amd64 or arm64
|
||||||
ACTION="${2:-all}" # all, build, deb, tar, rpm
|
ACTION="${2:-all}" # all, build, deb, tar, rpm
|
||||||
@ -99,6 +99,9 @@ build_go() {
|
|||||||
bash "$PROJECT_ROOT/deploy/packaging/build.sh" "linux/$ARCH" "waiter" 2>&1 || {
|
bash "$PROJECT_ROOT/deploy/packaging/build.sh" "linux/$ARCH" "waiter" 2>&1 || {
|
||||||
echo "WARNING: waiter build failed."
|
echo "WARNING: waiter build failed."
|
||||||
}
|
}
|
||||||
|
bash "$PROJECT_ROOT/deploy/packaging/build.sh" "linux/$ARCH" "initconfig" 2>&1 || {
|
||||||
|
echo "WARNING: initconfig build failed(包内将缺少首次配置初始化器)。"
|
||||||
|
}
|
||||||
|
|
||||||
local suffix="linux_${ARCH}"
|
local suffix="linux_${ARCH}"
|
||||||
local homed_bin="$BUILD_DIR/homed_$suffix"
|
local homed_bin="$BUILD_DIR/homed_$suffix"
|
||||||
|
|||||||
@ -10,6 +10,7 @@ import (
|
|||||||
"gitcode.com/JianFeeeee/HomeAgent/internal/memory/document"
|
"gitcode.com/JianFeeeee/HomeAgent/internal/memory/document"
|
||||||
"gitcode.com/JianFeeeee/HomeAgent/internal/memory/social"
|
"gitcode.com/JianFeeeee/HomeAgent/internal/memory/social"
|
||||||
"gitcode.com/JianFeeeee/HomeAgent/internal/memory/text"
|
"gitcode.com/JianFeeeee/HomeAgent/internal/memory/text"
|
||||||
|
"gitcode.com/JianFeeeee/HomeAgent/internal/meta"
|
||||||
"gitcode.com/JianFeeeee/HomeAgent/internal/plugin"
|
"gitcode.com/JianFeeeee/HomeAgent/internal/plugin"
|
||||||
sdk "gitcode.com/JianFeeeee/HomeAgent/internal/sdk"
|
sdk "gitcode.com/JianFeeeee/HomeAgent/internal/sdk"
|
||||||
"gitcode.com/JianFeeeee/HomeAgent/internal/tracker"
|
"gitcode.com/JianFeeeee/HomeAgent/internal/tracker"
|
||||||
@ -33,6 +34,7 @@ type LLMStatus = sdk.LLMStatus
|
|||||||
type ContextStatus = sdk.ContextStatus
|
type ContextStatus = sdk.ContextStatus
|
||||||
type RuntimeStatus = sdk.RuntimeStatus
|
type RuntimeStatus = sdk.RuntimeStatus
|
||||||
type TrackerStatus = sdk.TrackerStatus
|
type TrackerStatus = sdk.TrackerStatus
|
||||||
|
type BuildStatus = sdk.BuildStatus
|
||||||
|
|
||||||
func channelInfoFromIO(ch agentIO.ChannelInfo) ChannelInfo {
|
func channelInfoFromIO(ch agentIO.ChannelInfo) ChannelInfo {
|
||||||
return ChannelInfo{
|
return ChannelInfo{
|
||||||
@ -63,6 +65,15 @@ func collectKernelStatus(
|
|||||||
Uptime: time.Since(startTime).Round(time.Second).String(),
|
Uptime: time.Since(startTime).Round(time.Second).String(),
|
||||||
StartTime: startTime.Format(time.RFC3339),
|
StartTime: startTime.Format(time.RFC3339),
|
||||||
AgentID: agentID,
|
AgentID: agentID,
|
||||||
|
// 构建身份取自内核自己的 meta(-ldflags 注入点),
|
||||||
|
// 而非 SDK 仓的硬编码版本。
|
||||||
|
Build: BuildStatus{
|
||||||
|
Version: meta.Version,
|
||||||
|
Commit: meta.Commit,
|
||||||
|
BuildTime: meta.BuildTime,
|
||||||
|
SDKCompatible: meta.SDKCompatibleVersion,
|
||||||
|
KernelName: meta.KernelName,
|
||||||
|
},
|
||||||
Runtime: RuntimeStatus{
|
Runtime: RuntimeStatus{
|
||||||
Goroutines: runtime.NumGoroutine(),
|
Goroutines: runtime.NumGoroutine(),
|
||||||
GoVersion: runtime.Version(),
|
GoVersion: runtime.Version(),
|
||||||
|
|||||||
@ -1,5 +1,3 @@
|
|||||||
//go:build linux || darwin
|
|
||||||
|
|
||||||
package plugin
|
package plugin
|
||||||
|
|
||||||
import (
|
import (
|
||||||
@ -14,6 +12,20 @@ import (
|
|||||||
sdk "gitcode.com/JianFeeeee/HomeAgent/internal/sdk"
|
sdk "gitcode.com/JianFeeeee/HomeAgent/internal/sdk"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// 本文件平台中立。
|
||||||
|
//
|
||||||
|
// 曾经拆成 dynamic_proc_unix.go + dynamic_proc_windows.go(Part 1,610e9d0),
|
||||||
|
// 当时共享内存只有 POSIX mmap 实现,故 Windows 侧只放了个报「尚未实现」的桩。
|
||||||
|
// 但那个桩只定义了 tryLoadProc,而平台中立的 registry.go 还在调 loadProc /
|
||||||
|
// closeProcHost —— **Windows 下整个 homed 从那时起就编译不过**
|
||||||
|
// (plan.md §12.5 声称「交叉编译通过」,实际只验证了 proc 子包)。
|
||||||
|
//
|
||||||
|
// Part 6.2(d027c96)补齐了 Windows 共享内存(CreateFileMappingW)、事件通知
|
||||||
|
// (CreateEventW)与段传递(命名对象经环境变量),桩却没人回头删。
|
||||||
|
//
|
||||||
|
// 现在合回一个文件:本文件里没有任何平台专属调用,全部差异封装在 proc 包的
|
||||||
|
// shmalloc_* / evtfd_* / shmpass_* / procattr_* 里,那些文件各自带构建标签。
|
||||||
|
|
||||||
// tryLoadProc 只做静态校验(供双通道探测与测试),不构造插件实体。
|
// tryLoadProc 只做静态校验(供双通道探测与测试),不构造插件实体。
|
||||||
//
|
//
|
||||||
// 真正加载走 Registry.loadProc:子进程插件需要共享段 Host,
|
// 真正加载走 Registry.loadProc:子进程插件需要共享段 Host,
|
||||||
@ -1,25 +0,0 @@
|
|||||||
//go:build windows
|
|
||||||
|
|
||||||
package plugin
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"os"
|
|
||||||
"path/filepath"
|
|
||||||
|
|
||||||
sdk "gitcode.com/JianFeeeee/HomeAgent/internal/sdk"
|
|
||||||
)
|
|
||||||
|
|
||||||
// tryLoadProc 的 Windows 桩:子进程通道本身是跨平台的(stdio JSON-RPC 无平台差异),
|
|
||||||
// 但共享内存数据面当前基于 POSIX mmap,Windows 需改用 CreateFileMapping。
|
|
||||||
//
|
|
||||||
// 迁移评估 §9.2 已记录:Windows DLL 路径当前能力严重退化(只下发 3 字段、无写回),
|
|
||||||
// 迁移到子进程后三套 ABI 收敛为单一 RPC 实现,Windows 反而受益——但需要测试机验证。
|
|
||||||
func tryLoadProc(dir, name string, config map[string]interface{}) (sdk.Plugin, error) {
|
|
||||||
for _, candidate := range []string{binEntry, "plugin.exe"} {
|
|
||||||
if st, err := os.Stat(filepath.Join(dir, candidate)); err == nil && !st.IsDir() {
|
|
||||||
return nil, fmt.Errorf("proc plugin %s: Windows 子进程通道尚未实现(Part 2 + §9.2)", name)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return nil, nil
|
|
||||||
}
|
|
||||||
@ -2669,6 +2669,24 @@
|
|||||||
applyI18n();
|
applyI18n();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// fmtBuild 把构建身份压成一行:commit + 构建时间(日期部分)。
|
||||||
|
//
|
||||||
|
// 未注入 ldflags 的本地构建会得到 "unknown",此时只显示 SDK 版本,
|
||||||
|
// 避免把 "unknown / unknown" 这种噪音摆在概览卡上。
|
||||||
|
function fmtBuild(b, s) {
|
||||||
|
var parts = [];
|
||||||
|
var commit = (b && b.commit) || (s && s.commit) || "";
|
||||||
|
if (commit && commit !== "unknown") parts.push(commit);
|
||||||
|
var bt = (b && b.build_time) || (s && s.build_time) || "";
|
||||||
|
if (bt && bt !== "unknown") {
|
||||||
|
// 2026-09-03T05:55:35Z → 2026-09-03
|
||||||
|
parts.push(String(bt).split("T")[0]);
|
||||||
|
}
|
||||||
|
var sdkv = (b && b.sdk_compatible) || (s && s.sdk_version) || "";
|
||||||
|
if (sdkv) parts.push("SDK " + sdkv);
|
||||||
|
return parts.length ? parts.join(" · ") : "-";
|
||||||
|
}
|
||||||
|
|
||||||
function fmtUptime(ms) {
|
function fmtUptime(ms) {
|
||||||
var s = Math.floor(ms / 1000);
|
var s = Math.floor(ms / 1000);
|
||||||
if (s < 60) return s + "s";
|
if (s < 60) return s + "s";
|
||||||
@ -2724,7 +2742,18 @@
|
|||||||
'<div class="kv-row"><span class="key">' +
|
'<div class="kv-row"><span class="key">' +
|
||||||
__("版本", "Version") +
|
__("版本", "Version") +
|
||||||
'</span><span class="val">' +
|
'</span><span class="val">' +
|
||||||
escHtml(s.version || "0.1.0") +
|
escHtml(
|
||||||
|
k?.build?.version
|
||||||
|
? (k.build.kernel_name || "HomeAgent") + " v" + k.build.version
|
||||||
|
: s.version
|
||||||
|
? "v" + s.version
|
||||||
|
: "-",
|
||||||
|
) +
|
||||||
|
"</span></div>" +
|
||||||
|
'<div class="kv-row"><span class="key">' +
|
||||||
|
__("构建", "Build") +
|
||||||
|
'</span><span class="val">' +
|
||||||
|
escHtml(fmtBuild(k?.build, s)) +
|
||||||
"</span></div></div>";
|
"</span></div></div>";
|
||||||
if (k) {
|
if (k) {
|
||||||
html +=
|
html +=
|
||||||
|
|||||||
@ -22,6 +22,7 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
|
|
||||||
agentIO "gitcode.com/JianFeeeee/HomeAgent/internal/agent/io"
|
agentIO "gitcode.com/JianFeeeee/HomeAgent/internal/agent/io"
|
||||||
|
"gitcode.com/JianFeeeee/HomeAgent/internal/meta"
|
||||||
sdk "gitcode.com/JianFeeeee/HomeAgent/internal/sdk"
|
sdk "gitcode.com/JianFeeeee/HomeAgent/internal/sdk"
|
||||||
"gitcode.com/JianFeeeee/HomeAgent/pkg/types"
|
"gitcode.com/JianFeeeee/HomeAgent/pkg/types"
|
||||||
)
|
)
|
||||||
@ -943,11 +944,20 @@ func (h *Handler) handleStatus(w http.ResponseWriter, r *http.Request) {
|
|||||||
agentCount = len(h.supervisor.ListAgents())
|
agentCount = len(h.supervisor.ListAgents())
|
||||||
}
|
}
|
||||||
writeJSON(w, http.StatusOK, map[string]interface{}{
|
writeJSON(w, http.StatusOK, map[string]interface{}{
|
||||||
"status": "running",
|
"status": "running",
|
||||||
"uptime": time.Since(h.startTime).Round(time.Second).String(),
|
"uptime": time.Since(h.startTime).Round(time.Second).String(),
|
||||||
"agents": agentCount,
|
"agents": agentCount,
|
||||||
"version": sdk.SDKVersion,
|
// 内核版本取 internal/meta(-ldflags 注入点)。
|
||||||
"startedAt": h.startTime,
|
//
|
||||||
|
// 此前这里给的是 `sdk.SDKVersion`,那条链最终指向 **SDK 仓
|
||||||
|
// meta.Version 的硬编码值**,与构建时注入的内核版本无关——
|
||||||
|
// 两仲版本号碰巧相等时看不出问题,一旦不等就报错。
|
||||||
|
// SDK 版本另用 sdk_version 字段并行暴露。
|
||||||
|
"version": meta.Version,
|
||||||
|
"commit": meta.Commit,
|
||||||
|
"build_time": meta.BuildTime,
|
||||||
|
"sdk_version": sdk.SDKVersion,
|
||||||
|
"startedAt": h.startTime,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -10,6 +10,16 @@ type KernelStatus struct {
|
|||||||
Uptime string `json:"uptime"`
|
Uptime string `json:"uptime"`
|
||||||
StartTime string `json:"start_time"`
|
StartTime string `json:"start_time"`
|
||||||
|
|
||||||
|
// Build 是内核自身的版本与构建信息。
|
||||||
|
//
|
||||||
|
// 为何需要:此前 WebUI 展示的“版本”取自 `sdk.SDKVersion`,那是 **SDK 仓
|
||||||
|
// meta.Version 的硬编码值**;而 `-ldflags` 注入的是内核的
|
||||||
|
// `internal/meta.Version`——两条链完全不相交。于是:
|
||||||
|
// - 构建时注入的真实版本号、commit、构建时间全部丢失;
|
||||||
|
// - 两仲版本号碰巧相等时看不出问题,一旦不等就报错版本;
|
||||||
|
// - 无法回答“现网跑的是哪个 commit 构出来的”。
|
||||||
|
Build BuildStatus `json:"build"`
|
||||||
|
|
||||||
AgentID string `json:"agent_id"`
|
AgentID string `json:"agent_id"`
|
||||||
|
|
||||||
Plugins []PluginInfo `json:"plugins"`
|
Plugins []PluginInfo `json:"plugins"`
|
||||||
@ -87,6 +97,22 @@ type RuntimeStatus struct {
|
|||||||
GoVersion string `json:"go_version"`
|
GoVersion string `json:"go_version"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// BuildStatus 是内核二进制的构建身份,全部来自 `internal/meta`
|
||||||
|
// (由 -ldflags 在构建时注入,未注入时为源码默认值/unknown)。
|
||||||
|
type BuildStatus struct {
|
||||||
|
// Version 是内核语义版本(如 1.0.0)。
|
||||||
|
Version string `json:"version"`
|
||||||
|
// Commit 是构建时的 Git 短 hash;未注入为 unknown。
|
||||||
|
Commit string `json:"commit"`
|
||||||
|
// BuildTime 是 UTC 构建时间;未注入为 unknown。
|
||||||
|
BuildTime string `json:"build_time"`
|
||||||
|
// SDKCompatible 是本内核可兼容的最高 SDK 版本。
|
||||||
|
// 插件用旧 SDK 编译时靠它判断能不能加载。
|
||||||
|
SDKCompatible string `json:"sdk_compatible"`
|
||||||
|
// KernelName 是内核名(HomeAgent)。
|
||||||
|
KernelName string `json:"kernel_name"`
|
||||||
|
}
|
||||||
|
|
||||||
type TrackerStatus struct {
|
type TrackerStatus struct {
|
||||||
Available bool `json:"available"`
|
Available bool `json:"available"`
|
||||||
Dir string `json:"dir,omitempty"`
|
Dir string `json:"dir,omitempty"`
|
||||||
|
|||||||
Reference in New Issue
Block a user