You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Two layout defects that corrupt the rendered frame.
UX-15 — Subagent panel title clipped.ScrollablePanel budgets body rows as screen.rows - footerRows - 4 (packages/mayfly/src/core/scrollable-panel.ts:104), assuming a 2-row status footer and ignoring the dock's 1-transcript-row reservation (terminal.ts:300) and header/bottom lane rows (terminal.ts:667-674). The dock grants the editor slot only rows - actualFooterRows - 1 - laneRows (matching editorViewport, screen.ts:206) and slices overflow from the top (terminal.ts:322). With a 1-row footer the math coincidentally fits, but MayflyStatusDefinition.row?: 1 | 2 is public API (packages/ui/src/contracts.ts:184): any plugin contributing a 2-row status entry makes the panel render one row too many, and its first row — the ╭ Subagent · <label> ─ hint ╮ title bar (scrollable-panel.ts:84-88) — is silently dropped. The panel's own inner renderer is even told a different height truth (session-transcript-panel.ts:68 uses screen.editorViewport.rows).
UX-16 — Ghost hint overflows on CJK/emoji.truncateHint measures hint.length and slices by code units (chrome.ts:108-113), and available subtracts textLength in code units (chrome.ts:145-146), while the row budget is in terminal columns. The caller passes this.editor.getText().length (components.ts:387) although the JSDoc promises "the visible length of the real editor text" (chrome.ts:125). A hint containing wide chars (e.g. <文件路径> from a host command's input.hint, editor-plus.ts:517) renders wider than the spaces it replaces, the row exceeds render(width), and the frame clamp eats the editor's right │ border; the same slice() can split a surrogate pair. Existing tests pin ASCII only (tests/core/chrome.spec.ts:381-429).
Acceptance criteria
Panel body budget derives from the dock's actual editor-slot grant (or editorViewport), correct for 1- and 2-row footers and open lanes; a width/height regression test covers the 2-row footer case.
Ghost-hint truncation measures in display columns via the grapheme-aware width helpers; CJK/emoji hints cannot overflow the row or split a grapheme; tests cover wide-char hints.
In progress (status:in-progress). Covered by the unified layout/width plan:
UX-15 — one editor-slot budget: MayflyTerminalRuntime exposes lane rows, screen.editorViewport subtracts them, and ScrollablePanel derives its body budget from it (no more rows - footerRows - 4 guess). The panel title survives a 2-row footer and open lanes; the transcript renderer uses the same budget.
UX-16 — injectGhostHint/truncateHint measure display columns via the grapheme-aware width helpers instead of UTF-16 code units; CJK/emoji hints cannot overflow render(width) or split a surrogate pair.
Implementation opened as #81 (branch fix/display-layout-fidelity). pnpm run verify:full is green (typecheck, lint, build, shots, coverage, happy smoke). Manual runtime acceptance is pending before merge.
UX-15 (subagent panel title clipped): screen.editorViewport (packages/mayfly/src/core/screen.ts) subtracts the real status-footer rows plus the width-derived header/bottom lane rows (surfaceLaneRows() over measuredLaneRows(), core/terminal.ts), and panel bodies derive their budget from that grant — no frame of lag, and the 2-row-footer + open-lanes case keeps the panel title. Implemented by fix(ui): display-fidelity and layout-budget hardening (#67 #68 #73 #74) #81 (308d609); the budget survives the feat(transcript): render every conversation in the one transcript pane #85 conversation-views rework (panels now budget from editorViewport directly).
UX-16 (CJK ghost hints overflow): injectGhostHint/truncateHint measure display columns via the grapheme-aware helpers (visibleWidth + sliceByColumn, core/chrome.ts), so CJK/emoji hints cannot overflow render(width) or split a surrogate pair.
Deterministic evidence re-run today on main (14e6ce7): chrome.spec.ts 58, terminal.spec.ts 81, screen.spec.ts 6, surface-manager.spec.ts 27 — all pass.
Activity
GeekCmore commentedon Sep 28, 2026
In progress (
status:in-progress). Covered by the unified layout/width plan:MayflyTerminalRuntimeexposes lane rows,screen.editorViewportsubtracts them, andScrollablePanelderives its body budget from it (no morerows - footerRows - 4guess). The panel title survives a 2-row footer and open lanes; the transcript renderer uses the same budget.injectGhostHint/truncateHintmeasure display columns via the grapheme-aware width helpers instead of UTF-16 code units; CJK/emoji hints cannot overflowrender(width)or split a surrogate pair.Branch
fix/display-layout-fidelity. Tests:tests/core/chrome.spec.ts(wide-char hints) +tests/core/scrollable-panel.spec.ts(footer/lane height regression).GeekCmore commentedon Sep 28, 2026
部分处理中 / Partially in progress — PR #79 (
feat/i18n-hardening)。visibleWidth+sliceByColumn(..., true)按显示列截断,调用方传入编辑文本;CJK/emoji 不再溢出或劈开 grapheme,并新增宽度回归测试。PR: #79
GeekCmore commentedon Sep 28, 2026
Implementation opened as #81 (branch
fix/display-layout-fidelity).pnpm run verify:fullis green (typecheck, lint, build, shots, coverage, happy smoke). Manual runtime acceptance is pending before merge.fix(ui): unify display values, overflow signalling, and editor-slot l…
Merge pull request #81 from Ephemeral-AI-Lab/fix/display-layout-fidelity
GeekCmore commentedon Sep 29, 2026
Closing as fixed, verified on current
main.screen.editorViewport(packages/mayfly/src/core/screen.ts) subtracts the real status-footer rows plus the width-derived header/bottom lane rows (surfaceLaneRows()overmeasuredLaneRows(),core/terminal.ts), and panel bodies derive their budget from that grant — no frame of lag, and the 2-row-footer + open-lanes case keeps the panel title. Implemented by fix(ui): display-fidelity and layout-budget hardening (#67 #68 #73 #74) #81 (308d609); the budget survives the feat(transcript): render every conversation in the one transcript pane #85 conversation-views rework (panels now budget fromeditorViewportdirectly).injectGhostHint/truncateHintmeasure display columns via the grapheme-aware helpers (visibleWidth+sliceByColumn,core/chrome.ts), so CJK/emoji hints cannot overflowrender(width)or split a surrogate pair.Deterministic evidence re-run today on
main(14e6ce7):chrome.spec.ts58,terminal.spec.ts81,screen.spec.ts6,surface-manager.spec.ts27 — all pass.