Three tray bugs today, each caused by fixing the previous one without looking at what else the fix touched. Worth writing down as one thing rather than three. **Two dogs, again.** 0.1.4 taught the app to notice its own package being replaced and reopen. 0.1.5 added the same behaviour to `hound update`, which is the better mechanism because it works no matter which version was running — and I did not remove the first. Both fire during an update: the running app re-execs under a new pid while apt is working, so the updater kills a pid that has already moved and starts a second instance beside it. The in-app restart now waits eight seconds before acting. If the updater is doing its job this process is terminated during the pause and never restarts itself; what survives the wait is the only case the updater cannot cover, which is somebody running `apt upgrade` directly. Two mechanisms, one arbiter. **The launcher stopped working.** The single-instance lock added in 0.1.5 to prevent the duplicate icon made a second launch exit quietly, so clicking the desktop shortcut while Hound was open did nothing at all — no window, no error, no feedback. It now hands the request to the running instance, which shows, unminimises and focuses. The same channel the right-click scan already used: a launch with paths means "scan these", a launch without means "show yourself". Also in this release, and the reason the version is what it says it is: the workspace version did not get bumped. Adding the hound-watch crate pushed `version =` from line 6 to line 7 of Cargo.toml, and the bump was a line-numbered sed. The three GUI files went to 0.1.10 and the workspace stayed at 0.1.9, so the package built as 0.1.9 while the manifest would have advertised 0.1.10 — every installed agent would have offered an update forever, installed it, and still seen one available. `the_declared_versions_all_agree` caught it before the build finished. tools/bump-version.sh now does this by matching content and section rather than line numbers, asserts every substitution actually happened, and refuses to write invalid JSON. Adds crates/hound-watch: the registry firehose. npm publishes a CouchDB _changes stream and PyPI an RSS feed of every new project, both public, so this needs no user data at all — which is the answer to how a product with no telemetry grows its detection. Each new package is handed to the detectors Hound already ships, so there is one definition of "this install script is hostile" and a rule that fires in CI fires identically on the firehose. Verified against the live registries: 240 releases in one poll, 60 triaged, parsers tested against captured responses rather than the network. 476 tests pass. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
16 lines
671 B
Rust
16 lines
671 B
Rust
//! One poll of the registries, printing what was published.
|
|
//!
|
|
//! cargo run -p hound-watch --example poll-once
|
|
|
|
fn main() -> anyhow::Result<()> {
|
|
let mut cursor = hound_watch::Cursor::default();
|
|
let releases = hound_watch::poll(&mut cursor)?;
|
|
let npm = releases.iter().filter(|r| r.ecosystem == "npm").count();
|
|
let pypi = releases.iter().filter(|r| r.ecosystem == "PyPI").count();
|
|
println!("{} releases: {npm} npm, {pypi} PyPI", releases.len());
|
|
println!("cursor now: npm_seq={} pypi_last={}", cursor.npm_seq, cursor.pypi_last);
|
|
for r in releases.iter().take(8) {
|
|
println!(" {:<6} {}", r.ecosystem, r.name);
|
|
}
|
|
Ok(())
|
|
}
|