Skip to content

Friend Bot row: full-width hover; fallback avatar never matches own (part of #384) - #402

Merged
Birfy merged 3 commits into
ThinkFlowLab:mainfrom
Birfy:fix/384-friend-row-hover-avatar
Oct 19, 2026
Merged

Birfy merged 3 commits into
ThinkFlowLab:mainfrom
Birfy:fix/384-friend-row-hover-avatar

Conversation

@Birfy

@Birfy Birfy commented Oct 19, 2026 •

Copy link
Copy Markdown
Collaborator

Part of #384

What changed

  • Full-width hover/selected band. On a wrapped Bot row (bt-row-wrap), the settings gear is absolutely positioned over the row so the hover and selected background fill the same full-width band as a plain row (including at 150% zoom). The row gets a little right padding while the gear is visible so the title does not sit under it.
  • Distinct fallback avatars, on every surface. lookAvoidingLocals steps a friend's Bot seeded shape (then color, once all shapes are taken) when that fallback would match the exact shape+color of one of your own Bots. A named ink and its published lowercase hex count as the same color. indexRoster registers the own Bots and BotMark applies the avoidance to every remote Bot, so sidebar, header, palette, details drawer, room avatars and transcript marks agree. A published image, emoji, or stored shape is left alone (real look sync). Never picks the Main Bot whale.

Still open on #384: one short name format in chat header / picker / approval cards (touches #305 alias routing).

Verification

  • TZ=UTC ARCH_DOCS_BASE=upstream/main npm run verify (Node 22, harness 0.2.0-rc.2) at the tip: pass
  • core/test/looks.test.js covers clash avoidance, named-ink vs hex, full shape exhaustion, and the roster registry

Docs-not-needed: subsystem note updated in docs/subsystems/core-client.md.

…own (ThinkFlowLab#384)

The settings gear on a wrapped Bot row is absolutely positioned so hover and
selected fill the same full-width band as a plain row (including at 150% zoom).
A friend's Bot with no published look steps its seeded shape when it would match
one of your own Bots exactly; a stored image/emoji/shape is left alone.

Docs-not-needed: subsystem note updated in docs/subsystems/core-client.md.
@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Oct 19, 2026 •

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-10-19T00:14:17.864849Z 8d68252 PR opened
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 8d6825275d

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread core/src/client/mark.js Outdated
const settled = useSettled(state)
if (bot === undefined) return h(BotMark, { size })
// A friend's Bot never shares the exact fallback avatar of one of my own Bots (#384).
const look = bot.remote ? lookAvoidingLocals(bot, locals) : undefined

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Pass local Bots to every remote-avatar surface

When a remote fallback collides, this only works where a caller supplies locals; an omitted prop becomes []. CommandPalette (core/src/client/palette.js:54) and the details drawer (core/src/client/details-drawer.js:306) call BotAvatar without it, while remote chat messages use BotMark directly (core/src/client/cells.js:273). Consequently the same friend is distinct in the sidebar/header but reverts to the colliding seed on these surfaces, so pass the own roster through every renderer (including direct marks) or centralize avoidance.

Useful? React with 👍 / 👎.

Comment thread core/src/client/characters.js Outdated
export function lookKey(look) {
if (look?.image) return `image:${String(look.image).slice(0, 96)}`
if (look?.emoji) return `emoji:${look.emoji}`
return `shape:${shapeId(look?.shape)}:${look?.color ?? ''}`

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Normalize rendered colors in the collision key

With a partially published remote look (color present, no avatar shape), lookKey compares raw identifiers rather than rendered colors. In light mode an own Bot colored blue renders #2A92FE (core/src/client/inks.js:8), while Bot Social normalizes that published color to #2a92fe (plugins/social/src/look.js:35-36); identical shapes therefore produce different keys and the helper returns the visually identical fallback. Normalize equivalent named/hex and hex-case values in the key.

Useful? React with 👍 / 👎.

const candidate = { ...look, shape: shapes[index] }
if (!taken.has(lookKey(candidate))) return candidate
}
return look

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Avoid returning a taken look after exhausting shapes

For a team whose own Bots occupy all 19 non-whale picker shapes in the fallback's color, this loop necessarily exhausts: line 120 established the original key is taken, yet this post-loop return gives that same colliding look back. Nested tree rosters can exceed this size, so this is a valid configured team and the advertised “never matches” guarantee fails; vary another dimension or otherwise return an untaken key after shape exhaustion.

AGENTS.md reference: AGENTS.md:L69-L69

Useful? React with 👍 / 👎.

@Birfy

Birfy commented Oct 19, 2026

Copy link
Copy Markdown
Collaborator Author

Addressed the three Codex P2 findings at fa86850 (also merged main 9e6e2a0, regenerated client bundle + patches, verify green locally):

  1. Every surface: avoidance is centralized. indexRoster registers own Bots (setLocalBots) and BotMark applies lookAvoidingLocals to any remote Bot when no look is given, so palette, details drawer, room avatars and transcript cells match the sidebar/header. The per-call locals prop is gone.
  2. Rendered colors: lookKeys treats a named ink and its light/dark hex (any case) as one color, so blue and Bot Social's #2a92fe collide as they should.
  3. Exhaustion: after all non-whale shapes are taken in the fallback color, the color steps too; a taken look is never handed back.

Still needs an independent reviewed-tip PASS (T1) before the merge queue.

@Birfy
Birfy added this pull request to the merge queue Oct 19, 2026
Merged via the queue into ThinkFlowLab:main with commit 8ceb008 Oct 19, 2026
8 checks passed
@Birfy
Birfy deleted the fix/384-friend-row-hover-avatar branch October 19, 2026 03:48
Birfy added a commit to Birfy/FlyBot that referenced this pull request Oct 19, 2026
…ew (ThinkFlowLab#426)

Owner decision 2026-10-19 15:31 (Asia/Shanghai): stop using Codex for PR
review. The owner's own reviewer Bot, acting as `Birfy`, reviews and
PASSes (self-PASS already allowed by ThinkFlowLab#415, `selfReview: ["Birfy"]`).

How Codex was triggered: not by anything in this repo. No workflow,
script, routine, label or `@codex` comment requests it (rg of
`.github/`, skills, scripts, docs; `gh api
repos/ThinkFlowLab/FlyBot/hooks` is empty). The reviews on
ThinkFlowLab#402/ThinkFlowLab#414/ThinkFlowLab#415/ThinkFlowLab#416 come from the `chatgpt-codex-connector` GitHub App
with trigger "PR opened", i.e. Codex's automatic code review enabled for
this repo in ChatGPT Codex settings. That switch is outside the repo and
is turned off there by the owner.

This PR (wording only, no gate change):
- AGENTS.md, CONTRIBUTING.md, docs/autonomous-dev.md, LESSONS.md: the
reviewer is the owner's Bot (self-review); nothing requests or waits for
Codex.
- review-pr skill: drop the OpenCode↔Codex agreement requirement and
Verifier line; reviewer's own evidence at the tip decides.
- review-gate.test.mjs: neutral fixture login `reviewer-agent` instead
of `codex-agent`, drop the unused agreement line (the gate never parsed
it).

Unchanged: `.github/agent/review-policy.json` (reviewers
`hsliuustc0106`, `Birfy`; selfReview `Birfy`; Codex was not listed), CI,
risk tiers, T2/T3 maintainer approval.

Tip SHA: aa57d50
Ran:
- ARCH_DOCS_BASE=origin/main TZ=UTC npm run verify (Node 24.21.0) → pass
  - node --test .github/scripts/*.test.mjs → pass (88/88)
Not run:
- smoke / Desktop / live-e2e with a real model — no runtime code changed

T3 (touches AGENTS.md and .github/**): needs the maintainer's approval;
not merged by the agent.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant