gh-glance 0.4.0 → 0.5.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 +209 -0
- package/README.md +88 -40
- package/index.mjs +632 -115
- package/package.json +2 -1
package/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,213 @@ All notable changes to this project are documented here.
|
|
|
5
5
|
The format follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
|
|
6
6
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
7
|
|
|
8
|
+
## [0.5.0] - 2026-08-04
|
|
9
|
+
|
|
10
|
+
Findings from a cross-functional audit, filtered hard: everything that would
|
|
11
|
+
have added a release gate, a branch-protection rule or more test-harness
|
|
12
|
+
machinery was rejected outright. What is left is behaviour you can see.
|
|
13
|
+
|
|
14
|
+
### Added
|
|
15
|
+
|
|
16
|
+
- **`?` shows the keys without leaving the dashboard.** Paging, `j`/`k`,
|
|
17
|
+
`Shift+Tab` and the cursor timeout existed only in `--help` and the README --
|
|
18
|
+
and because this is a full-screen app, reading `--help` meant quitting it
|
|
19
|
+
first. Any key closes the overlay. `--help`, the overlay and the status-bar
|
|
20
|
+
hints are now generated from one table, so a binding cannot go missing from one
|
|
21
|
+
of them.
|
|
22
|
+
- **The panel names the repository** when it was chosen explicitly through
|
|
23
|
+
`--repo` or `GH_REPO` -- `╭─ Actions · acme/widget ─`. With several panes open,
|
|
24
|
+
or after changing directory, nothing on screen said which repository a pane was
|
|
25
|
+
watching. Dropped before the tab name when the pane is too narrow for both.
|
|
26
|
+
- **`--doctor` reports API budget**: REST and GraphQL headroom straight from
|
|
27
|
+
GitHub, plus what this configuration will actually spend per hour. The steady
|
|
28
|
+
cost is not small and was invisible -- roughly 2,200 REST requests an hour at
|
|
29
|
+
the default refresh with the Security tab open, about 44% of a personal token's
|
|
30
|
+
allowance, and `--refresh 2` projects past the limit outright. `gh api
|
|
31
|
+
rate_limit` does not itself count against the limit.
|
|
32
|
+
- **Native test coverage is measured and reported.** `npm run test:coverage`
|
|
33
|
+
runs the unit suite under Node's built-in coverage, and a nightly workflow
|
|
34
|
+
publishes the figure to the portfolio endpoint. The delivery script fails
|
|
35
|
+
closed on purpose: every input is required and a parse failure is an error
|
|
36
|
+
rather than a reported zero, so a broken producer cannot quietly claim perfect
|
|
37
|
+
coverage. Not wired into branch protection -- it reports, it does not gate.
|
|
38
|
+
- **A first-run hint when icons may be blank.** Without a Nerd Font every status
|
|
39
|
+
icon renders as an empty box, which reads as a broken program rather than a
|
|
40
|
+
missing font, and the fix was documented only in places you had to quit to
|
|
41
|
+
read. Shown for the second the first fetch takes, and only when the Nerd glyphs
|
|
42
|
+
are actually in use.
|
|
43
|
+
|
|
44
|
+
### Fixed
|
|
45
|
+
|
|
46
|
+
- **The `stale` indicator no longer fires on a repository that is simply quiet.**
|
|
47
|
+
Freshness was recorded only when the payload *changed*, and the whole point of
|
|
48
|
+
the poll loop is that an unchanged payload short-circuits before that write --
|
|
49
|
+
so on any calm repo the timestamp froze and the status bar accrued a growing
|
|
50
|
+
`stale 2h13m` while every poll was succeeding on schedule. It now records the
|
|
51
|
+
last successful *poll*. The warning fired loudest in the one state that was
|
|
52
|
+
completely healthy, which is the fastest way to teach someone to ignore it.
|
|
53
|
+
- **A tab whose fetch keeps failing no longer animates forever.** `setData` only
|
|
54
|
+
runs on success, so a tab that never succeeded stayed in its first-load state
|
|
55
|
+
permanently: the spinner ran at full rate for the life of the process while the
|
|
56
|
+
body rendered "loading actions…" directly above the error explaining that it had
|
|
57
|
+
failed. Measured at 7.8% of a core and 9.8 MB/hr of terminal writes,
|
|
58
|
+
indefinitely, triggered by something as ordinary as closing a laptop lid.
|
|
59
|
+
Motion now means "still working"; the error line means "not working".
|
|
60
|
+
- **`Enter` is guarded against key repeat.** Holding it down spawned a
|
|
61
|
+
`gh <kind> view --web` per repeat event -- roughly thirty a second -- each
|
|
62
|
+
opening another browser tab. The `r` key beside it had this guard all along.
|
|
63
|
+
- **The status bar adapts to narrow panes.** It was the only band that did not:
|
|
64
|
+
the table swaps to a compact header, the tab bar to short labels, the panel
|
|
65
|
+
edges drop their labels, and the status bar just let ink truncate. Because each
|
|
66
|
+
hint truncates individually the loss was silent -- at 45 columns the bar read
|
|
67
|
+
`Move: | Open: | Refresh |Quit:…`, dropping the arrows, `Refresh`'s key, and
|
|
68
|
+
most of `Quit`, which is the one hint someone stuck in a full-screen app needs.
|
|
69
|
+
It now falls back to `↑↓ Ent r q`, which keeps every key.
|
|
70
|
+
- **`--doctor` no longer prints the value of environment variables it was never
|
|
71
|
+
told about.** It discovers every `GH_*`/`GITHUB_*` variable that is set, and
|
|
72
|
+
printed the value of any whose *name* did not end in `_TOKEN`/`_SECRET`/
|
|
73
|
+
`_PASSWORD`/`_KEY` -- so `GH_APP_PEM` (an entire RSA private key) and
|
|
74
|
+
`GITHUB_OAUTH` were reproduced in full, in the one report that says it is safe
|
|
75
|
+
to paste into a bug report. Printing a value is now opt-in and the list is
|
|
76
|
+
curated; anything discovered reports `set` or `not set`.
|
|
77
|
+
- **`--doctor --verbose` produces the log it advertises.** argv was applied to
|
|
78
|
+
runtime state in two places and they had drifted, so the doctor path silently
|
|
79
|
+
dropped `--verbose`, `--refresh` and `--tab`. There is one application site now.
|
|
80
|
+
- **The 60s cursor clear no longer costs you your place.** Clearing the selection
|
|
81
|
+
left the scroll offset behind, and the next arrow key seeded from the top of the
|
|
82
|
+
list -- so scrolling to row 80 of 150, reading for a minute and pressing down
|
|
83
|
+
put you back at row 1, with no scroll animation to notice. Movement now seeds
|
|
84
|
+
from what is on screen.
|
|
85
|
+
- **`safe()` sanitizes non-string input.** It returned early for anything that
|
|
86
|
+
was not a string, skipping both the control-character strip and the length
|
|
87
|
+
clamp -- the guarantee was being provided by GitHub's schema rather than by the
|
|
88
|
+
function that claims to provide it.
|
|
89
|
+
- **The `!` "CI is red" marker stays in the tab bar**, where a label anchors it,
|
|
90
|
+
instead of also being interpolated into the frame's bottom edge as `4 of 4!`.
|
|
91
|
+
- **A blind Security tab no longer reports a confident zero.** When all three
|
|
92
|
+
alert endpoints fail -- an expired SAML session, a token without
|
|
93
|
+
`security_events`, an org OAuth restriction -- the tab rendered
|
|
94
|
+
`4:Security (0)`, byte-identical to a genuinely clean repository, on the one
|
|
95
|
+
surface where a false all-clear is the worst available answer. It now reads
|
|
96
|
+
`(?)`. A repository that simply has Advanced Security switched off is a
|
|
97
|
+
different thing and stays quiet, because that is an answer rather than an
|
|
98
|
+
absence of one.
|
|
99
|
+
- **A failing tab backs off instead of re-spawning `gh` every tick.** The three
|
|
100
|
+
list tabs had no backoff at all, so a wedged tab launched a subprocess every
|
|
101
|
+
five seconds indefinitely -- 720 an hour against a token already refusing --
|
|
102
|
+
and rate limiting was deliberately excluded from the ladder that did exist,
|
|
103
|
+
which had it backwards: GitHub's secondary limiter keys on sustained rate
|
|
104
|
+
against a limited *token*, so hammering can turn a self-clearing limit into a
|
|
105
|
+
longer block that also hits `git push`. Measured: two `gh run list` calls in
|
|
106
|
+
forty seconds where there were eight. The `r` key bypasses and clears the
|
|
107
|
+
backoff, because a refresh that silently declines to refresh would be worse
|
|
108
|
+
than no key at all.
|
|
109
|
+
- **Errors on the Actions, Issues and PR tabs say what to do.** They rendered raw
|
|
110
|
+
`gh` stderr while the Security tab one across had been classifying the same
|
|
111
|
+
failures into remedies all along. An expired token now reads "GitHub
|
|
112
|
+
authorization failed -- try `gh auth login` or `gh auth refresh`". Unclassified
|
|
113
|
+
failures still show their real message: inventing a remedy for something
|
|
114
|
+
nobody recognised would be worse than showing what happened.
|
|
115
|
+
- **Bidi override characters are stripped from remote text.** `U+202A`-`U+202E`
|
|
116
|
+
and the isolates measure as zero columns, so they cost no width and survived
|
|
117
|
+
truncation -- one `RLO` in an issue title makes the rest of that cell render
|
|
118
|
+
reversed on any terminal with bidi reordering, which is the same "the row does
|
|
119
|
+
not show its data" failure the control-character strip already prevents.
|
|
120
|
+
Deleted rather than replaced with a space, because they measure zero and a
|
|
121
|
+
space would shift every cell to its right. Genuine RTL, `LRM`, emoji, ZWJ
|
|
122
|
+
sequences and CJK are untouched.
|
|
123
|
+
- **`REPO_PATTERN` rejects `owner/..`.** It reached the API path, and `gh`
|
|
124
|
+
forwards the dot segment unnormalized, so GitHub resolved it to a different
|
|
125
|
+
endpoint than the one intended. Names that merely contain or start with a dot
|
|
126
|
+
-- `owner/.github` -- are still valid.
|
|
127
|
+
- **Backoff deadlines use a monotonic clock.** They measure elapsed time, and a
|
|
128
|
+
laptop resume or an NTP step could hold an alert source in backoff for an hour
|
|
129
|
+
of apparent time that never passed. Staleness deliberately stays on wall-clock
|
|
130
|
+
time, because a sleep gap is exactly what it exists to report.
|
|
131
|
+
- **A crash no longer orphans `gh` children.** The handlers exited without
|
|
132
|
+
unmounting, so the cleanup that aborts in-flight subprocesses never ran. Both
|
|
133
|
+
the crash output and the `--verbose` log are now redacted, like `--doctor`
|
|
134
|
+
already was -- all three are artifacts users are told to attach to bug reports,
|
|
135
|
+
and `gh` error messages quote the URL they failed on.
|
|
136
|
+
|
|
137
|
+
### Changed
|
|
138
|
+
|
|
139
|
+
- **The spinner runs at 200ms rather than 100ms.** It is the single largest CPU
|
|
140
|
+
term in the app, because every frame makes ink rebuild and diff the whole
|
|
141
|
+
output string: measured 7.8% of a core at 100ms against 3.9% at 200ms, on a
|
|
142
|
+
0.33% idle floor. The motion is load-bearing -- it is the only thing separating
|
|
143
|
+
an executing run from a queued one -- so it is slowed, never stopped.
|
|
144
|
+
- **Only an executing Actions row receives the spinner frame.** It went to every
|
|
145
|
+
visible row, so a prop changing several times a second defeated row
|
|
146
|
+
memoisation for all of them: 7,960 row renders over 20 seconds against 238.
|
|
147
|
+
- **The panel names the repository** when it was chosen explicitly via `--repo`
|
|
148
|
+
or `GH_REPO` -- `╭─ Actions · acme/widget ─`. With several panes open, or after
|
|
149
|
+
changing directory, nothing on screen said which repository a pane was watching.
|
|
150
|
+
It is dropped before the tab name when the pane is too narrow for both.
|
|
151
|
+
- **Column density is decided per tab.** One global breakpoint meant the widest
|
|
152
|
+
tab decided for the narrowest: Pull requests needs 61 columns and Security only
|
|
153
|
+
44, so Security dropped two columns a full 17 columns before it had to. Only
|
|
154
|
+
one tab is on screen at a time, so there is nothing to be inconsistent with.
|
|
155
|
+
- **Below 24 columns the pane says "too narrow"** instead of rendering a table
|
|
156
|
+
that cannot fit. Under that width even the compact columns overflow, which
|
|
157
|
+
hard-wraps every row and drives ink into repainting the whole screen each
|
|
158
|
+
frame -- reachable just by dragging a sidebar narrow. Widening recovers
|
|
159
|
+
immediately.
|
|
160
|
+
- **The Security tab collapses its not-enabled notes into one line.** Each
|
|
161
|
+
unavailable alert source took a full row above the column header, so any
|
|
162
|
+
repository without Advanced Security permanently spent two rows -- about a
|
|
163
|
+
tenth of a twenty-row pane -- restating a fact that will never change, on the
|
|
164
|
+
tab meant to make real alerts stand out. Failures that are not "not enabled"
|
|
165
|
+
keep their own lines, because those are actionable and transient.
|
|
166
|
+
- **Alert ordering is pinned rather than left to each endpoint's default.**
|
|
167
|
+
Severity ranking runs over one page, so the page boundary decides what can be
|
|
168
|
+
ranked at all -- a critical alert sitting past it was never fetched, and the
|
|
169
|
+
pane showed "100+" with a screen of moderates. Newest-first at least makes the
|
|
170
|
+
cut deterministic.
|
|
171
|
+
- **`-v` is no longer an alias for `--version`.** This CLI also has `--verbose`,
|
|
172
|
+
so `gh-glance -v 2>log` -- what you type when you want the log -- printed a
|
|
173
|
+
version string and exited 0. The argv surface exists to make typos fail loudly,
|
|
174
|
+
and this was the one flag that failed quietly. `--version` is unaffected.
|
|
175
|
+
|
|
176
|
+
### Documentation
|
|
177
|
+
|
|
178
|
+
- **Corrected a claim this project made about itself in 0.4.0 and repeated in the
|
|
179
|
+
0.4.1 release notes.** The status bar's `↑↓` glyphs were described as "a
|
|
180
|
+
deliberate, tested exception" whose double-width rendering "fails loudly" under
|
|
181
|
+
`npm run test:pty`. No such assertion exists or could: each hint truncates
|
|
182
|
+
individually, so the failure mode is silent text loss rather than overflow, and
|
|
183
|
+
at 80 columns the panel border is 79 cells against a 54-cell status bar, so the
|
|
184
|
+
bar never sets the maximum a width check would measure. The glyphs are fine;
|
|
185
|
+
the guarantee was not real, and a comment asserting coverage that does not
|
|
186
|
+
exist is worse than an acknowledged gap.
|
|
187
|
+
- The README no longer claims every run state has a distinct glyph under
|
|
188
|
+
`NO_COLOR`. Timed-out, action-required and running share one, as do skipped,
|
|
189
|
+
neutral, stale and queued. The tab bar's `!` marker is what actually answers
|
|
190
|
+
"is CI red" without colour, and it does.
|
|
191
|
+
- `eslint.config.js` no longer describes an inline `exhaustive-deps` suppression
|
|
192
|
+
that has never existed; the rule is now an error, which it can be precisely
|
|
193
|
+
because there is nothing to suppress.
|
|
194
|
+
|
|
195
|
+
## [0.4.1] - 2026-08-04
|
|
196
|
+
|
|
197
|
+
Two fixes to the interactive surface: a selection marker that outlived its
|
|
198
|
+
usefulness, and a key hint that named the wrong keys.
|
|
199
|
+
|
|
200
|
+
### Fixed
|
|
201
|
+
|
|
202
|
+
- **The row cursor clears itself after 60s without movement.** Once you pressed
|
|
203
|
+
a movement key the selection marker stayed on screen until you quit, so a pane
|
|
204
|
+
left in the corner of a screen sat there marked at something you had stopped
|
|
205
|
+
caring about an hour ago. Any movement key rearms the timer; expiry clears the
|
|
206
|
+
cursor on every tab, not just the visible one.
|
|
207
|
+
- **The `Move` hint in the status bar reads `↑↓` rather than `jk`.** The hints
|
|
208
|
+
are otherwise strictly width-1 ASCII, because East-Asian-Ambiguous glyphs
|
|
209
|
+
measure as two columns in ink's width model and overflowed an 80-column
|
|
210
|
+
terminal once before. The arrow pair is a deliberate exception: the pty suite
|
|
211
|
+
asserts the rendered frame stays inside the terminal width, so a font that
|
|
212
|
+
renders them double-width fails there loudly instead of shifting columns
|
|
213
|
+
silently.
|
|
214
|
+
|
|
8
215
|
## [0.4.0] - 2026-08-04
|
|
9
216
|
|
|
10
217
|
Correctness on GitHub Enterprise and Enterprise Managed Users tenants, and a
|
|
@@ -309,6 +516,8 @@ engineering, security, QA and UX. What follows is what changed as a result.
|
|
|
309
516
|
- The `main` field from `package.json`. It advertised the file as importable,
|
|
310
517
|
but importing it took over the terminal or exited the host process.
|
|
311
518
|
|
|
519
|
+
[0.5.0]: https://github.com/juan294/gh-glance/releases/tag/v0.5.0
|
|
520
|
+
[0.4.1]: https://github.com/juan294/gh-glance/releases/tag/v0.4.1
|
|
312
521
|
[0.4.0]: https://github.com/juan294/gh-glance/releases/tag/v0.4.0
|
|
313
522
|
[0.3.1]: https://github.com/juan294/gh-glance/releases/tag/v0.3.1
|
|
314
523
|
[0.3.0]: https://github.com/juan294/gh-glance/releases/tag/v0.3.0
|
package/README.md
CHANGED
|
@@ -30,17 +30,19 @@ without switching to the browser.
|
|
|
30
30
|
│ │
|
|
31
31
|
│ │
|
|
32
32
|
╰───────────────────────────────────────────────────────────────── 4 of 4 ─╯
|
|
33
|
-
⣾ Fetching
|
|
33
|
+
⣾ Fetching Move: ↑↓ | Open: Ent | Refresh: r | Quit: q
|
|
34
34
|
```
|
|
35
35
|
|
|
36
36
|
> Captured from a real run at 76 columns with `GH_GLANCE_ICONS=unicode`, so the
|
|
37
37
|
> status icons render in a browser. With a Nerd Font (the default) they are
|
|
38
38
|
> Octicon glyphs instead.
|
|
39
39
|
>
|
|
40
|
-
> The `>` on the first row is the cursor.
|
|
40
|
+
> The `>` on the first row is the cursor. Three more markers appear when they
|
|
41
41
|
> apply: a `+` after a tab's count means the list was truncated by the fetch
|
|
42
|
-
> limit,
|
|
43
|
-
>
|
|
42
|
+
> limit, a `!` after the Actions count means the newest run failed — so "is CI
|
|
43
|
+
> red" is answerable without switching to that tab — and a `?` in place of the
|
|
44
|
+
> Security count means its endpoints could not be read, which is not the same
|
|
45
|
+
> as there being nothing to report.
|
|
44
46
|
|
|
45
47
|
<!-- contract:allow-emoji -- the check/cross above stand in for Nerd Font
|
|
46
48
|
Octicons the app actually draws; they are literal examples, not decoration. -->
|
|
@@ -64,20 +66,26 @@ current.
|
|
|
64
66
|
(approved / changes requested / pending), age
|
|
65
67
|
- **Security** -- open Dependabot alerts: package, summary, age, sorted with the
|
|
66
68
|
most severe first and with severity spelled out in its own column, not carried
|
|
67
|
-
by colour alone.
|
|
69
|
+
by colour alone. One page of 100 newest alerts is fetched and ranked, so on a
|
|
70
|
+
repository with more open alerts than that the ranking covers the newest 100
|
|
71
|
+
rather than everything -- the `+` marker on the count is what tells you.
|
|
68
72
|
Code scanning and secret scanning alerts are included too, on repos/plans
|
|
69
73
|
that have GitHub Advanced Security enabled -- see [Limitations](#limitations).
|
|
70
74
|
- Tab bar with live counts, pinned to the top of the pane above a divider,
|
|
71
75
|
switchable via `1`-`4`, arrow keys, or `Tab`/`Shift+Tab`
|
|
72
76
|
- `lazygit`-style panel frame: the tab name sits in the top border, the
|
|
73
77
|
visible-of-total row count in the bottom
|
|
74
|
-
- A
|
|
75
|
-
|
|
78
|
+
- A `Fetching` indicator that brightens on every refresh and animates during the
|
|
79
|
+
first load or while a workflow run is executing, so the pane says when it's
|
|
80
|
+
working without spending a line on it
|
|
76
81
|
- Status icons are real GitHub Octicons (via the Nerd Font glyph set), not emoji
|
|
77
82
|
-- with a plain-ASCII fallback for terminals without one
|
|
78
|
-
- Readable without colour: severity has its own column,
|
|
79
|
-
|
|
80
|
-
deficiency both stay navigable
|
|
83
|
+
- Readable without colour: severity has its own column, a failing newest run puts
|
|
84
|
+
a `!` on the Actions tab, and the active tab is bracketed, so `NO_COLOR=1` and
|
|
85
|
+
colour-vision deficiency both stay navigable. Run-state *glyphs* are not all
|
|
86
|
+
distinct -- timed-out, action-required and running share one, as do skipped,
|
|
87
|
+
neutral, stale and queued -- so the tab marker, not the row icon, is what
|
|
88
|
+
answers "is CI red" without colour
|
|
81
89
|
- Says when it is stale rather than showing old data silently, and marks a tab
|
|
82
90
|
whose last refresh failed
|
|
83
91
|
- Adapts row count to the terminal pane's height live, on resize
|
|
@@ -187,11 +195,19 @@ stdout isn't a terminal rather than streaming redraw frames into a pipe.
|
|
|
187
195
|
| `PgUp` / `PgDn` | Move a page at a time |
|
|
188
196
|
| `Enter` | Open the selected item in your browser |
|
|
189
197
|
| `r` | Refresh the current tab now |
|
|
198
|
+
| `?` | Show the keys without leaving the dashboard (any key closes it) |
|
|
190
199
|
| `q` / `Esc` / `Ctrl+C` | Quit |
|
|
191
200
|
|
|
192
201
|
The cursor tracks the *item*, not the row position, so it stays on what you
|
|
193
202
|
selected as new rows arrive above it. `Enter` works on Actions, Issues and Pull
|
|
194
|
-
Requests; the Security tab has no per-alert `gh` command to open.
|
|
203
|
+
Requests; the Security tab has no per-alert `gh` command to open. It clears
|
|
204
|
+
itself after 60s with no cursor movement, so a pane left idle in the corner of
|
|
205
|
+
a screen doesn't sit there marked forever -- and the next arrow key picks up
|
|
206
|
+
from what is on screen rather than jumping back to the top of the list.
|
|
207
|
+
|
|
208
|
+
When the repository was chosen explicitly, with `--repo` or `GH_REPO`, the panel
|
|
209
|
+
says so: `╭─ Actions · acme/widget ─`. That is what tells two side-by-side panes
|
|
210
|
+
apart. It is dropped before the tab name when the pane is too narrow for both.
|
|
195
211
|
|
|
196
212
|
If `gh-glance` is started without an interactive stdin (for example with stdin
|
|
197
213
|
redirected), the key handlers cannot run and the status bar shows only `Quit: ^C`
|
|
@@ -221,7 +237,7 @@ Environment variables work too, and the flags take precedence:
|
|
|
221
237
|
| `GH_TOKEN`, `GH_ENTERPRISE_TOKEN`, `GH_CONFIG_DIR` | Not read by `gh-glance` -- passed through to `gh` untouched, along with the proxy variables. `gh-glance` handles no credentials of its own |
|
|
222
238
|
| `GH_GLANCE_ICONS=unicode` | Plain ASCII status icons, for terminals without a Nerd Font |
|
|
223
239
|
| `GH_GLANCE_NO_ANIMATION=1` | Freeze the spinner — no motion at all |
|
|
224
|
-
| `NO_COLOR=1` | Disable colour. Status stays readable: severity has its own column, run
|
|
240
|
+
| `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 |
|
|
225
241
|
| `INK_SCREEN_READER=true` | Switch the renderer to a linear, unthrottled mode. The status icons carry text labels for it, but this path has not been tested against a real screen reader — treat it as unverified rather than supported. |
|
|
226
242
|
|
|
227
243
|
## GitHub Enterprise and EMU
|
|
@@ -265,36 +281,55 @@ gh-glance --doctor > report.txt
|
|
|
265
281
|
|
|
266
282
|
Collects, in one plain-text block: the `gh-glance`, Node and `gh` versions;
|
|
267
283
|
which hosts `gh` is authenticated for; how the repository target resolved and
|
|
268
|
-
from where;
|
|
269
|
-
|
|
270
|
-
|
|
284
|
+
from where; your remaining REST and GraphQL budget plus what this configuration
|
|
285
|
+
will spend per hour; the relevant environment variables; and one probe per
|
|
286
|
+
endpoint with the exact argv it sent, its outcome, and how any error was
|
|
287
|
+
classified (`unavailable`, `rate-limited`, `auth-problem` or `other`).
|
|
288
|
+
|
|
289
|
+
Add `--verbose` to get a log of every `gh` call it makes alongside the report.
|
|
271
290
|
|
|
272
291
|
It exits 0 and prints a report even when `gh` is missing or you are outside a
|
|
273
292
|
git repository -- those are conditions worth reporting rather than failing on --
|
|
274
293
|
and it works through a pipe, unlike the dashboard itself.
|
|
275
294
|
|
|
276
|
-
**
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
295
|
+
**Values are printed only for variables on a short curated list** -- the ones
|
|
296
|
+
that are the thing being diagnosed, like `GH_HOST`, `GH_REPO` and `NO_COLOR`.
|
|
297
|
+
Everything else it finds, including any `GH_*`/`GITHUB_*` variable it was never
|
|
298
|
+
told about, is reported as `set` or `not set` and never by value. On top of
|
|
299
|
+
that: anything token-shaped anywhere in the captured text is replaced, proxy and
|
|
300
|
+
remote URL credentials are stripped to scheme and host, and no API response
|
|
301
|
+
bodies are included, only their sizes. The report is safe to attach to a bug
|
|
302
|
+
report, and the same redaction covers the `--verbose` log and the message
|
|
303
|
+
printed if `gh-glance` crashes.
|
|
281
304
|
|
|
282
305
|
## Rate limit
|
|
283
306
|
|
|
284
307
|
The visible tab refreshes every 5 seconds; the other three refresh every 60
|
|
285
308
|
seconds, purely to keep their counts honest.
|
|
286
309
|
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
310
|
+
The tabs do not all draw on the same budget. Actions and Security spend REST
|
|
311
|
+
calls; Issues and Pull Requests are sorted with `--search`, which routes them
|
|
312
|
+
through GraphQL instead — a separate 5,000/hour allowance. With the default
|
|
313
|
+
5-second refresh:
|
|
314
|
+
|
|
315
|
+
| Visible tab | REST / hour | GraphQL / hour |
|
|
316
|
+
|---|---|---|
|
|
317
|
+
| Actions | ~900 | ~240 |
|
|
318
|
+
| Issues or Pull Requests | ~240 | ~1,560 |
|
|
319
|
+
| Security | ~2,220 | ~240 |
|
|
320
|
+
|
|
321
|
+
Security is the expensive one because it is three endpoints rather than one,
|
|
322
|
+
and watching it costs just under half the REST budget. You do not have to take
|
|
323
|
+
these figures on trust: `gh-glance --doctor` reports your actual remaining
|
|
324
|
+
budget alongside what your configuration projects, which matters on a GitHub
|
|
325
|
+
Enterprise tenant where the ceiling may not be 5,000 at all.
|
|
326
|
+
|
|
327
|
+
Two things pull the real number down. Any endpoint that fails in a way
|
|
328
|
+
`gh-glance` recognises backs off instead of being re-asked every tick — a
|
|
329
|
+
feature that is not enabled for the repository retries on a ladder up to an
|
|
330
|
+
hour, an authorization failure every 30 seconds, a rate limit every minute.
|
|
331
|
+
Pressing `r` clears that backoff and retries immediately. And `--refresh`
|
|
332
|
+
scales the whole figure: doubling the interval halves it.
|
|
298
333
|
|
|
299
334
|
So a pane left open all day shares the budget with your other `gh` commands
|
|
300
335
|
rather than exhausting it, but it is not free, and parking it on the Security
|
|
@@ -306,19 +341,29 @@ tab is the case worth knowing about.
|
|
|
306
341
|
- **Security tab**: code scanning and secret scanning alerts require [GitHub
|
|
307
342
|
Advanced Security](https://docs.github.com/en/code-security/getting-started/github-security-features).
|
|
308
343
|
On repos/plans without it, `gh-glance` doesn't crash or spam errors -- it
|
|
309
|
-
|
|
310
|
-
it *can* get (Dependabot alerts
|
|
311
|
-
has GHAS enabled, those alerts just
|
|
312
|
-
configuration needed.
|
|
344
|
+
says so in a single collapsed line -- `Code scanning, Secret scanning: not
|
|
345
|
+
enabled here` -- and still displays whatever it *can* get (Dependabot alerts
|
|
346
|
+
work independently of GHAS). If your repo has GHAS enabled, those alerts just
|
|
347
|
+
show up automatically -- no configuration needed.
|
|
348
|
+
|
|
349
|
+
If the alert endpoints cannot be read at all -- an expired SAML session, a
|
|
350
|
+
token without `security_events`, an org OAuth restriction -- the tab count
|
|
351
|
+
shows `?` rather than a number. A blind Security tab and a clean one are not
|
|
352
|
+
the same thing, and reporting `0` for both would be the worst available
|
|
353
|
+
answer on that particular surface.
|
|
313
354
|
- Scrolling moves through what was fetched, not through everything on GitHub.
|
|
314
355
|
Issues and Pull Requests fetch 150, so there is real range there. Actions
|
|
315
356
|
deliberately fetches about a screenful -- its cost is linear in the number of
|
|
316
357
|
runs requested -- so scrolling that tab has little to move through. The count
|
|
317
358
|
in the bottom edge always says how much you are seeing out of how much was
|
|
318
359
|
fetched.
|
|
319
|
-
- **Minimum width.**
|
|
320
|
-
|
|
321
|
-
|
|
360
|
+
- **Minimum width.** Each tab drops to a compact layout (icon, title, and one
|
|
361
|
+
other column) at its own threshold, so a narrow pane keeps as much as that
|
|
362
|
+
particular tab can fit: Security holds its full set down to 44 columns,
|
|
363
|
+
Issues to 50, Actions to 56, Pull Requests to 61. Below 24 columns nothing
|
|
364
|
+
useful fits, so the pane says `too narrow` and keeps the frame, tab bar and
|
|
365
|
+
quit hint; widening it recovers immediately. The status bar has its own
|
|
366
|
+
breakpoint and drops to bare keys (`↑↓ Ent r q`) rather than truncating.
|
|
322
367
|
- Issues and pull requests are fetched 150 at a time and alerts 100 at a time.
|
|
323
368
|
A count is shown as `n+` when it was truncated, so the number is never
|
|
324
369
|
presented as exact when it is not.
|
|
@@ -361,10 +406,13 @@ in some terminals, which would shift every column to their right.
|
|
|
361
406
|
| `none of the git remotes ... point to a known GitHub host` | `gh` is not authenticated for that host. Run `gh auth login --hostname <host>`. |
|
|
362
407
|
| Security tab empty on an enterprise host, other tabs fine | The alert endpoints were sent to the wrong host. Use `--repo host/owner/name` or set `GH_HOST` -- a host-qualified `GH_REPO` alone does not route them. |
|
|
363
408
|
| 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. |
|
|
364
|
-
| A tab's count is red | That tab's last fetch failed. The error itself is shown when you switch to it. |
|
|
409
|
+
| 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. |
|
|
410
|
+
| 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. |
|
|
411
|
+
| A failing tab seems to have stopped retrying | It backs off deliberately, rather than re-spawning `gh` every five seconds against an endpoint that is refusing. Press `r` to clear the backoff and retry now. |
|
|
412
|
+
| `unknown argument: -v` | `-v` used to mean `--version` and no longer does, because this CLI also has `--verbose`. Use `--version` or `--verbose` explicitly. |
|
|
365
413
|
| `stale 2m` in the status bar | The visible tab has not refreshed successfully for a while — usually a network drop. |
|
|
366
414
|
| It exits immediately when piped | Intentional. It is a full-screen dashboard, not a reporting command. |
|
|
367
|
-
| 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.
|
|
415
|
+
| 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. |
|
|
368
416
|
| `--verbose` refuses to start | stderr is still your terminal, where the log would draw over the dashboard. Redirect it to a file. |
|
|
369
417
|
|
|
370
418
|
## Contributing
|