Skip to content

Folio v0.4.1

Latest

Choose a tag to compare

@skravtsov skravtsov released this 22 Oct 11:29

Compare pages and versions side by side, custom page templates, artifacts for
Claude and Cursor, and a clearer Folio AI. Pages and versions open in up to five
columns, with the changes highlighted and a link to share. Any page can be a
template, the MCP server has 45 tools (four of them for templates), Claude
artifacts and Cursor canvases become interactive pages, and properties update
live for everyone on the page. Share links open in your own account, copying
pages is about ten times faster on large spaces, and page exports are no longer
served stale behind a CDN. Adds migrations 049 to 052.

Added

  • Compare pages and versions side by side. Up to five pages, or older
    versions of a page, in one view (/compare?items=…). "Add to comparison" is in
    the sidebar and right-click menu (people who can only read a space get it too),
    in the page header and in the history panel. A "Comparison · N" chip at the
    bottom of the window holds the list (any spaces you can open, kept in the
    browser). A column of a current page is the page itself, with the live editor and
    live collaboration. In the history panel, "Compare with current" opens the page
    with the chosen version beside it, read-only, and "Add to comparison" sets a
    version aside. "Highlight changes" marks every version column against the
    leftmost one (green: new or changed blocks; red, struck through: removed text,
    with a count), "Refresh base" rereads the leftmost column, and synchronized
    scrolling keeps the columns together. "Copy link" copies an address with only
    page ids and version numbers; whoever opens it sees each column with their own
    access. Highlighting is block by block and skips a very large page; see
    LIMITATIONS.md.
  • Template tools for MCP and the assistant. Four new tools, 45 in all (21
    read-only, 24 that write): list_templates, create_page_from_template,
    save_page_as_template and create_template. create_page refuses a
    parentPath inside _templates/ and points to them. The assistant in Agent mode
    has the same tools, and its guide to them covers templates. See MCP.md.
  • Live status for Folio AI runs. The status line shows the model's thinking
    with a token counter, an elapsed-time counter after about three seconds of
    silence (a long page being written reports nothing for minutes) and the real
    tool names instead of a generic "mcp". The live reply keeps its paragraph breaks
    and renders Markdown links. The server logs the timing of each step of a run and
    stores it with the run (ai_runs.timing, migration 052).
  • Artifacts: publish Claude artifacts and Cursor canvases. A new page kind,
    "Artifact": an interactive page made by an agent (a Claude artifact, a Cursor
    canvas or any self-contained HTML page) that lives in the tree, search, trash and
    Git like any other page. On disk it is a folder <name>.artifact/ with
    index.html, an artifact.yaml manifest (type, origin, the capabilities the page
    expects, properties), the original source and assets/. It runs in a sandboxed
    iframe without cookies or access to the Folio API (/art/<signed token>/…, a
    sandbox Content-Security-Policy, scripts and fonts only from cdnjs, jsDelivr,
    unpkg, Tailwind, jQuery, esm.sh and Google Fonts); filters, tabs and charts work,
    and state is kept through window.storage (the Claude artifact API) and
    localStorage: in the database for signed-in readers (migration 051), in the
    browser for guests. Import with "Artifact…" in the "+" menu: a link to an
    .html, .zip, .svg or .md file, a file, pasted HTML, or the embed code of a
    Claude artifact; claude.ai and Cursor share links are not downloaded (the dialog
    suggests publishing over MCP). On the page: "Show source", "Download .zip",
    "Replace…", and a "works partially" note when the page expects calls to Claude,
    network access or connectors. New MCP tool publish_artifact creates an artifact or replaces one by id; read_page returns an artifact's
    manifest, files and entry HTML; kind:artifact works in search. The MCP request
    body limit outside the demo is now 25 MB, so a page with its data inlined fits.
    Folio does not build JSX or TSX: agents send finished HTML. See
    FEATURES.md, MCP.md and
    LIMITATIONS.md.
  • Custom page templates. Any page in the space's _templates/ folder is a
    template: a document, board, data table, form, base, or a whole page with
    subpages (before, only plain documents directly in the folder worked, one menu
    item each). "From template…" in the "+" menu (space root and every tree row)
    opens a picker, with a filter when there are more than six; creating copies the
    template with its subpages, properties and icon to the chosen place
    (POST /api/pages/from-template). In documents {{date}}, {{author}} and
    {{title}} are filled in; other {{…}} are left as they are. "Make template"
    in a page's context menu or "…" menu opens a dialog: the template name
    (prefilled with the page title), an optional description, and an "Include
    subpages" checkbox when the page has children. While it works the button says
    "Creating…" and the dialog can't be dismissed; afterwards the Templates section
    expands and a toast offers "Open". It copies the page into _templates/
    (POST /api/pages/:id/make-template with title, description and
    includeChildren); not for the space root, and disabled offline. The
    description is stored as the template's property template-description: it
    shows as a second line in the picker and as a tooltip in the sidebar, and a
    page created from the template does not get it. Editors get a "Templates"
    section in the sidebar (collapsed, with a count, rename and delete in the tree)
    whose "+", like the picker's empty-state button, opens the same dialog and
    creates a blank document template (POST /api/spaces/:space/templates with
    title and optional description; the items of GET on it carry
    description); an open template is marked "Template" in the breadcrumbs. The
    folder stays hidden from the page tree, graph, tags, bases and public sites. A
    new empty space starts with three templates in the creator's language (English
    or Ukrainian): Meeting notes, How-to, Decision record. Spaces cloned from Git
    get none.
  • Error reporting can attach a recording of recent actions to a report (Sentry
    Session Replay). Everything is masked: all text, form fields and images are
    replaced by placeholders, board drawings and embedded frames are not recorded,
    and no request bodies or headers are captured. The report dialog has a box
    "Attach a recording of recent actions (text hidden)", ticked by default and
    explained under "What is recorded?"; unticked, nothing is attached. SENTRY_REPLAY=0
    turns recording off, SENTRY_REPLAY_ON_ERROR (default 1) sets the share of
    visits with an error whose last minute is sent, and SENTRY_REPLAY_SESSION_RATE
    (default 0) the share of whole visits recorded. Click trails keep only an
    element's CSS path, never its text.

Changed

  • Starter templates have descriptions. The three templates a new space starts
    with (Meeting notes, How-to, Decision record) carry a template-description in
    the creator's language, shown as the second line in the "From template…" picker.

  • Copying pages is about ten times faster on large spaces. Make template,
    From template, Duplicate, Copy and New page reindex only the pages they wrote
    instead of rescanning the whole space, and the "is this a folder" lookup walks
    new range indexes (migration 050) instead of every file of the space. On a
    6150-page space with 5 ms per database query, duplicating a page with 40
    subpages went from 12.7 s to 1.3 s.

  • A share link opens in your own account. If you are signed in and can open
    the page yourself, /share/<token> takes you to the normal page
    (/s/<space>/p/<id>) with your sidebar and rights instead of the guest view.
    GET /api/share/:token adds ownAccess only for such a reader (never for a
    guest or a signed-in outsider) and answers with Cache-Control: private, no-store. Add ?as=guest to the link to see what a guest sees.

  • Properties update live. When someone else changes a page's properties (the
    panel, a base cell, MCP set_page_properties, a tag rename, the page icon, a Git
    sync), everyone who has the page open and may read it sees the change without a
    reload, and the bases of that space refresh. The server sends a small
    page-properties event over the existing /events socket only to sessions that
    may read that page. A field you are typing into is never overwritten: it says
    "Someone else changed this to …", Enter keeps yours, Esc takes theirs.

  • status is an ordinary property in a vault (an Obsidian vault or a
    repository with files of its own): any value, editable in the panel and in base
    cells, typed like other keys. Folio's page status reads only draft,
    published and archived from it; anything else counts as published. Search:
    status:todo (any value other than those three) matches the front matter
    status; the public site never matches it. Native Folio spaces are unchanged.

  • "Sync now" for editors. Anyone who can edit a space can sync it with Git from the space menu or the quick switcher; taking the Git version, connecting Git and the other space settings stay with space admins.

  • A tab left open across an update no longer reloads in a loop when a lazily loaded
    part of the app (the graph, the space settings, the board editor) is gone from
    the server. The page reloads at most once per missing file per minute; if the
    file is still missing, an error screen says "Part of the app could not be loaded.
    Reload the page." with Retry and, with error reporting on, "Report a problem",
    and the error is reported once.

  • An open tab that is behind the server now shows "A new version of Folio is
    available." with a Reload button, instead of failing later on a missing file.

  • With error reporting on, "Found an issue?" in a board's help dialog opens
    Folio's own "Report a problem" dialog instead of Excalidraw's GitHub issues, and
    Excalidraw's blog and YouTube links are hidden. The error screens have a
    "Report a problem" button that attaches the crash to the report. With no
    SENTRY_DSN the issue link is hidden too.

  • The page tree draws indent guides: a thin line drops from a parent's chevron
    through its children, so deep trees are easier to read.

Fixed

  • Vite 8.2.4 (development dependency): fixes GHSA-698v-4r3x-3vcv in
    launch-editor, which did not escape % in arguments on Windows (Dependabot
    alert #16). Only the dev server opened files in an editor that way; builds and
    the running server are unaffected.
  • Page exports are no longer served stale behind a CDN. Export routes sent no
    Cache-Control, so Cloudflare, which caches .pdf and .docx URLs by extension,
    returned the first file for every later export even after the page was edited.
    Every page export (Markdown, PDF, DOCX, YAML, the public-site routes and
    /share/<token>.md) now answers with Cache-Control: no-store
    (#7).