This batches the in-flight [Unreleased] block from CHANGELOG.md into a single commit. Highlights: - Real MCP protocol layer (initialize / tools/list / tools/call) so vendor MCP clients can complete the handshake against the per-PID socket. Legacy direct-dispatch preserved for the harness. - New mcp_injection kinds — cli_override for codex, config_env for opencode — joining the existing env-var and config_file paths so patterm can slot into more agents without touching their real config or auth. - Ctrl+A/D and Ctrl+W/S focus navigation across tabs and intra-tab process lists, recognised in legacy / kitty CSI u / xterm modifyOtherKeys encodings. - Palette macros (sw / k / sp ) and reordering so open sessions surface above spawn-new entries. - Two-row tab bar, sidebar/tabbar/status chrome cache, viewport-wipe on agent spawn, CR-terminated orchestrator injections, and split- Enter PTY writes so paste-detecting TUIs see Enter as a key event. Also fixes the bug logged in TODO: claude's Ctrl+O tool-call expansion emits CSI 0 J, which the viewport renderer was forwarding verbatim — wiping the sidebar to the right of the cursor and leaving the chrome cache convinced nothing had changed. CSI 0 J and CSI 1 J are now translated into per-row ECH sequences clamped to the viewport, same as CSI 2 J and CSI K already were. Agent guides (CLAUDE.md / AGENTS.md) now spell out the TODO->CHANGELOG workflow so completed items land in the changelog rather than as ticked entries left behind in TODO.
59 lines
1.6 KiB
Go
59 lines
1.6 KiB
Go
package app
|
|
|
|
import (
|
|
"testing"
|
|
|
|
"github.com/hjbdev/patterm/internal/preset"
|
|
)
|
|
|
|
func TestTerminalLayoutWideUsesMainViewport(t *testing.T) {
|
|
l := newTerminalLayout(120, 40)
|
|
if !l.sidebarVisible {
|
|
t.Fatal("wide layout should show sidebar")
|
|
}
|
|
if l.childCols() != 91 {
|
|
t.Fatalf("child cols: got %d want 91", l.childCols())
|
|
}
|
|
if l.childRows() != 37 {
|
|
t.Fatalf("child rows: got %d want 37", l.childRows())
|
|
}
|
|
if l.mainTop != 3 || l.statusRow != 40 {
|
|
t.Fatalf("unexpected vertical chrome: mainTop=%d statusRow=%d", l.mainTop, l.statusRow)
|
|
}
|
|
}
|
|
|
|
func TestTerminalLayoutNarrowHidesSidebar(t *testing.T) {
|
|
l := newTerminalLayout(38, 12)
|
|
if l.sidebarVisible {
|
|
t.Fatal("narrow layout should hide sidebar")
|
|
}
|
|
if l.childCols() != 38 {
|
|
t.Fatalf("child cols: got %d want 38", l.childCols())
|
|
}
|
|
if l.childRows() != 9 {
|
|
t.Fatalf("child rows: got %d want 9", l.childRows())
|
|
}
|
|
}
|
|
|
|
func TestTerminalLayoutTinyClampsChildSize(t *testing.T) {
|
|
l := newTerminalLayout(0, 1)
|
|
if l.childCols() != 1 || l.childRows() != 1 {
|
|
t.Fatalf("child size: got %dx%d want 1x1", l.childCols(), l.childRows())
|
|
}
|
|
}
|
|
|
|
func TestSpawnSizingUsesViewportDimensions(t *testing.T) {
|
|
l := newTerminalLayout(120, 40)
|
|
launcher := NewLauncher(nil, "", l.childCols(), l.childRows())
|
|
cols, rows := launcher.size()
|
|
if cols != 91 || rows != 37 {
|
|
t.Fatalf("launcher size: got %dx%d want 91x37", cols, rows)
|
|
}
|
|
|
|
host := newToolHost(nil, nil, nil, preset.Set{}, nil, l.childCols(), l.childRows())
|
|
cols, rows = host.size()
|
|
if cols != 91 || rows != 37 {
|
|
t.Fatalf("tool host size: got %dx%d want 91x37", cols, rows)
|
|
}
|
|
}
|