gh-glance 0.11.2 → 0.12.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 +58 -1
- package/README.md +36 -13
- package/index.mjs +1588 -231
- package/package.json +2 -2
package/CHANGELOG.md
CHANGED
|
@@ -7,6 +7,62 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
7
7
|
|
|
8
8
|
## [Unreleased]
|
|
9
9
|
|
|
10
|
+
## [0.12.0] - 2026-09-06
|
|
11
|
+
|
|
12
|
+
### Added
|
|
13
|
+
|
|
14
|
+
- **Panes sharing a GitHub account now share one API budget.** Quota is keyed by
|
|
15
|
+
the verified principal and access by the effective credential, so two tokens
|
|
16
|
+
for the same account coordinate as one instead of splitting the budget in
|
|
17
|
+
half. A shared transport permit serializes HTTP starts across panes, and the
|
|
18
|
+
bootstrap allowance is persisted before a request starts, so a crash, restart
|
|
19
|
+
or manual refresh cannot replenish it.
|
|
20
|
+
|
|
21
|
+
### Changed
|
|
22
|
+
|
|
23
|
+
- **Issues and Pull Requests use explicit, bounded GraphQL documents.**
|
|
24
|
+
`gh issue list` and `gh pr list` silently routed through GraphQL at a price
|
|
25
|
+
nothing in the codebase could name -- the budget was debited from a number
|
|
26
|
+
measured by hand once and written into a constant. Both now use fixed,
|
|
27
|
+
versioned documents with typed variables on stdin, so the query never reaches
|
|
28
|
+
argv and every page declares the cost it is held to.
|
|
29
|
+
- **`gh api rate_limit` is no longer a source of spendable GraphQL capacity.**
|
|
30
|
+
A claimed observer that selects only the meter supplies capacity and reports
|
|
31
|
+
what it cost. `/rate_limit` remains a diagnostic, is labelled as one in
|
|
32
|
+
`--doctor`, and is dropped on migration rather than kept as spendable
|
|
33
|
+
evidence.
|
|
34
|
+
- **Opening a row spends no API budget.** `gh <kind> view --web` paid a request
|
|
35
|
+
to be told a URL the app already held, and had to refuse the user the page
|
|
36
|
+
when the budget was tight. URLs are admitted -- https only, matching host --
|
|
37
|
+
before reaching the platform opener.
|
|
38
|
+
|
|
39
|
+
### Fixed
|
|
40
|
+
|
|
41
|
+
- **Issues and Pull Requests worked only with an explicit `--repo`.** `gh`
|
|
42
|
+
infers the repository from the working directory and GraphQL cannot, so the
|
|
43
|
+
query variables went out half-filled without it.
|
|
44
|
+
- **Multi-page repositories leaked a tab reservation on every poll.** Settlement
|
|
45
|
+
summed all page costs even though later pages settle against their own
|
|
46
|
+
reservation, and the resulting over-settlement was rejected as corrupt --
|
|
47
|
+
discarding the budget observations from the only requests carrying real cost
|
|
48
|
+
evidence.
|
|
49
|
+
- **The budget observer's own spend was attributed to external consumers**, so
|
|
50
|
+
the governor progressively throttled real work to make room for its own
|
|
51
|
+
probing.
|
|
52
|
+
- **A contended registry lock could retract a verified identity**, blanking
|
|
53
|
+
every tab and discarding the ETags that make the next round cheap. Unknown
|
|
54
|
+
and changed are now distinct, and only a proven change discards rows.
|
|
55
|
+
- **Bootstrap attempts that never proved a principal were never retired**, so
|
|
56
|
+
the registry filled to its cap behind a captive portal and refused every
|
|
57
|
+
later bootstrap permanently, recoverable only by deleting state by hand.
|
|
58
|
+
- **Identity debt transfer wrote the ledger and registry non-atomically**, so a
|
|
59
|
+
crash could orphan a charged receipt or record a debt as transferred to a
|
|
60
|
+
ledger that never received it.
|
|
61
|
+
- **A stopped pane held the single machine-wide HTTP permit indefinitely**, as
|
|
62
|
+
it was reclaimed only on owner death.
|
|
63
|
+
- **The Open key hint was dead on every tab**, and opening a cache-hydrated row
|
|
64
|
+
did nothing because the cache dropped the row's URL.
|
|
65
|
+
|
|
10
66
|
## [0.11.2] - 2026-08-31
|
|
11
67
|
|
|
12
68
|
### Fixed
|
|
@@ -795,7 +851,8 @@ engineering, security, QA and UX. What follows is what changed as a result.
|
|
|
795
851
|
- The `main` field from `package.json`. It advertised the file as importable,
|
|
796
852
|
but importing it took over the terminal or exited the host process.
|
|
797
853
|
|
|
798
|
-
[Unreleased]: https://github.com/juan294/gh-glance/compare/v0.
|
|
854
|
+
[Unreleased]: https://github.com/juan294/gh-glance/compare/v0.12.0...HEAD
|
|
855
|
+
[0.12.0]: https://github.com/juan294/gh-glance/compare/v0.11.2...v0.12.0
|
|
799
856
|
[0.11.2]: https://github.com/juan294/gh-glance/compare/v0.11.1...v0.11.2
|
|
800
857
|
[0.11.1]: https://github.com/juan294/gh-glance/compare/v0.11.0...v0.11.1
|
|
801
858
|
[0.11.0]: https://github.com/juan294/gh-glance/compare/v0.10.0...v0.11.0
|
package/README.md
CHANGED
|
@@ -319,7 +319,7 @@ pane definition. Flags are there when you want them:
|
|
|
319
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`. |
|
|
320
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. |
|
|
321
321
|
| `--tab <name>` | Start on `actions`, `issues`, `prs` or `security`. |
|
|
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`. |
|
|
322
|
+
| `--verbose` | Log one line per dashboard `gh` call to stderr, with timing and outcome. Credential lookup and the account-identity proof are deliberately excluded, so that they cannot log anything derived from a token. stderr must be redirected: `gh-glance --verbose 2>gh-glance.log`. |
|
|
323
323
|
| `--doctor` | Print a diagnostic report and exit. See [Diagnostics](#diagnostics). |
|
|
324
324
|
|
|
325
325
|
An unrecognised flag exits 2 rather than being ignored, so a typo fails loudly.
|
|
@@ -396,21 +396,39 @@ recovery state owned by the UI, not a configuration interface.
|
|
|
396
396
|
|
|
397
397
|
### Private API governor state
|
|
398
398
|
|
|
399
|
-
API admission uses a separate
|
|
399
|
+
API admission uses a separate directory beside the cache:
|
|
400
400
|
|
|
401
401
|
```text
|
|
402
|
-
$XDG_CONFIG_HOME/gh-glance/
|
|
403
|
-
~/Library/Application Support/gh-glance/
|
|
404
|
-
~/.config/gh-glance/
|
|
402
|
+
$XDG_CONFIG_HOME/gh-glance/coordination-v2/
|
|
403
|
+
~/Library/Application Support/gh-glance/coordination-v2/
|
|
404
|
+
~/.config/gh-glance/coordination-v2/
|
|
405
405
|
```
|
|
406
406
|
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
407
|
+
It holds `registry.json`, which maps credentials to verified accounts, and one
|
|
408
|
+
`quota-<hash>.json` ledger per account. The ledger hash binds the effective
|
|
409
|
+
GitHub host to the *verified principal* -- the account kind and numeric ID that
|
|
410
|
+
GitHub itself confirmed -- rather than to whichever local `gh` configuration
|
|
411
|
+
happened to select it, so two tokens for the same account coordinate as one
|
|
412
|
+
instead of splitting the budget in half.
|
|
413
|
+
|
|
414
|
+
A ledger records only the protocol needed to coordinate panes: REST and GraphQL
|
|
415
|
+
budget observations and epochs, leases, intents, reservations, fair-lane
|
|
416
|
+
cursors, probe ownership and outcomes, and temporary rate-limit blocks. It
|
|
417
|
+
stores no token, raw host, login, repository, working directory, title, author,
|
|
418
|
+
branch, alert, or other dashboard row.
|
|
419
|
+
|
|
420
|
+
`registry.json` is the one exception, and it is deliberate: to know that two
|
|
421
|
+
credentials are the same account it stores that account's numeric ID and its
|
|
422
|
+
sanitized login, alongside private digests of the credentials themselves. No
|
|
423
|
+
token is ever written, to it or anywhere else. Ephemeral lock records contain
|
|
424
|
+
only a PID and random nonce.
|
|
425
|
+
|
|
426
|
+
Panes from an older release coordinate through the previous
|
|
427
|
+
`rate-governor-v1-<scope hash>.json` files, which this version cannot join.
|
|
428
|
+
It preserves them as evidence, refuses to activate while any of their leases is
|
|
429
|
+
still live, and waits out any unsettled charge they left behind. Closing the
|
|
430
|
+
older panes is what completes the upgrade -- gh-glance will not close them for
|
|
431
|
+
you, and deleting the files instead discards quota that is still owed.
|
|
414
432
|
|
|
415
433
|
This state has a stricter role than `dashboard-cache.json`. A missing cache can
|
|
416
434
|
be ignored because it only supplies last-good rows. Missing governor state can
|
|
@@ -692,7 +710,12 @@ GH_GLANCE_ICONS=ascii gh-glance
|
|
|
692
710
|
| 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
711
|
| 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. |
|
|
694
712
|
| It exits immediately when piped | Intentional. It is a full-screen dashboard, not a reporting command. |
|
|
695
|
-
|
|
|
713
|
+
| `Restart required: close older gh-glance panes` | A pane from an older release still holds a live lease in the previous coordination format, which this version cannot join. Quit those panes; this one resumes on its own. Nothing is killed for you, and no state needs deleting. |
|
|
714
|
+
| `Upgrade waiting for legacy quota reset` | The older panes are gone, but left spend that cannot be proven settled. It waits for the affected rate-limit window to reset rather than assume the quota is free. |
|
|
715
|
+
| `Coordination state unavailable; evidence preserved` | Coordination state could not be read and was deliberately not overwritten, so nothing is lost. Run `gh-glance --doctor` and check the config directory's permissions. |
|
|
716
|
+
| `Shared HTTP request or cooldown in progress` | Panes share one outbound request slot and one cooldown. Another pane holds it, or a server-sent `Retry-After` is still running. Normal pacing, not an error. |
|
|
717
|
+
| `Verified identity unavailable; waiting to retry` | The account behind your credential has not been confirmed yet -- not signed in, a denied or malformed proof, or a slow credential helper. Check `gh auth status`. Retries are rate-limited, so this clears on its own rather than immediately. |
|
|
718
|
+
| It stopped updating and you cannot tell why | Run `gh-glance --verbose 2>gh-glance.log`, reproduce, then read the log: one line per dashboard `gh` call with its duration and outcome. Credential lookup and the identity proof are excluded by design. It is redacted the same way `--doctor` is, so it is safe to attach to a bug report. `--doctor --verbose` logs the probes too. |
|
|
696
719
|
| `--verbose` refuses to start | stderr is still your terminal, where the log would draw over the dashboard. Redirect it to a file. |
|
|
697
720
|
|
|
698
721
|
## Contributing
|