Conversation
Term command is a new way to use goose without the builtin REPL - instead the session is tied right into your terminal
- Fix bash/zsh: properly quote goose binary path to handle spaces - Extract session creation logic to ensure_terminal_session helper - Reduces code duplication between handle_term_log and handle_term_run
There was a problem hiding this comment.
Pull request overview
This PR introduces terminal integration for Goose, enabling users to interact with Goose directly from their shell prompt without switching to a separate REPL session. It adds the @goose and @g aliases (alongside the existing gt alias) to address conflicts with Graphite's gt command, and implements per-directory session management without requiring explicit session switching.
Key Changes
- Terminal-aware session management that automatically creates or resumes sessions based on the current working directory
- Shell integration scripts for bash, zsh, fish, and PowerShell with command history tracking
- New
goose termsubcommands for initialization, logging, and running prompts
Reviewed changes
Copilot reviewed 5 out of 6 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
| documentation/docs/guides/terminal-integration.md | Added comprehensive documentation covering setup, usage, performance characteristics, and session management for terminal integration |
| crates/goose-cli/src/commands/term.rs | Implements core terminal integration functionality including session management, shell script generation, and command history tracking |
| crates/goose-cli/src/commands/mod.rs | Exposes the new term module |
| crates/goose-cli/src/cli.rs | Adds CLI commands and argument parsing for goose term subcommands (init, log, run, info) |
| crates/goose-cli/Cargo.toml | Adds dirs dependency (appears unused) |
| Cargo.lock | Updates dependency tree with dirs 6.0.0 and related transitive dependencies |
| anstream = "0.6.18" | ||
| url = "2.5.7" | ||
| open = "5.3.2" | ||
| dirs = "6.0.0" |
There was a problem hiding this comment.
The dirs dependency is added to Cargo.toml but is not used anywhere in the codebase. Consider removing it if it's not needed.
| dirs = "6.0.0" |
| fn read_and_clear_shell_history(session_id: &str) -> Result<Vec<String>> { | ||
| let path = shell_history_path(session_id)?; | ||
|
|
||
| if !path.exists() { | ||
| return Ok(Vec::new()); | ||
| } | ||
|
|
||
| let content = fs::read_to_string(&path)?; | ||
| let commands: Vec<String> = content | ||
| .lines() | ||
| .filter(|line| !line.trim().is_empty()) | ||
| .map(|s| s.to_string()) | ||
| .collect(); | ||
|
|
||
| fs::write(&path, "")?; | ||
|
|
||
| Ok(commands) | ||
| } |
There was a problem hiding this comment.
Race condition: read_and_clear_shell_history reads then clears the file (lines 190-197), but append_shell_command could write between the read and clear operations. If a command is logged during this window, it will be lost. Consider using file locking (e.g., fs2 crate's FileExt::try_lock_exclusive()) or atomic operations to prevent this.
This picks up from: #5847
but adds
@goosealias (as gt is used by graphite) and also doesn't require session changes