012

module
v0.6.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Sep 30, 2026 License: MIT

README

012

A spreadsheet for the terminal with a Lotus 1-2-3 look and Google Sheets behavior, built on Bubble Tea v2.

Inside the grid it works the way Sheets does: typing replaces a cell, = starts a formula, Enter and Tab move you on, Shift+arrows and the mouse select, and Sheets' shortcuts do what you expect. Around the grid, the control panel, the mode indicator and the character grid keep 1-2-3's look. Sheets and 1-2-3 are where it starts, not specs it follows to the letter. It is one pure-Go binary.

Typing a small budget, pointing at cells in a formula, and watching totals recalculate

Install

curl -fsSL https://f58b.n.zip/install.sh | sh              # macOS, Linux: into ~/.local/bin
go install github.com/FelineStateMachine/012/cmd/012@latest  # or build it with Go 1.27

On Windows, irm https://f58b.n.zip/install.ps1 | iex in PowerShell.

Then run 012, or 012 budget.012 to open a sheet. F1 shows every shortcut, F10 or Alt+letter opens the menus, and Ctrl+K searches every command. Install and run has the rest: building from a clone, importing files, 012 serve and settings.

A short tour

  • Formulas as in Sheets, with Sheets' functions, suggestions and argument hints, pointing at cells with the arrows or the mouse, named ranges, references between sheets, arrays that spill (FILTER, SORT, UNIQUE, LAMBDA), optional decimal arithmetic for money, undo for everything, and tracing that marks what a formula reads and what reads it and steps through it part by part (formulas); numbers, dates and formulas typed and shown in a locale per file.
  • Data tools: freeze, sort, filter, find and replace, conditional formatting, dropdowns and checkboxes, notes, protected ranges, and live pivot tables (working with data); wrapped text, borders and merged cells drawn with the terminal's box-drawing lines (formatting).
  • Charts that float over the grid and follow their data, drawn as real images in kitty, Ghostty and WezTerm and as text elsewhere (charts).
  • Files: a diff-friendly JSON format, import from CSV, TSV, JSON, nushell's NUON, XLSX, SQLite, Parquet and Lotus 1-2-3, export to CSV, TSV, JSON, NUON, XLSX, SQLite and a self-contained web page with its charts as SVG (files).
  • Tables too big for any grid: a Parquet file or a SQLite table of tens of millions of rows links as a source on a tab of its own, scrolled, sorted and filtered in place, with SUMIFS, XLOOKUP and pivot tables streaming over every row (linked sources).
  • For agents: 012 describe, get, set --dry-run and recalc with JSON results, a Claude Code skill, and 012 mcp, an MCP server whose writes go through the same checks as yours, with views of ranges and charts in the chat (agents).
  • Coworking with agents: 012 --listen lets the agent into your running 012, its pointer and name in the grid, its changes suggestions you accept or reject cell by cell, within the scope you give it (live mode).
  • A stage in a pipeline: ls | sheet | where size > 1kb edits a table on the terminal and sends it on with its types, through the nushell module 012 nu --install-module installs, or as ls | to nuon | ^012 --pipe | from nuon without it (pipelines).
  • Nushell notebooks: 012 nu (or Data > Shell in any workbook) opens a notebook tab of code and note cells, run with Jupyter's keys, each output under its cell; later cells read it as $name, and sent to a sheet it's a live table formulas read as nu.name (notebooks).
  • Macros, recorded or written as Starlark scripts saved with the sheet (macros).
  • Made for terminals: the mouse, hyperlinks, the system clipboard over SSH, your terminal's colors or any of hundreds of schemes, optional vim keys, and 012 serve to reach your sheets over SSH (keys, themes, SSH).
  • Together over SSH: sessions of 012 serve opening the same file share it live, each with its own cursor, the others' in their colors, and undo that takes back only your own changes (sharing a workbook).
  • JEV functions ask TypeSafe's hosted model about your data from a formula (JEV).
Menus and the command palette Inserting a chart that follows its data
Menus and the command palette (Ctrl+K) Charts that float over the grid and follow their data
A task list with a color scale, a dropdown and checkboxes A pivot table of sales by region and quarter
Conditional formatting and data validation Pivot tables, live
UNIQUE, SORT and FILTER spilling their results
Arrays that spill Nushell notebooks
JEV functions classifying reviews Recording a macro and replaying it
JEV functions in formulas Macros
Ten million rows of Parquet linked as a source, sorted and summed
Linked sources, too big for any grid

Each guide shows its own recordings too. They are VHS tapes in demos/, rendered by make demos in the Catppuccin Mocha palette; 012 draws in your terminal's own colors by default (themes). Charts show as text here.

More

Young and moving quickly. The file format is versioned and older files keep loading; the Go packages are internal and may change at any time.

License

MIT

Directories

Path Synopsis
cmd
012 command
Command 012 is a Lotus 1-2-3 style spreadsheet for the terminal.
Command 012 is a Lotus 1-2-3 style spreadsheet for the terminal.
demos
fakejev command
Command fakejev is a stand-in for the TypeSafe JEV service, for demo recordings: it answers every question about a value by looking for complaint words in the value, so a demo never needs a real key and always records the same answers.
Command fakejev is a stand-in for the TypeSafe JEV service, for demo recordings: it answers every question about a value by looking for complaint words in the value, so a demo never needs a real key and always records the same answers.
gensales command
Command gensales writes the sales the linked sources demo reads (sources.tape): ten million rows of Parquet, an id, one of eight categories, an amount and a date each, the same every time (internal/stress's SalesParquet), into the file named on its command line.
Command gensales writes the sales the linked sources demo reads (sources.tape): ten million rows of Parquet, an id, one of eight categories, an amount and a date each, the same every time (internal/stress's SalesParquet), into the file named on its command line.
liveagent command
Command liveagent is the agent of the live-mode tape (live.tape): it writes a household budget, then attaches to the 012 listening on it with 012 mcp --attach, as a host would, and works through a script: it points at the bills, suggests March's figures, waits for the person to settle them, asks whether to add a line for the gym and, told yes, suggests it.
Command liveagent is the agent of the live-mode tape (live.tape): it writes a household budget, then attaches to the 012 listening on it with 012 mcp --attach, as a host would, and works through a script: it points at the bills, suggests March's figures, waits for the person to settle them, asks whether to add a line for the gym and, told yes, suggests it.
internal
chart
Package chart draws a sheet's charts: as text for any terminal (block elements for bars, braille for lines, half blocks for pies), and the plot area as an image for terminals with kitty graphics.
Package chart draws a sheet's charts: as text for any terminal (block elements for bars, braille for lines, half blocks for pies), and the plot area as an image for terminals with kitty graphics.
config
Package config is 012's settings file: a Ghostty-style list of "key = value" lines in <user config dir>/012/config, with # comments and config-file includes.
Package config is 012's settings file: a Ghostty-style list of "key = value" lines in <user config dir>/012/config, with # comments and config-file includes.
confine
Package confine maps the file names a user types to paths on disk, keeping them inside one directory when 012 serves sessions over SSH.
Package confine maps the file names a user types to paths on disk, keeping them inside one directory when 012 serves sessions over SSH.
cowork
Package cowork is live mode (docs/agents/live.md): the agent working in a running 012 session, as one of the participants of the session's room (package room).
Package cowork is live mode (docs/agents/live.md): the agent working in a running 012 session, as one of the participants of the session's room (package room).
diff
Package diff compares and merges .012 workbooks cell by cell, for 012 diff and 012 merge-driver (see docs/files/git.md).
Package diff compares and merges .012 workbooks cell by cell, for 012 diff and 012 merge-driver (see docs/files/git.md).
fileio
Package fileio moves data between sheets and other file formats: CSV and TSV, Excel workbooks, SQLite databases, Parquet files and Lotus 1-2-3 worksheets.
Package fileio moves data between sheets and other file formats: CSV and TSV, Excel workbooks, SQLite databases, Parquet files and Lotus 1-2-3 worksheets.
formula
Package formula is the formula language: A1 references and ranges, sheet names in references, the lexer and Pratt parser, the syntax tree, the printer that writes trees back in Sheets' spelling, and the rewriting of references when cells are copied, moved, inserted or deleted.
Package formula is the formula language: A1 references and ranges, sheet names in references, the lexer and Pratt parser, the syntax tree, the printer that writes trees back in Sheets' spelling, and the rewriting of references when cells are copied, moved, inserted or deleted.
functions
Package functions is 012's function library: the FuncDef table, the evaluation of formulas (operators and calls), the argument, range and criteria helpers functions share, decimal arithmetic, and the questions JEV functions ask.
Package functions is 012's function library: the FuncDef table, the evaluation of formulas (operators and calls), the argument, range and criteria helpers functions share, decimal arithmetic, and the questions JEV functions ask.
headless
Package headless works on workbook files without the screen, for 012 get, set, recalc and export (see docs/files/scripts.md): it opens a .012 file, finds the cells a reference names, reads and writes them, lists the errors formulas show and saves atomically.
Package headless works on workbook files without the screen, for 012 get, set, recalc and export (see docs/files/scripts.md): it opens a .012 file, finds the cells a reference names, reads and writes them, lists the errors formulas show and saves atomically.
jev
Package jev answers the spreadsheet's JEV functions with TypeSafe's hosted model.
Package jev answers the spreadsheet's JEV functions with TypeSafe's hosted model.
keyring
Package keyring keeps the JEV API key in the operating system's credential store: the macOS Keychain, the Windows Credential Manager, or the freedesktop Secret Service on Linux and the BSDs (GNOME Keyring, KWallet, KeePassXC).
Package keyring keeps the JEV API key in the operating system's credential store: the macOS Keychain, the Windows Credential Manager, or the freedesktop Secret Service on Linux and the BSDs (GNOME Keyring, KWallet, KeePassXC).
live
Package live reads the sources of linked regions as they change: a file followed as it grows or is rewritten (File), and anything else that yields a table's rows over time behind the same Source.
Package live reads the sources of linked regions as they change: a file followed as it grows or is rewritten (File), and anything else that yields a table's rows over time behind the same Source.
locale
Package locale is the table of spreadsheet locales, as Sheets' File > Settings > Locale offers them: how numbers, dates and currency are typed and shown, and how formulas separate their arguments.
Package locale is the table of spreadsheet locales, as Sheets' File > Settings > Locale offers them: how numbers, dates and currency are typed and shown, and how formulas separate their arguments.
macro
Package macro runs macros: Starlark scripts that act on a spreadsheet through a small API, as Google Sheets macros are Apps Script.
Package macro runs macros: Starlark scripts that act on a spreadsheet through a small API, as Google Sheets macros are Apps Script.
mcp
Package mcp is 012 mcp: a Model Context Protocol server on the workbooks in the folders open to it (see docs/agents/mcp.md).
Package mcp is 012 mcp: a Model Context Protocol server on the workbooks in the folders open to it (see docs/agents/mcp.md).
notebook
Package notebook is a notebook's document: its cells (code cells holding a nushell pipeline, note cells holding Markdown), the names cells give their outputs, what each cell reads, the order cells run in, and what a cell's last run left (its output).
Package notebook is a notebook's document: its cells (code cells holding a nushell pipeline, note cells holding Markdown), the names cells give their outputs, what each cell reads, the order cells run in, and what a cell's last run left (its output).
numfmt
Package numfmt renders numbers the way spreadsheets show them: number format patterns as in Sheets' custom number formats and TEXT(), General's shortest form, rounding on the 15 significant digits users see, and the serial day numbers dates and times are stored as.
Package numfmt renders numbers the way spreadsheets show them: number format patterns as in Sheets' custom number formats and TEXT(), General's shortest form, rounding on the 15 significant digits users see, and the serial day numbers dates and times are stored as.
nuon
Package nuon reads and writes NUON, nushell's object notation: the text `to nuon` writes and `from nuon` reads, which keeps nushell's types (file sizes, durations, dates, binary) where JSON would turn them into numbers and strings.
Package nuon reads and writes NUON, nushell's object notation: the text `to nuon` writes and `from nuon` reads, which keeps nushell's types (file sizes, durations, dates, binary) where JSON would turn them into numbers and strings.
nushell
Package nushell runs a notebook's code cells: each is a nushell pipeline run by `nu` as a separate process, reading other cells' outputs and ranges of sheets as variables ($sales, $selection), and printing what it made as NUON, which the notebook keeps as the cell's output.
Package nushell runs a notebook's code cells: each is a nushell pipeline run by `nu` as a separate process, reading other cells' outputs and ranges of sheets as variables ($sales, $selection), and printing what it made as NUON, which the notebook keeps as the cell's output.
nushell/module
Package module holds 012.nu, the nushell module that gives 012 the command `sheet`, so nushell users needn't type `^012` (a bare 012 is a number to nushell).
Package module holds 012.nu, the nushell module that gives 012 the command `sheet`, so nushell users needn't type `^012` (a bare 012 is a number to nushell).
paged
Package paged reads linked sources in place: Parquet files and SQLite tables or queries too big for any grid, linked as tables on tabs of their own (the engine's source.go).
Package paged reads linked sources in place: Parquet files and SQLite tables or queries too big for any grid, linked as tables on tabs of their own (the engine's source.go).
room
Package room shares workbooks between the people 012 serve hosts: a room is one workbook, opened by every session that opens the same file (or joins the same named room), and each participant has a seat in it.
Package room shares workbooks between the people 012 serve hosts: a room is one workbook, opened by every session that opens the same file (or joins the same named room), and each participant has a seat in it.
serve
Package serve runs 012 as an SSH server: each session gets its own spreadsheet over its own terminal, confined to one directory.
Package serve runs 012 as an SSH server: each session gets its own spreadsheet over its own terminal, confined to one directory.
sheet
Package sheet is the spreadsheet engine: cell storage, formula parsing and dependency-ordered recalculation.
Package sheet is the spreadsheet engine: cell storage, formula parsing and dependency-ordered recalculation.
stress
Package stress builds synthetic worst-case sheets for the stress benchmarks (see docs/contributing/limits.md and `make stress`).
Package stress builds synthetic worst-case sheets for the stress benchmarks (see docs/contributing/limits.md and `make stress`).
stress/benchrec command
Command benchrec turns `go test -bench` output into run records, one JSON line per benchmark, appended to a results file that DuckDB (and ClickHouse) read; see scripts/stress and docs/contributing/observability.md.
Command benchrec turns `go test -bench` output into run records, one JSON line per benchmark, appended to a results file that DuckDB (and ClickHouse) read; see scripts/stress and docs/contributing/observability.md.
telemetry
Package telemetry records what 012 spends its time on, as structured events written with log/slog.
Package telemetry records what 012 spends its time on, as structured events written with log/slog.
ui
Package ui is the Bubble Tea front end.
Package ui is the Bubble Tea front end.
ui/choicebar
Package choicebar is a small question asked on the context line and answered with a key, the way terminal programs confirm things, e.g.
Package choicebar is a small question asked on the context line and answered with a key, the way terminal programs confirm things, e.g.
ui/cmdhelp
Package cmdhelp is a nushell command's help, F1 on a command in a notebook's cell: a scrollable box over the notebook with what the command does, a link to its page in nushell's docs, its usage, flags, parameters, input and output types and examples, as nu's help has them.
Package cmdhelp is a nushell command's help, F1 on a command in a notebook's cell: a scrollable box over the notebook with what the command does, a link to its page in nushell's docs, its usage, flags, parameters, input and output types and examples, as nu's help has them.
ui/cmdline
Package cmdline is the command line (: with vim keys, or from the palette): what's typed on the context line, with completions from the command registry in a box under it.
Package cmdline is the command line (: with vim keys, or from the palette): what's typed on the context line, with completions from the command registry in a box under it.
ui/evalview
Package evalview is Data > Evaluate formula, after Excel's Evaluate Formula: a box over the grid showing the active cell's formula with the part computed next underlined and its value below.
Package evalview is Data > Evaluate formula, after Excel's Evaluate Formula: a box over the grid showing the active cell's formula with the part computed next underlined and its value below.
ui/filterpick
Package filterpick is the values list and condition of one column of a filter, in the manner of fzf: a condition on top, then the column's values with checkboxes, narrowed by a fuzzy search as you type.
Package filterpick is the values list and condition of one column of a filter, in the manner of fzf: a condition on top, then the column's values with checkboxes, narrowed by a fuzzy search as you type.
ui/findbar
Package findbar is find and replace: a bar on the context line rather than a dialog, in the spirit of less and vim.
Package findbar is find and replace: a bar on the context line rather than a dialog, in the spirit of less and vim.
ui/formula
Package formula reads the formula being typed in the UI: the reference F4 cycles through absolute markers, and the word and function call around the caret that formula assistance follows.
Package formula reads the formula being typed in the UI: the reference F4 cycles through absolute markers, and the word and function call around the caret that formula assistance follows.
ui/lineedit
Package lineedit is the one-line text editor behind every text field of the UI.
Package lineedit is the one-line text editor behind every text field of the UI.
ui/nbview
Package nbview draws a notebook tab and takes its keys and clicks, as Jupyter does: cells one under another, a code cell's pipeline in a box with its [n]: prompt and a ▶ that runs it, its output under it after Out[n]:, and a note cell's Markdown drawn as text.
Package nbview draws a notebook tab and takes its keys and clicks, as Jupyter does: cells one under another, a code cell's pipeline in a box with its [n]: prompt and a ▶ that runs it, its output under it after Out[n]:, and a note cell's Markdown drawn as text.
ui/overlay
Package overlay is the contract between the UI's root model and the components that take over input while open: menus, pickers, bars on the context line and dialogs.
Package overlay is the contract between the UI's root model and the components that take over input while open: menus, pickers, bars on the context line and dialogs.
ui/picker
Package picker is the searchable list behind the command palette and every other picker of the UI (functions, sheets, named ranges, macros, themes, files to import): a search field on top, results below with matched characters highlighted, in the manner of fzf.
Package picker is the searchable list behind the command palette and every other picker of the UI (functions, sheets, named ranges, macros, themes, files to import): a search field on top, results below with matched characters highlighted, in the manner of fzf.
ui/review
Package review is live mode's suggestions panel (docs/agents/live.md): a box at the right of the grid listing the agents' suggestions waiting for the person, each by agent and message with the cells it would set, to accept or reject whole or cell by cell, with keys or the mouse.
Package review is live mode's suggestions panel (docs/agents/live.md): a box at the right of the grid listing the agents' suggestions waiting for the person, each by agent and message with the cells it would set, to accept or reject whole or cell by cell, with keys or the mouse.
ui/rowtext
Package rowtext lays out the text of one row of cells across the columns on screen, as Sheets does: values formatted and aligned, text running on into blank neighbors, cut to column boundaries in a single pass.
Package rowtext lays out the text of one row of cells across the columns on screen, as Sheets does: values formatted and aligned, text running on into blank neighbors, cut to column boundaries in a single pass.
ui/rules
Package rules is the side panel for a sheet's rules, as Sheets' Conditional formatting and Data validation sidebars: a list of the rules, and a form to add or edit one.
Package rules is the side panel for a sheet's rules, as Sheets' Conditional formatting and Data validation sidebars: a list of the rules, and a form to add or edit one.
ui/shortcuts
Package shortcuts is the keyboard shortcuts view: a scrollable box over the grid listing every key by what it does, in two columns when the screen is wide enough.
Package shortcuts is the keyboard shortcuts view: a scrollable box over the grid listing every key by what it does, in two columns when the screen is wide enough.
ui/sortbar
Package sortbar is the bar that picks the columns and order to sort a range by, as Sheets' "Advanced range sorting options" dialog, on the context line.
Package sortbar is the bar that picks the columns and order to sort a range by, as Sheets' "Advanced range sorting options" dialog, on the context line.
ui/srcview
Package srcview is a linked source's tab: a window of the source's rows drawn as a sheet with a frozen header row, the row numbers and a scrollbar over the whole source, however many millions of rows it has.
Package srcview is a linked source's tab: a window of the source's rows drawn as a sheet with a frozen header row, the row numbers and a scrollbar over the whole source, however many millions of rows it has.
ui/suggest
Package suggest is formula assistance, as in Sheets: while a function, range or sheet name is being typed, a list of matching functions, named ranges and other sheets drops down from the formula bar at the caret, and while the caret is inside a function's parentheses the context line shows its signature with the current argument marked.
Package suggest is formula assistance, as in Sheets: while a function, range or sheet name is being typed, a list of matching functions, named ranges and other sheets drops down from the formula bar at the caret, and while the caret is inside a function's parentheses the context line shows its signature with the current argument marked.
ui/tabstrip
Package tabstrip is the sheet tabs at the left of the status line, the way tmux lists windows: the sheet shown is highlighted, a + adds a sheet, and when the tabs don't all fit, ‹ and › step through them.
Package tabstrip is the sheet tabs at the left of the status line, the way tmux lists windows: the sheet shown is highlighted, a + adds a sheet, and when the tabs don't all fit, ‹ and › step through them.
ui/theme
Package theme is the look of the UI: the style roles every view draws with, and the small widgets built from them (framed boxes, key chips, key hints).
Package theme is the look of the UI: the style roles every view draws with, and the small widgets built from them (framed boxes, key chips, key hints).
ui/themepicker
Package themepicker is File > Settings > Theme: every theme in a picker, fuzzy searched by name, narrowed to one kind by a search starting with "dark" or "light".
Package themepicker is File > Settings > Theme: every theme in a picker, fuzzy searched by name, narrowed to one kind by a search starting with "dark" or "light".
ui/transfer
Package transfer runs imports in the background and draws their progress: the mode indicator says WAIT, the context line offers Esc, the status line counts rows with a progress bar, and the terminal shows its own progress indicator.
Package transfer runs imports in the background and draws their progress: the mode indicator says WAIT, the context line offers Esc, the status line counts rows with a progress bar, and the terminal shows its own progress indicator.
value
Package value holds what a cell computes to and how it is shown: the Value of a cell, its number Format, and the parsing of typed text into numbers, dates and times.
Package value holds what a cell computes to and how it is shown: the Value of a cell, its number Format, and the parsing of typed text into numbers, dates and times.
scripts
doccheck command
Command doccheck keeps the documentation's structure sound, where a machine can tell:
Command doccheck keeps the documentation's structure sound, where a machine can tell:
doclint command
Command doclint keeps documentation about the code as it is.
Command doclint keeps documentation about the code as it is.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL