Add plugin system and interactive preset mode#23
Merged
Conversation
Plugins are executables named gw-<name> found in ~/.grove/plugins/ or $PATH. Unknown commands automatically fall back to plugin lookup. - gw plugin install <repo>: download from GitHub release - gw plugin list/remove/upgrade: manage installed plugins - Plugin metadata (.gw-<name>.json) tracks install source for upgrades - Env vars (GROVE_DIR, GROVE_CONFIG, GROVE_STATE, GROVE_WORKSPACE) passed to plugins for context - syscall.Exec on Unix for clean process handoff (TUI-friendly) - e2e tests covering full plugin lifecycle Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Limit extracted binary size to 256 MiB (zip bomb protection) - Limit GitHub API response body to 1 MiB - Validate download URL is HTTPS before fetching - Propagate plugin exit code on Windows instead of always exit(0) - Skip os.Args[0] in pluginArgs to avoid false match on binary name - Handle non-NotExist stat errors in Remove - Strip http:// prefix in parseRepo Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- gw create: offer preset picker when presets exist, with "Pick manually…" - gw preset add: interactive repo picker when --repos omitted - gw preset remove: interactive picker when no name given - Picker cancel (Esc/Ctrl+C) now exits cleanly (exit 0) instead of printing "error: selection cancelled" — applied across all 16 picker call sites via new exitOnPickerErr helper Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
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
gw plugin install/list/upgrade/remove+ automatic fallback for unknown commands (gw dash→ findsgw-dashbinary)gw createoffers preset picker when presets exist,gw preset add/removework interactively without flagserror: selection cancelledacross all picker call sitesPlugin details
Plugins are executables named
gw-<name>found in~/.grove/plugins/or$PATH. Install from GitHub releases, pass context via env vars (GROVE_DIR,GROVE_CONFIG,GROVE_STATE,GROVE_WORKSPACE). Usessyscall.Execon Unix for clean process handoff.Security: size-limited extraction (256 MiB), HTTPS-only downloads, rate-limit-friendly
GITHUB_TOKENsupport.Files
go/internal/plugin/— plugin discovery, execution, install, upgrade (+ 15 unit tests)go/cmd/plugin.go— cobra commandsgo/cmd/root.go— unknown command → plugin fallbackgo/cmd/create.go,go/cmd/preset.go— interactive preset pickergo/e2e/run.sh— 8 new e2e tests (70 total, all passing)docs/plugins.md— plugin documentationTest plan
gw plugin list— shows empty, then shows installed pluginsgw hello(with script in plugins dir) — falls back to plugin, passes env vars and argsgw plugin remove hello— deletes binary and metadatagw nonexistent— shows error, exits 1🤖 Generated with Claude Code