(cache: UpdateCheckCacheFile | null, d: ResolvedDeps)
| 139 | } |
| 140 | |
| 141 | function noticeFrom(cache: UpdateCheckCacheFile | null, d: ResolvedDeps): string | null { |
| 142 | if (!cache?.latest) return null; |
| 143 | // A dev build whose package.json couldn't be read reports the sentinel |
| 144 | // version; any comparison against it would always claim an update. |
| 145 | if (d.currentVersion === '0.0.0-unknown') return null; |
| 146 | // Canonicalize BOTH sides before comparing or rendering — a non-semver |
| 147 | // `latest` (garbage redirect, tampered cache) yields no notice at all |
| 148 | // rather than flowing into agent-visible text. |
| 149 | const latest = canonicalVersionTag(cache.latest); |
| 150 | const current = canonicalVersionTag(d.currentVersion); |
| 151 | if (!latest || !current) return null; |
| 152 | return isUpdateAvailable(current, latest) ? formatUpdateNotice(current, latest) : null; |
| 153 | } |
| 154 | |
| 155 | function cacheIsFresh(cache: UpdateCheckCacheFile | null, nowMs: number): boolean { |
| 156 | if (!cache) return false; |
no test coverage detected