Repository navigation
cmux-next agent pane: place drawn rows by their drawn height #16491
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
651557a
be647a0
f9818da
c4c0efd
e07f88f
ce1948a
58ecdae
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Large diffs are not rendered by default.
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
|
|
@@ -108,10 +108,18 @@ export function visibleRowRange(rowCount: number, scrollTop: number, viewportHei | |||||
| return { first, last }; | ||||||
| } | ||||||
|
|
||||||
| /// First-layout estimates for rows not yet drawn; a drawn row places by its drawn height. Each | ||||||
| /// includes the row's bottom padding (`.acpmux-row` in styles.css: 16px for messages, 8px else). | ||||||
| function fallbackRowHeight(row: AcpmuxRow, width: number): number { | ||||||
| const textLines = Math.max(1, Math.ceil((row.text?.length ?? 0) / Math.max(24, Math.floor(width / 8)))); | ||||||
| if (row.kind === "activity") return Math.max(46, 24 + (row.items?.length ?? 0) * 20); | ||||||
| if (row.kind === "turnSummary" || row.kind === "notice" || row.kind === "typing") return 32; | ||||||
| if (row.kind === "activity") { | ||||||
| // Collapsed tool calls, or the edited-files list (a title and one line per file). | ||||||
| const edits = row.items?.filter((item) => item.tool?.kind === "edit" || item.tool?.kind === "fileChange").length ?? 0; | ||||||
| return edits ? 8 + 16 * (1 + edits) : 34; | ||||||
| } | ||||||
| // Card padding and border, title, button row. | ||||||
| if (row.kind === "permission") return 87; | ||||||
| if (row.kind === "turnSummary" || row.kind === "notice" || row.kind === "plan" || row.kind === "typing") return 37; | ||||||
| return 24 + chromeHeight(row) + textLines * MESSAGE_LINE_HEIGHT; | ||||||
| } | ||||||
|
|
||||||
|
|
@@ -173,6 +181,8 @@ function measuredRowHeight(row: AcpmuxRow, width: number, cache: Map<string, Pre | |||||
| } else if (entry.text !== row.text) { | ||||||
| entry.text = row.text; | ||||||
| entry.blocks = markdownBlocks(row.text); | ||||||
| // A streaming row prepares a new last block on every version; keep the cache bounded. | ||||||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. P2: Once a streaming row passes 64 versions, every later version clears the entire Prompt for AI agents |
||||||
| if (entry.prepared.size > 64) entry.prepared.clear(); | ||||||
| } | ||||||
| if (entry.blocks.length === 0) return fallbackRowHeight(row, width); | ||||||
| const contentWidth = Math.max(80, row.kind === "user" ? USER_BUBBLE_SHARE * width - USER_BUBBLE_SIDES : width); | ||||||
|
|
@@ -196,6 +206,22 @@ export function layoutConversation(rows: AcpmuxRow[], width: number, cache = new | |||||
| return { tops, heights, totalHeight: top }; | ||||||
| } | ||||||
|
|
||||||
| /// Places rows again over `estimate`, taking a row's height from `heightAt` when it has one. | ||||||
| /// No row is measured, so this costs one pass over the rows' heights. | ||||||
| export function placeRows(estimate: ConversationLayout, heightAt: (index: number) => number | undefined): ConversationLayout { | ||||||
| const tops = new Float64Array(estimate.heights.length); | ||||||
| const heights = new Float64Array(estimate.heights.length); | ||||||
| let top = 0; | ||||||
| for (let index = 0; index < heights.length; index += 1) { | ||||||
| tops[index] = top; | ||||||
| const known = heightAt(index); | ||||||
| const height = known !== undefined && known > 0 ? known : estimate.heights[index]; | ||||||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. P2: Prompt for AI agents
Suggested change
|
||||||
| heights[index] = height; | ||||||
| top += height; | ||||||
| } | ||||||
| return { tops, heights, totalHeight: top }; | ||||||
| } | ||||||
|
|
||||||
| function upperBound(values: Float64Array, target: number): number { | ||||||
| let low = 0; | ||||||
| let high = values.length; | ||||||
|
|
||||||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
P2: The drawn-height cache has no session identity: switching to a same-sized session can recreate IDs such as
user-1at version 1 and retain the prior session's heights. Invalidate drawn heights on session changes or include a session/generation key in the cache validity check.Prompt for AI agents