dsh-model-health 0.2.5 → 0.2.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -1
- package/dist/client.js +66 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -57,6 +57,7 @@ dsh --profile web --dump-config | grep dsh-model-health # 配置层含本行
|
|
|
57
57
|
- API Key 通过 DSH credential service(`ctx.credentials.resolve`)解析,密钥不会输出到浏览器
|
|
58
58
|
- 测试结果(状态/延迟/错误)持久化到 localStorage,刷新页面后仍可见
|
|
59
59
|
- 状态列的 可用 / 不可用 / 跳过 徽章随时可点击,对单个模型重新测试,原地刷新状态与延迟
|
|
60
|
+
- 设置导航使用脉搏线(Activity)图标——宿主图标表没有「健康」类目,参考 dsh-better-sidebar 的方案,JS 精准打 marker,CSS 用 `::before` + `mask` 把齿轮 svg 原地替换;颜色随主题走
|
|
60
61
|
|
|
61
62
|
## 实现方式 / How it works
|
|
62
63
|
|
|
@@ -101,7 +102,7 @@ dsh-model-health/
|
|
|
101
102
|
├── src/host/ # host 实现:config / models / markdown / http / model-test
|
|
102
103
|
├── src/client.tsx # client 入口壳:注入 React,装配插件导出
|
|
103
104
|
├── src/client/ # client 实现:types / runtime / i18n / storage / api /
|
|
104
|
-
│ # styles / columns / use-test-results / apply
|
|
105
|
+
│ # styles / columns / use-test-results / nav-icon / apply
|
|
105
106
|
│ └── components/ # ModelListSection / StatusCell / ErrorTooltip
|
|
106
107
|
├── cordis.patch.yml # bundle 层声明(id/name 走包名解析)
|
|
107
108
|
└── dist/ # 构建产物(发布包含在 files 字段中)
|
package/dist/client.js
CHANGED
|
@@ -613,12 +613,14 @@
|
|
|
613
613
|
const models = data.models || [];
|
|
614
614
|
const activeLang = locale && typeof locale.getLocale === "function" ? locale.getLocale().active : "zh";
|
|
615
615
|
const updatedAt = new Date(data.updatedAt || Date.now()).toLocaleString(activeLang === "en" ? "en-US" : "zh-CN");
|
|
616
|
+
const validKeys = new Set(models.map((m) => m.key));
|
|
616
617
|
const stats = {
|
|
617
618
|
ok: 0,
|
|
618
619
|
fail: 0,
|
|
619
620
|
skip: 0
|
|
620
621
|
};
|
|
621
622
|
for (const k in run.results) {
|
|
623
|
+
if (!validKeys.has(k)) continue;
|
|
622
624
|
const s = run.results[k].status;
|
|
623
625
|
if (s === "ok") stats.ok++;
|
|
624
626
|
else if (s === "fail") stats.fail++;
|
|
@@ -699,6 +701,68 @@
|
|
|
699
701
|
})))), tooltip && /* @__PURE__ */ React.createElement(ErrorTooltip, { tip: tooltip }));
|
|
700
702
|
}
|
|
701
703
|
|
|
704
|
+
//#endregion
|
|
705
|
+
//#region src/client/nav-icon.ts
|
|
706
|
+
/** 本插件导航行按钮的 marker(参考 better-sidebar 的命名风格) */
|
|
707
|
+
const SETTINGS_NAV_MARKER = "data-dsh-model-health-settings-nav";
|
|
708
|
+
/**
|
|
709
|
+
* 在设置弹窗挂载期间,给本插件的导航行按钮持续打上 marker。
|
|
710
|
+
* label 解析器返回当前激活语言的 tab 文案(i18n 切换会重新求值),与导航行
|
|
711
|
+
* 按钮的 textContent 严格相等才算匹配——保证不会误伤其他插件的同名/相似 section。
|
|
712
|
+
* @param label - locale-aware label resolver used by the section registration
|
|
713
|
+
* @returns disposer: HMR / 插件卸载时断开观察器并清理已打的 marker
|
|
714
|
+
*/
|
|
715
|
+
function registerSettingsNavIcon(label) {
|
|
716
|
+
let disposed = false;
|
|
717
|
+
const sync = () => {
|
|
718
|
+
if (disposed) return;
|
|
719
|
+
const currentLabel = label().trim();
|
|
720
|
+
const buttons = document.querySelectorAll("[role=\"dialog\"] nav button");
|
|
721
|
+
for (let i = 0; i < buttons.length; i++) {
|
|
722
|
+
const button = buttons[i];
|
|
723
|
+
if (currentLabel.length > 0 && button.textContent && button.textContent.trim() === currentLabel) button.setAttribute(SETTINGS_NAV_MARKER, "");
|
|
724
|
+
else button.removeAttribute(SETTINGS_NAV_MARKER);
|
|
725
|
+
}
|
|
726
|
+
};
|
|
727
|
+
sync();
|
|
728
|
+
const observer = new MutationObserver(sync);
|
|
729
|
+
observer.observe(document.body, {
|
|
730
|
+
childList: true,
|
|
731
|
+
subtree: true,
|
|
732
|
+
characterData: true
|
|
733
|
+
});
|
|
734
|
+
return () => {
|
|
735
|
+
disposed = true;
|
|
736
|
+
observer.disconnect();
|
|
737
|
+
document.querySelectorAll(`[${SETTINGS_NAV_MARKER}]`).forEach((el) => {
|
|
738
|
+
el.removeAttribute(SETTINGS_NAV_MARKER);
|
|
739
|
+
});
|
|
740
|
+
};
|
|
741
|
+
}
|
|
742
|
+
/** 注入图标样式:隐藏 marker 行的齿轮 svg,用 ::before 注入脉搏线(mask 方案)。
|
|
743
|
+
* 16px 与宿主图标节奏一致;background: currentColor 让颜色跟随 nav 文案色
|
|
744
|
+
* (普通态 / hover / 选中态 / 明暗主题全自动)。 */
|
|
745
|
+
function ensureNavIconCss() {
|
|
746
|
+
const id = "dsh-model-health-nav-icon-style";
|
|
747
|
+
if (document.getElementById(id)) return;
|
|
748
|
+
const el = document.createElement("style");
|
|
749
|
+
el.id = id;
|
|
750
|
+
const mask = "url(\"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='22 12 18 12 15 21 9 3 6 12 2 12'/%3E%3C/svg%3E\") center / contain no-repeat";
|
|
751
|
+
el.textContent = `
|
|
752
|
+
[data-dsh-model-health-settings-nav] > svg:first-child { display: none; }
|
|
753
|
+
[data-dsh-model-health-settings-nav]::before {
|
|
754
|
+
content: '';
|
|
755
|
+
flex: none;
|
|
756
|
+
width: 16px;
|
|
757
|
+
height: 16px;
|
|
758
|
+
background: currentColor;
|
|
759
|
+
-webkit-mask: ${mask};
|
|
760
|
+
mask: ${mask};
|
|
761
|
+
}
|
|
762
|
+
`;
|
|
763
|
+
document.head.appendChild(el);
|
|
764
|
+
}
|
|
765
|
+
|
|
702
766
|
//#endregion
|
|
703
767
|
//#region src/client/apply.tsx
|
|
704
768
|
/** client 侧依赖:slots(注册 UI slot 的服务)+ locale(多语言词典) */
|
|
@@ -726,11 +790,13 @@
|
|
|
726
790
|
function apply(ctx) {
|
|
727
791
|
const React = getReact();
|
|
728
792
|
ensureStatusCss();
|
|
793
|
+
ensureNavIconCss();
|
|
729
794
|
ctx.effect(() => ctx.locale.register(NS, {
|
|
730
795
|
zh,
|
|
731
796
|
en
|
|
732
797
|
}), "dsh-model-health: dictionaries");
|
|
733
798
|
const t = ctx.locale.bind(NS);
|
|
799
|
+
ctx.effect(() => registerSettingsNavIcon(() => t("tab")), "dsh-model-health: settings navigation icon");
|
|
734
800
|
ctx.slots.inject("settings.section", () => ctx.slots.register({
|
|
735
801
|
name: "settings.section",
|
|
736
802
|
id: "model-health",
|
package/package.json
CHANGED