@timo972/cc-router 0.13.0-rc.5 → 0.13.0-rc.6

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.
@@ -225,21 +225,29 @@ export function UsageDashboard({ load, initialQuery = { period: "month" }, onExi
225
225
  if (showBoth || !gridFocus) {
226
226
  gap("gap-chart");
227
227
  // Few buckets (a week has seven) get wide columns so the bars fill the row and every label has room.
228
- const plotWidth = Math.max(2, Math.min(width, gridWidth) - 8);
229
- const columnWidth = Math.max(2, Math.min(MAX_COLUMN_WIDTH, Math.floor(plotWidth / Math.max(1, report.buckets.length))));
230
- const chart = chartColumns(report.buckets.map(b => ({
228
+ const buckets = report.buckets.map(b => ({
231
229
  label: query.period === "day" ? b.start.slice(11, 13) : query.period === "year" ? b.start.slice(5, 7) : b.start.slice(8, 10),
232
230
  series: Object.values(b.series).map(s => ({ ...s, tokens: measure(s.tokens, s.usd) })),
233
- })), Math.max(1, Math.floor(plotWidth / columnWidth)), chartHeight, models, models ? Math.max(2, Math.floor(width / 24)) : 3);
231
+ }));
232
+ // The y-axis gutter fits its widest label: a spend peak like $945.61 is seven characters, and a
233
+ // fixed six-character gutter pushed that row one column off the axis line.
234
+ const layout = (gutter) => {
235
+ const plotWidth = Math.max(2, Math.min(width, gridWidth) - gutter - 2);
236
+ const columnWidth = Math.max(2, Math.min(MAX_COLUMN_WIDTH, Math.floor(plotWidth / Math.max(1, report.buckets.length))));
237
+ const chart = chartColumns(buckets, Math.max(1, Math.floor(plotWidth / columnWidth)), chartHeight, models, models ? Math.max(2, Math.floor(width / 24)) : 3);
238
+ return { columnWidth, chart, gutter: Math.max(gutter, formatMeasure(chart.max).length) };
239
+ };
240
+ const first = layout(6);
241
+ const { columnWidth, chart, gutter } = first.gutter > 6 ? layout(first.gutter) : first;
234
242
  const colors = new Map(chart.legend.map((s, i) => [s.key, legendColor(s, i, models)]));
235
243
  const glyphs = new Map(chart.legend.map((s, i) => [s.key, legendGlyph(s, i, models)]));
236
244
  // Wide columns keep one blank cell between bars; two-cell columns stay flush as before.
237
245
  const fill = columnWidth >= 3 ? columnWidth - 1 : columnWidth;
238
246
  for (let row = 0; row < chartHeight; row++)
239
- lines.push(line(_jsxs(_Fragment, { children: [_jsxs(Text, { dimColor: true, children: [(row === 0 ? formatMeasure(chart.max) : row === chartHeight - 1 ? "0" : "").padStart(6), " \u2502"] }), chart.columns.map((col, i) => _jsx(Text, { color: col.cells[row] ? colors.get(col.cells[row]) : undefined, children: (col.cells[row] ? glyphs.get(col.cells[row]).repeat(fill) : " ".repeat(fill)).padEnd(columnWidth) }, i))] }), `bar${row}`));
247
+ lines.push(line(_jsxs(_Fragment, { children: [_jsxs(Text, { dimColor: true, children: [(row === 0 ? formatMeasure(chart.max) : row === chartHeight - 1 ? "0" : "").padStart(gutter), " \u2502"] }), chart.columns.map((col, i) => _jsx(Text, { color: col.cells[row] ? colors.get(col.cells[row]) : undefined, children: (col.cells[row] ? glyphs.get(col.cells[row]).repeat(fill) : " ".repeat(fill)).padEnd(columnWidth) }, i))] }), `bar${row}`));
240
248
  const labelStride = columnWidth >= 3 ? 1 : Math.max(1, Math.ceil(chart.columns.length / 8));
241
249
  const axisUnit = query.period === "day" ? "hour" : query.period === "year" ? "month" : "day";
242
- lines.push(line(_jsxs(Text, { dimColor: true, children: [" └", chart.columns.map((col, i) => i % labelStride === 0 ? col.label.padStart(2).slice(-2).padEnd(columnWidth) : " ".repeat(columnWidth)).join("").trimEnd(), " ", axisUnit] }), "axis"));
250
+ lines.push(line(_jsxs(Text, { dimColor: true, children: [`${" ".repeat(gutter + 1)}└`, chart.columns.map((col, i) => i % labelStride === 0 ? col.label.padStart(2).slice(-2).padEnd(columnWidth) : " ".repeat(columnWidth)).join("").trimEnd(), " ", axisUnit] }), "axis"));
243
251
  const labelWidth = Math.max(5, Math.floor(width / Math.max(1, chart.legend.length)) - 4);
244
252
  lines.push(line(_jsx(_Fragment, { children: chart.legend.map(s => _jsxs(Text, { color: colors.get(s.key), children: [glyphs.get(s.key), " ", s.label.length > labelWidth ? `${s.label.slice(0, Math.ceil((labelWidth - 1) / 2))}…${s.label.slice(-Math.floor((labelWidth - 1) / 2))}` : s.label, " "] }, s.key)) }), "legend"));
245
253
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@timo972/cc-router",
3
- "version": "0.13.0-rc.5",
3
+ "version": "0.13.0-rc.6",
4
4
  "description": "Cache-aware session router for Claude Max OAuth tokens — use multiple Claude Max accounts with Claude Code",
5
5
  "type": "module",
6
6
  "bin": {