Skip to content

Add plugin completion protocol#1487

Draft
mnorth-stripe wants to merge 1 commit intosentinel-block-managementfrom
plugin-completion-protocol
Draft

Add plugin completion protocol#1487
mnorth-stripe wants to merge 1 commit intosentinel-block-managementfrom
plugin-completion-protocol

Conversation

@mnorth-stripe
Copy link
Copy Markdown
Contributor

@mnorth-stripe mnorth-stripe commented Mar 15, 2026

Summary

Enables dynamic shell completion for plugin subcommands by invoking the plugin binary with Cobra's __complete protocol and parsing the response. When a user presses tab on a plugin command, the host CLI delegates completion to the plugin process.

Depends on #1485 (sentinel block management).

How it works

  1. User presses tab after a plugin command (e.g., stripe apps <TAB>)
  2. The host CLI invokes the plugin binary with __complete + the current args
  3. The plugin responds with Cobra-format completions (tab-separated name + description, plus a directive line)
  4. The host parses the response and returns it to Cobra's completion system

Key functions

  • GetPluginCompletions: Entry point — looks up the plugin, builds the command, invokes with timeout (3s), parses output
  • parseCompletionOutput: Parses Cobra's __complete output format (completions + :directive)
  • resolvePluginBinary / buildPluginCommand: Locate the plugin binary and construct the invocation, including Node.js runtime detection
  • ValidArgsFunction: Wired into plugin template commands to enable Cobra's completion system

Relationship to --map (#1481)

This PR and the --map flag (#1481) solve different aspects of plugin discoverability through complementary mechanisms:

  • --map uses static registration: plugins declare their command tree in the manifest ([[Plugin.Command]]), and the host CLI creates cobra.Command stubs from that metadata. This works well for structural discoverability because the command tree is stable between plugin install/update cycles.

  • This PR uses runtime invocation: at tab-press time, the host CLI invokes the plugin binary with __complete args and parses the response. This is necessary because completions need to be dynamic (e.g., completing service names from an on-disk catalog cache), context-sensitive (dependent on current subcommand, flags, and positional arg position), and up-to-date (valid values can change between any two tab presses).

Anything cached at the host CLI layer and only refreshed on plugin lifecycle events is inherently limited to structural (Tier 1) information — commands, subcommands, flag names. Dynamic argument values (Tier 2) require invoking the plugin, since only the plugin knows what values are valid for a given argument at a given moment. The __complete protocol provides exactly this: a standardized way to ask the plugin "what are the valid completions right now?"

The two approaches are not competing — --map gives users structural awareness without launching plugins; __complete gives the shell real-time, context-aware completions by asking the plugin directly.

Test plan

  • Protocol parsing: valid output with/without descriptions, all directive values, combined directives
  • Error cases: empty output, missing directive, non-numeric directive, whitespace-only
  • Edge cases: no trailing newline, directive-only (no completions)
  • ValidArgsFunction presence verified on plugin commands
  • Argument parsing regression test for complex flag/arg interactions

PR stack

  1. stripe completion --install Add sentinel block management for shell config files #1485 — sentinel block management (base: fish-completion)
  2. This PR — plugin completion protocol (base: stripe completion --install Add sentinel block management for shell config files #1485)
  3. Add completion auto-install and uninstall #1488 — completion auto-install --install / --uninstall (base: this PR)

@mnorth-stripe
Copy link
Copy Markdown
Contributor Author

PR stack (2 of 3)

  1. stripe completion --install Add sentinel block management for shell config files #1485 — sentinel block management (base: fish-completion)
  2. Add plugin completion protocol #1487 ← you are here — plugin completion protocol (base: stripe completion --install Add sentinel block management for shell config files #1485)
  3. Add completion auto-install and uninstall #1488 — completion auto-install (base: this PR)

@mnorth-stripe mnorth-stripe force-pushed the sentinel-block-management branch from 501737d to abe6b80 Compare March 16, 2026 03:59
@mnorth-stripe mnorth-stripe marked this pull request as draft March 16, 2026 16:05
@mnorth-stripe mnorth-stripe force-pushed the sentinel-block-management branch from abe6b80 to c62925c Compare April 14, 2026 16:31
@mnorth-stripe mnorth-stripe force-pushed the plugin-completion-protocol branch from e0e74b6 to 7a1b460 Compare April 14, 2026 16:36
@mnorth-stripe mnorth-stripe force-pushed the sentinel-block-management branch from c62925c to cd92117 Compare April 14, 2026 17:31
Enables dynamic shell completion for plugin subcommands by invoking
the plugin binary with Cobra's __complete protocol and parsing the
response. When a user presses tab on a plugin command, the host CLI
delegates completion to the plugin process.

- GetPluginCompletions: invokes plugin binary with __complete args,
  parses Cobra-format output (completions + directive)
- parseCompletionOutput: parses the tab-separated completion format
- resolvePluginBinary / buildPluginCommand: locate and construct the
  plugin invocation, including Node.js runtime detection
- Wires ValidArgsFunction into plugin template commands

Committed-By-Agent: claude
@mnorth-stripe mnorth-stripe force-pushed the plugin-completion-protocol branch from 7a1b460 to 463ba73 Compare April 14, 2026 17:39
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.

1 participant