gh-glance 0.9.1 → 0.11.0
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/CHANGELOG.md +71 -5
- package/README.md +172 -76
- package/index.mjs +4400 -519
- package/package.json +2 -2
package/CHANGELOG.md
CHANGED
|
@@ -7,6 +7,69 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
7
7
|
|
|
8
8
|
## [Unreleased]
|
|
9
9
|
|
|
10
|
+
## [0.11.0] - 2026-08-30
|
|
11
|
+
|
|
12
|
+
### Fixed
|
|
13
|
+
|
|
14
|
+
- **Manual refresh now owns exactly one fresh Actions batch.** It replaces the
|
|
15
|
+
due active-poll deadline, queues once when an automatic batch is already in
|
|
16
|
+
flight, and coalesces repeated `r` presses while that forced batch runs. This
|
|
17
|
+
prevents both a lost manual refresh and an immediate duplicate automatic
|
|
18
|
+
request.
|
|
19
|
+
- **Reset recovery no longer strands a pane that lost shared probe ownership.**
|
|
20
|
+
When the winning pane publishes between a waiter's bounded inspection and
|
|
21
|
+
its final snapshot, the waiter now adopts that locked, fresh, claim-free
|
|
22
|
+
publication instead of sleeping until the next control interval. A data wake
|
|
23
|
+
that saw the old held epoch can no longer leave its active tab on that stale
|
|
24
|
+
deadline after the new safe epoch is published.
|
|
25
|
+
|
|
26
|
+
### Changed
|
|
27
|
+
|
|
28
|
+
- **The shared governor now follows authoritative response counters.** Core
|
|
29
|
+
observations come from conditional endpoint headers and one shared `/user`
|
|
30
|
+
observer. The free `rate_limit` GraphQL counter is now documented as a known
|
|
31
|
+
open-loop input, not as an authority: live GraphQL response headers can move
|
|
32
|
+
while that endpoint remains unchanged.
|
|
33
|
+
Response accounting and reservation settlement now commit atomically, so
|
|
34
|
+
concurrent panes cannot double-charge, move an owner-established epoch, or
|
|
35
|
+
overwrite a newer budget sample.
|
|
36
|
+
- **Unchanged Actions and Security checks no longer consume REST quota.** The
|
|
37
|
+
dashboard now revalidates each REST endpoint with its cached ETag, while a
|
|
38
|
+
manual refresh still requests fresh data and new Actions runs still appear.
|
|
39
|
+
- **The footer stays calm while checks follow their safe schedule.** Scheduler
|
|
40
|
+
holds now remain Watching, grant and reset details use coarse relative
|
|
41
|
+
minutes, and a wait caused only by other local panes says `sharing N`.
|
|
42
|
+
Detail or stale text stays inside a fixed state region so key hints do not
|
|
43
|
+
move. Staleness also follows each tab's admitted request cadence.
|
|
44
|
+
- **GraphQL tolerates one unusable minute sample without a false hold.** Its
|
|
45
|
+
available observation remains probe-owned and fails closed after two missed
|
|
46
|
+
samples, but freshness does not make that counter accurate. The
|
|
47
|
+
response-header-backed core resource keeps its shorter freshness limit.
|
|
48
|
+
|
|
49
|
+
## [0.10.0] - 2026-08-19
|
|
50
|
+
|
|
51
|
+
### Fixed
|
|
52
|
+
|
|
53
|
+
- **Concurrent panes preserve a core hard reserve instead of slowing all the way
|
|
54
|
+
to exhaustion.** Local panes on one GitHub host and account now share atomic
|
|
55
|
+
grants, worst-case reservations, and one budget probe. gh-glance starts no
|
|
56
|
+
core request when its latest fresh, conservatively debited authoritative
|
|
57
|
+
sample cannot pay for it outside the final 20%. GraphQL work is locally paced
|
|
58
|
+
from its declared cost and the available `rate_limit` sample, but that sample
|
|
59
|
+
is not authoritative. Missing, corrupt, locked, or unwritable coordination
|
|
60
|
+
fails closed. REST exhaustion does not stop a GraphQL tab that its current
|
|
61
|
+
probe permits, and manual refresh cannot bypass the hold.
|
|
62
|
+
|
|
63
|
+
### Changed
|
|
64
|
+
|
|
65
|
+
- **Startup, reset, polling, and status now reflect the shared safe schedule.**
|
|
66
|
+
Stable pane phases spread startup and post-reset work, active checks precede
|
|
67
|
+
one rotating background check, and the old 60-second pacing ceiling is gone.
|
|
68
|
+
The active footer reports an explicit semantic state. Startup and manual
|
|
69
|
+
Checking animate while admitted; adapted automatic checks and non-working
|
|
70
|
+
states stay static. The next-grant detail names one current grant, not a
|
|
71
|
+
recurring interval.
|
|
72
|
+
|
|
10
73
|
## [0.9.1] - 2026-08-11
|
|
11
74
|
|
|
12
75
|
### Fixed
|
|
@@ -25,10 +88,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
25
88
|
open alerts fill the base page, then merge and de-duplicate the result. A `+`
|
|
26
89
|
marker stays explicit when any lane fills; the app never claims an unbounded
|
|
27
90
|
repository is complete.
|
|
28
|
-
- **Adaptive polling
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
91
|
+
- **Adaptive polling models both GitHub budgets separately.** Declared REST and
|
|
92
|
+
GraphQL costs, including failed calls, feed the safer interval without
|
|
93
|
+
lowering the configured refresh floor. `--doctor` reports the same model.
|
|
94
|
+
Later validation established that only REST now has an authoritative
|
|
95
|
+
response-counter feedback loop.
|
|
32
96
|
- **Terminal state has explicit non-colour and linear-rendering channels.** A
|
|
33
97
|
stable ASCII `x` marks fetch failure, selected rows include `selected` in
|
|
34
98
|
their accessibility label, narrow errors begin with the recovery action, and
|
|
@@ -712,7 +776,9 @@ engineering, security, QA and UX. What follows is what changed as a result.
|
|
|
712
776
|
- The `main` field from `package.json`. It advertised the file as importable,
|
|
713
777
|
but importing it took over the terminal or exited the host process.
|
|
714
778
|
|
|
715
|
-
[Unreleased]: https://github.com/juan294/gh-glance/compare/v0.
|
|
779
|
+
[Unreleased]: https://github.com/juan294/gh-glance/compare/v0.11.0...HEAD
|
|
780
|
+
[0.11.0]: https://github.com/juan294/gh-glance/compare/v0.10.0...v0.11.0
|
|
781
|
+
[0.10.0]: https://github.com/juan294/gh-glance/compare/v0.9.1...v0.10.0
|
|
716
782
|
[0.9.1]: https://github.com/juan294/gh-glance/compare/v0.9.0...v0.9.1
|
|
717
783
|
[0.9.0]: https://github.com/juan294/gh-glance/compare/v0.8.0...v0.9.0
|
|
718
784
|
[0.8.0]: https://github.com/juan294/gh-glance/compare/v0.7.0...v0.8.0
|
package/README.md
CHANGED
|
@@ -11,31 +11,35 @@
|
|
|
11
11
|
|
|
12
12
|
A live-refreshing GitHub dashboard that fits in a narrow terminal pane --
|
|
13
13
|
**Actions, Issues, Pull Requests, and Security alerts**, one tab at a time,
|
|
14
|
-
|
|
14
|
+
with a healthy single-pane refresh floor of 5 seconds and no flicker. Shared
|
|
15
|
+
budget coordination can schedule a later safe check when several panes or other
|
|
16
|
+
tools use the same GitHub account.
|
|
15
17
|
|
|
16
18
|
Built for pairing with a terminal multiplexer/workspace tool (e.g. a sidebar
|
|
17
19
|
pane next to your editor) where you want an always-on glance at repo activity
|
|
18
20
|
without switching to the browser.
|
|
19
21
|
|
|
20
22
|
```
|
|
21
|
-
[1:Actions (4)] 2:Issues
|
|
22
|
-
|
|
23
|
-
╭─ Actions
|
|
24
|
-
│ TITLE
|
|
25
|
-
│
|
|
26
|
-
│ >+ ci: pin actions to
|
|
27
|
-
│ x fix: restore the
|
|
28
|
-
│
|
|
29
|
-
│ - docs: update the readme
|
|
30
|
-
│
|
|
31
|
-
│
|
|
32
|
-
|
|
33
|
-
|
|
23
|
+
[1:Actions (4)] 2:Issues 3:PRs 4:Security
|
|
24
|
+
───────────────────────────────────────────────────────────────────────────
|
|
25
|
+
╭─ Actions · owner/repo ──────────────────────────────────────────────────╮
|
|
26
|
+
│ TITLE │WORKFLOW │BRANCH │TIME │UPDATED │
|
|
27
|
+
│ ─────────────────────────────────────────────────────────────────────── │
|
|
28
|
+
│ >+ ci: pin actions to com… #443 CI develop 1m20s 28d ago │
|
|
29
|
+
│ x fix: restore the prima… #442 Code… develop 1m28s 28d ago │
|
|
30
|
+
│ + chore: bump dependenci… #441 CI dependa…int-10 30s 28d ago │
|
|
31
|
+
│ - docs: update the readme #440 CI develop 15s 29d ago │
|
|
32
|
+
│ │
|
|
33
|
+
│ │
|
|
34
|
+
╰──────────────────────────────────────────────────────────────── 4 of 4 ─╯
|
|
35
|
+
· Watching Refresh: r Quit: q Move: ↑↓ Open: Ent Width: w
|
|
34
36
|
```
|
|
35
37
|
|
|
36
|
-
>
|
|
37
|
-
>
|
|
38
|
-
>
|
|
38
|
+
> Generated from this candidate's real binary under the repository PTY harness
|
|
39
|
+
> at 76 columns, using its deterministic fixture data and
|
|
40
|
+
> `GH_GLANCE_ICONS=unicode`; the repeatable command is in
|
|
41
|
+
> [CONTRIBUTING.md](./CONTRIBUTING.md). With a Nerd Font (the default), row
|
|
42
|
+
> icons are Octicon glyphs instead.
|
|
39
43
|
>
|
|
40
44
|
> The `>` on the first row is the cursor. Four more markers appear when they
|
|
41
45
|
> apply: a `+` after a tab's count means the list was truncated by the fetch
|
|
@@ -79,10 +83,13 @@ current.
|
|
|
79
83
|
mode, and preferences kept separately for each tab
|
|
80
84
|
- `lazygit`-style panel frame: the tab name sits in the top border, the
|
|
81
85
|
visible-of-total row count in the bottom
|
|
82
|
-
- A
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
+
- A semantic footer for the active tab: **Watching** is settled or scheduled;
|
|
87
|
+
**Checking** means admitted work is live; **Paused** protects a held or
|
|
88
|
+
unavailable budget; **Failed** names a normal fetch error; and **Limited**
|
|
89
|
+
means Security visibility is incomplete. Startup and manual Checking can
|
|
90
|
+
animate. Adapted automatic checks, Watching, Paused, Failed, and Limited are
|
|
91
|
+
static. A pure shared-lane wait adds `sharing N` without moving the key hints
|
|
92
|
+
- Row state icons are real GitHub Octicons (via the Nerd Font glyph set), not emoji
|
|
86
93
|
-- with a plain-ASCII fallback for terminals without one
|
|
87
94
|
- Readable without colour: severity has its own column, a failing newest run puts
|
|
88
95
|
a `!` on the Actions tab, and the active tab is bracketed, so `NO_COLOR=1` and
|
|
@@ -108,7 +115,7 @@ current.
|
|
|
108
115
|
a GitHub Enterprise or EMU tenant -- see [GitHub Enterprise and
|
|
109
116
|
EMU](#github-enterprise-and-emu))
|
|
110
117
|
- A terminal font with [Nerd Font](https://www.nerdfonts.com/) glyphs (for the
|
|
111
|
-
|
|
118
|
+
row icons to render correctly -- without one, they'll show as blank
|
|
112
119
|
boxes; see [Icons without a Nerd Font](#icons-without-a-nerd-font))
|
|
113
120
|
|
|
114
121
|
## Install
|
|
@@ -240,7 +247,7 @@ stdout isn't a terminal rather than streaming redraw frames into a pipe.
|
|
|
240
247
|
| `↑` / `↓` or `j` / `k` | Move the cursor between rows |
|
|
241
248
|
| `PgUp` / `PgDn` | Move a page at a time |
|
|
242
249
|
| `Enter` | Open the selected item, or accept an onboarding prompt |
|
|
243
|
-
| `r` |
|
|
250
|
+
| `r` | Request a current-tab refresh; a safe grant is still required. |
|
|
244
251
|
| `w` | Adjust table column widths |
|
|
245
252
|
| `?` | Show the keys without leaving the dashboard (any key closes it) |
|
|
246
253
|
| `q` / `Esc` / `Ctrl+C` | Quit (`Esc` leaves width mode) |
|
|
@@ -310,7 +317,7 @@ pane definition. Flags are there when you want them:
|
|
|
310
317
|
| Flag | Effect |
|
|
311
318
|
|---|---|
|
|
312
319
|
| `-R`, `--repo [host/]owner/name` | Watch a specific repository instead of the current directory's. Works from anywhere -- you do not need a local clone. The optional host targets a GitHub Enterprise or EMU data-residency tenant, e.g. `tenant.ghe.com/acme/widget`. |
|
|
313
|
-
| `--refresh <seconds>` |
|
|
320
|
+
| `--refresh <seconds>` | Minimum active-tab poll interval, 2-3600, default 5. Safe shared grants can make a check later; each background tab is considered about every 12 floors. |
|
|
314
321
|
| `--tab <name>` | Start on `actions`, `issues`, `prs` or `security`. |
|
|
315
322
|
| `--verbose` | Log one line per `gh` call to stderr, with timing and outcome. stderr must be redirected: `gh-glance --verbose 2>gh-glance.log`. |
|
|
316
323
|
| `--doctor` | Print a diagnostic report and exit. See [Diagnostics](#diagnostics). |
|
|
@@ -321,13 +328,14 @@ Environment variables work too, and the flags take precedence:
|
|
|
321
328
|
|
|
322
329
|
| Variable | Effect |
|
|
323
330
|
|---|---|
|
|
324
|
-
| `GH_REPO=owner/name` | Watch a specific repository instead of the current directory's. A
|
|
325
|
-
| `GH_HOST=<host>` |
|
|
326
|
-
| `GH_TOKEN`, `GITHUB_TOKEN`, `GH_ENTERPRISE_TOKEN`, `GITHUB_ENTERPRISE_TOKEN` | Used by `gh`. gh-glance never logs or stores these values, but hashes each set value locally as part of the account-scoped cache
|
|
327
|
-
| `GH_CONFIG_DIR` | Selects `gh`'s account configuration and contributes its normalized identity to the cache
|
|
328
|
-
| `GH_GLANCE_REFRESH=<seconds>` |
|
|
329
|
-
| `GH_GLANCE_ICONS=unicode` |
|
|
330
|
-
| `
|
|
331
|
+
| `GH_REPO=[host/]owner/name` | Watch a specific repository instead of the current directory's. A qualified value supplies the host; an unqualified value means `github.com`. An explicit `--repo` wins. |
|
|
332
|
+
| `GH_HOST=<host>` | When no explicit `--repo` overrides it, send every call and the account governor to a GitHub Enterprise or EMU host instead of `github.com`. |
|
|
333
|
+
| `GH_TOKEN`, `GITHUB_TOKEN`, `GH_ENTERPRISE_TOKEN`, `GITHUB_ENTERPRISE_TOKEN` | Used by `gh`. gh-glance never logs or stores these values, but hashes each set value locally as part of the account-scoped cache and governor namespaces so panes with different credentials cannot share rows or admission. The raw values are not written to disk. |
|
|
334
|
+
| `GH_CONFIG_DIR` | Selects `gh`'s account configuration and contributes its normalized identity to the cache and governor namespaces. Separate values can isolate simultaneous panes on different accounts; see [No account pinning](#limitations). |
|
|
335
|
+
| `GH_GLANCE_REFRESH=<seconds>` | Minimum active-tab poll interval, 2-3600. Sets the floor for every pane in a shell; `--refresh` takes precedence. See [Rate limit](#rate-limit). |
|
|
336
|
+
| `GH_GLANCE_ICONS=unicode` | Unicode status glyphs and single-cell text substitutes for Nerd Font row icons |
|
|
337
|
+
| `GH_GLANCE_ICONS=ascii` | ASCII-only status and row icons |
|
|
338
|
+
| `GH_GLANCE_NO_ANIMATION=1` | Stop status and run-state motion. Semantic words such as Watching, Checking, and Paused still report what is happening. |
|
|
331
339
|
| `NO_COLOR=1` | Disable colour. Status stays readable: severity has its own column, a failing newest run puts a `!` on the Actions tab, and the active tab is bracketed. Note that run-state glyphs are not all distinct -- see the feature list above |
|
|
332
340
|
| `INK_SCREEN_READER=true` | Switch the renderer to a linear, unthrottled mode. Automated PTY coverage checks that status and selection labels reach this Ink path, but it has not been validated with real assistive technology — treat it as automated rendering coverage, not claimed screen-reader support. |
|
|
333
341
|
|
|
@@ -386,6 +394,31 @@ The cache merges independent targets and tabs, while preferences merge columns,
|
|
|
386
394
|
so simultaneous panes do not overwrite one another's unrelated state. It is
|
|
387
395
|
recovery state owned by the UI, not a configuration interface.
|
|
388
396
|
|
|
397
|
+
### Private API governor state
|
|
398
|
+
|
|
399
|
+
API admission uses a separate file beside the cache:
|
|
400
|
+
|
|
401
|
+
```text
|
|
402
|
+
$XDG_CONFIG_HOME/gh-glance/rate-governor-v1-<scope hash>.json
|
|
403
|
+
~/Library/Application Support/gh-glance/rate-governor-v1-<scope hash>.json
|
|
404
|
+
~/.config/gh-glance/rate-governor-v1-<scope hash>.json
|
|
405
|
+
```
|
|
406
|
+
|
|
407
|
+
The hash binds the effective GitHub host to the local `gh` account namespace
|
|
408
|
+
without putting either raw value in the file name. The file records only the
|
|
409
|
+
protocol needed to coordinate panes: REST and GraphQL budget observations and
|
|
410
|
+
epochs, leases, intents, reservations, fair-lane cursors, probe ownership and
|
|
411
|
+
outcomes, and temporary rate-limit blocks. It stores no token, raw host, login,
|
|
412
|
+
repository, working directory, title, author, branch, alert, or other dashboard
|
|
413
|
+
row. Ephemeral lock records contain only a PID and random nonce.
|
|
414
|
+
|
|
415
|
+
This state has a stricter role than `dashboard-cache.json`. A missing cache can
|
|
416
|
+
be ignored because it only supplies last-good rows. Missing governor state can
|
|
417
|
+
be initialized under its private lock, but corrupt, stale, locked, or unwritable
|
|
418
|
+
coordination fails closed: quota-consuming calls wait or pause instead of
|
|
419
|
+
falling back to independent polling. On POSIX systems the directory is `0700`,
|
|
420
|
+
and governor, temporary, lock, recovery, and quarantine files are `0600`.
|
|
421
|
+
|
|
389
422
|
## GitHub Enterprise and EMU
|
|
390
423
|
|
|
391
424
|
**The common case needs no configuration.** Authenticate once --
|
|
@@ -408,11 +441,19 @@ The `[host/]owner/name` form is the same one `gh --repo` accepts. The host must
|
|
|
408
441
|
contain a dot, so `owner/name/extra` is still rejected as the typo it is rather
|
|
409
442
|
than read as a request to a host named `owner`.
|
|
410
443
|
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
`
|
|
415
|
-
|
|
444
|
+
**Every call and its governor use one effective host.** Resolution is explicit
|
|
445
|
+
and fail-closed: an explicit `--repo host/owner/name` uses that host, while an
|
|
446
|
+
explicit unqualified `--repo owner/name` means `github.com` even when `GH_HOST`
|
|
447
|
+
or `GH_REPO` is also set. Without `--repo`, `GH_HOST` is next, followed by a
|
|
448
|
+
qualified or unqualified `GH_REPO`, then one unambiguous host found across all
|
|
449
|
+
local remotes. An invalid present `GH_HOST`, or ambiguous remotes with no
|
|
450
|
+
explicit choice, cannot silently fall through to another server.
|
|
451
|
+
|
|
452
|
+
The resolved host routes list commands, alert endpoints, the free rate-limit
|
|
453
|
+
probe, and the shared account governor together. This corrects `gh api`'s native
|
|
454
|
+
behavior for host-qualified `GH_REPO`: gh-glance adds the required `--hostname`
|
|
455
|
+
itself. A running pane also rechecks the active account namespace and moves to a
|
|
456
|
+
fresh closed scope after `gh auth switch`, before it can receive another grant.
|
|
416
457
|
|
|
417
458
|
**SAML sessions expire.** When an enterprise session lapses, the endpoints
|
|
418
459
|
answer 403 and the tab shows the real `gh` message. Re-authorize in the browser
|
|
@@ -427,11 +468,21 @@ gh-glance --doctor > report.txt
|
|
|
427
468
|
|
|
428
469
|
Collects, in one plain-text block: the `gh-glance`, Node and `gh` versions;
|
|
429
470
|
which hosts `gh` is authenticated for; how the repository target resolved and
|
|
430
|
-
from where; your remaining REST and GraphQL budget plus
|
|
431
|
-
|
|
432
|
-
`Repository access` probe; and each bounded dashboard
|
|
433
|
-
Security priority lanes, with the exact argv it sent, its
|
|
434
|
-
error was classified (`unavailable`, `rate-limited`,
|
|
471
|
+
from where; your remaining REST and GraphQL budget plus the configuration's
|
|
472
|
+
unpaced cost projection; shared governor health; the relevant environment
|
|
473
|
+
variables; a read-only `Repository access` probe; and each bounded dashboard
|
|
474
|
+
probe, including the Security priority lanes, with the exact argv it sent, its
|
|
475
|
+
outcome, and how any error was classified (`unavailable`, `rate-limited`,
|
|
476
|
+
`auth-problem` or `other`).
|
|
477
|
+
|
|
478
|
+
Doctor first makes one free `rate_limit` request to the effective host. It then
|
|
479
|
+
uses an ephemeral governor lease and admits every quota-consuming endpoint at
|
|
480
|
+
its exact declared cost. A probe whose safe slot is later, whose resource is
|
|
481
|
+
held, or whose budget is unavailable is reported as `SKIPPED`; diagnostics do
|
|
482
|
+
not bypass the reserve. The `API governor` section reports `healthy`, `waiting
|
|
483
|
+
for probe`, `stale`, `blocked`, or `unavailable`, plus the number of live leases
|
|
484
|
+
and each resource's remaining calls, hard reserve, and reset. It does not print
|
|
485
|
+
the scope hash, account identity, state path, lock owner, or reservation IDs.
|
|
435
486
|
|
|
436
487
|
The `Repository access` probe shows whether the target resolves for the active
|
|
437
488
|
`gh` credentials. A failed GitHub resolution response cannot distinguish a
|
|
@@ -456,13 +507,18 @@ printed if `gh-glance` crashes.
|
|
|
456
507
|
|
|
457
508
|
## Rate limit
|
|
458
509
|
|
|
459
|
-
The
|
|
460
|
-
|
|
510
|
+
The default five seconds is a healthy single-pane floor, not an unconditional
|
|
511
|
+
request frequency. Each check first needs an atomic grant from the private
|
|
512
|
+
governor shared by local panes using the same effective host and account
|
|
513
|
+
namespace. The active tab is considered at its floor. One rotating inactive tab
|
|
514
|
+
is considered every four floors, so each of the three background tabs is
|
|
515
|
+
considered about every 12 floors without starting them together.
|
|
461
516
|
|
|
462
|
-
The
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
517
|
+
The resources are independent. Actions and Security spend REST `core` calls;
|
|
518
|
+
Issues and Pull Requests are sorted with `--search`, which routes them through
|
|
519
|
+
GraphQL. The following table is the conservative demand before shared pacing,
|
|
520
|
+
not a promise that the governor will start every listed request. At the default
|
|
521
|
+
floor:
|
|
466
522
|
|
|
467
523
|
| Visible tab | REST / hour | GraphQL / hour |
|
|
468
524
|
|---|---|---|
|
|
@@ -475,16 +531,47 @@ full uses the three base endpoint calls and lands near 2,280 REST requests per
|
|
|
475
531
|
hour. A full page activates bounded critical/high lanes for Dependabot and code
|
|
476
532
|
scanning, raising the safe projection to about 4,440. Actions is not cheap
|
|
477
533
|
either: one `gh run list` issues two REST requests. `gh-glance --doctor` reports
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
be 5,000.
|
|
534
|
+
this projection beside the server's actual REST and GraphQL budgets. Enterprise
|
|
535
|
+
ceilings can differ from 5,000.
|
|
481
536
|
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
537
|
+
For each resource, gh-glance calculates 20% of the reported limit for other work:
|
|
538
|
+
|
|
539
|
+
```text
|
|
540
|
+
reserve = ceil(limit * 0.2)
|
|
541
|
+
spendable = max(0, remaining - reserve - charged reservations)
|
|
542
|
+
```
|
|
543
|
+
|
|
544
|
+
That is 1,000 calls for a normal 5,000-call resource. Before any quota-consuming
|
|
545
|
+
`gh` process starts, its declared worst-case REST/GraphQL cost must fit inside
|
|
546
|
+
the latest fresh local observation without entering the calculated reserve. A
|
|
547
|
+
grant is charged immediately, then reconciled only when completion evidence
|
|
548
|
+
proves a lower cost.
|
|
549
|
+
Started, interrupted, or process-lost work stays conservative until a later
|
|
550
|
+
clean probe can account for it. Missing, stale, corrupt, locked, or unwritable
|
|
551
|
+
coordination denies the call instead of returning to five-second polling.
|
|
552
|
+
|
|
553
|
+
Core observations come from real response headers, so the core reserve has a
|
|
554
|
+
closed feedback loop. GraphQL is currently weaker: `gh issue` and `gh pr` do
|
|
555
|
+
not expose response headers in their normal output, and the free `rate_limit`
|
|
556
|
+
endpoint can remain unchanged while real GraphQL use rises. gh-glance therefore
|
|
557
|
+
paces its declared local GraphQL work and fails closed on a missing or stale
|
|
558
|
+
probe, but it cannot yet prove the account-wide GraphQL reserve.
|
|
559
|
+
|
|
560
|
+
One pane owns the free `rate_limit` probe for a control window and publishes it
|
|
561
|
+
for the others. Manual and diagnostic work is considered before tab-switch,
|
|
562
|
+
active, and background work; equal-priority panes rotate fairly. Manual `r`
|
|
563
|
+
coalesces repeated presses, gives immediate Watching or Paused feedback, and
|
|
564
|
+
clears an endpoint backoff only after admission. It cannot bypass a held budget
|
|
565
|
+
or force a request into the reserve.
|
|
566
|
+
|
|
567
|
+
The shared lane uses spendable capacity, time to reset, outstanding
|
|
568
|
+
reservations, and observed external spend. Startup and each new reset epoch add
|
|
569
|
+
a stable per-pane phase, so panes do not resume as a herd. There is no
|
|
570
|
+
60-second maximum: if the next safe slot is farther away, the pane waits that
|
|
571
|
+
long. `next 2m` is the coarse time until one current grant, not a promise of a
|
|
572
|
+
recurring polling interval. When another live local pane alone owns the lane
|
|
573
|
+
ahead of this pane, the detail says `sharing N` instead. The detail is capped
|
|
574
|
+
at `99m+`.
|
|
488
575
|
|
|
489
576
|
When a refresh fails, the last successful rows stay visible below the live
|
|
490
577
|
error instead of disappearing. If gh-glance is restarted while GitHub is still
|
|
@@ -493,18 +580,16 @@ age remains explicit through the `stale` label, and the rate-limit banner still
|
|
|
493
580
|
describes the current failed request; cached data never turns a failure into a
|
|
494
581
|
false success.
|
|
495
582
|
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
between panes: the token's own counter is what they all read, so it also notices
|
|
503
|
-
a `gh pr checks --watch` or anything else spending on the same token.
|
|
583
|
+
The enforceable boundary is local admission from fresh, conservatively debited
|
|
584
|
+
evidence. Another program can spend after the probe, and panes on another
|
|
585
|
+
machine or in a different local account scope cannot share this file. GitHub
|
|
586
|
+
does not offer an atomic global quota reservation. The token-wide counter still
|
|
587
|
+
lets gh-glance measure external use and reduce future capacity, but the hard
|
|
588
|
+
reserve is not a claim that unrelated consumers can never cross it.
|
|
504
589
|
|
|
505
590
|
`GH_GLANCE_REFRESH=30` sets a wider floor for every pane in a shell; `--refresh`
|
|
506
|
-
still wins per pane.
|
|
507
|
-
|
|
591
|
+
still wins per pane. A single pane on a healthy budget normally stays at its
|
|
592
|
+
floor and shows Watching between checks.
|
|
508
593
|
|
|
509
594
|
## Limitations
|
|
510
595
|
|
|
@@ -559,20 +644,26 @@ a single pane on a healthy budget stays at 5 seconds and shows no badge.
|
|
|
559
644
|
|
|
560
645
|
### Icons without a Nerd Font
|
|
561
646
|
|
|
562
|
-
The
|
|
647
|
+
The row icons are Octicon glyphs from the [Nerd
|
|
563
648
|
Fonts](https://www.nerdfonts.com/) private-use-area range. If your terminal
|
|
564
|
-
font isn't a Nerd Font they render as blank boxes -- which would leave
|
|
649
|
+
font isn't a Nerd Font they render as blank boxes -- which would leave row state
|
|
565
650
|
carried by the colour of a blank box, and by nothing at all under `NO_COLOR`.
|
|
566
651
|
|
|
567
|
-
Set `GH_GLANCE_ICONS=unicode` for
|
|
652
|
+
Set `GH_GLANCE_ICONS=unicode` for Unicode status glyphs and single-cell text
|
|
653
|
+
substitutes for the Nerd Font row icons:
|
|
568
654
|
|
|
569
655
|
```bash
|
|
570
656
|
GH_GLANCE_ICONS=unicode gh-glance
|
|
571
657
|
```
|
|
572
658
|
|
|
573
|
-
|
|
574
|
-
and `✗`, because those are East-Asian-Ambiguous width and render two cells
|
|
575
|
-
in some terminals
|
|
659
|
+
The row substitutes are deliberately single-cell ASCII rather than symbols like
|
|
660
|
+
`✓` and `✗`, because those are East-Asian-Ambiguous width and render two cells
|
|
661
|
+
wide in some terminals. Use `GH_GLANCE_ICONS=ascii` when the status glyphs must
|
|
662
|
+
also stay within plain ASCII:
|
|
663
|
+
|
|
664
|
+
```bash
|
|
665
|
+
GH_GLANCE_ICONS=ascii gh-glance
|
|
666
|
+
```
|
|
576
667
|
|
|
577
668
|
## Troubleshooting
|
|
578
669
|
|
|
@@ -585,16 +676,21 @@ in some terminals, which would shift every column to their right.
|
|
|
585
676
|
| `Repository not found or inaccessible to the active gh account` | The active identity cannot resolve the target. Check `gh auth status`, `git remote -v` or the explicit `--repo`, and use `gh auth switch` only if the wrong account is active. |
|
|
586
677
|
| `GraphQL: Could not resolve to a Repository...` in older gh-glance versions | The response has the same ambiguity: a missing or renamed target, or a private repository not visible to the active account. Run `gh-glance --doctor`. |
|
|
587
678
|
| Actions says `not available for this repository` while Repository access is `ok` | The repository resolved, but that endpoint is unavailable; inspect the corresponding doctor block. |
|
|
588
|
-
|
|
|
679
|
+
| Row icons are blank boxes | Your terminal font is not a Nerd Font. Use `GH_GLANCE_ICONS=unicode`. |
|
|
589
680
|
| Security tab shows a "not enabled" note | Code scanning and secret scanning need GitHub Advanced Security. Dependabot alerts work independently. The note now appears only when the feature genuinely is unavailable: auth, SSO and network failures show the real error instead. |
|
|
590
681
|
| `none of the git remotes ... point to a known GitHub host` | `gh` is not authenticated for that host. Run `gh auth login --hostname <host>`. |
|
|
591
|
-
| Security tab empty on an enterprise host
|
|
682
|
+
| Security tab empty on an enterprise host in an older gh-glance version | Older versions could route alert endpoints separately. Current gh-glance routes every API call and the governor to one effective host; use `--repo host/owner/name`, `GH_HOST`, or a qualified `GH_REPO`, then confirm the resolved host with `--doctor`. |
|
|
592
683
|
| Tabs start failing after working for a while | The enterprise SAML session lapsed. Re-authorize in the browser; the dashboard recovers within about 30 seconds. Run `gh-glance --doctor` to confirm. |
|
|
593
684
|
| A tab's count is red | That tab's last fetch failed. The error itself is shown when you switch to it, translated into what to do about it where `gh-glance` recognises the failure. |
|
|
594
685
|
| Security tab shows `?` instead of a number | The alert endpoints could not be read at all -- an expired SAML session, a token without `security_events`, or an org OAuth restriction. `?` means "unknown", not "zero"; run `gh-glance --doctor` to see which probe failed and how it was classified. |
|
|
595
|
-
|
|
|
686
|
+
| `Watching` with `next 2m` | The active tab has a shared budget probe or safe grant scheduled. The interval names this grant only; it is not a recurring polling interval. Pressing `r` raises safe priority but cannot bypass the lane or reserve. |
|
|
687
|
+
| `Watching` with `sharing 4` | Four local panes share this account governor, and another pane owns the lane immediately ahead of this grant. This is pacing, not quota scarcity. |
|
|
688
|
+
| `Paused` with a reset time | The active tab's REST or GraphQL resource is at its reserve, exhausted, or under a shared rate-limit block. Wait for the stated reset/probe. Other tabs can continue when they use the healthy resource. |
|
|
689
|
+
| `Paused` without a reset time | Budget or coordinator evidence is unknown, corrupt, locked, or unwritable. No data call is started. Run `gh-glance --doctor`; also check the config directory permissions and whether another live process owns its private lock. |
|
|
690
|
+
| A failing tab seems to have stopped retrying | Recognized endpoint failures back off rather than re-spawning `gh` at the floor. Press `r` to request a higher-priority retry; the backoff clears only after a safe grant, so the tab remains Watching or Paused. |
|
|
596
691
|
| `unknown argument: -v` | `-v` used to mean `--version` and no longer does, because this CLI also has `--verbose`. Use `--version` or `--verbose` explicitly. |
|
|
597
|
-
| `stale 2m`
|
|
692
|
+
| Cached rows plus `Paused` and `stale 2m` | The rows came from the separate last-known-good dashboard cache, while the live request is blocked or unsafe. Stale age is not extended by a pause. The error and footer describe current coordination; cached data never means the live check succeeded. |
|
|
693
|
+
| Repeated GitHub rate-limit messages | A classified rate-limit response is published as one shared resource block. Local panes make no data retry before that block's probe/reset deadline. Use `--doctor` to inspect the resource and reset; repeated manual refresh cannot override it. |
|
|
598
694
|
| It exits immediately when piped | Intentional. It is a full-screen dashboard, not a reporting command. |
|
|
599
695
|
| It stopped updating and you cannot tell why | Run `gh-glance --verbose 2>gh-glance.log`, reproduce, then read the log: one line per `gh` call with its duration and outcome. It is redacted the same way `--doctor` is, so it is safe to attach to a bug report. `--doctor --verbose` logs the probes too. |
|
|
600
696
|
| `--verbose` refuses to start | stderr is still your terminal, where the log would draw over the dashboard. Redirect it to a file. |
|