@caius_kong/ccusage-dashboard 0.2.16 → 0.2.17

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 (3) hide show
  1. package/README.md +6 -5
  2. package/lib/server.py +30 -26
  3. package/package.json +2 -4
package/README.md CHANGED
@@ -37,9 +37,9 @@ to what ccusage itself reports** — the source you already trust.
37
37
  npx @caius_kong/ccusage-dashboard
38
38
  ```
39
39
 
40
- That's it. npx downloads the package (including its own `ccusage` dependency),
41
- starts a local server on `http://127.0.0.1:8799`, and prints the dashboard URL
42
- for you to open.
40
+ That's it. npx downloads the package, uses the `ccusage` already on your machine
41
+ (or fetches the latest via `npx`), starts a local server on `http://127.0.0.1:8799`,
42
+ and prints the dashboard URL for you to open.
43
43
 
44
44
  > Requirements: **Node.js** (for the launcher) and **Python 3.8+** (for the server).
45
45
  > On macOS: `brew install python3`. No other installs, no build step, no config.
@@ -95,11 +95,12 @@ Browser (index.html)
95
95
  server.py (Python stdlib, zero deps)
96
96
  │ spawns: ccusage daily/monthly/weekly ... --json --offline
97
97
  ▼
98
- ccusage (bundled dependency — the real cost engine)
98
+ ccusage (your installed version — the real cost engine)
99
99
  ```
100
100
 
101
101
  - `lib/server.py` — Python stdlib HTTP server. Resolves a local ccusage
102
- (bundled dep → PATH → npx cache), warms caches on boot (~3s), then serves instant responses.
102
+ (PATH → npx cache → `npx ccusage@latest`), picking the highest real version so it
103
+ always matches the system's `ccusage`; warms caches on boot (~3s), then serves instant responses.
103
104
  - `lib/index.html` — single-file dashboard. No build step, no CDN.
104
105
  - `bin/ccusage-ui.js` — Node launcher (finds python3, starts server, prints URL).
105
106
 
package/lib/server.py CHANGED
@@ -51,28 +51,37 @@ def resolve_ccusage() -> list[str]:
51
51
  npx cache, the bun cache, then fall back to `npx --yes ccusage@latest`.
52
52
  Returns a command list to run.
53
53
  """
54
+ def _pkg_version(cli: Path) -> tuple | None:
55
+ """Real version of the ccusage package owning `cli`.
56
+
57
+ Read it from package.json, NEVER from the directory path: npm's npx
58
+ cache uses opaque hash dirs (no "ccusage@x.y.z"), so path-regex would
59
+ degrade every candidate to (0, 0, 0) and make "pick highest" a silent
60
+ no-op that picks an arbitrary (often stale) version.
61
+ """
62
+ pj = cli.parent.parent / "package.json"
63
+ try:
64
+ m = re.search(r'"version"\s*:\s*"(\d+)\.(\d+)\.(\d+)', pj.read_text())
65
+ except OSError:
66
+ return None
67
+ return tuple(map(int, m.groups())) if m else None
68
+
54
69
  def _npx_cached_cli() -> str | None:
55
- for base in ("npm", "bun"):
56
- roots = []
57
- if base == "npm":
58
- target = Path.home() / ".npm/_npx"
59
- if target.is_dir():
60
- roots.extend(p for p in target.glob("*/node_modules/ccusage/src/cli.js"))
61
- # also newer npm layout
62
- roots.extend((Path.home() / ".npm/_npx").glob("*/node_modules/ccusage/src/cli.js"))
63
- else:
64
- target = Path.home() / ".bun/install/cache"
65
- if target.is_dir():
66
- roots.extend(p for p in target.glob("ccusage*/src/cli.js"))
67
- # prefer highest semver-ish (sort by version suffix descending)
68
- def _ver(p: Path) -> tuple:
69
- s = p.as_posix()
70
- m = re.search(r"ccusage@?(\d+)\.(\d+)\.(\d+)", s)
71
- return tuple(map(int, m.groups())) if m else (0, 0, 0)
72
- best = max(roots, key=_ver, default=None)
73
- if best:
74
- return str(best)
75
- return None
70
+ """Highest-versioned ccusage in the npx/bun caches, or None.
71
+
72
+ Only candidates whose real version is readable are considered, so we
73
+ never fall back to an arbitrary pick. Returning None lets the caller
74
+ defer to `npx ccusage@latest`, which resolves the system's version.
75
+ """
76
+ roots = []
77
+ npm_target = Path.home() / ".npm/_npx"
78
+ if npm_target.is_dir():
79
+ roots.extend(npm_target.glob("*/node_modules/ccusage/src/cli.js"))
80
+ bun_target = Path.home() / ".bun/install/cache"
81
+ if bun_target.is_dir():
82
+ roots.extend(bun_target.glob("ccusage*/src/cli.js"))
83
+ scored = [(v, p) for p in roots if (v := _pkg_version(p)) is not None]
84
+ return str(max(scored)[1]) if scored else None
76
85
 
77
86
  explicit = _CCUSAGE_PATH_OVERRIDE
78
87
  if explicit:
@@ -80,11 +89,6 @@ def resolve_ccusage() -> list[str]:
80
89
  p = shutil.which("ccusage")
81
90
  if p:
82
91
  return [p]
83
- # Bundled ccusage dependency: walk up from the package to find node_modules/ccusage
84
- for parent in APP_DIR.parents:
85
- bundled = parent / "node_modules" / "ccusage" / "src" / "cli.js"
86
- if bundled.exists():
87
- return [_node(), str(bundled)]
88
92
  cli = _npx_cached_cli()
89
93
  if cli:
90
94
  return [_node(), str(cli)]
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@caius_kong/ccusage-dashboard",
3
- "version": "0.2.16",
3
+ "version": "0.2.17",
4
4
  "description": "One-command local dashboard for ccusage: today/week/month/custom cost by model, 30-day trend, monthly budget alert. Numbers straight from ccusage.",
5
5
  "license": "MIT",
6
6
  "type": "commonjs",
@@ -32,9 +32,7 @@
32
32
  "url": "https://github.com/caius-kong/ccusage-dashboard"
33
33
  },
34
34
  "author": "Caius Kong",
35
- "dependencies": {
36
- "ccusage": "^20.0.20"
37
- },
35
+ "dependencies": {},
38
36
  "publishConfig": {
39
37
  "access": "public"
40
38
  }