From cb0fd836ac8a1c18744acfea7e06c8a049f312c0 Mon Sep 17 00:00:00 2001 From: Teknium <127238744+teknium1@users.noreply.github.com> Date: Tue, 18 Aug 2026 20:47:35 -0700 Subject: [PATCH] feat: Bot Mode blob avatars gain 4 new silhouettes via blobatar 2.0.0 blobatar 0.2.0 -> 2.0.0 (gen2). Ten silhouettes instead of six: capsule, triangle, hexagon and droplet join round, organic, boxy, nub, cloud and sun. BLOB_KIND_TRAIT repinned to gen2 band centers (empirically verified against the published package: every pinned value resolves to its named silhouette across seeds). The avatar picker derives from BLOB_KINDS, so the new shapes appear there automatically. Note: gen2 remaps most unpinned seed->face mappings by design (upstream generation change). --- apps/desktop/package.json | 2 +- .../desktop/src/plugins/hermes-bots/plugin.js | 12 +++++--- .../tests/blobatar-shapes.test.mjs | 6 +++- package-lock.json | 30 +++++++++---------- 4 files changed, 29 insertions(+), 21 deletions(-) diff --git a/apps/desktop/package.json b/apps/desktop/package.json index 4d152c7a52..0c4dbf30cd 100644 --- a/apps/desktop/package.json +++ b/apps/desktop/package.json @@ -113,7 +113,7 @@ "@xterm/addon-web-links": "0.12.0", "@xterm/addon-webgl": "0.19.0", "@xterm/xterm": "6.0.0", - "blobatar": "0.2.0", + "blobatar": "2.0.0", "class-variance-authority": "0.7.1", "clsx": "2.1.1", "cmdk": "1.1.1", diff --git a/apps/desktop/src/plugins/hermes-bots/plugin.js b/apps/desktop/src/plugins/hermes-bots/plugin.js index 55be4d168f..e8c709bbae 100644 --- a/apps/desktop/src/plugins/hermes-bots/plugin.js +++ b/apps/desktop/src/plugins/hermes-bots/plugin.js @@ -852,17 +852,21 @@ function defaultShapeFor(name) { // 'blobatar' — the face follows the bot's NAME (renaming the // bot re-rolls the face, live in the dialog) // 'blobatar:' — seed locked (the 🔒 lock / 🎲 randomize picks) -// 'blobatar::' — plus one of the six silhouettes pinned +// 'blobatar::' — plus one of the ten silhouettes pinned // 'blobatar::' — silhouette pinned, seed still follows the name // Bot names are slugs (NAME_RE) and generated seeds are base36, so ':' never // appears inside a segment. Colors come from the library's own name-derived // palette (contrast-guaranteed) — the classic color swatches don't apply. -const BLOB_KINDS = ['round', 'organic', 'boxy', 'nub', 'cloud', 'sun'] +const BLOB_KINDS = ['round', 'organic', 'boxy', 'capsule', 'nub', 'cloud', 'droplet', 'hexagon', 'sun', 'triangle'] // Trait positions at the center of each silhouette band. Band thresholds are -// frozen per blobatar major (0.28 / 0.58 / 0.72 / 0.84 / 0.93). -const BLOB_KIND_TRAIT = { round: 0.14, organic: 0.43, boxy: 0.65, nub: 0.78, cloud: 0.885, sun: 0.965 } +// frozen per blobatar major (gen2: 0.22 / 0.48 / 0.60 / 0.70 / 0.79 / 0.86 / +// 0.915 / 0.95 / 0.98). +const BLOB_KIND_TRAIT = { + round: 0.11, organic: 0.35, boxy: 0.54, capsule: 0.65, nub: 0.745, + cloud: 0.825, droplet: 0.8875, hexagon: 0.9325, sun: 0.965, triangle: 0.99 +} function isBlobShape(shape) { return shape === 'blobatar' || (typeof shape === 'string' && shape.startsWith('blobatar:')) diff --git a/apps/desktop/src/plugins/hermes-bots/tests/blobatar-shapes.test.mjs b/apps/desktop/src/plugins/hermes-bots/tests/blobatar-shapes.test.mjs index 2806c52d21..cf15fcc4b4 100644 --- a/apps/desktop/src/plugins/hermes-bots/tests/blobatar-shapes.test.mjs +++ b/apps/desktop/src/plugins/hermes-bots/tests/blobatar-shapes.test.mjs @@ -64,7 +64,11 @@ test('blob shape strings round-trip through parse/build', () => { test('every silhouette has a trait position inside its frozen band', () => { const b = load() - const bands = { round: [0, 0.28], organic: [0.28, 0.58], boxy: [0.58, 0.72], nub: [0.72, 0.84], cloud: [0.84, 0.93], sun: [0.93, 1] } + const bands = { + round: [0, 0.22], organic: [0.22, 0.48], boxy: [0.48, 0.60], capsule: [0.60, 0.70], + nub: [0.70, 0.79], cloud: [0.79, 0.86], droplet: [0.86, 0.915], hexagon: [0.915, 0.95], + sun: [0.95, 0.98], triangle: [0.98, 1] + } for (const kind of b.BLOB_KINDS) { const v = b.BLOB_KIND_TRAIT[kind] diff --git a/package-lock.json b/package-lock.json index dcb2b160f7..4b79b63afe 100644 --- a/package-lock.json +++ b/package-lock.json @@ -99,7 +99,7 @@ "@xterm/addon-web-links": "0.12.0", "@xterm/addon-webgl": "0.19.0", "@xterm/xterm": "6.0.0", - "blobatar": "0.2.0", + "blobatar": "2.0.0", "class-variance-authority": "0.7.1", "clsx": "2.1.1", "cmdk": "1.1.1", @@ -194,6 +194,20 @@ "global-agent": "^3.0.0" } }, + "apps/desktop/node_modules/blobatar": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/blobatar/-/blobatar-2.0.0.tgz", + "integrity": "sha512-46STsjELfKv5hnnRYsWKgN1vlWFkaewSkwnqRRnptCD+LwxejfyXs1lYwek4fkwAtGrXabmJHP4fpzDxjnqAEg==", + "license": "MIT", + "peerDependencies": { + "react": ">=18" + }, + "peerDependenciesMeta": { + "react": { + "optional": true + } + } + }, "apps/desktop/node_modules/electron": { "version": "40.10.2", "resolved": "https://registry.npmjs.org/electron/-/electron-40.10.2.tgz", @@ -7691,20 +7705,6 @@ "react": ">=17.0.1" } }, - "node_modules/blobatar": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/blobatar/-/blobatar-0.2.0.tgz", - "integrity": "sha512-TL4blQf9fu+EzsFEKMjh7PVORnf42G9HdpaXzdLR9dTHcMSYJWEj5fPeLhsXTN5YFCNstZaRAQRAWyhW8lRAdw==", - "license": "MIT", - "peerDependencies": { - "react": ">=18" - }, - "peerDependenciesMeta": { - "react": { - "optional": true - } - } - }, "node_modules/bluebird": { "version": "3.7.2", "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz",