opencode-token-tracker 1.6.0 → 1.6.2
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/dist/bin/opencode-tokens.js +64 -40
- package/package.json +1 -1
|
@@ -534,13 +534,12 @@ function cmdConfig(positional) {
|
|
|
534
534
|
console.log("\n Usage: opencode-tokens config get <key>\n");
|
|
535
535
|
return;
|
|
536
536
|
}
|
|
537
|
-
|
|
538
|
-
if (value === undefined) {
|
|
537
|
+
if (!SETTABLE_KEYS[key]) {
|
|
539
538
|
console.log(`\n Unknown key: ${key}\n Available: ${Object.keys(SETTABLE_KEYS).join(", ")}\n`);
|
|
539
|
+
return;
|
|
540
540
|
}
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
}
|
|
541
|
+
const value = resolveConfigKey(config, key);
|
|
542
|
+
console.log(`\n ${key} = ${JSON.stringify(value)} (default: ${JSON.stringify(SETTABLE_KEYS[key].default)})\n`);
|
|
544
543
|
return;
|
|
545
544
|
}
|
|
546
545
|
if (action === "set") {
|
|
@@ -946,10 +945,16 @@ function cmdTrend(flags) {
|
|
|
946
945
|
console.log(`\n ${spark}\n`);
|
|
947
946
|
return;
|
|
948
947
|
}
|
|
949
|
-
// Build chart
|
|
948
|
+
// Build chart — pixel-based rendering
|
|
950
949
|
const cols = values.map((v) => ({ value: v, y: Math.round((v / maxVal) * (H - 1)) }));
|
|
951
950
|
const chartWidth = Math.max(width - 12, 20);
|
|
952
|
-
|
|
951
|
+
// Map data points to pixel x-positions (evenly spaced across chartWidth)
|
|
952
|
+
const px = [];
|
|
953
|
+
const py = [];
|
|
954
|
+
for (let i = 0; i < cols.length; i++) {
|
|
955
|
+
px.push(cols.length === 1 ? Math.floor(chartWidth / 2) : Math.round((i / (cols.length - 1)) * (chartWidth - 1)));
|
|
956
|
+
py.push(cols[i].y);
|
|
957
|
+
}
|
|
953
958
|
const yLabelStep = Math.max(1, Math.floor(H / 5));
|
|
954
959
|
const lines = [];
|
|
955
960
|
for (let row = H - 1; row >= 0; row--) {
|
|
@@ -960,56 +965,75 @@ function cmdTrend(flags) {
|
|
|
960
965
|
: "";
|
|
961
966
|
line += padLeft(label, 9);
|
|
962
967
|
line += row === 0 ? " ┼" : " ┤";
|
|
963
|
-
|
|
964
|
-
|
|
965
|
-
|
|
966
|
-
|
|
967
|
-
|
|
968
|
-
|
|
969
|
-
|
|
970
|
-
line += "╭";
|
|
971
|
-
else if (prevY > col.y && nextY >= col.y)
|
|
972
|
-
line += "╰";
|
|
973
|
-
else if (prevY < col.y || nextY < col.y)
|
|
974
|
-
line += "╭";
|
|
975
|
-
else if (prevY > col.y || nextY > col.y)
|
|
976
|
-
line += "╰";
|
|
977
|
-
else
|
|
978
|
-
line += "─";
|
|
968
|
+
// Build a sparse array of characters at specific x-positions for this row
|
|
969
|
+
const chars = [];
|
|
970
|
+
// Data points that land on this row
|
|
971
|
+
for (let i = 0; i < px.length; i++) {
|
|
972
|
+
if (py[i] === row) {
|
|
973
|
+
if (cols.length === 1) {
|
|
974
|
+
chars.push({ x: px[i], c: "─" });
|
|
979
975
|
}
|
|
980
976
|
else {
|
|
981
|
-
|
|
982
|
-
|
|
983
|
-
|
|
984
|
-
|
|
977
|
+
const prevSlope = i > 0 ? py[i] - py[i - 1] : 0;
|
|
978
|
+
const nextSlope = i < px.length - 1 ? py[i + 1] - py[i] : 0;
|
|
979
|
+
let c = "─";
|
|
980
|
+
if (i === 0)
|
|
981
|
+
c = nextSlope > 0 ? "╭" : nextSlope < 0 ? "╰" : "─";
|
|
982
|
+
else if (i === px.length - 1)
|
|
983
|
+
c = prevSlope > 0 ? "╮" : prevSlope < 0 ? "╯" : "─";
|
|
984
|
+
else if (prevSlope > 0 && nextSlope > 0)
|
|
985
|
+
c = "╭";
|
|
986
|
+
else if (prevSlope < 0 && nextSlope < 0)
|
|
987
|
+
c = "╰";
|
|
988
|
+
else if (prevSlope > 0 && nextSlope < 0)
|
|
989
|
+
c = "╮";
|
|
990
|
+
else if (prevSlope < 0 && nextSlope > 0)
|
|
991
|
+
c = "╯";
|
|
992
|
+
chars.push({ x: px[i], c });
|
|
985
993
|
}
|
|
986
994
|
}
|
|
987
|
-
|
|
988
|
-
|
|
989
|
-
|
|
990
|
-
|
|
991
|
-
|
|
992
|
-
|
|
993
|
-
|
|
994
|
-
|
|
995
|
+
}
|
|
996
|
+
// Line segments crossing this row (exact x of intersection)
|
|
997
|
+
for (let i = 1; i < px.length; i++) {
|
|
998
|
+
const y0 = py[i - 1], y1 = py[i];
|
|
999
|
+
// Skip if segment doesn't cross this row
|
|
1000
|
+
if ((y0 <= row && y1 <= row) || (y0 >= row && y1 >= row))
|
|
1001
|
+
continue;
|
|
1002
|
+
if (y0 === y1)
|
|
1003
|
+
continue;
|
|
1004
|
+
const t = (row - y0) / (y1 - y0);
|
|
1005
|
+
const cx = Math.round(px[i - 1] + t * (px[i] - px[i - 1]));
|
|
1006
|
+
const slope = y1 - y0;
|
|
1007
|
+
chars.push({ x: cx, c: slope > 0 ? "╱" : "╲" });
|
|
1008
|
+
}
|
|
1009
|
+
// Render the row: sort chars by x and fill gaps with spaces
|
|
1010
|
+
chars.sort((a, b) => a.x - b.x);
|
|
1011
|
+
let prevX = 0;
|
|
1012
|
+
for (const { x, c } of chars) {
|
|
1013
|
+
while (prevX < x) {
|
|
1014
|
+
line += " ";
|
|
1015
|
+
prevX++;
|
|
995
1016
|
}
|
|
1017
|
+
line += c;
|
|
1018
|
+
prevX = x + 1;
|
|
996
1019
|
}
|
|
997
1020
|
lines.push(line);
|
|
998
1021
|
}
|
|
999
1022
|
// Bottom axis
|
|
1000
1023
|
let axis = " ".repeat(9) + " └";
|
|
1001
|
-
axis += "─".repeat(
|
|
1024
|
+
axis += "─".repeat(chartWidth);
|
|
1002
1025
|
lines.push(axis);
|
|
1003
1026
|
// X axis labels
|
|
1004
1027
|
const labelStep = Math.max(1, Math.ceil(sorted.length / 6));
|
|
1005
1028
|
let xLabels = " ".repeat(11);
|
|
1006
|
-
for (let i = 0; i <
|
|
1007
|
-
if (i % labelStep === 0 || i ===
|
|
1029
|
+
for (let i = 0; i < px.length; i++) {
|
|
1030
|
+
if (i % labelStep === 0 || i === px.length - 1) {
|
|
1008
1031
|
const d = new Date(sorted[i][0]);
|
|
1009
1032
|
const ds = `${d.getMonth() + 1}/${d.getDate()}`;
|
|
1033
|
+
const pos = px[i] + 0;
|
|
1034
|
+
while (xLabels.length - 11 < pos)
|
|
1035
|
+
xLabels += " ";
|
|
1010
1036
|
xLabels += ds;
|
|
1011
|
-
if (i < cols.length - 1)
|
|
1012
|
-
xLabels += " ".repeat(Math.max(1, xStep - ds.length + 1));
|
|
1013
1037
|
}
|
|
1014
1038
|
}
|
|
1015
1039
|
lines.push(xLabels);
|
package/package.json
CHANGED