summaryrefslogtreecommitdiff
path: root/internal/tmuxedit/run.go
diff options
context:
space:
mode:
authorPaul Buetow <paul@buetow.org>2026-02-08 16:31:40 +0200
committerPaul Buetow <paul@buetow.org>2026-02-08 16:31:40 +0200
commitc802ba5803de1a53749bb5c4ecbc0159fceb385f (patch)
tree02e612286f36bc6c65563bc33cf53639817d2db1 /internal/tmuxedit/run.go
parent887d7bc186db90c3903851b0f1db2d24df5d7a7b (diff)
refactor tmuxedit to Agent interface with cursor/claude/config implementations
Replace monolithic AgentConfig struct with an Agent interface backed by baseAgent defaults and separate implementations for cursor (box-drawing extraction, bulk backspace clearing) and claude (section-scoped extraction with continuation lines, vim clearing). Simple agents (amp, aider) and user-defined agents use configAgent with baseAgent defaults. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Diffstat (limited to 'internal/tmuxedit/run.go')
-rw-r--r--internal/tmuxedit/run.go63
1 files changed, 40 insertions, 23 deletions
diff --git a/internal/tmuxedit/run.go b/internal/tmuxedit/run.go
index dde91fa..f81eb64 100644
--- a/internal/tmuxedit/run.go
+++ b/internal/tmuxedit/run.go
@@ -119,6 +119,8 @@ func dbg(format string, args ...any) {
}
// runWithConfig executes the edit workflow using the provided config.
+// It resolves the agent (by name or auto-detect), extracts the current
+// prompt, opens the editor popup, then clears and sends the result.
func runWithConfig(opts Options, cfg appconfig.App) error {
initDebugLog()
dbg("=== hexai-tmux-edit start ===")
@@ -137,29 +139,16 @@ func runWithConfig(opts Options, cfg appconfig.App) error {
return err
}
dbg("captured %d bytes from pane", len(content))
- // Log a few lines around the prompt
- for i, line := range strings.Split(content, "\n") {
- if strings.Contains(line, "│") || strings.Contains(line, "→") {
- dbg(" pane line %d: %q", i, line)
- }
- }
+ logPaneLines(content)
agents := resolveAgents(cfg.TmuxEditAgents)
agent := pickAgent(opts.Agent, content, agents)
- dbg("agent: name=%q detect=%q prompt=%q strip=%v clear=%v clearKeys=%q",
- agent.Name, agent.DetectPattern, agent.PromptPattern, agent.StripPatterns, agent.ClearFirst, agent.ClearKeys)
+ dbg("agent: name=%q", agent.Name())
- original := extractPrompt(content, agent)
+ original := agent.ExtractPrompt(content)
dbg("extractPrompt result: %q", original)
- popupW := cfg.TmuxEditPopupWidth
- if popupW == "" {
- popupW = "80%"
- }
- popupH := cfg.TmuxEditPopupHeight
- if popupH == "" {
- popupH = "80%"
- }
+ popupW, popupH := popupDimensions(cfg)
dbg("opening editor popup: w=%s h=%s initial=%q", popupW, popupH, original)
edited, err := openEditorPopup(original, popupW, popupH)
@@ -176,17 +165,45 @@ func runWithConfig(opts Options, cfg appconfig.App) error {
return nil
}
- dbg("sending to pane %q: %q", paneID, text)
- err = sendTextToPane(paneID, text, agent)
- if err != nil {
- dbg("sendTextToPane error: %v", err)
+ dbg("clearing and sending to pane %q: %q", paneID, text)
+ if err := agent.ClearInput(paneID); err != nil {
+ dbg("ClearInput error: %v", err)
+ return err
+ }
+ if err := agent.SendText(paneID, text); err != nil {
+ dbg("SendText error: %v", err)
+ return err
}
dbg("=== done ===")
- return err
+ return nil
+}
+
+// logPaneLines logs lines containing box-drawing or arrow characters for
+// debugging prompt detection.
+func logPaneLines(content string) {
+ for i, line := range strings.Split(content, "\n") {
+ if strings.Contains(line, "│") || strings.Contains(line, "→") {
+ dbg(" pane line %d: %q", i, line)
+ }
+ }
+}
+
+// popupDimensions returns the popup width and height from config, defaulting
+// to "80%" for both if not set.
+func popupDimensions(cfg appconfig.App) (string, string) {
+ w := cfg.TmuxEditPopupWidth
+ if w == "" {
+ w = "80%"
+ }
+ h := cfg.TmuxEditPopupHeight
+ if h == "" {
+ h = "80%"
+ }
+ return w, h
}
// pickAgent selects an agent by explicit name or auto-detection.
-func pickAgent(name, content string, agents []AgentConfig) AgentConfig {
+func pickAgent(name, content string, agents []Agent) Agent {
if name != "" {
return findAgentByName(name, agents)
}