How the Update Notice System Detects New Browser Versions in Ego Lite
The Ego Lite update notice system detects new browser versions by calling ego.getBrowserVersion() through an injected bridge, validating the returned BrowserVersionInfo, and emitting a formatted hint when updateAvailable equals true.
The update notice mechanism in citrolabs/ego-lite provides lightweight, stateless version detection that runs during every SDK command execution. Located in package/ego-browser/src/update-notice.ts, this system surfaces upgrade hints without persisting data or blocking command completion. This article breaks down the detection flow, suppression controls, and validation logic that powers the feature.
Entry Point: emitUpdateNotice and the Bridge Interface
The detection process begins at emitUpdateNotice in package/ego-browser/src/update-notice.ts (lines 36-39). This function receives two critical inputs:
- The
egobridge object, which optionally exposesgetBrowserVersion() - An
emitcallback that appends the notice to command output
When invoked, emitUpdateNotice passes a version source to updateNoticeLine. This source calls ego.getBrowserVersion() if the bridge method exists, otherwise resolving to null (lines 41-43).
// Simplified SDK usage pattern
import { emitUpdateNotice } from "./update-notice.js";
function runCommand(egoBridge, outputEmit) {
// Command execution logic...
// Attach update notice to output stream
emitUpdateNotice(egoBridge, (line) => outputEmit(line));
}
Suppressing the Notice with Environment Variables
Before any bridge interaction, the system checks noticeSuppressed (lines 50-53). When either condition below is true, the entire notice pipeline exits silently:
EGO_BROWSER_NO_UPDATE_NOTIFIERis setCIenvironment variable is present
This prevents update hints from appearing in automated pipelines or when explicitly disabled by the user.
Fetching the Version with Timeout Protection
The updateNoticeLine function executes the VersionSource within withTimeout (lines 44-45, 94-100). This races the bridge call against a 2-second timeout defined by NOTICE_PROBE_TIMEOUT_MS (2000 ms).
// Timeout-protected version probe
const NOTICE_PROBE_TIMEOUT_MS = 2000;
async function withTimeout<T>(
promise: Promise<T>,
ms: number
): Promise<T | null> {
// Races bridge call against timeout
}
This guarantee prevents a stalled getBrowserVersion() from degrading command performance.
Validating and Formatting the Notice
Once the bridge returns data, composeNotice (lines 70-85) applies strict validation rules:
| Field | Requirement |
|---|---|
updateAvailable |
Must be literal true |
currentVersion |
Must be non-empty string |
latestVersion |
Optional inclusion in output |
mandatory |
Added to message when true |
Valid notices receive the [ego-browser:notice] prefix from NOTICE_PREFIX (lines 40-41) before emission.
// Example formatted notice output
[ego-browser:notice] ego lite 1.3.0 is available (current 1.2.3) — run: ego-browser upgrade …
Emitting the Final Line
After updateNoticeLine resolves, emitUpdateNotice invokes the provided emit callback with the formatted line (lines 45-47). Errors at this stage are intentionally swallowed—wrapped in a catch block—to prevent unhandled rejections from disrupting command execution (lines 48-49).
Mocking for Testing
The modular design enables straightforward unit testing. Supply a fake VersionSource to updateNoticeLine to verify formatting logic without bridge dependencies:
import { updateNoticeLine } from "./update-notice.js";
const fakeSource = async () => ({
currentVersion: "1.2.3",
updateAvailable: true,
latestVersion: "1.3.0",
mandatory: false,
});
const line = await updateNoticeLine({ source: fakeSource });
console.log(line);
// → [ego-browser:notice] ego lite 1.3.0 is available (current 1.2.3) — run: ego-browser upgrade …
Supporting Files in the Detection Pipeline
| File | Responsibility |
|---|---|
package/ego-browser/src/update-notice.ts |
Core detection, validation, and formatting |
package/ego-browser/src/helpers.ts |
Registers emitUpdateNotice as output-sink trailer during SDK init |
package/ego-browser/src/env.ts |
Resolves suppression environment variables |
package/ego-browser/src/browser-runtime.ts |
Defines native ego bridge with getBrowserVersion |
Summary
- Bridge-dependent detection: The system relies on
ego.getBrowserVersion()injected at runtime, falling back to null if unavailable - Zero persistence: No caching or state storage; checks run fresh on every command
- 2-second timeout:
NOTICE_PROBE_TIMEOUT_MSprevents blocking - Strict validation: Only
updateAvailable: truewith validcurrentVersiontriggers output - Environment controls:
EGO_BROWSER_NO_UPDATE_NOTIFIERandCIprovide opt-out mechanisms - Fail-silent emission: Errors in notice delivery never propagate to callers
Frequently Asked Questions
How does the update notice system detect new browser versions without network calls?
The system delegates detection to the native ego bridge via getBrowserVersion(). This local call returns BrowserVersionInfo without HTTP requests, keeping the check lightweight and private. The bridge implementation in browser-runtime.ts handles actual version comparison against available releases.
What happens if the bridge call hangs or responds slowly?
withTimeout enforces a 2000 ms ceiling on the VersionSource promise. If getBrowserVersion() exceeds this limit, the promise races to null resolution, and no notice appears. Commands continue normally regardless of bridge responsiveness.
Why does the notice appear on every command instead of rate-limited?
By design, emitUpdateNotice executes statelessly. No timestamp files, registry entries, or cache entries track last-check time. This eliminates filesystem dependencies and ensures users always see current availability status, accepting the minimal overhead of a 2-second-capped local call.
Can I disable update notices in CI environments?
Yes. Setting CI to any value automatically suppresses detection via noticeSuppressed. Alternatively, set EGO_BROWSER_NO_UPDATE_NOTIFIER for explicit opt-out in any environment. These variables are resolved in package/ego-browser/src/env.ts before any bridge interaction occurs.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →