Skip to content

feat(client): show remote Bot and group avatars - #2535

Merged
DoodleBears merged 6 commits into
mainfrom
t3/remote-host-avatars
Oct 21, 2026
Merged

DoodleBears merged 6 commits into
mainfrom
t3/remote-host-avatars

Conversation

@DoodleBears

@DoodleBears DoodleBears commented Oct 21, 2026 •

Copy link
Copy Markdown
Contributor

Requested by Vain. Refs #2500 · Track 1 claim · Task: codex/local/01a15ee9-772a-7060-893b-027cecd4242d.

Why the change

远程频道列表、会话标题和 Bot 作者现在使用所属 Host 的真实头像,并在头像保存后通过现有 Host Feed 刷新。

Special things to note

  • Merge risk: two-way door / small blast radius — revert these commits; no schema or credential migration. Review focus: remote preview skips local Tob lookup, group data URLs remain direct, and registry notifications occur after committed avatar edits. The Desktop: icon-only Host strip, Add remote in the + menu; ADR-0243 drops environment tabs #2508 icon-only Host strip stays intact; remote-hosts.ts is unchanged. Required Browser/Computer bundles were rebuilt and committed; their maps remained byte-identical.
  • Verification: Before the final rebase, the portability integration on base a6704fd passed pnpm build (process-local GOMAXPROCS=2), pnpm typecheck, pnpm lint, pnpm format:check, and 13 files / 171 focused tests. The first unbounded-thread build was stopped and its log retained. On current head 0364c52, a single-worker boundary regression passed 6 files / 50 tests: StyleX, remote avatars, Device gateway, pairing, Connect account, and paired-device UI. The final rebase to b1cf50e adds main’s Connect/pairing work; the complete checks are not claimed as rerun across that SHA. New CI retains the original gates and owns final-head full build verification. Earlier independent suspected-baseline suites passed 11 tests, docs tests passed 4, and docs build passed; these remain earlier-stage evidence. Real local two-Host QA uses deepseek-v4-pro; light/dark before/after screenshots cover uploaded/seeded Bots, group member stacks, custom group images, headers and persisted authors. Dynamic QA: update, clear, restore and Remove Host passed on two real isolated Hosts, with canonical pixel checks, blob revocation, ready-shell observations and zero console/image errors. The first resumed run also recorded separate failed observer attempts whose resource URLs were not captured; their cause remains unresolved, with evidence retained. Later instrumented runs only recorded retried diagnostic-fetch aborts, not image failures. The shared StyleX portability fix was integrated independently from Track 2; new CI remains authoritative. Human QA remains with the coordinator. Remote bodies still show text/attachment names only; images/cards/approvals belong to Track 5. Host looks are intentionally device-local. DSH Desktop, native phone QA and physical-machine tailnet QA are unqualified; the live streaming-draft avatar path was not directly observed.
  • CI test plan: affected via existing source/test/reference rules; no rule addition. Broader local selections were bounded and stopped without a completion report; exact focused results and baseline failures are stated above. Parent orchestrates review and merging; this PR does not close Web: pair a second Computer and switch the channel list between All and each Computer #2500.

Change outline

Bot registry commits avatar/appearance
  └─ publishRosterCommitted()                 added notification
      └─ existing Host Feed + avatar cache    unchanged ownership
          └─ RemoteAvatar                    shared rendering adapter
              ├─ RemoteHostRows              avatar cell only
              ├─ conversation header         Bot / group
              └─ Bot authors                 persisted + live drafts
                  ├─ PersonaBotAvatar(preview=true)
                  └─ GroupChannelIcon(preview=true)

RemoteAvatar({ roster, avatars, target, size, t }) is reusable by Track 5; it performs no network request or subscription. GroupAvatarBot narrows the existing component contract. Device gateway production code is unchanged; its regression test covers the real avatar GET/query, PNG bytes, CORS and missing/revoked/cookie/origin rejection.

Light, before → after:

Before: remote Bot uses a generic icon; title and authors have no portrait

After: the remote uploaded portrait matches across row, title and authors

Dark theme, group member stack and custom group image — matched before/after Dark theme before Dark theme after Group before Group after: remote member stack and Bot authors Custom group before Custom group after: the group data URL takes priority
Dynamic two-Host QA: update → clear → restore → remove Host

The same open page follows the committed avatar through Host Feed updates; row, header and authors change together. Canonical image pixels, old blob revocation, and removal from saved devices were checked. Both instrumented runs reported a ready shell and zero console/image errors. The first resumed run's separate historical resource-error attempts remain unexplained and retained; this is not classified as a known baseline.

Dynamic update: uploaded portrait changes in row, header and authors Dynamic clear: seeded portrait replaces the removed upload Dynamic restore: uploaded portrait returns without a page reload Remove remote Host: its rows, strip and open conversation disappear

@DoodleBears DoodleBears self-assigned this Oct 21, 2026
@DoodleBears

DoodleBears commented Oct 21, 2026 •

Copy link
Copy Markdown
Contributor Author

Exact-head review aid refreshed for 0364c52, against base b1cf50e (2026-10-21 UTC).

The five-panel HTML explains the registry commit → Host Feed → authenticated object-URL cache → shared RemoteAvatar path, local Tob lookup isolation, failure paths and verification limits. Desktop and narrow previews were checked with no console messages. It is available in the task's local/thread handoff only: no GitHub-accessible HTML attachment or hosting path was available, so shared HTML delivery remains a known accessibility gap.

All 12 embedded GitHub images loaded at 1440×900, with positive rendered bounds; the longest URL is 113 characters. The body was read back with its attribution, real Task ID and correct Track 1 claim.

Validation is split by SHA: before the final rebase, full build/typecheck/lint/format and 13 files /171 tests passed. Current exact head passed the single-worker boundary regression: 6 files /50 tests, covering StyleX, remote avatars, gateway, pairing, Connect account and paired-device UI. Main's final rebase added pairing receipt/status, explicit revoke results and Connect account lifecycle/UI changes. Final-head full build belongs to new CI with unchanged gates.

Real two-Host update/clear/restore/remove passed twice, including canonical image pixels, blob revocation and saved-device removal. Both driven pages reported ready with zero console/image errors. The first run's separate historical resource-load failures remain unexplained and retained, not classified as a baseline or revoked-blob probe. Later captured failures were retried diagnostic-fetch aborts. Runtime captures exercise avatar implementation 87b4cad before the subsequent common generator integration.

Only verified task Hosts 47111/47112 were stopped; profiles and old evidence remain. No further model invocation occurred; the earlier real reply used deepseek-v4-pro. DSH Desktop, native-phone QA and physical-machine tailnet remain unqualified. Human QA, CI review and merging stay with the coordinator.

@coderabbitai

coderabbitai Bot commented Oct 21, 2026 •

Copy link
Copy Markdown

Warning

Review limit reached

You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository.

Next included review available in 38 minutes.

Check out review usage here.

View limit details

Limit details: You’ve used all 2 included reviews currently available.

Learn how review limits work.

Review configuration:

⚙️ Run configuration
  • Configuration used: defaults
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: cc0e0090-3708-4c37-87f4-06e883110377
📥 Commits

Reviewing files that changed from the base of the PR and between b1cf50e and 0364c52.

⛔ Files ignored due to path filters: 20
  • .github/pr-screenshots/2500-t1/after-all-dark.png is excluded by !**/*.png
  • .github/pr-screenshots/2500-t1/after-all-light.png is excluded by !**/*.png
  • .github/pr-screenshots/2500-t1/after-custom-dark.png is excluded by !**/*.png
  • .github/pr-screenshots/2500-t1/after-custom-light.png is excluded by !**/*.png
  • .github/pr-screenshots/2500-t1/after-dm-dark.png is excluded by !**/*.png
  • .github/pr-screenshots/2500-t1/after-dm-light.png is excluded by !**/*.png
  • .github/pr-screenshots/2500-t1/after-group-dark.png is excluded by !**/*.png
  • .github/pr-screenshots/2500-t1/after-group-light.png is excluded by !**/*.png
  • .github/pr-screenshots/2500-t1/avatar-cleared-dark.png is excluded by !**/*.png
  • .github/pr-screenshots/2500-t1/before-all-dark.png is excluded by !**/*.png
  • .github/pr-screenshots/2500-t1/before-all-light.png is excluded by !**/*.png
  • .github/pr-screenshots/2500-t1/before-custom-dark.png is excluded by !**/*.png
  • .github/pr-screenshots/2500-t1/before-custom-light.png is excluded by !**/*.png
  • .github/pr-screenshots/2500-t1/before-dm-dark.png is excluded by !**/*.png
  • .github/pr-screenshots/2500-t1/before-dm-light.png is excluded by !**/*.png
  • .github/pr-screenshots/2500-t1/before-group-dark.png is excluded by !**/*.png
  • .github/pr-screenshots/2500-t1/before-group-light.png is excluded by !**/*.png
  • .github/pr-screenshots/2500-t1/removed-dark.png is excluded by !**/*.png
  • .github/pr-screenshots/2500-t1/restored-dark.png is excluded by !**/*.png
  • .github/pr-screenshots/2500-t1/updated-dark.png is excluded by !**/*.png
📒 Files selected for processing: 16
  • .agents/skills/verify-deepseekbot/features/remote-hosts.md
  • changes/2500-remote-avatars.md
  • changes/2500-stylex-portable-bundles.md
  • packages/client/src/client/avatar.tsx
  • packages/client/src/client/group-avatar-stack.tsx
  • packages/client/src/client/host-tabs.tsx
  • packages/client/src/client/remote-avatar.tsx
  • packages/client/src/client/remote-conversation-view.tsx
  • packages/client/src/client/tob-presentation.ts
  • packages/client/test/remote-avatar.test.tsx
  • packages/core/src/bots/registry.ts
  • packages/core/src/plugin.ts
  • packages/core/test/device-gateway.test.ts
  • packages/core/test/registry.test.ts
  • scripts/stylex-plugin.mjs
  • scripts/test/stylex-plugin.test.mjs
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

Issue: #2500

Agent-Task: codex/local/01a15ee9-772a-7060-893b-027cecd4242d
Issue: #2500

Agent-Task: codex/local/01a15ee9-772a-7060-893b-027cecd4242d
Issue: #2500

Agent-Task: codex/local/01a15ee9-772a-7060-893b-027cecd4242d
Issue: #2500

Agent-Task: codex/local/01a15ee9-772a-7060-893b-027cecd4242d
StyleX commonJS hashes package-relative paths with native separators. Normalize the custom resolver's package identity to forward slashes while preserving extension fallback. Windows output now matches the Linux CI Browser and Computer bundles byte for byte.

Issue: #2500

Agent-Task: codex/local/01a15ee9-7784-7292-9194-6a6b18b23098
Issue: #2500

Agent-Task: codex/local/01a15ee9-772a-7060-893b-027cecd4242d
@DoodleBears
DoodleBears force-pushed the t3/remote-host-avatars branch from 87b4cad to 0364c52 Compare October 21, 2026 17:15
@DoodleBears
DoodleBears merged commit e0bbe34 into main Oct 21, 2026
13 checks passed
@DoodleBears
DoodleBears deleted the t3/remote-host-avatars branch October 28, 2026 04:26
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.

Web: pair a second Computer and switch the channel list between All and each Computer

1 participant