opencode-copilot-budget 1.1.0 → 1.2.0

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 (3) hide show
  1. package/README.md +1 -1
  2. package/package.json +1 -1
  3. package/src/index.tsx +29 -30
package/README.md CHANGED
@@ -8,7 +8,7 @@ Shows your GitHub Copilot premium request budget in the [OpenCode](https://openc
8
8
 
9
9
  - Progress bar that turns **red** when you reach 90 % of your budget
10
10
  - Request count and percentage used
11
- - Inline `🔄 Refresh` action next to the first usage line
11
+ - `↻ Refresh` button in the header row, with pointer cursor on hover
12
12
  - Reset date, updated automatically after prompt submit and after every AI response
13
13
  - 5-minute cache to avoid unnecessary API calls
14
14
  - Works with paid and free Copilot plans
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "opencode-copilot-budget",
3
- "version": "1.1.0",
3
+ "version": "1.2.0",
4
4
  "description": "GitHub Copilot premium budget in the OpenCode TUI sidebar",
5
5
  "author": "Bhaskar Melkani",
6
6
  "repository": {
package/src/index.tsx CHANGED
@@ -8,8 +8,8 @@
8
8
  * `github-copilot`.
9
9
  *
10
10
  * Display format:
11
- * Copilot Budget
12
- * ████████░░░░░░░░ 12% Used 🔄 Refresh
11
+ * Copilot Budget ↻ Refresh
12
+ * ████████░░░░░░░░ 12% Used
13
13
  * 117 / 1000 Premium Requests
14
14
  * Resets on 1 May
15
15
  *
@@ -27,6 +27,7 @@
27
27
 
28
28
  import type { TuiPlugin, TuiPluginApi, TuiPluginModule } from "@opencode-ai/plugin/tui"
29
29
  import { createMemo, createResource, createSignal, Match, onCleanup, onMount, Show, Switch } from "solid-js"
30
+ import { RGBA } from "@opentui/core"
30
31
  import { execFile } from "node:child_process"
31
32
  import { promisify } from "node:util"
32
33
 
@@ -220,6 +221,11 @@ function ProgressBar(props: { percent: number }) {
220
221
 
221
222
  function RefreshButton(props: { api: TuiPluginApi; refresh: () => void; disabled: boolean }) {
222
223
  const theme = () => props.api.theme.current
224
+ const color = () => props.disabled ? theme().textMuted : theme().primary
225
+ const bgTint = () => {
226
+ const c = color()
227
+ return RGBA.fromValues(c.r, c.g, c.b, 0.15)
228
+ }
223
229
 
224
230
  return (
225
231
  <box
@@ -227,11 +233,18 @@ function RefreshButton(props: { api: TuiPluginApi; refresh: () => void; disabled
227
233
  if (props.disabled) return
228
234
  props.refresh()
229
235
  }}
230
- paddingLeft={1}
236
+ onMouseOver={() => {
237
+ if (!props.disabled) props.api.renderer.setMousePointer("pointer")
238
+ }}
239
+ onMouseOut={() => props.api.renderer.setMousePointer("default")}
240
+ marginLeft={2}
241
+ flexDirection="row"
231
242
  >
232
- <text fg={props.disabled ? theme().textMuted : theme().primary}>
233
- <b>🔄 Refresh</b>
243
+ <text fg={bgTint()} bg={theme().background}>{"▐"}</text>
244
+ <text fg={color()} bg={bgTint()}>
245
+ <b>{"↻ Refresh"}</b>
234
246
  </text>
247
+ <text fg={bgTint()} bg={theme().background}>{"▌"}</text>
235
248
  </box>
236
249
  )
237
250
  }
@@ -286,7 +299,14 @@ function UsageDetail(props: { api: TuiPluginApi }) {
286
299
 
287
300
  return (
288
301
  <box flexDirection="column" gap={1}>
289
- <text fg={theme().text}><b>Copilot Budget</b></text>
302
+ <box flexDirection="row">
303
+ <text fg={theme().text}><b>Copilot Budget</b></text>
304
+ <RefreshButton
305
+ api={props.api}
306
+ refresh={triggerRefresh}
307
+ disabled={usage.loading || manualRefreshing()}
308
+ />
309
+ </box>
290
310
  <Switch>
291
311
  <Match when={manualRefreshing()}>
292
312
  <text fg={theme().textMuted}>syncing...</text>
@@ -297,24 +317,10 @@ function UsageDetail(props: { api: TuiPluginApi }) {
297
317
  <Show
298
318
  when={!data().unlimited}
299
319
  fallback={
300
- <box flexDirection="row">
301
- <text fg={theme().textMuted}>{`${data().used} used (unlimited)`}</text>
302
- <RefreshButton
303
- api={props.api}
304
- refresh={triggerRefresh}
305
- disabled={usage.loading || manualRefreshing()}
306
- />
307
- </box>
320
+ <text fg={theme().textMuted}>{`${data().used} used (unlimited)`}</text>
308
321
  }
309
322
  >
310
- <box flexDirection="row">
311
- <ProgressBar percent={data().percent} />
312
- <RefreshButton
313
- api={props.api}
314
- refresh={triggerRefresh}
315
- disabled={usage.loading || manualRefreshing()}
316
- />
317
- </box>
323
+ <ProgressBar percent={data().percent} />
318
324
  <text fg={theme().textMuted}>{`${data().used} / ${data().entitlement} Premium Requests`}</text>
319
325
  </Show>
320
326
  <Show when={data().overageCount > 0}>
@@ -330,14 +336,7 @@ function UsageDetail(props: { api: TuiPluginApi }) {
330
336
  <text fg={theme().textMuted}>syncing...</text>
331
337
  </Match>
332
338
  <Match when={true}>
333
- <box flexDirection="row">
334
- <text fg={theme().textMuted}>sync unavailable</text>
335
- <RefreshButton
336
- api={props.api}
337
- refresh={triggerRefresh}
338
- disabled={usage.loading || manualRefreshing()}
339
- />
340
- </box>
339
+ <text fg={theme().textMuted}>sync unavailable</text>
341
340
  </Match>
342
341
  </Switch>
343
342
  </box>