dsh-brief-sidebar 0.9.4 → 0.9.6

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/dsh.plugin.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "id": "dsh-external/dsh-brief-sidebar",
3
- "version": "0.9.4",
3
+ "version": "0.9.6",
4
4
  "main": "./lib/index.mjs",
5
5
  "description": "会话简报侧栏页(brief):把会话的 todo 列表(`todos` 投影的进展看板)、产物列表(`dshSummaryDeliverables` 投影的实时产出文件)与记忆槽位(`memorySlots` 投影,来自 dsh-prime-memory,开关可关)一起渲染成右侧栏的一个「概要」tab,并遮蔽 DSH 官方那条 composer 上方的 todo 面板。只读展示,不做写回。",
6
6
  "engines": {
package/lib/client.js CHANGED
@@ -253,7 +253,7 @@ window.__ModuleLoader__.load({
253
253
  display: "flex",
254
254
  flexDirection: "column"
255
255
  };
256
- const ROW_STYLE$6 = {
256
+ const ROW_STYLE$5 = {
257
257
  display: "flex",
258
258
  alignItems: "flex-start",
259
259
  gap: 8,
@@ -305,7 +305,7 @@ window.__ModuleLoader__.load({
305
305
  /** One task row. */
306
306
  function TodoRow(props) {
307
307
  const { item, t } = props;
308
- return (0, react.createElement)("li", { style: ROW_STYLE$6 }, (0, react.createElement)("span", { style: pillStyle(item.status) }, t(statusKey(item.status))), (0, react.createElement)("span", { style: contentStyle(item.status) }, item.content));
308
+ return (0, react.createElement)("li", { style: ROW_STYLE$5 }, (0, react.createElement)("span", { style: pillStyle(item.status) }, t(statusKey(item.status))), (0, react.createElement)("span", { style: contentStyle(item.status) }, item.content));
309
309
  }
310
310
  /**
311
311
  * The progress section. The subscription is unconditional (a plain listener,
@@ -364,8 +364,9 @@ window.__ModuleLoader__.load({
364
364
  const SKILL_USAGE_KEY = "dshSummarySkillUsage";
365
365
  /**
366
366
  * The search-reference key (queries and returned sources of this session's
367
- * `advanced_search` calls). Same rule as above: the name is ours, so no other
368
- * host-side unit can answer for it by accident.
367
+ * web searches — the plugin's `advanced_search` and the harness's `web_search`).
368
+ * Same rule as above: the name is ours, so no other host-side unit can answer
369
+ * for it by accident.
369
370
  */
370
371
  const SEARCH_REFS_KEY = "dshSummarySearchRefs";
371
372
  //#endregion
@@ -708,7 +709,7 @@ window.__ModuleLoader__.load({
708
709
  "section.searchRefs": "搜索引用",
709
710
  "references.tabSearch": "搜索",
710
711
  "searchRefs.empty": "本会话还没搜索过",
711
- "searchRefs.emptyHint": "模型调用 advanced_search 之后,查询与取回的外部来源会实时出现在这里。",
712
+ "searchRefs.emptyHint": "模型调用 web_search 或 advanced_search 之后,查询与取回的来源会实时出现在这里。",
712
713
  "searchRefs.queryGroup": "查询 · {count}",
713
714
  "searchRefs.sourceGroup": "来源 · {count}",
714
715
  "searchRefs.hits": "返回 {count} 条",
@@ -781,7 +782,7 @@ window.__ModuleLoader__.load({
781
782
  "section.searchRefs": "Web searches",
782
783
  "references.tabSearch": "Searches",
783
784
  "searchRefs.empty": "No searches in this session",
784
- "searchRefs.emptyHint": "Queries and the external sources they returned appear here once the model calls advanced_search.",
785
+ "searchRefs.emptyHint": "Queries and the sources they returned appear here once the model calls web_search or advanced_search.",
785
786
  "searchRefs.queryGroup": "Queries · {count}",
786
787
  "searchRefs.sourceGroup": "Sources · {count}",
787
788
  "searchRefs.hits": "{count} returned",
@@ -854,7 +855,7 @@ window.__ModuleLoader__.load({
854
855
  "section.searchRefs": "Web 検索",
855
856
  "references.tabSearch": "検索",
856
857
  "searchRefs.empty": "このセッションではまだ検索していません",
857
- "searchRefs.emptyHint": "モデルが advanced_search を呼び出すと、クエリと取得した外部ソースがここに表示されます。",
858
+ "searchRefs.emptyHint": "モデルが web_search または advanced_search を呼び出すと、クエリと取得した出典がここに表示されます。",
858
859
  "searchRefs.queryGroup": "クエリ · {count}",
859
860
  "searchRefs.sourceGroup": "ソース · {count}",
860
861
  "searchRefs.hits": "{count} 件返却",
@@ -927,7 +928,7 @@ window.__ModuleLoader__.load({
927
928
  "section.searchRefs": "웹 검색",
928
929
  "references.tabSearch": "검색",
929
930
  "searchRefs.empty": "이 세션에서는 아직 검색하지 않았습니다",
930
- "searchRefs.emptyHint": "모델이 advanced_search를 호출하면 쿼리와 가져온 외부 소스가 여기에 표시됩니다.",
931
+ "searchRefs.emptyHint": "모델이 web_search 또는 advanced_search를 호출하면 쿼리와 가져온 출처가 여기에 표시됩니다.",
931
932
  "searchRefs.queryGroup": "쿼리 · {count}",
932
933
  "searchRefs.sourceGroup": "소스 · {count}",
933
934
  "searchRefs.hits": "{count}件 반환",
@@ -1000,7 +1001,7 @@ window.__ModuleLoader__.load({
1000
1001
  "section.searchRefs": "Recherches web",
1001
1002
  "references.tabSearch": "Recherches",
1002
1003
  "searchRefs.empty": "Aucune recherche dans cette session",
1003
- "searchRefs.emptyHint": "Les requêtes et les sources externes renvoyées apparaissent ici dès que le modèle appelle advanced_search.",
1004
+ "searchRefs.emptyHint": "Les requêtes et les sources obtenues s’affichent ici dès que le modèle appelle web_search ou advanced_search.",
1004
1005
  "searchRefs.queryGroup": "Requêtes · {count}",
1005
1006
  "searchRefs.sourceGroup": "Sources · {count}",
1006
1007
  "searchRefs.hits": "{count} renvoyées",
@@ -1073,7 +1074,7 @@ window.__ModuleLoader__.load({
1073
1074
  "section.searchRefs": "Websuchen",
1074
1075
  "references.tabSearch": "Suchen",
1075
1076
  "searchRefs.empty": "Keine Suchen in dieser Sitzung",
1076
- "searchRefs.emptyHint": "Abfragen und die zurückgegebenen externen Quellen erscheinen hier, sobald das Modell advanced_search aufruft.",
1077
+ "searchRefs.emptyHint": "Abfragen und die gelieferten Quellen erscheinen hier, sobald das Modell web_search oder advanced_search aufruft.",
1077
1078
  "searchRefs.queryGroup": "Abfragen · {count}",
1078
1079
  "searchRefs.sourceGroup": "Quellen · {count}",
1079
1080
  "searchRefs.hits": "{count} zurückgegeben",
@@ -1146,7 +1147,7 @@ window.__ModuleLoader__.load({
1146
1147
  "section.searchRefs": "Ricerche web",
1147
1148
  "references.tabSearch": "Ricerche",
1148
1149
  "searchRefs.empty": "Nessuna ricerca in questa sessione",
1149
- "searchRefs.emptyHint": "Le query e le fonti esterne restituite compaiono qui quando il modello chiama advanced_search.",
1150
+ "searchRefs.emptyHint": "Le query e le fonti ottenute compaiono qui quando il modello chiama web_search o advanced_search.",
1150
1151
  "searchRefs.queryGroup": "Query · {count}",
1151
1152
  "searchRefs.sourceGroup": "Fonti · {count}",
1152
1153
  "searchRefs.hits": "{count} restituite",
@@ -1219,7 +1220,7 @@ window.__ModuleLoader__.load({
1219
1220
  "section.searchRefs": "Поиск в сети",
1220
1221
  "references.tabSearch": "Поиск",
1221
1222
  "searchRefs.empty": "В этой сессии ещё не было поиска",
1222
- "searchRefs.emptyHint": "Запросы и возвращённые внешние источники появятся здесь, как только модель вызовет advanced_search.",
1223
+ "searchRefs.emptyHint": "Запросы и полученные источники появятся здесь, когда модель вызовет web_search или advanced_search.",
1223
1224
  "searchRefs.queryGroup": "Запросы · {count}",
1224
1225
  "searchRefs.sourceGroup": "Источники · {count}",
1225
1226
  "searchRefs.hits": "возвращено {count}",
@@ -1292,7 +1293,7 @@ window.__ModuleLoader__.load({
1292
1293
  "section.searchRefs": "Búsquedas web",
1293
1294
  "references.tabSearch": "Búsquedas",
1294
1295
  "searchRefs.empty": "Sin búsquedas en esta sesión",
1295
- "searchRefs.emptyHint": "Las consultas y las fuentes externas devueltas aparecen aquí cuando el modelo llama a advanced_search.",
1296
+ "searchRefs.emptyHint": "Las consultas y las fuentes obtenidas aparecen aquí cuando el modelo llama a web_search o advanced_search.",
1296
1297
  "searchRefs.queryGroup": "Consultas · {count}",
1297
1298
  "searchRefs.sourceGroup": "Fuentes · {count}",
1298
1299
  "searchRefs.hits": "{count} devueltas",
@@ -1362,7 +1363,7 @@ window.__ModuleLoader__.load({
1362
1363
  display: "flex",
1363
1364
  flexDirection: "column"
1364
1365
  };
1365
- const ROW_STYLE$5 = {
1366
+ const ROW_STYLE$4 = {
1366
1367
  display: "flex",
1367
1368
  alignItems: "flex-start",
1368
1369
  gap: 8,
@@ -1408,11 +1409,11 @@ window.__ModuleLoader__.load({
1408
1409
  const title = plan === null ? path : `${t("deliverable.codeplanTag")}: ${plan.task} · ${path}`;
1409
1410
  const label = basename(path);
1410
1411
  const content = plan === null ? null : (0, react.createElement)("span", { style: TAG_STYLE$2 }, t("deliverable.codeplanTag"));
1411
- if (open === void 0) return (0, react.createElement)("li", { style: ROW_STYLE$5 }, content, (0, react.createElement)("span", {
1412
+ if (open === void 0) return (0, react.createElement)("li", { style: ROW_STYLE$4 }, content, (0, react.createElement)("span", {
1412
1413
  style: PATH_STYLE,
1413
1414
  title
1414
1415
  }, label));
1415
- return (0, react.createElement)("li", { style: ROW_STYLE$5 }, content, (0, react.createElement)("button", {
1416
+ return (0, react.createElement)("li", { style: ROW_STYLE$4 }, content, (0, react.createElement)("button", {
1416
1417
  style: BUTTON_STYLE,
1417
1418
  title,
1418
1419
  onClick: () => {
@@ -1595,10 +1596,11 @@ window.__ModuleLoader__.load({
1595
1596
  * The `dshSummarySearchRefs` projection — reading it.
1596
1597
  *
1597
1598
  * The unit is registered by THIS plugin's host half (key `dshSummarySearchRefs`):
1598
- * the queries this session ran through `advanced_search`, and the sources those
1599
- * searches brought back. It answers "what did the session pull in from outside"
1600
- * — where the skill tab says which instruction packs were loaded and the memory
1601
- * tab says which of the user's own knowledge was injected.
1599
+ * the queries this session ran — through the harness's `web_search` or the
1600
+ * user's own `advanced_search` — and the sources those searches brought back.
1601
+ * It answers "what did the session pull in from outside" — where the skill tab
1602
+ * says which instruction packs were loaded and the memory tab says which of the
1603
+ * user's own knowledge was injected.
1602
1604
  *
1603
1605
  * Reading discipline, same as every other brief section:
1604
1606
  * - `undefined` = the capability is ABSENT (no projection registry, or a frame
@@ -1612,6 +1614,14 @@ window.__ModuleLoader__.load({
1612
1614
  function isCounter$2(value) {
1613
1615
  return typeof value === "number" && Number.isSafeInteger(value) && value >= 0;
1614
1616
  }
1617
+ /**
1618
+ * The tool a row came from, defaulting to the plugin's own for a frame written
1619
+ * before the host half started publishing `tool`. Absent is "we do not know",
1620
+ * never "not a search", so the row still shows.
1621
+ */
1622
+ function readTool(value) {
1623
+ return typeof value === "string" && value.length > 0 ? value : "advanced_search";
1624
+ }
1615
1625
  /** Narrow one source row; `undefined` = malformed, dropped. */
1616
1626
  function readItem$1(value) {
1617
1627
  if (value === null || typeof value !== "object" || Array.isArray(value)) return void 0;
@@ -1624,6 +1634,7 @@ window.__ModuleLoader__.load({
1624
1634
  url: raw["url"],
1625
1635
  host: raw["host"],
1626
1636
  query: raw["query"],
1637
+ tool: readTool(raw["tool"]),
1627
1638
  count: raw["count"],
1628
1639
  lastTurn: raw["lastTurn"]
1629
1640
  };
@@ -1639,6 +1650,7 @@ window.__ModuleLoader__.load({
1639
1650
  if (!isCounter$2(raw["turn"]) || !isCounter$2(raw["hits"])) return void 0;
1640
1651
  return {
1641
1652
  query: raw["query"],
1653
+ tool: readTool(raw["tool"]),
1642
1654
  turn: raw["turn"],
1643
1655
  hits: raw["hits"]
1644
1656
  };
@@ -1992,7 +2004,7 @@ window.__ModuleLoader__.load({
1992
2004
  display: "flex",
1993
2005
  flexDirection: "column"
1994
2006
  };
1995
- const ROW_STYLE$4 = {
2007
+ const ROW_STYLE$3 = {
1996
2008
  display: "flex",
1997
2009
  alignItems: "baseline",
1998
2010
  gap: 8,
@@ -2060,7 +2072,7 @@ window.__ModuleLoader__.load({
2060
2072
  marker: "skill-usage-invoked-group"
2061
2073
  }), (0, react.createElement)("ul", { style: LIST_STYLE$3 }, view.session.map((entry) => (0, react.createElement)("li", {
2062
2074
  key: entry.name,
2063
- style: ROW_STYLE$4,
2075
+ style: ROW_STYLE$3,
2064
2076
  "data-dsh-brief-sidebar": "skill-usage-row"
2065
2077
  }, (0, react.createElement)("span", { style: NAME_STYLE$1 }, entry.name), (0, react.createElement)("span", { style: COUNT_STYLE }, expandPair(t("skillUsage.uses"), entry.count, entry.count)), latestNames.includes(entry.name) && (0, react.createElement)("span", { style: TAG_STYLE$1 }, t("skillUsage.latestTag"))))), rest.length > 0 && (0, react.createElement)(FoldToggle, {
2066
2078
  label: expandCount(t("skillUsage.availableGroup"), rest.length),
@@ -2074,7 +2086,7 @@ window.__ModuleLoader__.load({
2074
2086
  marker: "skill-usage-available-capped"
2075
2087
  }), availableOpen && (0, react.createElement)("ul", { style: LIST_STYLE$3 }, rest.map((name) => (0, react.createElement)("li", {
2076
2088
  key: name,
2077
- style: ROW_STYLE$4,
2089
+ style: ROW_STYLE$3,
2078
2090
  "data-dsh-brief-sidebar": "skill-usage-available-row"
2079
2091
  }, (0, react.createElement)("span", { style: NAME_STYLE$1 }, name)))), view.session.length > 0 && (0, react.createElement)("div", { style: FOOTER_STYLE$3 }, expandPair(t("skillUsage.count"), view.callTotal, view.sessionTotal)));
2080
2092
  }
@@ -2084,13 +2096,19 @@ window.__ModuleLoader__.load({
2084
2096
  * The search-reference section: the `dshSummarySearchRefs` projection drawn as
2085
2097
  * one tab of the references section.
2086
2098
  *
2087
- * It answers "what did this session pull in from outside": the queries it ran
2088
- * through `advanced_search`, and the sources those searches returned. Two
2089
- * groups, because they are two different facts — a query says what was asked,
2090
- * a source says what came back, and an older `dsh-free-search` without
2091
- * `presentationMeta` produces queries with no sources at all. That degraded
2092
- * case is stated rather than hidden, because an empty source list would
2093
- * otherwise read as "the search found nothing".
2099
+ * It answers "what did this session pull in from outside", and it answers it the
2100
+ * way the conversation to its left does: **one left-aligned bubble per source**,
2101
+ * title as a link, host and provider snippet under it. No group headers, no list
2102
+ * of query titles — that wall duplicated what the transcript already shows, and a
2103
+ * reader who opens this tab is looking for the results, not for a restatement of
2104
+ * the questions.
2105
+ *
2106
+ * The fold still records which query and which tool (`web_search` or the user's
2107
+ * own `advanced_search`) surfaced each source; that data stays in the frame for
2108
+ * any surface that wants it, it is just no longer drawn here. An older
2109
+ * `dsh-free-search` without `presentationMeta` yields queries with no sources —
2110
+ * that degraded case is stated (`searchRefs.noSourcesHint`) rather than left as
2111
+ * an empty pane, because an empty list reads as "the search found nothing".
2094
2112
  *
2095
2113
  * Optional on both sides: no registry, or a host half that never registered the
2096
2114
  * unit, means the client reads capability absence and the section hides.
@@ -2116,31 +2134,45 @@ window.__ModuleLoader__.load({
2116
2134
  const LIST_STYLE$2 = {
2117
2135
  listStyle: "none",
2118
2136
  margin: 0,
2119
- padding: "6px 0",
2120
- display: "flex",
2121
- flexDirection: "column"
2122
- };
2123
- const ROW_STYLE$3 = {
2137
+ padding: "8px 12px 10px",
2124
2138
  display: "flex",
2139
+ flexDirection: "column",
2125
2140
  alignItems: "flex-start",
2126
- gap: 8,
2127
- padding: "6px 12px"
2141
+ gap: 8
2128
2142
  };
2129
- const QUERY_STYLE = {
2143
+ /**
2144
+ * One result, drawn as a chat bubble: left-aligned, background-filled, rounded,
2145
+ * and narrower than the column. The reader reads this tab the way they read the
2146
+ * conversation to its left — each bubble is one thing the session pulled in — so
2147
+ * the list chrome (row rules, group headers, per-query title lines) is dropped
2148
+ * rather than restyled.
2149
+ *
2150
+ * `alignItems: flex-start` on the list is what keeps bubbles hugging the left
2151
+ * edge; without it a flex child stretches to the full column and the bubble
2152
+ * reads as a plain card.
2153
+ */
2154
+ const BUBBLE_STYLE$1 = {
2155
+ maxWidth: "92%",
2156
+ padding: "8px 10px",
2157
+ borderRadius: 10,
2158
+ background: "var(--dsw-alias-bg-layer-3)",
2159
+ border: "1px solid var(--dsw-alias-border-l2)",
2160
+ color: "var(--dsw-alias-label-primary)",
2161
+ fontSize: 12,
2162
+ lineHeight: "17px",
2130
2163
  minWidth: 0,
2131
- flex: "1 1 auto",
2132
- overflowWrap: "anywhere",
2133
- color: "var(--dsw-alias-label-secondary)"
2164
+ display: "flex",
2165
+ flexDirection: "column",
2166
+ gap: 2
2134
2167
  };
2135
- /** The source title, one line: the host and URL carry the identification. */
2168
+ /** The source title, up to three lines: inside a bubble it IS the content. */
2136
2169
  const TITLE_STYLE$2 = {
2137
2170
  minWidth: 0,
2138
- flex: "1 1 auto",
2171
+ overflowWrap: "anywhere",
2139
2172
  display: "-webkit-box",
2140
- WebkitLineClamp: 2,
2173
+ WebkitLineClamp: 3,
2141
2174
  WebkitBoxOrient: "vertical",
2142
- overflow: "hidden",
2143
- color: "var(--dsw-alias-label-secondary)"
2175
+ overflow: "hidden"
2144
2176
  };
2145
2177
  const SNIPPET_STYLE = {
2146
2178
  margin: 0,
@@ -2150,12 +2182,19 @@ window.__ModuleLoader__.load({
2150
2182
  fontSize: 11,
2151
2183
  lineHeight: "16px"
2152
2184
  };
2153
- const META_STYLE$2 = {
2154
- flexShrink: 0,
2185
+ const HOST_STYLE = {
2155
2186
  color: "var(--dsw-alias-label-tertiary)",
2156
2187
  fontSize: 11,
2157
- lineHeight: "18px",
2158
- whiteSpace: "nowrap"
2188
+ lineHeight: "16px",
2189
+ overflowWrap: "anywhere"
2190
+ };
2191
+ /** The bubble's own footer strip — where the "本轮" pill lives now. */
2192
+ const BUBBLE_FOOT_STYLE = {
2193
+ display: "flex",
2194
+ alignItems: "center",
2195
+ gap: 6,
2196
+ marginTop: 2,
2197
+ minWidth: 0
2159
2198
  };
2160
2199
  /** The "本轮" pill: same form as the skill tag, tertiary emphasis. */
2161
2200
  const TAG_STYLE = {
@@ -2200,52 +2239,29 @@ window.__ModuleLoader__.load({
2200
2239
  color: "var(--dsw-alias-label-secondary)"
2201
2240
  } }, t("searchRefs.empty")), (0, react.createElement)("div", null, t("searchRefs.emptyHint"))));
2202
2241
  const body = [];
2203
- if (view.queries.length > 0) {
2204
- body.push((0, react.createElement)(GroupHeader, {
2205
- key: "qh",
2206
- text: expandCount(t("searchRefs.queryGroup"), view.queries.length),
2207
- marker: "search-refs-query-group"
2208
- }));
2209
- body.push((0, react.createElement)("ul", {
2210
- key: "ql",
2211
- style: LIST_STYLE$2
2212
- }, view.queries.map((row) => (0, react.createElement)("li", {
2213
- key: `${row.turn}:${row.query}`,
2214
- style: ROW_STYLE$3,
2215
- "data-dsh-brief-sidebar": "search-refs-query"
2216
- }, (0, react.createElement)("span", { style: QUERY_STYLE }, row.query), (0, react.createElement)("span", { style: META_STYLE$2 }, expandCount(t("searchRefs.hits"), row.hits))))));
2217
- }
2218
- if (view.sources.length > 0) {
2219
- body.push((0, react.createElement)(GroupHeader, {
2220
- key: "sh",
2221
- text: expandCount(t("searchRefs.sourceGroup"), view.sources.length),
2222
- marker: "search-refs-source-group"
2223
- }));
2224
- body.push((0, react.createElement)("ul", {
2225
- key: "sl",
2226
- style: LIST_STYLE$2
2227
- }, view.sources.map((item) => {
2228
- const href = safeHref(item.url);
2229
- const label = item.title ?? item.url;
2230
- const link = href === void 0 ? (0, react.createElement)("span", { style: TITLE_STYLE$2 }, label) : (0, react.createElement)("a", {
2231
- style: TITLE_STYLE$2,
2232
- href,
2233
- target: "_blank",
2234
- rel: "noreferrer noopener"
2235
- }, label);
2236
- return (0, react.createElement)("li", {
2237
- key: item.url,
2238
- style: ROW_STYLE$3,
2239
- "data-dsh-brief-sidebar": "search-refs-source"
2240
- }, (0, react.createElement)("div", { style: {
2241
- minWidth: 0,
2242
- flex: "1 1 auto",
2243
- display: "flex",
2244
- flexDirection: "column",
2245
- gap: 2
2246
- } }, link, (0, react.createElement)("span", { style: META_STYLE$2 }, item.host), item.snippet !== void 0 && (0, react.createElement)("p", { style: SNIPPET_STYLE }, item.snippet)), isLatestSource(view, item.url) && (0, react.createElement)("span", { style: TAG_STYLE }, t("searchRefs.latestTag")));
2247
- })));
2248
- } else body.push((0, react.createElement)("div", {
2242
+ if (view.sources.length > 0) body.push((0, react.createElement)("ul", {
2243
+ key: "sl",
2244
+ style: LIST_STYLE$2
2245
+ }, view.sources.map((item) => {
2246
+ const href = safeHref(item.url);
2247
+ const label = item.title ?? item.url;
2248
+ const link = href === void 0 ? (0, react.createElement)("span", { style: TITLE_STYLE$2 }, label) : (0, react.createElement)("a", {
2249
+ style: TITLE_STYLE$2,
2250
+ href,
2251
+ target: "_blank",
2252
+ rel: "noreferrer noopener"
2253
+ }, label);
2254
+ const latest = isLatestSource(view, item.url);
2255
+ return (0, react.createElement)("li", {
2256
+ key: item.url,
2257
+ style: { minWidth: 0 },
2258
+ "data-dsh-brief-sidebar": "search-refs-source"
2259
+ }, (0, react.createElement)("div", {
2260
+ style: BUBBLE_STYLE$1,
2261
+ "data-dsh-brief-sidebar": "search-refs-bubble"
2262
+ }, link, (0, react.createElement)("span", { style: HOST_STYLE }, item.host), item.snippet !== void 0 && (0, react.createElement)("p", { style: SNIPPET_STYLE }, item.snippet), (latest || item.count > 1) && (0, react.createElement)("div", { style: BUBBLE_FOOT_STYLE }, latest && (0, react.createElement)("span", { style: TAG_STYLE }, t("searchRefs.latestTag")), item.count > 1 && (0, react.createElement)("span", { style: HOST_STYLE }, `\u00d7${item.count}`))));
2263
+ })));
2264
+ else body.push((0, react.createElement)("div", {
2249
2265
  key: "ns",
2250
2266
  style: FOOTER_STYLE$2,
2251
2267
  "data-dsh-brief-sidebar": "search-refs-no-sources"