--- name: harness-gui description: Develop or review Harness Anything GUI pages and shared components using its existing design system, entity navigation, motion preferences, and background Electron verification. Use for packages/gui work and GUI-specific agent missions. --- # Harness GUI development Start with the existing product, not a new visual system. Read the target page and adjacent consumers, then GUI package guidance at `packages/gui/README.md` (relative to the product repository root) and the actual shared component source under `packages/gui/src/renderer/components/primitives`. The runnable `packages/gui/component-catalog.html` imports production primitives and demonstrates their contract; inspect its source for real imports and supported states. Consult the project’s authored GUI design standard when the workspace supplies one. User-approved interaction changes take precedence over older examples. ## Choose the shared boundary Before writing JSX, identify the existing component that owns the behavior. A page composes domain data and actions; shared primitives own sizing, overflow, focus and motion. Fix a repeated problem at that boundary and migrate real consumers in the same change. Do not retain a second implementation or turn a domain-specific card into a generic framework merely to reduce a file’s size. - Addressable entities use `EntityRefLink` and the actual navigation callback. Keep the complete canonical reference available when the visible label is shortened. Do not infer entity kinds for arbitrary IDs. - Non-addressable IDs use the shared ID display; records combine ID/state/prose/time/actions through the shared record layout. Check every supplied field, including non-null receipts and mixed-language long prose. Removing overlap is necessary but insufficient: give reading text enough width instead of squeezing it between metadata columns. - Reuse status vocabulary, time formatting and interaction controls from the existing sources. Do not create page-local colors, raw timestamp formatting or duplicate button/switch implementations. - Treat empty results as product information: explain absence and the next relevant action where needed. Do not fill dashboards with unrelated totals or decorative ratios. Each number needs a question, scope and actionable meaning. ## Fit density to the task Optimize this functional GUI for readable work and efficient navigation. Shared components unify behavior, not dimensions: choose supported density, fill and layout options for the content and available space. Give documents reading width, directories scanning density, and controls only the space they need; do not copy one fixed ratio to every consumer. Respect user-adjusted region proportions. Distinguish parent task headers from child session rounds through hierarchy and continuous grouping. Make the round identifier primary and repeated agent metadata secondary. Remove repeated information and nested padding before squeezing text; neither crowded single-line records nor oversized cards and decorative gaps are acceptable. Do not shrink typography to claim higher density. Keep explicit monitoring surfaces visible when empty: WIP still shows zero and its current limit. Loading, stale data and failure are different states. Compare before/after at the same window size, font settings and content: useful information visible, readable text width and the actions needed to reach the intended item. Component reuse alone proves neither usability nor a performance improvement. ## Bound long content Every potentially long content surface—documents, logs, review prose, timelines and file previews—uses the shared bounded layout contract. Use `BoundedContent` and the shared `--long-content-cap` token, currently 55cqb of the sized `content-viewport`. Maximum height derives from the available container, not page-specific px/rem limits. Small content keeps its natural height; do not turn a maximum into a mandatory empty panel. Establish a finite parent height with shrinkable flex/grid children; keep titles, toolbars and primary actions outside the content scroll area. Overflow scrolls vertically inside that surface; wide tables/code scroll horizontally inside their own column without crossing adjacent text. Verify resizing, single/two-column layouts and nested wheel behavior. Use `DocReader` for Markdown documents, `MarkdownDocument` for shared Markdown parsing, and `BinaryDocumentPreview` for already-authorized image/PDF/Word bytes; `DocumentFrame` owns the bounded viewport and fixed toolbar. Exercise these in `components/catalog/ComponentCatalog.tsx`. Reuse the shared document viewer rather than mounting independent Markdown renderers; declare unsupported formats truthfully and preserve actual binary bytes through the authorized daemon read path. ## Arrange regions inside real pages The independent workbench has been removed. Implement layout in the actual route body; do not restore a floating canvas, panel catalog or second query state. Overview, work overview and task detail share `PageRegions` and existing split preferences. Use `Region` headers (or `RegionDragHandle` in document headers) for dedicated drag handles. Keep text selection, file clicks and graph input outside drag activation. Preserve semantic focus expansion and navigation. Persist region order, orientation and ratios locally by connection + repository + page slot. Reuse `SplitDivider` / `ColumnResizeHandle` for pointer and keyboard resizing; reset the whole page slot including nested splits. Verify pointer movement, keyboard movement, cancellation, reload and reset on the real route, including root task details nested in a work page. Structural seams use 2–4px spacing and a thin visible divider with a separate 12px hit target. Avoid stacked page padding and extra card shadows around an already bounded region. Keep document typography and readable row spacing. Each long body owns its scroll area; headers and controls remain reachable. Verify actual 1440 and 1120 window sizes and measure usable document geometry. ## Preserve interaction intent Use a preview drawer when the user needs the surrounding list or canvas, and full detail when the task is processing that entity. Relationship graphs retain inline node reading and progressive exploration; explicit refocus changes the center. Opening full details and returning must preserve exploration state and viewport. Do not replace graph exploration with a universal drawer rule. Use the existing motion configuration and reduced-motion preference. New shared interactions may extend the existing primitives; there is no frozen allowlist of animation files. Animate a defined interaction, keep text undistorted, and keep keyboard focus visible. A modal owns focus while open and returns it on close; a non-modal preview keeps its background reachable. Name icon-only controls and expose selected/disabled state semantically. Desktop functional controls use shared compact density: small buttons start at 24px, ordinary buttons and segmented controls at 28px, growing with their text. Do not force every desktop control to 40px. Coarse-pointer targets use real boxes of at least 40px in both axes; do not expand transparent hit areas over adjacent controls. Verify actual geometry under the product font settings. Keep adjacent body/remove targets separate. Static chips may retain compact sizing. ## Verify the actual surface Use focused behavior tests for the changed contract, then the repository’s applicable GUI checks. Prove the defect with the supported input that caused it; DOM class names alone do not prove layout. In Electron, measure the actual container and window size—minimum window constraints can invalidate a requested width. Include light/dark, narrow containers and keyboard paths when touched; exercise dynamic preference changes rather than module-load snapshots. Electron verification is hidden by default, uses an independent profile and Playwright/CDP input, and never calls show/focus/bringToFront or controls the user’s keyboard. Waiting for a process does not mean foregrounding its window. Place the ephemeral Chromium profile/cache in a temporary directory outside task artifacts; publish only intended screenshots and evidence, never browser storage. Use the repository’s GUI capture/test tools, verify the selected project and final entity heading, wait for the intended content, and inspect the image. A loading screen or another entity is not acceptance. Wait for the relevant transition to settle before measuring or capturing; a wide-window drawer does not prove narrow-window detail behavior. Validate both the page and its opened detail at the actual narrow viewport. Copy tests must use an isolated clipboard or an explicit test boundary that captures the requested text; never save and restore the user’s system clipboard, which can overwrite content copied while the test runs. Label simulated clipboard checks honestly and never put existing clipboard contents in logs. Show a window only for an explicit user-requested demonstration. Report the changed shared contract, real consumers migrated, old implementation removed, commands/results and material unverified behavior. A component catalog, passing structural check or worker self-report alone is not proof that the product page is usable.