원클릭으로
hom-tui-testing
Use when modifying TUI rendering, input routing, layout, command bar, or pane management
Codex 또는 Claude로 설치 이 Prompt를 복사해 Codex, Claude 또는 다른 어시스턴트에 붙여 넣으면 Skill 페이지를 검토하고 설치를 진행할 수 있습니다.
메뉴
Use when modifying TUI rendering, input routing, layout, command bar, or pane management
Codex 또는 Claude로 설치 이 Prompt를 복사해 Codex, Claude 또는 다른 어시스턴트에 붙여 넣으면 Skill 페이지를 검토하고 설치를 진행할 수 있습니다.
SOC 직업 분류 기준
| name | hom-tui-testing |
| description | Use when modifying TUI rendering, input routing, layout, command bar, or pane management |
Invoke this skill when:
crates/hom-tui/src/pane_render.rscrates/hom-tui/src/layout.rscrates/hom-tui/src/command_bar.rscrates/hom-tui/src/input.rscrates/hom-tui/src/render.rsApp state machine in crates/hom-tui/src/app.rsThe TUI has a clear data flow:
User Input → InputRouter → Action → App state mutation → render() → Frame
↓
pane.terminal.screen_snapshot() → pane_render → ratatui Buffer
Breaking any link in this chain means the user sees nothing, gets stuck, or loses input.
Command bar parsing — Pure function, no side effects:
#[test]
fn test_parse_spawn_command() {
let cmd = parse_command("spawn claude opus");
assert!(matches!(cmd, Ok(Command::Spawn { harness: Some(HarnessType::ClaudeCode), .. })));
}
#[test]
fn test_parse_unknown_harness() {
let cmd = parse_command("spawn nonexistent");
assert!(cmd.is_err());
}
Layout computation — Pure geometry:
#[test]
fn test_grid_layout_4_panes() {
let area = Rect::new(0, 0, 100, 50);
let panes = vec![1, 2, 3, 4];
let areas = compute_pane_areas(area, &panes, &LayoutKind::Grid);
assert_eq!(areas.len(), 4);
// 2x2 grid: each pane gets ~50x25
for (_, rect) in &areas {
assert!(rect.width >= 49);
assert!(rect.height >= 24);
}
}
Input encoding — Verify key events produce correct PTY bytes:
#[test]
fn test_ctrl_c_encoding() {
let key = KeyEvent::new(KeyCode::Char('c'), KeyModifiers::CONTROL);
let bytes = encode_key_event(&key);
assert_eq!(bytes, vec![0x03]);
}
Pane hit testing — Click coordinates → pane ID:
#[test]
fn test_pane_at_position() {
let pane_areas = vec![
(1, Rect::new(0, 0, 50, 25)),
(2, Rect::new(50, 0, 50, 25)),
];
assert_eq!(pane_at_position(&pane_areas, 25, 12), Some(1));
assert_eq!(pane_at_position(&pane_areas, 75, 12), Some(2));
}
Full render cycle — Create App, add panes, render to TestBackend, assert buffer contents:
use ratatui::backend::TestBackend;
use ratatui::Terminal;
#[test]
fn test_empty_state_renders_welcome() {
let backend = TestBackend::new(80, 24);
let mut terminal = Terminal::new(backend).unwrap();
let app = App::new(HomConfig::default());
terminal.draw(|f| render(f, &app)).unwrap();
let buf = terminal.backend().buffer().clone();
// Check that "Welcome to HOM" appears in the buffer
let text: String = buf.content().iter().map(|c| c.symbol().chars().next().unwrap_or(' ')).collect();
assert!(text.contains("Welcome to HOM"));
}
For these, use cargo run and test manually. Document what you tested.
| Pitfall | Why it breaks | Prevention |
|---|---|---|
| Off-by-one in pane border rendering | Pane content overflows into border or adjacent pane | Always use block.inner(area) for content area |
| Forgetting to handle empty pane list | Index panic in layout computation | Guard with if pane_ids.is_empty() { return } |
| Cursor position outside visible area | Terminal shows cursor in wrong pane | Clamp cursor to inner.right() / inner.bottom() |
| Command bar eating Escape key | User can't exit command mode | Test mode transitions explicitly |
| InputRouter not updating mode | Clicks do nothing, keys go to wrong pane | Every Action that changes focus must also update self.mode |
cargo test -p hom-tui passescargo run, spawn a pane, type into it, switch panescargo clippy cleanUse this skill when building, reviewing, or refactoring Rust code that requires strong maintainability discipline: SRP, DRY, OCP, explicit dependency injection, TDD/ATDD workflow, architecture review, and clean project structure. Complements the project's Rust CLAUDE.md with process rigor.
Use when adding a new harness adapter or modifying an existing one in hom-adapters
Use when working on terminal emulation, the TerminalBackend trait, libghostty integration, or PTY management
Use when creating, modifying, or debugging YAML workflow definitions or the workflow engine
Use before making meaningful code changes in HOM to load repository architecture, workflow rules, crate boundaries, feature flags, and verification requirements
Use when building, reviewing, or refactoring Rust code in HOM that requires strong maintainability, testing discipline, and explicit dependency boundaries