Skip to content

fix(chat): drop canon alias that duplicates a pairs command - #808

Merged
fathah merged 1 commit into
fathah:mainfrom
AmirF194:fix/slash-catalog-alias-name-collision
Jul 3, 2026
Merged

fix(chat): drop canon alias that duplicates a pairs command#808
fathah merged 1 commit into
fathah:mainfrom
AmirF194:fix/slash-catalog-alias-name-collision

Conversation

@AmirF194

@AmirF194 AmirF194 commented Jul 3, 2026

Copy link
Copy Markdown
Contributor

Summary

Fixes a crash on agent connect: Duplicate slash command alias: /compact.

The desktop reconciles the gateway's two-part command catalog — the flat pairs command list and the canon alias map — in agentCommandsFromCatalog(). When building the alias map it validated the alias's target (seen.has(target)) but never checked whether the alias name itself was already a first-class command from pairs.

The backend can legitimately expose the same name as both:

  • /compact ships as a standalone TUI command in _TUI_EXTRA → lands in pairs.
  • Since hermes-agent PR #57029, /compact is also an alias of /compress → populates canon["/compact"] = "/compress".

So the reconciled catalog listed /compact in both commands and aliases. createSlashCatalog() then registered it as a command and again as an alias, and registerAlias() threw Duplicate slash command alias: /compact, crashing the app during the initial "getting started" flow.

Fix

Skip any canon alias whose normalized name is already a pairs-derived command, so the reconciled catalog is self-consistent:

if (seen.has(alias)) continue;

The standalone command wins deterministically. I deliberately fixed this at the reconciliation source rather than loosening createSlashCatalog's throw-on-collision check — that throw is intentional validation for genuine desktop-authoring conflicts and is covered by existing tests, so it stays intact.

Verification

  • Added a regression test (drops a canon alias whose name is already a standalone command) that reproduces the exact /compact scenario. It fails without this change and passes with it.
  • npm test — full suite green except 3 pre-existing failures in ConfigHealthBanner.test.tsx (localStorage.clear is not a function, a jsdom mock issue on main), unrelated to this change.
  • npm run lint — 0 errors; the touched files are prettier- and eslint-clean.
  • npm run typecheck — passes.

Honesty note: I verified this via the unit test that reproduces the crash path. I did not run the packaged Electron app against a live hermes-agent v0.18 backend (no paired backend in my environment), so end-to-end confirmation on-device would be welcome.

Fixes #802
Fixes #804

agentCommandsFromCatalog reconciles the gateway's two-part command
catalog (flat `pairs` list + `canon` alias map). It filtered aliases by
target but never checked whether the alias name itself was already a
first-class command from `pairs`. When the backend exposes a name as
both — e.g. `/compact` is a standalone TUI command and, since
hermes-agent PR #57029, an alias of `/compress` — the reconciled catalog
listed `/compact` in both `commands` and `aliases`. createSlashCatalog
then registered it as a command and again as an alias, and registerAlias
threw `Duplicate slash command alias: /compact`, crashing the app on
agent connect.

Skip any canon alias whose normalized name is already a pairs-derived
command so the reconciled catalog stays self-consistent. The standalone
command wins deterministically; createSlashCatalog's throw-on-collision
validation (which guards genuine desktop-authoring conflicts) is left
intact.

Fixes fathah#802
Fixes fathah#804
@greptile-apps

greptile-apps Bot commented Jul 3, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR fixes slash command catalog reconciliation for duplicate backend names.

  • Drops canon aliases that already exist as standalone pairs commands.
  • Adds a regression test for the /compact and /compress catalog shape.
  • Documents why the reconciler keeps command names and alias names disjoint.

Confidence Score: 5/5

This looks safe to merge.

  • No blocking issues found in the changed code.
  • The new guard matches the downstream catalog rule that one slash name cannot be both a command and an alias.
  • The regression test covers the crash path described in the PR.

Important Files Changed

Filename Overview
src/renderer/src/screens/Chat/slash/commandCatalog.ts Skips colliding backend aliases before catalog creation so duplicate slash names do not crash the app.
src/renderer/src/screens/Chat/slash/commandCatalog.test.ts Adds regression coverage for a backend catalog where /compact appears as both a standalone command and an alias.
lat.md/chat-commands.md Documents the reconciliation rule for overlapping backend command and alias names.

Reviews (1): Last reviewed commit: "fix(chat): drop canon alias that duplica..." | Re-trigger Greptile

@fathah
fathah merged commit 7b7e3aa into fathah:main Jul 3, 2026
1 check passed
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.

Duplicate slash command alias: /compact crashes app on agent connect Slash-command catalog merge throws on any name collision, crashes app startup

2 participants