diff options
| author | Paul Buetow <paul@buetow.org> | 2025-09-17 22:49:13 +0300 |
|---|---|---|
| committer | Paul Buetow <paul@buetow.org> | 2025-09-17 22:49:13 +0300 |
| commit | d059ae333fa1c89cb58d7fb56ead79cdba15d5db (patch) | |
| tree | ae65ad59c8590f71232a6abefee312b72ddf6d3e /internal/hexaicli | |
| parent | 88103657fb230bb41217a06aa5602ae23e7acb8b (diff) | |
chore(version): bump to v0.11.1 (gpt-5 defaults, timeouts, global stats, editor fix)v0.11.1
Diffstat (limited to 'internal/hexaicli')
| -rw-r--r-- | internal/hexaicli/run.go | 11 | ||||
| -rw-r--r-- | internal/hexaicli/run_editor_behavior_test.go | 47 |
2 files changed, 52 insertions, 6 deletions
diff --git a/internal/hexaicli/run.go b/internal/hexaicli/run.go index 9909f4f..823dcaa 100644 --- a/internal/hexaicli/run.go +++ b/internal/hexaicli/run.go @@ -35,16 +35,15 @@ func Run(ctx context.Context, args []string, stdin io.Reader, stdout, stderr io. fmt.Fprintf(stderr, logging.AnsiBase+"hexai: LLM disabled: %v"+logging.AnsiReset+"\n", err) return err } - // No args: open editor to capture a prompt, then combine with stdin as usual. - if len(args) == 0 { + // Prefer piped stdin when present; only open the editor when there are no args + // and no stdin content available. + input, rerr := readInput(stdin, args) + if rerr != nil && len(args) == 0 { if prompt, eerr := editor.OpenTempAndEdit(nil); eerr == nil && strings.TrimSpace(prompt) != "" { args = []string{prompt} - } else { - // If editor fails or empty, continue; readInput will likely error if no stdin either. + input, rerr = readInput(stdin, args) } } - // Inline the flow here to use configured CLI prompts. - input, rerr := readInput(stdin, args) if rerr != nil { fmt.Fprintln(stderr, logging.AnsiBase+rerr.Error()+logging.AnsiReset) return rerr diff --git a/internal/hexaicli/run_editor_behavior_test.go b/internal/hexaicli/run_editor_behavior_test.go new file mode 100644 index 0000000..a934473 --- /dev/null +++ b/internal/hexaicli/run_editor_behavior_test.go @@ -0,0 +1,47 @@ +package hexaicli + +import ( + "bytes" + "context" + "strings" + "testing" + + "codeberg.org/snonux/hexai/internal/appconfig" + "codeberg.org/snonux/hexai/internal/editor" + "codeberg.org/snonux/hexai/internal/llm" +) + +// fake client that returns a fixed response +type okClient struct{} + +func (okClient) Chat(_ context.Context, _ []llm.Message, _ ...llm.RequestOption) (string, error) { + return "OK", nil +} +func (okClient) Name() string { return "prov" } +func (okClient) DefaultModel() string { return "m" } + +// Ensure that when stdin has content and args are empty, Run does not open the editor. +func TestRun_DoesNotOpenEditorWhenStdinPresent(t *testing.T) { + // Guard: make editor invocation fatal if called + oldRunEd := editor.RunEditor + defer func() { editor.RunEditor = oldRunEd }() + editor.RunEditor = func(_ string, _ string) error { + t.Fatalf("editor should not be invoked when stdin has content") + return nil + } + + // Stub client constructor to avoid hitting real providers + oldNew := newClientFromApp + defer func() { newClientFromApp = oldNew }() + newClientFromApp = func(_ appconfig.App) (llm.Client, error) { return okClient{}, nil } + + var out, errb bytes.Buffer + restore, f := setStdin(t, "from-stdin") + defer restore() + if err := Run(context.Background(), nil, f, &out, &errb); err != nil { + t.Fatalf("Run: %v", err) + } + if !strings.Contains(out.String(), "OK") { + t.Fatalf("expected OK output, got %q", out.String()) + } +} |
