diff options
| author | Paul Buetow <paul@buetow.org> | 2026-02-08 16:31:40 +0200 |
|---|---|---|
| committer | Paul Buetow <paul@buetow.org> | 2026-02-08 16:31:40 +0200 |
| commit | c802ba5803de1a53749bb5c4ecbc0159fceb385f (patch) | |
| tree | 02e612286f36bc6c65563bc33cf53639817d2db1 /internal/tmuxedit/cursor_agent.go | |
| parent | 887d7bc186db90c3903851b0f1db2d24df5d7a7b (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/cursor_agent.go')
| -rw-r--r-- | internal/tmuxedit/cursor_agent.go | 58 |
1 files changed, 58 insertions, 0 deletions
diff --git a/internal/tmuxedit/cursor_agent.go b/internal/tmuxedit/cursor_agent.go new file mode 100644 index 0000000..1346d05 --- /dev/null +++ b/internal/tmuxedit/cursor_agent.go @@ -0,0 +1,58 @@ +package tmuxedit + +import ( + "regexp" +) + +// cursorAgent handles Cursor's distinctive box-drawing │ → prompt │ UI. +// Cursor uses a text field (not vim), so clearing is done with End + bulk +// backspace. Multi-line prompts are entered with Shift-Enter within the box. +type cursorAgent struct{ baseAgent } + +// newCursorAgent returns a cursorAgent with the default configuration. +// Detect by the box structure or "/ commands" footer. Checked first because +// cursor panes often show model names like "Claude 4.5 Sonnet". +func newCursorAgent() *cursorAgent { + return &cursorAgent{baseAgent{ + name: "cursor", + displayName: "Cursor", + detectPattern: `(│\s*→|/ commands · @ files)`, + promptPat: `(?m)│\s*→?\s*(.+?)\s*│\s*$`, + stripPatterns: []string{"INSERT", "Add a follow-up", "ctrl+c to stop"}, + clearFirst: true, + clearKeys: "End BSpace*200", + newlineKeys: "S-Enter", + submitKeys: "Enter", + }} +} + +// ExtractPrompt extracts the prompt text from the last contiguous │...│ block +// in the pane. This avoids picking up earlier command-review or dialog boxes +// that also use box-drawing characters. +func (c *cursorAgent) ExtractPrompt(paneContent string) string { + if c.promptPat == "" { + return "" + } + re, err := regexp.Compile(c.promptPat) + if err != nil { + return "" + } + allMatches := matchPromptLines(re, paneContent) + if len(allMatches) == 0 { + return "" + } + return joinLastContiguousBlock(allMatches, c.stripPatterns) +} + +// ClearInput sends End + 200 backspaces to clear Cursor's text field. +// Cursor's input is a standard text field, not vim. +func (c *cursorAgent) ClearInput(paneID string) error { + if !c.clearFirst || c.clearKeys == "" { + return nil + } + if err := sendClearSequence(paneID, c.clearKeys); err != nil { + return err + } + sleepAfterClear() + return nil +} |
