From 1171a091c883c3e59bc81d8aacad9f38763b237b Mon Sep 17 00:00:00 2001 From: Bx Date: Tue, 25 Aug 2026 13:35:04 -0700 Subject: bare (non‑interactive) mode: output just the raw result MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- main.go | 45 +++++++++++++++++++++++++++++++++++++++------ 1 file changed, 39 insertions(+), 6 deletions(-) (limited to 'main.go') diff --git a/main.go b/main.go index df82ac9..c17cf5e 100644 --- a/main.go +++ b/main.go @@ -301,9 +301,7 @@ func toolBash(in map[string]any) (string, error) { case out = <-done: case <-time.After(30 * time.Second): // Kill the GROUP, not just sh: `sh -c "sleep 60"` forks, and the - // grandchild inherits the pipe's write end. Killing sh alone leaves - // the pipe open and the drain below blocks until the grandchild - // exits on its own -- a 30s timeout that takes 60s. + // grandchild inherits the pipe's write end. if err := syscall.Kill(-cmd.Process.Pid, syscall.SIGKILL); err != nil { cmd.Process.Kill() } @@ -500,10 +498,20 @@ func agentLoop(messages *[]message) error { } switch b.Type { case "text": - fmt.Printf("\n%s⏺%s %s\n", cyan, reset, renderMarkdown(b.Text)) + if bareMode { + // In bare mode, output raw text without leading newline or markers. + fmt.Print(b.Text) + if !strings.HasSuffix(b.Text, "\n") { + fmt.Print("\n") + } + } else { + fmt.Printf("\n%s⏺%s %s\n", cyan, reset, renderMarkdown(b.Text)) + } case "tool_use": - fmt.Printf("\n%s⏺ %s%s(%s%s%s)\n", - green, capitalize(b.Name), reset, dim, argPreview(b.Name, b.Input), reset) + if !bareMode { + fmt.Printf("\n%s⏺ %s%s(%s%s%s)\n", + green, capitalize(b.Name), reset, dim, argPreview(b.Name, b.Input), reset) + } out := runTool(b.Name, b.Input) printResult(out) results = append(results, toolResult{"tool_result", b.ID, out}) @@ -560,7 +568,18 @@ func argPreview(name string, input json.RawMessage) string { return "" } +// Global flag indicating bare (non‑interactive) mode. +var bareMode bool + func printResult(out string) { + if bareMode { + // In bare mode output the raw result. + fmt.Print(out) + if !strings.HasSuffix(out, "\n") { + fmt.Print("\n") + } + return + } lines := strings.Split(out, "\n") preview := truncate(lines[0], 60) if len(lines) > 1 { @@ -574,6 +593,20 @@ func printResult(out string) { // ---------------------------------------------------------------------- REPL func main() { + fi, _ := os.Stdin.Stat() + bareMode = (fi.Mode() & os.ModeCharDevice) == 0 + + if bareMode { + data, _ := io.ReadAll(os.Stdin) + line := strings.TrimSpace(string(data)) + if line == "" { + return + } + messages := []message{{"user", line}} + _ = agentLoop(&messages) // errors are printed inside agentLoop via fmt.Printf in interactive mode; here we ignore. + return + } + cwd, _ := os.Getwd() fmt.Printf("%spico%s | %s%s | %s%s\n\n", bold, reset, dim, model, cwd, reset) -- cgit v1.2.3