Allow Bash tool to Just Work with more cd
inputs (#27501)
Release Notes: - N/A
This commit is contained in:
parent
6ead57d5ed
commit
52c1e0021c
1 changed files with 39 additions and 4 deletions
|
@ -5,6 +5,7 @@ use language_model::LanguageModelRequestMessage;
|
||||||
use project::Project;
|
use project::Project;
|
||||||
use schemars::JsonSchema;
|
use schemars::JsonSchema;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
use std::path::Path;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use ui::IconName;
|
use ui::IconName;
|
||||||
use util::command::new_smol_command;
|
use util::command::new_smol_command;
|
||||||
|
@ -68,10 +69,44 @@ impl Tool for BashTool {
|
||||||
Err(err) => return Task::ready(Err(anyhow!(err))),
|
Err(err) => return Task::ready(Err(anyhow!(err))),
|
||||||
};
|
};
|
||||||
|
|
||||||
let Some(worktree) = project.read(cx).worktree_for_root_name(&input.cd, cx) else {
|
let project = project.read(cx);
|
||||||
return Task::ready(Err(anyhow!("Working directory not found in the project")));
|
let input_path = Path::new(&input.cd);
|
||||||
|
let working_dir = if input.cd == "." {
|
||||||
|
// Accept "." as meaning "the one worktree" if we only have one worktree.
|
||||||
|
let mut worktrees = project.worktrees(cx);
|
||||||
|
|
||||||
|
let only_worktree = match worktrees.next() {
|
||||||
|
Some(worktree) => worktree,
|
||||||
|
None => return Task::ready(Err(anyhow!("No worktrees found in the project"))),
|
||||||
|
};
|
||||||
|
|
||||||
|
if worktrees.next().is_some() {
|
||||||
|
return Task::ready(Err(anyhow!("'.' is ambiguous in multi-root workspaces. Please specify a root directory explicitly.")));
|
||||||
|
}
|
||||||
|
|
||||||
|
only_worktree.read(cx).abs_path()
|
||||||
|
} else if input_path.is_absolute() {
|
||||||
|
// Absolute paths are allowed, but only if they're in one of the project's worktrees.
|
||||||
|
if !project
|
||||||
|
.worktrees(cx)
|
||||||
|
.any(|worktree| input_path.starts_with(&worktree.read(cx).abs_path()))
|
||||||
|
{
|
||||||
|
return Task::ready(Err(anyhow!(
|
||||||
|
"The absolute path must be within one of the project's worktrees"
|
||||||
|
)));
|
||||||
|
}
|
||||||
|
|
||||||
|
input_path.into()
|
||||||
|
} else {
|
||||||
|
let Some(worktree) = project.worktree_for_root_name(&input.cd, cx) else {
|
||||||
|
return Task::ready(Err(anyhow!(
|
||||||
|
"`cd` directory {} not found in the project",
|
||||||
|
&input.cd
|
||||||
|
)));
|
||||||
|
};
|
||||||
|
|
||||||
|
worktree.read(cx).abs_path()
|
||||||
};
|
};
|
||||||
let working_directory = worktree.read(cx).abs_path();
|
|
||||||
|
|
||||||
cx.spawn(async move |_| {
|
cx.spawn(async move |_| {
|
||||||
// Add 2>&1 to merge stderr into stdout for proper interleaving.
|
// Add 2>&1 to merge stderr into stdout for proper interleaving.
|
||||||
|
@ -80,7 +115,7 @@ impl Tool for BashTool {
|
||||||
let output = new_smol_command("bash")
|
let output = new_smol_command("bash")
|
||||||
.arg("-c")
|
.arg("-c")
|
||||||
.arg(&command)
|
.arg(&command)
|
||||||
.current_dir(working_directory)
|
.current_dir(working_dir)
|
||||||
.output()
|
.output()
|
||||||
.await
|
.await
|
||||||
.context("Failed to execute bash command")?;
|
.context("Failed to execute bash command")?;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue