Spreadsheets you can verify

A spreadsheet engine for your terminal. Run formulas against data files, reconcile datasets, replay provenance scripts, and convert between formats.

brew install --cask visigrid/tap/visigrid

vgrid is included with every download

Fingerprint & verify

Same inputs + same formulas = same hash. Change one cell and the fingerprint changes. Revert it and the fingerprint returns.

Terminal
$ vgrid sheet fingerprint model.sheet
v1:24:8f3a1c9e7b2d4a06
$ vgrid sheet fingerprint model.sheet # after changing one input
v1:24:d1e5f8a2c7b39014 # different
$ vgrid sheet fingerprint model.sheet # after reverting
v1:24:8f3a1c9e7b2d4a06 # same
$ vgrid sheet verify model.sheet --fingerprint v1:24:8f3a1c9e7b2d4a06
Verified ✓

Commands

calc

Run formulas against data

Evaluate spreadsheet formulas on piped data. Supports all 96+ built-in functions.

Sum a column from a CSV file
$ cat revenue.csv | vgrid calc "=SUM(A:A)" --from csv
142850
Conditional sum with headers
$ cat sales.csv | vgrid calc "=SUMIF(B:B, \">1000\", C:C)" --from csv
34850
Array formula with spill output
$ cat data.csv | vgrid calc "=FILTER(A:A, B:B>10)" --from csv --spill json
[42, 98450, 1200]
diff

Reconcile two datasets

Compare two files by key column. Shows matched rows, rows only in left/right, and deltas with configurable tolerance.

Diff by key with JSON output
$ vgrid diff before.csv after.csv --key name --out json
{"matched":47,"only_left":2,"only_right":1,"delta":[{"name":"Alice","field":"amount","old":1200,"new":1350}]}
With tolerance for floating point
$ vgrid diff q3.csv q4.csv --key sku --tolerance 0.01
matched: 142 only_left: 3 only_right: 7 changed: 28
replay

Execute and verify provenance

Run Lua provenance scripts that record every edit made in VisiGrid. Verify that the output matches a known fingerprint for auditability.

Replay and verify
$ vgrid replay audit-trail.lua --verify
Replayed 12 operations
Fingerprint: v1:12:f2126a5f...
Verification: PASS (matches expected)
Replay to stdout
$ vgrid replay changes.lua -o - -f csv
SKU,Product,Price,Qty
W-100,Widget,9.99,100
...
convert

Filter, project, transform

Read CSV, TSV, JSON, XLSX, and .sheet files. Filter rows with --where, select and reorder columns with --select, write CSV, TSV, JSON, .sheet.

Select columns and pipe into diff
$ vgrid convert vendor.xlsx -t csv --headers --select 'Invoice,Amount' | \
vgrid diff - ours.csv --key Invoice --tolerance 0.01
matched: 14238 only_left: 2 value_diff: 3
Filter rows, then project columns
$ vgrid convert data.csv -t csv --headers \
--where 'Status=Pending' --select 'Amount,Vendor'
Amount,Vendor 150,CloudCo 0,CloudCo
XLSX to JSON with headers
$ vgrid convert data.xlsx -t json --headers --select 'Status,Amount'
[{"status":"Active","amount":1200},{"status":"Pending","amount":850}]
Pipe JSON to CSV
$ curl -s api.example.com/data | vgrid convert --from json -t csv
name,amount Alice,1200 Bob,850
peek

Terminal data inspector

View CSV and TSV files directly in the terminal. Interactive TUI with cursor navigation, column packing, and horizontal scroll. Or use --plain for scriptable output.

Interactive TUI viewer
$ vgrid peek sales.csv --headers
visigrid: sales.csv | 50 rows x 4 cols
Name Revenue Quarter Region
2 Alice 12345 Q1 East
>3 >Bob 9876 Q1 West
4 Charlie 5432 Q2 East
File shape for scripts (no TUI)
$ vgrid peek huge.csv --shape --headers
rows: 103221 loaded: 5000 cols: 12 headers: yes
Plain table to stdout
$ vgrid peek data.csv --headers --plain --max-rows 3
Name Amount Status ------------------------------- 2 Alice 1200 Active 3 Bob 850 Pending 4 Carol 2100 Active
list-functions

List available functions

Print all 96+ built-in spreadsheet functions. The same engine that powers the desktop app.

List all functions
$ vgrid list-functions | head -5
ABS ACOS AND AVERAGE AVERAGEIF
sessions

Control a running GUI

Inspect cells, apply changes, and watch state evolve — all from scripts. TCP localhost with token auth.

Inspect a cell
$ visigrid inspect A1
A1 = 1234.56 (number)
Apply operations atomically
$ cat ops.jsonl | visigrid apply --atomic --wait
Applied 3 operations (revision 42 → 45)
View grid snapshot
$ visigrid view --range A1:C3
| A | B | C 1 | Name | Qty | Price 2 | Widget | 100 | 9.99 3 | Gadget | 50 | 24.50

Provenance

Every edit in VisiGrid can generate a Lua provenance script — a complete, ordered record of what changed and when. These scripts are plain text, version-control friendly, and replayable.

audit-trail.lua
-- api=v1
-- VisiGrid Provenance Script
-- Expected fingerprint: v1:6:b38b632d7f38dedf...

grid.set{ sheet=1, cell="A1", value="Revenue" }
grid.set{ sheet=1, cell="A2", value="42850" }
grid.set{ sheet=1, cell="A3", value="38100" }
grid.set{ sheet=1, cell="A4", value="29400" }
grid.set{ sheet=1, cell="B1", value="Total" }
grid.set{ sheet=1, cell="B2", value="=SUM(A2:A4)" }

Use vgrid replay --verify to re-execute the script and confirm the output matches the recorded fingerprint. If anyone changed the source data or the script, verification fails.

Install

The CLI is included with every VisiGrid download. Install the app and you get both.

macOS brew install --cask visigrid/tap/visigrid
Windows winget install VisiGrid.VisiGrid
Linux yay -S visigrid-bin