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