@leo000001/opencode-quota-sidebar 4.0.15 → 4.1.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.
@@ -1,9 +1,9 @@
1
- import type { QuotaSidebarConfig, QuotaSnapshot, SidebarPanelState } from "./types.js";
2
- import type { UsageSummary } from "./usage.js";
3
- export type SidebarQuotaTone = "success" | "warning" | "error" | "muted";
1
+ import type { QuotaSidebarConfig, QuotaSnapshot, SidebarPanelState } from './types.js';
2
+ import type { UsageSummary } from './usage.js';
3
+ export type SidebarQuotaTone = 'success' | 'warning' | 'error' | 'muted';
4
4
  export type SidebarQuotaGroup = {
5
5
  providerID: string;
6
- status: QuotaSnapshot["status"];
6
+ status: QuotaSnapshot['status'];
7
7
  tone: SidebarQuotaTone;
8
8
  shortLabel: string;
9
9
  detail: string;
@@ -1,17 +1,17 @@
1
- import { fitLine, renderSidebarQuotaLineGroups } from "./format.js";
2
- import { collapseQuotaSnapshots } from "./quota_render.js";
3
- import { isSupportedQuotaSnapshot, isSupportedQuotaTitleLabel, } from "./supported_quota.js";
1
+ import { fitLine, renderSidebarQuotaLineGroups } from './format.js';
2
+ import { collapseQuotaSnapshots } from './quota_render.js';
3
+ import { isSupportedQuotaSnapshot, isSupportedQuotaTitleLabel, } from './supported_quota.js';
4
4
  const VISIBLE_QUOTA_STATUSES = new Set([
5
- "ok",
6
- "error",
7
- "unsupported",
8
- "unavailable",
5
+ 'ok',
6
+ 'error',
7
+ 'unsupported',
8
+ 'unavailable',
9
9
  ]);
10
10
  function parseQuotaLineParts(lines) {
11
- const firstLine = lines[0]?.trimStart() || "";
11
+ const firstLine = lines[0]?.trimStart() || '';
12
12
  const match = /^(\S+)(?:\s+(.*))?$/.exec(firstLine);
13
- const shortLabel = match?.[1] || firstLine || "Quota";
14
- const detail = match?.[2] || "";
13
+ const shortLabel = match?.[1] || firstLine || 'Quota';
14
+ const detail = match?.[2] || '';
15
15
  const continuationLines = lines
16
16
  .slice(1)
17
17
  .map((line) => line.trimEnd())
@@ -37,56 +37,56 @@ function quotaPercents(quota) {
37
37
  return values;
38
38
  }
39
39
  function quotaTone(quota) {
40
- if (quota.status === "error")
41
- return "error";
42
- if (quota.status === "unsupported" || quota.status === "unavailable") {
43
- return "muted";
40
+ if (quota.status === 'error')
41
+ return 'error';
42
+ if (quota.status === 'unsupported' || quota.status === 'unavailable') {
43
+ return 'muted';
44
44
  }
45
- if (quota.status !== "ok")
46
- return "muted";
45
+ if (quota.status !== 'ok')
46
+ return 'muted';
47
47
  const percents = quotaPercents(quota);
48
48
  if (percents.length === 0) {
49
49
  if (quota.balance && Number.isFinite(quota.balance.amount)) {
50
50
  if (quota.balance.amount < 0)
51
- return "error";
52
- return "muted";
51
+ return 'error';
52
+ return 'muted';
53
53
  }
54
- return "muted";
54
+ return 'muted';
55
55
  }
56
56
  const remaining = Math.min(...percents);
57
57
  if (remaining <= 5)
58
- return "error";
58
+ return 'error';
59
59
  if (remaining <= 20)
60
- return "warning";
61
- return "success";
60
+ return 'warning';
61
+ return 'success';
62
62
  }
63
63
  function fallbackQuotaTone(detail) {
64
64
  const safe = detail.trim();
65
65
  if (!safe)
66
- return "muted";
66
+ return 'muted';
67
67
  if (/\b(?:unsupported|unavailable)\b/i.test(safe))
68
- return "muted";
68
+ return 'muted';
69
69
  if (/\berror\b/i.test(safe) || /^\?$/.test(safe))
70
- return "error";
70
+ return 'error';
71
71
  if (/\bB-/.test(safe))
72
- return "error";
72
+ return 'error';
73
73
  const percents = [
74
74
  ...safe.matchAll(/\b(?:\d+[hdw]|[DWM]|S7d|O7d|OA7d|Co7d|Sk5h|SkW)(\d{1,3})\b/gi),
75
75
  ]
76
76
  .map((match) => Number(match[1]))
77
77
  .filter((value) => Number.isFinite(value));
78
78
  if (percents.length === 0)
79
- return "muted";
79
+ return 'muted';
80
80
  const remaining = Math.min(...percents);
81
81
  if (remaining <= 5)
82
- return "error";
82
+ return 'error';
83
83
  if (remaining <= 20)
84
- return "warning";
85
- return "success";
84
+ return 'warning';
85
+ return 'success';
86
86
  }
87
87
  export function renderSidebarQuotaGroups(quotas, config) {
88
88
  const visibleQuotaCount = collapseQuotaSnapshots(quotas).filter((quota) => VISIBLE_QUOTA_STATUSES.has(quota.status)).length;
89
- const renderConfig = visibleQuotaCount > 1
89
+ const renderConfig = visibleQuotaCount > 0
90
90
  ? {
91
91
  ...config,
92
92
  sidebar: {
@@ -139,8 +139,8 @@ export function mergeLiveAndPersistedPanelUsage(liveUsage, persistedUsage) {
139
139
  }
140
140
  export function fallbackQuotaGroupsFromTitle(title, width) {
141
141
  // Legacy compatibility: old sessions may only have compact title fragments.
142
- const parts = (title || "")
143
- .split(" | ")
142
+ const parts = (title || '')
143
+ .split(' | ')
144
144
  .map((part) => part.trim())
145
145
  .filter(Boolean);
146
146
  const quotaParts = parts
@@ -148,7 +148,7 @@ export function fallbackQuotaGroupsFromTitle(title, width) {
148
148
  .filter((part) => !/^Cd\d/.test(part) && !/^API\b/.test(part) && !/^Est\b/.test(part));
149
149
  if (quotaParts.length === 0)
150
150
  return [];
151
- const contentWidth = quotaParts.length > 1 ? Math.max(1, width - 2) : width;
151
+ const contentWidth = Math.max(1, width - 2);
152
152
  const groups = [];
153
153
  for (const [index, part] of quotaParts.entries()) {
154
154
  const line = fitLine(part, contentWidth);
@@ -157,7 +157,7 @@ export function fallbackQuotaGroupsFromTitle(title, width) {
157
157
  continue;
158
158
  groups.push({
159
159
  providerID: `fallback:${index}`,
160
- status: "ok",
160
+ status: 'ok',
161
161
  tone: fallbackQuotaTone(parsed.detail),
162
162
  shortLabel: parsed.shortLabel,
163
163
  detail: parsed.detail,
@@ -167,7 +167,7 @@ export function fallbackQuotaGroupsFromTitle(title, width) {
167
167
  return groups;
168
168
  }
169
169
  export function quotaGroupsUseBullets(groups) {
170
- return groups.length > 1;
170
+ return groups.length > 0;
171
171
  }
172
172
  export function quotaGroupsAreCollapsible(groups) {
173
173
  return groups.length > 2;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@leo000001/opencode-quota-sidebar",
3
- "version": "4.0.15",
3
+ "version": "4.1.0",
4
4
  "description": "OpenCode plugin that shows quota and token usage in TUI sidebar panels and compact session titles",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",