@artenx/dshb 0.1.9 → 0.1.11
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 +56 -90
- package/lib/client.js.map +1 -1
- package/lib/core/index.js +5 -1
- package/lib/core/index.js.map +1 -1
- package/lib/core/routes.d.ts +8 -1
- package/lib/core/routes.js +65 -3
- package/lib/core/routes.js.map +1 -1
- package/lib/core/workspace-bindings.js +6 -4
- package/lib/core/workspace-bindings.js.map +1 -1
- package/lib/exec-docker/daemon-runner.js +2 -2
- package/lib/exec-docker/docker-backend.d.ts +8 -0
- package/lib/exec-docker/docker-client.d.ts +9 -0
- package/lib/exec-docker/docker-client.js +10 -2
- package/lib/exec-docker/docker-client.js.map +1 -1
- package/lib/exec-docker/docker-routes.js +1 -1
- package/lib/exec-docker/fs-provider.d.ts +3 -12
- package/lib/exec-docker/fs-provider.js +19 -2
- package/lib/exec-docker/fs-provider.js.map +1 -1
- package/lib/exec-docker/index.js +1 -1
- package/lib/exec-docker/remote-docker-cli.d.ts +8 -0
- package/lib/exec-docker/remote-docker-cli.js +27 -1
- package/lib/exec-docker/remote-docker-cli.js.map +1 -1
- package/lib/exec-docker/world.d.ts +1 -1
- package/lib/exec-ssh/executor.d.ts +7 -0
- package/lib/exec-ssh/executor.js +18 -0
- package/lib/exec-ssh/executor.js.map +1 -1
- package/lib/exec-ssh/fs-provider.d.ts +3 -12
- package/lib/exec-ssh/fs-provider.js +20 -3
- package/lib/exec-ssh/fs-provider.js.map +1 -1
- package/lib/exec-ssh/world.d.ts +1 -1
- package/lib/router/decorate-fs.js +16 -2
- package/lib/router/decorate-fs.js.map +1 -1
- package/lib/router/decorate-shell.d.ts +1 -1
- package/lib/router/index.d.ts +1 -1
- package/lib/router/resolve.d.ts +1 -1
- package/lib/router/router-fs.d.ts +1 -1
- package/lib/router/types.d.ts +1 -1
- package/lib/{types-ekJQQ4x6.d.ts → types-DPP05ZsA.d.ts} +2 -2
- package/package.json +1 -1
package/lib/client.js
CHANGED
|
@@ -445,7 +445,7 @@ window.__ModuleLoader__.load({
|
|
|
445
445
|
get: () => true
|
|
446
446
|
});
|
|
447
447
|
ctx.plugin({
|
|
448
|
-
inject: ["slots"
|
|
448
|
+
inject: ["slots"],
|
|
449
449
|
apply: (sub) => {
|
|
450
450
|
sub.slots.inject("settings.section", () => sub.slots.register({
|
|
451
451
|
name: "settings.section",
|
|
@@ -539,7 +539,7 @@ window.__ModuleLoader__.load({
|
|
|
539
539
|
const res = await fetch("/api/dshb/nodes");
|
|
540
540
|
if (!res.ok) return;
|
|
541
541
|
const data = await res.json();
|
|
542
|
-
setNodes(
|
|
542
|
+
setNodes(data.nodes ?? []);
|
|
543
543
|
} catch {}
|
|
544
544
|
})();
|
|
545
545
|
}, [props.open]);
|
|
@@ -1555,72 +1555,36 @@ window.__ModuleLoader__.load({
|
|
|
1555
1555
|
"overflow-y",
|
|
1556
1556
|
"box-sizing"
|
|
1557
1557
|
];
|
|
1558
|
-
/**
|
|
1559
|
-
|
|
1560
|
-
* 水平居中(左右各留 8px,绝不贴边/溢出),高度按视口比例封顶并内容滚动,
|
|
1561
|
-
* 触发元素上方空间足够则向上展开、否则向下展开,四边都约束在视口内。
|
|
1562
|
-
* fixed 不受祖先 overflow 裁剪(祖先带 transform 时失效)。
|
|
1563
|
-
*/
|
|
1564
|
-
function positionFixedSheet(el, rootRect, maxWidth, maxHeightRatio) {
|
|
1558
|
+
/** Keep the model menu anchored to its trigger while fitting it in the viewport. */
|
|
1559
|
+
function positionAnchoredMenu(el, triggerRect, maxWidth, maxHeight) {
|
|
1565
1560
|
const margin = 8;
|
|
1566
1561
|
const vw = window.innerWidth;
|
|
1567
1562
|
const vh = window.innerHeight;
|
|
1568
|
-
const width = Math.max(0, Math.min(maxWidth, vw - 16));
|
|
1569
|
-
const left = Math.round((vw - width) / 2);
|
|
1570
|
-
const maxH = Math.round(vh * maxHeightRatio);
|
|
1571
|
-
const spaceAbove = rootRect.top - margin;
|
|
1572
|
-
const spaceBelow = vh - rootRect.bottom - margin;
|
|
1573
|
-
const expandUp = spaceAbove >= 140 && spaceAbove >= spaceBelow;
|
|
1574
|
-
let top;
|
|
1575
|
-
if (expandUp) {
|
|
1576
|
-
const h = Math.min(maxH, Math.max(spaceAbove, 140));
|
|
1577
|
-
top = rootRect.top - margin - h;
|
|
1578
|
-
} else top = rootRect.bottom + margin;
|
|
1579
|
-
top = Math.max(margin, top);
|
|
1580
|
-
el.style.setProperty("position", "fixed", "important");
|
|
1581
|
-
el.style.setProperty("box-sizing", "border-box", "important");
|
|
1582
|
-
el.style.setProperty("width", `${width}px`, "important");
|
|
1583
|
-
el.style.setProperty("left", `${left}px`, "important");
|
|
1584
|
-
el.style.setProperty("right", "auto", "important");
|
|
1585
|
-
el.style.setProperty("top", `${top}px`, "important");
|
|
1586
|
-
el.style.setProperty("bottom", "auto", "important");
|
|
1587
|
-
el.style.setProperty("min-width", "0", "important");
|
|
1588
|
-
el.style.setProperty("max-width", "none", "important");
|
|
1589
|
-
el.style.setProperty("max-height", `${maxH}px`, "important");
|
|
1590
|
-
el.style.setProperty("overflow-y", "auto", "important");
|
|
1591
|
-
}
|
|
1592
|
-
/**
|
|
1593
|
-
* 一级 pane(Model/Effort 单元格小菜单)紧凑浮层:右缘对齐触发按钮右缘
|
|
1594
|
-
* (面板右缘 x = 按钮右缘 x,钳制在视口内 8px 起,避免宽面板超出屏幕左缘时
|
|
1595
|
-
* 被甩到左边贴边),向上展开、空间不足向下展开;宽度跟随内容
|
|
1596
|
-
* (max-content,封顶 min(420, vw-16)),避免小菜单被全宽 sheet 拉远到
|
|
1597
|
-
* 屏幕中间。测量与定位在同一任务内同步完成,无闪烁。
|
|
1598
|
-
*/
|
|
1599
|
-
function positionCompactPanel(el, root, rootRect) {
|
|
1600
|
-
const margin = 8;
|
|
1601
|
-
const vw = window.innerWidth;
|
|
1602
|
-
const trigger = root.querySelector("[class*=\"7KE1Ra_trigger\"], [class*=\"_trigger\"]") ?? root;
|
|
1603
|
-
const anchorRect = trigger === root ? rootRect : trigger.getBoundingClientRect();
|
|
1604
1563
|
el.style.setProperty("position", "fixed", "important");
|
|
1605
1564
|
el.style.setProperty("box-sizing", "border-box", "important");
|
|
1606
1565
|
el.style.setProperty("left", "0", "important");
|
|
1607
|
-
el.style.setProperty("top", "0", "important");
|
|
1608
1566
|
el.style.setProperty("right", "auto", "important");
|
|
1567
|
+
el.style.setProperty("top", "0", "important");
|
|
1609
1568
|
el.style.setProperty("bottom", "auto", "important");
|
|
1610
|
-
el.style.setProperty("width", "max-content", "important");
|
|
1611
1569
|
el.style.setProperty("min-width", "0", "important");
|
|
1612
|
-
el.style.setProperty("max-width", `${Math.min(
|
|
1613
|
-
el.style.setProperty("max-height",
|
|
1614
|
-
el.style.setProperty("overflow-y", "
|
|
1615
|
-
|
|
1616
|
-
|
|
1617
|
-
const
|
|
1618
|
-
const
|
|
1619
|
-
const
|
|
1620
|
-
const
|
|
1570
|
+
el.style.setProperty("max-width", `${Math.max(0, Math.min(maxWidth, vw - 16))}px`, "important");
|
|
1571
|
+
el.style.setProperty("max-height", `${Math.max(0, Math.min(maxHeight, vh - 16))}px`, "important");
|
|
1572
|
+
el.style.setProperty("overflow-y", "auto", "important");
|
|
1573
|
+
let width = el.offsetWidth;
|
|
1574
|
+
let height = el.offsetHeight;
|
|
1575
|
+
const spaceAbove = Math.max(0, triggerRect.top - 16);
|
|
1576
|
+
const spaceBelow = Math.max(0, vh - triggerRect.bottom - 16);
|
|
1577
|
+
const expandUp = height <= spaceAbove || spaceAbove >= spaceBelow;
|
|
1578
|
+
const available = expandUp ? spaceAbove : spaceBelow;
|
|
1579
|
+
if (height > available) {
|
|
1580
|
+
el.style.setProperty("max-height", `${Math.max(0, available - margin)}px`, "important");
|
|
1581
|
+
height = el.offsetHeight;
|
|
1582
|
+
width = el.offsetWidth;
|
|
1583
|
+
}
|
|
1584
|
+
const top = expandUp ? triggerRect.top - margin - height : triggerRect.bottom + margin;
|
|
1585
|
+
const left = Math.max(margin, Math.min(triggerRect.right - width, vw - width - margin));
|
|
1621
1586
|
el.style.setProperty("left", `${left}px`, "important");
|
|
1622
|
-
el.style.setProperty("top", `${top}px`, "important");
|
|
1623
|
-
el.style.setProperty("width", `${w}px`, "important");
|
|
1587
|
+
el.style.setProperty("top", `${Math.max(margin, Math.min(top, vh - height - margin))}px`, "important");
|
|
1624
1588
|
}
|
|
1625
1589
|
/**
|
|
1626
1590
|
* 模型名多为纯连字符词(DeepSeek-V4-Flash-Vision-Exp);white-space:normal 下
|
|
@@ -1673,7 +1637,7 @@ window.__ModuleLoader__.load({
|
|
|
1673
1637
|
n.style.removeProperty("font-size");
|
|
1674
1638
|
}
|
|
1675
1639
|
}
|
|
1676
|
-
/** 清除
|
|
1640
|
+
/** 清除 anchored menu 写入的内联样式,交还上游 CSS。 */
|
|
1677
1641
|
function clearFixedSheet(el) {
|
|
1678
1642
|
if (el === null || el === void 0) return;
|
|
1679
1643
|
for (const key of SHEET_PROPS) el.style.removeProperty(key);
|
|
@@ -1683,10 +1647,8 @@ window.__ModuleLoader__.load({
|
|
|
1683
1647
|
* 元素:一级 Model/Effort 单元格列表(cellLabel),点击后切到模型列表(modelName)
|
|
1684
1648
|
* 或档位列表。上游默认 `position:absolute;right:0` 贴触发按钮右缘,触发按钮在
|
|
1685
1649
|
* 可横向滚动的 stats 行内时菜单会整体出屏。两级 pane 都必须接管(不能只按
|
|
1686
|
-
* modelName 匹配,否则一级 pane
|
|
1687
|
-
*
|
|
1688
|
-
* 二级列表走视口级居中 fixed sheet(左右各 8px、高度 45% 视口封顶、
|
|
1689
|
-
* 内容滚动、上方空间不足时向下展开)。
|
|
1650
|
+
* modelName 匹配,否则一级 pane 漏掉)。所有视口都把菜单锚定到触发按钮,
|
|
1651
|
+
* 在上方/下方可用空间中选择更合适的一侧,避免上游空间不足时把菜单钳到屏幕顶端。
|
|
1690
1652
|
*/
|
|
1691
1653
|
function installModelMenuPosition(ctx) {
|
|
1692
1654
|
ctx.effect(() => {
|
|
@@ -1706,37 +1668,41 @@ window.__ModuleLoader__.load({
|
|
|
1706
1668
|
let fittedVw = 0;
|
|
1707
1669
|
let fittedSig = -1;
|
|
1708
1670
|
let fittedMenus = [];
|
|
1671
|
+
let positionedMenus = [];
|
|
1709
1672
|
const sync = () => {
|
|
1710
1673
|
const menus = findMenus();
|
|
1711
|
-
if (!narrow.matches) {
|
|
1712
|
-
if (fittedMenus.length > 0) {
|
|
1713
|
-
for (const menu of fittedMenus) {
|
|
1714
|
-
clearFixedSheet(menu);
|
|
1715
|
-
clearModelNameFit(menu);
|
|
1716
|
-
}
|
|
1717
|
-
fittedVw = 0;
|
|
1718
|
-
fittedSig = -1;
|
|
1719
|
-
fittedMenus = [];
|
|
1720
|
-
window.dispatchEvent(new Event("resize"));
|
|
1721
|
-
}
|
|
1722
|
-
return;
|
|
1723
|
-
}
|
|
1724
1674
|
let vw = 0;
|
|
1725
1675
|
let sig = 0;
|
|
1726
1676
|
const modelMenus = [];
|
|
1677
|
+
const visibleMenus = [];
|
|
1727
1678
|
for (const menu of menus) {
|
|
1728
1679
|
const trigger = findTrigger(menu);
|
|
1729
|
-
if (trigger === null) continue;
|
|
1680
|
+
if (trigger === null || trigger.getAttribute("aria-expanded") !== "true") continue;
|
|
1730
1681
|
const rect = menu.getBoundingClientRect();
|
|
1731
1682
|
if (rect.width === 0 && rect.height === 0) continue;
|
|
1732
|
-
|
|
1683
|
+
positionAnchoredMenu(menu, trigger.getBoundingClientRect(), Math.min(420, window.innerWidth - 16), 360);
|
|
1684
|
+
visibleMenus.push(menu);
|
|
1733
1685
|
if (menu.querySelector("[class*=\"modelName\"]")) {
|
|
1734
|
-
positionFixedSheet(menu, triggerRect, Number.POSITIVE_INFINITY, .45);
|
|
1735
|
-
applyNonBreakingHyphens(menu);
|
|
1736
1686
|
modelMenus.push(menu);
|
|
1737
|
-
|
|
1738
|
-
|
|
1739
|
-
|
|
1687
|
+
if (narrow.matches) {
|
|
1688
|
+
applyNonBreakingHyphens(menu);
|
|
1689
|
+
vw = window.innerWidth;
|
|
1690
|
+
for (const n of menu.querySelectorAll("[class*=\"modelName\"]")) sig += n.textContent?.length ?? 0;
|
|
1691
|
+
}
|
|
1692
|
+
}
|
|
1693
|
+
}
|
|
1694
|
+
for (const previous of positionedMenus) {
|
|
1695
|
+
if (visibleMenus.includes(previous)) continue;
|
|
1696
|
+
clearFixedSheet(previous);
|
|
1697
|
+
clearModelNameFit(previous);
|
|
1698
|
+
}
|
|
1699
|
+
positionedMenus = visibleMenus;
|
|
1700
|
+
if (!narrow.matches) {
|
|
1701
|
+
for (const menu of modelMenus) clearModelNameFit(menu);
|
|
1702
|
+
fittedVw = 0;
|
|
1703
|
+
fittedSig = -1;
|
|
1704
|
+
fittedMenus = [];
|
|
1705
|
+
return;
|
|
1740
1706
|
}
|
|
1741
1707
|
const needFit = modelMenus.some((m) => !fittedMenus.includes(m));
|
|
1742
1708
|
if (vw > 0 && (needFit || vw !== fittedVw || sig !== fittedSig)) {
|
|
@@ -2350,11 +2316,9 @@ window.__ModuleLoader__.load({
|
|
|
2350
2316
|
if (selectedId === "new") return;
|
|
2351
2317
|
setBusy(true);
|
|
2352
2318
|
try {
|
|
2353
|
-
const
|
|
2354
|
-
|
|
2355
|
-
|
|
2356
|
-
} catch {}
|
|
2357
|
-
if ((await fetch(`/api/dshb/nodes/${selectedId}`, { method: "DELETE" })).ok) {
|
|
2319
|
+
const res = await fetch(`/api/dshb/nodes/${selectedId}`, { method: "DELETE" });
|
|
2320
|
+
const data = await res.json();
|
|
2321
|
+
if (res.ok && data.ok) {
|
|
2358
2322
|
flash({
|
|
2359
2323
|
kind: "ok",
|
|
2360
2324
|
text: "节点已删除"
|
|
@@ -2362,7 +2326,10 @@ window.__ModuleLoader__.load({
|
|
|
2362
2326
|
setSelectedId("new");
|
|
2363
2327
|
setForm(EMPTY_FORM);
|
|
2364
2328
|
reload();
|
|
2365
|
-
}
|
|
2329
|
+
} else flash({
|
|
2330
|
+
kind: "error",
|
|
2331
|
+
text: data.error ?? "删除失败"
|
|
2332
|
+
});
|
|
2366
2333
|
} catch {
|
|
2367
2334
|
flash({
|
|
2368
2335
|
kind: "error",
|
|
@@ -2373,7 +2340,6 @@ window.__ModuleLoader__.load({
|
|
|
2373
2340
|
}
|
|
2374
2341
|
}, [
|
|
2375
2342
|
selectedId,
|
|
2376
|
-
nodes,
|
|
2377
2343
|
flash,
|
|
2378
2344
|
reload
|
|
2379
2345
|
]);
|