This contract preserves the approved MVP concept and prevents feature ownership from drifting.
- HOME uses fixed-size
82 × 72logical cells with18pxgaps so enlarging the page never makes existing widgets smaller. Fresh profiles start at16 × 12, while the original arrangement remains in the upper-left12 × 8area and leaves explicit spare space for plugins. Its persisted boundary and cell grid are shown only in Edit HOME, where the bottom-right corner resizes the area up to the generous48 × 36safety ceiling. - The wide left tile contains exactly Codex, Claude, and Kimi limit rows. Each row prefers the provider's longest real default quota window (the weekly window when exposed), and falls back to another real window only when needed. It shows the countdown to that window's
resetsAtand the matching usage rail. Values below one day useHH:MM; longer values useNд HHч/Nd HHh. Window length stays in accessible metadata; unavailable data is labeled and has no fake reset or percentage. - The right tile is the only session list. Its viewport shows three rows and scrolls when more real sessions exist; it never discards rows. Each row shows provider mark, localized semantic state, and identity. Session duration and limit-style progress rails never appear here.
- The clock is the dominant middle tile and renders only
HH:MM. The adjacent media tile is an autonomous widget: click to pick or replace an image/GIF; remove from the widget itself. - The bottom dock contains Terminal, Codex, Claude, Kimi, and Browser. Settings is a separate tile. Browser opens or focuses the one built-in browser card and never launches an external browser. Agent badges never overlay the Browser launcher icon.
- Every default tile except Settings may be hidden. Settings remains the recovery entry point. Edit HOME mode shows the full cell grid and exact HOME boundary, hides all terminal and canvas-plugin windows, and keeps its changes as a draft until Save. Tiles move without overlap and may temporarily cross any HOME edge; Save is disabled until every tile is fully inside. Every tile edge and corner resizes it while preserving the opposite edge, with visible cues only at the top-left and bottom-right corners. The boundary can grow or shrink without crossing placed widgets. Adding a widget automatically grows HOME when the current boundary is full.
- Runtime HOME widgets use the same tile bounds and zoom behavior. Their UI runs inside a sandboxed iframe and cannot reach the trusted renderer DOM or
window.canvasTTY.
- Clicking a provider opens a Focus Card for that provider. The provider is fixed; there is no second provider selector.
- The Focus Card contains only the provider mark, project folder, Normal/YOLO profile, launch action, and contextual danger confirmation.
- Settings uses a top section strip: General, Appearance, Controls, Browser, and Plugins. General owns language. Appearance owns palette, background pattern, the shortcut-hint toggle, system HOME tiles, and the HOME editor entry. Controls owns click focus, hover focus, window snapping, edge panning, zoom sensitivity, wheel direction, and keyboard shortcuts. Browser owns agent access, agent-indicator visibility, tab restore, downloads, redacted activity, and browser-data clearing. Plugins owns install preview, permission review, the installed-plugin list, enable/disable/uninstall, and contribution actions. Media controls never appear there.
- Click focus has three explicit modes: Off, Single click, and Double click. It is off by default. Selection and its visible outline still work when camera focus is off; a double-click mode never jumps the camera on the first click.
- Selection is exclusive across terminals and the built-in Browser: pressing on empty canvas clears it. The selected live surface holds keyboard focus and loses it on deselect.
- Hover focus is a separate off-by-default selection mode: after a configurable delay (slow
500ms, normal250ms, fast80ms) the terminal or built-in Browser under the pointer becomes selected and receives keyboard focus; leaving the card clears the selection after the same delay. - Keyboard shortcuts are user-remappable and persisted locally. Defaults are
Homefor focusing the Home zone andF2for renaming the selected terminal window. Rename is an inline header edit and does not recreate the PTY. A compact passive hint in the canvas bottom-right reflects the persisted bindings immediately and can be hidden from Appearance. - Snapping is enabled by default and can be disabled without changing existing window bounds. Edge panning remains off by default and exposes slow/normal/fast speed. Wheel direction is configurable separately for terminal scrolling and camera zoom. By default, wheel-down scrolls a live terminal down, while camera zoom preserves the original CanvasTTY direction.
- Flat, large, pastel tiles; strong dark/light contrast; restrained shadows; no ornamental micro-controls or explanatory microcopy around self-evident controls.
- Home renders at
1:1whenever its current persisted boundary fits. Auto-fit uses discrete scale steps down to0.2×and integer camera coordinates so borders and dock spacing stay optically even across larger plugin layouts. - System actions use locally vendored SVGs from the official Lucide repository. Do not hand-draw system icons in TSX and do not add an icon runtime package.
- Provider marks use unmodified vendor assets. Do not redraw, recolor, filter, or approximate them. Kimi's raster mark must not render above its native
48pxsize. - Dots and grid are CSS patterns. Waves use the seamless SVG tile in
assets/patterns/waves.svg; do not emulate waves with radial gradients. - Terminal cards keep a
54pxheader. At normal scale the header shows the provider mark and terminal working directory until the user explicitly renames the window; a custom title then replaces the path. Close remains visible at the far right; canvas cards do not expose maximize/fullscreen. There is no lifecycle dot in terminal chrome. - After a provider PTY exits, its terminal card exposes restart in the same session with a header action and
Ctrl+D. Restart preserves the card, title, bounds, scrollback, and xterm instance while issuing a fresh provider process and browser capability. - Terminal cards switch to semantic summary mode below
0.5×. Summary typography counter-scales as the camera moves farther out so identical cards keep the same readable hierarchy instead of exposing tiny xterm text. - In semantic summary mode a card is a canvas navigation target: wheel input zooms the camera around it, and clicking the summary always selects it with a visible card outline. Camera focus follows only the configured Off/Single click/Double click mode. At normal scale the live terminal regains wheel ownership.
- Every terminal edge and corner is a resize target. The minimum card size is
420 × 260; resizing updates the xterm viewport and preserves the opposite edge. - Live terminal selection follows the visible pointer position at every canvas zoom. With a non-empty selection,
Ctrl+C/Ctrl+Shift+C(orCmd+C) copies it;Ctrl+Shift+V/Cmd+VandShift+Insertpaste from the system clipboard. PlainCtrl+Cwithout a selection remains the PTY interrupt.Shift+Entersends a line-break sequence (ESC [ 13 ; 2 u) to the PTY instead of submitting the line. - Canvas plugin apps use the same movable card grammar,
54pxheader, resize/snap behavior, and semantic summary below0.5×. Awindowcontribution opens a separate CanvasTTY-owned sandboxed window; arbitrary native window embedding is not part of the contract. - The built-in Browser is one movable, resizable core canvas card, not a plugin contribution. It uses the same
54pxouter window header as other canvas cards, with its identity and hide-card action isolated from the internal tab strip below. Its trusted DOM chrome owns compact tabs/favicons, address/search, back/forward/reload, downloads, per-tab provider badges, site dialogs, and explicit Close tab/Close all. Hiding the card keeps its tabs and shared authenticated Chromium profile alive. Below0.5×, during Edit HOME, and behind trusted dialogs/popovers, the native page is hidden and replaced with a stable semantic surface. During card or camera motion it remains live and follows frame-coalesced viewport geometry. - An authenticated connection or heartbeat alone never shows agent presence. A branded badge appears only after that agent actually issues a browser command, and its cursor appears only after a real pointer position exists. Claude uses
#D97757, Codex#10A37F, Kimi#7C5CFC, and an unknown provider#7A8291. Browser Settings separately controls indicator visibility without revoking browser access; the agent-access kill switch revokes the connection itself. - With window snapping enabled, drag and resize use a hidden
10pxgrid and a10pxmagnetic threshold for neighboring edges, centers, and a consistent20pxgap. - Wheel input belongs to the surface under the pointer when that surface actually scrolls or consumes wheel input. Fresh profiles route wheel input over terminal and native Browser surfaces to the camera so a large card cannot trap canvas navigation; Controls → Zoom over applications can restore local application wheel ownership. The session list keeps local ownership. Passive Home widgets — limits, clock, media, and launcher tiles — allow camera zoom so Home does not shrink the usable zoom area.
- The canvas edge-pans RTS-style while the pointer rests within
56pxof a viewport edge over empty canvas; speed ramps linearly up to900px/sat the edge itself. Edge panning is off by default and enabled in Settings. Motion pauses over interactive surfaces (terminal cards, Home, controls) and while drag-panning. - Dialog close actions stay inside their own header/control row with a consistent inset; they never overlap a field, outline, or panel boundary.
- No custom
<svg>or<path>elements in React TSX. - No media picker or media-fit selector in Settings.
- No provider picker inside
AgentLaunchDialog. - No maximize/fullscreen action inside a canvas card.
- No fake counts, percentages, reset timers, determinate progress, or placeholder sessions.
- Plugin install always shows the validated manifest and requested permissions before confirmation; repository scripts are never executed.
- A newly opened PTY starts as
idle. Only a structured provider lifecycle signal may mark itworkingorneeds_approval; PTY existence and terminal text are not activity signals. needs_approvalis displayed only after a structured provider-adapter signal; terminal output is never parsed to invent it.- Home, Focus Card, Settings, at least one live terminal, and the built-in Browser are inspected in an isolated real Electron window after build.