Repository navigation
feat(grok): manage Grok plugins through grok plugin - #602
Merged
Merged
Conversation
Grok's native plugin system behind the provider plugin contract, through its non-interactive CLI only, one bounded process per command (null stdin; with an inherited non-terminal stdin `grok plugin` fails with ENXIO). Verified against grok 1.0.46 in throwaway HOME/GROK_HOME, each operation followed by a native read (fixtures and provenance in tests/fixtures/plugins/grok). - Listing: `plugin list --json --available` and `plugin marketplace list --json`, plus `plugin details` per installed plugin (its description and native text). Marketplace plugins are `name@marketplace`, as `install` takes them; the other commands take the plain name. Grok installs for the user only. - Install: without `--trust` Grok explains what installing activates and prints the command that proceeds. That becomes the existing AcceptCommand challenge (Grok's command and text, bound by their SHA-256), and `--trust` is passed only on a re-run whose challenge still hashes to the accepted value; anything else is shown again. - Update is offered for marketplace installs (it refreshes a git marketplace's checkout itself); a path install is a live link that `update` leaves as it is. - Uninstall is not offered for a plugin of a multi-plugin repository: Grok then needs `--confirm` and removes them all, and the contract's uninstall carries no consent. `--confirm` and `--force` are never passed. - Marketplaces: add and remove. Removal uninstalls the marketplace's plugins, which the listing reports so the host confirms first. - Enable/Disable are left out: no `grok plugin` read reports enablement, and `grok inspect` (text and --json) reports a disabled plugin as enabled; a session confirmed the disabled plugin did not load. ApplyNote gains ReloadOrNextSession: against a running session, an install (skills, commands, hooks, an MCP server) and an update both applied after `/reload-plugins`, and in sessions started afterwards, but not before.
…ils` A plugin installed from a path or a URL has no marketplace, and the listing classified it by whether its `source` parsed as an absolute path on the host. Grok reports the kind itself: `plugin details`, which the listing already runs for every installed plugin, prints `kind: local: <path>` or `kind: git: <url>` per repository. The kind now comes from there, so it no longer depends on the host's path syntax (on Windows the recorded `/tmp/…` source read as a git URL), and a git install is classified from Grok's word instead of by elimination. Recorded against grok 1.0.46: the same two-plugin repository installed from a `file://` URL (`plugin-list-git-install.json`, `details-git-install.txt`), and a relative path install, whose source Grok makes absolute against its cwd.
…eckout The install challenge's SHA-256 is taken over Grok's stderr exactly as printed. A checkout that converts line endings (core.autocrlf on Windows) turned the recorded LF into CRLF, so the test hashed bytes Grok never printed. The fixtures are now never converted. The product needs no change for this: the challenge and its acceptance are both hashed on the host from the same Grok's output, so they agree whatever line endings Grok prints.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Grok plugin management behind the provider-native plugin contract, through
grok pluginonly.Install consent follows the Claude path's rule:
--trustis passed only after the user accepted the challenge whose sha256 is the SHA-256 of Grok's own refusal text.Deliberately not offered, because the CLI cannot report or scope them honestly: enable/disable (no
grok pluginread reports enablement;grok inspectreports a disabled plugin as enabled), uninstall of one plugin from a multi-plugin repository (Grok removes the whole repository), update of path installs. A direct install's source kind comes fromgrok plugin details(kind: local:/kind: git:), never from host path syntax.Evidence
Every operation through the production path (
examples/probe plugins grok) against the realgrok 1.0.46in a throwawayGROK_HOME, each followed by a native read:file://) →grok plugin marketplace list --jsonshowslocal/gitAcceptCommand{sha256: 73bbb8b2…}, native list[]; stale hash → challenge again, native list[]; correct hash →Installed 1 plugin(s) from mkt: alpha, native list showsalpha 1.0.0updated 1.0.0 → 1.1.0(local) and1.0.0 → 1.2.0(git); native list agreesdetails zeta→Plugin "zeta" not found["alpha@mkt"]matches Grok'suninstalled 1 plugin(s): alpha-…Settings → Plugins, Grok section (light, default width): entries with their kind badge (Git / local path), user scope, install path, "enable state unknown", and the apply note. Not looked at: dark theme, narrow width.
Tests replay recorded CLI output (provenance in
COMMANDS.md): listing ids/actions/confirm sets, direct-install kind fromdetails,--trustonly for an accepted current hash, argv never consents and appliesGROK_HOME, update outcome as Grok prints it.Checks (macOS):
cargo fmt --all --check,cargo clippy --workspace --all-targets --locked -- -D warnings,cargo nextest run --workspace --locked(936 passed, 11 skipped),cargo machete, wasm / iOS-sim / Android checks with-D warnings, and Windows cross-compile Clippy for agent, services and runtime. Each commit builds and passes Clippy.Two tests failed on Windows in an earlier run of this code and were settled per CONTRIBUTING: source-kind classification was a product defect (host path syntax) → now read from
details; the sha256 mismatch was the checkout converting the hashed fixture to CRLF →.gitattributespins those fixtures. This PR's CI is their first Windows run since.Merge Danger
Door: two-way — revert restores
PluginManagement::NONEfor Grok; no persisted state is written by Tcode (Grok's own files stay the truth).Blast Radius: Grok-only
Off by default: per-provider plugin management defaults to off except Codex, so nothing runs until the user enables Grok in Settings → Plugins. Not verified: Windows execution of the plugin tests (CI), a real xAI login, and whether a running session picks up changes without
/reload-plugins(the apply note says reload or next session, as observed).