runScriptBlock writes the block's single script to a temp file and runs it, streaming output to the terminal and accumulating it into allOutput.
(ctx context.Context, block agent.CommandBlock, shell string, allOutput *strings.Builder, lastError *string)
| 751 | // runScriptBlock writes the block's single script to a temp file and runs it, |
| 752 | // streaming output to the terminal and accumulating it into allOutput. |
| 753 | func (a *AgentMode) runScriptBlock(ctx context.Context, block agent.CommandBlock, shell string, allOutput *strings.Builder, lastError *string) { |
| 754 | scriptContent := block.Commands[0] |
| 755 | tmpFile, err := os.CreateTemp("", "chatcli-script-*.sh") |
| 756 | if err != nil { |
| 757 | errorMsg := i18n.T("agent.error.create_temp_file", err) |
| 758 | errMsg := fmt.Sprintf("%s\n", errorMsg) |
| 759 | fmt.Print(errMsg) |
| 760 | allOutput.WriteString(errMsg) |
| 761 | *lastError = err.Error() |
| 762 | return |
| 763 | } |
| 764 | scriptPath := tmpFile.Name() |
| 765 | defer func() { _ = os.Remove(scriptPath) }() |
| 766 | |
| 767 | if _, werr := tmpFile.WriteString(scriptContent); werr != nil { |
| 768 | errorMsg := i18n.T("agent.error.write_script", werr) |
| 769 | errMsg := fmt.Sprintf("%s\n", errorMsg) |
| 770 | fmt.Print(errMsg) |
| 771 | allOutput.WriteString(errMsg) |
| 772 | *lastError = werr.Error() |
| 773 | } |
| 774 | _ = tmpFile.Close() |
| 775 | _ = os.Chmod(scriptPath, 0o700) //#nosec G302 -- intentional: script must be owner-executable to run |
| 776 | |
| 777 | header := i18n.T("agent.status.executing_script", shell) + "\n" |
| 778 | fmt.Print(header) |
| 779 | allOutput.WriteString(header) |
| 780 | |
| 781 | result, runErr := a.executor.Execute(ctx, scriptPath, false) |
| 782 | |
| 783 | safe := utils.SanitizeSensitiveText(result.Output) |
| 784 | for _, line := range strings.Split(strings.TrimRight(safe, "\n"), "\n") { |
| 785 | fmt.Println(" " + line) |
| 786 | } |
| 787 | allOutput.WriteString(safe + "\n") |
| 788 | |
| 789 | if runErr != nil { |
| 790 | errMsg := fmt.Sprintf("❌ Erro: %v\n", runErr) |
| 791 | allOutput.WriteString(errMsg) |
| 792 | *lastError = runErr.Error() |
| 793 | } |
| 794 | |
| 795 | meta := fmt.Sprintf(" [exit=%d, duração=%s]\n", result.ExitCode, result.Duration) |
| 796 | fmt.Print(meta) |
| 797 | allOutput.WriteString(fmt.Sprintf("[meta] exit=%d duration=%s\n", result.ExitCode, result.Duration)) |
| 798 | } |
| 799 | |
| 800 | // runSingleCommand executes one command from a non-script block, handling |
| 801 | // cd changes, dangerous-command confirmation, and interactive detection. |
no test coverage detected