Writing
A database in a Markdown file
Every repository has the same table in it. A feature matrix, a decision log, a list of endpoints with owners. It starts as six rows of pipes and dashes in a Markdown file, and it works.
Then it reaches forty rows and five columns. Editing it by hand is miserable, the pipes stop lining up, and sorting it means retyping it. So it moves somewhere that can hold a table properly, and from that moment it is out of the repository: behind a login, in someone's export format, and reachable by your agents only through an API, a page at a time, if at all.
That is the trade this is about. Sheaf is a Markdown editor for VS Code and the editors built on it, and it takes a different route: keep the table in the file, and give the file the parts that made you leave.
Name the table
A table of real data reads better as CSV than as pipes, so write it as a fencedcsv block. Sheaf draws it as a grid you edit like a spreadsheet: click a cell and type, Tab across, drag a row to move it, paste a range in from Excel or Sheets.
Give the block a name on its opening line, and something else can refer to it:
```csv id=tasks
task,status,crew,days
Amplifier controller,In progress,Quill,5
Cryocooler service,Done,Quill,8
```Every other tool reads the first word of that line as the language and ignores the rest, so on GitHub the block looks exactly as it did before.
Query it in place
A second fenced block, with the language view, is a query over that table:
```view
from: #tasks
where: status != Done
sort: days desc
show: task, crew, days
```Sheaf draws the rows it keeps, in the order it asks for, with the columns it names. You rarely type one: click a column header to sort, use its menu to filter or hide a column, and Sheaf writes the line into the query for you.

Editing a cell in the view changes that cell in the table it reads, and only that field. The view itself never holds data. Off Sheaf it is a code block showing its own query, which tells the next reader exactly what they are looking at.
Or draw it as a board
Two more lines, layout: board and group: status, and the same rows are cards in columns. Drag a card to another column and its value changes in the table. The filtering and the sorting still apply.

When the table outgrows the document, move it to a .csv file of its own and point the view at the path instead. The file opens as a grid too, and rows move between a block and a file in one step.
Why keep it in the file
Because of what reads it. An agent working in your repository opens the document and gets the argument and the numbers in one pass, with no connector, no pagination and no per-cell JSON around every value. The same is true of a colleague on GitHub, ofgit blame on the row that changed, and of you in six months on a branch.
It also means the history is the repository's. Every version, with a message saying why, and no plan tier that expires it.
What it does not do
There are no formulas, no totals, no joins between tables. A view filters, sorts, hides columns and groups into a board, and that is the whole language. Nothing computes a number that is not written down.
It suits the tables a team actually keeps by hand: tens to low hundreds of rows. A spreadsheet of ten thousand is a different problem and wants a different tool.
Try it on a table of your own
The demo on the front page is the real editor running in the page, with no install and no account: open a document, click into a table, type. Theninstall it in VS Code, Cursor, Windsurf, Kiro or VSCodium, open a repository, and point a view at something you already maintain.
Sheaf is MIT licensed and every line is on GitHub. If the syntax above is not the syntax you would have chosen, it is a fenced block and a parser, and the parser is right there.