gh-glance 0.16.0 → 0.16.1

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/CHANGELOG.md +18 -1
  2. package/index.mjs +22 -3
  3. package/package.json +1 -1
package/CHANGELOG.md CHANGED
@@ -7,6 +7,22 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7
7
 
8
8
  ## [Unreleased]
9
9
 
10
+ ## [0.16.1] - 2026-10-02
11
+
12
+ ### Fixed
13
+
14
+ - When external API use pushes every pane's next request slot past the quota
15
+ reset, panes now show "GitHub quota pacing; retry automatically after reset"
16
+ instead of "Local coordination unavailable ... retry when storage works".
17
+ Deferred background refreshes also get their own notice.
18
+ - Heavy API use by other tools on the same account no longer starves every
19
+ pane until the quota resets. Pacing now divides by at most 4 times the
20
+ measured external pressure, while the reserve still stops gh-glance before
21
+ the account runs out.
22
+ - Uncertain charges left by dead panes are released one quota window after
23
+ their newest charge, instead of reducing every hour's budget until the next
24
+ reboot.
25
+
10
26
  ## [0.16.0] - 2026-10-01
11
27
 
12
28
  ### Changed
@@ -1216,7 +1232,8 @@ engineering, security, QA and UX. What follows is what changed as a result.
1216
1232
  - The `main` field from `package.json`. It advertised the file as importable,
1217
1233
  but importing it took over the terminal or exited the host process.
1218
1234
 
1219
- [Unreleased]: https://github.com/juan294/gh-glance/compare/v0.16.0...HEAD
1235
+ [Unreleased]: https://github.com/juan294/gh-glance/compare/v0.16.1...HEAD
1236
+ [0.16.1]: https://github.com/juan294/gh-glance/compare/v0.16.0...v0.16.1
1220
1237
  [0.16.0]: https://github.com/juan294/gh-glance/compare/v0.15.2...v0.16.0
1221
1238
  [0.15.2]: https://github.com/juan294/gh-glance/compare/v0.15.1...v0.15.2
1222
1239
  [0.15.1]: https://github.com/juan294/gh-glance/compare/v0.15.0...v0.15.1
package/index.mjs CHANGED
@@ -2289,6 +2289,12 @@ function sharedLaneEvidence(value) {
2289
2289
  // Below this many completed shared calls in a probe window, external-spend
2290
2290
  // inference is noise. Under the threshold the loop retains the previous factor.
2291
2291
  const MIN_SAMPLE_CALLS = 5;
2292
+ // Pacing divides the spendable share by the external factor, so a large factor
2293
+ // compounds: gh-glance's own paid calls shrink, the next sample's ratio grows,
2294
+ // and the lane is pushed past the reset while quota sits unused. The reserve,
2295
+ // not this divisor, is what keeps gh-glance off the floor, so the divisor can
2296
+ // be bounded without letting external load exhaust the account.
2297
+ const MAX_PACING_EXTERNAL_FACTOR = 4;
2292
2298
 
2293
2299
  const REQUEST_PRIORITIES = Object.freeze({
2294
2300
  manual: 0,
@@ -2517,7 +2523,8 @@ function resourceDecision({
2517
2523
  epoch: capacity.epoch,
2518
2524
  };
2519
2525
  }
2520
- const callsPerMs = capacity.spendable / (capacity.resetMs - nowMs) / externalFactor;
2526
+ const callsPerMs = capacity.spendable / (capacity.resetMs - nowMs) /
2527
+ Math.min(externalFactor, MAX_PACING_EXTERNAL_FACTOR);
2521
2528
  if (!Number.isFinite(callsPerMs) || callsPerMs <= 0) {
2522
2529
  return {
2523
2530
  mode: "paused",
@@ -4564,6 +4571,9 @@ function transferReceiptToDebt(state, receipt, nowMs, groupId = null) {
4564
4571
  group.units[resource] += amount;
4565
4572
  group.counts[resource] += amount > 0 ? 1 : 0;
4566
4573
  }
4574
+ // The newest charge, not the group's creation, starts the window after
4575
+ // which reconcileBootDebt may treat the group as settled.
4576
+ group.at = Math.max(group.at, nowMs);
4567
4577
  state.debtGroups[id] = group;
4568
4578
  return true;
4569
4579
  }
@@ -4611,12 +4621,17 @@ function retireControlReceiptToDebt(state, resource, at) {
4611
4621
  return true;
4612
4622
  }
4613
4623
 
4624
+ // A reboot proves an unknown owner's children are gone. So does age: a group's
4625
+ // `at` is its newest charge, and once a full window has elapsed since then
4626
+ // GitHub has charged every covered request to a window that is already over.
4614
4627
  function reconcileBootDebt(state, at) {
4615
4628
  const bootId = coordinationBootId();
4616
- if (bootId === null) return { ok: true, changed: false };
4617
4629
  let changed = false;
4618
4630
  for (const group of Object.values(state.debtGroups)) {
4619
- if (group.quiescent || group.bootId === null || group.bootId === bootId) continue;
4631
+ if (group.quiescent) continue;
4632
+ const priorBoot = bootId !== null && group.bootId !== null && group.bootId !== bootId;
4633
+ const outlivedWindow = group.sealed && at - group.at >= IDENTITY_UNCERTAIN_MAX_MS;
4634
+ if (!priorBoot && !outlivedWindow) continue;
4620
4635
  if (!makeDebtGroupQuiescent(state, group, at)) {
4621
4636
  return { ok: false, reason: "accounting-overflow" };
4622
4637
  }
@@ -15633,6 +15648,8 @@ const RECOVERY_COPY = Object.freeze({
15633
15648
  "probe-failed": ["GitHub budget check failed", "Retry automatically at the shown time", "Budget check; retry"],
15634
15649
  "block-unpublished": ["Saving GitHub request limit", "Retry sharing the hold automatically", "Saving hold; retry"],
15635
15650
  "budget-reset": ["GitHub quota pacing", "Retry automatically after reset", "Quota; retry"],
15651
+ reset: ["GitHub quota pacing", "Retry automatically after reset", "Quota; retry"],
15652
+ priority: ["Background refresh waiting its turn", "Retry automatically at the next slot", "Queued; retry"],
15636
15653
  "rate-limit": ["GitHub quota pacing", "Retry automatically after reset", "Quota; retry"],
15637
15654
  "rate-limited": ["GitHub request limit", "Retry automatically after the shared hold", "Limit; retry"],
15638
15655
  "local-reserve": ["Local quota reserve pacing", "Retry automatically at the next grant", "Reserve; retry"],
@@ -20338,6 +20355,8 @@ export {
20338
20355
  GOVERNOR_PHASE_WINDOW_MS,
20339
20356
  BUDGET_PROBE_MS,
20340
20357
  MIN_SAMPLE_CALLS,
20358
+ MAX_PACING_EXTERNAL_FACTOR,
20359
+ IDENTITY_UNCERTAIN_MAX_MS,
20341
20360
  REQUEST_PRIORITIES,
20342
20361
  normalizeBudgetResource,
20343
20362
  budgetEpoch,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "gh-glance",
3
- "version": "0.16.0",
3
+ "version": "0.16.1",
4
4
  "description": "A live-refreshing GitHub dashboard for your terminal: Actions, Issues, Pull Requests, and Security alerts in one narrow pane",
5
5
  "type": "module",
6
6
  "bin": {