gh-glance 0.15.2 → 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.
- package/CHANGELOG.md +69 -1
- package/README.md +76 -25
- package/index.mjs +2257 -501
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -7,6 +7,72 @@ 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
|
+
|
|
26
|
+
## [0.16.0] - 2026-10-01
|
|
27
|
+
|
|
28
|
+
### Changed
|
|
29
|
+
|
|
30
|
+
- Default to `--background on-demand`: automatically update active Actions,
|
|
31
|
+
check secondary tabs when opened or refreshed, and retain cached results with
|
|
32
|
+
visible source age. Keep `all` and `off` for continuous polling.
|
|
33
|
+
|
|
34
|
+
### Added
|
|
35
|
+
|
|
36
|
+
- Add a strict 24-hour freshness monitor with a fixed candidate hash, declared
|
|
37
|
+
pane cohort and cadence, source-clock checks, process-liveness checks, and
|
|
38
|
+
independently captured provider-hold evidence. Earlier monitor manifests
|
|
39
|
+
remain available for diagnostics but cannot qualify a run.
|
|
40
|
+
- Add a deterministic 72-hour request and governor oracle with repeated quota
|
|
41
|
+
resets, persistent pane cohorts, interrupted requests, and a completion-write
|
|
42
|
+
retry that reconciles charges without repeating HTTP requests.
|
|
43
|
+
|
|
44
|
+
### Fixed
|
|
45
|
+
|
|
46
|
+
- Recover automatically from full or aged quota receipt stores and acquisition
|
|
47
|
+
uncertainty while preserving retained charges and cached data.
|
|
48
|
+
- Allow up to three admitted HTTP requests per host while retaining FIFO starts,
|
|
49
|
+
shared pacing, quota reserves and provider backoff. Renew queued lease ownership
|
|
50
|
+
within the original request deadline.
|
|
51
|
+
- Keep active Actions progressing while a slower secondary response is in flight.
|
|
52
|
+
- Read shared acquisition snapshots consistently during concurrent publication.
|
|
53
|
+
- Retain requested collector refreshes through connection setup and welcome.
|
|
54
|
+
- Advance the displayed cached source age while secondary views are idle,
|
|
55
|
+
without requesting another observation.
|
|
56
|
+
- Preserve diagnostic recovery notices until a matching guarded write proves
|
|
57
|
+
recovery, and tolerate event-clock rollback without discarding journal evidence.
|
|
58
|
+
- Preserve bounded Core and GraphQL recovery causes across observer handoffs and
|
|
59
|
+
show the next action and truthful cached source age in normal, narrow,
|
|
60
|
+
no-color, and screen-reader output.
|
|
61
|
+
- Let plain `--doctor` inspect a unique cached quota scope without GitHub calls
|
|
62
|
+
or state writes. Report bounded receipt/debt and recovery diagnostics while
|
|
63
|
+
withholding credential and quota fingerprints.
|
|
64
|
+
- Keep legacy and interrupted request charges until causal observer evidence
|
|
65
|
+
can retire them; the diagnostic journal does not grant or refund quota.
|
|
66
|
+
|
|
67
|
+
### Migration
|
|
68
|
+
|
|
69
|
+
- Restart every pane sharing coordination state with the upgraded binary;
|
|
70
|
+
mixed-version coordination is unsupported.
|
|
71
|
+
An older live transport request must drain before registry migration, and older
|
|
72
|
+
writers are fenced afterward. Retained quota charges are preserved.
|
|
73
|
+
- Rolling back to v0.15.2 cannot restore operation against the newer ledger.
|
|
74
|
+
Use a compatible repaired version and retain the current accounting state.
|
|
75
|
+
|
|
10
76
|
## [0.15.2] - 2026-09-24
|
|
11
77
|
|
|
12
78
|
### Fixed
|
|
@@ -1166,7 +1232,9 @@ engineering, security, QA and UX. What follows is what changed as a result.
|
|
|
1166
1232
|
- The `main` field from `package.json`. It advertised the file as importable,
|
|
1167
1233
|
but importing it took over the terminal or exited the host process.
|
|
1168
1234
|
|
|
1169
|
-
[Unreleased]: https://github.com/juan294/gh-glance/compare/v0.
|
|
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
|
|
1237
|
+
[0.16.0]: https://github.com/juan294/gh-glance/compare/v0.15.2...v0.16.0
|
|
1170
1238
|
[0.15.2]: https://github.com/juan294/gh-glance/compare/v0.15.1...v0.15.2
|
|
1171
1239
|
[0.15.1]: https://github.com/juan294/gh-glance/compare/v0.15.0...v0.15.1
|
|
1172
1240
|
[0.15.0]: https://github.com/juan294/gh-glance/compare/v0.14.1...v0.15.0
|
package/README.md
CHANGED
|
@@ -84,10 +84,11 @@ current.
|
|
|
84
84
|
- `lazygit`-style panel frame: the tab name sits in the top border, the
|
|
85
85
|
visible-of-total row count in the bottom
|
|
86
86
|
- A semantic footer for the active tab: **Watching** is settled or scheduled;
|
|
87
|
+
**Cached** shows a secondary view's source age until its next requested refresh;
|
|
87
88
|
**Checking** means admitted work is live; **Paused** protects a held or
|
|
88
89
|
unavailable budget; **Failed** names a normal fetch error; and **Limited**
|
|
89
90
|
means Security visibility is incomplete. Startup and manual Checking can
|
|
90
|
-
animate. Adapted automatic checks, Watching, Paused, Failed, and Limited are
|
|
91
|
+
animate. Adapted automatic checks, Watching, Cached, Paused, Failed, and Limited are
|
|
91
92
|
static. A pure shared-lane wait adds `sharing N` without moving the key hints
|
|
92
93
|
- Row state icons are real GitHub Octicons (via the Nerd Font glyph set), not emoji
|
|
93
94
|
-- with a plain-ASCII fallback for terminals without one
|
|
@@ -319,9 +320,9 @@ pane definition. Flags are there when you want them:
|
|
|
319
320
|
| Flag | Effect |
|
|
320
321
|
|---|---|
|
|
321
322
|
| `-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`. |
|
|
322
|
-
| `--refresh <seconds>` | Minimum
|
|
323
|
+
| `--refresh <seconds>` | Minimum automatic poll interval, 2-3600, default 5. A floor, never a ceiling: a tab whose content is unchanged twice in a row slows to 30 seconds (60 for Security), and Actions with a running or queued job is checked every 5. Safe shared grants can make any check later. |
|
|
323
324
|
| `--tab <name>` | Start on `actions`, `issues`, `prs` or `security`. |
|
|
324
|
-
| `--background <mode>` | `
|
|
325
|
+
| `--background <mode>` | `on-demand` (default): active Actions updates automatically; Issues, PRs and Security use cached data and check when opened or refreshed with `r`. Unopened tabs make no data requests. `all` continuously polls active and inactive tabs; `off` continuously polls only the selected tab. |
|
|
325
326
|
| `--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`. |
|
|
326
327
|
| `--doctor` | Print a diagnostic report and exit. See [Diagnostics](#diagnostics). |
|
|
327
328
|
| `--doctor --probe` | Add bounded, admitted GitHub capability probes to the local diagnostic report. |
|
|
@@ -721,6 +722,13 @@ secondary limits, disconnected acquisition, shared producer waits, and local
|
|
|
721
722
|
coordination. Doctor checks acquisition metadata, referenced snapshot artifacts,
|
|
722
723
|
and the lock path separately. A readable metadata file does not make an aged
|
|
723
724
|
orphan lock or invalid snapshot healthy; plain doctor never repairs either.
|
|
725
|
+
When one cached identity names the selected host, plain doctor also reads its
|
|
726
|
+
quota ledger without changing it or contacting GitHub. It reports receipt and
|
|
727
|
+
debt totals, observer age, the current recovery cause, and an actual retry time
|
|
728
|
+
when one is known. If several cached identities match, it says the scope is
|
|
729
|
+
unavailable instead of choosing an account. For a corrupt or unreadable quota
|
|
730
|
+
file, it names the coordination directory and a `quota-[redacted].json` file
|
|
731
|
+
pattern with the cause. The private quota fingerprint stays out of reports.
|
|
724
732
|
|
|
725
733
|
Use `gh-glance --doctor --probe` when live capability evidence is needed. Probe
|
|
726
734
|
mode uses an ephemeral governor lease and admits every quota-consuming endpoint
|
|
@@ -730,8 +738,9 @@ classification (`unavailable`, `rate-limited`, `auth-problem` or `other`). A
|
|
|
730
738
|
probe whose safe slot is later, whose resource is held, or whose budget is
|
|
731
739
|
unavailable is reported as `SKIPPED`; diagnostics do not bypass the reserve.
|
|
732
740
|
The `API governor` section then reports its measured health and resource state.
|
|
733
|
-
Neither mode prints scope hashes, account identity keys,
|
|
734
|
-
owners, reservation IDs, response bodies, or credentials.
|
|
741
|
+
Neither mode prints scope hashes, account identity keys, quota fingerprints,
|
|
742
|
+
lock owners, reservation IDs, response bodies, or credentials. The redacted
|
|
743
|
+
state-file location above is shown only when local recovery needs it.
|
|
735
744
|
|
|
736
745
|
The `Repository access` probe shows whether the target resolves for the active
|
|
737
746
|
`gh` credentials. A failed GitHub resolution response cannot distinguish a
|
|
@@ -761,7 +770,15 @@ The default five seconds is a healthy single-pane floor, not an unconditional
|
|
|
761
770
|
request frequency. Each check first needs an atomic grant from the private
|
|
762
771
|
governor shared by local panes using the same effective host and account
|
|
763
772
|
namespace. Beyond that floor, the cadence follows what the repository is
|
|
764
|
-
actually doing
|
|
773
|
+
actually doing. By default only active Actions polls automatically. Secondary
|
|
774
|
+
views show Cached with source age after their requested observation; open the tab
|
|
775
|
+
or press `r` to check again. Opening can reuse a fresh shared snapshot. An
|
|
776
|
+
outstanding request continues through admission delays and transient failures.
|
|
777
|
+
Cached tab counts are last known values, not live counts. `--background all`
|
|
778
|
+
restores continuous polling of all tabs; `--background off` continuously polls
|
|
779
|
+
only the selected tab.
|
|
780
|
+
|
|
781
|
+
The following cadence table applies to automatically polled tabs:
|
|
765
782
|
|
|
766
783
|
| State | Earliest normal check |
|
|
767
784
|
|---|---|
|
|
@@ -844,6 +861,14 @@ rate-limiting, it loads the saved rows for that same target immediately. Their
|
|
|
844
861
|
age remains explicit through the `stale` label, and the rate-limit banner still
|
|
845
862
|
describes the current failed request; cached data never turns a failure into a
|
|
846
863
|
false success.
|
|
864
|
+
After a sustained hold, the notice names the Core or GraphQL cause, the next
|
|
865
|
+
automatic retry or required action, and the age of the last complete source
|
|
866
|
+
observation. A successful budget check, cache load, or heartbeat cannot make
|
|
867
|
+
old rows fresh. A validated unchanged `304` response does count as a new source
|
|
868
|
+
observation. Unknown older spend remains charged until owner/child quiescence
|
|
869
|
+
and a later matching observer establish safe retirement. A verified new system
|
|
870
|
+
boot can establish that boundary for otherwise unidentifiable older children;
|
|
871
|
+
the app does not assume a restart or reset alone refunded the charge.
|
|
847
872
|
|
|
848
873
|
The enforceable boundary is admission from fresh, conservatively debited
|
|
849
874
|
evidence. Another program can spend after the probe, and standalone panes in a
|
|
@@ -886,29 +911,51 @@ fixture performance is not presented as live GitHub performance.
|
|
|
886
911
|
### Live freshness monitor
|
|
887
912
|
|
|
888
913
|
The repository includes a read-only monitor for a declared set of live panes.
|
|
889
|
-
|
|
890
|
-
|
|
891
|
-
|
|
892
|
-
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
|
|
914
|
+
For a qualifying run, create a schema 2 manifest independently of the
|
|
915
|
+
acquisition store before sampling. Fix `candidateHash` to the SHA-256 of the
|
|
916
|
+
exact executable, `requestedDurationMs` to the full observation window, and
|
|
917
|
+
`sampleIntervalMs` to `5000`. Each expected pane needs its ID, live PID,
|
|
918
|
+
repository, repository ID, tab, host, access-key fingerprint, start time in
|
|
919
|
+
Unix milliseconds, and declared `cadenceMs`. The monitor checks the live PID
|
|
920
|
+
and subscription against that fixed identity on every sample. It derives the
|
|
921
|
+
source deadline from the declared cadence, not from the app's `nextDueAt`.
|
|
896
922
|
|
|
897
|
-
Use the
|
|
923
|
+
Use the panes' private config root and a new report path:
|
|
898
924
|
|
|
899
925
|
```sh
|
|
900
|
-
node scripts/freshness-monitor.mjs --manifest
|
|
926
|
+
node scripts/freshness-monitor.mjs --manifest "$GH_GLANCE_QUALIFICATION_MANIFEST" \
|
|
901
927
|
--store "$XDG_CONFIG_HOME/gh-glance/coordination-v2/acquisition.json" \
|
|
902
|
-
--
|
|
928
|
+
--quota "$GH_GLANCE_MONITORED_QUOTA" \
|
|
929
|
+
--candidate "$(command -v gh-glance)" --report freshness.jsonl \
|
|
930
|
+
--interval-ms 5000 --duration-ms 86400000
|
|
903
931
|
```
|
|
904
932
|
|
|
905
|
-
|
|
906
|
-
|
|
907
|
-
|
|
908
|
-
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
|
|
933
|
+
Set `GH_GLANCE_MONITORED_QUOTA` to the quota file selected by the cached
|
|
934
|
+
registry entry matching every declared host and access-key fingerprint; the
|
|
935
|
+
monitor rejects an unrelated or ambiguous scope. Resolve the installed
|
|
936
|
+
executable with `command -v gh-glance` only after confirming it is the exact
|
|
937
|
+
candidate under observation. The JSONL records requested and actual
|
|
938
|
+
elapsed time, sample gaps, source clocks, maximum eligible gaps, overdue time,
|
|
939
|
+
observer/debt counts, and separate wall, external-outage, and eligible windows.
|
|
940
|
+
Its `windowClass` is derived from requested duration: `short` below 30
|
|
941
|
+
minutes, `initial` from 30 minutes to under 24 hours, and `full` from 24 hours.
|
|
942
|
+
A successful short or initial report does not complete 24-hour acceptance;
|
|
943
|
+
that requires a separate full window and its declared live transitions.
|
|
944
|
+
Missing or expired subscriptions, a disappeared PID, corrupt stores, an early
|
|
945
|
+
SIGINT, or a sample gap over 15 seconds makes the report nonqualifying. A sleep
|
|
946
|
+
gap requires a new uninterrupted window. A schema 1 manifest supports a
|
|
947
|
+
diagnostic `--once` read only; it cannot qualify a run.
|
|
948
|
+
|
|
949
|
+
Provider-limit exclusions require `--external-evidence` pointing to an
|
|
950
|
+
append-only JSON trace with `schema: 1` and an `events` array. Each `raw-http`
|
|
951
|
+
event records the independently captured issue and finish timestamps, host,
|
|
952
|
+
access-key fingerprint, Core or GraphQL resource, and raw HTTP status line and
|
|
953
|
+
bounded headers. The monitor derives the interval from a matching 429 or
|
|
954
|
+
rate-exhausted 403 response with `Retry-After`. It reloads the trace on every
|
|
955
|
+
sample and rejects changed past records or future responses. App hold labels
|
|
956
|
+
and synthetic request-oracle records grant no exclusion. Local coordination
|
|
957
|
+
holds fail qualification even when brief. Keep this trace and the manifest private. The
|
|
958
|
+
monitor makes no GitHub request or coordination write.
|
|
912
959
|
|
|
913
960
|
## Limitations
|
|
914
961
|
|
|
@@ -1022,9 +1069,13 @@ GH_GLANCE_ICONS=ascii gh-glance
|
|
|
1022
1069
|
| It exits immediately when piped | Intentional. It is a full-screen dashboard, not a reporting command. |
|
|
1023
1070
|
| `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. |
|
|
1024
1071
|
| `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. This one has a deadline and clears itself. |
|
|
1025
|
-
| `Upgrade blocked: older spend cannot be settled or waited out` |
|
|
1072
|
+
| `Upgrade blocked: older spend cannot be settled or waited out` | Older spend has no reliable reset or child evidence. Verify old children ended and use `gh-glance --doctor` to inspect reserved units. An unidentifiable old child may require a verified system restart before a later observer can retire its charge. Keep the quota files as accounting evidence. |
|
|
1026
1073
|
| `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. |
|
|
1027
|
-
| `
|
|
1074
|
+
| `Local coordination` corruption, overflow, full storage, or unsafe permissions | Run `gh-glance --doctor`; its read-only report gives the exact cause and redacted local file location when known. Repair storage or permissions, then let the app retry. Preserve corrupt and overflow evidence for diagnosis. |
|
|
1075
|
+
| `Saving request result` or `Recovering interrupted request` | The original request may have consumed quota. The app keeps its charge, retries settlement without repeating HTTP, and waits for safe observer evidence before retiring uncertain debt. |
|
|
1076
|
+
| `GitHub request limit` | A shared secondary hold preserves GitHub's retry deadline. Wait for the shown time; if the repeated-limit circuit explicitly asks, press `r` once to retry. Repeated refresh cannot bypass a hold. |
|
|
1077
|
+
| `Collector connection unavailable` or `GitHub App authorization unavailable` | Restore the selected collector connection or App authorization. The mode does not switch to independent requests. Cached rows remain labeled with their source age. |
|
|
1078
|
+
| `Shared HTTP request or cooldown in progress` | Panes share up to three admitted requests per host, FIFO starts with at least 250 ms spacing, and one cooldown. The pool is full, a queued request is ahead, or a server-sent `Retry-After` is still running. Normal pacing, not an error. |
|
|
1028
1079
|
| `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. |
|
|
1029
1080
|
| 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. |
|
|
1030
1081
|
| `--verbose` refuses to start | stderr is still your terminal, where the log would draw over the dashboard. Redirect it to a file. |
|