add nushell terminal and completion support (#8628)
Signed-off-by: Can H. Tartanoglu <gpg@rotas.mozmail.com>
This commit is contained in:
committed by
GitHub
parent
ba60b597fa
commit
80cac3626f
Generated
+11
@@ -1870,6 +1870,16 @@ dependencies = [
|
||||
"clap",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "clap_complete_nushell"
|
||||
version = "4.6.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fbb9e9715d29a754b468591be588f6b926f5b0a1eb6a8b62acabeb66ff84d897"
|
||||
dependencies = [
|
||||
"clap",
|
||||
"clap_complete",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "clap_derive"
|
||||
version = "4.6.1"
|
||||
@@ -4500,6 +4510,7 @@ dependencies = [
|
||||
"chrono",
|
||||
"clap",
|
||||
"clap_complete",
|
||||
"clap_complete_nushell",
|
||||
"clap_mangen",
|
||||
"cliclack",
|
||||
"comfy-table",
|
||||
|
||||
@@ -64,6 +64,7 @@ comfy-table = "7.2.2"
|
||||
sha2 = { workspace = true }
|
||||
sigstore-verify = { version = "=0.6.5", default-features = false }
|
||||
axum.workspace = true
|
||||
clap_complete_nushell = "4.6.0"
|
||||
|
||||
[target.'cfg(target_os = "windows")'.dependencies]
|
||||
winapi = { workspace = true }
|
||||
|
||||
+100
-7
@@ -1,6 +1,7 @@
|
||||
use anyhow::Result;
|
||||
use clap::{Args, CommandFactory, Parser, Subcommand};
|
||||
use clap_complete::{generate, Shell as ClapShell};
|
||||
use clap_complete_nushell::Nushell as ClapNushell;
|
||||
use goose::agents::GoosePlatform;
|
||||
use goose::builtin_extension::register_builtin_extensions;
|
||||
use goose::config::{Config, GooseMode};
|
||||
@@ -934,7 +935,8 @@ enum Command {
|
||||
long_about = "Runs a goose session tied to your terminal window.\n\
|
||||
Each terminal maintains its own persistent session that resumes automatically.\n\n\
|
||||
Setup:\n \
|
||||
eval \"$(goose term init zsh)\" # Add to ~/.zshrc\n\n\
|
||||
eval \"$(goose term init zsh)\" # zsh/bash\n \
|
||||
let init = ($nu.cache-dir | path join \"goose-term-init.nu\"); ^goose term init nu | save --force $init; source $init\n\n\
|
||||
Usage:\n \
|
||||
goose term run \"list files in this directory\"\n \
|
||||
@goose \"create a python script\" # using alias\n \
|
||||
@@ -953,10 +955,12 @@ enum Command {
|
||||
},
|
||||
|
||||
/// Generate completions for various shells
|
||||
#[command(about = "Generate the autocompletion script for the specified shell")]
|
||||
#[command(
|
||||
about = "Generate the autocompletion script or Nushell module for the specified shell"
|
||||
)]
|
||||
Completion {
|
||||
#[arg(value_enum)]
|
||||
shell: ClapShell,
|
||||
shell: CompletionShell,
|
||||
|
||||
#[arg(long, default_value = "goose", help = "Provide a custom binary name")]
|
||||
bin_name: String,
|
||||
@@ -1016,11 +1020,16 @@ enum TermCommand {
|
||||
Setup:\n \
|
||||
echo 'eval \"$(goose term init zsh)\"' >> ~/.zshrc\n \
|
||||
source ~/.zshrc\n\n\
|
||||
Nushell:\n \
|
||||
let init = ($nu.cache-dir | path join \"goose-term-init.nu\")\n \
|
||||
^goose term init nu | save --force $init\n \
|
||||
source $init\n\n\
|
||||
With --default (anything typed that isn't a command goes to goose):\n \
|
||||
echo 'eval \"$(goose term init zsh --default)\"' >> ~/.zshrc"
|
||||
echo 'eval \"$(goose term init zsh --default)\"' >> ~/.zshrc\n \
|
||||
^goose term init nu --default | save --force $init"
|
||||
)]
|
||||
Init {
|
||||
/// Shell type (bash, zsh, fish, powershell)
|
||||
/// Shell type (bash, zsh, fish, nu, powershell)
|
||||
#[arg(value_enum)]
|
||||
shell: Shell,
|
||||
|
||||
@@ -1031,7 +1040,7 @@ enum TermCommand {
|
||||
#[arg(
|
||||
long = "default",
|
||||
help = "Make goose the default handler for unknown commands",
|
||||
long_help = "When enabled, anything you type that isn't a valid command will be sent to goose. Only supported for zsh and bash."
|
||||
long_help = "When enabled, anything you type that isn't a valid command will be sent to goose. Supported for zsh, bash, and nu."
|
||||
)]
|
||||
default: bool,
|
||||
},
|
||||
@@ -1074,6 +1083,31 @@ enum CliProviderVariant {
|
||||
Ollama,
|
||||
}
|
||||
|
||||
#[derive(clap::ValueEnum, Clone, Copy, Debug, PartialEq, Eq)]
|
||||
enum CompletionShell {
|
||||
Bash,
|
||||
Elvish,
|
||||
Fish,
|
||||
#[value(alias = "pwsh")]
|
||||
Powershell,
|
||||
#[value(alias = "nushell")]
|
||||
Nu,
|
||||
Zsh,
|
||||
}
|
||||
|
||||
impl CompletionShell {
|
||||
fn generate(self, cmd: &mut clap::Command, bin_name: &str, writer: &mut dyn std::io::Write) {
|
||||
match self {
|
||||
CompletionShell::Bash => generate(ClapShell::Bash, cmd, bin_name, writer),
|
||||
CompletionShell::Elvish => generate(ClapShell::Elvish, cmd, bin_name, writer),
|
||||
CompletionShell::Fish => generate(ClapShell::Fish, cmd, bin_name, writer),
|
||||
CompletionShell::Powershell => generate(ClapShell::PowerShell, cmd, bin_name, writer),
|
||||
CompletionShell::Nu => generate(ClapNushell, cmd, bin_name, writer),
|
||||
CompletionShell::Zsh => generate(ClapShell::Zsh, cmd, bin_name, writer),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct InputConfig {
|
||||
pub contents: Option<String>,
|
||||
@@ -1846,7 +1880,7 @@ pub async fn cli() -> anyhow::Result<()> {
|
||||
match cli.command {
|
||||
Some(Command::Completion { shell, bin_name }) => {
|
||||
let mut cmd = Cli::command();
|
||||
generate(shell, &mut cmd, bin_name, &mut std::io::stdout());
|
||||
shell.generate(&mut cmd, &bin_name, &mut std::io::stdout());
|
||||
Ok(())
|
||||
}
|
||||
Some(Command::Configure {}) => handle_configure().await,
|
||||
@@ -1939,3 +1973,62 @@ pub async fn cli() -> anyhow::Result<()> {
|
||||
None => handle_default_session().await,
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn completion_command_accepts_nushell_alias() {
|
||||
let cli = Cli::try_parse_from(["goose", "completion", "nushell"]).expect("parse failed");
|
||||
|
||||
match cli.command {
|
||||
Some(Command::Completion {
|
||||
shell: CompletionShell::Nu,
|
||||
..
|
||||
}) => {}
|
||||
_ => panic!("expected nu completion shell"),
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn nushell_completion_generation_emits_module() {
|
||||
let mut cmd = Cli::command();
|
||||
let mut buffer = Vec::new();
|
||||
|
||||
CompletionShell::Nu.generate(&mut cmd, "goose", &mut buffer);
|
||||
|
||||
let script = String::from_utf8(buffer).expect("utf8");
|
||||
assert!(script.contains("module completions"));
|
||||
assert!(script.contains("export extern goose"));
|
||||
assert!(script.contains("export use completions *"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn term_init_help_mentions_nushell() {
|
||||
let mut cmd = Cli::command();
|
||||
let term = cmd.find_subcommand_mut("term").expect("term command");
|
||||
let init = term.find_subcommand_mut("init").expect("init command");
|
||||
let mut buffer = Vec::new();
|
||||
|
||||
init.write_long_help(&mut buffer).expect("write help");
|
||||
|
||||
let help = String::from_utf8(buffer).expect("utf8");
|
||||
assert!(help.contains("goose term init nu"));
|
||||
assert!(help.contains("Supported for zsh, bash, and nu"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn completion_help_lists_nu() {
|
||||
let mut cmd = Cli::command();
|
||||
let completion = cmd
|
||||
.find_subcommand_mut("completion")
|
||||
.expect("completion command");
|
||||
let mut buffer = Vec::new();
|
||||
|
||||
completion.write_long_help(&mut buffer).expect("write help");
|
||||
|
||||
let help = String::from_utf8(buffer).expect("utf8");
|
||||
assert!(help.contains("nu"));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,11 +9,13 @@ use crate::session::{build_session, SessionBuilderConfig};
|
||||
|
||||
use clap::ValueEnum;
|
||||
|
||||
#[derive(ValueEnum, Clone, Debug)]
|
||||
#[derive(ValueEnum, Clone, Copy, Debug, PartialEq, Eq)]
|
||||
pub enum Shell {
|
||||
Bash,
|
||||
Zsh,
|
||||
Fish,
|
||||
#[value(alias = "nushell")]
|
||||
Nu,
|
||||
#[value(alias = "pwsh")]
|
||||
Powershell,
|
||||
}
|
||||
@@ -29,6 +31,7 @@ impl Shell {
|
||||
Shell::Bash => &BASH_CONFIG,
|
||||
Shell::Zsh => &ZSH_CONFIG,
|
||||
Shell::Fish => &FISH_CONFIG,
|
||||
Shell::Nu => &NU_CONFIG,
|
||||
Shell::Powershell => &POWERSHELL_CONFIG,
|
||||
}
|
||||
}
|
||||
@@ -97,6 +100,42 @@ end"#,
|
||||
command_not_found: None,
|
||||
};
|
||||
|
||||
static NU_CONFIG: ShellConfig = ShellConfig {
|
||||
script_template: r#"$env.AGENT_SESSION_ID = "{session_id}"
|
||||
def --wrapped @goose [...args] { run-external "{goose_bin}" "term" "run" ...$args }
|
||||
def --wrapped @g [...args] { run-external "{goose_bin}" "term" "run" ...$args }
|
||||
|
||||
if (($env | get -o GOOSE_NU_PREEXEC_INSTALLED | default false) != true) {
|
||||
$env.GOOSE_NU_PREEXEC_INSTALLED = true
|
||||
$env.config.hooks.pre_execution = (
|
||||
$env.config.hooks.pre_execution
|
||||
| append {||
|
||||
let line = (commandline | str trim)
|
||||
if ($line | is-empty) {
|
||||
return
|
||||
}
|
||||
if ($line =~ '^goose term(\s|$)') {
|
||||
return
|
||||
}
|
||||
if ($line =~ '^(@goose|@g)(\s|$)') {
|
||||
return
|
||||
}
|
||||
job spawn { run-external "{goose_bin}" "term" "log" $line | complete | ignore } | ignore
|
||||
}
|
||||
)
|
||||
}
|
||||
{command_not_found_handler}"#,
|
||||
command_not_found: Some(
|
||||
r#"
|
||||
$env.config.hooks.command_not_found = {|command_name|
|
||||
let prompt = (try { commandline | str trim } catch { $command_name })
|
||||
print $"🪿 Command '($command_name)' not found. Asking goose..."
|
||||
run-external "{goose_bin}" "term" "run" $prompt | complete | ignore
|
||||
null
|
||||
}"#,
|
||||
),
|
||||
};
|
||||
|
||||
static POWERSHELL_CONFIG: ShellConfig = ShellConfig {
|
||||
script_template: r#"$env:AGENT_SESSION_ID = "{session_id}"
|
||||
function @goose {{ & '{goose_bin}' term run @args }}
|
||||
@@ -113,12 +152,34 @@ Set-PSReadLineKeyHandler -Chord Enter -ScriptBlock {{
|
||||
command_not_found: None,
|
||||
};
|
||||
|
||||
fn render_term_init_script(
|
||||
shell: Shell,
|
||||
session_id: &str,
|
||||
goose_bin: &str,
|
||||
with_command_not_found: bool,
|
||||
) -> String {
|
||||
let config = shell.config();
|
||||
let command_not_found_handler = if with_command_not_found {
|
||||
config
|
||||
.command_not_found
|
||||
.map(|handler| handler.replace("{goose_bin}", goose_bin))
|
||||
.unwrap_or_default()
|
||||
} else {
|
||||
String::new()
|
||||
};
|
||||
|
||||
config
|
||||
.script_template
|
||||
.replace("{session_id}", session_id)
|
||||
.replace("{goose_bin}", goose_bin)
|
||||
.replace("{command_not_found_handler}", &command_not_found_handler)
|
||||
}
|
||||
|
||||
pub async fn handle_term_init(
|
||||
shell: Shell,
|
||||
name: Option<String>,
|
||||
with_command_not_found: bool,
|
||||
) -> Result<()> {
|
||||
let config = shell.config();
|
||||
let session_manager = SessionManager::instance();
|
||||
|
||||
let working_dir = std::env::current_dir()?;
|
||||
@@ -159,28 +220,18 @@ pub async fn handle_term_init(
|
||||
.map(|p| p.to_string_lossy().into_owned())
|
||||
.unwrap_or_else(|_| "goose".to_string());
|
||||
|
||||
let command_not_found_handler = if with_command_not_found {
|
||||
config
|
||||
.command_not_found
|
||||
.map(|s| s.replace("{goose_bin}", &goose_bin))
|
||||
.unwrap_or_default()
|
||||
} else {
|
||||
String::new()
|
||||
};
|
||||
|
||||
let script = config
|
||||
.script_template
|
||||
.replace("{session_id}", &session.id)
|
||||
.replace("{goose_bin}", &goose_bin)
|
||||
.replace("{command_not_found_handler}", &command_not_found_handler);
|
||||
|
||||
println!("{}", script);
|
||||
println!(
|
||||
"{}",
|
||||
render_term_init_script(shell, &session.id, &goose_bin, with_command_not_found)
|
||||
);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub async fn handle_term_log(command: String) -> Result<()> {
|
||||
let session_id = std::env::var("AGENT_SESSION_ID").map_err(|_| {
|
||||
anyhow!("AGENT_SESSION_ID not set. Run 'eval \"$(goose term init <shell>)\"' first.")
|
||||
anyhow!(
|
||||
"AGENT_SESSION_ID not set. Initialize terminal integration with `goose term init <shell>` and reload your shell first."
|
||||
)
|
||||
})?;
|
||||
|
||||
let message = Message::new(
|
||||
@@ -202,9 +253,8 @@ pub async fn handle_term_run(prompt: Vec<String>) -> Result<()> {
|
||||
let session_id = std::env::var("AGENT_SESSION_ID").map_err(|_| {
|
||||
anyhow!(
|
||||
"AGENT_SESSION_ID not set.\n\n\
|
||||
Add to your shell config (~/.zshrc or ~/.bashrc):\n \
|
||||
eval \"$(goose term init zsh)\"\n\n\
|
||||
Then restart your terminal or run: source ~/.zshrc"
|
||||
Initialize terminal integration with `goose term init <shell>` in your shell profile, \
|
||||
then restart or reload that shell."
|
||||
)
|
||||
})?;
|
||||
|
||||
@@ -317,3 +367,37 @@ pub async fn handle_term_info() -> Result<()> {
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn render_term_init_script_includes_nushell_hooks() {
|
||||
let script = render_term_init_script(Shell::Nu, "session-123", "/tmp/goose", false);
|
||||
|
||||
assert!(script.contains("$env.AGENT_SESSION_ID = \"session-123\""));
|
||||
assert!(script.contains("def --wrapped @goose [...args]"));
|
||||
assert!(script.contains("def --wrapped @g [...args]"));
|
||||
assert!(script.contains("GOOSE_NU_PREEXEC_INSTALLED"));
|
||||
assert!(script.contains("$env.config.hooks.pre_execution"));
|
||||
assert!(script.contains("job spawn { run-external \"/tmp/goose\" \"term\" \"log\" $line | complete | ignore } | ignore"));
|
||||
assert!(!script.contains("command_not_found = {|command_name|"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn render_term_init_script_includes_nushell_default_handler() {
|
||||
let script = render_term_init_script(Shell::Nu, "session-123", "/tmp/goose", true);
|
||||
|
||||
assert!(script.contains("$env.config.hooks.command_not_found = {|command_name|"));
|
||||
assert!(script
|
||||
.contains("run-external \"/tmp/goose\" \"term\" \"run\" $prompt | complete | ignore"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn render_term_init_script_skips_unsupported_default_handler() {
|
||||
let script = render_term_init_script(Shell::Fish, "session-123", "/tmp/goose", true);
|
||||
|
||||
assert!(!script.contains("command_not_found"));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -47,6 +47,42 @@ fn flatpak_spawn_process() -> std::process::Command {
|
||||
command
|
||||
}
|
||||
|
||||
#[cfg(not(windows))]
|
||||
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
|
||||
enum UnixShellFlavor {
|
||||
Posix,
|
||||
Nushell,
|
||||
}
|
||||
|
||||
#[cfg(not(windows))]
|
||||
fn unix_shell_flavor(shell: &str) -> UnixShellFlavor {
|
||||
let name = std::path::Path::new(shell)
|
||||
.file_stem()
|
||||
.and_then(|stem| stem.to_str())
|
||||
.unwrap_or(shell)
|
||||
.to_ascii_lowercase();
|
||||
|
||||
match name.as_str() {
|
||||
"nu" | "nushell" => UnixShellFlavor::Nushell,
|
||||
_ => UnixShellFlavor::Posix,
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(not(windows))]
|
||||
fn unix_login_shell_command_args(shell: &str) -> [&'static str; 4] {
|
||||
let probe = match unix_shell_flavor(shell) {
|
||||
UnixShellFlavor::Nushell => "print ($env.PATH | str join (char esep))",
|
||||
UnixShellFlavor::Posix => "echo $PATH",
|
||||
};
|
||||
|
||||
["-l", "-i", "-c", probe]
|
||||
}
|
||||
|
||||
#[cfg(not(windows))]
|
||||
fn unix_shell_command_args(command_line: &str) -> [&str; 2] {
|
||||
["-c", command_line]
|
||||
}
|
||||
|
||||
/// Resolve the preferred Unix shell for command execution, respecting GOOSE_SHELL.
|
||||
///
|
||||
/// Auto-detected shells are returned as basenames (e.g. `"bash"`) so that
|
||||
@@ -169,15 +205,16 @@ fn resolve_login_shell_path() -> Option<String> {
|
||||
use process_wrap::std::{CommandWrap, ProcessSession};
|
||||
|
||||
let shell = unix_shell();
|
||||
let login_args = unix_login_shell_command_args(&shell);
|
||||
|
||||
// Build the command, varying only the flatpak vs direct invocation.
|
||||
let mut cmd = if is_flatpak() {
|
||||
let mut c = flatpak_spawn_process();
|
||||
c.args([&shell, "-l", "-i", "-c", "echo $PATH"]);
|
||||
c.arg(&shell).args(login_args);
|
||||
CommandWrap::from(c)
|
||||
} else {
|
||||
let mut c = std::process::Command::new(&shell);
|
||||
c.args(["-l", "-i", "-c", "echo $PATH"]);
|
||||
c.args(login_args);
|
||||
CommandWrap::from(c)
|
||||
};
|
||||
|
||||
@@ -597,11 +634,13 @@ fn build_shell_command(
|
||||
if let Some(path) = login_path {
|
||||
command.arg(format!("--env=PATH={}", path));
|
||||
}
|
||||
command.arg(&shell).arg("-c").arg(command_line);
|
||||
command
|
||||
.arg(&shell)
|
||||
.args(unix_shell_command_args(command_line));
|
||||
command
|
||||
} else {
|
||||
let mut command = tokio::process::Command::new(shell);
|
||||
command.arg("-c").arg(command_line);
|
||||
command.args(unix_shell_command_args(command_line));
|
||||
if let Some(path) = working_dir {
|
||||
command.current_dir(path);
|
||||
}
|
||||
@@ -812,6 +851,37 @@ mod tests {
|
||||
assert_eq!(observed, expected);
|
||||
}
|
||||
|
||||
#[cfg(not(windows))]
|
||||
#[test]
|
||||
fn unix_shell_flavor_detects_nushell_names() {
|
||||
assert_eq!(unix_shell_flavor("nu"), UnixShellFlavor::Nushell);
|
||||
assert_eq!(unix_shell_flavor("nushell"), UnixShellFlavor::Nushell);
|
||||
assert_eq!(
|
||||
unix_shell_flavor("/etc/profiles/per-user/can/bin/nu"),
|
||||
UnixShellFlavor::Nushell
|
||||
);
|
||||
assert_eq!(unix_shell_flavor("/bin/bash"), UnixShellFlavor::Posix);
|
||||
}
|
||||
|
||||
#[cfg(not(windows))]
|
||||
#[test]
|
||||
fn unix_login_shell_command_args_use_nushell_probe() {
|
||||
assert_eq!(
|
||||
unix_login_shell_command_args("nu"),
|
||||
["-l", "-i", "-c", "print ($env.PATH | str join (char esep))"]
|
||||
);
|
||||
assert_eq!(
|
||||
unix_login_shell_command_args("/bin/bash"),
|
||||
["-l", "-i", "-c", "echo $PATH"]
|
||||
);
|
||||
}
|
||||
|
||||
#[cfg(not(windows))]
|
||||
#[test]
|
||||
fn unix_shell_command_args_wrap_commands_for_execution() {
|
||||
assert_eq!(unix_shell_command_args("ls -la"), ["-c", "ls -la"]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn render_output_returns_full_output_when_under_limit() {
|
||||
let dir = tempfile::tempdir().unwrap();
|
||||
|
||||
@@ -104,7 +104,7 @@ Once installed, you can:
|
||||
- Discover options without checking `--help`
|
||||
|
||||
**Arguments:**
|
||||
- **`<SHELL>`**: The shell to generate completions for. Supported shells: `bash`, `elvish`, `fish`, `powershell`, `zsh`
|
||||
- **`<SHELL>`**: The shell to generate completions for. Supported shells: `bash`, `elvish`, `fish`, `nu`, `powershell`, `zsh`
|
||||
|
||||
**Usage:**
|
||||
```bash
|
||||
@@ -112,6 +112,7 @@ Once installed, you can:
|
||||
goose completion bash
|
||||
goose completion zsh
|
||||
goose completion fish
|
||||
goose completion nu
|
||||
```
|
||||
|
||||
**Installation by Shell:**
|
||||
@@ -153,6 +154,20 @@ goose completion fish > ~/.config/fish/completions/goose.fish
|
||||
|
||||
Then restart your terminal or run `exec fish`.
|
||||
|
||||
</TabItem>
|
||||
<TabItem value="nu" label="Nushell">
|
||||
|
||||
```nu
|
||||
let autoload_dir = ($nu.user-autoload-dirs | first)
|
||||
mkdir $autoload_dir
|
||||
goose completion nu | save --force ($autoload_dir | path join "goose.nu")
|
||||
```
|
||||
|
||||
Then restart Nushell or run:
|
||||
```nu
|
||||
source (($nu.user-autoload-dirs | first) | path join "goose.nu")
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
<TabItem value="powershell" label="PowerShell">
|
||||
|
||||
|
||||
@@ -31,6 +31,16 @@ Add to `~/.config/fish/config.fish`:
|
||||
goose term init fish | source
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
<TabItem value="nu" label="Nushell">
|
||||
|
||||
Add to `~/.config/nushell/config.nu`:
|
||||
```nu
|
||||
let goose_term_init = ($nu.cache-dir | path join "goose-term-init.nu")
|
||||
^goose term init nu | save --force $goose_term_init
|
||||
source $goose_term_init
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
<TabItem value="powershell" label="PowerShell">
|
||||
|
||||
@@ -87,6 +97,15 @@ eval "$(goose term init bash --name my-project)"
|
||||
goose term init fish --name my-project | source
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
<TabItem value="nu" label="Nushell">
|
||||
|
||||
```nu
|
||||
let goose_term_init = ($nu.cache-dir | path join "goose-term-init.nu")
|
||||
^goose term init nu --name my-project | save --force $goose_term_init
|
||||
source $goose_term_init
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
<TabItem value="powershell" label="PowerShell">
|
||||
|
||||
@@ -110,6 +129,36 @@ eval "$(goose term init zsh --name auth-bug)"
|
||||
# Continues the same conversation with context
|
||||
```
|
||||
|
||||
## Default Handler
|
||||
|
||||
Use `--default` if you want goose to answer commands your shell cannot resolve.
|
||||
|
||||
<Tabs groupId="default-shells">
|
||||
<TabItem value="zsh" label="zsh" default>
|
||||
|
||||
```bash
|
||||
eval "$(goose term init zsh --default)"
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
<TabItem value="bash" label="bash">
|
||||
|
||||
```bash
|
||||
eval "$(goose term init bash --default)"
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
<TabItem value="nu" label="Nushell">
|
||||
|
||||
```nu
|
||||
let goose_term_init = ($nu.cache-dir | path join "goose-term-init.nu")
|
||||
^goose term init nu --default | save --force $goose_term_init
|
||||
source $goose_term_init
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
## Show Context Status in Your Prompt
|
||||
|
||||
Add `goose term info` to your prompt to see how much context you've used and which model is active during a terminal goose session.
|
||||
@@ -138,6 +187,13 @@ function fish_prompt
|
||||
end
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
<TabItem value="nu" label="Nushell">
|
||||
|
||||
```nu
|
||||
$env.PROMPT_COMMAND = {|| $"(goose term info) (pwd)> " }
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
<TabItem value="powershell" label="PowerShell">
|
||||
|
||||
@@ -170,6 +226,11 @@ You can also check the id of the goose session in your current terminal:
|
||||
echo $AGENT_SESSION_ID
|
||||
# Should show something like: 20251209_151730
|
||||
```
|
||||
```nu
|
||||
# Nushell
|
||||
$env.AGENT_SESSION_ID
|
||||
# Should show something like: 20251209_151730
|
||||
```
|
||||
To share context across terminal windows, use a [named session](#named-sessions) instead.
|
||||
|
||||
**Session getting too full** (prompt shows `●●●●●`):
|
||||
@@ -178,3 +239,9 @@ If goose's responses are getting slow or hitting context limits, start a fresh g
|
||||
# Start a new goose session in the same shell
|
||||
eval "$(goose term init zsh)"
|
||||
```
|
||||
```nu
|
||||
# Nushell
|
||||
let goose_term_init = ($nu.cache-dir | path join "goose-term-init.nu")
|
||||
^goose term init nu | save --force $goose_term_init
|
||||
source $goose_term_init
|
||||
```
|
||||
|
||||
Reference in New Issue
Block a user