@goodandready/dsh-usage-guard 0.1.3 → 0.1.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/README.md +18 -0
- package/README.ru.md +18 -0
- package/README.zh.md +18 -0
- package/lib/client.js +13 -70
- package/lib/index.js +6 -1
- package/lib/patch.js +7 -4
- package/lib/usage.js +4 -4
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -112,6 +112,24 @@ Logs informative diagnostic warnings naming the exact session, turn, step, raw p
|
|
|
112
112
|
|
|
113
113
|
---
|
|
114
114
|
|
|
115
|
+
## 🚀 Changed in v0.1.5
|
|
116
|
+
|
|
117
|
+
* **Strict `settings.plugin.item` Registration (#3)**:
|
|
118
|
+
Completely removed the deprecated fallback registration into `settings.section`. In compliance with DSH Plugin Authoring guidelines, settings are rendered exclusively in the "Settings → Plugins" tab (`settings.plugin.item`) with key `dsh-usage-guard` without cluttering the global sidebar.
|
|
119
|
+
* **Refined Client Architecture**:
|
|
120
|
+
Cleaned up the browser bundle to register strictly one slot entry with zero runtime fallback delays.
|
|
121
|
+
|
|
122
|
+
## 🚀 Changed in v0.1.4
|
|
123
|
+
|
|
124
|
+
* **Style Isolation with `data-dsh-plugin`**:
|
|
125
|
+
Dynamic `<style>` element is explicitly tagged with `data-dsh-plugin="dsh-usage-guard"`, preventing style purging during neighbor plugin reloads or HMR.
|
|
126
|
+
* **Direct Slot Registration**:
|
|
127
|
+
Replaced broken invocation pattern with standard `ctx.slots.register('settings.plugin.item', ...)`.
|
|
128
|
+
* **Canonical Localization Standard**:
|
|
129
|
+
Streamlined client registration to strictly register the canonical English locale dictionary, delegating localized user interfaces to DSH translation plugins.
|
|
130
|
+
* **Safe Configuration Loading & English Diagnostics**:
|
|
131
|
+
Protected `Config()` initialization with `try...catch` and migrated diagnostic log messages to English.
|
|
132
|
+
|
|
115
133
|
## 🚀 Changed in v0.1.3
|
|
116
134
|
|
|
117
135
|
* **Fractional Token Protection (Floats & Decimals)**:
|
package/README.ru.md
CHANGED
|
@@ -112,6 +112,24 @@ graph LR
|
|
|
112
112
|
|
|
113
113
|
---
|
|
114
114
|
|
|
115
|
+
## 🚀 Изменения в версии v0.1.5 (Changed in v0.1.5)
|
|
116
|
+
|
|
117
|
+
* **Строгая регистрация в `settings.plugin.item` (#3)**:
|
|
118
|
+
Полностью удалена устаревшая ветка регистрации в боковом меню `settings.section`. По канону DSH Plugin Authoring карточка настроек размещается исключительно во вкладке «Настройки → Плагины» (`settings.plugin.item`) с ключом `dsh-usage-guard`, не занимая ограниченный ресурс бокового списка.
|
|
119
|
+
* **Очистка клиентской архитектуры**:
|
|
120
|
+
Регистрация интерфейса упрощена до единственного прямого вызова без задержек и fallback-таймеров.
|
|
121
|
+
|
|
122
|
+
## 🚀 Изменения в версии v0.1.4 (Changed in v0.1.4)
|
|
123
|
+
|
|
124
|
+
* **Изоляция стилей через `data-dsh-plugin`**:
|
|
125
|
+
Динамический тег `<style>` помечен атрибутом `data-dsh-plugin="dsh-usage-guard"`, предотвращая сброс стилей карточки при HMR или обновлении соседних плагинов.
|
|
126
|
+
* **Прямая регистрация слота**:
|
|
127
|
+
Заменён некорректный вызов `ctx.slots.inject()` на прямой `ctx.slots.register('settings.plugin.item', ...)`.
|
|
128
|
+
* **Канонический стандарт локализации**:
|
|
129
|
+
Клиентский модуль регистрирует только канонический словарь `en`, передавая управление переводами системному translation-плагину.
|
|
130
|
+
* **Безопасная инициализация и англоязычные логи**:
|
|
131
|
+
Вызов `Config()` защищён блоком `try...catch`, а системные предупреждения в консоли переведены на английский язык.
|
|
132
|
+
|
|
115
133
|
## 🚀 Изменения в версии v0.1.3 (Changed in v0.1.3)
|
|
116
134
|
|
|
117
135
|
* **Защита от дробных токенов (Floats & Decimals)**:
|
package/README.zh.md
CHANGED
|
@@ -85,6 +85,24 @@ graph LR
|
|
|
85
85
|
|
|
86
86
|
---
|
|
87
87
|
|
|
88
|
+
## 🚀 v0.1.5 版本更新说明 (Changed in v0.1.5)
|
|
89
|
+
|
|
90
|
+
* **规范设置卡片插槽注册 (#3)**:
|
|
91
|
+
彻底移除废弃的顶层侧边栏 `settings.section` 回退逻辑。严格遵循 DSH Plugin Authoring 规范,卡片仅注册至“设置 → 插件”标签页(`settings.plugin.item`),键名与命名空间一致为 `dsh-usage-guard`,不再占用全局侧边栏资源。
|
|
92
|
+
* **精简前端注册流**:
|
|
93
|
+
客户端模块仅保留标准单一插槽注册,无任何额外回退延时。
|
|
94
|
+
|
|
95
|
+
## 🚀 v0.1.4 版本更新说明 (Changed in v0.1.4)
|
|
96
|
+
|
|
97
|
+
* **样式隔离标记 `data-dsh-plugin`**:
|
|
98
|
+
动态 `<style>` 标签附加 `data-dsh-plugin="dsh-usage-guard"` 属性,避免被相邻插件的热重载清理机制误删。
|
|
99
|
+
* **修复插槽直接注册**:
|
|
100
|
+
替换无效的 `ctx.slots.inject()` 调用为直接标准 `ctx.slots.register('settings.plugin.item', ...)`。
|
|
101
|
+
* **规范化单一英文字典**:
|
|
102
|
+
客户端仅保留基础英语字典,翻译工作完全交由 DSH 核心翻译插件运行时接管。
|
|
103
|
+
* **安全配置初始化与全英文诊断**:
|
|
104
|
+
`Config()` 初始化增加 `try...catch` 防护,控制台输出全面切换为标准英语日志。
|
|
105
|
+
|
|
88
106
|
## 🚀 v0.1.3 版本更新说明 (Changed in v0.1.3)
|
|
89
107
|
|
|
90
108
|
* **浮点与小数 Token 防崩保护 (Floats & Decimals)**:
|
package/lib/client.js
CHANGED
|
@@ -136,7 +136,7 @@ window.__ModuleLoader__.load({
|
|
|
136
136
|
const badgeClass = isRepairActive ? 'ug-badge ug-badge-green' : 'ug-badge ug-badge-yellow';
|
|
137
137
|
|
|
138
138
|
return React.createElement('div', { className: 'ug-card' },
|
|
139
|
-
React.createElement('style',
|
|
139
|
+
React.createElement('style', {'data-dsh-plugin': 'dsh-usage-guard'}, `
|
|
140
140
|
.ug-card { border:1px solid var(--dsw-alias-border-l2); background:var(--dsw-alias-bg-layer-3); border-radius:12px; list-style:none }
|
|
141
141
|
.ug-head { appearance:none; width:100%; font:inherit; color:inherit; text-align:left; cursor:pointer; background:0 0; border:0; border-radius:12px; display:flex; align-items:center; gap:12px; padding:14px 16px }
|
|
142
142
|
.ug-title { color:var(--dsw-alias-label-primary); font-size:15px; font-weight:600; line-height:1.4 }
|
|
@@ -226,81 +226,24 @@ window.__ModuleLoader__.load({
|
|
|
226
226
|
report: 'Log diagnostic warnings',
|
|
227
227
|
reportDesc: 'Log a line naming the turn, step, and raw sample whenever damaged usage arrives.',
|
|
228
228
|
},
|
|
229
|
-
ru: {
|
|
230
|
-
title: 'Защита истории токенов',
|
|
231
|
-
subtitle: 'Санитайзер расхода токенов и защита от сбоев истории',
|
|
232
|
-
active: 'АКТИВЕН',
|
|
233
|
-
reportOnly: 'ТОЛЬКО ЛОГ',
|
|
234
|
-
saved: 'Сохранено',
|
|
235
|
-
loading: 'Загрузка…',
|
|
236
|
-
unavailable: 'Пространство настроек недоступно',
|
|
237
|
-
save: 'Сохранить',
|
|
238
|
-
saving: 'Сохранение…',
|
|
239
|
-
repair: 'Автоматическое исправление расхода',
|
|
240
|
-
repairDesc: 'Подставлять ноль вместо повреждённых счётчиков до сложения для предотвращения блокировки истории диалогов.',
|
|
241
|
-
report: 'Диагностические предупреждения',
|
|
242
|
-
reportDesc: 'Логировать номер хода, шага и исходные данные при обнаружении битой порции расхода.',
|
|
243
|
-
},
|
|
244
|
-
zh: {
|
|
245
|
-
title: '用量与会话防崩守卫',
|
|
246
|
-
subtitle: 'Token 用量数据清洗与历史记录防白屏保护',
|
|
247
|
-
active: '已激活',
|
|
248
|
-
reportOnly: '仅记录',
|
|
249
|
-
saved: '已保存',
|
|
250
|
-
loading: '加载中…',
|
|
251
|
-
unavailable: '设置作用域不可用',
|
|
252
|
-
save: '保存',
|
|
253
|
-
saving: '保存中…',
|
|
254
|
-
repair: '自动修复用量计数',
|
|
255
|
-
repairDesc: '在累加前将缺失或非数字计数置为 0,彻底防止 NaN 导致会话历史永久白屏。',
|
|
256
|
-
report: '记录诊断告警',
|
|
257
|
-
reportDesc: '当检测到异常用量数据包时,在控制台记录轮次、步骤和原始数据。',
|
|
258
|
-
},
|
|
259
229
|
});
|
|
260
230
|
} catch (_) {}
|
|
261
231
|
|
|
262
|
-
|
|
232
|
+
// Register exclusively in settings.plugin.item (DSH Settings → Plugins tab).
|
|
233
|
+
// Custom top-level sidebar sections (settings.section) are forbidden for simple plugin settings cards.
|
|
263
234
|
try {
|
|
264
|
-
if (ctx.slots && typeof ctx.slots.
|
|
265
|
-
ctx.slots.
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
PluginCard,
|
|
275
|
-
);
|
|
276
|
-
});
|
|
235
|
+
if (ctx.slots && typeof ctx.slots.register === 'function') {
|
|
236
|
+
ctx.slots.register(
|
|
237
|
+
{
|
|
238
|
+
name: 'settings.plugin.item',
|
|
239
|
+
key: NS,
|
|
240
|
+
locale: NS,
|
|
241
|
+
inject: () => ({ ctx }),
|
|
242
|
+
},
|
|
243
|
+
PluginCard,
|
|
244
|
+
);
|
|
277
245
|
}
|
|
278
246
|
} catch (_) {}
|
|
279
|
-
|
|
280
|
-
const timer = setTimeout(() => {
|
|
281
|
-
if (placed) return;
|
|
282
|
-
try {
|
|
283
|
-
if (ctx.slots && typeof ctx.slots.inject === 'function') {
|
|
284
|
-
ctx.slots.inject('settings.section', () => {
|
|
285
|
-
ctx.slots.register(
|
|
286
|
-
{
|
|
287
|
-
name: 'settings.section',
|
|
288
|
-
id: '@goodandready/dsh-usage-guard',
|
|
289
|
-
order: 50,
|
|
290
|
-
locale: NS,
|
|
291
|
-
label: () => (ctx.locale && ctx.locale.bind ? ctx.locale.bind(NS)('title') : 'Usage Guard'),
|
|
292
|
-
inject: () => ({ ctx }),
|
|
293
|
-
},
|
|
294
|
-
PluginCard,
|
|
295
|
-
);
|
|
296
|
-
});
|
|
297
|
-
}
|
|
298
|
-
} catch (_) {}
|
|
299
|
-
}, 3000);
|
|
300
|
-
|
|
301
|
-
if (typeof ctx.effect === 'function') {
|
|
302
|
-
ctx.effect(() => () => clearTimeout(timer), 'dsh-usage-guard: fallback section');
|
|
303
|
-
}
|
|
304
247
|
};
|
|
305
248
|
|
|
306
249
|
return module.exports;
|
package/lib/index.js
CHANGED
|
@@ -48,7 +48,12 @@ export const Config = z.object({
|
|
|
48
48
|
})
|
|
49
49
|
|
|
50
50
|
export function apply(ctx, config) {
|
|
51
|
-
let live
|
|
51
|
+
let live
|
|
52
|
+
try {
|
|
53
|
+
live = Config(structuredClone(config ?? {})) ?? config
|
|
54
|
+
} catch (_) {
|
|
55
|
+
live = Config({}) ?? {}
|
|
56
|
+
}
|
|
52
57
|
|
|
53
58
|
ctx.inject(['settings'], (sctx) => {
|
|
54
59
|
const scope = sctx.settings.register(name, Config, { base: config })
|
package/lib/patch.js
CHANGED
|
@@ -58,16 +58,19 @@ export function patchRegistry(registry, guard) {
|
|
|
58
58
|
}
|
|
59
59
|
|
|
60
60
|
// Заведутся позже — поймаем на укладке в карту.
|
|
61
|
-
|
|
62
|
-
|
|
61
|
+
// Save the current map.set (may be the prototype method or a previous patched version).
|
|
62
|
+
// We restore via explicit assignment — relying on `delete` to restore the prototype method
|
|
63
|
+
// is fragile when the environment mutates Map.prototype.
|
|
64
|
+
const originalSet = map.set
|
|
65
|
+
if (!originalSet[PATCHED]) {
|
|
63
66
|
const patched = function (key, value) {
|
|
64
67
|
if (value && value.def) undo.push(wrapApply(value.def, guard))
|
|
65
|
-
return
|
|
68
|
+
return originalSet.call(this, key, value)
|
|
66
69
|
}
|
|
67
70
|
patched[PATCHED] = true
|
|
68
71
|
map.set = patched
|
|
69
72
|
undo.push(() => {
|
|
70
|
-
if (map.set === patched)
|
|
73
|
+
if (map.set === patched) map.set = originalSet
|
|
71
74
|
})
|
|
72
75
|
}
|
|
73
76
|
|
package/lib/usage.js
CHANGED
|
@@ -194,16 +194,16 @@ function safeStringify(value) {
|
|
|
194
194
|
try {
|
|
195
195
|
return String(value)
|
|
196
196
|
} catch {
|
|
197
|
-
return '[
|
|
197
|
+
return '[not serializable]'
|
|
198
198
|
}
|
|
199
199
|
}
|
|
200
200
|
}
|
|
201
201
|
|
|
202
202
|
/** Короткая строка для журнала: по ней видно, кого звать к ответу. */
|
|
203
203
|
export function complaint(found, bad) {
|
|
204
|
-
const where =
|
|
204
|
+
const where = `turn ${String(found.turn)}, step ${String(found.step)}`
|
|
205
205
|
const taken = bad
|
|
206
|
-
.map((field) => (found.usage && borrowed(found.usage, field) !== undefined ? `${field}
|
|
206
|
+
.map((field) => (found.usage && borrowed(found.usage, field) !== undefined ? `${field} recovered via alias` : `${field} zeroed`))
|
|
207
207
|
.join('; ')
|
|
208
|
-
return
|
|
208
|
+
return `malformed usage sample — ${where}; received: ${safeStringify(found.usage)}; ${taken}`
|
|
209
209
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@goodandready/dsh-usage-guard",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.5",
|
|
4
4
|
"description": "Keeps a malformed token-usage sample from taking a whole session history down with it: a missing or non-numeric counter becomes zero before the harness adds it up, so the fold never yields NaN and already-broken sessions open again.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"deepseek-harness",
|
|
@@ -54,4 +54,4 @@
|
|
|
54
54
|
"scripts": {
|
|
55
55
|
"test": "node --test test/*.test.mjs"
|
|
56
56
|
}
|
|
57
|
-
}
|
|
57
|
+
}
|