feat: flag when a newer Kagan release is available - #10
Merged
Conversation
Greptile SummaryThis PR adds a cached update check and surfaces newer Kagan releases in the board footer. The main changes are:
Confidence Score: 5/5This PR is safe to merge with minimal risk. The change is localized and follows the existing TUI/store separation. Tests cover parsing, version comparison, caching, fetch failures, malformed responses, clock skew, dev-version suppression, and footer rendering. No blocking logic or security issues were found. No files require special attention.
What T-Rex did
|
| Filename | Overview |
|---|---|
| README.md | Adds a short note pointing users to update instructions when the footer reports a newer release. |
| docs/quickstart.md | Documents OpenCode plugin cache behavior and the supported manual update paths. |
| src/board.tsx | Renders the update availability signal in the footer without changing board behavior. |
| src/store.tsx | Adds a simple store signal for the latest available version. |
| src/tui.tsx | Starts the injected update check from the TUI entrypoint and records newer versions in the store. |
| src/update-check.ts | Introduces version parsing, TTL-backed npm dist-tag lookup, cached fallback handling, and update notification logic. |
| test/board.test.tsx | Covers the new footer indicator rendering when the update signal is set. |
| test/update-check.test.ts | Covers version parsing/comparison, TTL cache behavior, fetch failures, malformed responses, and dev-version suppression. |
Reviews (1): Last reviewed commit: "feat: flag when a newer Kagan release is..." | Re-trigger Greptile
OpenCode installs a plugin once and caches it forever — it never re-checks npm, so users are never told a newer Kagan exists. Check the npm dist-tags endpoint at most once a day (cached in api.kv across restarts), and show `→ vX.Y.Z available` in the board footer when a newer release is out. The check runs off the render path from the TUI entry, skips dev/prerelease builds so local installs never nag, and never crashes or hangs the board on a network failure. Docs cover the two real ways to update, since re-running the install command reuses the same cache and does nothing.
|
🎉 This PR is included in version 0.2.0 🎉 The release is available on: Your semantic-release bot 📦🚀 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Why
OpenCode installs a plugin once and caches it forever. It never re-checks npm, and re-running
opencode plugin @kagan-sh/kaganreuses the same cache — so a user who installs Kagan is never told a newer version exists and has no obvious way to move to it. (Confirmed by reading the opencode plugin loader and npm cache: the resolved@latestspec is cached per exact string and short-circuits on subsequent loads;opencode upgradedoesn't touch the plugin cache either.)What
src/update-check.ts— checks npm'sdist-tagsendpoint at most once a day, caching the result inapi.kvacross restarts. Pure, fully-injected logic:parseReleaseaccepts only cleanx.y.zreleases; dev/prerelease builds (the repo's own0.0.0-development, any-beta) returnundefined, so local/dev installs never nag and a prereleaselatestcan't false-positive.isNewerReleasecompares segments numerically (0.1.10 > 0.1.3).resolveLatestVersionkeeps serving the cached value on a network failure without going dark for a day, and refetches if the stored timestamp is in the future (clock skew).→ vX.Y.Z availablein the accent color when a newer release exists — always visible whenever the board is open, which is the only place Kagan lives.tui.tsx), off the render path, and can never crash or hang the board (short timeout + abort, all errors swallowed).quickstart.md+ README pointer) explain the two real ways to update: clear the cached package dir, or pin-and-bump the version.Design notes
tui.tsx, not in the store — so no store/board unit test triggers a live npm request. The store just holds a signal; the board test drives the indicator viastore.setUpdateAvailable(...).Testing
test/update-check.test.ts: version-comparison edge cases, TTL/cache behavior, network-failure fallback, clock-skew refetch, dev-version skip.test/board.test.tsx.bun run check(prettier + oxlint + tsc + 650 tests + package-check) passes clean.Reviewed adversarially before opening (kv-ready timing, cache-path accuracy, network isolation in tests, version-compare correctness all verified against opencode source); no blockers or majors found.