Folio is a document-based personal computing environment. Instead of switching between separate apps for calendar, email, tasks, notes, and spreadsheets, everything lives in a single text document. The left pane shows the raw text; the right pane renders it as live, interactive widgets.
Every change you make — checking a task, editing a table cell, sending an email reply — is a text edit. Your document is the source of truth, saved automatically to your browser, and downloadable as a plain text file.
.folio.txt file.Directives are lines that start with :: and summon live widgets into the document. They are readable as plain text even without a renderer.
Renders an agenda of events. Each event is a body line with title=, time=, duration=, type=, and status=. Pending events show accept / decline buttons; clicking one updates the event in the text and appends a log entry.
::cal[today]{view=agenda}
title="Team sync" time=09:00 duration=30min type=internal status=pending
::end
Inbox (::email[inbox]{filter=unread}) shows filtered messages with a file action that logs to the document. Thread (::email[thread-id]{limit=3}) renders a conversation with a reply bar. Draft (::email[draft]{to=... subject=...}) is a compose form whose body is the message text. Sending replaces the block with a sent log line; discarding deletes it.
A contact card with key = value fields in the body (name, email, role, org, phone, notes). Click edit to modify fields inline. email and call buttons log actions to the document.
::contact[sara.chen] name = Sara Chen email = sara@example.com ::end
An editable text block. The body is free-form prose; params hold structured metadata. Click inside to edit; changes save to the document on blur.
A text-native table with pipe-delimited rows. If editable=true, click any cell to edit it. Edits are written back to the document text. If linked to a ::py block via source=, the divergence protocol tracks whether cells have been manually edited:
::table[budget]{source=analysis editable=true}
| Region | Q1 | Q2 |
| North | 3500 | 4200 |
::end
A computation block that runs Python (via Pyodide) in the browser. Code can query any other directive type: cal.query(), table.query({'id': 'budget'}), email.query(), etc. Click run to evaluate; run=auto evaluates on page load.
::py[analysis]{run=auto}
data = table.query({'id': 'budget'})
print(sum(d['q1'] for d in data))
::end
A single-line directive with a checkbox. All metadata (due=, priority=, blocked-by=, status=) is preserved when you toggle it. Completed tasks get a completed= timestamp. A task with blocked-by=other-task is disabled until the blocker is done.
::task[call-finance]{due=today priority=high status=todo}
A reference to a file on disk. Renders a card with filename, path, and type icon. Set preview=true for a preview area.
::file[~/docs/report.pdf]{preview=true}
A slice of a chat channel. Messages are body lines with user=, text=, time=. Type a message and click Send to post (appends a log line). Hover a message and click promote to write it as prose below the embed.
::chat[#design]{limit=5}
user=sara text="Ready for review?" time=09:15
::end
Embeds a URL reference with reader-mode rendering. Body lines above --- are metadata (title =, summary =); lines below are your annotations, editable inline.
::web[https://example.com/article]{view=reader}
title = An Interesting Article
summary = Key findings about...
---
My notes on this article.
::end