feat(catalog): resolve publisher display name in catalog detail pane - #3640
Merged
Conversation
The `PersonaCatalogDetail` component hardcoded the label passed to `PersonaAddedBy` as "Community member" for any non-own catalog entry. The publisher's pubkey is already available as `catalogSource.ownerPubkey` (set from the kind:30175 event's pubkey). Use `useUsersBatchQuery` to resolve the pubkey to a kind:0 display name. Label precedence: own entry → "You"; resolved profile → `displayName` then `name`; loading or unresolvable → "Community member" (unchanged fallback). The batch query is disabled when the entry is not a community entry, so there is no extra network call for own entries or built-in agents. E2e: update the existing assertion that was checking for the hardcoded fallback, add a new test that verifies "Community member" still renders when the publisher pubkey is not in the mock profile registry. Co-authored-by: Will Pfleger <pfleger.will@gmail.com> Signed-off-by: Will Pfleger <pfleger.will@gmail.com>
…ests Thufir (review at b570318) found that a present-but-empty or whitespace-only kind:0 `displayName` is not nullish, so the `??` chain stopped early and the detail pane rendered 'Added by ' with a blank label. Replace `??` with truthy short-circuit on trimmed values, and extract the derivation into `resolveCatalogOwnerLabel` so it can be exercised directly. Unit tests cover: populated displayName wins; whitespace-only displayName falls through to name; both candidates empty/whitespace/null/undefined all fall through to 'Community member'. Co-authored-by: Will Pfleger <pfleger.will@gmail.com> Signed-off-by: Will Pfleger <pfleger.will@gmail.com>
wpfleger96
force-pushed
the
hayt/catalog-owner-display-name
branch
from
July 30, 2026 15:12
b570318 to
f1a03bd
Compare
wpfleger96
added a commit
that referenced
this pull request
Jul 30, 2026
…chive * origin/main: (22 commits) feat(catalog): resolve publisher display name in catalog detail pane (#3640) feat(mesh): upgrade embedded mesh to v0.74 and harden shared compute (split 1/2 of #3467) (#3741) docs(nips): specify kind:30621 multi-repo projects (NIP-MP) (#3163) Refine agent sharing dialog (#3699) desktop: enable getUserMedia in the Linux WebKitGTK webview (#3607) fix: align responsive agent views (#3688) Add macOS agent menu-bar menu (#3565) Fix pending message feedback (#3543) fix(desktop): remove remaining Projects panel fills (#3742) feat(mobile): desktop-parity emoji and thread experience (#3485) desktop: restore direct community member adds (#3634) fix(desktop): explain open agent access (#2561) fix(cli): resolve agents from owner records (#3178) fix(desktop): remove Projects overview card fills (#3416) feat(replica): portable heartbeat-token fence with snapshot-local reader routing (#3268) fix(git): channel binding tooling + author remediation for unbound repos (#3626) feat: configure S3 URL addressing style (#3400) feat: add first-class OpenRouter provider support (#1975) feat(agent,acp): wire provider total_tokens through NIP-AM publish chain (#3593) chore(release): release Buzz Desktop version 0.5.2 (#3624) ... Signed-off-by: Will Pfleger <pfleger.will@gmail.com>
wpfleger96
pushed a commit
that referenced
this pull request
Jul 30, 2026
…g-pipeline * origin/main: feat(catalog): resolve publisher display name in catalog detail pane (#3640) feat(mesh): upgrade embedded mesh to v0.74 and harden shared compute (split 1/2 of #3467) (#3741) docs(nips): specify kind:30621 multi-repo projects (NIP-MP) (#3163) Signed-off-by: npub1mn7jgtj4w2pd0g0zeuhxsa6jy6p0rewxz4kujt98my82ahfmp72sxjexk7 <dcfd242e557282d7a1e2cf2e6877522682f1e5c6156dc92ca7d90eaedd3b0f95@buzz.block.builderlab.xyz>
joahg
added a commit
to joahg/buzz-dev-mode
that referenced
this pull request
Jul 30, 2026
…-style * origin/main: fix(acp): preserve truncated thread context (block#3340) feat(catalog): resolve publisher display name in catalog detail pane (block#3640) feat(mesh): upgrade embedded mesh to v0.74 and harden shared compute (split 1/2 of block#3467) (block#3741) docs(nips): specify kind:30621 multi-repo projects (NIP-MP) (block#3163) Refine agent sharing dialog (block#3699) desktop: enable getUserMedia in the Linux WebKitGTK webview (block#3607) fix: align responsive agent views (block#3688) Add macOS agent menu-bar menu (block#3565) Fix pending message feedback (block#3543) fix(desktop): remove remaining Projects panel fills (block#3742) feat(mobile): desktop-parity emoji and thread experience (block#3485) desktop: restore direct community member adds (block#3634) fix(desktop): explain open agent access (block#2561) fix(cli): resolve agents from owner records (block#3178) fix(desktop): remove Projects overview card fills (block#3416) feat(replica): portable heartbeat-token fence with snapshot-local reader routing (block#3268) Signed-off-by: Joah Gerstenberg <joah@squareup.com>
wpfleger96
added a commit
that referenced
this pull request
Jul 30, 2026
* origin/main: (59 commits) Fix video reviews in thread replies (#3719) feat(release): make desktop releases immutable (#3568) Make relay reconnect backoff authoritative (#3774) feat(desktop): add password-protected backups in settings (#3701) fix(desktop): reuse profiles when joining communities (#2155) Render mobile agent mention chips (#3702) fix(catalog): update Amp description (#3758) fix(acp): preserve truncated thread context (#3340) feat(catalog): resolve publisher display name in catalog detail pane (#3640) feat(mesh): upgrade embedded mesh to v0.74 and harden shared compute (split 1/2 of #3467) (#3741) docs(nips): specify kind:30621 multi-repo projects (NIP-MP) (#3163) Refine agent sharing dialog (#3699) desktop: enable getUserMedia in the Linux WebKitGTK webview (#3607) fix: align responsive agent views (#3688) Add macOS agent menu-bar menu (#3565) Fix pending message feedback (#3543) fix(desktop): remove remaining Projects panel fills (#3742) feat(mobile): desktop-parity emoji and thread experience (#3485) desktop: restore direct community member adds (#3634) fix(desktop): explain open agent access (#2561) ... # Conflicts: # desktop/scripts/check-file-sizes.mjs
wpfleger96
pushed a commit
that referenced
this pull request
Jul 30, 2026
* origin/main: (29 commits) feat(desktop): raise the install ceiling and make installs observable (#3368) fix(db): isolate usage metrics advisory-lock test on scratch DB (#3670) Add Devin as a preset ACP harness (#3225) feat(desktop): improve agent activity header ui (#3321) perf(presence): reduce heartbeat frequency (#3783) Tighten continuation message rows (#3724) Fix video reviews in thread replies (#3719) feat(release): make desktop releases immutable (#3568) Make relay reconnect backoff authoritative (#3774) feat(desktop): add password-protected backups in settings (#3701) fix(desktop): reuse profiles when joining communities (#2155) Render mobile agent mention chips (#3702) fix(catalog): update Amp description (#3758) fix(acp): preserve truncated thread context (#3340) feat(catalog): resolve publisher display name in catalog detail pane (#3640) feat(mesh): upgrade embedded mesh to v0.74 and harden shared compute (split 1/2 of #3467) (#3741) docs(nips): specify kind:30621 multi-repo projects (NIP-MP) (#3163) Refine agent sharing dialog (#3699) desktop: enable getUserMedia in the Linux WebKitGTK webview (#3607) fix: align responsive agent views (#3688) ... Signed-off-by: npub1g8493u0xfsjrvflg4n08ezd7vec99mnwzlv0qgwpr9d7gvjwhuzqx59rhw <41ea58f1e64c243627e8acde7c89be667052ee6e17d8f021c1195be4324ebf04@buzz.block.builderlab.xyz>
wpfleger96
added a commit
that referenced
this pull request
Jul 31, 2026
Main's agent-sharing UI changed during the branch's review arc: - PersonaShareDialog (PR #3699, Jul 30): replaced the catalog-share dropdown (SnapshotOptionMenu "Not shared"/"Shared") with a plain Switch (aria-label="Share to catalog", checked = shared). - PersonaCatalogDialog (PR #3640): added resolveCatalogOwnerLabel + useUsersBatchQuery to the detail pane, showing "Added by <display name>" instead of a hardcoded "Community member" fallback. TeamShareDialog: adopt the Switch pattern, removing the SnapshotOptionMenu and the now-unused teamCatalogCopy.shareAriaLabel / notSharedOption / sharedOption keys. TeamCatalogDialog: wire resolveCatalogOwnerLabel + useUsersBatchQuery into TeamCatalogDetail, mirroring PersonaCatalogDetail exactly. Community entries now resolve the owner's display name / username; own entries still show "You". Full audit performed against PersonaShareDialog and PersonaCatalogDialog at origin/main — no other structural divergences found beyond these two. Playwright specs updated: setTeamCatalogAccess now uses Switch semantics (.isChecked() / .click()), the share-access-menu screenshot removed (no open dropdown in the Switch pattern), and the "Added by" assertion updated to the resolved username. Co-authored-by: Will Pfleger <pfleger.will@gmail.com> Signed-off-by: Will Pfleger <pfleger.will@gmail.com>
wpfleger96
added a commit
that referenced
this pull request
Jul 31, 2026
…unity catalog Adds kind:30178 projection builder and v1 size contract, publish/unshare/ tombstone, workspace-apply freshness with automatic retraction, atomic add_team_from_catalog with backend head verification, member provenance, TeamShareDialog/catalog UI, and reuse of the persona-sharing machinery. Key design decisions and invariants: - v1 size contract: MAX_TOTAL_BYTES 192 KiB, MAX_SYSTEM_PROMPT_BYTES 16 KiB, MAX_AVATAR_URL_BYTES 32 KiB, MAX_MEMBERS 64. - Member identity: SHA-256 of (owner_pubkey || persona_id) as member_key, preventing key collapse across publishers. - Projection freshness: workspace-apply rebuilds retained shared 30178 heads; failed rebuilds (size violation, missing member, resolution failure) immediately purge+tombstone the shared head and emit a typed notice. - Allowlist mode normalized to owner-only at adoption (source pubkeys never published; empty allowlist would fail mint). - Built-in avatar normalization: oversized install-local avatars silently stripped for canonical built-ins; non-built-ins get deterministic rejection. - Transactional purge+tombstone: DELETE + INSERT kind:5 in one BEGIN IMMEDIATE transaction so a process kill cannot leave a relay head shared indefinitely. - Byte-level rollback: both persona and team stores snapshot before any write; independent restores on failure with error aggregation. - Agent-ref preservation: catalog copy deactivation skips any copy whose ID is referenced by a remaining team's persona_ids OR a managed agent's persona_id — prevents deleting a catalog team from breaking a standalone agent. - URL safety contract: UTF-8 byte cap (2048) → ECMAScript-\s/paren rejection (exact WHATWG equivalence: char::is_whitespace() - U+0085 + U+FEFF) → url::Url::parse → normalized http/https scheme check. Identical algorithm on both Rust and TypeScript sides proven by 4200-case cross-runtime corpus. - E2E tie-break: mock bridge returns events in created_at DESC, id ASC order matching relay behavior for equal-second arrivals. - UI aligned with current agent-sharing patterns: TeamShareDialog uses Switch (not SnapshotOptionMenu) for the catalog-share control, matching PersonaShareDialog post-#3699; TeamCatalogDialog uses resolveCatalogOwnerLabel + useUsersBatchQuery for publisher attribution, matching PersonaCatalogDialog post-#3640. Co-authored-by: Will Pfleger <pfleger.will@gmail.com> Signed-off-by: Will Pfleger <pfleger.will@gmail.com>
wpfleger96
added a commit
that referenced
this pull request
Jul 31, 2026
…unity catalog Adds kind:30178 projection builder and v1 size contract, publish/unshare/ tombstone, workspace-apply freshness with automatic retraction, atomic add_team_from_catalog with backend head verification, member provenance, TeamShareDialog/catalog UI, and reuse of the persona-sharing machinery. Key design decisions and invariants: - v1 size contract: MAX_TOTAL_BYTES 192 KiB, MAX_SYSTEM_PROMPT_BYTES 16 KiB, MAX_AVATAR_URL_BYTES 32 KiB, MAX_MEMBERS 64. - Member identity: SHA-256 of (owner_pubkey || persona_id) as member_key, preventing key collapse across publishers. - Projection freshness: workspace-apply rebuilds retained shared 30178 heads; failed rebuilds (size violation, missing member, resolution failure) immediately purge+tombstone the shared head and emit a typed notice. - Allowlist mode normalized to owner-only at adoption (source pubkeys never published; empty allowlist would fail mint). - Built-in avatar normalization: oversized install-local avatars silently stripped for canonical built-ins; non-built-ins get deterministic rejection. - Transactional purge+tombstone: DELETE + INSERT kind:5 in one BEGIN IMMEDIATE transaction so a process kill cannot leave a relay head shared indefinitely. - Byte-level rollback: both persona and team stores snapshot before any write; independent restores on failure with error aggregation. - Agent-ref preservation: catalog copy deactivation skips any copy whose ID is referenced by a remaining team's persona_ids OR a managed agent's persona_id — prevents deleting a catalog team from breaking a standalone agent. - URL safety contract: UTF-8 byte cap (2048) → ECMAScript-\s/paren rejection (exact WHATWG equivalence: char::is_whitespace() - U+0085 + U+FEFF) → url::Url::parse → normalized http/https scheme check. Identical algorithm on both Rust and TypeScript sides proven by 4200-case cross-runtime corpus. - E2E tie-break: mock bridge returns events in created_at DESC, id ASC order matching relay behavior for equal-second arrivals. - UI aligned with current agent-sharing patterns: TeamShareDialog uses Switch (not SnapshotOptionMenu) for the catalog-share control, matching PersonaShareDialog post-#3699; TeamCatalogDialog uses resolveCatalogOwnerLabel + useUsersBatchQuery for publisher attribution, matching PersonaCatalogDialog post-#3640. - Detail pane exposes full configuration: each member row is expandable (accordion with aria-expanded, keyboard-operable) showing AgentDefinitionMetadata (model/runtime/provider) + member system prompt; team-level instructions render below the description when set. AgentDefinitionMetadata gains an optional provider prop used by both catalogs (persona and team), rendering "Preferred provider" cell when present. Co-authored-by: Will Pfleger <pfleger.will@gmail.com> Signed-off-by: Will Pfleger <pfleger.will@gmail.com>
calvadev
pushed a commit
to shopstr-eng/buzz
that referenced
this pull request
Aug 3, 2026
…lock#3640) The catalog detail pane hardcoded "Community member" for every non-own catalog entry. The publisher pubkey (`catalogSource.ownerPubkey`) was already on every entry — it just was not being resolved to a name. ## What changed **`desktop/src/features/agents/ui/PersonaCatalogDialog.tsx`** `PersonaCatalogDetail` now calls `useUsersBatchQuery([ownerPubkey])` when the selected entry is a community (non-own) catalog agent. The label derivation is extracted into the exported pure function `resolveCatalogOwnerLabel` and uses truthy fallbacks to handle empty or whitespace-only kind:0 fields: - Own entry → `"You"` (unchanged) - `displayName` present and non-blank → the display name - `displayName` absent/blank but `name` present and non-blank → the name - Loading, unresolvable, or both candidates blank → `"Community member"` (fallback preserved) The batch query is disabled (`enabled: false`) when the entry is not a community entry, so there is no extra network call for own entries or built-in agents. **`desktop/src/features/agents/ui/personaCatalogOwnerLabel.test.mjs`** Unit tests for `resolveCatalogOwnerLabel` covering: populated `displayName` wins; whitespace-only `displayName` falls through to `name`; both candidates empty/whitespace/null/undefined all fall through to `"Community member"`. **`desktop/tests/e2e/agents.spec.ts`** - Updated the existing assertion — it previously checked for the hardcoded fallback; now asserts the resolved mock display name `"alice"`. - Added "catalog detail shows Community member when the publisher profile cannot be resolved" — installs a catalog event from an unknown pubkey and asserts the fallback still renders. --------- Signed-off-by: Will Pfleger <pfleger.will@gmail.com> Co-authored-by: npub1g8493u0xfsjrvflg4n08ezd7vec99mnwzlv0qgwpr9d7gvjwhuzqx59rhw <41ea58f1e64c243627e8acde7c89be667052ee6e17d8f021c1195be4324ebf04@buzz.block.builderlab.xyz>
wpfleger96
added a commit
that referenced
this pull request
Aug 3, 2026
…unity catalog Adds kind:30178 projection builder and v1 size contract, publish/unshare/ tombstone, workspace-apply freshness with automatic retraction, atomic add_team_from_catalog with backend head verification, member provenance, TeamShareDialog/catalog UI, and reuse of the persona-sharing machinery. Key design decisions and invariants: - v1 size contract: MAX_TOTAL_BYTES 192 KiB, MAX_SYSTEM_PROMPT_BYTES 16 KiB, MAX_AVATAR_URL_BYTES 32 KiB, MAX_MEMBERS 64. - Member identity: SHA-256 of (owner_pubkey || persona_id) as member_key, preventing key collapse across publishers. - Projection freshness: workspace-apply rebuilds retained shared 30178 heads; failed rebuilds (size violation, missing member, resolution failure) immediately purge+tombstone the shared head and emit a typed notice. - Allowlist mode normalized to owner-only at adoption (source pubkeys never published; empty allowlist would fail mint). - Built-in avatar normalization: oversized install-local avatars silently stripped for canonical built-ins; non-built-ins get deterministic rejection. - Transactional purge+tombstone: DELETE + INSERT kind:5 in one BEGIN IMMEDIATE transaction so a process kill cannot leave a relay head shared indefinitely. - Byte-level rollback: both persona and team stores snapshot before any write; independent restores on failure with error aggregation. - Agent-ref preservation: catalog copy deactivation skips any copy whose ID is referenced by a remaining team's persona_ids OR a managed agent's persona_id — prevents deleting a catalog team from breaking a standalone agent. - URL safety contract: UTF-8 byte cap (2048) → ECMAScript-\s/paren rejection (exact WHATWG equivalence: char::is_whitespace() - U+0085 + U+FEFF) → url::Url::parse → normalized http/https scheme check. Identical algorithm on both Rust and TypeScript sides proven by 4200-case cross-runtime corpus. - E2E tie-break: mock bridge returns events in created_at DESC, id ASC order matching relay behavior for equal-second arrivals. - UI aligned with current agent-sharing patterns: TeamShareDialog uses Switch (not SnapshotOptionMenu) for the catalog-share control, matching PersonaShareDialog post-#3699; TeamCatalogDialog uses resolveCatalogOwnerLabel + useUsersBatchQuery for publisher attribution, matching PersonaCatalogDialog post-#3640. - Detail pane exposes full configuration: each member row is expandable (accordion with aria-expanded, keyboard-operable) showing AgentDefinitionMetadata (model/runtime/provider) + member system prompt; team-level instructions render below the description when set. AgentDefinitionMetadata gains an optional provider prop used by both catalogs (persona and team), rendering "Preferred provider" cell when present. Co-authored-by: Will Pfleger <pfleger.will@gmail.com> Signed-off-by: Will Pfleger <pfleger.will@gmail.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
The catalog detail pane hardcoded "Community member" for every non-own catalog entry. The publisher pubkey (
catalogSource.ownerPubkey) was already on every entry — it just was not being resolved to a name.What changed
desktop/src/features/agents/ui/PersonaCatalogDialog.tsxPersonaCatalogDetailnow callsuseUsersBatchQuery([ownerPubkey])when the selected entry is a community (non-own) catalog agent. The label derivation is extracted into the exported pure functionresolveCatalogOwnerLabeland uses truthy fallbacks to handle empty or whitespace-only kind:0 fields:"You"(unchanged)displayNamepresent and non-blank → the display namedisplayNameabsent/blank butnamepresent and non-blank → the name"Community member"(fallback preserved)The batch query is disabled (
enabled: false) when the entry is not a community entry, so there is no extra network call for own entries or built-in agents.desktop/src/features/agents/ui/personaCatalogOwnerLabel.test.mjsUnit tests for
resolveCatalogOwnerLabelcovering: populateddisplayNamewins; whitespace-onlydisplayNamefalls through toname; both candidates empty/whitespace/null/undefined all fall through to"Community member".desktop/tests/e2e/agents.spec.ts"alice".