Discord: allow /acp inline action#32777
Conversation
Greptile SummaryThis PR fixes a regression where typing Key changes:
Notes for reviewers:
Confidence Score: 4/5
Last reviewed commit: a7d0868 |
| const forceAutocomplete = command.key === "acp" && arg.name === "action"; | ||
| const shouldAutocomplete = | ||
| resolvedChoices.length > 0 && | ||
| (typeof arg.choices === "function" || resolvedChoices.length > 25); | ||
| (forceAutocomplete || typeof arg.choices === "function" || resolvedChoices.length > 25); |
There was a problem hiding this comment.
Hard-coded command key in generic function
forceAutocomplete embeds command-specific knowledge ("acp" / "action") directly inside the generic buildDiscordCommandOptions function. Several other commands share the same structure — static choices arrays with fewer than 25 items (e.g. /subagents action, /tts action, /session action) — and would face the same inline-arg regression if Discord's behaviour applies to them too. Adding entries here each time would keep widening this special-case block.
A more extensible approach would be to add a forceAutocomplete?: boolean field to CommandArgDefinition and set it on the acp action arg at the definition site in commands-registry.data.ts, keeping this function generic:
// In commands-registry.data.ts, acp action arg:
{
name: "action",
description: "Action to run",
type: "string",
forceAutocomplete: true,
choices: [ "spawn", "cancel", ... ],
}
// In native-command.ts:
const forceAutocomplete = arg.forceAutocomplete === true;This is a design preference for now — the current approach works correctly for the targeted fix — but worth noting if similar issues arise on other commands.
Prompt To Fix With AI
This is a comment left during a code review.
Path: src/discord/monitor/native-command.ts
Line: 118-121
Comment:
**Hard-coded command key in generic function**
`forceAutocomplete` embeds command-specific knowledge (`"acp"` / `"action"`) directly inside the generic `buildDiscordCommandOptions` function. Several other commands share the same structure — static choices arrays with fewer than 25 items (e.g. `/subagents action`, `/tts action`, `/session action`) — and would face the same inline-arg regression if Discord's behaviour applies to them too. Adding entries here each time would keep widening this special-case block.
A more extensible approach would be to add a `forceAutocomplete?: boolean` field to `CommandArgDefinition` and set it on the `acp` `action` arg at the definition site in `commands-registry.data.ts`, keeping this function generic:
```typescript
// In commands-registry.data.ts, acp action arg:
{
name: "action",
description: "Action to run",
type: "string",
forceAutocomplete: true,
choices: [ "spawn", "cancel", ... ],
}
// In native-command.ts:
const forceAutocomplete = arg.forceAutocomplete === true;
```
This is a design preference for now — the current approach works correctly for the targeted fix — but worth noting if similar issues arise on other commands.
How can I resolve this? If you propose a fix, please make it concise.Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!
| const shouldAutocomplete = | ||
| resolvedChoices.length > 0 && | ||
| (typeof arg.choices === "function" || resolvedChoices.length > 25); | ||
| (forceAutocomplete || typeof arg.choices === "function" || resolvedChoices.length > 25); |
There was a problem hiding this comment.
forceAutocomplete is silently suppressed when choices are absent
Despite the name implying an unconditional override, forceAutocomplete has no effect when resolvedChoices.length === 0 because of the outer && guard:
const shouldAutocomplete =
resolvedChoices.length > 0 && // ← still blocks when choices = []
(forceAutocomplete || ...);Currently this is safe — the acp action arg always carries 15 static choices — but if someone ever refactored those choices away, the flag would silently stop working with no error or warning. Consider restructuring to make the intent explicit:
| const shouldAutocomplete = | |
| resolvedChoices.length > 0 && | |
| (typeof arg.choices === "function" || resolvedChoices.length > 25); | |
| (forceAutocomplete || typeof arg.choices === "function" || resolvedChoices.length > 25); | |
| const shouldAutocomplete = | |
| forceAutocomplete | |
| ? resolvedChoices.length > 0 // need choices to respond with | |
| : resolvedChoices.length > 0 && (typeof arg.choices === "function" || resolvedChoices.length > 25); |
This makes the dependency on choices explicit for the forced case while keeping the same runtime semantics.
Prompt To Fix With AI
This is a comment left during a code review.
Path: src/discord/monitor/native-command.ts
Line: 119-121
Comment:
**`forceAutocomplete` is silently suppressed when choices are absent**
Despite the name implying an unconditional override, `forceAutocomplete` has no effect when `resolvedChoices.length === 0` because of the outer `&&` guard:
```typescript
const shouldAutocomplete =
resolvedChoices.length > 0 && // ← still blocks when choices = []
(forceAutocomplete || ...);
```
Currently this is safe — the `acp action` arg always carries 15 static choices — but if someone ever refactored those choices away, the flag would silently stop working with no error or warning. Consider restructuring to make the intent explicit:
```suggestion
const shouldAutocomplete =
forceAutocomplete
? resolvedChoices.length > 0 // need choices to respond with
: resolvedChoices.length > 0 && (typeof arg.choices === "function" || resolvedChoices.length > 25);
```
This makes the dependency on choices explicit for the forced case while keeping the same runtime semantics.
How can I resolve this? If you propose a fix, please make it concise.|
Superseded by #33136, which consolidates the /acp inline action autocomplete fix plus the bound-thread bot system message guard. Closing in favor of that PR. |
Summary
Describe the problem and fix in 2–5 bullets:
/acp closesendaction=nulland always show the menu./acpactionoption so Discord passes typed values through.Change Type (select all)
Scope (select all touched areas)
Linked Issue/PR
User-visible / Behavior Changes
/acpaccepts inline action values (e.g./acp close) without forcing the picker menu.Security Impact (required)
Yes, explain risk + mitigation:Repro + Verification
Environment
Steps
/acp closeand submit.Expected
/acp closeexecutes directly without opening the action picker.Actual
Evidence
Attach at least one:
Human Verification (required)
What you personally verified (not just CI), and how:
Compatibility / Migration
Failure Recovery (if this breaks)
src/discord/monitor/native-command.ts/acpautocompletion not showing choices.Risks and Mitigations