opencode-go-usage-tui 1.3.0 → 1.3.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.
- package/README.md +3 -2
- package/README_EN.md +3 -2
- package/dist/tui.js +13 -4
- package/package.json +1 -1
- package/src/index.tsx +15 -3
package/README.md
CHANGED
|
@@ -120,14 +120,15 @@ Cookie 有效期约 1 年,过期后重新获取。
|
|
|
120
120
|
- **`/go-lang`**:切换 中文 / English
|
|
121
121
|
- 用量超过阈值(默认 80%,可用 `OPENCODE_GO_WARN_THRESHOLD` 调整)显示为红色
|
|
122
122
|
- 点击面板标题可折叠/展开
|
|
123
|
-
- 面板标题显示当前插件版本号(如 `v1.3.
|
|
123
|
+
- 面板标题显示当前插件版本号(如 `v1.3.1`)
|
|
124
124
|
|
|
125
125
|
## 模型请求限额面板
|
|
126
126
|
|
|
127
|
-
- 独立面板显示各模型的 5小时/每周/每月
|
|
127
|
+
- 独立面板显示各模型的 5小时/每周/每月 请求数上限,表格风格两端对齐(值与面板右缘对齐)
|
|
128
128
|
- 从 opencode.ai/docs/go 实时抓取公开数据(无需登录)
|
|
129
129
|
- 默认每 30 分钟自动刷新(可用 `/go-settings` 或 `pricing_interval_sec` 调整)
|
|
130
130
|
- 每次刷新自动对比上次数据,变化时 toast 提醒,历史保留最近 10 次到 `go-pricing-data.json`
|
|
131
|
+
- 额度达到 100%(`rate-limited` 状态)时仍正常显示用量与重置时间,不会出现"查询失败"
|
|
131
132
|
|
|
132
133
|
## 语言
|
|
133
134
|
|
package/README_EN.md
CHANGED
|
@@ -120,14 +120,15 @@ The cookie is valid for about 1 year; get a new one after it expires.
|
|
|
120
120
|
- **`/go-lang`**: switch between 中文 / English
|
|
121
121
|
- Usage above the threshold (default 80%, adjustable via `OPENCODE_GO_WARN_THRESHOLD`) is shown in red
|
|
122
122
|
- Click the panel title to collapse/expand
|
|
123
|
-
- The panel title shows the current plugin version (e.g. `v1.3.
|
|
123
|
+
- The panel title shows the current plugin version (e.g. `v1.3.1`)
|
|
124
124
|
|
|
125
125
|
## Model request limits panel
|
|
126
126
|
|
|
127
|
-
- Independent panel showing each model's 5h / weekly / monthly request caps, table style with
|
|
127
|
+
- Independent panel showing each model's 5h / weekly / monthly request caps, table style with values right-aligned to the panel edge
|
|
128
128
|
- Scraped live from opencode.ai/docs/go (public data, no login)
|
|
129
129
|
- Auto-refreshes every 30 minutes by default (adjustable via `/go-settings` or `pricing_interval_sec`)
|
|
130
130
|
- Each refresh diffs against the last snapshot; toast on change; last 10 changes kept in `go-pricing-data.json`
|
|
131
|
+
- When quota hits 100% (`rate-limited` status), usage and reset time still display normally - no "query failed" error
|
|
131
132
|
|
|
132
133
|
## Language
|
|
133
134
|
|
package/dist/tui.js
CHANGED
|
@@ -460,7 +460,7 @@ function updatePricingStore(newData) {
|
|
|
460
460
|
}
|
|
461
461
|
|
|
462
462
|
// src/index.tsx
|
|
463
|
-
var VERSION = "1.3.
|
|
463
|
+
var VERSION = "1.3.1";
|
|
464
464
|
var CHECK_INTERVAL = Number(process?.env?.OPENCODE_GO_CHECK_INTERVAL ?? 6e4);
|
|
465
465
|
var WARN_THRESHOLD = Number(process?.env?.OPENCODE_GO_WARN_THRESHOLD ?? 0.8);
|
|
466
466
|
var CONFIG_DIR = process?.env?.OPENCODE_CONFIG_DIR || (process?.env?.USERPROFILE ? `${process.env.USERPROFILE}\\.config\\opencode` : "") || process?.env?.HOME + "/.config/opencode";
|
|
@@ -692,7 +692,7 @@ async function fetchUsage(workspaceId, authCookie, signal) {
|
|
|
692
692
|
};
|
|
693
693
|
}
|
|
694
694
|
const extract = (key) => {
|
|
695
|
-
const m = text.match(new RegExp(`${key}:[^}]*?\\{status:"
|
|
695
|
+
const m = text.match(new RegExp(`${key}:[^}]*?\\{status:"[^"]*",resetInSec:(\\d+),usagePercent:(\\d+)\\}`));
|
|
696
696
|
if (!m) return null;
|
|
697
697
|
return {
|
|
698
698
|
resetInSec: Number(m[1]),
|
|
@@ -1080,6 +1080,11 @@ function PricePanel(props) {
|
|
|
1080
1080
|
});
|
|
1081
1081
|
let boxEl;
|
|
1082
1082
|
let priceController = null;
|
|
1083
|
+
createEffect(() => {
|
|
1084
|
+
if (boxEl && typeof boxEl.width === "number" && boxEl.width > 0) {
|
|
1085
|
+
setPanelWidth(Math.max(20, boxEl.width));
|
|
1086
|
+
}
|
|
1087
|
+
});
|
|
1083
1088
|
async function refreshPricing() {
|
|
1084
1089
|
if (priceLoading()) return;
|
|
1085
1090
|
setPriceLoading(true);
|
|
@@ -1137,7 +1142,8 @@ function PricePanel(props) {
|
|
|
1137
1142
|
return out + "\u2026";
|
|
1138
1143
|
}
|
|
1139
1144
|
function justify(label, value) {
|
|
1140
|
-
const
|
|
1145
|
+
const outer = boxEl && typeof boxEl.width === "number" && boxEl.width > 0 ? boxEl.width : panelWidth();
|
|
1146
|
+
const gauge = Math.max(10, outer - 4);
|
|
1141
1147
|
const used = visualWidth(label) + visualWidth(value);
|
|
1142
1148
|
const gap = Math.max(1, gauge - used);
|
|
1143
1149
|
return label + " ".repeat(gap) + value;
|
|
@@ -1170,7 +1176,10 @@ function PricePanel(props) {
|
|
|
1170
1176
|
setPal(p);
|
|
1171
1177
|
});
|
|
1172
1178
|
const colors = () => pal();
|
|
1173
|
-
const sep = () =>
|
|
1179
|
+
const sep = () => {
|
|
1180
|
+
const outer = boxEl && typeof boxEl.width === "number" && boxEl.width > 0 ? boxEl.width : panelWidth();
|
|
1181
|
+
return "\u2500".repeat(Math.max(1, outer - 4));
|
|
1182
|
+
};
|
|
1174
1183
|
setTimeout(() => {
|
|
1175
1184
|
const store = loadPricingStore();
|
|
1176
1185
|
if (store.current.models.length > 0) {
|
package/package.json
CHANGED
package/src/index.tsx
CHANGED
|
@@ -213,7 +213,7 @@ async function fetchUsage(workspaceId: string, authCookie: string, signal?: Abor
|
|
|
213
213
|
return { error: "cookie_expired" } as Usage
|
|
214
214
|
}
|
|
215
215
|
const extract = (key: string): { resetInSec: number; usagePercent: number } | null => {
|
|
216
|
-
const m = text.match(new RegExp(`${key}:[^}]*?\\{status:"
|
|
216
|
+
const m = text.match(new RegExp(`${key}:[^}]*?\\{status:"[^"]*",resetInSec:(\\d+),usagePercent:(\\d+)\\}`))
|
|
217
217
|
if (!m) return null
|
|
218
218
|
return { resetInSec: Number(m[1]), usagePercent: Number(m[2]) }
|
|
219
219
|
}
|
|
@@ -450,6 +450,13 @@ function PricePanel(props: { theme: TuiThemeCurrent; api: TuiPluginApi }): JSX.E
|
|
|
450
450
|
let boxEl: any
|
|
451
451
|
let priceController: AbortController | null = null
|
|
452
452
|
|
|
453
|
+
// 强制同步 panelWidth 与 box 真实宽度(visual-cache 模式,避免首次不触发 onSizeChange)
|
|
454
|
+
createEffect(() => {
|
|
455
|
+
if (boxEl && typeof boxEl.width === "number" && boxEl.width > 0) {
|
|
456
|
+
setPanelWidth(Math.max(20, boxEl.width))
|
|
457
|
+
}
|
|
458
|
+
})
|
|
459
|
+
|
|
453
460
|
async function refreshPricing() {
|
|
454
461
|
if (priceLoading()) return
|
|
455
462
|
setPriceLoading(true)
|
|
@@ -511,8 +518,10 @@ function PricePanel(props: { theme: TuiThemeCurrent; api: TuiPluginApi }): JSX.E
|
|
|
511
518
|
}
|
|
512
519
|
|
|
513
520
|
// visual-cache 风格:左标签 + 自动填充 + 右值
|
|
521
|
+
// 直接读取 boxEl 实时宽度(避免 panelWidth 信号滞后)
|
|
514
522
|
function justify(label: string, value: string): string {
|
|
515
|
-
const
|
|
523
|
+
const outer = boxEl && typeof boxEl.width === "number" && boxEl.width > 0 ? boxEl.width : panelWidth()
|
|
524
|
+
const gauge = Math.max(10, outer - 4)
|
|
516
525
|
const used = visualWidth(label) + visualWidth(value)
|
|
517
526
|
const gap = Math.max(1, gauge - used)
|
|
518
527
|
return label + " ".repeat(gap) + value
|
|
@@ -540,7 +549,10 @@ function PricePanel(props: { theme: TuiThemeCurrent; api: TuiPluginApi }): JSX.E
|
|
|
540
549
|
})
|
|
541
550
|
const colors = () => pal()
|
|
542
551
|
|
|
543
|
-
const sep = () =>
|
|
552
|
+
const sep = () => {
|
|
553
|
+
const outer = boxEl && typeof boxEl.width === "number" && boxEl.width > 0 ? boxEl.width : panelWidth()
|
|
554
|
+
return "\u2500".repeat(Math.max(1, outer - 4))
|
|
555
|
+
}
|
|
544
556
|
|
|
545
557
|
setTimeout(() => {
|
|
546
558
|
const store = loadPricingStore()
|