Skip to content

UI refactor: standard window, bottom command bar, theme flavors#46

Merged
ojowwalker77 merged 17 commits into
release-1.3.0from
refactor-ui
Jul 1, 2026
Merged

UI refactor: standard window, bottom command bar, theme flavors#46
ojowwalker77 merged 17 commits into
release-1.3.0from
refactor-ui

Conversation

@ojowwalker77

Copy link
Copy Markdown
Owner

Summary

The full UI refactor: BonsAI becomes a single standard macOS window with floating chrome, gets a token-driven design system, and ships four named themes with a preview gallery.

Window architecture

  • The floating-panel mode is removed. BonsAI is one titled, resizable window; the canvas fills it edge to edge, and all chrome floats over it as Liquid Glass pills.
  • Traffic lights are re-laid onto the control row's centerline (Books-style strip); frame autosave; hotkey shows/hides the window.
  • Agent and Settings are in-canvas glass overlays — no auxiliary windows. PanelController shrinks to ~130 lines.

Layout (tldraw-style)

  • Top-left: the board pill — at rest just the board name; on hover the same surface grows into the board manager (switch, inline rename, two-click delete, New board).
  • Top-right: the agent toggle.
  • Bottom-center: one command bar — zoom · the eight tools · grounding folder · Settings.
  • Removed as superseded by the Canvas API: Describe Board, Copy Board (incl. copy-time connector/shell resolution and ⇧⌘C), and the History overlay (rename/delete moved into the board pill).

Design system

  • WindowChrome tokens (control size, paddings, radius, fonts, insets) + a chromePill() wrapper — no inline metrics in chrome views.
  • Themes are data (ThemeFlavor): Bonsai Dark, Bonsai Light, Catppuccin Mocha, Catppuccin Latte. Every palette token maps a semantic role onto the active flavor; Color.accentColor fully swept for Theme.Palette.accent.
  • Settings ▸ Appearance shows flavor-painted preview cards; switching rebuilds the canvas (the agent is a singleton, so the conversation survives).
  • Canvas background transparency slider (solid by default, desktop glass at the top).
  • Brand chip colors normalize per-flavor (dynamic NSColor) so connectors stay legible on every theme.

Panels

  • Agent chat modernized: slim header, model + grounding chips in the input container, circular send, empty-state suggestion chips.
  • Settings modernized: capsule chip tabs, theme gallery, dead controls removed.
  • Trackpad haptics throughout the chrome.

Test plan

  • swift test — 40/40 green.
  • Manual: both Bonsai themes + both Catppuccin themes (canvas, pills, chips, shape ink), board pill hover manager (rename/delete/new), bottom bar tools/zoom, agent chat send/stop/suggestions, Settings tabs, canvas transparency slider, window resize (traffic lights stay on the control row), hotkey show/hide.

The 1.2.0 fix intercepted Return via .onKeyPress but returned `.ignored` for
Shift+Return, expecting the field editor to insert the break. Instead the event
fell through to the field editor's default Return handling, which selected all
the text. Handle both keys explicitly: plain Return submits; Shift+Return inserts
the line break directly into the focused field editor (the key window's first
responder while editing) at the caret, routing through the normal text-change
path so the draft updates and the input auto-grows.

Fixes the regression from #27.
…and Cursor

The bonsai-board skill previously only existed as a local Claude Code skill
file living outside the repo. Bundle the canvas API doc for three agents and
offer to install it on first launch (only for agents detected on the Mac),
with a reinstall/install-more control in Settings > Connectors > Agent Skills.

Claude Code and Cursor get a dedicated file; Codex's AGENTS.md is shared with
the user's own notes, so it's merged into a marked section instead of
overwritten.
An image card renders its own rounded border. The accent selection ring was
drawn `selectionGap` px outside at a larger corner radius, so selecting an image
showed two concentric rounded borders with a visible gap. For image cards the
ring now hugs the image's own edge (tight gap, matching radius, slightly heavier
stroke) as a single clean accent outline. Text, shapes, and lines are unchanged.
Resolve conflict in AppDelegate.swift: keep both the agent-skills first-launch prompt (this PR) and the SIGTERM handler (release-1.2.2) — independent additions.
feat(agent-skills): install canvas-API skill for Claude Code, Codex, and Cursor
Brings in the 1.2.1 changelog + Shift+Enter select-all follow-up fix from main, and rolls the release-1.2.2 Unreleased notes into a [1.2.2] section (agent skills, model pickers, autosave-flush-on-quit, image selection ring).
…ring hugs the image

Dropped images were created at a fixed 220x140 landscape frame while the image drew with scaledToFill and no frame clamp, so non-landscape images overflowed the card — the selection ring hugged the frame while the image spilled past it. Size the card to the image's pixel aspect ratio on drop, clamp the image to the frame so it fills-and-crops instead of overflowing, and align the image ring corner radius (10->8) to the image's own border.
…bundle; don't clobber an unreadable AGENTS.md

.process("Resources") flattens the bundle tree, so the subdirectory: "AgentSkills" lookup always returned nil and every install failed. Try the no-subdirectory form first (as EngineLogo does), with the subdirectory as fallback. Also: mergeMarkedSection mapped any read failure to "" via try?, so an existing-but-unreadable AGENTS.md would be overwritten with only BonsAI's section — now only a genuinely-absent file is treated as empty; a real read error propagates.
…the image

On Copy/Compile an image card now serializes to its absolute file path instead of contributing nothing (or only OCR text) — so the reference is pasteable and a board that's just an image no longer copies as empty. Describe passes the image path through the board-state JSON and grants `claude -p` the read-only Read tool (--allowedTools Read) so the model opens and views the actual image.
…against reversed markers

The Settings > Runtime > Models 'Describe board' picker sets a claude --model alias, so it silently no-op'd when preferredEngine() resolved to Codex (Claude disabled/unavailable). It now disables with an explanatory note whenever Claude isn't the engine that will run Describe. Also harden AgentSkillsInstaller.mergeMarkedSection: if a file's end marker precedes its begin marker, append a fresh section instead of trapping on a reversed replaceSubrange range.
The floating-panel mode is removed entirely; BonsAI is now a single
titled, resizable macOS window with all chrome floating over a solid
edge-to-edge canvas.

- Window: FloatingPanel is always a standard window; traffic lights are
  re-laid onto the control row's centerline; PanelController loses all
  dock/summon logic (Agent/Settings are in-canvas glass overlays).
- Layout (tldraw-style): board pill top-left that grows on hover into
  the board manager (switch, inline rename, two-click delete, New
  board); agent toggle top-right; ONE bottom command bar with zoom,
  tools, grounding folder, and Settings. Rail, top toolbar, and the
  History overlay are gone.
- Design system: WindowChrome tokens (sizes, paddings, radius, fonts)
  plus a chromePill() wrapper so no chrome view carries inline metrics;
  trackpad haptics via Haptics.swift.
- Theming: System/Light/Dark applied as NSAppearance; solid canvas
  (black dark / paper white light); all light-mode ink derives from
  #575757 — no black instances; board elements are outline-only in
  light mode.
- Removed features superseded by the Canvas API: Describe Board and
  Copy Board (with copy-time connector/shell resolution,
  SelfContainedRenderer, the describe model pref, and the ⇧⌘C
  shortcut).
- Panels modernized: Agent chat with slim header, input-area
  model/grounding chips, circular send, suggestion chips; Settings with
  capsule chip tabs and a Theme picker.
Themes become data: `ThemeFlavor` (14 semantic slots + appearance class
+ accent) with four named flavors — Bonsai Dark, Bonsai Light,
Catppuccin Mocha, and Catppuccin Latte. Every `Theme.Palette` token maps
a role onto the active flavor; `Color.accentColor` is fully swept for
`Theme.Palette.accent`.

- Settings ▸ Appearance: a 2×2 gallery of preview cards, each painted
  from its own flavor's palette (mini canvas, pill, accent, ink lines).
- Theme switch sets the window appearance and rebuilds the canvas;
  `CanvasAgent` is now a singleton so the chat survives the rebuild.
- Canvas transparency slider returns (canvas background over
  behind-window blur; solid at the default 0).
- Light-mode fixes: NodeLabel ink, brand chip colors normalized
  per-flavor (dynamic NSColor), grayscale marks use the flavor ink.
@github-actions github-actions Bot added size:XXL vouch:trusted PR author is trusted by repo permissions or the VOUCHED list. labels Jul 1, 2026
@ojowwalker77 ojowwalker77 merged commit 11ec497 into release-1.3.0 Jul 1, 2026
6 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:XXL vouch:trusted PR author is trusted by repo permissions or the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant