@goodandready/dsh-cost-meter 0.8.21 → 0.8.22

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 CHANGED
@@ -103,6 +103,11 @@ window.__ModuleLoader__.load({
103
103
  'projection.burn_rate': 'Burn rate:',
104
104
  'projection.projected': 'Projected:',
105
105
  'projection.per_hour': '/hr',
106
+ 'field.displayMode': 'Display mode',
107
+ 'hint.displayMode': 'Widget display mode: auto (collapses on mobile <= 768px), full, or always compact.',
108
+ 'mode.auto': 'Auto (responsive)',
109
+ 'mode.full': 'Full',
110
+ 'mode.compact': 'Compact pill',
106
111
  }
107
112
 
108
113
  const zh = {
@@ -186,6 +191,11 @@ window.__ModuleLoader__.load({
186
191
  'projection.burn_rate': '消耗速率:',
187
192
  'projection.projected': '预估总计:',
188
193
  'projection.per_hour': '/小时',
194
+ 'field.displayMode': '显示模式',
195
+ 'hint.displayMode': '计量器外观模式:自动(<=768px 移动端自适应折叠)、完整或始终紧凑。',
196
+ 'mode.auto': '自动自适应',
197
+ 'mode.full': '完整显示',
198
+ 'mode.compact': '紧凑药丸',
189
199
  }
190
200
 
191
201
  function makeT(dict, fallback) {
@@ -275,9 +285,11 @@ window.__ModuleLoader__.load({
275
285
  .dcm-dot-idle { background: var(--dsw-alias-label-tertiary); }
276
286
 
277
287
  .dcm-chip-timer { opacity: 0.72; font-size: 11px; padding-left: 2px; border-left: 1px solid var(--dsw-alias-border-l2); }
278
- @media (max-width: 680px) {
288
+ @media (max-width: 768px) {
279
289
  .dcm-chip-timer { display: none; }
290
+ .dcm-panel { width: min(320px, calc(100vw - 32px)); right: 0; }
280
291
  }
292
+ .dcm-chip-compact .dcm-chip-timer { display: none !important; }
281
293
 
282
294
  @keyframes dcm-pulse { 0%, 100% { opacity: 1; transform: scale(1); } 50% { opacity: 0.4; transform: scale(0.85); } }
283
295
 
@@ -640,6 +652,10 @@ window.__ModuleLoader__.load({
640
652
  setSaving(true); setErr(''); setSaved(false)
641
653
  const broken = []
642
654
 
655
+ try {
656
+ await scope.set('displayMode', (draft.displayMode === 'compact' || draft.displayMode === 'full') ? draft.displayMode : 'auto')
657
+ } catch (e) { broken.push('displayMode: ' + (e && e.message || String(e))) }
658
+
643
659
  try {
644
660
  await scope.set('currency', String(draft.currency || '$'))
645
661
  } catch (e) { broken.push('currency: ' + (e && e.message || String(e))) }
@@ -819,6 +835,19 @@ window.__ModuleLoader__.load({
819
835
  ),
820
836
  ),
821
837
  ),
838
+ React.createElement('div', { className: 'dcm-field', style: { marginTop: 6 } },
839
+ React.createElement('label', { className: 'dcm-label' }, t('field.displayMode')),
840
+ React.createElement('select', {
841
+ className: 'dcm-input',
842
+ value: (draft && draft.displayMode) || 'auto',
843
+ onChange: (e) => setDraft({ ...draft, displayMode: e.target.value }),
844
+ }, [
845
+ React.createElement('option', { key: 'auto', value: 'auto' }, t('mode.auto')),
846
+ React.createElement('option', { key: 'full', value: 'full' }, t('mode.full')),
847
+ React.createElement('option', { key: 'compact', value: 'compact' }, t('mode.compact')),
848
+ ]),
849
+ React.createElement('span', { className: 'dcm-hint' }, t('hint.displayMode')),
850
+ ),
822
851
  ),
823
852
 
824
853
  // Section 2: OpenRouter Pricing Catalog
@@ -1225,6 +1254,7 @@ window.__ModuleLoader__.load({
1225
1254
  const currency = stored.currency !== undefined ? String(stored.currency) : (state.currency || '$')
1226
1255
  const fx = stored.usdRate !== undefined && !isNaN(Number(stored.usdRate)) ? Number(stored.usdRate) : (Number(state.usdRate) || 1)
1227
1256
  const budgetThreshold = stored.budgetThreshold !== undefined ? Number(stored.budgetThreshold) : (Number(state.budgetThreshold) || 0)
1257
+ const displayMode = stored.displayMode !== undefined ? stored.displayMode : (state.displayMode || 'auto')
1228
1258
  const schedule = state.schedule
1229
1259
  const hasUsage = usage !== undefined && usage !== null
1230
1260
  const minute = now.getUTCHours() * 60 + now.getUTCMinutes()
@@ -1233,7 +1263,7 @@ window.__ModuleLoader__.load({
1233
1263
  return h('div', { ref: box, style: { position: 'relative' } }, [
1234
1264
  h('button', {
1235
1265
  key: 'chip', type: 'button',
1236
- className: 'dcm-chip',
1266
+ className: 'dcm-chip' + (displayMode === 'compact' ? ' dcm-chip-compact' : ''),
1237
1267
  onClick: () => setOpen((v) => !v), title: t('chipUnknown'),
1238
1268
  }, [
1239
1269
  h('span', { key: 'dot', className: 'dcm-dot dcm-dot-idle' }),
@@ -1402,7 +1432,7 @@ window.__ModuleLoader__.load({
1402
1432
  return h('div', { ref: box, style: { position: 'relative' } }, [
1403
1433
  h('button', {
1404
1434
  key: 'chip', type: 'button',
1405
- className: 'dcm-chip',
1435
+ className: 'dcm-chip' + (displayMode === 'compact' ? ' dcm-chip-compact' : ''),
1406
1436
  onClick: () => setOpen((v) => !v),
1407
1437
  title: (budgetExceeded
1408
1438
  ? t('budget.exceeded', { limit: money(budgetThreshold * fx, currency) })
@@ -1639,4 +1669,4 @@ window.__ModuleLoader__.load({
1639
1669
  return module.exports
1640
1670
  },
1641
1671
  })
1642
-
1672
+
package/lib/index.js CHANGED
@@ -124,6 +124,7 @@ export function normalizeConfig(raw) {
124
124
  usdRate: getFxRate(currency, u.usdRate, autoFx),
125
125
  displayTimeZone: typeof u.displayTimeZone === 'string' && u.displayTimeZone ? u.displayTimeZone : 'Europe/Moscow',
126
126
  budgetThreshold: Number(u.budgetThreshold) || 0,
127
+ displayMode: (u.displayMode === 'compact' || u.displayMode === 'full') ? u.displayMode : 'auto',
127
128
  useOpenRouter: u.useOpenRouter !== false,
128
129
  refreshHours: Number(u.refreshHours) || 24,
129
130
  deepseekPeakPrices: u.deepseekPeakPrices || {},
@@ -151,6 +152,7 @@ export const Config = z.object({
151
152
  usdRate: z.number().description('Units of `currency` per USD. 1 keeps everything in USD.').default(1).volatile(),
152
153
  displayTimeZone: z.string().description('IANA zone the widget shows tariff hours in.').default('Europe/Moscow').volatile(),
153
154
  budgetThreshold: z.number().description('Optional session budget threshold in USD. 0 disables threshold warnings.').default(0).volatile(),
155
+ displayMode: z.union(['auto', 'full', 'compact']).description('Widget display mode: auto, full, or compact.').default('auto').volatile(),
154
156
  deepseekPeakPrices: z.dict(PriceRow).description('Override the built-in DeepSeek peak rates, by model id.').default({}).volatile(),
155
157
  useOpenRouter: z.boolean().description('Pull rates and discount windows from the public OpenRouter catalog.').default(true).volatile(),
156
158
  refreshHours: z.number().description('How often to refetch the catalog.').default(24).volatile(),
@@ -296,5 +298,5 @@ export function apply(ctx, config) {
296
298
  getCatalog: () => catalog,
297
299
  })
298
300
  }
299
-
300
-
301
+
302
+
package/lib/routes.js CHANGED
@@ -100,6 +100,7 @@ export function registerRoutes(ctx, options) {
100
100
  usdRate: Number(cfg?.usdRate) > 0 ? Number(cfg.usdRate) : 1,
101
101
  displayTimeZone: typeof cfg?.displayTimeZone === 'string' && cfg.displayTimeZone ? cfg.displayTimeZone : 'Europe/Moscow',
102
102
  budgetThreshold: Number(cfg?.budgetThreshold) || 0,
103
+ displayMode: cfg?.displayMode || 'auto',
103
104
  route,
104
105
  source: own.source,
105
106
  matchedId: own.matchedId,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@goodandready/dsh-cost-meter",
3
- "version": "0.8.21",
3
+ "version": "0.8.22",
4
4
  "description": "DeepSeek Harness plugin: a session cost chip in the conversation header - live token usage by bucket, peak/off-peak tariff, and a countdown to the next tariff switch.",
5
5
  "type": "module",
6
6
  "main": "lib/index.js",