Summary
fmtCost() in plugins/tps/format.js formats monetary values with three precision tiers. The transition from 4 decimal places (for values < $0.01) to 3 decimal places (for values >= $0.01) is visually inconsistent: a $0.0050 cost shows more digits than a $0.012 cost.
Root Cause
File: plugins/tps/format.js:58-64
export function fmtCost(value) {
const n = Number(value);
if (!Number.isFinite(n) || n === 0) return "$0";
if (n < 0.01) return "$" + n.toFixed(4);
if (n < 1) return "$" + n.toFixed(3);
return "$" + n.toFixed(2);
}
The thresholds create a jump:
| Value |
Condition |
toFixed |
Output |
0.005 |
< 0.01 |
toFixed(4) |
"$0.0050" |
0.0123 |
>= 0.01, < 1 |
toFixed(3) |
"$0.012" |
0.0099 |
< 0.01 |
toFixed(4) |
"$0.0099" |
0.0100 |
>= 0.01, < 1 |
toFixed(3) |
"$0.010" |
A cost of 0.005 (half a cent) renders as $0.0050 — 3 significant digits with a trailing zero. A cost of 0.0123 (1.2 cents) renders as $0.012 — only 2 significant digits, with the final digit silently truncated. This is backwards: smaller values show more precision with less meaningful trailing digits, while larger values discard meaningful digits.
The existing test at tests/format.test.mjs:52-53 asserts this behavior:
assert.equal(fmtCost(0.005), "$0.0050");
assert.equal(fmtCost(0.0123), "$0.012");
The assertion treats both as correct, but the inconsistency between them is the bug.
Impact
- Visual inconsistency. Two costs side by side in the TUI render with different decimal precision for no semantic reason.
- Information loss.
0.0123 truncated to 0.012 loses 0.0003 in a context where the showCost feature is explicitly opt-in and users who enable it likely care about precision.
- Misleading for small costs. A $0.0050 display implies sub-millicent precision that API billing doesn't actually provide — it's just a rendering artifact of
toFixed(4).
Expected Behavior
Consistent significant-digit display across the full range, e.g.:
- < $0.01 → 4 significant figures (
"$0.0050", "$0.0123")
- < $1 → 3-4 significant figures depending on magnitude
-
= $1 → 2 decimal places
Or, simpler: always show 4 decimal places for values < $1 and 2 for >= $1, aligning with how API billing costs are typically displayed.
Suggested Fix
Option A — uniform sub-dollar precision:
if (n < 1) return "$" + n.toFixed(4);
return "$" + n.toFixed(2);
Option B — significant-figures approach (more complex but strictly better):
if (n < 0.01) return "$" + n.toPrecision(2);
if (n < 1) return "$" + n.toPrecision(3);
return "$" + n.toFixed(2);
Option B produces: 0.005 → "$0.0050", 0.0123 → "$0.0123", 0.123 → "$0.123", 1.50 → "$1.50".
Summary
fmtCost()inplugins/tps/format.jsformats monetary values with three precision tiers. The transition from 4 decimal places (for values < $0.01) to 3 decimal places (for values >= $0.01) is visually inconsistent: a $0.0050 cost shows more digits than a $0.012 cost.Root Cause
File:
plugins/tps/format.js:58-64The thresholds create a jump:
toFixed0.005< 0.01toFixed(4)"$0.0050"0.0123>= 0.01, < 1toFixed(3)"$0.012"0.0099< 0.01toFixed(4)"$0.0099"0.0100>= 0.01, < 1toFixed(3)"$0.010"A cost of 0.005 (half a cent) renders as
$0.0050— 3 significant digits with a trailing zero. A cost of 0.0123 (1.2 cents) renders as$0.012— only 2 significant digits, with the final digit silently truncated. This is backwards: smaller values show more precision with less meaningful trailing digits, while larger values discard meaningful digits.The existing test at
tests/format.test.mjs:52-53asserts this behavior:The assertion treats both as correct, but the inconsistency between them is the bug.
Impact
0.0123truncated to0.012loses 0.0003 in a context where theshowCostfeature is explicitly opt-in and users who enable it likely care about precision.toFixed(4).Expected Behavior
Consistent significant-digit display across the full range, e.g.:
"$0.0050","$0.0123")Or, simpler: always show 4 decimal places for values < $1 and 2 for >= $1, aligning with how API billing costs are typically displayed.
Suggested Fix
Option A — uniform sub-dollar precision:
Option B — significant-figures approach (more complex but strictly better):
Option B produces: 0.005 → "$0.0050", 0.0123 → "$0.0123", 0.123 → "$0.123", 1.50 → "$1.50".