ClipSpacesClipSpaces Docs
Back to app

All releases

Clip AI chat rebuilt, a "/" command palette, and Figma-style comments

Changed

  • Comments polish + migration applied. Applied the 20260724000100_comments migration (plus the two pending ai_soul / ai_usage_tokens migrations) to the hosted Supabase, so comments now work live. Comment mode now shows a speech-bubble cursor (echoing the toolbar's comment glyph, tail as the drop point) instead of a generic crosshair. The inline thread's compose/reply box is rebuilt on the shadcn Textarea + Button primitives (auto-growing field, cleaner single surface) and no longer draws a stray divider above a fresh draft. The two comment buttons on the canvas toolbar are now split into their own divided category, separate from the drawing tools.

Added

  • All-comments panel — the comments Sheet (Phase 3, slice 3). A second toolbar button opens a right-side shadcn Sheet listing every thread in the space, split into Open and Resolved, each row showing the author's initial avatar, name, relative time, a two-line snippet, and reply count. Clicking a row pans the canvas to that pin and opens its inline thread (via a shared focus state). The button carries an unresolved-count badge. New components/comments/CommentsSheet.tsx; Toolbar gains onOpenComments + commentUnresolved, and the page renders the Sheet from the cloud space. Completes the Phase-3 comments feature (data layer → pins/threads → panel).
  • Figma-style comment pins + inline threads (Phase 3, slice 2). A comment tool in the canvas toolbar (cloud spaces only) toggles comment mode; clicking the canvas drops a pin and opens an inline thread composer at that spot. Pins live in flow coordinates (they pan/zoom with the board, via a new CommentLayer rendered inside the ReactFlowProvider alongside the cursors/draw overlays), show the author's colored initial, and fade when the thread is resolved. Clicking a pin opens its thread — root + replies with avatars and relative timestamps, a resolve/reopen toggle, delete (author-only), and a reply box. Both the composer and reply box support @-mention autocomplete over the space's members (↑/↓/Enter, click). New components/comments/* (CommentLayer, CommentThread, shared CommentsCtx type) + lib/use-space-comments.ts (loads comments + members, subscribes to Realtime, refetch-on-write); Canvas gains a comments prop, the page wires it from the cloud space, and the Toolbar gains the comment toggle. Local spaces are unaffected (no member list → no comments). The all-comments Sheet panel is the next slice.
  • Comments data layer (Phase 3, slice 1 — foundation, inert). Groundwork for cloud-only, Figma-style comments: a new public.comments table (client-uuid id, self-FK parent_id for replies with cascade, author_id default auth.uid(), resolved flag, and a data jsonb for body/anchor/mentions), member-read / self-insert / author-or-editor update+delete RLS via the private.* helpers, added to supabase_realtime with replica identity full (20260724000100_comments.sql). New lib/supabase/comments.ts mapper + CRUD (loadComments/createComment/editComment/setResolved/deleteComment) and a subscribeComments Realtime helper (refetch-on-change). Nothing consumes it yet — the canvas pin overlay and the Sheet thread UI land in the next slices.
  • / slash-command palette in the AI composer (Phase 2). Claude-style: typing / as the first character opens an anchored, grouped command menu above the composer that filters as you type, with ↑/↓ + Enter/Tab to run, Esc to dismiss, and mouse hover/click; a non-matching /text still sends as a normal message. The + button now opens the same palette. Commands span three groups — Board (/brief, /layout auto-layout, /new chat), Mode & model (/agent, /chat, /model), and Add to board (/add sticky · text · frame · shape). Board/add commands run through the existing onActions path (validated AIActions: auto_layout, create_sticky/create_text/create_frame/create_shape placed at the viewport center). New lib/ai/commands.ts registry (declarative run(ctx) per command, no React/icon deps — unit-tested, tests/ai-commands.test.ts) + components/ai/SlashCommandMenu.tsx.
  • Clip AI chat rebuilt on shadcn chat primitives (Phase 1). Installed the shadcn MessageScroller / Message / Bubble / Marker / Attachment / Avatar components and rewired the compact AI popover thread onto them: the scroller now owns follow-while-streaming, turn anchoring, and a floating jump-to-latest control (replacing the hand-rolled scroll container). User turns render as right-aligned secondary bubbles, assistant replies as plain ghost bubbles, and day dividers as Marker separators — all still carrying briefing badges, thoughts, token counts, and the "Board updated" action meta. The composer gains a + add-context menu (brief space / new chat) on the left and a round send button on the right, matching the reference layout while keeping the model switcher, mic/dictation, mode, and Enter-to-send intact.
  • The shadcn chat primitives ship for Tailwind v4; a few v4-only utilities they use (wrap-break-word, ring-3, duration-400, scrollbar-*, shimmer) are backported to this project's Tailwind v3 build via tailwind.config.ts + a @layer utilities block in globals.css, and the generated components' v4 variant syntax (has-data-, *:data-slot, size-*!) was rewritten to v3 form. Button gains icon-sm / icon-xs sizes the primitives expect.

Fixed

  • Chat flickered while completely idle — replaced the observer-driven scroller. The shadcn MessageScroller (from @shadcn/react) drives scroll position with a ResizeObserverrequestAnimationFramesetSnapshot (context setState) measurement loop, plus a MutationObserver and more rAF probes. Its viewport also toggled data-autoscrolling:scrollbar-none, which changes the reserved scrollbar-gutter width — so hiding/showing the scrollbar resized the viewport, the ResizeObserver re-fired, it re-measured and re-toggled: a self-sustaining measure→repaint loop that re-rendered the whole thread every frame at idle (the "full redraw" flicker). Replaced it with a plain scroll container: a useLayoutEffect pins to the newest turn (pre-paint) and a small onScroll check drives the jump-to-latest button — no observers, no rAF loop, stable gutter (scrollbar-gutter: stable, never hidden). The Message/Bubble/Marker visuals are unchanged. Removed the now-unused components/ui/message-scroller.tsx and the @shadcn/react dependency.
  • Chat polish — user bubbles were transparent, composer felt boxed-in, thread jumped. Three follow-up fixes to the Phase-1 chat: (1) the shadcn Bubble applies its fill through a *:data-[slot=bubble-content]:bg-… variant that Tailwind 3.4 silently drops — so user (secondary) bubbles rendered with no background; rewrote those variants to the v3-valid [&>[data-slot=bubble-content]]:bg-… child selector (verified the bg-secondary/bg-primary/ bg-muted rules now emit into the compiled CSS). (2) The composer no longer sits in a bordered footer container — it floats over the thread (rounded pill with a soft shadow, a top fade so the conversation dissolves behind it), matching the reference; the legal disclaimer line was dropped from the compact view and the jump-to-latest button lifted above the pill. (3) Removed the upstream content-visibility:auto + contain-intrinsic-size from MessageScrollerItem — that long-thread virtualization estimated row heights and caused visible scroll jumpiness in this short-thread popover.