Some checks failed
release / build-linux-amd64 (push) Failing after 10m52s
Bundles the in-flight work into the first tagged release. See CHANGELOG.md `[0.0.1] - 2026-05-14` for the full per-change list. Highlights: - Sidebar / chrome stability: clamp absolute cursor positioning and printable bytes to the viewport so long-running TUIs (claude, codex) can't spray into the right rail; bound tab bar's row clear to the viewport width so the rail isn't wiped on every tab redraw; flag scroll escapes (RI/IND/NEL/SU/SD/IL/DL) and clamp `CSI 0/1/2 J`/`K` to viewport columns. - Palette: "Spawn process…" form, macros (`sw `, `k `, `sp `), kill entries mark the focused tab, dead agents drop out of the switch list. - Sidebar: split into Processes (session-wide) + Agent Tree (per-active-agent) sections; relaunch indicator; Ctrl+W/S walks the combined list, Ctrl+A/D steps tabs. - MCP: protocol handshake (`initialize`, `tools/list`, `tools/call`, `ping`), `mcp_injection.kind = cli_override / config_env` so codex and opencode pick up the server with no file writes, `lifecycle` help topic and tool-description cleanup-duty pointers. - Lifecycle: orchestrator-spawned children cascade-killed when the parent dies; orchestrator-injected prompts end with CR + delayed Enter so claude submits cleanly.
28 lines
2.0 KiB
JSON
28 lines
2.0 KiB
JSON
{
|
|
"name": "sidebar_survives_wide_writes",
|
|
"cols": 120,
|
|
"rows": 40,
|
|
"scripts": [
|
|
{
|
|
"name": "widewrite",
|
|
"body": "#!/bin/sh\n# Reproduces a long-running TUI whose internal column state drifted\n# past the viewport width (the symptom seen in fucked-up-terminal.txt:\n# claude's input box drew a horizontal divider all the way to the host\n# edge, overwriting the sidebar). The widths here are: cols=120,\n# sidebarCols=28, so the viewport is 91 cols wide and the sidebar\n# border lives at col 92. Anything the child writes at col >= 92 lands\n# in the sidebar unless patterm defensively clamps it.\n#\n# After WIDE READY, emit 12 throw-away chunks to exhaust the focus\n# snapshot replay budget (8 chunks) so the wide-write clobber goes\n# through the *incremental* viewport renderer path. That's the path\n# that long-running sessions stay on — without clamping it can spray\n# bytes into the sidebar.\nprintf 'WIDE READY\\n'\ni=0\nwhile [ $i -lt 12 ]; do\n printf 'tick %d\\n' \"$i\"\n i=$((i + 1))\n sleep 0.05\ndone\nprintf 'PRE-CLOBBER\\n'\nsleep 0.2\nprintf '\\033[5;95HCLOBBER-CUP'\nsleep 0.1\nprintf '\\033[7;100HCLOBBER-CUP2'\nsleep 0.1\nprintf '\\033[9;1H'\nprintf '\\033[110GCLOBBER-CHA'\nprintf '\\nDONE\\n'\nsleep 5\n"
|
|
}
|
|
],
|
|
"steps": [
|
|
{
|
|
"type": "mcp_call",
|
|
"method": "spawn_process",
|
|
"params": { "kind": "command", "argv": ["widewrite"], "name": "widewrite" }
|
|
},
|
|
{ "type": "wait_text", "contains": "WIDE READY", "timeout_ms": 5000 },
|
|
{ "type": "wait_text", "contains": "DONE", "timeout_ms": 5000 },
|
|
{ "type": "wait_stable", "timeout_ms": 2000 },
|
|
{ "type": "assert_contains", "contains": "Agent Tree" },
|
|
{ "type": "assert_contains", "contains": "Processes" },
|
|
{ "type": "assert_contains", "contains": "Scratchpads" },
|
|
{ "type": "assert_contains", "contains": "● widewrite" },
|
|
{ "type": "assert_not_contains", "contains": "CLOBBER-CUP" },
|
|
{ "type": "assert_not_contains", "contains": "CLOBBER-CHA" }
|
|
]
|
|
}
|