@d3lm/pr-stats 0.2.23 → 0.2.24

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/README.md CHANGED
@@ -99,7 +99,7 @@ The report holds a `review`, `authored`, and `comments` object with one entry pe
99
99
 
100
100
  Closed and merged PRs are cached on disk per PR, because their timelines and sizes no longer change. Searches and open PRs are fetched fresh on each run. The TUI also snapshots the last successful load, so a later start with the same options renders instantly while the real load refreshes in the background.
101
101
 
102
- The cache lives in `~/Library/Caches/pr-stats` on macOS and in `$XDG_CACHE_HOME/pr-stats` or `~/.cache/pr-stats` elsewhere. The `PR_STATS_CACHE_DIR` environment variable overrides the location. `--no-cache` skips every cache read for one run, and the settings dialog can disable the cache permanently.
102
+ The cache lives in `~/Library/Caches/pr-stats` on macOS and in `$XDG_CACHE_HOME/pr-stats` or `~/.cache/pr-stats` elsewhere. The `PR_STATS_CACHE_DIR` environment variable overrides the location. `--no-cache` skips every cache read for one run, and the settings dialog can disable the cache permanently. The Clear cache row in the settings dialog shows the path next to the size of the directory on disk, and deletes the cached PR data while keeping the saved options and settings.
103
103
 
104
104
  The options modal saves the current options to the cache directory with the `s` key. Later runs start from the saved options wherever no flag was given, and flags always take precedence.
105
105
 
@@ -19,9 +19,9 @@
19
19
  <key>CFBundlePackageType</key>
20
20
  <string>APPL</string>
21
21
  <key>CFBundleShortVersionString</key>
22
- <string>0.2.23</string>
22
+ <string>0.2.24</string>
23
23
  <key>CFBundleVersion</key>
24
- <string>0.2.23</string>
24
+ <string>0.2.24</string>
25
25
  <key>LSMinimumSystemVersion</key>
26
26
  <string>13.0</string>
27
27
  <key>LSUIElement</key>
package/dist/tui-app.mjs CHANGED
@@ -143,7 +143,7 @@ import { readFileSync as readFileSync3 } from "node:fs";
143
143
  import { join as join3 } from "node:path";
144
144
 
145
145
  // src/cache.ts
146
- import { mkdirSync, readFileSync, renameSync, rmSync, writeFileSync } from "node:fs";
146
+ import { mkdirSync, readdirSync, readFileSync, renameSync, rmSync, statSync, writeFileSync } from "node:fs";
147
147
  import { homedir } from "node:os";
148
148
  import { dirname, join } from "node:path";
149
149
  var VERSION = 5;
@@ -163,6 +163,24 @@ function cacheDir() {
163
163
  }
164
164
  return join(process.env.XDG_CACHE_HOME ?? join(homedir(), ".cache"), "pr-stats");
165
165
  }
166
+ function cacheSize() {
167
+ const dir = cacheDir();
168
+ let total = 0;
169
+ try {
170
+ const entries = readdirSync(dir, { withFileTypes: true });
171
+ for (const entry of entries) {
172
+ if (!entry.isFile()) {
173
+ continue;
174
+ }
175
+ try {
176
+ total += statSync(join(dir, entry.name)).size;
177
+ } catch {
178
+ }
179
+ }
180
+ } catch {
181
+ }
182
+ return total;
183
+ }
166
184
  function prKey(repo, number) {
167
185
  return `${repo}#${number}`;
168
186
  }
@@ -277,6 +295,19 @@ function fail(message) {
277
295
  function formatMinutesOfDay(minutes) {
278
296
  return `${Math.floor(minutes / 60)}:${String(minutes % 60).padStart(2, "0")}`;
279
297
  }
298
+ function formatBytes(bytes) {
299
+ const units = ["B", "KiB", "MiB", "GiB", "TiB"];
300
+ let value2 = bytes;
301
+ let unit = 0;
302
+ while (value2 >= 1023.5 && unit < units.length - 1) {
303
+ value2 /= 1024;
304
+ unit += 1;
305
+ }
306
+ if (unit === 0) {
307
+ return `${value2} ${units[unit]}`;
308
+ }
309
+ return `${value2 < 10 ? value2.toFixed(1) : Math.round(value2)} ${units[unit]}`;
310
+ }
280
311
  function percentile(sorted, percent) {
281
312
  const index = Math.min(sorted.length - 1, Math.ceil(percent / 100 * sorted.length) - 1);
282
313
  return sorted[Math.max(0, index)];
@@ -3794,7 +3825,7 @@ import { join as join6 } from "node:path";
3794
3825
  // src/github.ts
3795
3826
  import { execFile } from "node:child_process";
3796
3827
  import { createHash } from "node:crypto";
3797
- import { statSync } from "node:fs";
3828
+ import { statSync as statSync2 } from "node:fs";
3798
3829
  import { join as join5, resolve } from "node:path";
3799
3830
  import { promisify } from "node:util";
3800
3831
  var execFileAsync = promisify(execFile);
@@ -3804,10 +3835,10 @@ var token;
3804
3835
  var ghBinary = "gh";
3805
3836
  function resolveDebugBinary(input) {
3806
3837
  const resolved = resolve(input);
3807
- const stats = statSync(resolved, { throwIfNoEntry: false });
3838
+ const stats = statSync2(resolved, { throwIfNoEntry: false });
3808
3839
  if (stats?.isDirectory()) {
3809
3840
  const binary = join5(resolved, "gh");
3810
- if (!statSync(binary, { throwIfNoEntry: false })?.isFile()) {
3841
+ if (!statSync2(binary, { throwIfNoEntry: false })?.isFile()) {
3811
3842
  throw new CliError(`--debug directory "${input}" does not contain a gh executable`);
3812
3843
  }
3813
3844
  return binary;
@@ -5350,7 +5381,15 @@ function SettingValue({
5350
5381
  return /* @__PURE__ */ jsx12(ToggleValue, { value: noCache2 ? "yes" : "no", isSelected });
5351
5382
  }
5352
5383
  case "clearCache": {
5353
- return /* @__PURE__ */ jsx12(PathValue, { path: cacheDir(), confirming: cacheAction === "confirm", isSelected });
5384
+ return /* @__PURE__ */ jsx12(
5385
+ PathValue,
5386
+ {
5387
+ path: cacheDir(),
5388
+ detail: formatBytes(cacheSize()),
5389
+ confirming: cacheAction === "confirm",
5390
+ isSelected
5391
+ }
5392
+ );
5354
5393
  }
5355
5394
  case "autoReload": {
5356
5395
  return /* @__PURE__ */ jsx12(ToggleValue, { value: autoReload2 ? "yes" : "no", isSelected });
@@ -5428,11 +5467,22 @@ function IntervalValue({ value: value2, active, isSelected }) {
5428
5467
  }
5429
5468
  return /* @__PURE__ */ jsx12("text", { wrapMode: "none", fg: theme.muted, children: value2 });
5430
5469
  }
5431
- function PathValue({ path, confirming, isSelected }) {
5470
+ function PathValue({
5471
+ path,
5472
+ detail,
5473
+ confirming,
5474
+ isSelected
5475
+ }) {
5432
5476
  if (confirming) {
5433
5477
  return /* @__PURE__ */ jsx12("text", { wrapMode: "none", children: /* @__PURE__ */ jsx12("b", { fg: theme.warn, children: "enter to confirm" }) });
5434
5478
  }
5435
- return /* @__PURE__ */ jsx12("text", { wrapMode: "none", fg: isSelected ? theme.text : theme.muted, children: path.replace(homedir2(), "~") });
5479
+ return /* @__PURE__ */ jsxs11("text", { wrapMode: "none", children: [
5480
+ /* @__PURE__ */ jsx12("span", { fg: isSelected ? theme.text : theme.muted, children: path.replace(homedir2(), "~") }),
5481
+ detail === void 0 ? null : /* @__PURE__ */ jsxs11("span", { fg: isSelected ? theme.muted : theme.dim, children: [
5482
+ " \xB7 ",
5483
+ detail
5484
+ ] })
5485
+ ] });
5436
5486
  }
5437
5487
 
5438
5488
  // src/tui/components/SnoozeModal.tsx
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@d3lm/pr-stats",
3
- "version": "0.2.23",
3
+ "version": "0.2.24",
4
4
  "description": "GitHub PR stats in an interactive terminal UI, via the gh CLI or an access token",
5
5
  "type": "module",
6
6
  "author": "Dominic Elm",