[Feat] Gateway: add commands.list RPC method#62656
Conversation
Greptile SummaryThis PR adds a Confidence Score: 5/5Safe to merge; purely additive change with no impact on existing behavior. No P0 or P1 issues found. The only finding is a P2 test fixture inaccuracy where a skill command's scope doesn't match what production code generates, which does not represent a logic bug. All other aspects — scope filtering, skill detection, plugin passthrough, schema alignment with CommandCategory, and gateway wiring — are correct. No files require special attention. Prompt To Fix All With AIThis is a comment left during a code review.
Path: src/gateway/server-methods/commands.test.ts
Line: 47-55
Comment:
**Skill fixture scope mismatches production**
The mock skill command uses `scope: "native"`, but `buildSkillCommandDefinitions` in `src/auto-reply/commands-registry.ts` always produces skill commands with `scope: "both"`. As a result, the `scope: "text"` filtering test never exercises the real production path where skills pass through because `"both"` satisfies any filter. Aligning the fixture to `"both"` and adding an assertion for the `scope: "text"` case would close this gap.
```suggestion
{
key: "skill:code-review",
nativeName: "code_review",
description: "Run code review",
textAliases: [],
acceptsArgs: true,
scope: "both",
category: "tools",
},
```
How can I resolve this? If you propose a fix, please make it concise.Reviews (1): Last reviewed commit: "Gateway: add commands.list RPC method" | Re-trigger Greptile |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: c266596365
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
|
Re: Greptile P2 (skill fixture scope) — Good catch, fixed in latest push. Fixture now uses Re: Codex P2 (plugin provider passthrough) — Known v1 limitation. |
|
Thanks for adding a proper runtime command catalog. I found one blocker before this is safe to land: the plugin-command branch in Today
So the current RPC can advertise plugin commands to providers that should not expose them, and it can return the wrong plugin command name for providers with native aliases. There is already existing regression coverage for the first contract in Please thread |
71b5af3 to
1f97e28
Compare
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 1f97e28565
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
|
Thanks @frankekn, good catch, fixed in the latest push. |
|
@codex review |
|
Codex Review: Didn't find any major issues. Keep it up! ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
If Codex has suggestions, it will comment; otherwise it will react with 👍. Codex can also answer questions or update the PR. Try commenting "@codex address that feedback". |
1f97e28 to
2807ec5
Compare
|
@codex review |
1512498 to
6ba9557
Compare
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 6ba9557841
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| ...(nativeName ? { nativeName } : {}), | ||
| ...(cmd.scope !== "native" ? { textAliases: resolveTextAliases(cmd) } : {}), | ||
| description: cmd.description, | ||
| ...(cmd.category ? { category: cmd.category } : {}), |
There was a problem hiding this comment.
Assign a category to skill commands in commands.list
commands.list only emits category when cmd.category is already populated, but skill command definitions built from listSkillCommandsForAgents do not set a category (buildSkillCommandDefinitions in src/auto-reply/commands-registry.ts). As a result, every skill entry is returned without category metadata, which breaks category-based grouping/filtering in clients even though this RPC is intended to provide per-command categorization.
Useful? React with 👍 / 👎.
| for (const spec of listPluginCommands()) { | ||
| commands.push({ | ||
| name: spec.name, | ||
| textAliases: [`/${spec.name}`], | ||
| description: spec.description, |
There was a problem hiding this comment.
Include plugin native names in text-surface results
When scope="text", plugin commands are serialized from listPluginCommands() only, so nativeName is never returned even if a provider-specific native alias exists. In the same mode, built-in commands still include nativeName, so clients that request text-surface names but rely on nativeName metadata cannot correctly map plugin commands to provider-native slash names.
Useful? React with 👍 / 👎.
|
Merged. Thanks @samzong |
Merged via squash. Co-authored-by: samzong <[email protected]> Co-authored-by: Frank Yang <[email protected]> Reviewed-by: @frankekn
Merged via squash. Co-authored-by: samzong <[email protected]> Co-authored-by: Frank Yang <[email protected]> Reviewed-by: @frankekn
Replaces the hardcoded STATIC_SLASH_COMMANDS list with a dynamic catalog hydrated from the upstream 'commands.list' RPC (openclaw/openclaw#62656). - shared: add CommandEntry / CommandArg / CommandsListParams / CommandsListResponse types mirroring the Gateway schema (7 categories, source=native|skill|plugin, scope=text|native|both, structured args) - main: new gateway-client.listCommands + ws:commands-list IPC handler; preload bridge + .d.ts exposure - core: GatewayTransportPort.listCommands; ui-store.commandCatalogByGateway + setter; gateway-dispatcher fetches commands in parallel with models/agents/tools/skills on connect - pwa: mirror the same port on the web adapter - renderer: slash-commands.ts rewritten around CommandEntry -> SlashCommandView; NATIVE_OVERLAY preserves choices for /think /fast /verbose /reasoning /usage /elevated /activation when Gateway omits them; mergeWithOverlay composes gateway data with local defaults; alias-aware prefix filter - UI: SlashCommandMenu + SlashCommandDashboard show source badges for skill/plugin; Dashboard gains search input, empty state, fixed-height scroll (no jitter on result count change); shared CommandSourceBadge component - keyboard: rAF re-focus + window-level keydown fallback in useSlashAutocomplete to survive Radix Dialog FocusScope handoff - i18n: 8 locales updated - 7 category keys + 3 source labels + search placeholder + empty state; key parity preserved Signed-off-by: samzong <[email protected]> ## Considered and deferred - packages/desktop/src/renderer/lib/slash-commands.ts [BOT-TASTE]: Default category for uncategorized gateway commands resolves to 'status'. Both 'status' and 'tools' are defensible buckets; upstream CommandEntry.category is optional by schema. Revisit after UX feedback. - packages/desktop/src/renderer/lib/slash-commands.ts [BOT-NIT]: SlashCommandView.acceptsArgs is populated but not currently consumed by any renderer. Kept for parity with upstream CommandEntry shape; safe to drop in a later cleanup. - packages/desktop/src/renderer/lib/slash-commands.ts [BOT-NIT]: getCommandsForGateway runs two sequential .map passes. Cold path (per-reconnect); fuse if profiling ever points here. - packages/desktop/src/renderer/lib/slash-commands.ts [BOT-NIT]: filterSlashCommands lower-cases aliases per keystroke. Negligible for <50 commands; pre-lowercase at view-build time if catalog scales. - packages/desktop/src/renderer/lib/slash-commands.ts [BOT-SCOPE]: No unit tests for mergeWithOverlay / commandEntryToView / detectPickerType / getCommandsForGateway. Follow-up PR to cover overlay precedence and empty-catalog fallback. - packages/shared/src/types.ts [BOT-NIT]: CommandEntry / CommandArg / CommandsListResponse lack JSDoc anchoring to the Gateway upstream schema. Additive types are back-compat; link in a later docs pass. - packages/desktop/src/renderer/components/ChatInput/useSlashAutocomplete.ts [BOT-TASTE]: activeGatewayId selector duplicated in SlashCommandDashboard. Pre-existing pattern across 4+ renderer sites; extract useActiveGatewayId() hook in a cleanup PR. - packages/desktop/src/renderer/components/ChatInput/useSlashAutocomplete.ts [BOT-TASTE]: Window-level keydown fallback survives Radix Dialog FocusScope handoff; document.activeElement guard keeps it a no-op on the happy path. Document the rationale inline in a follow-up. - packages/desktop/src/renderer/components/ChatInput/useSlashAutocomplete.ts [BOT-TASTE]: buildArgOptions reads useTaskStore and useUiStore via getState(). Functionally correct; consider lifting to explicit selectors for surface clarity. Signed-off-by: samzong <[email protected]>
Replaces the hardcoded STATIC_SLASH_COMMANDS list with a dynamic catalog hydrated from the upstream 'commands.list' RPC (openclaw/openclaw#62656). - shared: add CommandEntry / CommandArg / CommandsListParams / CommandsListResponse types mirroring the Gateway schema (7 categories, source=native|skill|plugin, scope=text|native|both, structured args) - main: new gateway-client.listCommands + ws:commands-list IPC handler; preload bridge + .d.ts exposure - core: GatewayTransportPort.listCommands; ui-store.commandCatalogByGateway + setter; gateway-dispatcher fetches commands in parallel with models/agents/tools/skills on connect - pwa: mirror the same port on the web adapter - renderer: slash-commands.ts rewritten around CommandEntry -> SlashCommandView; NATIVE_OVERLAY preserves choices for /think /fast /verbose /reasoning /usage /elevated /activation when Gateway omits them; mergeWithOverlay composes gateway data with local defaults; alias-aware prefix filter - UI: SlashCommandMenu + SlashCommandDashboard show source badges for skill/plugin; Dashboard gains search input, empty state, fixed-height scroll (no jitter on result count change); shared CommandSourceBadge component - keyboard: rAF re-focus + window-level keydown fallback in useSlashAutocomplete to survive Radix Dialog FocusScope handoff - i18n: 8 locales updated - 7 category keys + 3 source labels + search placeholder + empty state; key parity preserved Signed-off-by: samzong <[email protected]> - packages/desktop/src/renderer/lib/slash-commands.ts [BOT-TASTE]: Default category for uncategorized gateway commands resolves to 'status'. Both 'status' and 'tools' are defensible buckets; upstream CommandEntry.category is optional by schema. Revisit after UX feedback. - packages/desktop/src/renderer/lib/slash-commands.ts [BOT-NIT]: SlashCommandView.acceptsArgs is populated but not currently consumed by any renderer. Kept for parity with upstream CommandEntry shape; safe to drop in a later cleanup. - packages/desktop/src/renderer/lib/slash-commands.ts [BOT-NIT]: getCommandsForGateway runs two sequential .map passes. Cold path (per-reconnect); fuse if profiling ever points here. - packages/desktop/src/renderer/lib/slash-commands.ts [BOT-NIT]: filterSlashCommands lower-cases aliases per keystroke. Negligible for <50 commands; pre-lowercase at view-build time if catalog scales. - packages/desktop/src/renderer/lib/slash-commands.ts [BOT-SCOPE]: No unit tests for mergeWithOverlay / commandEntryToView / detectPickerType / getCommandsForGateway. Follow-up PR to cover overlay precedence and empty-catalog fallback. - packages/shared/src/types.ts [BOT-NIT]: CommandEntry / CommandArg / CommandsListResponse lack JSDoc anchoring to the Gateway upstream schema. Additive types are back-compat; link in a later docs pass. - packages/desktop/src/renderer/components/ChatInput/useSlashAutocomplete.ts [BOT-TASTE]: activeGatewayId selector duplicated in SlashCommandDashboard. Pre-existing pattern across 4+ renderer sites; extract useActiveGatewayId() hook in a cleanup PR. - packages/desktop/src/renderer/components/ChatInput/useSlashAutocomplete.ts [BOT-TASTE]: Window-level keydown fallback survives Radix Dialog FocusScope handoff; document.activeElement guard keeps it a no-op on the happy path. Document the rationale inline in a follow-up. - packages/desktop/src/renderer/components/ChatInput/useSlashAutocomplete.ts [BOT-TASTE]: buildArgOptions reads useTaskStore and useUiStore via getState(). Functionally correct; consider lifting to explicit selectors for surface clarity. Signed-off-by: samzong <[email protected]>
Merged via squash. Co-authored-by: samzong <[email protected]> Co-authored-by: Frank Yang <[email protected]> Reviewed-by: @frankekn
Merged via squash. Co-authored-by: samzong <[email protected]> Co-authored-by: Frank Yang <[email protected]> Reviewed-by: @frankekn
Merged via squash. Co-authored-by: samzong <[email protected]> Co-authored-by: Frank Yang <[email protected]> Reviewed-by: @frankekn
Merged via squash. Co-authored-by: samzong <[email protected]> Co-authored-by: Frank Yang <[email protected]> Reviewed-by: @frankekn
Merged via squash. Co-authored-by: samzong <[email protected]> Co-authored-by: Frank Yang <[email protected]> Reviewed-by: @frankekn
Summary
commands.listgateway RPC method that returns a structured, machine-readable list of all available commands (native + skill + plugin) with per-command scope, category, source, and argument definitions. Includes provider-aware native name resolution via channel plugin hooks.commands.changedpush event. No dynamic choices resolution. No command execution via RPC.Change Type (select all)
Scope (select all touched areas)
Linked Issue/PR
Root Cause (if applicable)
N/A — new feature.
Regression Test Plan (if applicable)
N/A — new feature. 15 unit tests added covering:
Evidence
pnpm checkpassing (lint + format + type check)pnpm buildpassing (protocol schema changes affect build output)Human Verification (required)
Review Conversations
Compatibility / Migration
Risks and Mitigations
CommandCategorySchemais a hand-maintained copy of theCommandCategoryTypeScript type. If core adds a new category, the schema must be updated manually.