@goodandready/dsh-cost-meter 0.8.22 → 0.8.24

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
@@ -1184,7 +1184,6 @@ window.__ModuleLoader__.load({
1184
1184
  const useProjection = props.useProjection
1185
1185
  const usage = useProjection ? useProjection('tokenUsage') : undefined
1186
1186
  const byModel = useProjection ? useProjection('costByModel') : undefined
1187
- const turns = (byModel?.turns && byModel.turns.length > 0) ? byModel.turns : (state?.turns || [])
1188
1187
  const [state, setState] = React.useState(null)
1189
1188
  const [open, setOpen] = React.useState(false)
1190
1189
  const [now, setNow] = React.useState(() => new Date())
@@ -1250,6 +1249,7 @@ window.__ModuleLoader__.load({
1250
1249
 
1251
1250
  if (!state) return null
1252
1251
 
1252
+ const turns = (byModel?.turns && byModel.turns.length > 0) ? byModel.turns : (state.turns || [])
1253
1253
  const stored = (settingsSnap && settingsSnap.value) || {}
1254
1254
  const currency = stored.currency !== undefined ? String(stored.currency) : (state.currency || '$')
1255
1255
  const fx = stored.usdRate !== undefined && !isNaN(Number(stored.usdRate)) ? Number(stored.usdRate) : (Number(state.usdRate) || 1)
@@ -1472,6 +1472,31 @@ window.__ModuleLoader__.load({
1472
1472
  budgetExceeded ? h('div', { key: 'budget-warn', className: 'dcm-alert dcm-alert-err', style: { marginTop: 6, padding: '6px 10px', fontSize: 11 } },
1473
1473
  t('budget.exceeded', { limit: money(budgetThreshold * fx, currency) })) : null,
1474
1474
 
1475
+ renderSparkline(turns, {
1476
+ h,
1477
+ currency,
1478
+ fx,
1479
+ activeRate: active,
1480
+ t,
1481
+ }),
1482
+
1483
+ (() => {
1484
+ const proj = calculateBurnRateAndProjection(turns, total / fx)
1485
+ const burnRate = proj.burnRatePerHourUsd * fx
1486
+ const projectedTotal = proj.projectedCostUsd * fx
1487
+ if (burnRate <= 0) return null
1488
+ return h('div', { key: 'proj-box', className: 'dcm-proj-box' }, [
1489
+ h('span', { key: 'burn', className: 'dcm-proj-item' }, [
1490
+ h('span', null, t('projection.burn_rate') + ' '),
1491
+ h('span', { className: 'dcm-proj-val' }, money(burnRate, currency) + t('projection.per_hour')),
1492
+ ]),
1493
+ h('span', { key: 'proj', className: 'dcm-proj-item' }, [
1494
+ h('span', null, t('projection.projected') + ' '),
1495
+ h('span', { className: 'dcm-proj-val' }, '≈ ' + money(projectedTotal, currency)),
1496
+ ]),
1497
+ ])
1498
+ })(),
1499
+
1475
1500
  h('hr', { key: 'hr1', className: 'dcm-hr' }),
1476
1501
 
1477
1502
  h('div', { key: 'rates', className: flat ? 'dcm-panel-grid-flat' : 'dcm-panel-grid' }, [
package/lib/index.js CHANGED
@@ -68,8 +68,11 @@ export function isTrustedCaller(request, ctx = null) {
68
68
  }
69
69
  }
70
70
  const remote = request.socket?.remoteAddress || request.connection?.remoteAddress
71
+ const loopback = isLoopback(remote)
72
+ if (ctx && !conn && !loopback) return false
73
+
71
74
  const site = request.headers?.['sec-fetch-site']
72
- if (site === 'cross-site') return false
75
+ if (site === 'cross-site' || site === 'same-site') return false
73
76
 
74
77
  const host = request.headers?.['host']
75
78
  const origin = request.headers?.['origin']
@@ -78,11 +81,11 @@ export function isTrustedCaller(request, ctx = null) {
78
81
  const url = new URL(origin)
79
82
  if (url.protocol === 'http:' || url.protocol === 'https:') {
80
83
  if (host && url.host.toLowerCase() === host.toLowerCase()) return true
81
- if (isLoopback(url.hostname) && isLoopback(remote)) return true
84
+ if (isLoopback(url.hostname) && loopback) return true
82
85
  return false
83
86
  }
84
87
  // Non-http/https origin (e.g. dsh-app://app in DSH Desktop)
85
- if (isLoopback(remote)) return true
88
+ if (loopback) return true
86
89
  return false
87
90
  } catch {
88
91
  return false
@@ -95,20 +98,18 @@ export function isTrustedCaller(request, ctx = null) {
95
98
  const url = new URL(referer)
96
99
  if (url.protocol === 'http:' || url.protocol === 'https:') {
97
100
  if (host && url.host.toLowerCase() === host.toLowerCase()) return true
98
- if (isLoopback(url.hostname) && isLoopback(remote)) return true
101
+ if (isLoopback(url.hostname) && loopback) return true
99
102
  return false
100
103
  }
101
104
  // Non-http/https referer (e.g. dsh-app://app/ in DSH Desktop)
102
- if (isLoopback(remote)) return true
105
+ if (loopback) return true
103
106
  return false
104
107
  } catch {
105
108
  return false
106
109
  }
107
110
  }
108
111
 
109
- if (site === 'same-site') return false
110
- if (site === 'same-origin') return true
111
- if (isLoopback(remote)) return true
112
+ if (loopback) return true
112
113
 
113
114
  return false
114
115
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@goodandready/dsh-cost-meter",
3
- "version": "0.8.22",
3
+ "version": "0.8.24",
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",