Repository navigation
Folio v0.3.0
Folio 0.3.0: your Obsidian vault or docs folder as a team wiki
Connect an Obsidian vault or a docs/ folder and it becomes a team wiki in the browser. The files stay untouched: Folio adds no id to them, keeps its metadata in a dotfile, and git status stays clean after the scan. Teammates who do not use Obsidian read, edit and comment in the browser; you keep working in your editor, and both sides meet in Git.
Obsidian markup is read. Wikilinks ([[Note]], [[Note|alias]], [[Note#Heading]], [[Note#^block]]), note and image embeds (![[Note]], ![[image.png|300]]), callouts of any type, %%comments%%, block ids, #tags and $formulas$ are drawn in reading mode, printed in PDF and DOCX, and found by search. Embeds respect the reader's access rights on the server.
How to try it: create a space from a repository with a vault, or point it at a folder.
Properties, tags and search. A properties panel with types (text, number, checkbox, date, list, tags, aliases) rewrites only the front matter block. A tag tree in the sidebar renames a tag across the space in one go. Search has one grammar in the UI, REST and MCP: "phrase", -word, tag:, in:folder/, kind:, status:, prop:key=value (several values of one filter match any of them, as in kind:doc,table), with saved searches.
A richer index. Each page is parsed once into headings, block ids, tags, properties and every link. You can list unresolved links and orphan pages for a space. Agents get the same through three new MCP tools (26 in all): get_page_metadata, list_unresolved_links, list_orphans.
Site and PDF settings live in the repository. A "Site & PDF settings" page edits a .folio/ folder: site title, logo, favicon, a sanitized stylesheet for the public site, and the PDF header, footer and print stylesheet. Every save is one commit, and Git is an equal editor.
SEO for public sites. Each public page gets its own title, description, Open Graph tags and canonical link from the server, and Folio serves robots.txt and sitemap.xml. A switch turns indexing off.
Honest limits: Obsidian markup is read, not written. Dataview and query blocks, Canvas, Bases and community plugins are not rendered, and a PDF embed is a link, not a viewer. In the live editor an image embed ![[img]] shows as a label, and reading mode draws the image. Space files are not in the tree or in search; they are found by name. The full list is in LIMITATIONS.md.
Links: https://foliowiki.online, Folio and Obsidian side by side: https://foliowiki.online/compare/obsidian/, try it without installing: https://demo.foliowiki.online (shared, resets every 24 hours).
Also in this release
- Six docs-as-code fixes found by testing real documentation repositories: another tool's
id:no longer merges spaces, front matter values Folio did not write are never removed, opening a page writes nothing, no inserted or duplicate H1, links with%20or without an extension open, and skipped.mdxfiles are reported. - Fixes from a test on real Obsidian vaults:
labels:is kept, images and files by name work through share links, DOCX and PDF embed images, mixed line endings are kept. - "Page not found" and "no access" are different screens; the public site layout is tidier.
- The public demo can publish, and the Folio Handbook there is a public site.
Upgrading
Back up first, then update as usual (docs/INSTALL.md). Migrations 040 to 044 apply at startup and are one-way (042 turns the links table into a view), so an upgraded database cannot go back to 0.2.x without restoring the backup. The first start re-reads every document once because the page index has a new version; the server listens before that scan, but while a very large space is re-parsed it can stop answering health checks for a few minutes. A connection check that expects 23 MCP tools now sees 26.
Full changelog 0.3.0
Your Obsidian vault or docs/ folder becomes a team wiki in the browser, and
the files stay untouched. A vault connects with a light footprint (no id is
written, git status stays clean) and Folio reads Obsidian markup: wikilinks
and embeds, callouts, %%comments%%, block ids, tags and formulas, with a
properties panel and types, a tag tree with rename, one search grammar with
operators and saved searches, an index of space files, and a page index with
metadata, unresolved links and orphans (the MCP server now has 26 tools).
Also in this release: a "Site & PDF" settings page backed by a .folio/
folder, SEO for public sites (per-page <head>, robots.txt, sitemap.xml),
six docs-as-code fixes found by testing real documentation repositories, and
fixes from a test on real Obsidian vaults. Obsidian markup is read, not
written; Dataview, Canvas and plugins are not supported.
Added
- A "Site & PDF" settings page and a
.folio/folder in the repository.
A space administrator opens the space menu, chooses "Site & PDF settings…" and
gets one page,/s/<space>/settings, with three tabs: Site (title, tagline,
description, language, social image, favicon and logo, next to a summary of
the publication), Site appearance (a stylesheet with a live preview) and PDF
(header, footer and print stylesheet, with a "Test PDF" button). What a space
looks like outside the app is kept in the repository, in a.folio/folder at
the root of the space's content (docs/.folio/for a space with a root path):
site.json,site.css,export.css,pdf-header.html,pdf-footer.html
andassets/for the logo, favicon, social image and fonts. Git is an equal
editor: each file shows its path and an "Open in repository" link, every save
is one commit (settings: update .folio/site.css) that contains only the
files you saved, never other people's unsaved page edits, and if a file was
changed in the repository after the page was opened, the save is refused and
the page shows the difference so you can take the repository's version or
keep yours. Who can see the site and where (visibility, subdomain, domain,
downloads, Folio AI) stays in the database and in the publishing dialog. The
"Powered by Folio" footer of a public site is not configurable. - SEO for public sites. Every public page now gets its own
<head>from
the server, so crawlers and link previews see it without running scripts:
the title (page title, then site title), a description (the page's front
matterdescription, else the site's, else an excerpt), Open Graph tags, a
canonical link, the language, the site's favicon, andnoindexfor a page
withunlisted: truein its front matter. A page that is not on the site
answers with a real 404. Folio servesrobots.txtandsitemap.xmlfor each
host: a site's own host gets that site's sitemap, and the main host keeps
crawlers out of/s/,/share/and/api/and lists the sitemaps of sites
served at/public/<space>(/public/<space>/sitemap.xml). The publishing
dialog has a switch, "Allow search engines to index this site" (on by default;
off meansnoindexon every page,Disallow: /and no sitemap), and a
"Primary address" choice (automatic, address on this Folio, subdomain or
custom domain) that decides which address is canonical and goes into the
sitemap. In the public demo every site isnoindex. Adds migration 040. - A stylesheet for the public site.
.folio/site.cssrestyles a public site
and never the app itself. Folio sanitizes it before serving it: comments and
@importare removed,url()keeps onlydata:images and fonts and files
from.folio/assets/(anything else becomesnone), and a file over 256 KB
is not applied at all. The settings page shows the same warnings while you
type..folio-siteand[data-folio-site-part="header"](alsosidebar,
main,footerandpage) are stable selectors. The logo fromsite.json
appears in the header of the site, and the site title replaces the space
name. There is no JavaScript and no third-party snippet. - Obsidian vaults connect without a single change to your files. A
repository (or the chosen folder) that holds.obsidian/is detected when you
create the space, and the space is created with a light footprint even when it
is the whole repository: Folio adds noidto any file, keeps its metadata in
a dotfile (.<slug>.folio), andgit statusstays clean after the scan. The
"Light footprint" switch can also be turned on by hand. What the scan skips is
now a per-space list:.obsidian/,.trash/and.git/are always skipped,
and a space administrator adds more (a name, aprefix*pattern, a trailing
/for folders only) in the space menu under "Indexing & files…", or with
PATCH /api/spaces/:space/scan-settings; changing the list rescans the space
and never touches the files on disk. Wikilinks ([[Note]],[[Note|alias]],
[[Note#Heading]],[[Note#^block]],![[Note]]and![[image.png]]) are
indexed with Obsidian's shortest-path rules, so they show up in backlinks and
in the broken-link count, and renaming or moving a page rewrites them in their
own form. Code blocks and inline code are never indexed or rewritten. Adds migration 041. - A richer page index. Each page is parsed once, when the space is scanned
and when the page is saved, and the index now holds its headings (with the
same anchors as the outline),^block-ids, tags (#tagin the text outside
code, andtags:in the front matter, withlabels:read as a synonym), the
whole front matter as properties, and every link of every kind: Markdown
links, images, wikilinks, embeds, HTML<a>and<img>, and reference-style
links, each with its heading or block fragment and whether that fragment
exists. Links are resolved in a second step over the whole space, so a page
that appears later brings the links that point to it back to life, and a
deleted page leaves its links as unresolved instead of erasing them. New
reads, all filtered by the reader's rights in the query itself (counts and
lists never include a page the reader cannot open):
GET /api/pages/:id/meta(outline, tags, properties, links);
GET /api/pages/:id/backlinks, now one entry per link with its syntax,
fragment, line and the line of text around it;GET /api/spaces/:space/tags;
GET /api/spaces/:space/unresolved-links; andGET /api/spaces/:space/orphans
(pages nothing links to). HTML and reference-style links are indexed but not
rewritten when a page is renamed or moved. Adds migration 042. - Three more MCP tools, 26 in all.
get_page_metadatareturns a page's
outline, tags, properties and links,list_unresolved_linkslists a space's
links that point nowhere, andlist_orphanslists the pages nothing links to.
All three respect the token owner's access rights. - Obsidian markup is shown, never written. Wikilinks (
[[Note]],
[[Note|alias]],[[Note#Heading]],[[Note#^block]]) are links, a dashed one
offers "Create page" when its target is missing;![[image.png|300]]is an
image;![[Note]]and![[Note#Heading]]embed the note (the reader's access is
checked on the server, depth up to 3, cycles cut) through
GET /api/pages/:id/embed; callouts of any type with fold and title;%%comments%%
are hidden;^block-idis an anchor;#tagis a chip; formulas are drawn with
KaTeX. Reading and Live agree, PDF/DOCX and search get the same text, and the
files are never rewritten. Dataview, Canvas, Bases and plugins are not supported. - Space files are indexed as files (migration 043). Attachments and
assets/
stay out of the tree and search, but links to them resolve by Obsidian's rules
(from the root, or by name with the nearest folder) and a missing file shows up
among unresolved links.GET /api/spaces/:space/files. - A properties panel. Property types (
text,number,checkbox,date,
datetime,list,tags,aliases) live in.folio/properties.json, with
.obsidian/types.jsonas a read-only fallback. Saving rewrites only the front
matter block. A Folio key with a foreign value is shown as such and never
overwritten;labels:is read,tags:is written. - Tags and search. A tag tree in the sidebar with bulk rename
(POST /api/spaces/:space/tags/rename), and one search grammar everywhere (UI,
REST, MCP):"phrase",-word,tag:,in:folder/,kind:,status:,
prop:key=value; saved searches (up to 50 per person, migration 044).
Changed
-
The PDF header and footer moved from the dialog to the settings page. The
"PDF header & footer" dialog is gone; the PDF tab of the new page edits the
header, the footer and the print stylesheet, which now live in.folio/
(pdf-header.html,pdf-footer.html,export.css). Images in a template are
files in.folio/assets/referred to by name (<img src="logo.png">) and
are embedded when the PDF is made, so printing makes no network requests.
Settings saved earlier (theexportsection of<slug>.folioand
<slug>.export.css) are still read, and the first save of the PDF tab moves
them into.folio/in one commit, with embedded pictures becoming files in
.folio/assets/. -
The public demo can publish. In demo mode (
FOLIO_DEMO_MODE=1) a demo
account that administers a space can now change its visibility and publish
settings, so visitors can try "Publish as website". A subdomain or a custom
domain is refused (400) so that nobody can point a host at a shared demo, and
Ask Folio AI on a public site stays off. The demo seed publishes the Folio
Handbook at/public/folio-handbook. -
The MCP server now offers 26 tools (it was 23). The three new ones are
get_page_metadata,list_unresolved_linksandlist_orphans, and the
instructionsthe server sends to clients mention them. A client that lists
tools shows 26, so a connection check that expects 23 needs updating. -
The first start after upgrading re-reads every document. The page index
has a new version, so the scan re-parses all documents once even when their
files have not changed. The server starts listening before that scan, but
a very large space can keep it from answering for a few minutes, and
until it has passed over a space the new page metadata, tags and unresolved
links for it are incomplete. Thelinkstable is now a view over the new
page_linkstable, with the same columns for anything that still reads it.
Fixed
-
Obsidian vaults, fixes from a test on real vaults. A
labels:key is no
longer removed or merged intotags:by the properties panel or a tag rename.
A space created from a non-empty repository at its root now uses the light
footprint by default, so connecting it writes noid:into the files.
Images and files resolved by name now work through share links and for
![[file.pdf]]. DOCX export embeds images next to text and JPEG, GIF, BMP and
WebP, and PDF and DOCX honour|200widths; anything that cannot be embedded
shows as[image: name]. Note embeds after text, wikilinks with a code alias,
callouts with a non-breaking space and block embeds of a callout render
correctly. Mixed line endings are kept per line after an edit. -
"Page not found" and "no access" are different screens. A page or space
that does not exist shows 404 with no "Request access" button. A page or
space that exists but you cannot open shows "No access": a "Request access"
button when you have no role in the space, or a note to ask the page owner
when the page itself is restricted to specific people. Anonymous visitors
never see the button. -
Public site layout. Search and "Ask AI" moved into the header, like the
main app; "Space home" is back above the page tree; "Sign in" and "Powered
by Folio" (now linking to foliowiki.online) sit at the bottom of the left
column, and the footer under the content is gone. -
Another tool's
id:no longer merges spaces. Two connected documentation
folders whose files carry the same front matterid(Docusaurus and Jest use
id: intro) used to trade pages: the space scanned last took them over, and an
edit in one landed in the other's file. A file'sidnow counts only when no
live page already holds it; a duplicate gets an id of its own in the index and
its file is left untouched. A file carried from one space to another outside
Folio still takes its id along. -
Front matter values Folio did not write are never removed. Saving a page
no longer drops a value under a key Folio also uses when Folio could not have
written it, such as MkDocs'status: deprecated. Clearing a status, order,
icon or cover that Folio set still works. -
Opening a page writes nothing. Merely viewing a page used to rewrite its
file and commit it: the executable bit was lost, CRLF line endings became LF,
a missing final newline was added, and a# Titleline ending in CRLF was not
recognised as the heading, which renamed the file. Nothing changes until
someone edits the page, and an edit keeps the file mode, CRLF and a missing
final newline. -
No inserted or duplicate H1 in a docs folder. In a space that is a
sub-folder of a repository, the editor no longer adds# <file name>to a page
that has no heading, and a page with a blank line above its# Headingno
longer gets a second one. A page without an H1 is titled by its front matter
title:(Hugo, Docusaurus, Jekyll) and only then by its file name. -
Links with
%20and links without an extension open.
[x](guide/Getting%20Started.md)and[x](../getting-started)open the page
instead of "Page not found" or a file download, on public sites too, and
backlinks and broken-link counts agree with what opens. A link without an
extension that matches no page (LICENSE,Makefile) still opens the raw
file. -
The scan reports skipped
.mdxand.markdownfiles. MDX is still not
supported, but a folder of.mdxfiles no longer connects as an empty space
in silence: each scan logs how many such files it skipped.
GitHub Discussion post: see v0.3.0-discussion.md.