dsh-memo-ilife 0.3.13 → 0.3.14

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/dist/client.js CHANGED
@@ -43,9 +43,12 @@ window.__ModuleLoader__.load({
43
43
  const RPC_ENDPOINT_CONFIG_GET = "config.get";
44
44
  const RPC_ENDPOINT_CONFIG_SAVE = "config.save";
45
45
  const RPC_ENDPOINT_CONFIG_RESET = "config.reset";
46
- /** 高级组标题与副文案(六家逐字相同,收在这里一处)。 */
46
+ /** 高级组标题(六家逐字相同,收在这里一处)。
47
+ *
48
+ * #934:原先还有一条副文案 `ADVANCED_GROUP_NOTE`(「不常改。留空=用默认值。」),
49
+ * 维护者裁定**整条删除、删后不另找地方说**——理由:三家高级项全是只读行、不参与保存、根本没有"留空",
50
+ * 而"留空会怎样"这条口径本就逐行住在每条的 `hint` 里(见本件 `ConfigItem.hint` 的契约)。 */
47
51
  const ADVANCED_GROUP_TITLE = "高级";
48
- const ADVANCED_GROUP_NOTE = "不常改。留空=用默认值。";
49
52
  /** 请求超时毫秒:与宿主侧 SPAWN_TIMEOUT_MS 同级,界面永不无限转圈。 */
50
53
  const READ_TIMEOUT_MS$1 = 2e4;
51
54
  /** 复制那一枚按钮就地变「已复制」之后,多久变回「复制」(定稿 v3 第三条:1.5 秒,不弹提示)。 */
@@ -832,7 +835,7 @@ window.__ModuleLoader__.load({
832
835
  textOverflow: "ellipsis",
833
836
  whiteSpace: "nowrap"
834
837
  },
835
- error: { color: "var(--dsw-alias-label-error, #e66)" }
838
+ error: { color: "var(--dsw-alias-state-error-primary, #e66)" }
836
839
  };
837
840
  /** 面包屑:从文件系统根到当前层,每一格都是跳转目标(`listing.crumbs` 由取数方给)。 */
838
841
  function crumbRow(state, onEnter) {
@@ -1087,6 +1090,23 @@ window.__ModuleLoader__.load({
1087
1090
  * 键名一个都不许改:六家附加块真消费 `okText`/`error`/`rows`/`label`/`muted`/`hint`/`info`/
1088
1091
  * `bar`/`btn` 这九格(`plugin-memo-ilife/src/client.ts`、`plugin-schedule-ilife/src/client.ts` 的
1089
1092
  * `PanelStyleSlots`),跨包锁另钉 `card`/`input`/`btnPrimary`/`btnPick`/`summary`/`title`/`version`。 */
1093
+ /** #941/丁:**浅色档距自合成**——宿主在浅色下四层底同白(`bg-base = bg-layer-1/2/3`),
1094
+ * 拿不到可用的层级差,所以三处面(卡描边/沉底盒底/输入框描边)由我们自己按墨色派生。
1095
+ *
1096
+ * 取 `label-primary` 当墨色分母:浅色下它是近黑、深色下它是近白 ⇒ **同一条表达式两套主题都成立**
1097
+ * (浅色补出可用的档距,深色退化成今天那几档观感)。百分比来自维护者选定的方案丁:
1098
+ * 卡描边 19%/沉底盒底 9%/输入框描边 24%/骨架条 21%。这是本仓第一处"自定值",属真源增补
1099
+ * (v3.1 只有深色一套 token,从未覆盖浅色)。 */
1100
+ const PANEL_INK = "var(--dsw-alias-label-primary, #f9fafb)";
1101
+ const inkMix = (percent, into) => into === void 0 ? `color-mix(in srgb, ${PANEL_INK} ${percent}%, transparent)` : `color-mix(in srgb, ${PANEL_INK} ${percent}%, ${into})`;
1102
+ /** 卡片描边:浅色 ≈`#cfcfcf` ⇔ 深色 ≈`#4a4b4d`。 */
1103
+ const PANEL_CARD_EDGE = inkMix(19);
1104
+ /** 沉底盒底(母版行/高级组体/状态行):浅色 ≈`#e9e9e9` ⇔ 深色 ≈`#3a3b3d`。 */
1105
+ const PANEL_SUNKEN_FILL = inkMix(9, "var(--dsw-alias-bg-layer-1, #232324)");
1106
+ /** 输入框描边:浅色 ≈`#c4c4c4` ⇔ 深色 ≈`#5a5b5d`。 */
1107
+ const PANEL_FIELD_EDGE = inkMix(24);
1108
+ /** 骨架条:浅色 ≈`#c9ccd2`(1.6:1)⇔ 深色 ≈`#404143`。 */
1109
+ const PANEL_SKELETON_FILL = inkMix(21);
1090
1110
  const S = {
1091
1111
  /** `.ic-card`:`background:var(--ic-surface)`(=bg-layer-1)+`border:1px solid var(--ic-line-strong)`
1092
1112
  * +`border-radius:12px`+`padding:14px`+`box-shadow:inset 0 1px 0 rgba(255,255,255,.06)`。
@@ -1094,7 +1114,7 @@ window.__ModuleLoader__.load({
1094
1114
  card: {
1095
1115
  padding: 14,
1096
1116
  borderRadius: 12,
1097
- border: "1px solid var(--dsw-alias-border-l2, rgba(255,255,255,.12))",
1117
+ border: "1px solid " + PANEL_CARD_EDGE,
1098
1118
  background: "var(--dsw-alias-bg-layer-1, #232324)",
1099
1119
  color: "var(--dsw-alias-label-primary, #f9fafb)",
1100
1120
  boxShadow: "inset 0 1px 0 rgba(255,255,255,.06)"
@@ -1114,6 +1134,83 @@ window.__ModuleLoader__.load({
1114
1134
  /** `.ic-file{margin-top:4px}` 的那 4px 挂在两行的公共容器上:`info` 自己一格 margin 都不写
1115
1135
  * (#743 ①:头部两行间距不一家一个数,故这一项一律不写 margin)。 */
1116
1136
  fileWrap: { marginTop: 4 },
1137
+ /** #939:骨架条(照真源 `.ic-sk`:`display:block;height:17px;border-radius:4px`)。
1138
+ * 高度按一行正文画——inline-block 跟着父级行高走会让骨架行比填充后的文字行高 4px、六家叠起来就是一片下移。
1139
+ * 底色走派生值(宿主专用骨架档 `bg-skeleton` 在浅色下只有 1.09:1,等于看不见)。 */
1140
+ skeleton: {
1141
+ display: "block",
1142
+ height: 17,
1143
+ borderRadius: 4,
1144
+ background: PANEL_SKELETON_FILL
1145
+ },
1146
+ /** #936:状态行那一块(照真源 `.ic-status`)——沉底面盒子,里面三行:状态行/路径行/官网行。 */
1147
+ statusBox: {
1148
+ marginTop: 11,
1149
+ padding: "10px 12px",
1150
+ background: PANEL_SUNKEN_FILL,
1151
+ border: "1px solid var(--dsw-alias-border-l2, rgba(255,255,255,.12))",
1152
+ borderRadius: 8
1153
+ },
1154
+ /** `.ic-srow{display:flex;align-items:center;gap:8px;font-size:12px;flex-wrap:wrap}`(12px ⇒ 0.86em)。 */
1155
+ statusRow: {
1156
+ display: "flex",
1157
+ alignItems: "center",
1158
+ gap: 8,
1159
+ fontSize: "0.86em",
1160
+ flexWrap: "wrap"
1161
+ },
1162
+ /** `.ic-dot{width:8px;height:8px;border-radius:50%}`——底色按档位在组件里补。 */
1163
+ statusDot: {
1164
+ width: 8,
1165
+ height: 8,
1166
+ borderRadius: "50%",
1167
+ flex: "0 0 auto"
1168
+ },
1169
+ /** `.ic-sname{font-weight:600;white-space:nowrap}`。 */
1170
+ statusName: {
1171
+ fontWeight: 600,
1172
+ whiteSpace: "nowrap"
1173
+ },
1174
+ /** `.ic-stxt{color:var(--ic-muted);min-width:0}`。 */
1175
+ statusText: {
1176
+ color: "var(--dsw-alias-label-secondary, #cfd3d6)",
1177
+ minWidth: 0
1178
+ },
1179
+ /** `.ic-sfind{display:flex;align-items:center;gap:8px;margin-top:7px}`。 */
1180
+ statusFind: {
1181
+ display: "flex",
1182
+ alignItems: "center",
1183
+ gap: 8,
1184
+ marginTop: 7
1185
+ },
1186
+ /** `.ic-spath{font-size:10.5px;color:var(--ic-faint);white-space:nowrap;overflow:hidden}`
1187
+ * ——单行不折、超出裁掉(**不写省略号**:本件有一条"零省略号"的跨包锁)。
1188
+ * **不写 `fontFamily`**:v3.1 这一格要 `var(--ic-mono)`,但 `#739 ①` 明令共用件零字族(宿主没有界面字族
1189
+ * token,钉死会在别的窗口尺寸上失真)——与真源的同一处已知不同,账在 #920 证据件里。 */
1190
+ statusPath: {
1191
+ fontSize: "0.75em",
1192
+ color: "var(--dsw-alias-label-tertiary, #adb2b8)",
1193
+ minWidth: 0,
1194
+ whiteSpace: "nowrap",
1195
+ overflow: "hidden"
1196
+ },
1197
+ /** `.ic-ver{font-size:10px;border:1px solid var(--ic-line-strong);border-radius:999px;padding:0 6px}`。 */
1198
+ statusVersion: {
1199
+ fontSize: "0.72em",
1200
+ color: "var(--dsw-alias-label-tertiary, #adb2b8)",
1201
+ border: "1px solid var(--dsw-alias-border-l2, rgba(255,255,255,.12))",
1202
+ borderRadius: 999,
1203
+ padding: "0 6px",
1204
+ whiteSpace: "nowrap"
1205
+ },
1206
+ /** `.ic-url{display:inline-block;margin-top:7px;font-size:10.5px;color:var(--ic-faint)}`
1207
+ * ——字族同样继承宿主(`#739 ①`:共用件零 `fontFamily`),理由同上一格。 */
1208
+ statusUrl: {
1209
+ display: "inline-block",
1210
+ marginTop: 7,
1211
+ fontSize: "0.75em",
1212
+ color: "var(--dsw-alias-label-tertiary, #adb2b8)"
1213
+ },
1117
1214
  /** `.ic-file b{color:var(--ic-faint);font-weight:400;margin-right:5px}`(「配置文件」「数据目录」那两个字)。 */
1118
1215
  fileLabel: {
1119
1216
  color: "var(--dsw-alias-label-tertiary, #adb2b8)",
@@ -1239,7 +1336,7 @@ window.__ModuleLoader__.load({
1239
1336
  /** `.ic-master`:母版行那一块盒子(`--ic-sunken` 底 + `border-radius:8px` + `padding:11px 12px`
1240
1337
  * + `margin-top:11px` + 内高光)。 */
1241
1338
  master: {
1242
- background: "var(--dsw-alias-bg-layer-3, #353638)",
1339
+ background: PANEL_SUNKEN_FILL,
1243
1340
  border: "1px solid var(--dsw-alias-border-l2, rgba(255,255,255,.12))",
1244
1341
  borderRadius: 8,
1245
1342
  padding: "11px 12px",
@@ -1279,7 +1376,7 @@ window.__ModuleLoader__.load({
1279
1376
  padding: "5px 8px",
1280
1377
  boxSizing: "border-box",
1281
1378
  background: "var(--dsw-alias-bg-base, #151517)",
1282
- border: "1px solid var(--dsw-alias-border-l2, rgba(255,255,255,.12))",
1379
+ border: "1px solid " + PANEL_FIELD_EDGE,
1283
1380
  borderRadius: 6,
1284
1381
  color: "var(--dsw-alias-label-primary, #f9fafb)"
1285
1382
  },
@@ -1346,18 +1443,13 @@ window.__ModuleLoader__.load({
1346
1443
  },
1347
1444
  /** `.ic-ghead::before{content:'›';color:var(--ic-muted)}`——画成真的那一个字符(内联样式给不出伪元素)。 */
1348
1445
  groupMark: { color: "var(--dsw-alias-label-secondary, #cfd3d6)" },
1349
- /** `.ic-ghead .ic-gnote{color:var(--ic-faint);font-weight:400;font-size:11.5px}`(11.5px ⇒ `0.92em`)。 */
1350
- groupNote: {
1351
- color: "var(--dsw-alias-label-tertiary, #adb2b8)",
1352
- fontWeight: 400,
1353
- fontSize: "0.92em"
1354
- },
1446
+ /** #934:`.ic-gnote` 那条副文案的样式随之删除——副文案本身已按维护者裁定整条撤掉(零消费者的槽位不留)。 */
1355
1447
  /** `.ic-group > .ic-gbody{margin-top:9px;padding:11px 12px;background:var(--ic-sunken);
1356
1448
  * border-radius:8px;box-shadow:inset 0 1px 0 rgba(255,255,255,.04)}`。 */
1357
1449
  groupBody: {
1358
1450
  marginTop: 9,
1359
1451
  padding: "11px 12px",
1360
- background: "var(--dsw-alias-bg-layer-3, #353638)",
1452
+ background: PANEL_SUNKEN_FILL,
1361
1453
  border: "1px solid var(--dsw-alias-border-l2, rgba(255,255,255,.12))",
1362
1454
  borderRadius: 8,
1363
1455
  boxShadow: "inset 0 1px 0 rgba(255,255,255,.04)"
@@ -1413,14 +1505,8 @@ window.__ModuleLoader__.load({
1413
1505
  cursor: "pointer",
1414
1506
  whiteSpace: "nowrap"
1415
1507
  },
1416
- /** 附加块(版本行/状态行)那份字面:`--ic-faint` + `0.92em`(#739 ③ 钉死这一格)。 */
1417
- version: {
1418
- marginTop: 8,
1419
- paddingTop: 8,
1420
- borderTop: "1px dashed var(--dsw-alias-border-l1, rgba(255,255,255,.06))",
1421
- color: "var(--dsw-alias-label-tertiary, #adb2b8)",
1422
- fontSize: "0.92em"
1423
- },
1508
+ /** #934:原先这里有一格 `version`(各家附加块的版本行字面)。版本行已按维护者裁定整条撤掉
1509
+ *(那两家面板内的渲染点 + 六家各自那份字面副本),这一格随之删除:没人取的槽位不留。 */
1424
1510
  /** `.ic-badge{font-size:11px;line-height:1;padding:4px 9px;border-radius:999px;white-space:nowrap;
1425
1511
  * display:inline-flex;align-items:center;gap:6px;border:1px solid transparent}`(11px ⇒ `0.88em`)。 */
1426
1512
  badge: {
@@ -1619,7 +1705,18 @@ window.__ModuleLoader__.load({
1619
1705
  kind: badge,
1620
1706
  dirtyCount
1621
1707
  }));
1622
- const fileLines = surface === null ? null : react.createElement("div", { style: S.fileWrap }, react.createElement("div", { style: S.info }, react.createElement("b", { style: S.fileLabel }, "配置文件"), surface.path), react.createElement("div", { style: S.info }, react.createElement("b", { style: S.fileLabel }, "数据目录"), headDataDir), surface.created ? react.createElement("div", { style: S.muted }, "(配置文件刚按默认值生成)") : null);
1708
+ /** #939:这一块的高度由**客户端常量**决定、不由回执时序决定——加载期就把两行连标签一起画出来,
1709
+ * 值位画骨架条(`.ic-sk`),回执到了**原地填值** ⇒ 回执零位移(原先加载期只画一行小灰字、
1710
+ * 回执到了才长出两行,整块下移 21px)。
1711
+ *
1712
+ * 判断式按 `state.kind`:**不许**照 `surface === null` 写——它同时覆盖失败态,照写会让失败屏长出两行假骨架。 */
1713
+ const loading = state.kind === "loading";
1714
+ const fileValue = (text) => text === null ? react.createElement("span", {
1715
+ style: S.skeleton,
1716
+ "data-ilife-skeleton": "value"
1717
+ }) : text;
1718
+ const fileRow = (label, text, tail) => react.createElement("div", { style: S.info }, react.createElement("b", { style: S.fileLabel }, label), fileValue(text), tail === void 0 ? null : tail);
1719
+ const fileLines = !loading && surface === null ? null : react.createElement("div", { style: S.fileWrap }, fileRow("配置文件", surface === null ? null : surface.path, surface !== null && surface.created ? react.createElement("span", { style: S.muted }, "(配置文件刚按默认值生成)") : null), fileRow("数据目录", surface === null ? null : headDataDir));
1623
1720
  const parts = {
1624
1721
  styles: S,
1625
1722
  reply: surface
@@ -1663,7 +1760,7 @@ window.__ModuleLoader__.load({
1663
1760
  const commonLast = lastIndexOf(common);
1664
1761
  const advancedLast = lastIndexOf(advanced);
1665
1762
  const dirty = ready && dirtyCount > 0;
1666
- return react.createElement("div", { style: S.card }, head, fileLines, ready ? null : react.createElement("div", { style: S.muted }, "配置读取中"), react.createElement("div", { style: S.rows }, common.map((item, index) => renderRow(item, index === commonLast))), advanced.length === 0 ? null : react.createElement("details", { style: S.advanced }, react.createElement("summary", { style: S.summary }, react.createElement("span", { style: S.groupMark }, "›"), ADVANCED_GROUP_TITLE, react.createElement("span", { style: S.groupNote }, ADVANCED_GROUP_NOTE)), react.createElement("div", { style: S.groupBody }, advanced.map((item, index) => renderRow(item, index === advancedLast)))), extra, react.createElement("div", { style: S.bar }, react.createElement("button", {
1763
+ return react.createElement("div", { style: S.card }, head, fileLines, react.createElement("div", { style: S.rows }, common.map((item, index) => renderRow(item, index === commonLast))), advanced.length === 0 ? null : react.createElement("details", { style: S.advanced }, react.createElement("summary", { style: S.summary }, react.createElement("span", { style: S.groupMark }, "›"), ADVANCED_GROUP_TITLE), react.createElement("div", { style: S.groupBody }, advanced.map((item, index) => renderRow(item, index === advancedLast)))), extra, react.createElement("div", { style: S.bar }, react.createElement("button", {
1667
1764
  style: dirty ? S.btnPrimary : S.btn,
1668
1765
  type: "button",
1669
1766
  disabled: frozen || !dirty,
@@ -1678,7 +1775,7 @@ window.__ModuleLoader__.load({
1678
1775
  type: "button",
1679
1776
  disabled: frozen,
1680
1777
  onClick: props.onRetry
1681
- }, "重新读取"), dirty ? react.createElement("div", { style: S.saveMsg }, `浏览改动后请点保存(${dirtyCount} 项未保存),保存后跟随项自动更新`) : ready ? react.createElement("div", { style: S.barNote }, "没有未保存的改动") : null), props.picking ? react.createElement("div", { style: S.muted }, "已唤起系统文件夹对话框:选中后自动填上,取消则不动。") : null, props.browseRow !== null ? react.createElement(DirectoryBrowserFromRow, {
1778
+ }, "重新读取"), dirty ? react.createElement("div", { style: S.saveMsg }, `浏览改动后请点保存(${dirtyCount} 项未保存),保存后跟随项自动更新`) : ready ? react.createElement("div", { style: S.barNote }, "没有未保存的改动") : react.createElement("div", { style: S.barNote }, "配置读取中")), props.picking ? react.createElement("div", { style: S.muted }, "已唤起系统文件夹对话框:选中后自动填上,取消则不动。") : null, props.browseRow !== null ? react.createElement(DirectoryBrowserFromRow, {
1682
1779
  open: true,
1683
1780
  row: props.browseRow,
1684
1781
  labels: BROWSER_LABELS
@@ -1687,6 +1784,39 @@ window.__ModuleLoader__.load({
1687
1784
  role: "alert"
1688
1785
  }, props.writeError) : null, props.error !== null ? react.createElement("div", { style: S.error }, props.error) : null, props.notice !== null ? react.createElement("div", { style: S.okText }, props.notice) : null);
1689
1786
  }
1787
+ /** 状态点的底色:三档状态色 + 默认灰(照真源 `.is-ok/.is-warn/.is-bad` 与 `.ic-dot` 的默认档)。 */
1788
+ const STATUS_DOT_COLOR = {
1789
+ ok: "var(--dsw-alias-state-success-primary, #4ec9a0)",
1790
+ warn: "var(--dsw-alias-state-warn-primary, #e0a33e)",
1791
+ bad: "var(--dsw-alias-state-error-primary, #e0685f)",
1792
+ pending: "var(--dsw-alias-label-tertiary, #adb2b8)"
1793
+ };
1794
+ function StatusBlock(props) {
1795
+ const actions = props.actions ?? [];
1796
+ return react.createElement("div", {
1797
+ style: S.statusBox,
1798
+ "data-ilife-status": "block"
1799
+ }, react.createElement("div", { style: S.statusRow }, react.createElement("span", { style: {
1800
+ ...S.statusDot,
1801
+ background: STATUS_DOT_COLOR[props.tone]
1802
+ } }), react.createElement("span", { style: S.statusName }, props.name), react.createElement("span", { style: S.statusText }, props.text), ...actions.map((action, index) => react.createElement("button", {
1803
+ key: action.text,
1804
+ style: index === 0 ? {
1805
+ ...S.btnPick,
1806
+ marginLeft: "auto"
1807
+ } : S.btnPick,
1808
+ type: "button",
1809
+ onClick: action.onPress
1810
+ }, action.text))), react.createElement("div", { style: S.statusFind }, props.path === null ? react.createElement("span", {
1811
+ style: S.skeleton,
1812
+ "data-ilife-skeleton": "statusPath"
1813
+ }) : react.createElement("span", { style: S.statusPath }, props.path), props.version === void 0 || props.version === null || props.version === "" ? null : react.createElement("span", { style: S.statusVersion }, props.version)), props.link === void 0 ? null : react.createElement("a", {
1814
+ style: S.statusUrl,
1815
+ href: props.link.href,
1816
+ target: "_blank",
1817
+ rel: "noreferrer"
1818
+ }, props.link.text));
1819
+ }
1690
1820
  //#endregion
1691
1821
  //#region ../plugin-manager/dist/directory-browser-roots.js
1692
1822
  /** 「本机根清单」的取数接线(客户端半):把一通电话变成图上那一行可跳转的根。
@@ -2137,7 +2267,7 @@ window.__ModuleLoader__.load({
2137
2267
  card: {
2138
2268
  padding: "12px 14px",
2139
2269
  borderRadius: 10,
2140
- border: "1px solid var(--dsw-alias-border, rgba(128,128,128,.35))",
2270
+ border: "1px solid var(--dsw-alias-border-l1, rgba(128,128,128,.35))",
2141
2271
  background: "var(--dsw-alias-bg-base, transparent)",
2142
2272
  color: "var(--dsw-alias-label-primary, inherit)",
2143
2273
  lineHeight: 1.6
@@ -2158,14 +2288,14 @@ window.__ModuleLoader__.load({
2158
2288
  },
2159
2289
  error: {
2160
2290
  marginTop: 8,
2161
- color: "var(--dsw-alias-label-error, #b3261e)",
2291
+ color: "var(--dsw-alias-state-error-primary, #b3261e)",
2162
2292
  fontSize: "1em",
2163
2293
  whiteSpace: "pre-wrap"
2164
2294
  },
2165
2295
  version: {
2166
2296
  marginTop: 8,
2167
2297
  paddingTop: 8,
2168
- borderTop: "1px dashed var(--dsw-alias-border, rgba(128,128,128,.25))",
2298
+ borderTop: "1px dashed var(--dsw-alias-border-l1, rgba(128,128,128,.25))",
2169
2299
  color: "var(--dsw-alias-label-tertiary, #8a8a8a)",
2170
2300
  fontSize: "0.92em"
2171
2301
  }
@@ -2369,29 +2499,36 @@ window.__ModuleLoader__.load({
2369
2499
  return Promise.resolve(false);
2370
2500
  }
2371
2501
  }
2372
- /** 「飞书 CLI」状态行(#760,定稿 #759;不是配置项):三档读数 + 复制安装指引按钮 + 官网链接。
2502
+ /** 「飞书 CLI」状态行(#760 定稿 #759;**#936 起照真源 `.ic-status` 画**):三档读数 + 复制安装指引 + 官网链接。
2373
2503
  *
2374
- * 判据由技能侧出(回执 `lark` 格),面板只显示:
2375
- * · 没找到 CLI → 红「没找到飞书 CLI」+ 复制安装指引按钮 + 官网链接;
2376
- * · 找到了但没登录/缺 task 权限 → 黄「找到了〈路径〉,但还没登录或没拿到 task 域授权」+ 同一个按钮 + 官网链接;
2377
- * · 就绪 → 绿「已登录且 task 域可写:〈路径〉(〈版本〉)」+ 同一个按钮 + 官网链接。
2378
- * 官网行三档逐字显示「飞书CLI官网为:https://www.feishu.cn/feishu-cli」,显示成文字+点一下新窗口跳转。
2379
- * 旧技能(回执无 `lark` 格)⇒ 只显示一行弱提示,不报错、不探测。 */
2504
+ * 判据由技能侧出(回执 `lark` 格),面板只显示;**形状由共用件的 `StatusBlock` 给**(两家同形,真源那一件):
2505
+ * · 没找到 → 红点「没找到飞书 CLI」;
2506
+ * · 找到了但没登录/缺 task 权限 → 黄点「找到了,但还没登录或没拿到 task 域授权」+ 路径行;
2507
+ * · 就绪 → 绿点「已登录,task 域可写」+ 路径行 + 版本胶囊(`lark.version`,技能侧交的短版本号)。
2508
+ * 官网行三档逐字显示,显示成文字+点一下新窗口跳转。旧技能(回执无 `lark` 格)⇒ 只显示一行弱提示,不报错、不探测。 */
2380
2509
  function LarkStatus(props) {
2381
- const S = props.styles ?? {};
2382
2510
  const lark = props.lark;
2383
- if (lark === void 0) return react.createElement("div", { style: S.rows }, react.createElement("div", { style: S.label }, "飞书 CLI"), react.createElement("div", { style: S.muted }, "状态未知(技能回执无此格,请升级技能包)。"));
2384
- const status = lark.tier === "missing" ? "没找到飞书 CLI" : lark.tier === "partial" ? "找到了 " + (lark.cliPath ?? "飞书 CLI") + ",但还没登录或没拿到 task 域授权" : "已登录且 task 域可写:" + (lark.cliPath ?? "") + (lark.version !== null ? "(" + lark.version + ")" : "");
2385
- const statusStyle = lark.tier === "full" ? S.okText : lark.tier === "partial" ? S.muted : S.error;
2386
- return react.createElement("div", { style: S.rows }, react.createElement("div", { style: S.label }, "飞书 CLI"), react.createElement("div", { style: statusStyle }, status), react.createElement("div", { style: S.bar }, react.createElement("button", {
2387
- style: S.btn,
2388
- type: "button",
2389
- onClick: () => props.onCopy(lark.prompt)
2390
- }, "复制安装指引"), react.createElement("a", {
2391
- href: lark.websiteUrl,
2392
- target: "_blank",
2393
- rel: "noreferrer"
2394
- }, lark.websiteLine)));
2511
+ if (lark === void 0) return react.createElement(StatusBlock, {
2512
+ name: "飞书 CLI",
2513
+ tone: "pending",
2514
+ text: "状态未知(技能回执无此格,请升级技能包)",
2515
+ path: ""
2516
+ });
2517
+ return react.createElement(StatusBlock, {
2518
+ name: "飞书 CLI",
2519
+ tone: lark.tier === "full" ? "ok" : lark.tier === "partial" ? "warn" : "bad",
2520
+ text: lark.tier === "full" ? "已登录,task 域可写" : lark.tier === "partial" ? "找到了,但还没登录或没拿到 task 域授权" : "没找到飞书 CLI",
2521
+ path: lark.cliPath ?? "",
2522
+ version: lark.version,
2523
+ actions: [{
2524
+ text: "复制安装指引",
2525
+ onPress: () => props.onCopy(lark.prompt)
2526
+ }],
2527
+ link: {
2528
+ text: lark.websiteLine,
2529
+ href: lark.websiteUrl
2530
+ }
2531
+ });
2395
2532
  }
2396
2533
  /** 跟随映射(#863):触发键一脏,这些只读派生行就进“将跟随更新”态。纯函数,面板与单测共用。 */
2397
2534
  const DB_FOLLOWERS = ["db.name", "html.dir"];
@@ -2406,17 +2543,18 @@ window.__ModuleLoader__.load({
2406
2543
  const lark = reply.lark;
2407
2544
  return typeof lark === "object" && lark !== null ? lark : void 0;
2408
2545
  }
2409
- /** 自家附加块(设置页那张卡的插槽):版本行 +「飞书 CLI」状态行。
2546
+ /** 自家附加块(设置页那张卡的插槽):「飞书 CLI」状态行。
2410
2547
  *
2411
- * 为什么单起一个组件:#918 起版本是**本家自己的一通电话**(`VERSION_READ_KEY`,宿主回装机版本对),
2412
- * 飞书状态是本家回执多带的那一格(共用面板不认识它),复制回执也住在本家——
2548
+ * #934 起**这里不再有版本行**(维护者裁定:面板内那行 `总管 …· 版本` 整条撤掉;
2549
+ * 版本仍可从 sidebar 干活区卡片、装机包描述文件、版本魔键三路取到)。
2550
+ * 状态行住这里的原因:飞书状态是本家回执多带的那一格(共用面板不认识它),复制回执也住在本家——
2413
2551
  * 组件自己持这点状态,面板只管把它画进插槽(面板主体之后、动作条之前)。 */
2414
2552
  function MemoExtras(props) {
2415
2553
  const [copied, setCopied] = react.useState("idle");
2416
2554
  const onCopy = (prompt) => {
2417
2555
  copyPrompt(prompt).then((ok) => setCopied(ok ? "done" : "failed"));
2418
2556
  };
2419
- return react.createElement("div", null, react.createElement(HostVersionLine, { getCall: props.getCall }), props.hasReply ? react.createElement(LarkStatus, {
2557
+ return react.createElement("div", null, props.hasReply ? react.createElement(LarkStatus, {
2420
2558
  lark: props.lark,
2421
2559
  onCopy,
2422
2560
  styles: props.styles