ClipSpacesClipSpaces Docs
Back to app

All releases

PDFs, smarter AI context, Notion AI export, and fixes

A batch covering auth, files, the AI assistant, Notion, the docs site, and a couple of database-advisor cleanups.

Added

  • Multiple AI model profiles (components/AISettingsPanel.tsx, app/api/ai/credentials/route.ts, lib/ai/config.ts). AI settings is now a managed list: a user can save several profiles — each its own provider, model, endpoint, and (encrypted) API key — and pick which one is active; the active profile drives the AI panel. ai_credentials is reshaped from one-row-per-user to many (id PK, label, is_active, one-active-per-user index); the API gains list / create / update / set-active / delete. Note: this migration was never successfully applied before (it referenced the dropped public.touch_updated_at()), so applying it now creates the table fresh.
  • PDF cards (components/cards/FileCard.tsx, components/Canvas.tsx). Dropped PDFs show a first-page thumbnail on the canvas and double-click (or the expand button) opens a full, scrollable lightbox — reusing the existing image/video/embed preview modal. Data-URL PDFs are rendered via a blob URL (browsers block data: inside iframes). Size is capped by auth state: 5 MB signed out (inlined locally), 25 MB signed in (uploaded to the cards Supabase Storage bucket via the new lib/supabase/upload.ts); over-limit drops are rejected with a clear toast.
  • AI summary → Notion (app/api/integrations/notion/export/route.ts, components/NotionPicker.tsx). The Notion export gains an Include AI summary option that prepends the space's AI briefing (the saved one, or a freshly generated one) above the exported cards.
  • Richer AI context (lib/ai-enrich.ts). Map cards are resolved through the Nominatim geocoder so the model sees the real place, kind, and coordinates instead of a bare search string; uploaded PDFs have their text extracted (unpdf); file cards are now described to the model at all.

Changed

  • Shapes picker (components/Toolbar.tsx). The diagram-shapes flyout was redrawn from a cramped two-column icon+text list into a tidy tile grid — each glyph centered in its own swatch with a caption, split into Flowchart and Architecture rows (Frame joins the architecture row), so it's an even, scannable 4-up instead of a list with an orphan "Frame" row.
  • Releases page (app/(docs)/releases/, lib/changelog.ts). Releases are grouped by day (same-day entries collapse under one date), each shows a short summary, and a Read details button opens a blog-style permalink at /releases/<slug>. The month filter / TOC is unchanged.
  • Email templates (supabase/templates/). The sign-in emails now use the real ClipSpaces logo image instead of a CSS letter-box.
  • AI board context moved to lib/ai/board.ts, shared by the AI route and the Notion export (no behavioural change to chat/brief).

Fixed

  • Toolbar active state invisible (components/Toolbar.tsx). The active tool was marked by a floating layoutId indicator layer behind the button, which could fail to paint over the toolbar's backdrop-blur — leaving just a white glyph on a transparent button (notably in light mode). The active fill is now painted directly on the button (solid var(--accent) + white glyph), so it's unmistakable in both themes.
  • Sign-in code length mismatch (components/EmailOtpForm.tsx, supabase/config.toml). The hosted project issues 8-digit codes, but the form announced "a 6-digit code" and was spaced for 6 — so the real code didn't fit the copy or the field. The form is now length-agnostic (fits up to 10, tighter letter-spacing) and local otp_length matches the hosted 8.
  • Paste leaked onto the canvas (components/Canvas.tsx). The global paste handler fired even when a form field was focused, so pasting a sign-in code also dropped a card on the board behind the popover. It now ignores pastes that land in inputs/textareas/contenteditable; the OTP field also sanitizes pasted codes (stripping spaces/dashes).

Security

  • accept_space_invite (supabase/migrations/20260630000100_…). Documented why it must stay SECURITY DEFINER (acknowledged advisor lint 0029) and re-asserted least-privilege grants.
  • Leaked-password protection — noted in supabase/config.toml as a hosted-dashboard toggle to enable (clears the advisor WARN; no real surface since auth is passwordless OTP).