feat(commands): render agents under their display name in room commands - #343
Open
raullopez-sandbox wants to merge 1 commit into
Open
feat(commands): render agents under their display name in room commands#343raullopez-sandbox wants to merge 1 commit into
raullopez-sandbox wants to merge 1 commit into
Conversation
The `!` command surface still named every agent by its routing identifier, so a room that shows "Switch Dev" everywhere else fell back to "switchdev" the moment someone ran `!list-agents`. Which of the two names a command prints depends on what the reader does next: - `!list-agents`, `!list-all-agents`, `!invite-agent`, `!alias` and the status replies print both — `Switch Dev (`switchdev`)` — because the identifier is what you type back. - `!roles` holders and `!list-documents` creators print the label alone; nobody addresses a document's author. - The room greeting keeps the bare identifier, because "Mention @switchdev" is a live mention token and has to stay one. Listings now sort on the label, so the order matches what is on screen. A display name is user-supplied text landing in a message body, and the bridges rewrite a plain `@handle` into a real mention on the way out — so a display name of `@everyone` was a mass ping waiting to happen. The zero-width defusal that the platform adapters already applied moves into `agent_display_name`, where the command layer shares one implementation of it rather than growing a second. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
raullopez-sandbox
requested review from
amaudruz and
christian-mcdermott
as code owners
September 2, 2026 11:58
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.
Stacked on #338. Review that one first; this diff is only the last commit.
What
The
!command surface was the last place still naming every agent by itsrouting identifier. A room that shows "Switch Dev" in every bridged message
dropped back to "switchdev" the moment anyone ran
!list-agents.Which name a command prints is decided by one question — does the reader
have to type it back?
!list-agents,!list-all-agents,!invite-agent,!alias, status repliesSwitch Dev (`switchdev`)!rolesholders,!list-documentscreatorsSwitch Dev@switchdevListings sort on the label, so the order matches what is on screen rather than
a hidden identifier.
The security half
A display name is text a user typed, and these replies are handed to the
bridge, which escapes nothing on the way out but does rewrite a plain
@handleinto a real mention. A display name of@everyonewould have been amass ping — latent before this feature existed, armed by it.
Every command therefore defuses the label first. The zero-width-space
treatment the platform adapters already applied moves down into
agent_display_nameso the command layer shares that one implementationinstead of growing a second copy:
Invisible to a reader, inert to the mention parser.
Verification
2237 pass (+47), ruff and mypy clean. Beyond the suite I mutation-tested the
six load-bearing claims — every one of them fails the suite when broken:
which is what proves the extraction is genuinely shared rather than a copy)
agent_label/agent_label_with_identifierskipping defusal → 6 / 14switchdev (`switchdev`)→ 12That last one is the one worth keeping: it is the check that stops a later
edit from "consistently" applying the display name to the greeting and
silently breaking the mention it hands out.
🤖 Generated with Claude Code