@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.
@@ -139,13 +139,36 @@ function providerRows(usage, showCost) {
139
139
  const providers = Object.values(usage.providers).sort((a, b) => b.total - a.total);
140
140
  if (providers.length === 0)
141
141
  return ['no provider activity'];
142
- return providers.map((provider) => {
142
+ const prepared = providers.map((provider) => {
143
143
  const cache = getProviderCacheCoverageMetrics(provider).cachedRatio;
144
- const base = `${quotaDisplayLabel({ providerID: provider.providerID, label: provider.providerID, status: 'ok', checkedAt: 0 }).padEnd(10, ' ')} ${shortNumber(provider.assistantMessages).padStart(4, ' ')} req ${shortNumber(provider.total).padStart(7, ' ')} tok ${(cache !== undefined ? formatPercent(cache, 0) : '-').padStart(4, ' ')} cache`;
145
- const apiCost = canonicalProviderID(provider.providerID) === 'github-copilot'
146
- ? '-'
147
- : formatApiCost(provider.apiCost);
148
- return showCost ? `${base} ${apiCost.padStart(7, ' ')}` : base;
144
+ return {
145
+ label: quotaDisplayLabel({
146
+ providerID: provider.providerID,
147
+ label: provider.providerID,
148
+ status: 'ok',
149
+ checkedAt: 0,
150
+ }),
151
+ requests: shortNumber(provider.assistantMessages),
152
+ tokens: shortNumber(provider.total),
153
+ cached: cache !== undefined ? formatPercent(cache, 0) : '-',
154
+ cost: canonicalProviderID(provider.providerID) === 'github-copilot'
155
+ ? '-'
156
+ : formatApiCost(provider.apiCost),
157
+ };
158
+ });
159
+ const labelWidth = Math.max(...prepared.map((row) => row.label.length));
160
+ const requestWidth = Math.max(...prepared.map((row) => row.requests.length));
161
+ const tokenWidth = Math.max(...prepared.map((row) => row.tokens.length));
162
+ const cachedWidth = Math.max(...prepared.map((row) => row.cached.length));
163
+ const costWidth = Math.max(...prepared.map((row) => row.cost.length));
164
+ return prepared.map((row) => {
165
+ const base = [
166
+ padRight(row.label, labelWidth),
167
+ `${row.requests.padStart(requestWidth)} req`,
168
+ `${row.tokens.padStart(tokenWidth)} tok`,
169
+ `${row.cached.padStart(cachedWidth)} cached`,
170
+ ].join(' ');
171
+ return showCost ? `${base} ${row.cost.padStart(costWidth)}` : base;
149
172
  });
150
173
  }
151
174
  function cliApiCostSummary(usage) {
@@ -156,18 +179,30 @@ function cliApiCostSummary(usage) {
156
179
  return hasNonCopilot ? formatApiCost(usage.apiCost) : '-';
157
180
  }
158
181
  function totalsRows(input) {
159
- const left = [`Requests ${input.requests}`, `Tokens ${input.tokens}`];
160
- const right = [
161
- ...(input.cost ? [`API Cost ${input.cost}`] : []),
162
- ...(input.cache ? [`Cache ${input.cache}`] : []),
163
- ];
164
- const metaLeft = input.periods ? `Periods ${input.periods}` : undefined;
165
- const metaRight = input.current ? `Current ${input.current}` : undefined;
166
- const row1 = [left[0], left[1], ...right].join(' ');
167
- const row2 = [metaLeft, metaRight].filter(Boolean).join(' ');
168
- return [row1, ...(row2 ? [row2] : [])];
182
+ const leftLabelWidth = Math.max('Sessions'.length, 'API Cost'.length);
183
+ const leftValueWidth = Math.max(input.sessions.length, input.tokens.length, input.cost?.length ?? 0);
184
+ const rightLabelWidth = 'Requests'.length;
185
+ const rightValueWidth = Math.max(input.requests.length, input.cached?.length ?? 0);
186
+ const leftCell = (label, value) => `${padRight(label, leftLabelWidth)} ${value.padEnd(leftValueWidth, ' ')}`;
187
+ const rightCell = (label, value) => `${padRight(label, rightLabelWidth)} ${value.padEnd(rightValueWidth, ' ')}`;
188
+ const row1 = [
189
+ leftCell('Sessions', input.sessions),
190
+ rightCell('Requests', input.requests),
191
+ ]
192
+ .join(' ')
193
+ .trimEnd();
194
+ const row2 = [
195
+ leftCell('Tokens', input.tokens),
196
+ ...(input.cached ? [rightCell('Cached', input.cached)] : []),
197
+ ]
198
+ .join(' ')
199
+ .trimEnd();
200
+ const row3 = input.cost
201
+ ? leftCell('API Cost', input.cost).trimEnd()
202
+ : undefined;
203
+ return [row1, row2, ...(row3 ? [row3] : [])];
169
204
  }
170
- function trendBar(value, maxValue, width = 20) {
205
+ function trendBar(value, maxValue, width = 16) {
171
206
  if (!Number.isFinite(value) || value <= 0 || maxValue <= 0) {
172
207
  return '░'.repeat(width);
173
208
  }
@@ -178,11 +213,10 @@ function trendMetricBlock(input) {
178
213
  const visibleRows = input.rows.slice(-Math.min(8, input.rows.length));
179
214
  const values = visibleRows.map(input.pick);
180
215
  const maxValue = Math.max(...values, 0);
181
- const currentValue = input.current ? input.pick(input.current) : 0;
182
216
  const displayLabels = visibleRows.map((row) => `${row.range.shortLabel}${row.range.isCurrent ? '*' : ''}`);
183
- const labelWidth = Math.max(8, Math.min(28, Math.max(...displayLabels.map((label) => label.length), 8)));
217
+ const labelWidth = Math.max(6, Math.min(20, Math.max(...displayLabels.map((label) => label.length), 6)));
184
218
  return [
185
- `${input.label} ${input.format(currentValue)}`,
219
+ input.label,
186
220
  ...visibleRows.map((row, index) => {
187
221
  const value = input.pick(row);
188
222
  const tag = padRight(displayLabels[index], labelWidth);
@@ -200,13 +234,12 @@ export function renderCliDashboard(input) {
200
234
  '',
201
235
  'TOTALS',
202
236
  ...totalsRows({
237
+ sessions: `${input.usage.sessionCount}`,
203
238
  requests: shortNumber(input.usage.assistantMessages),
204
239
  tokens: shortNumber(input.usage.total),
205
240
  ...(showCost ? { cost: cliApiCostSummary(input.usage) } : {}),
206
- cache: cache !== undefined ? formatPercent(cache, 1) : '-',
207
- periods: `${input.usage.sessionCount}`,
241
+ cached: cache !== undefined ? formatPercent(cache, 1) : '-',
208
242
  }),
209
- `Input ${shortNumber(input.usage.input)} Output ${shortNumber(input.usage.output)}`,
210
243
  '',
211
244
  'PROVIDERS',
212
245
  ...providerRows(input.usage, showCost),
@@ -217,10 +250,16 @@ export function renderCliHistoryDashboard(input) {
217
250
  const showCost = input.showCost !== false;
218
251
  const rows = input.result.rows;
219
252
  const current = [...rows].reverse().find((row) => row.range.isCurrent) || rows.at(-1);
220
- const currentIndex = current ? rows.indexOf(current) : -1;
221
- const previous = currentIndex > 0 ? rows[currentIndex - 1] : undefined;
222
253
  const cache = getCacheCoverageMetrics(input.result.total).cachedRatio;
223
254
  const trendBlocks = [
255
+ ...trendMetricBlock({
256
+ label: 'Sessions',
257
+ rows,
258
+ current,
259
+ pick: (row) => row.usage.sessionCount,
260
+ format: (value) => shortNumber(value),
261
+ }),
262
+ '',
224
263
  ...trendMetricBlock({
225
264
  label: 'Requests',
226
265
  rows,
@@ -238,7 +277,7 @@ export function renderCliHistoryDashboard(input) {
238
277
  }),
239
278
  '',
240
279
  ...trendMetricBlock({
241
- label: 'Cache',
280
+ label: 'Cached',
242
281
  rows,
243
282
  current,
244
283
  pick: (row) => getCacheCoverageMetrics(row.usage).cachedRatio ?? 0,
@@ -263,12 +302,11 @@ export function renderCliHistoryDashboard(input) {
263
302
  '',
264
303
  'TOTALS',
265
304
  ...totalsRows({
305
+ sessions: `${input.result.total.sessionCount}`,
266
306
  requests: shortNumber(input.result.total.assistantMessages),
267
307
  tokens: shortNumber(input.result.total.total),
268
308
  ...(showCost ? { cost: cliApiCostSummary(input.result.total) } : {}),
269
- cache: cache !== undefined ? formatPercent(cache, 1) : '-',
270
- periods: `${rows.length}`,
271
- current: current?.range.shortLabel || '-',
309
+ cached: cache !== undefined ? formatPercent(cache, 1) : '-',
272
310
  }),
273
311
  '',
274
312
  'PROVIDERS',
package/dist/tui.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  /** @jsxImportSource @opentui/solid */
2
- import type { TuiPluginModule } from "@opencode-ai/plugin/tui";
2
+ import type { TuiPluginModule } from '@opencode-ai/plugin/tui';
3
3
  declare const plugin: TuiPluginModule & {
4
4
  id: string;
5
5
  };