@@ -815,14 +815,14 @@ export function ConnectApp(props: ConnectAppProps): React.ReactElement {
815815 if ( working && canSend ) submit ( '/stop' )
816816 } ,
817817 )
818- // The notice bar doubles as the ctrl+c prompt: armed, it says what a second
819- // press does, so the quit is never a surprise .
818+ // Armed, the meta line below the composer becomes the ctrl+c prompt (it
819+ // says what a second press does), and the arm expires after a few seconds .
820820 // The browser is for reading, not sending: it drops the composer for the rows
821821 // (a whole screen of conversation is the point of opening it) and says so on
822822 // the notice line, which is where the app's one line of transient guidance
823823 // already lives.
824824 const browserNotice = '↑↓ scroll · → open · ← close · ctrl+r expand all · esc back to the chat'
825- const shownNotice = windowed ? browserNotice : ctrlCArmed ? CTRL_C_QUIT_HINT : notice
825+ const shownNotice = windowed ? browserNotice : notice
826826 const { viewBudget, padRows, composerRows, noticeRows, menuRows } = useMemo ( ( ) => {
827827 // Both wrapping parts of the footer are measured as the rows they will
828828 // actually OCCUPY, not as the newlines they contain: a notice ("stream
@@ -1479,9 +1479,10 @@ export function ConnectApp(props: ConnectAppProps): React.ReactElement {
14791479 const totalStr = `$${ ( serverCostUsd ?? cost . total ?? 0 ) . toFixed ( 2 ) } `
14801480 // Sized to fit by construction: Ink measures the OSC-8 hyperlink's
14811481 // invisible URL bytes as width, so a linked id only ships when the whole
1482- // line — escape bytes included — fits the pane; otherwise the id renders
1483- // as plain text, shortened if even that overflows. Never rely on Ink
1484- // wrapping/truncating this line: it's budgeted at exactly one row.
1482+ // line — escape bytes included — fits the pane; otherwise the line renders
1483+ // as plain text, cut to the pane with a … if even that overflows. Never
1484+ // rely on Ink wrapping/truncating this line: it's budgeted at exactly one
1485+ // row.
14851486 const metaParts = ( id : string ) : string [ ] => [
14861487 `${ statusWord } · ${ totalStr } total` ,
14871488 ...( props . model ? [ props . model ] : [ ] ) ,
@@ -1491,12 +1492,13 @@ export function ConnectApp(props: ConnectAppProps): React.ReactElement {
14911492 ]
14921493 const linked = metaParts ( hyperlink ( props . sessionUrl , sessionId ) ) . join ( ' · ' )
14931494 const plain = metaParts ( sessionId ) . join ( ' · ' )
1494- const metaLine =
1495- linked . length < cols
1495+ const metaLine = ctrlCArmed
1496+ ? CTRL_C_QUIT_HINT
1497+ : linked . length < cols
14961498 ? linked
14971499 : plain . length < cols
14981500 ? plain
1499- : metaParts ( `${ sessionId . slice ( 0 , 20 ) } …` ) . join ( ' · ' )
1501+ : `${ plain . slice ( 0 , Math . max ( 0 , cols - 2 ) ) } …`
15001502 return (
15011503 // Hosted panes pin BOTH dimensions: without the width the root sizes to
15021504 // its widest child (the unwrapped meta line) and smears rows across the
0 commit comments