OXYGENHUB

Kimi's avatar: an original monogram for agent:kimi (closes #351) ac689cd21adf

Author
Andy McCall @andymccall <[email protected]>
via
agent agent:claude@andymccall <[email protected]> · keyless, under your grant for changes,refs,seal · key 0c7ca683bbbd
When
· 2026-10-31 22:29 UTC
Signature
◈ sealed by agent:claude@andymccall
Hash
ac689cd21adf10d5e791fe3251ff8a1e91fde2a093ab579cb467aa1ab9a2edc0
Depends on
041a945f55f8 08e221b77658 101740454617 206c1fc1b06a b5668108487f
Depended on by
b7e1be264c0a 75491d35c258 42c77f6515c2
In bookmarks
main
In tags
v0.9.19 v0.9.20 v0.9.21 v0.9.22 v0.9.23 v0.9.24
Edits
8 atoms, 1 tree operation, 4 files

Browse the tree at this change

added assets/agents/kimi.svg +1 −0
1 +
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" role="img" aria-label="Kimi"><title>Kimi</title><circle cx="12" cy="12" r="12" fill="#0B0D12"/><circle cx="12" cy="12" r="11.5" fill="none" stroke="#3A4256" stroke-width="1"/><g fill="none" stroke="#fff" stroke-width="2.6" stroke-linecap="round" stroke-linejoin="round"><path d="M8.6 6.2v11.6"/><path d="M15 6.8 9 12.4l6.6 5.4"/></g><circle cx="17.7" cy="6.4" r="1.7" fill="#2F8CFF"/></svg>
modified CHANGELOG.md +4 −0
…
1 unchanged lines
2 2
3 3
OxygenHub runs at https://oxygenhub.io; each deploy's build is on the About page and at `/api/v1/version`.
4 4
5 +
## Unreleased
6 +
7 +
- **Kimi has its own avatar (#351).** Changes signed via an agent named Kimi (`agent:kimi@…`, or Moonshot) now show a Kimi mark, a white K with a blue dot on a dark disc, instead of an identicon, as Claude, Gemini and the others have theirs.
8 +
5 9
## 0.9.17 (2026-10-29)
6 10
7 11
- **Drops over the API: fork, star and comment (#349).** What a drop's page does, for the VS Code extension and other clients: `POST /api/v1/drops/{id}/fork`, `PUT`/`DELETE /api/v1/drops/{id}/star`, `GET`/`POST /api/v1/drops/{id}/comments` and `DELETE /api/v1/drops/{id}/comments/{n}`, by the web's rules (the owner told of a comment; its author, the owner or an administrator deletes it). A drop over the API now says its stars, whether you starred it, what it was forked from and its embed address. `oh drop fork|star|unstar|comments|comment`. The API's TypeScript types now include the dashboard's proposals, the starter and test reports.
…
424 unchanged lines
modified assets/agents/README.md +1 −1
1 -
Brand marks for AI agents' avatars (hub spec §6): the paths are from simple-icons (CC0), each set white on the brand's colour. `antigravity` uses the Gemini mark, Antigravity having none of its own there; Grok has no mark and falls back to the identicon.
1 +
Brand marks for AI agents' avatars (hub spec §6): the paths are from simple-icons (CC0), each set white on the brand's colour. `antigravity` uses the Gemini mark, Antigravity having none of its own there; Grok has no mark and falls back to the identicon. `kimi` is our own monogram (a K and a blue dot on a dark disc), simple-icons having no Kimi mark.
modified crates/hub/src/web/avatar.rs +12 −1
…
155 unchanged lines
156 156
        ("mistral", include_str!("../../../../assets/agents/mistral.svg")),
157 157
        ("antigravity", include_str!("../../../../assets/agents/antigravity.svg")),
158 158
        ("gemini", include_str!("../../../../assets/agents/antigravity.svg")),
159 +
        ("kimi", include_str!("../../../../assets/agents/kimi.svg")),
160 +
        ("moonshot", include_str!("../../../../assets/agents/kimi.svg")),
159 161
    ];
160 162
    let lower = name.to_lowercase();
161 163
    MARKS.iter().find(|(k, _)| lower.contains(k)).map(|(_, svg)| *svg)
…
41 unchanged lines
203 205
204 206
#[cfg(test)]
205 207
mod tests {
206 -
    use super::{identicon, process, system_mark, SIZE};
208 +
    use super::{agent_mark, identicon, process, system_mark, SIZE};
207 209
208 210
    fn encoded(img: image::DynamicImage, format: image::ImageFormat) -> Vec<u8> {
209 211
        let mut out = Vec::new();
…
33 unchanged lines
243 245
    }
244 246
245 247
    #[test]
248 +
    fn kimi_has_its_mark() {
249 +
        for name in ["kimi", "Kimi", "agent:kimi@andymccall", "Moonshot Kimi"] {
250 +
            let svg = agent_mark(name).unwrap_or_else(|| panic!("{name} has no mark"));
251 +
            assert!(svg.contains("aria-label=\"Kimi\""), "{name}");
252 +
        }
253 +
        assert!(agent_mark("kim").is_none(), "only the name itself matches");
254 +
    }
255 +
256 +
    #[test]
246 257
    fn the_diffusion_account_has_its_mark() {
247 258
        let m = system_mark("diffusion").expect("a mark");
248 259
        assert!(m.starts_with("<svg") && m.contains("<title>Diffusion</title>"));
…
25 unchanged lines