Conversation
|
Demo: banner-sync.mp4 |
There was a problem hiding this comment.
This looks great, small nits mainly. My one question is whether there will ever be other conditions besides just your lk version that might want to trigger a banner? A specific command for example might want to provide usage tips that aren't dependent on version, but aren't appropriate to show at all times.
|
Demo of the separator: one notice alone, then three entries in banner.json of which two match this version and render with a rule between them, then a piped run that skips the banner. banner.mp4 |
2b331e2 to
b49f524
Compare
The CLI fetches banner.json from the repo's main branch on every run and, when the message is non-empty and the semver constraint in "versions" matches the running build, prints it to stderr after the command finishes. The fetch is never awaited: whatever has not arrived by then is dropped, so no command gets slower. Non-interactive runs never see it. Editing banner.json on main is the whole publishing process, so notices such as "upgrade via brew" reach installed CLIs without a release or an auto-updater.
One entry per notice, each with its own versions constraint, so a new-feature announcement for old builds can sit next to an upgrade notice without either having to be removed first.
Every --json flag binds to a shared jsonOutput destination so the banner, which prints after the command returns, can tell a --json run apart from an interactive one and keep stderr clean for downstream parsers.
This reverts commit b9e5001.
Status puts it on stderr and honors --quiet; the border sets it apart from the command's own output.
Printing before the command means the notice cannot wait on the network, so each run shows the banner.json cached at ~/.livekit/banner.json by the run before it and refreshes that cache in the background. A notice lands one run after it is published; no command gets slower.
The fetch is awaited with a 1s timeout and the file is cached for an hour, so only the first run each hour pays the round trip. Non-interactive runs skip the fetch entirely.
The cache is {data, downloadedAt}; a refetch happens once downloadedAt is
over an hour old. Sync tools and backups that rewrite mtime no longer force
a refetch or hide a stale file.
…time" This reverts commit 4daab13.
|
LGTM! Just reiterating the question: do we want to add an optional "command-level" filter so that banners can be shown only for specific commands and their subcommands? Also happy to cross that bridge when we get there. |
Let's cross that bridge when we get there |
Why
We want to tell people running an installed
lkthings like "a new version is out, runbrew upgrade livekit-cli" or "livekit.toml layout changed" without shipping an auto-updater (decided against) and without waiting for them to update to see the notice.What
banner.jsonat the repo root, fetched frommainon every run. It is a list of notices, each with its own version selector:[ {"message": "lk agent simulate can now export runs. Upgrade: brew upgrade livekit-cli", "versions": "< 2.18.0"}, {"message": "lk 3.0 is out and moves the agent id to [cloud] in livekit.toml.", "versions": "< 3.0.0"} ]versionsis a semver constraint; empty matches every build. Every entry that matches prints, in file order, so a new-feature announcement for old builds can sit next to an upgrade notice. The committed file is[]. Editing the file onmainis the whole publishing process.out.Status, so it honors--quietand never mixes with stdout. Only shown on an interactive terminal, so scripts and pipes are unaffected.~/.livekit/banner.jsonfor an hour, so only the first run each hour fetches at all (~70-170ms to raw.githubusercontent.com). A failed fetch falls back to the stale cache. The rootAfterhook waits for the flush so a fast command cannot exit with output still held. Non-interactive runs skip the fetch entirely.Verification
go build ./cmd/lk,go vet ./cmd/lk,go test ./cmd/lkpass. Demo video in a comment below.