From 2c7ab6a187f70f8152c65277e49d5bbc2492d9be Mon Sep 17 00:00:00 2001 From: JianFeeeee Date: Sat, 12 Sep 2026 09:41:06 +0800 Subject: [PATCH] =?UTF-8?q?feat(status):=20=E6=9A=B4=E9=9C=B2=E6=9E=84?= =?UTF-8?q?=E5=BB=BA=E6=BA=90=E7=A0=81=E5=9C=B0=E5=9D=80=EF=BC=8CWebUI=20?= =?UTF-8?q?=E7=8A=B6=E6=80=81=E9=A1=B5=E7=BB=99=E5=87=BA=20AGPL=20=C2=A713?= =?UTF-8?q?=20=E7=9A=84=E6=BA=90=E7=A0=81=E5=85=A5=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 选了 AGPL-3.0-only 之后,§13(Remote Network Interaction)就不只是声明问题: 把修改过的版本作为网络服务提供出去时,必须给使用者取得 Corresponding Source 的机会。 只在仓库里放 LICENSE 并不自动满足这一条——**使用者拿到的是服务,不是仓库**。 所以把它做进产品里,而不是写进文档就算完: - `internal/meta.SourceURL`:本次构建对应的源码地址,默认指向本仓库。 注释里写明「修改后对外部署的分支必须改指向自己的仓库」,并给出 -ldflags 覆盖方式 (`-X .../internal/meta.SourceURL=<你的仓库>`),不需要改源码。 - `BuildStatus.SourceURL`(`json:"source_url,omitempty"`)+ 内核状态填充: 走已有的 `/api/v1/kernel` 构建身份链路,不新增端点。 - WebUI 状态页在「版本」行下渲染「源码 / Source」链接(URL 经 escHtml 转义后进属性; `target="_blank" rel="noopener noreferrer"`)。 - 用 `omitempty`:未注入该值的旧构建不会在 JSON 里多出一个空字段。 验证: - `internal/plugins/webui/dashboard.html` 的两个内联 script 块 `node --check` 均通过; - 全仓库 `go build ./...` 通过,`internal/meta/meta.go` gofmt 干净 (`internal/agent/core/status.go` 有**既有**的 gofmt 差异,与本改动无关,按纪律未整体重排); - 端到端:本地构建 homed → 冷启动 → `GET /api/v1/kernel` 的 `build.source_url` 实测为 `https://gitcode.com/JianFeeeee/HomeAgent`。 --- internal/agent/core/status.go | 2 ++ internal/meta/meta.go | 13 +++++++++++++ internal/plugins/webui/dashboard.html | 12 ++++++++++++ internal/sdk/status.go | 4 ++++ 4 files changed, 31 insertions(+) diff --git a/internal/agent/core/status.go b/internal/agent/core/status.go index 46703e6..fa33081 100644 --- a/internal/agent/core/status.go +++ b/internal/agent/core/status.go @@ -73,6 +73,8 @@ func collectKernelStatus( BuildTime: meta.BuildTime, SDKCompatible: meta.SDKCompatibleVersion, KernelName: meta.KernelName, + // AGPL-3.0 §13:状态页向网络使用者展示取得源码的入口。 + SourceURL: meta.SourceURL, }, Runtime: RuntimeStatus{ Goroutines: runtime.NumGoroutine(), diff --git a/internal/meta/meta.go b/internal/meta/meta.go index 4b8d54d..05d7539 100644 --- a/internal/meta/meta.go +++ b/internal/meta/meta.go @@ -43,6 +43,19 @@ var ( // 1.2.0。用 SDK 1.0.0/1.1.0 编的存量插件照旧可用——新增方法由 // **插件调用、内核实现**,不调就不受影响,无需重编。 SDKCompatibleVersion = "1.2.0" + + // SourceURL 是本内核构建所对应的源码地址。 + // + // AGPL-3.0 §13(Remote Network Interaction)要求:当你把修改过的版本 + // 作为网络服务提供出去时,必须给使用者提供取得 Corresponding Source 的机会。 + // WebUI 的状态页会把这个值渲染成可见链接,所以: + // + // ❗**修改后对外部署的分支必须把它改指向自己的源码仓库**,否则链接指向的 + // 不是你实际运行的那份代码,§13 的提供义务并未履行。 + // + // 构建时可用 -ldflags 覆盖,无需改源码: + // -X gitcode.com/JianFeeeee/HomeAgent/internal/meta.SourceURL=<你的仓库> + SourceURL = "https://gitcode.com/JianFeeeee/HomeAgent" ) // FullVersion 返回完整的版本字符串。 diff --git a/internal/plugins/webui/dashboard.html b/internal/plugins/webui/dashboard.html index 9dff18c..66d566f 100644 --- a/internal/plugins/webui/dashboard.html +++ b/internal/plugins/webui/dashboard.html @@ -2750,6 +2750,18 @@ : "-", ) + "" + + // AGPL-3.0 §13:向网络使用者提供取得对应源码的入口。 + // 地址来自内核 meta.SourceURL(构建时可 -ldflags 覆盖), + // 修改后对外部署的分支必须把它指向自己的源码仓库。 + (k?.build?.source_url + ? '
' + + __("源码", "Source") + + '' + + escHtml(k.build.source_url) + + "
" + : "") + '
' + __("构建", "Build") + '' + diff --git a/internal/sdk/status.go b/internal/sdk/status.go index 19e5bd3..1a5b00e 100644 --- a/internal/sdk/status.go +++ b/internal/sdk/status.go @@ -111,6 +111,10 @@ type BuildStatus struct { SDKCompatible string `json:"sdk_compatible"` // KernelName 是内核名(HomeAgent)。 KernelName string `json:"kernel_name"` + // SourceURL 是本次构建对应的源码地址。AGPL-3.0 §13 要求:向使用者提供网络 + // 服务时,要给他们拿到 Corresponding Source 的机会——WebUI 状态页会把它渲染成 + // 可见链接,所以**修改后对外部署的分支必须把这个值改指向自己的源码仓库**。 + SourceURL string `json:"source_url,omitempty"` } type TrackerStatus struct {