summaryrefslogtreecommitdiff
path: root/internal/hexaiaction/run.go
diff options
context:
space:
mode:
Diffstat (limited to 'internal/hexaiaction/run.go')
-rw-r--r--internal/hexaiaction/run.go74
1 files changed, 74 insertions, 0 deletions
diff --git a/internal/hexaiaction/run.go b/internal/hexaiaction/run.go
new file mode 100644
index 0000000..2a67a58
--- /dev/null
+++ b/internal/hexaiaction/run.go
@@ -0,0 +1,74 @@
+package hexaiaction
+
+import (
+ "context"
+ "fmt"
+ "io"
+ "log"
+ "strings"
+
+ "codeberg.org/snonux/hexai/internal/appconfig"
+ "codeberg.org/snonux/hexai/internal/logging"
+ "codeberg.org/snonux/hexai/internal/llmutils"
+)
+
+// Run executes the hexai-action command flow.
+func Run(ctx context.Context, stdin io.Reader, stdout, stderr io.Writer) error {
+ logger := log.New(stderr, "hexai-action ", log.LstdFlags|log.Lmsgprefix)
+ cfg := appconfig.Load(logger)
+ client, err := llmutils.NewClientFromApp(cfg)
+ if err != nil {
+ fmt.Fprintf(stderr, logging.AnsiBase+"hexai-action: LLM disabled: %v"+logging.AnsiReset+"\n", err)
+ return err
+ }
+ parts, err := ParseInput(stdin)
+ if err != nil {
+ fmt.Fprintln(stderr, logging.AnsiBase+"hexai-action: failed to read input"+logging.AnsiReset)
+ return err
+ }
+ if strings.TrimSpace(parts.Selection) == "" {
+ return fmt.Errorf("hexai-action: no input provided on stdin")
+ }
+ kind, err := RunTUI()
+ if err != nil {
+ return err
+ }
+ out, err := executeAction(ctx, kind, parts, cfg, client, stderr)
+ if err != nil {
+ return err
+ }
+ io.WriteString(stdout, out)
+ return nil
+}
+
+func executeAction(ctx context.Context, kind ActionKind, parts InputParts, cfg appconfig.App, client chatDoer, stderr io.Writer) (string, error) {
+ switch kind {
+ case ActionSkip:
+ return parts.Selection, nil
+ case ActionRewrite:
+ instr, cleaned := ExtractInstruction(parts.Selection)
+ if strings.TrimSpace(instr) == "" {
+ fmt.Fprintln(stderr, logging.AnsiBase+"hexai-action: no inline instruction found; echoing input"+logging.AnsiReset)
+ return parts.Selection, nil
+ }
+ cctx, cancel := timeout10s(ctx)
+ defer cancel()
+ return runRewrite(cctx, cfg, client, instr, cleaned)
+ case ActionDiagnostics:
+ cctx, cancel := timeout10s(ctx)
+ defer cancel()
+ return runDiagnostics(cctx, cfg, client, parts.Diagnostics, parts.Selection)
+ case ActionDocument:
+ cctx, cancel := timeout10s(ctx)
+ defer cancel()
+ return runDocument(cctx, cfg, client, parts.Selection)
+ case ActionGoTest:
+ cctx, cancel := timeout8s(ctx)
+ defer cancel()
+ return runGoTest(cctx, cfg, client, parts.Selection)
+ default:
+ return parts.Selection, nil
+ }
+}
+
+// client construction is shared via internal/llmutils