diff --git a/Cargo.lock b/Cargo.lock index 3a38fb5..2f0bb40 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -791,7 +791,7 @@ checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" [[package]] name = "hotusage" -version = "0.8.0" +version = "0.9.0" dependencies = [ "chrono", "libc", diff --git a/Cargo.toml b/Cargo.toml index cfaebaf..432ec92 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "hotusage" -version = "0.8.0" +version = "0.9.0" edition = "2024" [dependencies] diff --git a/README.md b/README.md index ab4de59..70ccffd 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ -# hotusage +# hototel Know what your team's AI coding agents are actually doing — who uses them, on which projects, with which models, and what it would cost. @@ -21,14 +21,14 @@ whole team's: macOS and Linux, one line: ```bash -curl -fsSL https://raw.githubusercontent.com/hotdata-dev/hotusage-client/main/install.sh | sh +curl -fsSL https://raw.githubusercontent.com/hotdata-dev/hototel-client/main/install.sh | sh ``` Your browser opens, you approve the machine, and the first sync runs immediately. Nothing to configure. On Windows, download the `.zip` from the -[latest release](https://github.com/hotdata-dev/hotusage-client/releases), +[latest release](https://github.com/hotdata-dev/hototel-client/releases), put `hotusage.exe` somewhere on your PATH, and run `hotusage install`. ## Ask your agent diff --git a/docs/internals.md b/docs/internals.md index 1b2a8bd..020ec94 100644 --- a/docs/internals.md +++ b/docs/internals.md @@ -128,7 +128,7 @@ First run writes `~/.hotusage/collector.json`: ```json { - "server_url": "https://www.hotusage.ai", + "server_url": "https://hototel.com", "token": "", "user_email": "you@company.com", "interval_minutes": 15, diff --git a/install.sh b/install.sh index fdab43d..e4e297e 100755 --- a/install.sh +++ b/install.sh @@ -1,7 +1,7 @@ #!/bin/sh # hotusage installer for macOS and Linux. # -# curl -fsSL https://raw.githubusercontent.com/hotdata-dev/hotusage-client/main/install.sh | sh +# curl -fsSL https://raw.githubusercontent.com/hotdata-dev/hototel-client/main/install.sh | sh # # Downloads the latest release binary for this machine, puts it on PATH, # registers it as a background agent (macOS LaunchAgent / systemd user unit), @@ -9,7 +9,7 @@ # about your organization's usage. set -eu -REPO=hotdata-dev/hotusage-client +REPO=hotdata-dev/hototel-client BIN=hotusage # What this was called before 0.4.0. `$BIN install` retires the old service # registration itself; the stale binary is this script's job, because a copy @@ -175,7 +175,7 @@ TXT cat < Self { Config { - server_url: "https://www.hotusage.ai".into(), + server_url: "https://hototel.com".into(), token: String::new(), user_email: String::new(), interval_minutes: 15, @@ -117,12 +117,14 @@ pub fn load_config() -> Config { if cfg.user_email.is_empty() { cfg.user_email = guess_email(); } - // Installs created before the default changed point at the apex, which - // 301s to www; a POST that follows it arrives as a GET (401 on sign-in, - // a silently discarded upload on sync). Changing the default cannot help - // those machines, because their config file already exists -- so repair - // the value itself, on the exact host and nothing else. - if let Some(fixed) = apex_to_www(&cfg.server_url) { + // The service moved from hotusage.ai to hototel.com (Sep 2026; the old + // domain still serves during the transition, but is being retired). + // Changing the default cannot help existing machines, because their + // config file already exists -- so repair the value itself, on the exact + // legacy hosts and nothing else. Same token, same backend: only the host + // changes. (This replaces the earlier apex-to-www repair, which existed + // because the old apex once 301'd POSTs into GETs.) + if let Some(fixed) = legacy_to_hototel(&cfg.server_url) { cfg.server_url = fixed; let _ = save_config(&cfg); } @@ -135,12 +137,14 @@ pub fn load_config() -> Config { cfg } -/// `https://hotusage.ai[/...]` -> `https://www.hotusage.ai[/...]`, or None -/// when nothing needs changing. -fn apex_to_www(url: &str) -> Option { - let rest = url.strip_prefix("https://hotusage.ai")?; +/// `https://hotusage.ai[/...]` or `https://www.hotusage.ai[/...]` -> +/// `https://hototel.com[/...]`, or None when nothing needs changing. +fn legacy_to_hototel(url: &str) -> Option { + let rest = url + .strip_prefix("https://www.hotusage.ai") + .or_else(|| url.strip_prefix("https://hotusage.ai"))?; if rest.is_empty() || rest.starts_with('/') { - Some(format!("https://www.hotusage.ai{rest}")) + Some(format!("https://hototel.com{rest}")) } else { None } @@ -557,17 +561,22 @@ pub fn sync(config: &Config) -> Result { #[cfg(test)] mod tests { - use super::{apex_to_www, is_loopback, validated_url}; + use super::{is_loopback, legacy_to_hototel, validated_url}; #[test] - fn apex_is_repaired_but_nothing_else_is() { - assert_eq!(apex_to_www("https://hotusage.ai").as_deref(), - Some("https://www.hotusage.ai")); - assert_eq!(apex_to_www("https://hotusage.ai/").as_deref(), - Some("https://www.hotusage.ai/")); - assert!(apex_to_www("https://www.hotusage.ai").is_none()); - assert!(apex_to_www("https://hotusage.ai.evil.example").is_none()); - assert!(apex_to_www("https://internal.example").is_none()); + fn legacy_hosts_are_repaired_but_nothing_else_is() { + assert_eq!(legacy_to_hototel("https://hotusage.ai").as_deref(), + Some("https://hototel.com")); + assert_eq!(legacy_to_hototel("https://hotusage.ai/").as_deref(), + Some("https://hototel.com/")); + assert_eq!(legacy_to_hototel("https://www.hotusage.ai").as_deref(), + Some("https://hototel.com")); + assert_eq!(legacy_to_hototel("https://www.hotusage.ai/x").as_deref(), + Some("https://hototel.com/x")); + assert!(legacy_to_hototel("https://hototel.com").is_none()); + assert!(legacy_to_hototel("https://hotusage.ai.evil.example").is_none()); + assert!(legacy_to_hototel("https://www.hotusage.ai.evil.example").is_none()); + assert!(legacy_to_hototel("https://internal.example").is_none()); } #[test] diff --git a/src/tray.rs b/src/tray.rs index d8d643e..a355701 100644 --- a/src/tray.rs +++ b/src/tray.rs @@ -52,7 +52,7 @@ const UPDATE_ITEM_POSITION: usize = 4; /// The releases page, for the platform that has no scripted install. #[cfg(not(unix))] -const RELEASES_URL: &str = "https://github.com/hotdata-dev/hotusage-client/releases/latest"; +const RELEASES_URL: &str = "https://github.com/hotdata-dev/hototel-client/releases/latest"; /// What the update row says. It names the version rather than saying "an /// update is available", so the click is a decision about a known thing. diff --git a/src/update.rs b/src/update.rs index 02068e2..40f2b34 100644 --- a/src/update.rs +++ b/src/update.rs @@ -52,7 +52,7 @@ fn private_tempdir() -> Result { Err("could not create a temporary directory".into()) } -const REPO: &str = "hotdata-dev/hotusage-client"; +const REPO: &str = "hotdata-dev/hototel-client"; /// The installer as it stood at one tag. Pinned rather than tracking `main`: /// see the module comment -- this script is executed, and the tag resolved by