opencode-token-tracker 1.6.3 → 1.6.4

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.
@@ -899,55 +899,39 @@ function cmdHelp() {
899
899
  opencode-tokens config get toast.enabled # Check if toast is enabled
900
900
  `);
901
901
  }
902
+ const BRAILLE_DOTS = [0x01, 0x02, 0x04, 0x40, 0x08, 0x10, 0x20, 0x80];
902
903
  function getTrendValue(point, metric) {
903
904
  return metric === "tokens" ? point.tokens : metric === "messages" ? point.messages : point.cost;
904
905
  }
905
906
  function formatTrendValue(value, metric) {
906
907
  return metric === "tokens" ? formatTokens(value) : metric === "messages" ? String(Math.round(value)) : formatCost(value);
907
908
  }
909
+ function formatSignedTrendValue(value, metric) {
910
+ const sign = value > 0 ? "+" : value < 0 ? "-" : "";
911
+ return `${sign}${formatTrendValue(Math.abs(value), metric)}`;
912
+ }
908
913
  function metricLabel(metric) {
909
914
  return metric === "tokens" ? "Token Trend" : metric === "messages" ? "Message Trend" : "Cost Trend";
910
915
  }
911
- function createTrendRows(height, width, gridRows) {
912
- const rows = [];
913
- for (let row = 0; row < height; row++) {
914
- const grid = gridRows.has(row);
915
- rows.push(Array.from({ length: width }, (_, x) => grid && x % 2 === 0 ? "·" : " "));
916
- }
917
- return rows;
918
- }
919
- function drawTrendSegment(rows, from, to) {
920
- const startX = Math.min(from.x, to.x);
921
- const endX = Math.max(from.x, to.x);
922
- const slope = to.y - from.y;
923
- for (let x = startX; x <= endX; x++) {
924
- const t = x === from.x ? 0 : (x - from.x) / (to.x - from.x);
925
- const y = Math.round(from.y + slope * t);
926
- const char = slope > 0 ? "╱" : slope < 0 ? "╲" : "─";
927
- rows[y][x] = char;
928
- }
916
+ function addBraillePoint(cells, x, y) {
917
+ const cellX = Math.floor(x / 2);
918
+ const cellY = Math.floor(y / 4);
919
+ const dotX = x % 2;
920
+ const dotY = y % 4;
921
+ cells[cellY][cellX] |= BRAILLE_DOTS[dotX * 4 + dotY];
929
922
  }
930
- function drawTrendArea(rows, points) {
923
+ function buildBrailleRows(points, width, height) {
924
+ const cells = Array.from({ length: height }, () => Array.from({ length: width }, () => 0));
931
925
  for (let i = 1; i < points.length; i++) {
932
926
  const from = points[i - 1];
933
927
  const to = points[i];
934
- const startX = Math.min(from.x, to.x);
935
- const endX = Math.max(from.x, to.x);
936
- for (let x = startX; x <= endX; x++) {
937
- const t = x === from.x ? 0 : (x - from.x) / (to.x - from.x);
938
- const y = Math.round(from.y + (to.y - from.y) * t);
939
- for (let fillY = 0; fillY < y; fillY++) {
940
- if (rows[fillY][x] === " " || rows[fillY][x] === "·") {
941
- rows[fillY][x] = "░";
942
- }
943
- }
928
+ const steps = Math.max(Math.abs(to.x - from.x), Math.abs(to.y - from.y), 1);
929
+ for (let step = 0; step <= steps; step++) {
930
+ const t = step / steps;
931
+ addBraillePoint(cells, Math.round(from.x + (to.x - from.x) * t), Math.round(from.y + (to.y - from.y) * t));
944
932
  }
945
933
  }
946
- }
947
- function drawTrendPoints(rows, points) {
948
- for (const point of points) {
949
- rows[point.y][point.x] = "●";
950
- }
934
+ return cells.map(row => row.map(mask => mask === 0 ? " " : String.fromCharCode(0x2800 + mask)).join(""));
951
935
  }
952
936
  function buildTrendXAxis(points, chartPoints, chartWidth) {
953
937
  const labelChars = Array.from({ length: chartWidth }, () => " ");
@@ -1004,7 +988,7 @@ function cmdTrend(flags) {
1004
988
  const totalVal = values.reduce((sum, value) => sum + value, 0);
1005
989
  const avgVal = totalVal / values.length;
1006
990
  const deltaVal = values[values.length - 1] - values[0];
1007
- const H = Math.max(5, Math.min(Math.floor(width / 3), 20));
991
+ const chartHeight = sorted.length <= 3 ? 6 : Math.max(6, Math.min(Math.floor(width / 4), 12));
1008
992
  if (width < 35) {
1009
993
  // Fallback: simple sparkline
1010
994
  const chars = ["▁", "▂", "▃", "▄", "▅", "▆", "▇", "█"];
@@ -1013,37 +997,30 @@ function cmdTrend(flags) {
1013
997
  return;
1014
998
  }
1015
999
  const chartWidth = Math.max(width - 12, 20);
1016
- const yLabelStep = Math.max(1, Math.floor(H / 5));
1017
- const gridRows = new Set();
1018
- for (let row = 0; row < H; row++) {
1019
- if (row === 0 || row === H - 1 || (H - 1 - row) % yLabelStep === 0) {
1020
- gridRows.add(row);
1021
- }
1022
- }
1000
+ const yLabelStep = Math.max(1, Math.floor(chartHeight / 4));
1001
+ const dotWidth = chartWidth * 2;
1002
+ const dotHeight = chartHeight * 4;
1023
1003
  const chartPoints = values.map((value, i) => ({
1024
- x: values.length === 1 ? Math.floor(chartWidth / 2) : Math.round((i / (values.length - 1)) * (chartWidth - 1)),
1025
- y: Math.round((value / maxVal) * (H - 1)),
1004
+ x: values.length === 1 ? Math.floor(dotWidth / 2) : Math.round((i / (values.length - 1)) * (dotWidth - 1)),
1005
+ y: Math.max(0, dotHeight - 1 - Math.round((value / maxVal) * (dotHeight - 1))),
1026
1006
  }));
1027
- const rows = createTrendRows(H, chartWidth, gridRows);
1028
- drawTrendArea(rows, chartPoints);
1029
- for (let i = 1; i < chartPoints.length; i++) {
1030
- drawTrendSegment(rows, chartPoints[i - 1], chartPoints[i]);
1031
- }
1032
- drawTrendPoints(rows, chartPoints);
1007
+ const rows = buildBrailleRows(chartPoints, chartWidth, chartHeight);
1008
+ const labelPoints = chartPoints.map(point => ({ x: Math.floor(point.x / 2), y: point.y }));
1033
1009
  const lines = [];
1034
- lines.push(`${metricLabel(metric)} · ${sorted.length} days · peak ${formatTrendValue(maxVal, metric)} · avg ${formatTrendValue(avgVal, metric)} · Δ ${deltaVal >= 0 ? "+" : ""}${formatTrendValue(deltaVal, metric)}`);
1010
+ lines.push(`${metricLabel(metric)} · ${sorted.length} days · peak ${formatTrendValue(maxVal, metric)} · avg ${formatTrendValue(avgVal, metric)} · Δ ${formatSignedTrendValue(deltaVal, metric)}`);
1035
1011
  lines.push(`range ${formatTrendValue(minVal, metric)} → ${formatTrendValue(maxVal, metric)}`);
1036
- for (let row = H - 1; row >= 0; row--) {
1037
- const valAtRow = (row / (H - 1)) * maxVal;
1038
- const label = gridRows.has(row)
1012
+ for (let row = 0; row < chartHeight; row++) {
1013
+ const valueRatio = 1 - row / (chartHeight - 1);
1014
+ const valAtRow = valueRatio * maxVal;
1015
+ const label = row === 0 || row === chartHeight - 1 || row % yLabelStep === 0
1039
1016
  ? formatTrendValue(valAtRow, metric)
1040
1017
  : "";
1041
- const line = `${padLeft(label, 9)}${row === 0 ? " ┼" : " ┤"}${rows[row].join("")}`;
1018
+ const line = `${padLeft(label, 9)} ┤${rows[row]}`;
1042
1019
  lines.push(line);
1043
1020
  }
1044
1021
  const axis = `${" ".repeat(9)} └${"─".repeat(chartWidth)}`;
1045
1022
  lines.push(axis);
1046
- lines.push(`${" ".repeat(11)}${buildTrendXAxis(sorted, chartPoints, chartWidth)}`);
1023
+ lines.push(`${" ".repeat(11)}${buildTrendXAxis(sorted, labelPoints, chartWidth)}`);
1047
1024
  console.log();
1048
1025
  for (const l of lines)
1049
1026
  console.log(` ${l}`);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "opencode-token-tracker",
3
- "version": "1.6.3",
3
+ "version": "1.6.4",
4
4
  "description": "Real-time token usage and cost tracking plugin for OpenCode with Toast notifications and CLI stats",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",