mirror of
https://gitcode.com/JianFeeeee/HomeAgent.git
synced 2026-09-22 18:08:04 +00:00
feat(webui): 总览底部源码区改为独立的「开源许可」框(协议 + 全文 + 源码)
此前总览底部只在 KPI 卡里挂了一行小链接(.ov-foot),既看不出受什么许可
约束,也看不出 AGPL 网络服务场景下的义务。现在单独成一张卡:
开销许可
许可协议 AGPL-3.0-only → GNU 官方全文
源码仓库 <source_url> → 仓库
网络服务条款(§13):把修改后的版本作为网络服务对外提供时,
必须向使用者提供取得对应源码的途径。
内核侧(License 是新事实,不能只靠前端写死):
- internal/meta:新增 License(SPDX 标识)与 LicenseURL,都可 -ldflags 覆盖。
LicenseURL 默认指向 GNU 官方 AGPL-3.0 全文页 —— 与仓库托管方、分支名、
文件路径都无关,换仓库/换分支不会失效。
- internal/sdk/status.go 的 BuildStatus:新增 License / LicenseURL 两个
json 字段(additive,旧消费方忽略未知字段即可)。
❗注意 internal/sdk 不受公开接口冻结约束(docs/git-branching.md §六),
本次未触碰 third_party/homeagent-sdk/sdk/。
- internal/agent/core/status.go:从 meta 填充。
前端:
- 骨架里 .ov-foot 换成独立的 <div class="card" id="ov-legal">(放在 KPI 卡之后)。
- 网络条款那一段按许可标识是否含 AGPL 决定是否渲染,不硬写协议名。
- 内容对一次构建是常量,沿用 __html 比对,填一次后不再重建(不引入闪烁)。
验证(现网 1400x920,CDP 实测):
- /api/v1/kernel 的 build 现在带 license="AGPL-3.0-only"、
license_url="https://www.gnu.org/licenses/agpl-3.0.html"
- 卡片为真框:class=card、border 1px、radius 14px;总览结构 = rt-panel | card | ov-legal
- 两个链接均为真 <a>,target=_blank + rel=noopener noreferrer
- updateOverview() 再跑一次,卡片子节点身份不变(不重建、不闪)
- 回归:KPI 版本副行、阶段管道 5 节点/5 列/6 SVG、队列 5 行×5 格 均正常
- 无横向溢出;总览/侧栏/顶栏渲染文本无 emoji
- go vet 干净;agent/core、plugins/webui、plugins 全量测试通过
This commit is contained in:
@ -2855,9 +2855,15 @@
|
||||
.ov-dot.bad {
|
||||
background: var(--error);
|
||||
}
|
||||
.ov-foot {
|
||||
margin-top: 10px;
|
||||
/* 开源许可卡:协议标识 + 协议全文 + 源码仓库。
|
||||
此前只是 KPI 卡底部一行小链接(.ov-foot),在长页面里基本看不见。 */
|
||||
.ov-legal h2 {
|
||||
margin-bottom: 6px;
|
||||
}
|
||||
.ov-legal-note {
|
||||
margin: 10px 0 0;
|
||||
font-size: 11px;
|
||||
line-height: 1.55;
|
||||
color: var(--text-muted);
|
||||
}
|
||||
|
||||
|
||||
@ -1378,7 +1378,10 @@
|
||||
ovKpi("memory", OV_ICONS.db, __("记忆", "Memory")) +
|
||||
ovKpi("docs", OV_ICONS.file, __("文档", "Docs")) +
|
||||
ovKpi("runtime", OV_ICONS.cpu, __("运行时", "Runtime")) +
|
||||
'</div><div class="ov-foot" id="ov-foot"></div></div>';
|
||||
'</div></div>' +
|
||||
// 开源许可单独成框:之前在 KPI 卡底部只是一行小链接(.ov-foot),
|
||||
// 几乎看不见,也看不出是许可证还是别的什么。
|
||||
'<div class="card" id="ov-legal"></div>';
|
||||
}
|
||||
updateOverview();
|
||||
}
|
||||
@ -1427,20 +1430,55 @@
|
||||
"ov-runtime",
|
||||
rt.goroutines ? rt.goroutines + (rt.memory_mb ? " · " + rt.memory_mb + "M" : "") : "—",
|
||||
);
|
||||
// 源码链接(AGPL §13):静态文本,第一次填好后不参与轮询刷新。
|
||||
var foot = document.getElementById("ov-foot");
|
||||
if (foot) {
|
||||
var src = k && k.build && k.build.source_url;
|
||||
var want = src
|
||||
? '<a href="' +
|
||||
// 开源许可卡:协议标识 + 协议全文 + 源码仓库。
|
||||
//
|
||||
// 为什么单独成框、且三者都给:AGPL-3.0 §13 的义务是「向网络使用者提供
|
||||
// 取得 Corresponding Source 的机会」——只给一个仓库链接、不写协议名,
|
||||
// 使用者看不出这受什么许可约束,也看不出网络服务场景下还有 §13 的义务。
|
||||
// 内容对一次构建是常量,所以填一次就够(__html 比对避免重复重建)。
|
||||
var legal = document.getElementById("ov-legal");
|
||||
if (legal) {
|
||||
var lb = (k && k.build) || {};
|
||||
var src = lb.source_url || "";
|
||||
var lic = lb.license || "";
|
||||
var licURL = lb.license_url || "";
|
||||
var rows = "";
|
||||
if (lic) {
|
||||
rows +=
|
||||
'<div class="kv-row"><span class="key">' +
|
||||
__("许可协议", "License") +
|
||||
'</span><span class="val">' +
|
||||
(licURL
|
||||
? '<a href="' + escHtml(licURL) + '" target="_blank" rel="noopener noreferrer">' + escHtml(lic) + "</a>"
|
||||
: escHtml(lic)) +
|
||||
"</span></div>";
|
||||
}
|
||||
if (src) {
|
||||
rows +=
|
||||
'<div class="kv-row"><span class="key">' +
|
||||
__("源码仓库", "Source") +
|
||||
'</span><span class="val"><a href="' +
|
||||
escHtml(src) +
|
||||
'" target="_blank" rel="noopener noreferrer">' +
|
||||
__("源码", "Source") +
|
||||
"</a>"
|
||||
escHtml(src) +
|
||||
"</a></span></div>";
|
||||
}
|
||||
// 网络条款只在 AGPL 系的许可下才成立,所以按标识判断,不硬写协议名。
|
||||
var note =
|
||||
lic && lic.toUpperCase().indexOf("AGPL") >= 0
|
||||
? '<p class="ov-legal-note">' +
|
||||
__(
|
||||
"网络服务条款(§13):把修改后的版本作为网络服务对外提供时,必须向使用者提供取得对应源码的途径。",
|
||||
"Network clause (section 13): offering a modified version as a network service requires giving users a way to obtain the Corresponding Source.",
|
||||
) +
|
||||
"</p>"
|
||||
: "";
|
||||
var want = rows
|
||||
? '<h2>' + __("开源许可", "License") + "</h2>" + rows + note
|
||||
: "";
|
||||
if (foot.__html !== want) {
|
||||
foot.__html = want;
|
||||
foot.innerHTML = want;
|
||||
if (legal.__html !== want) {
|
||||
legal.__html = want;
|
||||
legal.innerHTML = want;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user