dsh-skill-hub 0.3.3 → 0.3.5

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/lib/client.js CHANGED
@@ -48,6 +48,10 @@ window.__ModuleLoader__.load({
48
48
  sourceRestore: "/api/skill-hub/sources/restore",
49
49
  sourceTrashClear: "/api/skill-hub/sources/trash/clear"
50
50
  };
51
+ /** 项目级技能来源(它们有 workspace 归属,不属于「个人」组)。 */
52
+ function isProjectSource(source) {
53
+ return source === "project-dsh" || source === "project-agents";
54
+ }
51
55
  //#endregion
52
56
  //#region src/client/api.ts
53
57
  /**
@@ -842,334 +846,6 @@ window.__ModuleLoader__.load({
842
846
  };
843
847
  }
844
848
  //#endregion
845
- //#region src/client/grouping.ts
846
- /**
847
- * Derive a group switch view from its member names and the set of currently
848
- * enabled skill names (catalog.skills). Members not in the enabled set count
849
- * as disabled (catalog.disabled or absent read-only rows).
850
- */
851
- function groupSwitchView(members, enabledNames) {
852
- const enabled = [];
853
- const disabled = [];
854
- for (const name of members) if (enabledNames.has(name)) enabled.push(name);
855
- else disabled.push(name);
856
- return {
857
- state: disabled.length === 0 ? "on" : enabled.length === 0 ? "off" : "mixed",
858
- enabled,
859
- disabled
860
- };
861
- }
862
- /** Names of every group a skill belongs to (tags + collections). */
863
- function groupNamesOf(name, tags, collections) {
864
- const names = [];
865
- for (const tag of tags) if (tag.skillNames.includes(name)) names.push(tag.name);
866
- for (const collection of collections) if (collection.skillNames.includes(name)) names.push(collection.name);
867
- return names;
868
- }
869
- /**
870
- * Members of a group that are currently enabled AND also belong to at least
871
- * one other group — the set a "close" action must ask about.
872
- */
873
- function conflictsOnClose(members, enabledNames, otherGroups) {
874
- return members.filter((name) => {
875
- if (!enabledNames.has(name)) return false;
876
- return otherGroups.some((group) => group.members.includes(name));
877
- });
878
- }
879
- /** Origin-repo filter value: skills with no source record (private skills). */
880
- const PRIVATE_SOURCE = "private";
881
- /** 项目级技能来源(它们有 workspace 归属,不属于「个人」组)。 */
882
- function isProjectSource(source) {
883
- return source === "project-dsh" || source === "project-agents";
884
- }
885
- /**
886
- * Apply the origin filter ('all' or a specific origin repo; skills without a
887
- * source record count as PRIVATE_SOURCE). The origins map is the store's
888
- * skillName → repo derivation, so filtering follows the tracked source
889
- * records instead of the filesystem root a skill happens to live under.
890
- * 项目级技能(有 workspace 归属)永远不算「个人」。
891
- */
892
- function filterBySource(skills, source, origins) {
893
- if (source === "all") return [...skills];
894
- return skills.filter((skill) => {
895
- if (isProjectSource(skill.source)) return false;
896
- return (origins[skill.name] ?? "private") === source;
897
- });
898
- }
899
- /**
900
- * Sort a skill list in place-safe copy order: name ascending, added
901
- * descending (newest first, unknown addedAt last), or uses descending
902
- * (most-called first). Unknown values always trail.
903
- */
904
- function sortSkills(skills, key, getUses) {
905
- const list = [...skills];
906
- if (key === "name") list.sort((a, b) => a.name.localeCompare(b.name));
907
- else if (key === "added") list.sort((a, b) => (b.addedAt ?? -Infinity) - (a.addedAt ?? -Infinity));
908
- else if (key === "uses") list.sort((a, b) => (getUses?.(b.name) ?? 0) - (getUses?.(a.name) ?? 0));
909
- return list;
910
- }
911
- /** Format an epoch-ms timestamp as a short relative time bucket. */
912
- function formatRelativeTime(ms, now = Date.now()) {
913
- const diff = Math.max(0, now - ms);
914
- const minutes = Math.floor(diff / 6e4);
915
- if (minutes < 1) return { key: "time.justNow" };
916
- if (minutes < 60) return {
917
- key: "time.minutesAgo",
918
- value: minutes
919
- };
920
- const hours = Math.floor(minutes / 60);
921
- if (hours < 24) return {
922
- key: "time.hoursAgo",
923
- value: hours
924
- };
925
- const days = Math.floor(hours / 24);
926
- if (days < 7) return {
927
- key: "time.daysAgo",
928
- value: days
929
- };
930
- return {
931
- key: "time.weeksAgo",
932
- value: Math.floor(days / 7)
933
- };
934
- }
935
- //#endregion
936
- //#region src/client/helpers.ts
937
- /**
938
- * Shared panel helpers: the active-dictionary pick (document-language
939
- * based, family precedent) plus a small error-message extractor.
940
- */
941
- /** Active dictionary, picked by the document language at call time. */
942
- function dictionary() {
943
- return (typeof document !== "undefined" ? document.documentElement.lang : "zh").toLowerCase().startsWith("en") ? { ...en } : { ...zh };
944
- }
945
- /** Translate a key with optional {name} template params (current language). */
946
- function tt(key, values) {
947
- return t(dictionary(), key, values);
948
- }
949
- /** Human-readable error text from an unknown thrown value. */
950
- function errorMessage(error) {
951
- if (error instanceof Error) return error.message;
952
- return String(error);
953
- }
954
- //#endregion
955
- //#region src/client/panel/format.ts
956
- /** Model-invocable dot color default. Single source for the TS side; the
957
- * panel's CSS mirrors it via --hub-model (panel.module.css). */
958
- const DEFAULT_DOT_MODEL_COLOR = "#2f81f7";
959
- /** User-invocable dot color default. Single source for the TS side; the
960
- * panel's CSS mirrors it via --hub-user (panel.module.css). */
961
- const DEFAULT_DOT_USER_COLOR = "#3fb950";
962
- /** Dot inline style from the user-chosen color (undefined keeps the CSS default). */
963
- function dotStyle(color) {
964
- if (color === void 0) return void 0;
965
- return {
966
- background: color,
967
- borderColor: color
968
- };
969
- }
970
- /** Localized relative-time text for a Unix-ms timestamp. */
971
- function relativeTimeText(ms) {
972
- const rt = formatRelativeTime(ms);
973
- return tt(rt.key, rt.value !== void 0 ? { value: rt.value } : void 0);
974
- }
975
- /** Localized absolute time for the detail meta (e.g. "2026/8/16 11:00:00"). */
976
- function formatDateTime(ms) {
977
- return new Date(ms).toLocaleString();
978
- }
979
- /** Short form of a commit SHA for display. */
980
- function shortSha(sha) {
981
- return sha.length > 7 ? sha.slice(0, 7) : sha;
982
- }
983
- //#endregion
984
- //#region src/client/slash-dots.tsx
985
- /** The core plugin's skill source identity on the '/' trigger. */
986
- const SKILL_SOURCE = {
987
- trigger: "/",
988
- name: "skill"
989
- };
990
- /** How long one catalog-derived modelInvocable map stays hot before refresh. */
991
- const MODEL_TTL_MS = 6e4;
992
- /**
993
- * Find the core `/skill` source through the runtime registry, or undefined.
994
- * The lookup never throws: a missing/reshaped registry just means no dots. Exported
995
- * for unit tests; the apply path only calls it indirectly through setupSkillSlashDots.
996
- * @param service - the ctx.inputTriggers service face.
997
- * @returns the registered skill source, or undefined.
998
- */
999
- function findSkillSource(service) {
1000
- const live = service.live;
1001
- if (live?.sources === void 0) return void 0;
1002
- return live.sources.find((source) => source.trigger === SKILL_SOURCE.trigger && source.name === SKILL_SOURCE.name);
1003
- }
1004
- /** One catalog-derived name → modelInvocable snapshot with a load timestamp. */
1005
- let modelCache;
1006
- /**
1007
- * Clear the modelInvocable cache. Called on connection/reset so a fresh
1008
- * catalog wins after reconnect; exported for deterministic unit tests.
1009
- */
1010
- function resetModelCache() {
1011
- modelCache = void 0;
1012
- }
1013
- /**
1014
- * Resolve name → modelInvocable from the hub's catalog, cached for
1015
- * MODEL_TTL_MS. A failed load caches the failure briefly so a downed route
1016
- * doesn't hammer the host on every keystroke; the returned map is empty then
1017
- * (callers fall back to the model dot for unknown names).
1018
- * @param api - the hub browser API.
1019
- * @returns name → whether the model may call the skill.
1020
- */
1021
- async function modelInvocableMap(api) {
1022
- const now = Date.now();
1023
- const cached = modelCache;
1024
- if (cached !== void 0 && now - cached.at < MODEL_TTL_MS) return "failed" in cached ? /* @__PURE__ */ new Map() : cached.map;
1025
- try {
1026
- const catalog = await api.catalog();
1027
- const map = new Map(catalog.skills.map((skill) => [skill.name, skill.invocation.modelInvocable]));
1028
- modelCache = {
1029
- at: now,
1030
- map
1031
- };
1032
- return map;
1033
- } catch (error) {
1034
- console.error("[dsh-skill-hub] slash dot color lookup failed:", error);
1035
- modelCache = {
1036
- at: now,
1037
- failed: true
1038
- };
1039
- return /* @__PURE__ */ new Map();
1040
- }
1041
- }
1042
- /**
1043
- * One menu-row dot element. Inline span so it needs no CSS module; the
1044
- * candidate menu centers it inside its 16×16 leading icon slot.
1045
- * @param color - the dot's background color.
1046
- * @returns a React node (memory-only, never crosses the Host boundary).
1047
- */
1048
- function dotIcon(color) {
1049
- return (0, react.createElement)("span", {
1050
- "aria-hidden": true,
1051
- style: {
1052
- display: "inline-block",
1053
- width: 6,
1054
- height: 6,
1055
- borderRadius: 3,
1056
- background: color,
1057
- flex: "none"
1058
- }
1059
- });
1060
- }
1061
- /**
1062
- * Wrap the core skill source so every menu row carries the invocation dot.
1063
- * Exported for unit tests; production wiring goes through setupSkillSlashDots.
1064
- * @param source - the registered `/skill` source.
1065
- * @param api - hub browser API for the modelInvocable lookup.
1066
- * @param scope - hub settings scope for the dot colors.
1067
- * @returns a disposer restoring the original candidates.
1068
- */
1069
- /**
1070
- * DOM 兜底:在 alpha.2 新版 MenuView(icon 仅枚举)下通过直接操作
1071
- * 已渲染的 `[role="option"]` 列表注入彩色点,绕过 `icon` 限制。
1072
- * 旧版仍走 `icon` 注入,此处仅为新版。
1073
- */
1074
- function injectDotsViaDOM(modelByName, modelColor, userColor) {
1075
- if (typeof document === "undefined" || typeof requestAnimationFrame === "undefined") return;
1076
- const run = () => {
1077
- const options = document.querySelectorAll("[role=\"option\"]");
1078
- for (const opt of options) {
1079
- if (opt.querySelector("[data-skill-dot]") !== null) continue;
1080
- const nameEl = opt.querySelector("[class*=\"itemName\"]");
1081
- if (nameEl === null) continue;
1082
- const name = (nameEl.textContent ?? "").trim();
1083
- if (name.length === 0) continue;
1084
- const color = modelByName.get(name) ?? true ? modelColor : userColor;
1085
- const wrapper = document.createElement("span");
1086
- wrapper.setAttribute("data-skill-dot", "");
1087
- wrapper.setAttribute("aria-hidden", "true");
1088
- wrapper.style.width = "16px";
1089
- wrapper.style.height = "16px";
1090
- wrapper.style.display = "inline-flex";
1091
- wrapper.style.justifyContent = "center";
1092
- wrapper.style.alignItems = "center";
1093
- wrapper.style.flex = "none";
1094
- const dot = document.createElement("span");
1095
- dot.style.display = "inline-block";
1096
- dot.style.width = "6px";
1097
- dot.style.height = "6px";
1098
- dot.style.borderRadius = "3px";
1099
- dot.style.background = color;
1100
- dot.style.flex = "none";
1101
- wrapper.appendChild(dot);
1102
- nameEl.parentElement?.insertBefore(wrapper, nameEl);
1103
- }
1104
- };
1105
- requestAnimationFrame(() => setTimeout(run, 0));
1106
- }
1107
- function wrapSkillSource(source, api, scope) {
1108
- const original = source.candidates;
1109
- source.candidates = async (session, req) => {
1110
- const items = await original(session, req);
1111
- if (req.signal.aborted) return items;
1112
- const isNewHost = req !== null && typeof req === "object" && "drilled" in req;
1113
- const modelByName = await modelInvocableMap(api);
1114
- if (req.signal.aborted) return items;
1115
- const snapshot = scope.getSnapshot();
1116
- const modelColor = snapshot.value?.dotModelColor ?? "#2f81f7";
1117
- const userColor = snapshot.value?.dotUserColor ?? "#3fb950";
1118
- if (isNewHost) {
1119
- injectDotsViaDOM(modelByName, modelColor, userColor);
1120
- return items;
1121
- }
1122
- return items.map((item) => ({
1123
- ...item,
1124
- icon: dotIcon(modelByName.get(item.name) ?? true ? modelColor : userColor)
1125
- }));
1126
- };
1127
- return () => {
1128
- source.candidates = original;
1129
- };
1130
- }
1131
- /**
1132
- * Mount the slash-menu dots on the registered `/skill` source. Idempotent and
1133
- * defensive: if the core source isn't registered yet (or the registry shape
1134
- * changes), it retries briefly and then gives up silently — the chat keeps
1135
- * working, it simply shows no dots. The returned disposer restores the
1136
- * original candidates and clears the model cache.
1137
- * @param ctx - the client root context (inputTriggers + events).
1138
- * @param api - hub browser API.
1139
- * @param scope - hub settings scope for dot colors.
1140
- * @returns a cleanup function for `ctx.effect`.
1141
- */
1142
- function setupSkillSlashDots(ctx, api, scope) {
1143
- const inputTriggers = ctx.get("inputTriggers");
1144
- if (inputTriggers === void 0) return () => {};
1145
- let disposed = false;
1146
- let restore;
1147
- let attempts = 0;
1148
- const attempt = () => {
1149
- if (disposed) return;
1150
- const source = findSkillSource(inputTriggers);
1151
- if (source === void 0) {
1152
- if (attempts < 10) {
1153
- attempts += 1;
1154
- setTimeout(attempt, 100);
1155
- }
1156
- return;
1157
- }
1158
- restore = wrapSkillSource(source, api, scope);
1159
- };
1160
- attempt();
1161
- const clearCache = () => {
1162
- resetModelCache();
1163
- };
1164
- const offReset = ctx.on("connection/reset", clearCache);
1165
- return () => {
1166
- disposed = true;
1167
- offReset();
1168
- restore?.();
1169
- restore = void 0;
1170
- };
1171
- }
1172
- //#endregion
1173
849
  //#region src/client/icons.tsx
1174
850
  /** ic_ds_chevron_down_outline_14 */
1175
851
  function IconChevronDownOutline14({ size = 14, className }) {
@@ -2437,6 +2113,141 @@ window.__ModuleLoader__.load({
2437
2113
  }
2438
2114
  };
2439
2115
  //#endregion
2116
+ //#region src/client/grouping.ts
2117
+ /**
2118
+ * Derive a group switch view from its member names and the set of currently
2119
+ * enabled skill names (catalog.skills). Members not in the enabled set count
2120
+ * as disabled (catalog.disabled or absent read-only rows).
2121
+ */
2122
+ function groupSwitchView(members, enabledNames) {
2123
+ const enabled = [];
2124
+ const disabled = [];
2125
+ for (const name of members) if (enabledNames.has(name)) enabled.push(name);
2126
+ else disabled.push(name);
2127
+ return {
2128
+ state: disabled.length === 0 ? "on" : enabled.length === 0 ? "off" : "mixed",
2129
+ enabled,
2130
+ disabled
2131
+ };
2132
+ }
2133
+ /** Names of every group a skill belongs to (tags + collections). */
2134
+ function groupNamesOf(name, tags, collections) {
2135
+ const names = [];
2136
+ for (const tag of tags) if (tag.skillNames.includes(name)) names.push(tag.name);
2137
+ for (const collection of collections) if (collection.skillNames.includes(name)) names.push(collection.name);
2138
+ return names;
2139
+ }
2140
+ /**
2141
+ * Members of a group that are currently enabled AND also belong to at least
2142
+ * one other group — the set a "close" action must ask about.
2143
+ */
2144
+ function conflictsOnClose(members, enabledNames, otherGroups) {
2145
+ return members.filter((name) => {
2146
+ if (!enabledNames.has(name)) return false;
2147
+ return otherGroups.some((group) => group.members.includes(name));
2148
+ });
2149
+ }
2150
+ /** Origin-repo filter value: skills with no source record (private skills). */
2151
+ const PRIVATE_SOURCE = "private";
2152
+ /**
2153
+ * Apply the origin filter ('all' or a specific origin repo; skills without a
2154
+ * source record count as PRIVATE_SOURCE). The origins map is the store's
2155
+ * skillName → repo derivation, so filtering follows the tracked source
2156
+ * records instead of the filesystem root a skill happens to live under.
2157
+ * 项目级技能(有 workspace 归属)永远不算「个人」。
2158
+ */
2159
+ function filterBySource(skills, source, origins) {
2160
+ if (source === "all") return [...skills];
2161
+ return skills.filter((skill) => {
2162
+ if (isProjectSource(skill.source)) return false;
2163
+ return (origins[skill.name] ?? "private") === source;
2164
+ });
2165
+ }
2166
+ /**
2167
+ * Sort a skill list in place-safe copy order: name ascending, added
2168
+ * descending (newest first, unknown addedAt last), or uses descending
2169
+ * (most-called first). Unknown values always trail.
2170
+ */
2171
+ function sortSkills(skills, key, getUses) {
2172
+ const list = [...skills];
2173
+ if (key === "name") list.sort((a, b) => a.name.localeCompare(b.name));
2174
+ else if (key === "added") list.sort((a, b) => (b.addedAt ?? -Infinity) - (a.addedAt ?? -Infinity));
2175
+ else if (key === "uses") list.sort((a, b) => (getUses?.(b.name) ?? 0) - (getUses?.(a.name) ?? 0));
2176
+ return list;
2177
+ }
2178
+ /** Format an epoch-ms timestamp as a short relative time bucket. */
2179
+ function formatRelativeTime(ms, now = Date.now()) {
2180
+ const diff = Math.max(0, now - ms);
2181
+ const minutes = Math.floor(diff / 6e4);
2182
+ if (minutes < 1) return { key: "time.justNow" };
2183
+ if (minutes < 60) return {
2184
+ key: "time.minutesAgo",
2185
+ value: minutes
2186
+ };
2187
+ const hours = Math.floor(minutes / 60);
2188
+ if (hours < 24) return {
2189
+ key: "time.hoursAgo",
2190
+ value: hours
2191
+ };
2192
+ const days = Math.floor(hours / 24);
2193
+ if (days < 7) return {
2194
+ key: "time.daysAgo",
2195
+ value: days
2196
+ };
2197
+ return {
2198
+ key: "time.weeksAgo",
2199
+ value: Math.floor(days / 7)
2200
+ };
2201
+ }
2202
+ //#endregion
2203
+ //#region src/client/helpers.ts
2204
+ /**
2205
+ * Shared panel helpers: the active-dictionary pick (document-language
2206
+ * based, family precedent) plus a small error-message extractor.
2207
+ */
2208
+ /** Active dictionary, picked by the document language at call time. */
2209
+ function dictionary() {
2210
+ return (typeof document !== "undefined" ? document.documentElement.lang : "zh").toLowerCase().startsWith("en") ? { ...en } : { ...zh };
2211
+ }
2212
+ /** Translate a key with optional {name} template params (current language). */
2213
+ function tt(key, values) {
2214
+ return t(dictionary(), key, values);
2215
+ }
2216
+ /** Human-readable error text from an unknown thrown value. */
2217
+ function errorMessage(error) {
2218
+ if (error instanceof Error) return error.message;
2219
+ return String(error);
2220
+ }
2221
+ //#endregion
2222
+ //#region src/client/panel/format.ts
2223
+ /** Model-invocable dot color default. Single source for the TS side; the
2224
+ * panel's CSS mirrors it via --hub-model (panel.module.css). */
2225
+ const DEFAULT_DOT_MODEL_COLOR = "#2f81f7";
2226
+ /** User-invocable dot color default. Single source for the TS side; the
2227
+ * panel's CSS mirrors it via --hub-user (panel.module.css). */
2228
+ const DEFAULT_DOT_USER_COLOR = "#3fb950";
2229
+ /** Dot inline style from the user-chosen color (undefined keeps the CSS default). */
2230
+ function dotStyle(color) {
2231
+ if (color === void 0) return void 0;
2232
+ return {
2233
+ background: color,
2234
+ borderColor: color
2235
+ };
2236
+ }
2237
+ /** Localized relative-time text for a Unix-ms timestamp. */
2238
+ function relativeTimeText(ms) {
2239
+ const rt = formatRelativeTime(ms);
2240
+ return tt(rt.key, rt.value !== void 0 ? { value: rt.value } : void 0);
2241
+ }
2242
+ /** Localized absolute time for the detail meta (e.g. "2026/8/16 11:00:00"). */
2243
+ function formatDateTime(ms) {
2244
+ return new Date(ms).toLocaleString();
2245
+ }
2246
+ /** Short form of a commit SHA for display. */
2247
+ function shortSha(sha) {
2248
+ return sha.length > 7 ? sha.slice(0, 7) : sha;
2249
+ }
2250
+ //#endregion
2440
2251
  //#region src/client/SkillHubSettingsCard.tsx
2441
2252
  /**
2442
2253
  * The dsh-skill-hub plugin settings card: bridges the hub's settings
@@ -2655,7 +2466,7 @@ window.__ModuleLoader__.load({
2655
2466
  }
2656
2467
  //#endregion
2657
2468
  //#region \0dsh-css:/Users/huanyi/Documents/personal/tools/dsh-skill-hub/src/client/panel/panel.module.css.mjs
2658
- const css = "._6VtqdG_panel{-webkit-font-smoothing:antialiased;color-scheme:light dark;--hub-model:#2f81f7;--hub-user:#3fb950;flex-direction:column;gap:14px;max-width:720px;margin:0 auto;padding:28px 20px 44px;font-family:-apple-system,BlinkMacSystemFont,SF Pro Text,Helvetica Neue,sans-serif;display:flex}._6VtqdG_header{flex-wrap:wrap;align-items:baseline;gap:10px;display:flex}._6VtqdG_title{letter-spacing:-.02em;margin:0;font-size:24px;font-weight:700}._6VtqdG_hint{opacity:.5;font-size:12px}._6VtqdG_actions{gap:8px;margin-left:auto;display:flex}._6VtqdG_segmented{background:#80808024;border-radius:9px;gap:2px;padding:2px;display:flex}._6VtqdG_segBtn{color:inherit;opacity:.62;cursor:pointer;background:0 0;border:none;border-radius:7px;padding:5px 13px;font-size:12px;transition:background .15s,opacity .15s}._6VtqdG_segBtn:hover{opacity:.9}._6VtqdG_segBtnActive{opacity:1;background:#80808047;font-weight:600}._6VtqdG_search{width:100%;color:inherit;background:#8080801f;border:none;border-radius:10px;outline:none;padding:10px 14px;font-size:13px;transition:background .15s}._6VtqdG_search::placeholder{opacity:.45}._6VtqdG_search:focus{background:#8080802e}._6VtqdG_section{background:#8080800f;border-radius:12px;flex-direction:column;margin-top:4px;display:flex;overflow:hidden;box-shadow:0 1px 2px #00000008,0 4px 12px #0000000a}._6VtqdG_sectionTitle{margin:14px 16px 2px;font-size:13px;font-weight:700}._6VtqdG_groupHead{box-sizing:border-box;align-items:center;gap:8px;min-height:44px;padding:10px 14px;display:flex}._6VtqdG_groupTitle{opacity:.92;flex:1;align-items:center;gap:6px;min-width:0;font-size:13px;font-weight:600;line-height:1;display:inline-flex}._6VtqdG_groupOps{flex:none;align-items:center;gap:6px;display:inline-flex}._6VtqdG_opBtn{color:inherit;cursor:pointer;background:#80808021;border:none;border-radius:999px;padding:3px 11px;font-size:11px;transition:background .15s}._6VtqdG_opBtn:hover{background:#80808038}._6VtqdG_opBtn:disabled{opacity:.4;cursor:default}._6VtqdG_row{cursor:pointer;background:0 0;align-items:center;gap:12px;padding:10px 14px;transition:background .12s;display:flex}._6VtqdG_row:hover{background:#80808014}._6VtqdG_row:focus-visible{outline:2px solid var(--hub-model);outline-offset:-2px}._6VtqdG_rowStatic{cursor:default}._6VtqdG_rowStatic:hover{background:0 0}._6VtqdG_row+._6VtqdG_row{border-top:.5px solid #80808021}._6VtqdG_rowMain{flex:1;min-width:0}._6VtqdG_rowName{align-items:center;gap:5px;font-size:13.5px;display:flex}._6VtqdG_rowNameText{font-weight:600}._6VtqdG_rowDesc{opacity:.52;white-space:nowrap;text-overflow:ellipsis;margin-top:1px;font-size:12.5px;overflow:hidden}._6VtqdG_rowMeta{opacity:.45;white-space:nowrap;flex:none;font-size:11.5px}._6VtqdG_badges{flex:none;align-items:center;gap:6px;display:flex}._6VtqdG_badge{opacity:.8;white-space:nowrap;border:.5px solid #8080804d;border-radius:999px;padding:1px 7px;font-size:10.5px}._6VtqdG_badgeModel{color:var(--hub-model);border-color:currentColor}._6VtqdG_badgeUser{color:var(--hub-user);border-color:currentColor}._6VtqdG_badgeUses{color:#d29922;border-color:currentColor}._6VtqdG_badgeReadonly{opacity:.5}._6VtqdG_switch{cursor:pointer;background:#8080804d;border:none;border-radius:999px;flex:none;width:36px;height:21px;padding:2px;transition:background .18s}._6VtqdG_switch:disabled{opacity:.5;cursor:default}._6VtqdG_switchOn{background:#34c759}._6VtqdG_switchThumb{background:#fff;border-radius:50%;width:17px;height:17px;transition:transform .18s;display:block;transform:translate(0);box-shadow:0 1px 2px #00000040}._6VtqdG_switchOn ._6VtqdG_switchThumb{transform:translate(15px)}._6VtqdG_empty{opacity:.5;text-align:center;padding:20px 0;font-size:13px}._6VtqdG_diagRow{background:#d299220f;border-left:3px solid #d29922;padding:9px 14px;font-size:12px}._6VtqdG_diagPath{opacity:.75;word-break:break-all;font-family:ui-monospace,SFMono-Regular,Menlo,monospace;font-size:11px}._6VtqdG_diagReason{opacity:.65;margin-top:1px}._6VtqdG_updateLink{color:inherit;font-weight:600;text-decoration:underline}._6VtqdG_errorBanner{color:#d1242f;white-space:pre-wrap;word-break:break-all;background:#d1242f12;border-radius:10px;align-items:flex-start;gap:10px;padding:10px 14px;font-size:12.5px;display:flex}._6VtqdG_successBanner{color:#3fb950;white-space:pre-wrap;word-break:break-all;background:#3fb95014;border-radius:10px;align-items:flex-start;gap:10px;padding:10px 14px;font-size:12.5px;display:flex}._6VtqdG_detailHead{flex-wrap:wrap;align-items:center;gap:10px;display:flex}._6VtqdG_back{color:inherit;cursor:pointer;background:#8080801f;border:none;border-radius:8px;padding:6px 12px;font-size:12.5px}._6VtqdG_back:hover{background:#80808033}._6VtqdG_detailName{letter-spacing:-.01em;font-size:19px;font-weight:700}._6VtqdG_detailMeta{opacity:.6;flex-direction:column;gap:4px;font-size:12px;display:flex}._6VtqdG_detailMetaLine{word-break:break-all}._6VtqdG_detailContent{white-space:pre-wrap;word-break:break-word;background:#8080800d;border-radius:12px;max-height:62vh;padding:14px 16px;font-family:ui-monospace,SFMono-Regular,Menlo,monospace;font-size:12px;line-height:1.6;overflow:auto}._6VtqdG_form{background:#8080800d;border-radius:12px;flex-direction:column;gap:10px;padding:14px 16px;display:flex;box-shadow:0 1px 2px #00000008,0 4px 12px #0000000a}._6VtqdG_formRow{flex-direction:column;gap:5px;display:flex}._6VtqdG_formLabel{opacity:.6;font-size:12px}._6VtqdG_input,._6VtqdG_select{color:inherit;background:#8080801f;border:none;border-radius:9px;outline:none;padding:9px 12px;font-size:13px}._6VtqdG_input:focus,._6VtqdG_select:focus{background:#8080802e}._6VtqdG_buttons{align-items:center;gap:8px;display:flex}._6VtqdG_button{cursor:pointer;color:inherit;background:#8080801f;border:none;border-radius:8px;padding:6px 13px;font-size:12.5px;transition:background .15s}._6VtqdG_button:hover{background:#80808033}._6VtqdG_primary{background:var(--hub-model);color:#fff}._6VtqdG_primary:hover{opacity:.92;background:#2f81f7}._6VtqdG_primary:disabled{opacity:.45;cursor:default}._6VtqdG_danger{color:#fff;background:#d1242f}._6VtqdG_danger:hover{opacity:.92;background:#d1242f}._6VtqdG_danger:disabled{opacity:.45;cursor:default}._6VtqdG_formError{color:#d1242f}._6VtqdG_formSuccess{color:#3fb950}._6VtqdG_muted{opacity:.55}._6VtqdG_dot{vertical-align:middle;border-radius:50%;width:7px;height:7px;margin-left:5px;display:inline-block}._6VtqdG_dotModel{background:var(--hub-model)}._6VtqdG_dotUser{background:var(--hub-user)}._6VtqdG_legend{opacity:.55;flex-wrap:wrap;align-items:center;gap:12px;padding:2px 2px 0;font-size:11.5px;display:flex}._6VtqdG_legendItem{align-items:center;gap:4px;display:inline-flex}._6VtqdG_legendItem ._6VtqdG_dot{margin-left:0}._6VtqdG_legendHint{opacity:.8}._6VtqdG_badgeSource,._6VtqdG_badgeCount{opacity:.72;background:#8080801a;border:none}._6VtqdG_badgeDisabled{opacity:.58;background:#8080801a;border:none}._6VtqdG_disclosure{min-width:0;color:inherit;cursor:pointer;text-align:left;background:0 0;border:none;flex:1;align-items:center;gap:7px;min-height:24px;padding:2px 0;display:flex}._6VtqdG_disclosure:hover ._6VtqdG_groupTitle{opacity:1}._6VtqdG_chevron{opacity:.55;border-bottom:1.5px solid;border-right:1.5px solid;flex:none;align-self:center;width:8px;height:8px;margin-right:2px;transition:transform .15s;transform:rotate(45deg)translateY(-1px)}._6VtqdG_chevronCollapsed{transform:rotate(-45deg)translateY(-1px)}._6VtqdG_headerCount{opacity:.5;white-space:nowrap;margin-left:2px;font-size:12px}._6VtqdG_pluginVersion{opacity:.45;white-space:nowrap;font-variant-numeric:tabular-nums;margin-left:6px;font-size:12px;font-weight:500}._6VtqdG_subbar{flex-wrap:wrap;align-items:center;gap:8px;display:flex}._6VtqdG_legendToggle{width:22px;height:22px;color:inherit;cursor:pointer;opacity:.55;background:#80808024;border:none;border-radius:50%;flex:none;font-size:12px;line-height:1;transition:opacity .15s,background .15s}._6VtqdG_legendToggle:hover{opacity:1}._6VtqdG_legendToggleActive{opacity:1;background:#80808047}._6VtqdG_filterBar{flex-wrap:wrap;align-items:center;gap:8px;display:flex}._6VtqdG_filterBar ._6VtqdG_formLabel{margin:0}._6VtqdG_useCount{color:#d29922;vertical-align:1px;background:#d299221f;border-radius:999px;margin-left:6px;padding:0 6px;font-size:11px;font-weight:700;line-height:1.6;display:inline-block}._6VtqdG_useTime{opacity:.45;white-space:nowrap;margin-left:auto;font-size:11px}._6VtqdG_switchMixed{background:#2f81f773}._6VtqdG_switchMixed ._6VtqdG_switchThumb{transform:translate(7.5px);box-shadow:0 1px 2px #00000040}._6VtqdG_groupTitleInner{align-items:baseline;display:inline-flex}._6VtqdG_groupOps{flex-wrap:wrap;flex:none;align-items:center;gap:6px;display:inline-flex}._6VtqdG_sourceLink{color:inherit;opacity:.9;border-bottom:1px dotted;font-weight:600;text-decoration:none}._6VtqdG_sourceLink:hover{opacity:1}._6VtqdG_statusBadges{flex:none;align-items:center;gap:4px;display:inline-flex}._6VtqdG_statusBadge{opacity:.8;white-space:nowrap;background:#8080801a;border:.5px solid #8080804d;border-radius:999px;padding:1px 7px;font-size:10.5px}._6VtqdG_statusOk{color:#3fb950;background:0 0;border-color:currentColor}._6VtqdG_statusUpdated{color:#d29922;background:#d2992214;border-color:currentColor}._6VtqdG_statusError{color:#d1242f;background:#d1242f14;border-color:currentColor}._6VtqdG_statusWrap{cursor:pointer;background:0 0;border:none;align-items:center;gap:4px;padding:0;font-family:inherit;display:inline-flex}._6VtqdG_statusWrap:hover ._6VtqdG_statusBadge{opacity:1}._6VtqdG_statusButton{cursor:pointer;font-family:inherit}._6VtqdG_statusButton:hover{opacity:1}._6VtqdG_opDanger{color:#d1242f;background:#d1242f1a}._6VtqdG_opDanger:hover{background:#d1242f2e}._6VtqdG_iconBtn{border-radius:999px;justify-content:center;align-items:center;width:24px;height:24px;padding:0;display:inline-flex}._6VtqdG_sourceCard{background:#8080800d;border-radius:12px;flex-direction:column;gap:4px;padding:12px 14px;font-size:12px;display:flex}._6VtqdG_sourceCardTitle{flex-wrap:wrap;align-items:center;gap:8px;display:flex}._6VtqdG_dialogOverlay{z-index:50;-webkit-backdrop-filter:blur(2px);background:#00000059;justify-content:center;align-items:center;padding:24px;display:flex;position:fixed;inset:0}._6VtqdG_dialog{background:var(--dsw-surface,#f5f5f7);min-width:min(320px,100%);max-width:380px;color:var(--dsw-text,#1d1d1f);border-radius:14px;padding:18px 18px 14px;box-shadow:0 12px 40px #00000047,0 2px 8px #00000029}@media (prefers-color-scheme:dark){._6VtqdG_dialog{color:#f5f5f7;background:#2c2c2e}}._6VtqdG_dialogTitle{letter-spacing:-.01em;margin:0 0 8px;font-size:15px;font-weight:700}._6VtqdG_dialogText{opacity:.65;margin:0 0 10px;font-size:12.5px;line-height:1.5}._6VtqdG_dialogList{flex-direction:column;gap:5px;max-height:200px;margin:0 0 14px;padding:0;list-style:none;display:flex;overflow:auto}._6VtqdG_dialogList li{opacity:.85;word-break:break-all;font-size:12.5px}._6VtqdG_dialogActions{justify-content:flex-end;gap:8px;display:flex}._6VtqdG_filterBar ._6VtqdG_search{flex:1;min-width:160px}._6VtqdG_filterBar ._6VtqdG_formLabel{flex:none}._6VtqdG_filterBar ._6VtqdG_select{flex:none;max-width:150px}._6VtqdG_filterBar ._6VtqdG_segmented{flex:none}._6VtqdG_titleIcon{vertical-align:-2px;opacity:.8;margin-right:2px;display:inline-block}._6VtqdG_grow{flex:1}._6VtqdG_hintLine{opacity:.55;margin:0;font-size:11.5px}._6VtqdG_hintPadded{margin:6px 12px 2px}._6VtqdG_hintInline{margin:4px 2px}._6VtqdG_rowMuted{cursor:default;opacity:.55}._6VtqdG_actionsPadded{padding:8px 12px}._6VtqdG_actionsTop{margin-top:8px}._6VtqdG_actionsBottom{margin-bottom:8px}._6VtqdG_groupTime{margin-left:6px}._6VtqdG_sectionHeadRow{align-items:center;gap:8px;display:flex}._6VtqdG_sectionTitleFill{flex:1}._6VtqdG_dialogSelect{width:100%;margin-bottom:12px}._6VtqdG_dialogRow{align-items:center;gap:8px;display:flex}._6VtqdG_workspaceBox{align-items:center;gap:6px;display:inline-flex}._6VtqdG_workspaceInput{width:200px;padding:6px 10px;font-size:12px}._6VtqdG_projectNest{border-left:1px solid #80808024;flex-direction:column;margin:2px 0 0 14px;display:flex}._6VtqdG_dragHandle{cursor:grab;opacity:.32;letter-spacing:1px;user-select:none;flex:none;justify-content:center;align-self:center;align-items:center;height:20px;padding:0 4px;font-size:11px;display:inline-flex}._6VtqdG_dragHandle:active{cursor:grabbing}._6VtqdG_dragging{opacity:.45}._6VtqdG_dragOver{outline:2px dashed var(--hub-model,#2f81f7);outline-offset:-2px;background:#2f81f712}._6VtqdG_scanList{background:#8080800f;border:.5px solid #80808021;border-radius:12px;max-height:360px;margin-top:8px;overflow:auto}._6VtqdG_scanProgressTrack{background:#80808021;border-radius:4px;flex:1;height:6px;overflow:hidden}._6VtqdG_scanProgressFill{background:var(--hub-model,#2f81f7);height:100%;transition:width .2s}";
2469
+ const css = "._6VtqdG_panel{-webkit-font-smoothing:antialiased;color-scheme:light dark;--hub-model:#2f81f7;--hub-user:#3fb950;flex-direction:column;gap:14px;max-width:720px;margin:0 auto;padding:28px 20px 44px;font-family:-apple-system,BlinkMacSystemFont,SF Pro Text,Helvetica Neue,sans-serif;display:flex}._6VtqdG_header{flex-wrap:wrap;align-items:baseline;gap:10px;display:flex}._6VtqdG_title{letter-spacing:-.02em;margin:0;font-size:24px;font-weight:700}._6VtqdG_hint{opacity:.5;font-size:12px}._6VtqdG_actions{gap:8px;margin-left:auto;display:flex}._6VtqdG_segmented{background:#80808024;border-radius:9px;gap:2px;padding:2px;display:flex}._6VtqdG_segBtn{color:inherit;opacity:.62;cursor:pointer;background:0 0;border:none;border-radius:7px;padding:5px 13px;font-size:12px;transition:background .15s,opacity .15s}._6VtqdG_segBtn:hover{opacity:.9}._6VtqdG_segBtnActive{opacity:1;background:#80808047;font-weight:600}._6VtqdG_search{width:100%;color:inherit;background:#8080801f;border:none;border-radius:10px;outline:none;padding:10px 14px;font-size:13px;transition:background .15s}._6VtqdG_search::placeholder{opacity:.45}._6VtqdG_search:focus{background:#8080802e}._6VtqdG_section{background:#8080800f;border-radius:12px;flex-direction:column;margin-top:4px;display:flex;overflow:hidden;box-shadow:0 1px 2px #00000008,0 4px 12px #0000000a}._6VtqdG_sectionTitle{margin:14px 16px 2px;font-size:13px;font-weight:700}._6VtqdG_groupHead{box-sizing:border-box;align-items:center;gap:8px;min-height:44px;padding:10px 14px;display:flex}._6VtqdG_groupTitle{opacity:.92;flex:1;align-items:center;gap:6px;min-width:0;font-size:13px;font-weight:600;line-height:1;display:inline-flex}._6VtqdG_groupOps{flex-wrap:wrap;flex:none;align-items:center;gap:6px;display:inline-flex}._6VtqdG_opBtn{color:inherit;cursor:pointer;background:#80808021;border:none;border-radius:999px;padding:3px 11px;font-size:11px;transition:background .15s}._6VtqdG_opBtn:hover{background:#80808038}._6VtqdG_opBtn:disabled{opacity:.4;cursor:default}._6VtqdG_row{cursor:pointer;background:0 0;align-items:center;gap:12px;padding:10px 14px;transition:background .12s;display:flex}._6VtqdG_row:hover{background:#80808014}._6VtqdG_row:focus-visible{outline:2px solid var(--hub-model);outline-offset:-2px}._6VtqdG_rowStatic{cursor:default}._6VtqdG_rowStatic:hover{background:0 0}._6VtqdG_row+._6VtqdG_row{border-top:.5px solid #80808021}._6VtqdG_rowMain{flex:1;min-width:0}._6VtqdG_rowName{align-items:center;gap:5px;font-size:13.5px;display:flex}._6VtqdG_rowNameText{font-weight:600}._6VtqdG_rowDesc{opacity:.52;white-space:nowrap;text-overflow:ellipsis;margin-top:1px;font-size:12.5px;overflow:hidden}._6VtqdG_rowMeta{opacity:.45;white-space:nowrap;flex:none;font-size:11.5px}._6VtqdG_badges{flex:none;align-items:center;gap:6px;display:flex}._6VtqdG_badge{opacity:.8;white-space:nowrap;border:.5px solid #8080804d;border-radius:999px;padding:1px 7px;font-size:10.5px}._6VtqdG_badgeModel{color:var(--hub-model);border-color:currentColor}._6VtqdG_badgeUser{color:var(--hub-user);border-color:currentColor}._6VtqdG_badgeUses{color:#d29922;border-color:currentColor}._6VtqdG_badgeReadonly{opacity:.5}._6VtqdG_switch{cursor:pointer;background:#8080804d;border:none;border-radius:999px;flex:none;width:36px;height:21px;padding:2px;transition:background .18s}._6VtqdG_switch:disabled{opacity:.5;cursor:default}._6VtqdG_switchOn{background:#34c759}._6VtqdG_switchThumb{background:#fff;border-radius:50%;width:17px;height:17px;transition:transform .18s;display:block;transform:translate(0);box-shadow:0 1px 2px #00000040}._6VtqdG_switchOn ._6VtqdG_switchThumb{transform:translate(15px)}._6VtqdG_empty{opacity:.5;text-align:center;padding:20px 0;font-size:13px}._6VtqdG_diagRow{background:#d299220f;border-left:3px solid #d29922;padding:9px 14px;font-size:12px}._6VtqdG_diagPath{opacity:.75;word-break:break-all;font-family:ui-monospace,SFMono-Regular,Menlo,monospace;font-size:11px}._6VtqdG_diagReason{opacity:.65;margin-top:1px}._6VtqdG_updateLink{color:inherit;font-weight:600;text-decoration:underline}._6VtqdG_errorBanner{color:#d1242f;white-space:pre-wrap;word-break:break-all;background:#d1242f12;border-radius:10px;align-items:flex-start;gap:10px;padding:10px 14px;font-size:12.5px;display:flex}._6VtqdG_successBanner{color:#3fb950;white-space:pre-wrap;word-break:break-all;background:#3fb95014;border-radius:10px;align-items:flex-start;gap:10px;padding:10px 14px;font-size:12.5px;display:flex}._6VtqdG_detailHead{flex-wrap:wrap;align-items:center;gap:10px;display:flex}._6VtqdG_back{color:inherit;cursor:pointer;background:#8080801f;border:none;border-radius:8px;padding:6px 12px;font-size:12.5px}._6VtqdG_back:hover{background:#80808033}._6VtqdG_detailName{letter-spacing:-.01em;font-size:19px;font-weight:700}._6VtqdG_detailMeta{opacity:.6;flex-direction:column;gap:4px;font-size:12px;display:flex}._6VtqdG_detailMetaLine{word-break:break-all}._6VtqdG_detailContent{white-space:pre-wrap;word-break:break-word;background:#8080800d;border-radius:12px;max-height:62vh;padding:14px 16px;font-family:ui-monospace,SFMono-Regular,Menlo,monospace;font-size:12px;line-height:1.6;overflow:auto}._6VtqdG_form{background:#8080800d;border-radius:12px;flex-direction:column;gap:10px;padding:14px 16px;display:flex;box-shadow:0 1px 2px #00000008,0 4px 12px #0000000a}._6VtqdG_formRow{flex-direction:column;gap:5px;display:flex}._6VtqdG_formLabel{opacity:.6;font-size:12px}._6VtqdG_input,._6VtqdG_select{color:inherit;background:#8080801f;border:none;border-radius:9px;outline:none;padding:9px 12px;font-size:13px}._6VtqdG_input:focus,._6VtqdG_select:focus{background:#8080802e}._6VtqdG_buttons{align-items:center;gap:8px;display:flex}._6VtqdG_button{cursor:pointer;color:inherit;background:#8080801f;border:none;border-radius:8px;padding:6px 13px;font-size:12.5px;transition:background .15s}._6VtqdG_button:hover{background:#80808033}._6VtqdG_primary{background:var(--hub-model);color:#fff}._6VtqdG_primary:hover{opacity:.92;background:#2f81f7}._6VtqdG_primary:disabled{opacity:.45;cursor:default}._6VtqdG_danger{color:#fff;background:#d1242f}._6VtqdG_danger:hover{opacity:.92;background:#d1242f}._6VtqdG_danger:disabled{opacity:.45;cursor:default}._6VtqdG_formError{color:#d1242f}._6VtqdG_formSuccess{color:#3fb950}._6VtqdG_muted{opacity:.55}._6VtqdG_dot{vertical-align:middle;border-radius:50%;width:7px;height:7px;margin-left:5px;display:inline-block}._6VtqdG_dotModel{background:var(--hub-model)}._6VtqdG_dotUser{background:var(--hub-user)}._6VtqdG_legend{opacity:.55;flex-wrap:wrap;align-items:center;gap:12px;padding:2px 2px 0;font-size:11.5px;display:flex}._6VtqdG_legendItem{align-items:center;gap:4px;display:inline-flex}._6VtqdG_legendItem ._6VtqdG_dot{margin-left:0}._6VtqdG_legendHint{opacity:.8}._6VtqdG_badgeSource,._6VtqdG_badgeCount{opacity:.72;background:#8080801a;border:none}._6VtqdG_badgeDisabled{opacity:.58;background:#8080801a;border:none}._6VtqdG_disclosure{min-width:0;color:inherit;cursor:pointer;text-align:left;background:0 0;border:none;flex:1;align-items:center;gap:7px;min-height:24px;padding:2px 0;display:flex}._6VtqdG_disclosure:hover ._6VtqdG_groupTitle{opacity:1}._6VtqdG_chevron{opacity:.55;border-bottom:1.5px solid;border-right:1.5px solid;flex:none;align-self:center;width:8px;height:8px;margin-right:2px;transition:transform .15s;transform:rotate(45deg)translateY(-1px)}._6VtqdG_chevronCollapsed{transform:rotate(-45deg)translateY(-1px)}._6VtqdG_headerCount{opacity:.5;white-space:nowrap;margin-left:2px;font-size:12px}._6VtqdG_pluginVersion{opacity:.45;white-space:nowrap;font-variant-numeric:tabular-nums;margin-left:6px;font-size:12px;font-weight:500}._6VtqdG_subbar{flex-wrap:wrap;align-items:center;gap:8px;display:flex}._6VtqdG_legendToggle{width:22px;height:22px;color:inherit;cursor:pointer;opacity:.55;background:#80808024;border:none;border-radius:50%;flex:none;font-size:12px;line-height:1;transition:opacity .15s,background .15s}._6VtqdG_legendToggle:hover{opacity:1}._6VtqdG_legendToggleActive{opacity:1;background:#80808047}._6VtqdG_filterBar{flex-wrap:wrap;align-items:center;gap:8px;display:flex}._6VtqdG_filterBar ._6VtqdG_formLabel{margin:0}._6VtqdG_useCount{color:#d29922;vertical-align:1px;background:#d299221f;border-radius:999px;margin-left:6px;padding:0 6px;font-size:11px;font-weight:700;line-height:1.6;display:inline-block}._6VtqdG_useTime{opacity:.45;white-space:nowrap;margin-left:auto;font-size:11px}._6VtqdG_switchMixed{background:#2f81f773}._6VtqdG_switchMixed ._6VtqdG_switchThumb{transform:translate(7.5px);box-shadow:0 1px 2px #00000040}._6VtqdG_groupTitleInner{align-items:baseline;display:inline-flex}._6VtqdG_sourceLink{color:inherit;opacity:.9;border-bottom:1px dotted;font-weight:600;text-decoration:none}._6VtqdG_sourceLink:hover{opacity:1}._6VtqdG_statusBadges{flex:none;align-items:center;gap:4px;display:inline-flex}._6VtqdG_statusBadge{opacity:.8;white-space:nowrap;background:#8080801a;border:.5px solid #8080804d;border-radius:999px;padding:1px 7px;font-size:10.5px}._6VtqdG_statusOk{color:#3fb950;background:0 0;border-color:currentColor}._6VtqdG_statusUpdated{color:#d29922;background:#d2992214;border-color:currentColor}._6VtqdG_statusError{color:#d1242f;background:#d1242f14;border-color:currentColor}._6VtqdG_statusWrap{cursor:pointer;background:0 0;border:none;align-items:center;gap:4px;padding:0;font-family:inherit;display:inline-flex}._6VtqdG_statusWrap:hover ._6VtqdG_statusBadge{opacity:1}._6VtqdG_statusButton{cursor:pointer;font-family:inherit}._6VtqdG_statusButton:hover{opacity:1}._6VtqdG_opDanger{color:#d1242f;background:#d1242f1a}._6VtqdG_opDanger:hover{background:#d1242f2e}._6VtqdG_iconBtn{border-radius:999px;justify-content:center;align-items:center;width:24px;height:24px;padding:0;display:inline-flex}._6VtqdG_sourceCard{background:#8080800d;border-radius:12px;flex-direction:column;gap:4px;padding:12px 14px;font-size:12px;display:flex}._6VtqdG_sourceCardTitle{flex-wrap:wrap;align-items:center;gap:8px;display:flex}._6VtqdG_dialogOverlay{z-index:50;-webkit-backdrop-filter:blur(2px);background:#00000059;justify-content:center;align-items:center;padding:24px;display:flex;position:fixed;inset:0}._6VtqdG_dialog{background:var(--dsw-surface,#f5f5f7);min-width:min(320px,100%);max-width:380px;color:var(--dsw-text,#1d1d1f);border-radius:14px;padding:18px 18px 14px;box-shadow:0 12px 40px #00000047,0 2px 8px #00000029}@media (prefers-color-scheme:dark){._6VtqdG_dialog{color:#f5f5f7;background:#2c2c2e}}._6VtqdG_dialogTitle{letter-spacing:-.01em;margin:0 0 8px;font-size:15px;font-weight:700}._6VtqdG_dialogText{opacity:.65;margin:0 0 10px;font-size:12.5px;line-height:1.5}._6VtqdG_dialogList{flex-direction:column;gap:5px;max-height:200px;margin:0 0 14px;padding:0;list-style:none;display:flex;overflow:auto}._6VtqdG_dialogList li{opacity:.85;word-break:break-all;font-size:12.5px}._6VtqdG_dialogActions{justify-content:flex-end;gap:8px;display:flex}._6VtqdG_filterBar ._6VtqdG_search{flex:1;min-width:160px}._6VtqdG_filterBar ._6VtqdG_formLabel{flex:none}._6VtqdG_filterBar ._6VtqdG_select{flex:none;max-width:150px}._6VtqdG_filterBar ._6VtqdG_segmented{flex:none}._6VtqdG_titleIcon{vertical-align:-2px;opacity:.8;margin-right:2px;display:inline-block}._6VtqdG_grow{flex:1}._6VtqdG_hintLine{opacity:.55;margin:0;font-size:11.5px}._6VtqdG_hintPadded{margin:6px 12px 2px}._6VtqdG_hintInline{margin:4px 2px}._6VtqdG_rowMuted{cursor:default;opacity:.55}._6VtqdG_actionsPadded{padding:8px 12px}._6VtqdG_actionsTop{margin-top:8px}._6VtqdG_actionsBottom{margin-bottom:8px}._6VtqdG_groupTime{margin-left:6px}._6VtqdG_sectionHeadRow{align-items:center;gap:8px;display:flex}._6VtqdG_sectionTitleFill{flex:1}._6VtqdG_dialogSelect{width:100%;margin-bottom:12px}._6VtqdG_dialogRow{align-items:center;gap:8px;display:flex}._6VtqdG_workspaceBox{align-items:center;gap:6px;display:inline-flex}._6VtqdG_workspaceInput{width:200px;padding:6px 10px;font-size:12px}._6VtqdG_projectNest{border-left:1px solid #80808024;flex-direction:column;margin:2px 0 0 14px;display:flex}._6VtqdG_dragHandle{cursor:grab;opacity:.32;letter-spacing:1px;user-select:none;flex:none;justify-content:center;align-self:center;align-items:center;height:20px;padding:0 4px;font-size:11px;display:inline-flex}._6VtqdG_dragHandle:active{cursor:grabbing}._6VtqdG_dragging{opacity:.45}._6VtqdG_dragOver{outline:2px dashed var(--hub-model,#2f81f7);outline-offset:-2px;background:#2f81f712}._6VtqdG_scanList{background:#8080800f;border:.5px solid #80808021;border-radius:12px;max-height:360px;margin-top:8px;overflow:auto}._6VtqdG_scanProgressTrack{background:#80808021;border-radius:4px;flex:1;height:6px;overflow:hidden}._6VtqdG_scanProgressFill{background:var(--hub-model,#2f81f7);height:100%;transition:width .2s}";
2659
2470
  const tagId = "dsh-skill-hub/panel.module.css";
2660
2471
  if (typeof document !== "undefined" && document.querySelector("style[data-plugin-css=" + JSON.stringify(tagId) + "]") === null) {
2661
2472
  const tag = document.createElement("style");
@@ -4365,33 +4176,23 @@ window.__ModuleLoader__.load({
4365
4176
  alignItems: "center",
4366
4177
  gap: 6
4367
4178
  },
4368
- children: [
4369
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { style: {
4370
- width: 7,
4371
- height: 7,
4372
- borderRadius: "50%",
4373
- background: "var(--hub-model, #2f81f7)",
4374
- display: "inline-block"
4375
- } }),
4376
- "扫描结果",
4377
- /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
4378
- style: {
4379
- fontWeight: 400,
4380
- opacity: .75
4381
- },
4382
- children: [
4383
- "— ",
4384
- repoDiscoverState.status === "ready" ? repoDiscoverState.data.repo : repoDiscoverState.status === "error" ? scanningRepo ?? "" : scanningRepo ?? "",
4385
- repoDiscoverState.status === "ready" && repoDiscoverState.data.ref !== null ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
4386
- style: {
4387
- opacity: .5,
4388
- marginLeft: 6
4389
- },
4390
- children: ["ref ", repoDiscoverState.data.ref]
4391
- }) : null
4392
- ]
4393
- })
4394
- ]
4179
+ children: ["扫描结果", /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
4180
+ style: {
4181
+ fontWeight: 400,
4182
+ opacity: .75
4183
+ },
4184
+ children: [
4185
+ "— ",
4186
+ repoDiscoverState.status === "ready" ? repoDiscoverState.data.repo : repoDiscoverState.status === "error" ? scanningRepo ?? "" : scanningRepo ?? "",
4187
+ repoDiscoverState.status === "ready" && repoDiscoverState.data.ref !== null ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
4188
+ style: {
4189
+ opacity: .5,
4190
+ marginLeft: 6
4191
+ },
4192
+ children: ["ref ", repoDiscoverState.data.ref]
4193
+ }) : null
4194
+ ]
4195
+ })]
4395
4196
  }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
4396
4197
  type: "button",
4397
4198
  className: panel_module_css_default.opBtn,
@@ -6532,8 +6333,7 @@ window.__ModuleLoader__.load({
6532
6333
  "locale",
6533
6334
  "connection",
6534
6335
  "remote",
6535
- "settingsScope",
6536
- "inputTriggers"
6336
+ "settingsScope"
6537
6337
  ];
6538
6338
  /**
6539
6339
  * Mount the settings card and the skill hub section.
@@ -6547,7 +6347,6 @@ window.__ModuleLoader__.load({
6547
6347
  const t = ctx.locale.bind(NS);
6548
6348
  const api = new SkillHubApi();
6549
6349
  const settingsCard = new SkillHubSettingsCardController(ctx.settingsScope.bind({ namespace: NS }));
6550
- ctx.effect(() => setupSkillSlashDots(ctx, api, ctx.settingsScope.bind({ namespace: NS })), "dsh-skill-hub: slash dots");
6551
6350
  ctx.effect(() => ctx.slots.inject("settings.plugin.item", () => ctx.slots.register({
6552
6351
  name: "settings.plugin.item",
6553
6352
  key: NS,