|
|
bc32fbbc98
|
feat(webui): 阶段管道的工具格改为滚动展示最新一条调用
「工具」是循环格:一轮里可能调几十次工具/输出通道。此前每一次都追加成
chip,这一格被撑成一长条,反而看不出「现在在调什么」。改为固定一行的
滚动视口——只留最新一条,右侧给出本轮累计次数;新调用到来时旧条向上
滚出、新条滑入(morph 就地改文本不会重放 CSS 动画,故摘类 + 强制 reflow
+ 重加类)。并给 chip 名称加 .rt-chip-t 承接省略号,窄框不再硬切半截。
配套 TestStagePipelineToolCellShowsLatestOnly 钉住该口径。
|
2026-09-14 20:07:29 +08:00 |
|
|
|
0faf9fb4e8
|
style(webui): 队列/管道列宽下限收到 100px,消掉「4 个 + 1 个」孤行
118px 时容器 540px(小窗口侧栏展开的宽度)只放得下 4 列,第 5 个框
落到第二行且后面四个位置全空 —— 正是「看着空」的那种观感。
收到 100px 后 540px 也能一行放下 5 个;配套给 .rt-qmeta 加 wrap,
窄框里「登记/抢占」两枚迷你条换行而不是撑破框。
五档实测(1400/1100/900/700/480):1400/1100/900/700 都是 5 框一行
(200/140/100/120px),480 为 3+2;均无横向溢出,框内元素无越界。
|
2026-09-14 18:45:36 +08:00 |
|
|
|
f89e57a732
|
feat(webui): 阶段管道与中断队列统一为等大表框,字体加大加粗
问题:阶段管道是「小圆点 + 一条连接线 + 9px 小字」,中断队列是五行
「名字 | 进度条 | 元数据」的扁条 —— 两块都远小于旁边的 KPI 框,中断队列四级
全为 0 时四行几乎全是空白,既占高度又难看。
改法:两块统一成同一套视觉语言 —— **等大表框**(与 KPI 同一种骨架)。
阶段管道(.rt-pipe-row / .rt-pipe-cell)
- 5 个等大框,框内 = 图标 + 阶段名 + 本阶段本轮发生的事件 chip。
- 阶段名 9px/500 → 13.5px/700;图标 12px → 15px。
- 当前阶段整框点亮(accent 描边 + 淡底 + 内阴影),不再靠一个小圆点表意。
- 删掉圆点、连接线、滑块把手那套已死的 CSS(.rt-pipe-track/.rt-pipe-knob 等)。
中断队列(.rt-queues / .rt-qcell)
- 五行扁条 → 5 个等大框(L4/L3/L2/L1 + 排队),一行排开。
- 框头级别名 16px/800、深度数字 26px/800(原来深度只是行末一个小数字)。
- 级别色同时用在框头、点亮格槽、有积压时的整框描边 —— 一处配色贯穿。
- 排队队列无级别,用虚线框与四级中断区分(另一**类别**,不是另一优先级)。
- 保留可见格槽:0 时也有形状,不会变回一片空白。
列宽自适应:两块共用 repeat(auto-fit, minmax(118px, 1fr)),
118px 而不是 150px 是为了让 640–740px 容器(窄屏侧栏收起后的宽度)也能
5 个框排一行,不出现「4 个 + 1 个」的孤行。chip 补 min-width:0 以免撑破窄框。
顺带清掉一条无用的旧 .rt-chip 规则(与新规则重名且只被阶段事件用到)。
实测(现网 CDP,1400/1100/900/700/480 五档):
- 1400/1100/700px:5 框一行(200px / 140px / 120px);900/480px:换行且框仍等大
- 五档均无横向溢出
- 字号:阶段名 13.5px/700,级别 16px/800,深度 26px/800
- 注入一轮轨迹:输入=输入|行动=思考|工具=qq_get_message x3 qq*|输出=生成|结束=完成
- 注入 L3=3/排队=2:L3 描边 rgba(255,166,87,.55)、框头与点亮槽同为琥珀色;
排队绿框;空的 L4 保持默认描边(首次读到的默认色是 0.25s 过渡中途,非 bug)
- chip 未溢出所在框;总览/侧栏/顶栏渲染文本无 emoji
|
2026-09-14 18:38:08 +08:00 |
|
|
|
37924b295b
|
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 全量测试通过
|
2026-09-14 17:48:54 +08:00 |
|
|
|
bead5746c3
|
feat(webui): 总览显示内核身份、图标全 SVG 化、队列改格槽、阶段管道下方按阶段列事件
四个问题一起改(都出在总览/内核页的展示层,不动内核逻辑):
1) 内核版本不再"看不见"
- 36b577b 改图标 KPI 时把 kernel_name 丢了,只剩一个 "v1.4.0",分不清
是哪个内核、哪次构建。现在 KPI 值给版本号,下面补一行副行
「HomeAgent · <commit>」(.ov-sub)。
- 内核页此前**完全没有构建信息**,现在补一张「构建」卡:内核名/内核版本/
Commit/构建时间/SDK 兼容/源码链接(AGPL §13 的入口页)。
2) 任何位置都不再用 emoji/符号字符充当图标
- 新增 RT_ICO(纯内联 SVG,24x24 / currentColor),替换:阶段节点的循环
标记(原 ↻)、轨迹 chip 的工具/输出标记(原 ⚙/⇥)、"立即运行"(原 ⚡)、
工具卡与思考卡的下拉箭头(原 ▾)。
- CSS 注释里的同类字符一并去掉。
3) 队列不再"空着只有文字"
- 原来画的是宽度百分比进度条:深度为 0 时宽度就是 0,五行只剩文字。
改成 rtSlots 的「车位」式格槽(至少 5 格、最多 16 格,按全场最大深度
缩放),0 时仍有可见形状,占用多少一眼可数;超出格数时给 +N。
- 修掉一个真实的 DOM 结构错误:第五条「排队」队列被写在 .rt-levels 闭合
**之后**,且后面多一个 </div>,多出来的闭合标签会提前关掉祖先节点、
把整块布局撞歪。现在它回到容器内。
4) 每一步管道的事件显示在管道下方对应阶段列里
- 原来是一条拍平的 chip 序列,看不出"这件事发生在哪个阶段"。
现在 .rt-pipe-cols 与上面的阶段节点共用 5 等分栅格,事件按 g(阶段组)
分列落位;实测列中心与节点中心偏差 ≤ 2px。
- 轨迹覆盖全部阶段(输入/思考/工具/输出/完成),同阶段重复的同一条
累加 ×N 而不是刷屏(rtTrailPush)。空列显示一个弱化的「无」。
验证(现网 1400x920,CDP 实测):
- 版本 KPI = v1.4.0+hotfix.0fd4fb1 / HomeAgent · 0fd4fb1;内核页构建卡齐全
- 注入一轮轨迹:col0=输入 col1=思考x2 col2=qq_get_message x3/qq/cmd_run
col3=生成x2 col4=完成,active 节点=工具,×N 计数正常,3 个 chip SVG
- 队列 L3=3/5、排队=2/5 点亮,L3 取到琥珀色 rgb(255,166,87)
- 页面无横向溢出;总览/侧栏/顶栏/内核页渲染文本无 emoji
- go vet 干净,internal/plugins/webui 测试通过
|
2026-09-14 17:40:54 +08:00 |
|
|
|
0fd4fb1f7a
|
fix(webui): 拓扑按实测容器宽布局 + 字号/截断,修间距失衡与文字难读
三处实机问题:
1) viewBox 固定 640 而容器 ~920,浏览器按 'meet' 把内容顶到左上、右侧空出一大片
—— 观感就是「间距不对」。改为 viewBox 宽 = 实测容器宽、width 用像素值,
缩放恒为 1(已用 getScreenCTM().a 验证)。
2) 文字全是 9-11px + 低对比度硬编码色(#8b90a5)→ 难读。字号提到 10.5-12.5px,
fill/font-size 改走 .tp-* 类,颜色交给 --text-primary/--text-muted 主题变量。
3) 列短的一侧原来顶在带上半、节点居中,连线又长又歪;长通道名还会溢出到邻居身上。
现在两列在带内各自居中、节点块高度参与带高计算(单行带不再把节点名压到下一条带),
长名按估算宽度截断加 …,完整名放 <title> 悬停可见。
另:rtSpark 用的 _rtEdgeIn/_rtEdgeOut 键与取值方式未变,光点动画照旧。
|
2026-09-14 16:51:41 +08:00 |
|
|
|
c252915083
|
feat(webui): 阶段管道改「循环 + 本轮轨迹」,区分工具/输出调用;再砍总览文字
jianf:阶段管道像无记忆的单向滑块,但一轮里会多次 toolcall、也可能多次输出;
且没区分 output_* 调用与普通工具调用;总览仍有一大坨文字。
- 阶段管道不再是单向滑块:#
画成 输入 → 行动 ⇄(工具↻) → 输出 → 结束 的循环结构,当前阶段高亮;
下面用一排 chip 记**本轮真实发生过的序列**(on_input 重置、before_toolcall 追加、
after_output 收尾,最多 24 条)。工具调用会反复出现,循环因此可见。
- 区分调用类型:普通工具 chip 前缀 ⚙(青),output_* 输出通道调用前缀 ⇥(accent 色),
两者配色与图标都不同。
- 文字再收缩:删掉「累计:入队/执行/抢占/挂起/背压」整行;队列标签由
「L4 内核独占…」压成 L4/L3/L2/L1/排队(原描述进 title);各段标题压成
「队列」「栈」「拓扑」;KPI 块标签压成 排队/中断/栈/子代理。
顺带(同类问题):CLI /stop 是人在终端当场下的指令,优先级由默认 L1 提到 L3。
|
2026-09-14 16:31:37 +08:00 |
|
|
|
36b577bff8
|
fix(webui): 总览改静态骨架 + 图标 KPI,彻底去掉整页重建的闪烁
jianf:仍严重闪烁;应彻底摒弃增量重建,用动态图标 + api 数据展示;主页文字太多。
- renderOverview 从「每次 innerHTML 重建整页(含运行态面板)」改成**首帧建一次
静态骨架**,之后 renderAll(每 15s 一次)只 updateOverview —— 只写 textContent
与类名,一个节点都不重建。实测连续两次 renderAll 后 #ov-kpis / #ov-status /
#rt-panel 仍是同一批 DOM 节点,这是"不再闪"的直接判据。
- 主页文字大幅收缩:删掉「系统概览 / LLM 状态 / 记忆状态 / 运行时」四张 kv 文字卡,
改成一排 8 个图标 KPI(状态/运行/插件/版本/LLM/记忆/文档/运行时),状态用彩色
圆点表达,其余只留数字 + 两字标签。
- 运行态面板不再被 renderOverview 清空(去掉 _rtSig=null 与重建),保持连续更新。
|
2026-09-14 16:16:14 +08:00 |
|
|
|
f722498dba
|
feat(webui): 默认配色改黑白 + 设置页新增「外观」区
jianf:默认配色太花,且配色要能在设置页调。
- 新增 mono(黑白灰)配色并设为默认:未选过配色的 localStorage 一律
data-color=mono。黑白下连拓扑归属配色也走灰阶,不至于只剩一张彩图。
- accent 的所有硬编码 rgba(255,127,172,x) 收敛成语义变量 --accent-rgb,
各配色块(sakura/cyan/violet/emerald/amber/blue)各自声明自己的 rgb,
于是换配色时阴影/描边/阴影辉光一起换,不再残留粉色。
- 设置页新增「外观」区(侧栏最前):主题(浅/深)+ 7 个配色圆点 +
背景图 URL/模糊。原先只有侧栏底部一个调色盘图标,找不到。
- 切配色时强制重画运行态(置空 _rtSig),否则拓扑会停在旧色。
|
2026-09-14 15:44:17 +08:00 |
|
|
|
e4d69fa140
|
feat(webui): 总览改版 —— 阶段管道滑块 / per-agent 负载环 / 通道→agent 拓扑与光点
总览页此前是一堆数字与文字块,看不出「这一轮走到哪、谁忙、消息从哪进哪出」。
本次把运行态面板改成以图形为主:
- 阶段管道:七阶段滑块,由 SSE stage 事件驱动,当前阶段高亮、滑块滑过去;
一轮结束(after_output 或 2.5s 无事件)自动回到空闲,不做假动画。
- 队列与中断栈:沿用五条进度条(L1–L4 + 排队),中断栈补一条深度进度条。
- Agent 拓扑:改成「每 agent 一条横带」——左 inputch、中 agent 节点(圆环 = 负载)、
右 outputch,连线即路由;删掉旧的「归属框 + 单个内核盒」画法(看得出哪个子接了哪条输入)。
- 光点动画:channel_input(新增轻量 SSE 事件)沿 inputch→agent 连线跑;
agent_output 沿 agent→outputch 连线跑。用 SMIL animateMotion,不需要 rAF 循环。
- 负载:由该 agent **自己的**调度器积压(排队 / 四级中断 / 中断栈)按级别加权折算,
环形图展示。为此把驻留子的调度器积压透出到状态面(SDK 纯追加字段)。
后端:sdk.ResidentStatus / core.ResidentInfo 增加子 agent 调度器积压四项;
WebUI SSE 增加 channel_input 轻量事件(只带通道名与 agent id,不带正文)。
顺带收口对话区视觉(页签改分段控件、消息间距/气泡区分、输入区分隔线)。
|
2026-09-14 15:33:23 +08:00 |
|
|
|
0fda210e8b
|
feat(webui): 视觉重做第一轮 —— 侧栏图标化、顶栏标题化、卡片/行/按钮收口
反馈是「丑死了」,没有具体项,所以按「哪儿在制造廉价感」逐条改:
1. **侧栏只有文字**:6 个导航项各加 24×24 stroke 图标(currentColor,随选中/hover 变色),
10px 间距、13.5px/500 字重、圆角 10px 的药丸命中区;品牌字改 sakura→frost 渐变。
→ 空荡荡的 16rem 栏终于有了骨架。
2. **选中态把文字整体右推 + 发光文字**:原来用 `border-left: 3px` 画选中条,
hover 时整行抖 3px;还加了 text-shadow 光晕。改成 `box-shadow: inset 2px 0 0`
(不占布局)+ 取消光晕 + 选中加粗。这类「一像素级不稳」是廉价感的主要来源。
3. **顶栏只有一行灰字面包屑**:把当前页做成 15px/650 的标题色,面包屑碎片
压到 12.5px 且降透明度;顶栏 48→56px。页面总算有「入口」。
4. **卡片 hover 整页上下浮**:`.card:hover` 去掉 `translateY(-1px)`(十几张卡一起
浮,视线扫过像在抖),只提亮阴影与描边;padding 20→22、卡片间距 16→18。
5. **卡片标题没有章节信号**:`h2` 前加 3×14px 的 sakura→frost 渐变短竖。
6. **kv-row 是文字墙**:flex + 固定 180px 键列 → grid `minmax(110px,180px) 1fr`,
行高 8px、负外边距 hover 高亮、末行去分隔线、数值 `tabular-nums`(端口/计数上下对齐)。
7. **满屏药丸按钮**:`.btn` 圆角从 999px 收到 10px(与卡片同一套圆角),
padding/font 微调;`.btn-sm` 11→11.5px 提升可读性。
8. **内容区靠左铺满**:`.container` 居中 + `max-width: 1240px`(超宽屏摊满整个
屏幕是「后台模板」的典型观感)。
i18n 有个坑:切语言那段是 `el.textContent = …`,所以 `data-i18n` 必须从 `<a>` 挪到
内层 `<span>`,否则切一次语言图标就被抹掉。实测 ZH→EN→ZH 图标都在。
验证:go build/测试绿(webui + sdk + agent + plugin);真机 1440×900 六页截图对比
(侧栏图标、渐变品牌、标题竖条、grid 行、居中内容区均生效)。
|
2026-09-14 14:29:17 +08:00 |
|
|
|
e8d7bb4c06
|
feat(webui): 通道归属合并进拓扑图,整张图改 SVG(少文字、多图形)
上一版把「通道分配(按归属)」单开一段,等于把同一件事拆成两张表——
而通道属于谁是**拓扑的一部分**(左边这些输入口分别被谁接管),拆开反而
看不出关系。按用户要求合并,并整体改成图形化:
- 整张拓扑用 SVG:左侧按归属画出输入通道容器(根=青色虚线框,驻留子=彩色
实线框并标轮次/上下文满),→ 汇集母线 → 内核 → 输出母线 → 右侧输出通道。
**连线即路由**。
- 信息全部改用图形编码:归属=容器/配色、容量=节点内细条(默认容量不画填充)、
输出能力=五个彩色圆点(text/file/image/audio/structured)。
- 文字降到最少:去掉四个数字块的副标题、排队队列那行只留 "FIFO"、
通道行不再写"回程由来源决定"这类说明。
- 段名改为「通道拓扑(连线即路由;左框 = 归属)」。
验证:node --check 通过;go build ./... 干净;webui 测试全绿。
|
2026-09-14 11:22:20 +08:00 |
|
|
|
d502fc1bf5
|
fix(webui): 运行态面板逐段更新(真修「一闪一闪」)+ 补第五条排队队列
1) 上一版只做了整体签名缓存,实测仍会重建:设备通道列表本身就在来回变
(远程设备通道 11→9 条),签名一变就整块 innerHTML,没变的段落(含条
transition)也跟着推倒重来——视觉上仍是闪。改法:外壳只建一次,之后
**逐段**(tiles/levels/stack/owners/topo)比较 HTML,只替换真正变了的那段。
2) 设计是「四条中断队列(L1–L4)+ 一条排队队列」= 五个队列,面板只画了四条:
排队输入这条线在运行态里凭空消失。补第五行「排队(无级别)」,用中性色 +
虚线分隔(它不是优先级,而是另一**类别**),并把它计入条形归一化基准。
段标题从「中断队列(按级别)」改为「队列(四级中断 + 排队)」。
3) 顺带把累计计数(入队/执行/抢占/挂起恢复/拒绝/背压)显式列在数字块下方——
背压是新指标,之前只能看接口看不到面板。
验证:node --check 通过;go build ./... 干净;webui/core/sdk 测试全绿。
|
2026-09-14 11:03:37 +08:00 |
|
|
|
43536ba326
|
fix(webui): 运行态面板不再闪、通道分配带归属(含驻留子)、改图形化
三个用户可见问题,逐个说明根因与改法。
1) 首页「一闪一闪」——运行态每 3s 轮询一次,renderRuntime 无条件重建
#rt-panel 的 innerHTML:数据没变也把整块 DOM(含各级条的 transition)
推倒重来。改法:缓存数据签名(**不含 uptime**——它每秒都变,带上等于没缓存),
签名相同直接 return,一个字节都不动。另:renderOverview 会整块重建
#rt-panel(面板本身是空的),所以那里必须让签名失效,否则空面板填不上。
2) 通道分配只显示内核/根 agent,看不见驻留子——根因是状态面只暴露了设备能力
(KernelStatus.Channels,来自 iom.ListChannels),而「这条输入归谁」是
ChannelRegistry 的属性(InputChannel.Owner/Capacity/Output),从未出过内核。
而登记表本来就是根 agent 与驻留子**共用同一份**,所以数据一直都在,只是没画。
改法:KernelStatus 新增 InputChannels(+ sdk.InputChannelInfo),
/api/v1/runtime 带出 input_channels;前端把它按 owner 分进「归属容器」,
驻留子即使一条 inputch 都没划到也照样出现在图里(否则"子存在但看不见"
与"子不存在"无法区分),并显示其 allowed_outputs / 轮次 / 上下文满标记。
3) 「这些信息明明可以图形化」——四级中断的登记/抢占由纯文本改成并排迷你条;
通道分配用归属容器 + 容量滑块(轨道/填充/把手/读数),并把回程通道、
注册插件做成胶囊标签。设备能力拓扑(原有)保留。
验证:go build/vet 干净;go test ./internal/agent/... ./internal/plugin/...
./internal/sdk/... ./cmd/... 全绿;node --check dashboard.js 语法通过。
TestRuntimeEndpoint 扩展为同时钉住 input_channels 的归属与「驻留子划走的那条」。
|
2026-09-14 10:55:45 +08:00 |
|
|
|
1ce3a917a5
|
feat(status+webui): 运行态图形化 —— 排队/四级中断队列/中断栈/驻留子/通道拓扑
需求:首页不该只有文字,要能一眼看出内核在忙什么——排队消息数、各级中断
排队与中断栈、驻留子 agent 数量;这些要向**内部 SDK 暴露接口**,供 WebUI 等应用
展示;通道划分也要能画出来。
## 一、内核状态面(internal/sdk,内部 SDK,不受公开 SDK 冻结约束)
* SchedulerStatus 补:
- interrupt_queues[5]:**四级中断队列各自的深度**(下标即级别 1..4,下标 0 恒 0,
这样 level 能直接当数组下标用)。此前只有 pending_interrupts 总数,
看不出"堵在 L1 还是 L4"——四级是抢占优先级,堵在哪级是完全不同的运行状态。
- immediate:刚抢占成功、下一个安全点立即运行的那个中断(此前完全不可见)。
- suspend_frames:中断栈的帧(栈底→栈顶,只给任务标识),depth 之外还能看出
"谁被谁打断"。
- interrupts_by_level / preempts_by_level:各级累计登记数与抢占成功数。
* KernelStatus 补 residents(驻留子运行时视图:状态/轮次/上下文已满/输入通道/允许输出)。
刻意**不带**每个驻留子的 inputch 登记明细——状态面会被反复轮询,明细会让
每次 /status 背上几十 KB;只给表大小,要明细走专门接口。
* ChannelInfo 补 direction(in/out/io)、description、tools、output_caps、caps_text。
此前 collectKernelStatus 只透传 Name/Type,把描述/工具/能力**全丢了**,
前端只能画出一排光秃秃的名字。
## 二、WebUI
* 新增只读 `/api/v1/runtime`:只回运行态三件事(scheduler/residents/channels),
实测 **1.0KB**(/kernel 是 30KB 级)——所以能 3 秒轮询做"实时"感,
而不必反复拉全量状态。
* 首页新增「运行态」面板(纯 CSS + 内联 SVG,前端仍无构建链):
- 四个数字块:排队任务 / 待处理中断 / 中断栈(深度/上限) / 驻留子 Agent,带占比条;
- 四级中断队列条形图:每级"深度 · 登记/抢占",四级语义**照抄内核**
(L4 内核独占 / L3 交互 / L2 消息 / L1 后台),不自己起名字;
- 中断栈层叠图(栈顶在上)+ ⚡立即运行项;
- 通道拓扑:输入通道 → 内核 → 输出通道,双向通道两侧都出现,能力以胶囊标签显示。
* 3 秒轮询只在总览页可见时才发请求;切回总览时 renderAll 会立刻补一次。
## 验证
* 新增 TestSchedulerStatusExposesLevelsAndStack(四级队列/立即项/栈帧/各级计数映射,
并断言"未使用的级别必须为 0"与"下标 0 恒 0")、TestChannelInfoCarriesTopology、
TestRuntimeEndpoint(形状 + 不携带 tools/plugins + 无状态源时 503)。
* go build / vet / agent+core+sdk+plugin+webui 全量测试绿。
* 真实浏览器实测(CDP 驱动,注入运行态样本走真实渲染路径):
数字块 [3, 5, 2/4, 2];四级条 L4=1/L3=2/L2=1/L1=1 与数据一致;
栈帧按"栈底→栈顶"渲染且标出栈顶;通道左右分列、io 通道两侧都出现。
|
2026-09-14 09:05:14 +08:00 |
|
|
|
764939ed90
|
refactor(webui): dashboard.html 6637 行拆成「外壳 + 样式 + 脚本」
前端刻意没有构建链(纯 CSS + Vanilla JS,go:embed 进二进制),所以拆法是:
外壳 dashboard.html 留 {{DASHBOARD_CSS}} / {{DASHBOARD_JS}} 两个占位符,
init() 启动时把两份资产原样填回去 —— **发出的 HTML 与拆分前逐字节一致**,
但 6637 行的单文件变成三份,便于编辑与评审。
dashboard.html 168 行 外壳(head/body 结构 + 两个占位符)
dashboard.css 2099 行 样式
dashboard.js 4371 行 脚本
逐字节校验(三重):
* 组装结果 sha256 == git HEAD 里拆分前的 dashboard.html;
* 真实实例 GET /(带 API key)返回体 sha256 同上:0ef14b49…c053;
* 新增 TestDashboardAssetsSplit:占位符必须存在、样式/脚本不得再内联回外壳、
组装结果不得残留占位符且必须含样式与脚本特征串。
按行号切片时踩过一次坑并已修正:`</style>`/`</script>` 两个闭合标签被切掉
(正好少 27 字节)——正是因为当时少了逐字节校验,现在把它固化成断言。
|
2026-09-14 07:17:23 +08:00 |
|