dsh-stall-guard 0.1.1 → 0.1.3
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/CHANGELOG.md +22 -0
- package/client.js +47 -13
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,28 @@
|
|
|
5
5
|
格式参考 [Keep a Changelog](https://keepachangelog.com/zh-CN/1.1.0/),
|
|
6
6
|
版本号遵循 [语义化版本](https://semver.org/lang/zh-CN/)。
|
|
7
7
|
|
|
8
|
+
## [0.1.3] - 2026-10-21
|
|
9
|
+
|
|
10
|
+
### 修复
|
|
11
|
+
|
|
12
|
+
- **拖动图标会带动上方状态栏**:浮动态原先仍渲染在标题栏槽位里,那个槽位是正常文档流
|
|
13
|
+
中的 flex 项,`position:fixed` 在那里无效,图标移动时会把整行撑动。
|
|
14
|
+
现在浮动态改由 `shell.overlay` 渲染(真正脱离所有列与滚动容器),标题栏在浮动时
|
|
15
|
+
渲染空。这样图标可以像贴纸一样拖到任意位置,不影响任何其他元素。
|
|
16
|
+
- **调整大小时看不到实时预览**:设置面板原先从 `top:56px` 开始展开,正好压住标题栏
|
|
17
|
+
上的图标,所以拖滑块时看不到尺寸变化。面板改为从标题栏下方开始(`top:118px`)。
|
|
18
|
+
- 浮动态的层级提到面板之上(`z-index:75`),即使图标被拖到面板范围内也仍然可见可拖。
|
|
19
|
+
- 拖动位置改从 store 读取而不是每帧读 localStorage,避免高频拖动时状态竞争、
|
|
20
|
+
丢中间位置。
|
|
21
|
+
|
|
22
|
+
## [0.1.2] - 2026-10-21
|
|
23
|
+
|
|
24
|
+
### 修复
|
|
25
|
+
|
|
26
|
+
- **点气泡会打开面板**:0.1.1 里气泡的点击改成了「关闭提示」(`acknowledge`),
|
|
27
|
+
但这个改动晚于 0.1.1 的发布,所以 npm 上那版仍是旧的。本版包含该修复。
|
|
28
|
+
现在点气泡 = 关掉通知,点鱼图标 = 打开设置。
|
|
29
|
+
|
|
8
30
|
## [0.1.1] - 2026-10-21
|
|
9
31
|
|
|
10
32
|
### 新增
|
package/client.js
CHANGED
|
@@ -208,7 +208,8 @@ window.__ModuleLoader__.load({
|
|
|
208
208
|
showSupervisor: 'Show the supervisor',
|
|
209
209
|
showSupervisorHint: 'Off hides the figure but keeps the guard running; a small tab stays in the corner so you can switch it back.',
|
|
210
210
|
showBubble: 'Show the text bubble on a stall',
|
|
211
|
-
showBubbleHint: 'Off keeps the bouncing animation but hides the sentence. Click the
|
|
211
|
+
showBubbleHint: 'Off keeps the bouncing animation but hides the sentence. Click the bubble to dismiss it; click the figure for settings.',
|
|
212
|
+
dismissBubble: 'Dismiss this notice',
|
|
212
213
|
supervisorHiddenHint: 'Supervisor hidden — click to open settings',
|
|
213
214
|
appearanceLabel: 'Icon appearance (this browser only)',
|
|
214
215
|
iconSize: 'Size',
|
|
@@ -299,7 +300,8 @@ window.__ModuleLoader__.load({
|
|
|
299
300
|
showSupervisor: '\u663e\u793a\u76d1\u7763\u5458',
|
|
300
301
|
showSupervisorHint: '\u5173\u6389\u540e\u4e0d\u518d\u663e\u793a\u5f62\u8c61\uff0c\u4f46\u5b88\u536b\u4ecd\u5728\u8fd0\u884c\uff1b\u53f3\u4e0b\u89d2\u4f1a\u7559\u4e00\u4e2a\u5c0f\u70b9\uff0c\u70b9\u5b83\u53ef\u4ee5\u518d\u6253\u5f00\u3002',
|
|
301
302
|
showBubble: '\u5361\u987f\u65f6\u663e\u793a\u6587\u5b57\u6c14\u6ce1',
|
|
302
|
-
showBubbleHint: '\u5173\u6389\u4ecd\u4f1a\u8df3\u52a8\uff0c\u4f46\u4e0d\u663e\u793a\u6587\u5b57\u3002\u70b9\
|
|
303
|
+
showBubbleHint: '\u5173\u6389\u4ecd\u4f1a\u8df3\u52a8\uff0c\u4f46\u4e0d\u663e\u793a\u6587\u5b57\u3002\u70b9\u6c14\u6ce1\u53ef\u4ee5\u5173\u6389\u5b83\uff1b\u70b9\u56fe\u6807\u6253\u5f00\u8bbe\u7f6e\u3002',
|
|
304
|
+
dismissBubble: '\u5173\u6389\u8fd9\u6761\u63d0\u793a',
|
|
303
305
|
supervisorHiddenHint: '\u76d1\u7763\u5458\u5df2\u9690\u85cf \u2014 \u70b9\u51fb\u6253\u5f00\u8bbe\u7f6e',
|
|
304
306
|
appearanceLabel: '\u56fe\u6807\u5916\u89c2\uff08\u4ec5\u672c\u6d4f\u89c8\u5668\uff09',
|
|
305
307
|
iconSize: '\u5927\u5c0f',
|
|
@@ -953,7 +955,7 @@ window.__ModuleLoader__.load({
|
|
|
953
955
|
/* Hidden state: the bubble is not rendered at all, so there is nothing to dim. */
|
|
954
956
|
|
|
955
957
|
/* ---- overlay panel ---- */
|
|
956
|
-
'.dsg-panel{position:fixed;top:
|
|
958
|
+
'.dsg-panel{position:fixed;top:118px;right:14px;left:auto;z-index:70;box-sizing:border-box;width:min(430px,calc(100vw - 40px));max-height:min(74vh,660px);overflow:hidden;pointer-events:auto;display:flex;flex-direction:column;gap:0;padding:12px;border:1px solid var(--dsw-alias-border-l1,var(--dsh-border,rgba(255,255,255,.12)));border-radius:var(--dsw-radius-panel,12px);background:var(--dsw-alias-bg-overlay,var(--dsh-surface,rgba(20,22,28,.96)));box-shadow:var(--dsw-elevation-soft,0 8px 28px rgba(0,0,0,.22));color:var(--dsw-alias-label-primary,var(--dsh-text-primary,#e6e6e6));font:inherit;font-size:12px;line-height:18px}',
|
|
957
959
|
'.dsg-head{display:flex;align-items:center;gap:8px;flex-wrap:wrap;flex:0 0 auto;padding-bottom:8px}',
|
|
958
960
|
/* The title bar holds Save and Close now, so the title must not push them out. */
|
|
959
961
|
'.dsg-title{flex:0 1 auto;min-width:0;margin:0;font-size:13px;font-weight:600;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}',
|
|
@@ -1038,7 +1040,7 @@ window.__ModuleLoader__.load({
|
|
|
1038
1040
|
'.dsg-offTab{display:block;width:100%;height:100%;border-radius:50%}',
|
|
1039
1041
|
'.dsg-orb[data-floating="yes"]{box-shadow:0 2px 10px rgba(0,0,0,.28);background:var(--dsw-alias-bg-overlay,var(--dsh-surface,rgba(20,22,28,.9)));border:1px solid var(--dsw-alias-border-l1,var(--dsh-border,rgba(255,255,255,.12)))}',
|
|
1040
1042
|
'.dsg-orb[data-dragging="yes"]{transition:none!important;cursor:grabbing}',
|
|
1041
|
-
'.dsg-seat[data-floating="yes"]{position:fixed}',
|
|
1043
|
+
'.dsg-seat[data-floating="yes"]{position:fixed;z-index:75}',
|
|
1042
1044
|
/* Only visible while the supervisor is hidden: a 14px grab handle in the corner. */
|
|
1043
1045
|
'.dsg-restoreTab{position:fixed;right:10px;bottom:10px;z-index:67;width:14px;height:14px;padding:0;border:1px solid var(--dsw-alias-border-l1,var(--dsh-border,rgba(255,255,255,.2)));border-radius:50%;background:var(--dsw-alias-label-tertiary,var(--dsh-text-muted,#8b93a7));opacity:.4;cursor:pointer;transition:opacity .15s ease,transform .15s ease}',
|
|
1044
1046
|
'.dsg-restoreTab:hover,.dsg-restoreTab:focus-visible{opacity:1;transform:scale(1.35);background:var(--dsw-alias-brand-primary,var(--dsh-accent,#4d6bfe))}',
|
|
@@ -1236,7 +1238,8 @@ window.__ModuleLoader__.load({
|
|
|
1236
1238
|
|
|
1237
1239
|
/* Float placement: drag moves the control, and the position is clamped into the
|
|
1238
1240
|
* viewport on release so a window resize cannot strand it off-screen. */
|
|
1239
|
-
|
|
1241
|
+
// The overlay seat forces the floating posture; the header seat reads the setting.
|
|
1242
|
+
const floating = props.forcePlace === 'float' || appearance.place === 'float';
|
|
1240
1243
|
const startDrag = useCallback((event) => {
|
|
1241
1244
|
if (!floating) return;
|
|
1242
1245
|
if (event.button !== undefined && event.button !== 0) return;
|
|
@@ -1252,7 +1255,9 @@ window.__ModuleLoader__.load({
|
|
|
1252
1255
|
setDragging(true);
|
|
1253
1256
|
const nextX = Math.max(0, Math.min(window.innerWidth - rect.width, moveEvent.clientX - offsetX));
|
|
1254
1257
|
const nextY = Math.max(0, Math.min(window.innerHeight - rect.height, moveEvent.clientY - offsetY));
|
|
1255
|
-
|
|
1258
|
+
// Read from the store, not localStorage: a per-frame disk read would race with
|
|
1259
|
+
// the in-memory value and drop intermediate positions.
|
|
1260
|
+
store.setAppearance({ ...store.getAppearance(), x: Math.round(nextX), y: Math.round(nextY) });
|
|
1256
1261
|
};
|
|
1257
1262
|
const onUp = () => {
|
|
1258
1263
|
window.removeEventListener('pointermove', onMove);
|
|
@@ -1265,10 +1270,10 @@ window.__ModuleLoader__.load({
|
|
|
1265
1270
|
event.preventDefault();
|
|
1266
1271
|
}, [floating]);
|
|
1267
1272
|
|
|
1268
|
-
// Hidden
|
|
1269
|
-
//
|
|
1270
|
-
//
|
|
1271
|
-
if (supervisorOff) return null;
|
|
1273
|
+
// Hidden, or drawn by the overlay because it floats: the header renders nothing in
|
|
1274
|
+
// both cases. A floating figure inside the header's flow would push the header row
|
|
1275
|
+
// around as it moved, which is exactly the bug this split fixes.
|
|
1276
|
+
if (supervisorOff || floating) return null;
|
|
1272
1277
|
|
|
1273
1278
|
const label = t('supervisor') + ' — ' + t(MODE_KEY[mode]);
|
|
1274
1279
|
const size = appearance.size;
|
|
@@ -1318,16 +1323,20 @@ window.__ModuleLoader__.load({
|
|
|
1318
1323
|
'data-place': bubbleBelow ? 'below' : 'above',
|
|
1319
1324
|
role: 'button',
|
|
1320
1325
|
tabIndex: 0,
|
|
1321
|
-
title: t('
|
|
1326
|
+
title: t('dismissBubble'),
|
|
1327
|
+
'aria-label': t('dismissBubble'),
|
|
1328
|
+
/* Pressing the notice dismisses it; it does not navigate. Opening the settings
|
|
1329
|
+
* panel stays on the figure, so the two affordances cannot be confused. */
|
|
1322
1330
|
onClick: (event) => {
|
|
1323
1331
|
event.stopPropagation();
|
|
1324
|
-
|
|
1332
|
+
event.preventDefault();
|
|
1333
|
+
void store.acknowledge();
|
|
1325
1334
|
},
|
|
1326
1335
|
onKeyDown: (event) => {
|
|
1327
1336
|
if (event.key === 'Enter' || event.key === ' ') {
|
|
1328
1337
|
event.preventDefault();
|
|
1329
1338
|
event.stopPropagation();
|
|
1330
|
-
store.
|
|
1339
|
+
void store.acknowledge();
|
|
1331
1340
|
}
|
|
1332
1341
|
},
|
|
1333
1342
|
}, message)
|
|
@@ -1335,6 +1344,22 @@ window.__ModuleLoader__.load({
|
|
|
1335
1344
|
);
|
|
1336
1345
|
}
|
|
1337
1346
|
|
|
1347
|
+
/**
|
|
1348
|
+
* The floating posture, rendered in the frame-wide overlay.
|
|
1349
|
+
*
|
|
1350
|
+
* `shell.overlay` is outside every column and scroll container, so an absolutely
|
|
1351
|
+
* positioned figure there cannot affect the header's layout. The component is shared
|
|
1352
|
+
* with the header seat; only the posture differs.
|
|
1353
|
+
*/
|
|
1354
|
+
function FloatingSeat(props) {
|
|
1355
|
+
const t = useTranslate(props);
|
|
1356
|
+
const snapshot = useStore();
|
|
1357
|
+
useEffect(() => store.start(), []);
|
|
1358
|
+
if (snapshot.config === null) return null;
|
|
1359
|
+
if (snapshot.config.supervisor.show === false) return null;
|
|
1360
|
+
return h(SupervisorSeat, { t, forcePlace: 'float' });
|
|
1361
|
+
}
|
|
1362
|
+
|
|
1338
1363
|
/* ------------------------------------------------------------ the panel */
|
|
1339
1364
|
|
|
1340
1365
|
function StatValue(props) {
|
|
@@ -1973,6 +1998,15 @@ window.__ModuleLoader__.load({
|
|
|
1973
1998
|
inject: () => ({}),
|
|
1974
1999
|
}, PanelSeat));
|
|
1975
2000
|
|
|
2001
|
+
// The floating posture lives in the overlay so it cannot disturb the header row.
|
|
2002
|
+
ctx.slots.inject('shell.overlay', () => ctx.slots.register({
|
|
2003
|
+
name: 'shell.overlay',
|
|
2004
|
+
id: 'stall-guard-floating',
|
|
2005
|
+
order: 69,
|
|
2006
|
+
locale: NS,
|
|
2007
|
+
inject: () => ({}),
|
|
2008
|
+
}, FloatingSeat));
|
|
2009
|
+
|
|
1976
2010
|
// The way back when the supervisor is hidden.
|
|
1977
2011
|
ctx.slots.inject('shell.overlay', () => ctx.slots.register({
|
|
1978
2012
|
name: 'shell.overlay',
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dsh-stall-guard",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.3",
|
|
4
4
|
"description": "DSH 卡顿守卫:下载类命令(git clone / pnpm install / pip / curl)超时后自动中止,并把「换个下载源重试」的提示写进工具结果给智能体看,解决 GitHub 在国内网络不稳导致智能体一直干等的问题。另可按工具类型自定义超时秒数,并附一个只在卡顿时唤醒的 DeepSeek 监督员。",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"dsh",
|