tokmon 0.14.3 → 0.14.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.
Files changed (2) hide show
  1. package/dist/cli.js +86 -26
  2. package/package.json +1 -1
package/dist/cli.js CHANGED
@@ -609,9 +609,10 @@ function glyphs() {
609
609
 
610
610
  // src/app.tsx
611
611
  import { spawn } from "child_process";
612
- import { useState as useState3, useEffect as useEffect3, useCallback, useRef as useRef2, useMemo } from "react";
612
+ import { appendFileSync as appendFileSync2 } from "fs";
613
+ import { useState as useState3, useEffect as useEffect3, useCallback as useCallback2, useRef as useRef2, useMemo } from "react";
613
614
  import { Box as Box7, Text as Text7, Transform, useInput, useStdout, useApp } from "ink";
614
- import { useMouse } from "@zenobius/ink-mouse";
615
+ import { useMouse as useMouse2 } from "@zenobius/ink-mouse";
615
616
 
616
617
  // src/http.ts
617
618
  async function readJson(res) {
@@ -2244,9 +2245,10 @@ async function requestCloudCodeJson(path, token, body) {
2244
2245
  }
2245
2246
  function readPlan(loadData) {
2246
2247
  const paid = typeof loadData?.paidTier?.name === "string" ? loadData.paidTier.name.trim() : "";
2247
- if (paid) return paid;
2248
2248
  const current = typeof loadData?.currentTier?.name === "string" ? loadData.currentTier.name.trim() : "";
2249
- return current || null;
2249
+ const raw = paid || current;
2250
+ if (!raw) return null;
2251
+ return raw.replace(/^Gemini Code Assist (?:in|for)\s+/i, "").replace(/^Gemini Code Assist$/i, "Code Assist");
2250
2252
  }
2251
2253
  function parseBuckets(data) {
2252
2254
  if (!Array.isArray(data?.buckets)) return [];
@@ -2321,8 +2323,8 @@ function normalizeLabel(label) {
2321
2323
  }
2322
2324
  function poolLabel(label) {
2323
2325
  const lower = normalizeLabel(label).toLowerCase();
2324
- if (lower.includes("gemini") && lower.includes("pro")) return "Gemini Pro";
2325
- if (lower.includes("gemini") && lower.includes("flash")) return "Gemini Flash";
2326
+ if (lower.includes("gemini") && lower.includes("pro")) return "Pro";
2327
+ if (lower.includes("gemini") && lower.includes("flash")) return "Flash";
2326
2328
  return "Claude";
2327
2329
  }
2328
2330
  function sortKey(label) {
@@ -2667,9 +2669,10 @@ function saveSnapshot(stats) {
2667
2669
  }
2668
2670
 
2669
2671
  // src/ui/shared.tsx
2670
- import { useState, useEffect, useRef } from "react";
2672
+ import { appendFileSync } from "fs";
2673
+ import { useState, useEffect, useRef, useCallback } from "react";
2671
2674
  import { Box, Text } from "ink";
2672
- import { useOnMouseClick } from "@zenobius/ink-mouse";
2675
+ import { useOnMouseClick, useMouse, useElementPosition, useElementDimensions } from "@zenobius/ink-mouse";
2673
2676
  import { jsx, jsxs } from "react/jsx-runtime";
2674
2677
  function truncateName(s, n) {
2675
2678
  const ell = glyphs().ellipsis;
@@ -2682,6 +2685,42 @@ function ClickableBox({ onClick, children, ...props }) {
2682
2685
  });
2683
2686
  return /* @__PURE__ */ jsx(Box, { ref, ...props, children });
2684
2687
  }
2688
+ function LinkBox({ onClick, children, ...props }) {
2689
+ const ref = useRef(null);
2690
+ const mouse = useMouse();
2691
+ const pos3 = useElementPosition(ref);
2692
+ const dim = useElementDimensions(ref);
2693
+ const handler = useCallback((m, action) => {
2694
+ if (process.env.TOKMON_LINKDEBUG) {
2695
+ try {
2696
+ appendFileSync(process.env.TOKMON_LINKDEBUG, `evt action=${action} m=${m.x},${m.y} pos=${pos3.left},${pos3.top} dim=${dim.width},${dim.height}
2697
+ `);
2698
+ } catch {
2699
+ }
2700
+ }
2701
+ if (action !== "press") return;
2702
+ const mx = m.x - 1;
2703
+ const my = m.y - 1;
2704
+ const { left, top } = pos3;
2705
+ const { width, height } = dim;
2706
+ if (mx >= left && mx <= left + width && my >= top && my <= top + height) onClick();
2707
+ }, [pos3, dim, onClick]);
2708
+ useEffect(() => {
2709
+ const events = mouse.events;
2710
+ if (process.env.TOKMON_LINKDEBUG) {
2711
+ try {
2712
+ appendFileSync(process.env.TOKMON_LINKDEBUG, `LINKBOX subscribe events=${events ? "present" : "MISSING"} on=${typeof events?.on}
2713
+ `);
2714
+ } catch {
2715
+ }
2716
+ }
2717
+ events.on("click", handler);
2718
+ return () => {
2719
+ events.off("click", handler);
2720
+ };
2721
+ }, [mouse.events, handler]);
2722
+ return /* @__PURE__ */ jsx(Box, { ref, ...props, children });
2723
+ }
2685
2724
  function Spinner({ label }) {
2686
2725
  const frames = glyphs().spinner;
2687
2726
  const [i, setI] = useState(0);
@@ -2889,14 +2928,6 @@ function ProviderCard({ provider, accounts, stats, width, variant }) {
2889
2928
  /* @__PURE__ */ jsx2(Text2, { color: meta.color, children: sparkline(activity.series) }),
2890
2929
  /* @__PURE__ */ jsx2(Box2, { flexGrow: 1, justifyContent: "flex-end", children: /* @__PURE__ */ jsx2(Text2, { dimColor: true, children: activity.summary }) })
2891
2930
  ] })
2892
- ] }),
2893
- !meta.hasUsage && !activity && variant === "full" && /* @__PURE__ */ jsxs2(Fragment, { children: [
2894
- /* @__PURE__ */ jsx2(Box2, { flexGrow: 1 }),
2895
- /* @__PURE__ */ jsxs2(Text2, { dimColor: true, children: [
2896
- "Billing only ",
2897
- glyphs().emDash,
2898
- " no local history"
2899
- ] })
2900
2931
  ] })
2901
2932
  ] });
2902
2933
  }
@@ -2974,7 +3005,7 @@ function MetricRow({ m, color, barW }) {
2974
3005
  if (m.format.kind === "percent") {
2975
3006
  const barColor = m.used >= 90 ? "red" : m.used >= 75 ? "yellow" : color;
2976
3007
  return /* @__PURE__ */ jsxs2(Box2, { children: [
2977
- /* @__PURE__ */ jsx2(Box2, { width: 7, children: /* @__PURE__ */ jsx2(Text2, { dimColor: true, children: m.label }) }),
3008
+ /* @__PURE__ */ jsx2(Box2, { width: 7, children: /* @__PURE__ */ jsx2(Text2, { dimColor: true, wrap: "truncate", children: m.label }) }),
2978
3009
  /* @__PURE__ */ jsx2(Bar, { pct: m.used, color: barColor, width: barW }),
2979
3010
  /* @__PURE__ */ jsx2(Box2, { width: 5, justifyContent: "flex-end", children: /* @__PURE__ */ jsxs2(Text2, { bold: true, children: [
2980
3011
  Math.round(m.used),
@@ -2984,7 +3015,7 @@ function MetricRow({ m, color, barW }) {
2984
3015
  ] });
2985
3016
  }
2986
3017
  return /* @__PURE__ */ jsxs2(Box2, { children: [
2987
- /* @__PURE__ */ jsx2(Box2, { width: 7, children: /* @__PURE__ */ jsx2(Text2, { dimColor: true, children: m.label }) }),
3018
+ /* @__PURE__ */ jsx2(Box2, { width: 7, children: /* @__PURE__ */ jsx2(Text2, { dimColor: true, wrap: "truncate", children: m.label }) }),
2988
3019
  /* @__PURE__ */ jsx2(Text2, { bold: true, color: "yellow", children: metricValueText(m) })
2989
3020
  ] });
2990
3021
  }
@@ -3885,6 +3916,8 @@ var CURSOR_SORTS = [
3885
3916
  ];
3886
3917
  var IS_TTY = process.stdin.isTTY === true;
3887
3918
  var REPO_URL = "https://github.com/DavidIlie/tokmon";
3919
+ var SITE_URL = "https://davidilie.com";
3920
+ var IS_APPLE_TERMINAL = process.env.TERM_PROGRAM === "Apple_Terminal";
3888
3921
  function detectHyperlinks(env, isTTY) {
3889
3922
  const force = env.FORCE_HYPERLINK;
3890
3923
  if (force != null && force !== "") return force !== "0" && force.toLowerCase() !== "false";
@@ -3902,6 +3935,13 @@ function detectHyperlinks(env, isTTY) {
3902
3935
  }
3903
3936
  var HYPERLINKS = detectHyperlinks(process.env, process.stdout.isTTY === true);
3904
3937
  function openUrl(url) {
3938
+ if (process.env.TOKMON_OPENLOG) {
3939
+ try {
3940
+ appendFileSync2(process.env.TOKMON_OPENLOG, url + "\n");
3941
+ } catch {
3942
+ }
3943
+ return;
3944
+ }
3905
3945
  try {
3906
3946
  if (process.platform === "darwin") spawn("open", [url], { stdio: "ignore", detached: true }).unref();
3907
3947
  else if (process.platform === "win32") spawn("cmd", ["/c", "start", "", url], { stdio: "ignore", detached: true }).unref();
@@ -4205,12 +4245,12 @@ function App({ interval: cliInterval, initialConfig }) {
4205
4245
  useEffect3(() => {
4206
4246
  setDashPage((p) => Math.min(p, dashPageCount - 1));
4207
4247
  }, [dashPageCount]);
4208
- const resetView = useCallback(() => {
4248
+ const resetView = useCallback2(() => {
4209
4249
  setCursor(0);
4210
4250
  setExpanded(-1);
4211
4251
  }, []);
4212
4252
  const clampRow = (n) => Math.max(0, Math.min(rowCountRef.current - 1, n));
4213
- const mouse = useMouse();
4253
+ const mouse = useMouse2();
4214
4254
  useEffect3(() => {
4215
4255
  if (!IS_TTY) return;
4216
4256
  mouse.enable();
@@ -4223,8 +4263,20 @@ function App({ interval: cliInterval, initialConfig }) {
4223
4263
  }
4224
4264
  };
4225
4265
  mouse.events.on("scroll", onScroll);
4266
+ let onClickDbg = null;
4267
+ if (process.env.TOKMON_LINKDEBUG) {
4268
+ onClickDbg = (p, a) => {
4269
+ try {
4270
+ appendFileSync2(process.env.TOKMON_LINKDEBUG, `APP click p=${p.x},${p.y} a=${a}
4271
+ `);
4272
+ } catch {
4273
+ }
4274
+ };
4275
+ mouse.events.on("click", onClickDbg);
4276
+ }
4226
4277
  return () => {
4227
4278
  mouse.events.off("scroll", onScroll);
4279
+ if (onClickDbg) mouse.events.off("click", onClickDbg);
4228
4280
  };
4229
4281
  }, [tab]);
4230
4282
  function updateConfig(fn) {
@@ -4515,6 +4567,10 @@ function App({ interval: cliInterval, initialConfig }) {
4515
4567
  exit();
4516
4568
  return;
4517
4569
  }
4570
+ if (input === "O") {
4571
+ openUrl(REPO_URL);
4572
+ return;
4573
+ }
4518
4574
  if (showSettings) {
4519
4575
  if (key.escape || input === "s") {
4520
4576
  setShowSettings(false);
@@ -4927,21 +4983,25 @@ function AccountStrip({ slots, activeIdx, onSelect }) {
4927
4983
  }
4928
4984
  function Footer({ hasAccounts, paginated, cols }) {
4929
4985
  const inner = cols - 4;
4930
- const BASE2 = "by David Ilie (davidilie.com) \xB7 s=settings q=quit".length;
4986
+ const BASE2 = "by David Ilie (davidilie.com) \xB7 O=repo s=settings q=quit".length;
4987
+ const optHint = (glyphs().shift === "\u21E7" ? "\u2325" : "opt") + "-click links ";
4988
+ const OPT = IS_APPLE_TERMINAL ? optHint.length : 0;
4931
4989
  const JUMP = "0-9=jump a/A=cycle ".length;
4932
4990
  const PAGE = "scroll=page ".length;
4933
- const showJump = hasAccounts && inner >= BASE2 + JUMP + (paginated ? PAGE : 0);
4934
- const showPage = paginated && inner >= BASE2 + (showJump ? JUMP : 0) + PAGE;
4991
+ const showOpt = IS_APPLE_TERMINAL && inner >= BASE2 + OPT;
4992
+ const showJump = hasAccounts && inner >= BASE2 + (showOpt ? OPT : 0) + JUMP + (paginated ? PAGE : 0);
4993
+ const showPage = paginated && inner >= BASE2 + (showOpt ? OPT : 0) + (showJump ? JUMP : 0) + PAGE;
4935
4994
  return /* @__PURE__ */ jsxs7(Box7, { marginTop: 1, flexWrap: "nowrap", children: [
4936
4995
  /* @__PURE__ */ jsx7(Text7, { dimColor: true, children: "by " }),
4937
- /* @__PURE__ */ jsx7(ClickableBox, { onClick: () => openUrl(REPO_URL), children: /* @__PURE__ */ jsx7(Transform, { transform: (s) => osc8(s, REPO_URL), children: /* @__PURE__ */ jsx7(Text7, { underline: true, children: "David Ilie" }) }) }),
4996
+ /* @__PURE__ */ jsx7(LinkBox, { onClick: () => openUrl(REPO_URL), children: /* @__PURE__ */ jsx7(Transform, { transform: (s) => osc8(s, REPO_URL), children: /* @__PURE__ */ jsx7(Text7, { underline: true, children: "David Ilie" }) }) }),
4938
4997
  /* @__PURE__ */ jsx7(Text7, { dimColor: true, children: " (" }),
4939
- /* @__PURE__ */ jsx7(ClickableBox, { onClick: () => openUrl("https://davidilie.com"), children: /* @__PURE__ */ jsx7(Transform, { transform: (s) => osc8(s, "https://davidilie.com"), children: /* @__PURE__ */ jsx7(Text7, { color: "cyan", underline: true, children: "davidilie.com" }) }) }),
4998
+ /* @__PURE__ */ jsx7(LinkBox, { onClick: () => openUrl(SITE_URL), children: /* @__PURE__ */ jsx7(Transform, { transform: (s) => osc8(s, SITE_URL), children: /* @__PURE__ */ jsx7(Text7, { color: "cyan", underline: true, children: "davidilie.com" }) }) }),
4940
4999
  /* @__PURE__ */ jsxs7(Text7, { dimColor: true, children: [
4941
5000
  ") ",
4942
5001
  glyphs().middot,
4943
- " s=settings "
5002
+ " O=repo s=settings "
4944
5003
  ] }),
5004
+ showOpt && /* @__PURE__ */ jsx7(Text7, { dimColor: true, children: optHint }),
4945
5005
  showJump && /* @__PURE__ */ jsx7(Text7, { dimColor: true, children: "0-9=jump a/A=cycle " }),
4946
5006
  showPage && /* @__PURE__ */ jsx7(Text7, { dimColor: true, children: "scroll=page " }),
4947
5007
  /* @__PURE__ */ jsx7(Text7, { dimColor: true, children: "q=quit" })
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "tokmon",
3
- "version": "0.14.3",
3
+ "version": "0.14.4",
4
4
  "description": "Terminal dashboard for Claude Code, Codex, and Cursor usage, limits, and costs",
5
5
  "type": "module",
6
6
  "bin": {