@jgabor/opencode-neuralwatt 0.1.0 → 0.1.1

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.
Files changed (2) hide show
  1. package/package.json +1 -1
  2. package/tui.tsx +51 -37
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "$schema": "https://json.schemastore.org/package.json",
3
3
  "name": "@jgabor/opencode-neuralwatt",
4
- "version": "0.1.0",
4
+ "version": "0.1.1",
5
5
  "type": "module",
6
6
  "description": "OpenCode TUI plugin that shows Neuralwatt account quota, usage, and burn rate in a sidebar widget and panel.",
7
7
  "exports": {
package/tui.tsx CHANGED
@@ -1,7 +1,7 @@
1
1
  /** @jsxImportSource @opentui/solid */
2
2
 
3
3
  import { TextAttributes } from "@opentui/core"
4
- import { createSignal, type JSX } from "solid-js"
4
+ import { createMemo, createSignal, type JSX } from "solid-js"
5
5
  import type { TuiPlugin, TuiPluginModule } from "@opencode-ai/plugin/tui"
6
6
 
7
7
  // ---------------------------------------------------------------------------
@@ -391,22 +391,36 @@ function SidebarView(props: {
391
391
  onOpen: () => void
392
392
  }) {
393
393
  const theme = props.api.theme.current
394
- const q = props.quota()
395
- const err = props.error()
396
394
 
397
- const creditColor: ThemeColor =
398
- q && q.balance.credits_remaining_usd <= 0 ? "error" : "primary"
399
- const creditUsedPct =
400
- q && q.balance.total_credits_usd > 0
401
- ? (q.balance.credits_used_usd / q.balance.total_credits_usd) * 100
395
+ const q = createMemo(() => props.quota())
396
+ const err = createMemo(() => props.error())
397
+
398
+ const creditColor = createMemo<ThemeColor>(() =>
399
+ q() && q()!.balance.credits_remaining_usd <= 0 ? "error" : "primary",
400
+ )
401
+ const creditUsedPct = createMemo(() =>
402
+ q() && q()!.balance.total_credits_usd > 0
403
+ ? (q()!.balance.credits_used_usd / q()!.balance.total_credits_usd) * 100
404
+ : 0,
405
+ )
406
+ const sub = createMemo(() => q()?.subscription ?? null)
407
+ const hasKwh = createMemo(() => {
408
+ const s = sub()
409
+ return Boolean(s && (s.kwh_included ?? 0) > 0)
410
+ })
411
+ const kwhUsedPct = createMemo(() => {
412
+ const s = sub()
413
+ return hasKwh() && s && s.kwh_included! > 0
414
+ ? (s.kwh_used! / s.kwh_included!) * 100
402
415
  : 0
403
- const sub = q?.subscription ?? null
404
- const hasKwh = sub && (sub.kwh_included ?? 0) > 0
405
- const kwhUsedPct =
406
- hasKwh && sub.kwh_included! > 0 ? (sub.kwh_used! / sub.kwh_included!) * 100 : 0
407
- const kwhColor: ThemeColor = hasKwh && sub.in_overage ? "error" : "primary"
408
- const accountingColor: ThemeColor =
409
- q?.balance.accounting_method === "energy" ? "success" : "info"
416
+ })
417
+ const kwhColor = createMemo<ThemeColor>(() => {
418
+ const s = sub()
419
+ return hasKwh() && s && s.in_overage ? "error" : "primary"
420
+ })
421
+ const accountingColor = createMemo<ThemeColor>(() =>
422
+ q()?.balance.accounting_method === "energy" ? "success" : "info",
423
+ )
410
424
 
411
425
  return (
412
426
  <box
@@ -427,29 +441,29 @@ function SidebarView(props: {
427
441
  Neuralwatt
428
442
  </text>
429
443
  </box>
430
- <text fg={q ? theme[accountingColor] : theme.textMuted}>
431
- {q ? q.balance.accounting_method : "loading"}
444
+ <text fg={q() ? theme[accountingColor()] : theme.textMuted}>
445
+ {q() ? q()!.balance.accounting_method : "loading"}
432
446
  </text>
433
447
  </box>
434
448
 
435
- {err ? (
436
- <text fg={theme.error}>{err}</text>
437
- ) : q ? (
449
+ {err() ? (
450
+ <text fg={theme.error}>{err()}</text>
451
+ ) : q() ? (
438
452
  <>
439
453
  <box flexDirection="column" gap={0}>
440
454
  <LegendRow
441
455
  theme={theme}
442
456
  marker="█"
443
- markerColor={creditColor}
457
+ markerColor={creditColor()}
444
458
  label="Credits used"
445
- value={formatCurrency(q.balance.credits_used_usd)}
459
+ value={formatCurrency(q()!.balance.credits_used_usd)}
446
460
  />
447
461
  <LegendRow
448
462
  theme={theme}
449
463
  marker="░"
450
- markerColor={creditColor === "error" ? "error" : "borderSubtle"}
464
+ markerColor={creditColor() === "error" ? "error" : "borderSubtle"}
451
465
  label="Credits remaining"
452
- value={formatCurrency(q.balance.credits_remaining_usd)}
466
+ value={formatCurrency(q()!.balance.credits_remaining_usd)}
453
467
  />
454
468
  <LegendRow
455
469
  theme={theme}
@@ -457,25 +471,25 @@ function SidebarView(props: {
457
471
  markerColor="warning"
458
472
  label="Credits burn rate"
459
473
  value={estimateDuration(
460
- q.balance.credits_remaining_usd,
461
- burnRateCurrentMonth(q),
474
+ q()!.balance.credits_remaining_usd,
475
+ burnRateCurrentMonth(q()!),
462
476
  )}
463
477
  />
464
478
  </box>
465
479
 
466
480
  <SidebarUsageBlock
467
481
  theme={theme}
468
- creditUsedPct={creditUsedPct}
469
- creditColor={creditColor}
470
- hasKwh={Boolean(hasKwh)}
471
- sub={sub!}
472
- kwhUsedPct={kwhUsedPct}
473
- kwhColor={kwhColor}
474
- kwhBurnRate={sub ? estimateDuration(sub.kwh_remaining ?? 0, burnRateKwh(sub, q.snapshot_at)) : "—"}
475
- monthCost={q.usage.current_month.cost_usd}
476
- monthKwh={q.usage.current_month.energy_kwh}
477
- lifetimeCost={q.usage.lifetime.cost_usd}
478
- lifetimeKwh={q.usage.lifetime.energy_kwh}
482
+ creditUsedPct={creditUsedPct()}
483
+ creditColor={creditColor()}
484
+ hasKwh={hasKwh()}
485
+ sub={sub()!}
486
+ kwhUsedPct={kwhUsedPct()}
487
+ kwhColor={kwhColor()}
488
+ kwhBurnRate={sub() ? estimateDuration(sub()!.kwh_remaining ?? 0, burnRateKwh(sub()!, q()!.snapshot_at)) : "—"}
489
+ monthCost={q()!.usage.current_month.cost_usd}
490
+ monthKwh={q()!.usage.current_month.energy_kwh}
491
+ lifetimeCost={q()!.usage.lifetime.cost_usd}
492
+ lifetimeKwh={q()!.usage.lifetime.energy_kwh}
479
493
  />
480
494
  </>
481
495
  ) : (