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.
- package/README.md +1 -1
- package/package.json +1 -1
- 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
|
-
-
|
|
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
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
|
|
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
|
-
|
|
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={
|
|
233
|
-
|
|
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
|
-
<
|
|
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
|
-
<
|
|
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
|
-
<
|
|
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
|
-
<
|
|
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>
|