Skip to content

fix(daemon): use real terminal size for PTY instead of hardcoded 24x80#624

Merged
Wirasm merged 2 commits intomainfrom
fix/daemon-pty-size
Mar 4, 2026
Merged

fix(daemon): use real terminal size for PTY instead of hardcoded 24x80#624
Wirasm merged 2 commits intomainfrom
fix/daemon-pty-size

Conversation

@Wirasm
Copy link
Owner

@Wirasm Wirasm commented Mar 4, 2026

Summary

  • Daemon PTYs were created with hardcoded 24x80 dimensions, causing agents to render incorrectly until the Ghostty attach window connected and sent a resize
  • Add a 4-tier resolution chain for initial PTY dimensions: --rows/--cols CLI flags > [daemon] default_rows/default_cols config > ioctl(TIOCGWINSZ) on stdout > 80×24 fallback
  • Fixes the real-terminal case (ioctl detects actual size) and enables non-TTY callers like Claude Code to specify dimensions via flags or config

Test plan

  • kild create test --daemon --rows 50 --cols 200 → daemon log shows rows:50, cols:200
  • Config [daemon] default_rows = 50 / default_cols = 200 → used when no CLI flags and no TTY
  • From real Ghostty terminal: kild create test --daemon → uses actual terminal dimensions
  • cargo test --all passes
  • cargo clippy --all -- -D warnings clean

Daemon PTYs were created with hardcoded 24x80 dimensions regardless of
the actual terminal size. This caused agents like Claude Code to render
incorrectly until the attach window connected and sent a resize.

Add a resolution chain for initial PTY dimensions:
1. --rows/--cols CLI flags (explicit override)
2. [daemon] default_rows/default_cols config (set-and-forget)
3. ioctl(TIOCGWINSZ) on stdout (real terminal detection)
4. 80x24 fallback (no TTY available)

This fixes the common case where `kild create --daemon` runs from a real
terminal, and enables non-TTY callers (Claude Code, scripts) to specify
dimensions via flags or config.
@Wirasm
Copy link
Owner Author

Wirasm commented Mar 4, 2026

PR Review Summary

Critical Issues (1 found)

Agent Issue Location
code-reviewer, silent-failure-hunter, code-simplifier Partial CLI/config override silently discardedresolve_pty_size() requires both --rows AND --cols to be set for either to take effect. kild create foo --cols 220 silently ignores the flag and falls through to ioctl/80×24. Same for config: setting only default_cols has no effect. daemon_spawn.rs:270-282

Fix: Resolve each dimension independently:

fn resolve_pty_size(params: &AgentSpawnParams<'_>) -> (u16, u16) {
    let cfg = &params.kild_config.daemon;
    let (terminal_cols, terminal_rows) = query_terminal_size();
    let cols = params.cols.or(cfg.default_cols).unwrap_or(terminal_cols);
    let rows = params.rows.or(cfg.default_rows).unwrap_or(terminal_rows);
    (cols, rows)
}

Important Issues (1 found)

Agent Issue Location
code-reviewer, code-simplifier #[allow(clippy::too_many_arguments)]open_session now has 9 positional args. Project enforces -D warnings. An OpenSessionRequest struct (matching existing CreateSessionRequest pattern) would fix this properly. open.rs:48

Suggestions (3 found)

Agent Suggestion Location
silent-failure-hunter Add debug! log in query_terminal_size() fallback path and in resolve_pty_size() showing which source won daemon_spawn.rs:288-302
code-simplifier Merge with_rows()/with_cols() into with_pty_size(rows, cols) request.rs:118-126
docs-impact-agent Missing --rows/--cols in CLAUDE.md CLI quick-reference and README config block CLAUDE.md, README.md

Strengths

  • Clean 4-tier resolution chain design
  • Correct and well-documented unsafe ioctl block
  • Proper config merge for new fields
  • nix::libc is already a transitive dep — no new crate added

Verdict: NEEDS FIXES

  1. Fix resolve_pty_size to resolve each dimension independently (critical — user-visible bug)
  2. Consider OpenSessionRequest struct to eliminate #[allow(clippy::too_many_arguments)]

…sionRequest

- Fix resolve_pty_size to resolve each dimension independently via
  .or() chaining instead of requiring both --rows AND --cols. Previously
  passing only --cols 220 silently discarded the flag. Same fix for config
  default_rows/default_cols.
- Add debug logging to PTY size resolution and ioctl fallback paths.
- Introduce OpenSessionRequest struct matching CreateSessionRequest
  pattern, removing #[allow(clippy::too_many_arguments)] from open_session.
- Merge with_rows/with_cols into with_pty_size on both request types.
@Wirasm Wirasm merged commit 6bcede7 into main Mar 4, 2026
6 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant