Skip to content

chore: promote staging to staging-promote/be0b33b2-24451653982 (2026-04-15 13:31 UTC)#2501

Merged
henrypark133 merged 1 commit intomainfrom
staging-promote/62bb007b-24457402179
Apr 18, 2026
Merged

chore: promote staging to staging-promote/be0b33b2-24451653982 (2026-04-15 13:31 UTC)#2501
henrypark133 merged 1 commit intomainfrom
staging-promote/62bb007b-24457402179

Conversation

@ironclaw-ci
Copy link
Copy Markdown
Contributor

@ironclaw-ci ironclaw-ci Bot commented Apr 15, 2026

Auto-promotion from staging CI

Batch range: a53eac5c2dec6b6cd5c08189086093fde64aa9cb..62bb007b57e18281ba09195329a2f30f6db81c83
Promotion branch: staging-promote/62bb007b-24457402179
Base: staging-promote/be0b33b2-24451653982
Triggered by: Staging CI batch at 2026-04-15 13:31 UTC

Commits in this batch (47):

Current commits in this promotion (0)

Current base: main
Current head: staging-promote/62bb007b-24457402179
Current range: origin/main..origin/staging-promote/62bb007b-24457402179

  • (no non-merge commits in range)

Auto-updated by staging promotion metadata workflow

Waiting for gates:

  • Tests: pending
  • E2E: pending
  • Claude Code review: pending (will post comments on this PR)

Auto-created by staging-ci workflow

* feat(tui): add multiline support & minor fixes

This commit introduces:
- Support for multi-line messagess (input and rendering)
- A UX improvement: ctrl+c first clears the screen, then exits

Now, users can create multi-line messages by inserting new lines using
(Shift+Enter) or (Alt+Enter) or (Ctrl+J) - all terminal standards to
handle multi-line input.

The input area grows with content (3..=12 rows) based on logical line count.

Pastes with CR or CRLF line endings are normalized so multi-line pastes
from terminals like macOS Terminal.app render as real newlines

User messages in the conversation panel now render each logical line
on its own row instead of collapsing newlines into whitespace

- Ctrl+C on a non-empty input clears it; Ctrl+C on an empty input quits
- History recall (Up/Down) lands the cursor on the first line of the
  recalled entry, and returning to the saved draft also lands at (0,0),
  so long multi-line drafts are immediately re-navigable
- Down within a recalled multi-line message now moves the cursor instead
  of snapping back to the draft

- Tests added for all of the above (176 passing)

* fix: height calculation and missing history

As Gemini code assistant pointed, there were two errors with the
code.

First, we were for some reason getting ride of the history_index
when inserting a new line, which makes no sense. We are now simply
adding the new line.

Second, we had an off-by-one error on counting the number of displayed
lines to the user, for which we were showing one less than expected.

* chore: undo unnecesary change on comment

* fix: remove unnecesary pub(crate)

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

* fix: address reviewer comments

- Renamed Quit action to ClearOrQuite to better reflect its behaviour.
- Added a cast to u16 on clamping text_rows

* fix: better separate history content on lines

* chore: cargo fmt

* chore: apply minor reviews from copilot

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

* fix: update input overlay on /model as suggested by copilot

* chore: rename test function

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

---------

Co-authored-by: Guillermo Alejandro Gallardo Diez <gagdiez@iR2.local>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
@github-actions github-actions Bot added size: L 200-499 changed lines risk: low Changes to docs, tests, or low-risk modules contributor: core 20+ merged PRs labels Apr 15, 2026
@claude
Copy link
Copy Markdown

claude Bot commented Apr 15, 2026

Code review

Found 6 issues:

  1. [MEDIUM:90] String allocations in hot rendering path
conversation.rs lines 393-396 call .to_string() on fixed strings for every message line in the render loop:
Span::raw("  ".to_string())  // allocates new String every render frame

Ratatui's Span::raw() accepts Into<String>, so passing a literal &str avoids the unnecessary allocation:

Span::raw("  ")  // &str, already Into<String>

https://github.com/anthropics/ironclaw/blob/c24aff59105506cacdd96a2f2c9b02703a9f3919/crates/ironclaw_tui/src/widgets/conversation.rs#L393-L396

  1. [MEDIUM:80] Unbounded input buffer on paste could block event loop
input_box.rs lines 96-99: insert_text() performs two sequential string replacements on user input without bounds:
let text = text.replace("\r\n", "\n").replace('\r', "\n");

A pathologically large paste (>1GB with CR line breaks) allocates and blocks the async event loop. Add a size guard like if text.len() > MAX_PASTE_SIZE { error }; to prevent DOS.

https://github.com/anthropics/ironclaw/blob/c24aff59105506cacdd96a2f2c9b02703a9f3919/crates/ironclaw_tui/src/widgets/input_box.rs#L96-L99

  1. [MEDIUM:75] Input height calculation comment is misleading
app.rs line 1825: comment says "up to displaying 10 rows" but doesn't account for the +1 border or attachment rows

Total visible input height ranges 3-12 rows depending on attachments. The comment should clarify:

https://github.com/anthropics/ironclaw/blob/c24aff59105506cacdd96a2f2c9b02703a9f3919/crates/ironclaw_tui/src/app.rs#L1825-L1835

  1. [LOW:85] CLAUDE.md keybindings table is outdated
crates/ironclaw_tui/CLAUDE.md line 30: Key Bindings table documents Ctrl-C as "Quit"

The implementation now does ClearOrQuit (clears non-empty input on first press, quits on second/empty), which is a UX improvement but documentation should reflect this.

  1. [LOW:80] Missing explanation for behavioral change in history navigation
app.rs line 1476: removed state.history_index.is_some() condition from Down key handler

The test down_within_recalled_multiline_message_moves_cursor_not_history validates this is intentional, but a one-line comment explaining "Down only navigates history when cursor is on the last line; otherwise moves cursor within the message" would prevent accidental reversion and document the state machine rule.

https://github.com/anthropics/ironclaw/blob/c24aff59105506cacdd96a2f2c9b02703a9f3919/crates/ironclaw_tui/src/app.rs#L1475-L1476

  1. [LOW:78] Redundant state synchronization
app.rs lines 2256 and 2244: Both take_input_and_reset() and update_input_overlays_from_input() update state.input_line_count

This is harmless but slightly inefficient. Consider consolidating if both are always called together.

https://github.com/anthropics/ironclaw/blob/c24aff59105506cacdd96a2f2c9b02703a9f3919/crates/ironclaw_tui/src/app.rs#L2240-L2260

Base automatically changed from staging-promote/be0b33b2-24451653982 to main April 18, 2026 00:59
@henrypark133 henrypark133 merged commit 62bb007 into main Apr 18, 2026
57 of 72 checks passed
@henrypark133 henrypark133 deleted the staging-promote/62bb007b-24457402179 branch April 18, 2026 01:00
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

contributor: core 20+ merged PRs risk: low Changes to docs, tests, or low-risk modules size: L 200-499 changed lines staging-promotion

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants