chore: rename parameter and add better description

Kujtim Hoxha created

Change summary

internal/agent/tools/bash.go                      | 30 +++++++++-------
internal/agent/tools/bash.tpl                     | 16 +++++++-
internal/tui/components/chat/messages/renderer.go |  2 
3 files changed, 30 insertions(+), 18 deletions(-)

Detailed changes

internal/agent/tools/bash.go 🔗

@@ -19,17 +19,17 @@ import (
 )
 
 type BashParams struct {
-	Command     string `json:"command" description:"The command to execute"`
-	Description string `json:"description,omitempty" description:"A brief description of what the command does"`
-	WorkingDir  string `json:"working_dir,omitempty" description:"The working directory to execute the command in (defaults to current directory)"`
-	Background  bool   `json:"background,omitempty" description:"Run the command in a background shell. Returns a shell ID for managing the process."`
+	Command         string `json:"command" description:"The command to execute"`
+	Description     string `json:"description,omitempty" description:"A brief description of what the command does"`
+	WorkingDir      string `json:"working_dir,omitempty" description:"The working directory to execute the command in (defaults to current directory)"`
+	RunInBackground bool   `json:"run_in_background,omitempty" description:"Set to true (boolean) to run this command in the background. Use bash_output to read the output later."`
 }
 
 type BashPermissionsParams struct {
-	Command     string `json:"command"`
-	Description string `json:"description"`
-	WorkingDir  string `json:"working_dir"`
-	Background  bool   `json:"background"`
+	Command         string `json:"command"`
+	Description     string `json:"description"`
+	WorkingDir      string `json:"working_dir"`
+	RunInBackground bool   `json:"run_in_background"`
 }
 
 type BashResponseMetadata struct {
@@ -231,11 +231,12 @@ func NewBashTool(permissions permission.Service, workingDir string, attribution
 				}
 			}
 
-			// If explicitly requested as background, start immediately
-			if params.Background {
+			// If explicitly requested as background, start immediately with detached context
+			if params.RunInBackground {
 				startTime := time.Now()
 				bgManager := shell.GetBackgroundShellManager()
-				bgShell, err := bgManager.Start(ctx, execWorkingDir, blockFuncs(), params.Command)
+				// Use background context so it continues after tool returns
+				bgShell, err := bgManager.Start(context.Background(), execWorkingDir, blockFuncs(), params.Command)
 				if err != nil {
 					return fantasy.ToolResponse{}, fmt.Errorf("error starting background shell: %w", err)
 				}
@@ -255,9 +256,9 @@ func NewBashTool(permissions permission.Service, workingDir string, attribution
 			// Start synchronous execution with auto-background support
 			startTime := time.Now()
 
-			// Start background shell immediately but wait for threshold before deciding
+			// Start with detached context so it can survive if moved to background
 			bgManager := shell.GetBackgroundShellManager()
-			bgShell, err := bgManager.Start(ctx, execWorkingDir, blockFuncs(), params.Command)
+			bgShell, err := bgManager.Start(context.Background(), execWorkingDir, blockFuncs(), params.Command)
 			if err != nil {
 				return fantasy.ToolResponse{}, fmt.Errorf("error starting shell: %w", err)
 			}
@@ -283,7 +284,8 @@ func NewBashTool(permissions permission.Service, workingDir string, attribution
 					stdout, stderr, done, execErr = bgShell.GetOutput()
 					break waitLoop
 				case <-ctx.Done():
-					// Context was cancelled, kill the shell and return error
+					// Incoming context was cancelled before we moved to background
+					// Kill the shell and return error
 					bgManager.Kill(bgShell.ID)
 					return fantasy.ToolResponse{}, ctx.Err()
 				}

internal/agent/tools/bash.tpl 🔗

@@ -24,12 +24,22 @@ Common shell builtins and core utils available on Windows.
 </usage_notes>
 
 <background_execution>
-- Set background=true to run commands in a separate background shell
-- Commands taking longer than 1 minute automatically convert to background
+- Set run_in_background=true to run commands in a separate background shell
 - Returns a shell ID for managing the background process
 - Use bash_output tool to view current output from background shell
 - Use bash_kill tool to terminate a background shell
-- Useful for long-running processes, servers, or monitoring tasks
+- IMPORTANT: NEVER use '&' at the end of commands to run in background - use run_in_background parameter instead
+- Commands that should run in background:
+  * Long-running servers (e.g., 'npm start', 'python -m http.server', 'node server.js')
+  * Watch/monitoring tasks (e.g., 'npm run watch', 'tail -f logfile')
+  * Continuous processes that don't exit on their own
+  * Any command expected to run indefinitely
+- Commands that should NOT run in background:
+  * Build commands (e.g., 'npm run build', 'go build')
+  * Test suites (e.g., 'npm test', 'pytest')
+  * Git operations
+  * File operations
+  * Short-lived scripts
 </background_execution>
 
 <git_commits>

internal/tui/components/chat/messages/renderer.go 🔗

@@ -217,7 +217,7 @@ func (br bashRenderer) Render(v *toolCallCmp) string {
 	cmd = strings.ReplaceAll(cmd, "\t", "    ")
 	args := newParamBuilder().
 		addMain(cmd).
-		addFlag("background", params.Background).
+		addFlag("background", params.RunInBackground).
 		build()
 
 	return br.renderWithParams(v, "Bash", args, func() string {