Skip to content

feat(desktop): autocomplete ACP slash commands - #2653

Open
kevinmanase wants to merge 1 commit into
block:mainfrom
kevinmanase:feat/2528-agent-command-autocomplete
Open

feat(desktop): autocomplete ACP slash commands#2653
kevinmanase wants to merge 1 commit into
block:mainfrom
kevinmanase:feat/2528-agent-command-autocomplete

Conversation

@kevinmanase

@kevinmanase kevinmanase commented Jul 24, 2026

Copy link
Copy Markdown

Summary

  • forward ACP available_commands_update notifications as encrypted semantic observer snapshots
  • persist the latest bounded command catalog per owner and agent, including trusted archive hydration
  • add grouped slash-command autocomplete at message start or after leading agent mentions
  • route start-of-message selections through the chosen agent mention and register its exact pubkey

Behavior

Typing / at the start of a message shows commands advertised by agent members in the channel. Typing / after one or more leading @Agent mentions narrows suggestions to those agents. Duplicate command names stay grouped by provider, empty updates remove stale commands, and catalogs survive app restarts.

Testing

  • pnpm --dir desktop test (3,466 passing)
  • pnpm --dir desktop check
  • pnpm --dir desktop typecheck
  • pnpm --dir desktop build
  • cargo test -p buzz-acp available_commands_update_emits_complete_semantic_snapshot
  • cargo clippy -p buzz-acp --all-targets -- -D warnings
  • cargo fmt --all -- --check

Fixes #2528

@kevinmanase
kevinmanase requested a review from a team as a code owner July 24, 2026 00:31
Signed-off-by: kevb10 <gasydev@gmail.com>
@rshiozaki

Copy link
Copy Markdown

We'd like to see this land, so we did a full review of this PR against today's main (22cdda4) and revived the branch. TL;DR: the implementation is solid, and we've prepared a conflict-free, test-green rebase that @kevinmanase or maintainers are welcome to take over: https://github.com/rshiozaki/buzz/tree/rebase/acp-slash-autocomplete

Review findings

Strengths:

  • Persistence design is right. available_commands_captured observer frames feed a per-owner+agent localStorage catalog; both the live and archive ingestion paths record it, and restart survival is covered by tests.
  • Scoping avoids the union-menu trap. With no mention typed, suggestions group per agent rather than merging into one ambiguous list; selecting inserts @Agent /cmd and registers the exact pubkey; leading mentions narrow the list.
  • Advertised data is treated as untrusted: name ≤128 chars (no whitespace), description ≤512, ≤256 commands per agent, deduped, re-sanitized on hydrate, plain-text rendering only.
  • Staleness handling: newer (ts, seq) wins, and an empty available_commands_update is honored as an authoritative removal (tested).

Gaps worth follow-ups (not blockers in our view):

  • No visual distinction between built-in commands and discovered skills — the catalog is a flat {name, description}.
  • A command that has gone stale by send time fails silently; there's no send-time revalidation or freshness hint in the UI.
  • Sanitization bounds lengths/counts but doesn't strip control or bidi characters.
  • One undisclosed limitation worth stating in the PR body: catalogs only populate for agents the current user owns (observer frames are encrypted to the owner), so a teammate's agent shows no commands. Reasonable for v1, but the longer-term shape probably wants a signed per-agent advertisement event any channel member can read — happy to write that up as a design issue if there's interest.
  • With two or more leading mentions, an inserted /cmd addresses all mentioned agents rather than one.

What the rebased branch adds

All feature credit to @kevinmanase; we started from the conflict resolutions in #3537 (thanks to its author too) and brought it the rest of the way:

  • Rebased onto today's main — the original branch was 687 commits behind and merge-dirty; three conflict sites resolved (MessageComposer.tsx composer-dock changes, localStorageQuota.ts prefixes, check-file-sizes.mjs).
  • File-size gate satisfied without an override. The feature pushed MessageComposer.tsx to 1,047 lines; the original commit slipped under the 1,000-line gate via an override mechanism that has since been removed from the repo. We extracted the shared autocomplete insertion path and picker keydown chain into a sibling hook (useComposerAutocompleteInsertions.ts), following the existing composer hook pattern — the composer is now 968 lines, below where main already is (999).
  • Green on today's main: full desktop unit suite (5,578 tests, 0 failures), tsc --noEmit, biome, and the agent-harness Rust tests including this feature's snapshot test.

Related work, for cross-reference: this implements #2528 and also covers the ask in #5741; #6567 builds the picker-chip UI for the same space but without persistence or the typed-/ path.

Happy to open the rebased branch as a fresh PR, or hand it off however is easiest — whichever the maintainers prefer.

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.

feat(desktop): slash-command autocomplete in composer from ACP available_commands_update (follow-up to #919)

2 participants