=============== LIBRARY RULES =============== From library maintainers: - Install via Homebrew (brew install lost-in-the/tap/grove) then run grove setup. Shell integration (eval "$(grove install zsh)") enables directory switching and tab completion. - Core commands: grove new (create worktree+branch+tmux), grove to (switch), grove fetch pr/42 (from GitHub PR/issue), grove ls, grove rm, grove fork. - Config in .grove/config.toml per project. Key sections: [switch] dirty handling, [tmux] session control, [naming] worktree pattern, [protection] branch guards. - Hooks in .grove/hooks.toml define post-create actions: copy files, symlink dirs (node_modules, vendor/bundle), run setup commands. Auto-detected by grove init. - Docker plugin: embedded mode (per-worktree compose) or external mode (shared compose-dev, ADMIN_DIR). Troubleshoot with grove doctor. Plugin API in plugins/ directory. ### Docker Plugin Configuration: Auto Start Source: https://github.com/lost-in-the/grove/blob/main/plugins/docker/README.md Example TOML configuration to enable automatic container startup when switching to a worktree. ```toml [plugins.docker] auto_start = true ``` -------------------------------- ### Install Grove using go install Source: https://github.com/lost-in-the/grove/blob/main/docs/AGENT_GUIDE.md Alternative installation method for Grove using the go install command. ```bash go install github.com/lost-in-the/grove/cmd/grove@latest ``` -------------------------------- ### Test Install Method Detection and Update Commands Source: https://github.com/lost-in-the/grove/blob/main/docs/superpowers/plans/2026-05-07-update-notification.md Write unit tests to verify the `detectInstallFromPath` and `UpdateCommand` functions. These tests cover various installation paths and expected update commands for different install methods. ```go package updatecheck import "testing" func TestDetectInstallFromPath(t *testing.T) { cases := []struct { name string path string want InstallMethod }{ {"homebrew apple silicon", "/opt/homebrew/Cellar/grove/0.6.0/bin/grove", InstallBrew}, {"homebrew intel", "/usr/local/Cellar/grove/0.6.0/bin/grove", InstallBrew}, {"go install", "/Users/leah/go/bin/grove", InstallGoInstall}, {"binary download", "/usr/local/bin/grove", InstallBinary}, {"empty", "", InstallUnknown}, } for _, tc := range cases { t.Run(tc.name, func(t *testing.T) { if got := detectInstallFromPath(tc.path); got != tc.want { t.Errorf("detectInstallFromPath(%q) = %v, want %v", tc.path, got, tc.want) } }) } } func TestUpdateCommand(t *testing.T) { cases := []struct { method InstallMethod want string }{ {InstallBrew, "brew upgrade lost-in-the/tap/grove"}, {InstallGoInstall, "go install github.com/lost-in-the/grove/cmd/grove@latest"}, {InstallBinary, "Visit https://github.com/lost-in-the/grove/releases for the latest binary"}, {InstallUnknown, "Visit https://github.com/lost-in-the/grove/releases for the latest binary"}, } for _, tc := range cases { t.Run(tc.method.String(), func(t *testing.T) { if got := UpdateCommand(tc.method); got != tc.want { t.Errorf("UpdateCommand(%v) = %q, want %q", tc.method, got, tc.want) } }) } } ``` -------------------------------- ### Install Grove Binary Source: https://github.com/lost-in-the/grove/blob/main/README.md Install the Grove binary to `$GOPATH/bin`. ```bash make install # Install to $GOPATH/bin ``` -------------------------------- ### Install Method Detection Logic Source: https://github.com/lost-in-the/grove/blob/main/docs/superpowers/specs/2026-05-07-update-notification-design.md Defines an InstallMethod type and constants for various installation methods. The DetectInstall function determines the installation method based on the executable path. ```go type InstallMethod int const ( InstallUnknown InstallMethod = iota InstallBrew InstallGoInstall InstallBinary ) func DetectInstall() InstallMethod ``` -------------------------------- ### Complete hooks.toml Example Source: https://github.com/lost-in-the/grove/blob/main/docs/CONFIGURATION_REFERENCE.md A comprehensive example of a hooks.toml file, demonstrating various hook types like copy and command, along with override settings. ```toml # .grove/hooks.toml [hooks] # Override global post_create hooks for this project (instead of appending) override_post_create = true [[hooks.post_create]] type = "copy" from = ".env.example" to = ".env" on_failure = "warn" [[hooks.post_create]] type = "copy" from = "config/master.key" to = "config/master.key" required = true [[hooks.post_create]] type = "command" command = "bundle install" working_dir = "new" timeout = 300 on_failure = "fail" [[hooks.post_switch]] type = "command" command = "echo 'Switched to {{.worktree}} on {{.branch}}'" ``` -------------------------------- ### Grove Project Configuration Example Source: https://github.com/lost-in-the/grove/blob/main/README.md Example of a project-level configuration file. Sets project name, defines how to handle uncommitted changes during switches, configures tmux integration, specifies the test command, and enables Docker plugin with auto-start. ```toml # .grove/config.toml project_name = "my-project" [switch] # What to do with uncommitted changes when switching # "prompt" (default) | "auto-stash" | "refuse" dirty_handling = "prompt" [tmux] # "auto" (default) | "manual" | "off" # auto: Grove creates and attaches sessions automatically # manual: Grove creates sessions but doesn't attach (good for scripts) # off: No tmux integration mode = "auto" [test] command = "bin/rails test" # service = "app" # exec into this Docker service instead of running locally [session] # command = "claude" # what to run when opening a session via 'grove open' # popup = true # open in a tmux popup overlay [plugins.docker] enabled = true auto_start = true # start containers when switching to a worktree auto_stop = false # stop containers when switching away [protection] protected = ["production"] # requires --force --unprotect to delete immutable = ["main"] # blocks apply/sync; can still be removed ``` -------------------------------- ### Install Edge Build from Main Source: https://github.com/lost-in-the/grove/blob/main/README.md Install the latest development version of Grove directly from the main branch for testing purposes. ```bash go install github.com/lost-in-the/grove/cmd/grove@main ``` -------------------------------- ### Build and Install Grove from Source Source: https://github.com/lost-in-the/grove/blob/main/README.md Follow these steps to build and install Grove from the source code. This requires Git and Make, and ensures you have the very latest code. ```bash git pull && make build && sudo make install ``` -------------------------------- ### Implement Install Method Detection Logic Source: https://github.com/lost-in-the/grove/blob/main/docs/superpowers/plans/2026-05-07-update-notification.md Provides the Go implementation for detecting the Grove installation method based on the executable path. Includes the `InstallMethod` type, constants, and the `DetectInstall` and `detectInstallFromPath` functions. ```go package updatecheck import ( "os" "strings" ) // InstallMethod identifies how the running grove binary was installed. type InstallMethod int const ( InstallUnknown InstallMethod = iota InstallBrew InstallGoInstall InstallBinary ) // String renders the method as a human-readable name (used in test output and logs). func (m InstallMethod) String() string { switch m { case InstallBrew: return "brew" case InstallGoInstall: return "go-install" case InstallBinary: return "binary" default: return "unknown" } } // DetectInstall inspects the running binary's path and returns the most likely // install method. func DetectInstall() InstallMethod { exe, err := os.Executable() if err != nil { return InstallUnknown } return detectInstallFromPath(exe) } func detectInstallFromPath(path string) InstallMethod { if path == "" { return InstallUnknown } if strings.Contains(path, "/Cellar/grove/") { // covers /opt/homebrew/Cellar/grove/... and /usr/local/Cellar/grove/... return InstallBrew } if strings.HasSuffix(path, "/go/bin/grove") || strings.Contains(path, "/go/bin/") { return InstallGoInstall } return InstallBinary } // UpdateCommand returns the recommended update command for a given install method. func UpdateCommand(m InstallMethod) string { switch m { case InstallBrew: return "brew upgrade lost-in-the/tap/grove" case InstallGoInstall: return "go install github.com/lost-in-the/grove/cmd/grove@latest" default: return "Visit https://github.com/lost-in-the/grove/releases for the latest binary" } } ``` -------------------------------- ### Manual zsh Setup Source: https://github.com/lost-in-the/grove/blob/main/docs/SHELL_INTEGRATION.md Add this line to your ~/.zshrc file for manual zsh shell integration. ```bash eval "$(grove install zsh)" ``` -------------------------------- ### Grove Adopt Command Output Examples Source: https://github.com/lost-in-the/grove/blob/main/docs/COMMAND_SPECIFICATIONS.md These examples show the expected output when adopting a new worktree or when the worktree is already registered. ```bash ↪ Bootstrapping worktree "feature" at /path/to/project-feature ... ✓ adopted "feature" (branch: feature) config symlinked, state registered, post-create hooks fired ``` ```bash ℹ worktree "feature" is already registered (path: /path/to/project-feature) ``` -------------------------------- ### Build Grove from Source Source: https://github.com/lost-in-the/grove/blob/main/README.md Build and install Grove locally from its source code repository. ```bash git clone https://github.com/lost-in-the/grove cd grove make build sudo make install ``` -------------------------------- ### Start Docker Containers with grove up Source: https://github.com/lost-in-the/grove/blob/main/docs/COMMAND_SPECIFICATIONS.md Starts Docker containers for the current worktree. Use the --build flag to build images first, or --isolated to start an isolated stack. By default, it runs in the background. ```bash grove up [services...] [flags] ``` ```bash grove up --build ``` ```bash grove up --isolated ``` ```bash grove up --slot 1 ``` -------------------------------- ### Complete Workflow Example Source: https://github.com/lost-in-the/grove/blob/main/plugins/tracker/README.md Demonstrates a complete workflow for managing issues, from browsing and selection to making changes, creating a PR, and cleanup. ```bash # Browse issues grove issues --label bug # Select issue #123 from fzf # → Creates worktree: issue-123-fix-auth-bug # → Creates branch: issue-123-fix-auth-bug # → Creates tmux session: grove-issue-123-fix-auth-bug # → Changes directory (with shell integration) # Make changes, commit, push git commit -m "fix: resolve authentication bug" git push -u origin issue-123-fix-auth-bug # Create PR gh pr create # Clean up grove rm issue-123-fix-auth-bug ``` -------------------------------- ### Error: fzf Not Installed Source: https://github.com/lost-in-the/grove/blob/main/plugins/tracker/README.md This error message indicates that `fzf` is not installed. Follow the provided link for installation instructions. ```text ✗ fzf not installed Install: https://github.com/junegunn/fzf#installation ``` -------------------------------- ### Override Project Post-Create Hook Source: https://github.com/lost-in-the/grove/blob/main/docs/CONFIGURATION_REFERENCE.md Example of a project-level hook that overrides the global post_create hook to run `bundle install`. It specifies a working directory, timeout, and failure behavior. ```toml # .grove/hooks.toml (project — overrides global post_create, appends to post_switch) [hooks] override_post_create = true [[hooks.post_create]] type = "command" command = "bundle install" working_dir = "new" timeout = 300 on_failure = "fail" ``` -------------------------------- ### Manual Shell Integration Setup for zsh Source: https://github.com/lost-in-the/grove/blob/main/docs/AGENT_GUIDE.md Manual setup for Grove's shell integration specifically for zsh users. ```bash echo 'eval "$(grove install zsh)"' >> ~/.zshrc source ~/.zshrc ``` -------------------------------- ### Worktree Naming Convention Examples Source: https://github.com/lost-in-the/grove/blob/main/docs/COMMAND_SPECIFICATIONS.md Examples demonstrating the required pattern for all worktrees created by Grove, ensuring consistency and preventing collisions. ```shell | Project | User Input | Worktree Directory | Tmux Session | |---------|------------|-------------------|--------------| | grove | testing | grove-testing | grove-testing | grove | feature-auth | grove-feature-auth | grove-feature-auth | my-app | hotfix-123 | my-app-hotfix-123 | my-app-hotfix-123 | ``` -------------------------------- ### Install Grove using Homebrew Source: https://github.com/lost-in-the/grove/blob/main/docs/AGENT_GUIDE.md Preferred installation method for Grove using the Homebrew package manager. ```bash brew install lost-in-the/tap/grove ``` -------------------------------- ### Commit Install Method Detection Changes Source: https://github.com/lost-in-the/grove/blob/main/docs/superpowers/plans/2026-05-07-update-notification.md Stage and commit the new Go files for install method detection and testing. ```bash git add internal/updatecheck/install.go internal/updatecheck/install_test.go git commit -m "feat(updatecheck): install method detection with tailored update command" ``` -------------------------------- ### Start Containers (Detached) Source: https://github.com/lost-in-the/grove/blob/main/plugins/docker/README.md Starts Docker containers for the current worktree in detached mode. Use the alias 'w up'. ```bash grove up # Start containers in detached mode (default) grove up --detach=false # Start containers in foreground w up # Using alias ``` -------------------------------- ### Manual Shell Integration Setup for bash Source: https://github.com/lost-in-the/grove/blob/main/docs/AGENT_GUIDE.md Manual setup for Grove's shell integration specifically for bash users. ```bash echo 'eval "$(grove install bash)"' >> ~/.bashrc source ~/.bashrc ``` -------------------------------- ### Automatically start Docker services Source: https://github.com/lost-in-the/grove/blob/main/docs/CONFIGURATION_REFERENCE.md When true, automatically starts Docker services when switching to a worktree. Defaults to true. ```toml auto_start = true ``` -------------------------------- ### Grove Open Output (New Worktree) Source: https://github.com/lost-in-the/grove/blob/main/docs/COMMAND_SPECIFICATIONS.md Example output when a new worktree and session are successfully created. ```bash ✓ Created worktree 'feature-x' ✓ Created session 'grove-feature-x' running 'claude' ``` -------------------------------- ### Manual bash Setup Source: https://github.com/lost-in-the/grove/blob/main/docs/SHELL_INTEGRATION.md Add this line to your ~/.bashrc file for manual bash shell integration. ```bash eval "$(grove install bash)" ``` -------------------------------- ### Install Grove via Release Binaries (macOS ARM) Source: https://github.com/lost-in-the/grove/blob/main/README.md Manually download and install Grove for macOS on Apple Silicon. Replace `` with the actual release tag. ```bash # macOS (Apple Silicon) — replace with the latest tag from the # releases page, e.g. 0.7.0 curl -L https://github.com/lost-in-the/grove/releases/download/v/grove__Darwin_arm64.tar.gz | tar xz sudo mv grove /usr/local/bin/ ``` -------------------------------- ### Project Context Detection Examples Source: https://github.com/lost-in-the/grove/blob/main/docs/COMMAND_SPECIFICATIONS.md Examples illustrating how Grove detects the project context based on directory structure and Git repository information. ```shell ~/projects/grove/.git → project = "grove" ~/projects/my-app/.grove/ → project = (from config or "my-app") ``` -------------------------------- ### PR Review Workflow Example Source: https://github.com/lost-in-the/grove/blob/main/plugins/tracker/README.md Illustrates a workflow for reviewing pull requests, including browsing, checking out branches, and cleaning up after merging. ```bash # Browse PRs needing review grove prs --label needs-review # Select PR #456 from fzf # → Creates worktree: pr-456-add-user-api # → Checks out branch: add-user-api # → Creates tmux session: grove-pr-456-add-user-api # Review, test, comment grove to main # Switch back to main # Clean up after merge grove rm pr-456-add-user-api ``` -------------------------------- ### Install and Authenticate gh CLI Source: https://github.com/lost-in-the/grove/blob/main/plugins/tracker/README.md Install the `gh` CLI tool using Homebrew on macOS or download from the official website. Authenticate the CLI with your GitHub account. ```bash # Install gh CLI brew install gh # macOS # Or visit https://cli.github.com/ # Authenticate gh auth login ``` -------------------------------- ### Worktree Name Transformation Examples Source: https://github.com/lost-in-the/grove/blob/main/docs/COMMAND_SPECIFICATIONS.md Examples showing how user input for worktree names is validated and transformed to adhere to Grove's naming rules. ```shell | User Input | Stored Name | Reason | |------------|-------------|--------| | `testing` | `testing` | Valid | | `Feature Auth` | `feature-auth` | Lowercase, space→hyphen | | `fix/bug-123` | `fix-bug-123` | Slash→hyphen | | `--testing--` | `testing` | Strip leading/trailing | | `TESTING` | `testing` | Lowercase | ``` -------------------------------- ### Grove Open Output (Existing Worktree) Source: https://github.com/lost-in-the/grove/blob/main/docs/COMMAND_SPECIFICATIONS.md Example output when reattaching to an existing worktree and session. ```bash ✓ Launched 'claude' in existing session *Popup opens or session switches* ``` -------------------------------- ### Example hooks.toml Configuration Source: https://github.com/lost-in-the/grove/blob/main/docs/PLUGIN_DEVELOPMENT.md Users can define custom actions in hooks.toml, referencing the registered handler type and providing necessary parameters. ```toml [[hooks.post_create]] type = "myplugin:run" command = "echo hello" ``` -------------------------------- ### Sourcing Shell Configuration Source: https://github.com/lost-in-the/grove/blob/main/docs/SHELL_INTEGRATION.md After manual setup, restart your shell or source the relevant configuration file to apply changes. ```bash source ~/.zshrc # zsh ``` ```bash source ~/.bashrc # bash ``` -------------------------------- ### Grove Last Success Output Source: https://github.com/lost-in-the/grove/blob/main/docs/COMMAND_SPECIFICATIONS.md Example output when successfully switching to the previous worktree. ```bash ✓ Switched to 'testing' (previous worktree) ``` -------------------------------- ### Grove Which Formatted Output (Services Running) Source: https://github.com/lost-in-the/grove/blob/main/docs/COMMAND_SPECIFICATIONS.md Example formatted output when services are running for the current worktree. ```bash Worktree: testing Branch: feat/testing Services: ● running for testing ``` -------------------------------- ### Register and Get Trackers Source: https://github.com/lost-in-the/grove/blob/main/plugins/tracker/README.md Demonstrates how to register a new tracker adapter (e.g., GitHub) and retrieve a registered tracker by its name. Also shows how to list all registered tracker names. ```go import "github.com/lost-in-the/grove/plugins/tracker" // Register a tracker tracker.Register("github", NewGitHubAdapter()) // Get a registered tracker t, err := tracker.Get("github") // List all trackers names := tracker.List() ``` -------------------------------- ### Docker Exec Hook Example Source: https://github.com/lost-in-the/grove/blob/main/plugins/docker/README.md Use this hook to execute a command inside an externally managed Docker container by its name. Useful for setup tasks within a running container. ```toml # Exec into an externally-managed container by name [[hooks.post_create]] type = "docker:exec" container = "shared-app-1" command = "bundle install" ``` -------------------------------- ### mise Setup for .env.local Source: https://github.com/lost-in-the/grove/blob/main/plugins/docker/README.md Configure mise to load environment variables from .env.local. This is an alternative to direnv for managing environment-specific configurations. ```bash # ~/.zshrc eval "$(mise activate zsh)" ``` ```toml # ~/projects/shared-infra/.mise.toml [env] _.file = ".env.local" ``` -------------------------------- ### Configure Non-Blocking Services in Grove Config Source: https://github.com/lost-in-the/grove/blob/main/docs/superpowers/plans/2026-04-30-issue-25-plan-3-service-health.md Example TOML configuration for `.grove/config.toml` demonstrating how to set both `services` and `non_blocking_services`. This setup is used for testing scenarios where a non-blocking service might fail. ```toml # .grove/config.toml [plugins.docker.external] services = ["app", "asset_precompile"] non_blocking_services = ["asset_precompile"] ``` -------------------------------- ### Define Global Post-Switch Hook Source: https://github.com/lost-in-the/grove/blob/main/docs/CONFIGURATION_REFERENCE.md Example of a global hook that runs after switching to a worktree, printing the worktree name. ```toml # ~/.config/grove/hooks.toml (global — applies to all projects) [[hooks.post_switch]] type = "command" command = "echo 'switched to {{.worktree}}'" ``` -------------------------------- ### Grove Success Output Source: https://github.com/lost-in-the/grove/blob/main/docs/COMMAND_SPECIFICATIONS.md Example output indicating successful creation of a worktree, tmux session, and Docker stack. ```bash ✓ Created worktree 'testing' ✓ Created tmux session 'grove-testing' ✓ Docker stack started ``` -------------------------------- ### Grove Worktree Branch Naming Examples Source: https://github.com/lost-in-the/grove/blob/main/docs/COMMAND_SPECIFICATIONS.md Illustrates the default and configurable patterns for naming branches when creating new worktrees with Grove. ```bash w new testing → branch: testing w new feature-auth → branch: feature-auth w new is/123 → branch: is/123 (issue integration) w new pr/456 → branch: pr/456 (PR integration) ``` -------------------------------- ### Initialize and Use State Manager in Go Source: https://github.com/lost-in-the/grove/blob/main/internal/state/README.md Demonstrates creating a state manager, freezing, checking, listing, and resuming worktrees. Ensure error handling for all operations. ```go import "github.com/lost-in-the/grove/internal/state" // Create a manager (empty string uses default location) mgr, err := state.NewManager("") if err != nil { log.Fatal(err) } // Freeze a worktree if err := mgr.Freeze("feature-auth"); err != nil { log.Fatal(err) } // Check if frozen frozen, err := mgr.IsFrozen("feature-auth") if err != nil { log.Fatal(err) } // List all frozen worktrees list, err := mgr.ListFrozen() if err != nil { log.Fatal(err) } // Resume a worktree if err := mgr.Resume("feature-auth"); err != nil { log.Fatal(err) } ``` -------------------------------- ### Grove Which Formatted Output (Services Running for Different Worktree) Source: https://github.com/lost-in-the/grove/blob/main/docs/COMMAND_SPECIFICATIONS.md Example formatted output when services are running but for a different worktree. ```bash Worktree: testing Branch: feat/testing Services: ⚠ running for feature-auth (not this worktree) ``` -------------------------------- ### Docker Plugin Verification Output Source: https://github.com/lost-in-the/grove/blob/main/plugins/docker/README.md Example output from 'grove doctor' indicating successful detection and configuration of the environment file loader. ```text ✓ Env file target (.env.local) ✓ Env file loader (direnv found in PATH) ✓ Env file loader configured (configured) ``` -------------------------------- ### Prerequisites Check for Grove Installation Source: https://github.com/lost-in-the/grove/blob/main/docs/AGENT_GUIDE.md Verify that the necessary tools and their versions are installed before proceeding with Grove installation. This includes git, go, tmux, and gh. ```bash git --version # Need 2.30+ go version # Need 1.24+ (build only, not runtime) tmux -V # 3.0+ (optional, needed for session management) gh --version # optional, needed for grove fetch pr/N and grove prs/issues ``` -------------------------------- ### Error: gh CLI Not Installed or Not Authenticated Source: https://github.com/lost-in-the/grove/blob/main/plugins/tracker/README.md This error message indicates that the GitHub CLI is either not installed or not authenticated. Follow the provided links to install and authenticate. ```text ✗ gh CLI not installed or not authenticated Install: https://cli.github.com/ Authenticate: gh auth login ``` -------------------------------- ### Original setupCreatedWorktree Logic Source: https://github.com/lost-in-the/grove/blob/main/docs/superpowers/plans/2026-04-30-issue-25-plan-2-worktree-adopt.md This code block shows the original implementation of `setupCreatedWorktree` before the extraction of `BootstrapWorktree`. It includes state management, hook execution, and global plugin hook firing. ```go func setupCreatedWorktree(ctx *GroveContext, mgr *worktree.Manager, name, branchName string, opts worktreeSetupOpts, w *cli.Writer) (*worktree.Worktree, error) { wsState := &state.WorktreeState{ Path: opts.WorktreePath, Branch: opts.Branch, Root: false, CreatedAt: now, LastAccessedAt: now, Environment: opts.IsEnvironment, } if opts.IsEnvironment { wsState.Mirror = opts.Mirror wsState.LastSyncedAt = &now } if err := stateMgr.AddWorktree(opts.Name, wsState); err != nil { return fmt.Errorf("register worktree: %w", err) } // Per-project post-create hooks hookExecutor, hookErr := hooks.NewExecutor() if hookErr == nil && hookExecutor.HasHooksForEvent(hooks.EventPostCreate) { hookCtx := &hooks.ExecutionContext{ Event: hooks.EventPostCreate, Worktree: opts.Name, WorktreeFull: opts.ProjectName + "-" + opts.Name, Branch: opts.Branch, Project: opts.ProjectName, MainPath: opts.MainPath, NewPath: opts.WorktreePath, } _ = hookExecutor.Execute(hooks.EventPostCreate, hookCtx) } // Global plugin post-create hook (e.g., docker external) globalHookCtx := &hooks.Context{ Worktree: opts.Name, Config: cfg, WorktreePath: opts.WorktreePath, MainPath: opts.MainPath, } _ = hooks.Fire(hooks.EventPostCreate, globalHookCtx) return nil } ``` -------------------------------- ### Shell Integration cd Directive Implementation Source: https://github.com/lost-in-the/grove/blob/main/docs/COMMAND_SPECIFICATIONS.md Example Go code demonstrating how to implement the 'cd' directive for shell integration, outputting a 'cd:' prefix for directory changes or a fallback message. ```go // In Go code if shellIntegration { fmt.Printf("cd:%s\n", targetPath) } else { fmt.Printf("To change directory: cd %s\n", targetPath) } ``` -------------------------------- ### Grove Doctor Report Example Source: https://github.com/lost-in-the/grove/blob/main/docs/AGENT_GUIDE.md An example of a warning message indicating a worktree was not created by Grove and requires adoption. ```bash ⚠ this worktree (project-feature) wasn't created by grove and isn't registered in state run 'grove adopt' to bootstrap it (symlinks config, runs hooks, registers state) ``` -------------------------------- ### Write Plugin Tests in Go Source: https://github.com/lost-in-the/grove/blob/main/docs/PLUGIN_DEVELOPMENT.md Create comprehensive tests for your plugin using Go's testing package. Ensure Name(), Init(), and Enabled() methods function correctly. ```go // plugins/myplugin/plugin_test.go package myplugin import ( "testing" "github.com/lost-in-the/grove/internal/hooks" ) func TestPluginName(t *testing.T) { p := New() if p.Name() != "myplugin" { t.Errorf("expected name 'myplugin', got '%s'", p.Name()) } } func TestInit(t *testing.T) { p := New() err := p.Init(nil) if err != nil { t.Errorf("Init() failed: %v", err) } } func TestEnabled(t *testing.T) { p := New() _ = p.Init(nil) if !p.Enabled() { t.Error("expected plugin to be enabled") } } ``` -------------------------------- ### Grove Test Configuration Example Source: https://github.com/lost-in-the/grove/blob/main/docs/COMMAND_SPECIFICATIONS.md This TOML snippet shows how to configure the test command, including the command itself, an optional Docker service, and dependency management for tests. ```toml [test] command = "bin/rails test" # Optional: run in a Docker service container service = "app" # Optional: skip docker compose dependency services (default: false → --no-deps is passed) include_deps = false ``` -------------------------------- ### Verify Grove Installation and Shell Integration Source: https://github.com/lost-in-the/grove/blob/main/docs/AGENT_GUIDE.md Commands to verify the Grove installation and check if the shell integration is correctly loaded. ```bash grove version # grove v1.x.x type grove # grove is a shell function # If this says "grove is /usr/local/bin/grove", shell integration is not loaded. grove doctor # Runs all health checks — see §8 Troubleshooting ``` -------------------------------- ### Start Isolated Stack Source: https://github.com/lost-in-the/grove/blob/main/plugins/docker/README.md Allocates a slot and starts services for an isolated Docker stack. Supports specifying a slot number. ```bash grove up --isolated # Allocate a slot and start services grove up --isolated --slot 3 # Use a specific slot number ``` -------------------------------- ### Initialize Grove Project Source: https://github.com/lost-in-the/grove/blob/main/docs/COMMAND_SPECIFICATIONS.md Use 'grove init' to set up a new grove project in the current git repository. It creates a .grove/ directory with configuration files and optionally generates hooks.toml based on project type detection. Flags control the creation of additional worktrees and hook generation behavior. ```bash grove init [flags] ``` -------------------------------- ### Check Grove Version Source: https://github.com/lost-in-the/grove/blob/main/README.md Run this command to display the currently installed version of Grove. This is useful for verifying installation or update success. ```bash grove version ``` -------------------------------- ### Display Agent Help Source: https://github.com/lost-in-the/grove/blob/main/README.md Display built-in quick reference for agent commands. ```bash grove agent-help ``` -------------------------------- ### Implement New Tracker Adapter Source: https://github.com/lost-in-the/grove/blob/main/plugins/tracker/README.md Example of implementing a new tracker adapter for a service like Linear. It involves creating a struct, implementing the `Tracker` interface methods, and registering the adapter. ```go type LinearAdapter struct { // ... } func (l *LinearAdapter) Name() string { return "linear" } func (l *LinearAdapter) FetchIssue(number int) (*Issue, error) { // Implementation using Linear API } // ... implement other methods // In init or main: tracker.Register("linear", NewLinearAdapter()) ``` -------------------------------- ### Run Full Test Suite Source: https://github.com/lost-in-the/grove/blob/main/docs/superpowers/plans/2026-04-30-issue-25-plan-3-service-health.md Execute the project's full test suite using the `make test` command. This is a standard step to ensure all tests pass after making changes. ```bash make test ``` -------------------------------- ### Install or Update Grove using Homebrew Source: https://github.com/lost-in-the/grove/blob/main/README.md Use this command to update Homebrew and upgrade the Grove package. Ensure Homebrew is installed and up-to-date. ```bash brew update && brew upgrade lost-in-the/tap/grove ``` -------------------------------- ### Before Grove: Creating a Feature Branch Source: https://github.com/lost-in-the/grove/blob/main/docs/AGENT_GUIDE.md Manual steps to create a new feature branch, including fetching, adding a worktree, checking out a new branch, copying environment variables, and setting up Docker and tmux. ```bash git fetch origin git worktree add ../myapp-auth main cd ../myapp-auth git checkout -b feature/auth cp ../.env.local .env.local docker compose up -d tmux new-session -d -s myapp-auth ``` -------------------------------- ### Register Plugin in Main Initialization Source: https://github.com/lost-in-the/grove/blob/main/docs/PLUGIN_DEVELOPMENT.md Add your plugin to the main initialization process in `cmd/grove/main.go` by creating an instance, initializing it, and registering its hooks if enabled. ```go import ( myplugin "github.com/lost-in-the/grove/plugins/myplugin" ) func initializePlugins(cfg *config.Config, registry *hooks.Registry) error { p := myplugin.New() if err := p.Init(cfg); err != nil { return fmt.Errorf("myplugin: %w", err) } if p.Enabled() { if err := p.RegisterHooks(registry); err != nil { return fmt.Errorf("myplugin hooks: %w", err) } } return nil } ``` -------------------------------- ### Start Isolated Docker Stacks for Agents Source: https://github.com/lost-in-the/grove/blob/main/docs/AGENT_GUIDE.md Start isolated Docker stacks for each agent worktree. This ensures containers run on offset ports, preventing conflicts. ```bash # Each agent starts an isolated Docker stack cd ../myapp-agent-task-1 grove up --isolated # gets slot 1 # → containers running on offset ports cd ../myapp-agent-task-2 grove up --isolated # gets slot 2 # → containers running on different offset ports ``` -------------------------------- ### Grove Init Output Example Source: https://github.com/lost-in-the/grove/blob/main/docs/COMMAND_SPECIFICATIONS.md This output shows the result of 'grove init' in auto mode with a TTY, including detected project type, a preview of the generated hooks.toml, and confirmation prompts. ```bash ✓ Created .grove/config.toml ✓ Detected project type: Node + Docker Generated hooks.toml preview: [[hooks.post_create]] type = "copy" from = ".env.example" to = ".env" [[hooks.post_create]] type = "docker:compose" service = "app" command = "npm install" Apply this configuration? [Y/n]: y ✓ Wrote .grove/hooks.toml ✓ Initialized grove project 'my-app' ``` -------------------------------- ### Initialize Grove Project Source: https://github.com/lost-in-the/grove/blob/main/docs/AGENT_GUIDE.md Command to initialize Grove within a project directory. ```bash cd ~/projects/myapp grove init ``` -------------------------------- ### Create Plugin README Source: https://github.com/lost-in-the/grove/blob/main/docs/PLUGIN_DEVELOPMENT.md Document your plugin's functionality, features, configuration, and usage in a README.md file within the plugin directory. ```markdown # MyPlugin Brief description of what your plugin does. ## Features - Feature 1 - Feature 2 ## Configuration Describe any configuration options. ## Usage Show examples of using your plugin. ``` -------------------------------- ### Grove Trim Command Output Examples Source: https://github.com/lost-in-the/grove/blob/main/docs/COMMAND_SPECIFICATIONS.md These examples illustrate the output of the 'grove trim' command, showing eligible worktrees for cleanup, confirmation prompts, and the results of the cleanup operation, including branch deletion. ```bash Found 2 worktree(s) eligible for cleanup: old-feature (feature/auth) - 45 days since last access [dirty] experiment (experiment) - 32 days since last access This will permanently remove 2 worktree(s) and their associated tmux sessions. Type 'yes' to confirm: yes Removed 'old-feature' Removed 'experiment' Cleanup complete: 2 removed, 0 failed Associated branches: ⚠ feature/auth (2 unpushed commits) • experiment (merged, safe to delete) Delete 2 associated branch(es)? [Y/n]: y Deleted branch 'feature/auth' Deleted branch 'experiment' Deleted 2 branch(es) ``` ```bash No worktrees eligible for cleanup. Excluded worktrees: main - root worktree testing - accessed 5 days ago (threshold: 30) production - environment worktree ``` -------------------------------- ### Initialize Grove Project Source: https://github.com/lost-in-the/grove/blob/main/docs/AGENT_GUIDE.md Use `--auto` and `--yes` for non-interactive project initialization in scripts or CI. `--auto` detects project type and generates default configurations, while `--yes` skips the preview prompt. ```bash grove init --auto --yes ``` ```bash grove init --no-hooks ``` -------------------------------- ### Initialize Grove Project Source: https://github.com/lost-in-the/grove/blob/main/README.md Run this command in your project's root directory to initialize Grove. It detects your project type and generates a default `.grove/hooks.toml` configuration file. ```bash cd my-project grove init ``` -------------------------------- ### Create Plugin Directory Source: https://github.com/lost-in-the/grove/blob/main/docs/PLUGIN_DEVELOPMENT.md Create a new directory for your plugin under the `plugins/` directory. ```bash mkdir plugins/myplugin cd plugins/myplugin ``` -------------------------------- ### Grove Last No Previous Worktree Output Source: https://github.com/lost-in-the/grove/blob/main/docs/COMMAND_SPECIFICATIONS.md Example output when no previous worktree is recorded. ```bash ✗ No previous worktree recorded This is your first switch in this session. Use 'grove to ' to switch to a worktree. ``` -------------------------------- ### Project Bootstrap Sequence: grove init Source: https://github.com/lost-in-the/grove/blob/main/docs/DATA_FLOWS.md Illustrates the sequence of operations when initializing a new Grove project using the 'grove init' command. It covers Git checks, directory creation, configuration file writes, and auto-detection of project types. ```mermaid sequenceDiagram participant U as User participant I as grove init participant FS as Filesystem participant G as Git participant D as detect.Detect U->>I: grove init [--full] I->>G: Check git repo I->>G: Check not inside worktree I->>FS: Check .grove/ doesn't exist I->>FS: Create .grove/ directory I->>FS: Write .grove/config.toml (project_name) I->>FS: Create state.json (project, main worktree) I->>FS: Update .gitignore (add state.json) I->>FS: Write .grove/.envrc I->>D: Auto-detect project type I->>FS: Generate .grove/hooks.toml opt --with-testing / --full I->>G: git worktree add (testing) end opt --with-scratch / --full I->>G: git worktree add (scratch) end opt --full I->>G: git worktree add (hotfix) end ``` -------------------------------- ### Grove Here Output (Not in a worktree) Source: https://github.com/lost-in-the/grove/blob/main/docs/COMMAND_SPECIFICATIONS.md Example output when 'grove here' is executed outside of a grove-managed worktree. ```text Not in a grove-managed worktree Current directory: ~/Downloads To see available worktrees: grove ls To create a new worktree: grove new ``` -------------------------------- ### Grove Here Default Output Source: https://github.com/lost-in-the/grove/blob/main/docs/COMMAND_SPECIFICATIONS.md Example of the default output when 'grove here' is run in a clean worktree. ```text Worktree: testing Project: grove Branch: testing Path: ~/projects/grove-testing Commit: abc1234 (2 hours ago) Fix authentication bug Status: clean Tmux: attached (grove-testing) Docker: running (3 containers) ``` -------------------------------- ### Refactored setupCreatedWorktree with BootstrapWorktree Source: https://github.com/lost-in-the/grove/blob/main/docs/superpowers/plans/2026-04-30-issue-25-plan-2-worktree-adopt.md This is the refactored `setupCreatedWorktree` function. It now delegates the bootstrapping logic to `worktree.BootstrapWorktree`, simplifying its own responsibilities. Errors during bootstrapping are now collapsed into a single 'Bootstrap failed' message. ```go func setupCreatedWorktree(ctx *GroveContext, mgr *worktree.Manager, name, branchName string, opts worktreeSetupOpts, w *cli.Writer) (*worktree.Worktree, error) { wt, err := mgr.Find(name) if err != nil || wt == nil { return nil, fmt.Errorf("failed to find created worktree: %w", err) } if !opts.JSONOutput { cli.Step(w, "Running post-create hooks...") } bootstrapOpts := worktree.BootstrapOpts{ Name: name, Branch: branchName, WorktreePath: wt.Path, MainPath: ctx.ProjectRoot, ProjectName: mgr.GetProjectName(), Now: time.Now(), IsEnvironment: opts.IsEnvironment, Mirror: opts.Mirror, } if err := worktree.BootstrapWorktree(ctx.State, ctx.Config, bootstrapOpts); err != nil { if !opts.JSONOutput { cli.Warning(w, "Bootstrap failed: %v", err) cli.Faint(w, "run 'grove repair' to fix") } } autoStartDocker(w, ctx.Config, wt.Path, opts.NoDocker, opts.JSONOutput) return wt, nil } ``` -------------------------------- ### Verify Grove Shell Function Source: https://github.com/lost-in-the/grove/blob/main/docs/SHELL_INTEGRATION.md Check if 'grove' is recognized as a shell function after setup. ```bash type grove # Should output: grove is a shell function ``` -------------------------------- ### Grove Which JSON Output Source: https://github.com/lost-in-the/grove/blob/main/docs/COMMAND_SPECIFICATIONS.md Example JSON output when the --json flag is used with 'grove which'. ```json { "worktree": "testing", "branch": "feat/testing", "path": "/path/to/grove-testing", "services": { "running_for": "testing", "matches_current": true } } ``` -------------------------------- ### Configure Copy Hook for Post-Create Event Source: https://github.com/lost-in-the/grove/blob/main/docs/CONFIGURATION_REFERENCE.md Example of a 'copy' hook action that copies a file from the main worktree to the new worktree after creation. It includes optional `required` and `on_failure` settings. ```toml [[hooks.post_create]] type = "copy" from = ".env.local" # source path, relative to main worktree to = ".env.local" # destination path, relative to new worktree required = false # bool: if true, failure aborts the operation (default: false) on_failure = "warn" # "warn" (default) | "fail" | "ignore" ``` -------------------------------- ### Grove Here JSON Output Source: https://github.com/lost-in-the/grove/blob/main/docs/COMMAND_SPECIFICATIONS.md Example of the JSON output when 'grove here' is run with the --json flag. ```json { "name": "testing", "full_name": "grove-testing", "project": "grove", "branch": "testing", "path": "~/projects/grove-testing", "commit": { "hash": "abc1234def5678", "short_hash": "abc1234", "message": "Fix authentication bug", "age": "2 hours ago" }, "status": "dirty", "changes": ["M src/auth.go", "?? src/new_file.go"], "tmux": { "session": "grove-testing", "status": "attached" }, "docker": { "status": "running", "containers": 3 } } ```