Patches

A patch is the graph plus the workspace it was saved with. A .gfi is a zip holding both.

LslIn py
out
Filter rs
input
out
Psd rs
input
out
Fooof py
psd
aperiodic
peaks

An LSL stream, filtered, its spectrum viewed, and a FOOOF fit off the same spectrum. Every node here is one goofi ships.

A .gfi is an archive

A .gfi is a zip holding the manifest beside the workspace tree it was saved with, so a patch that grew its own nodes carries them. Loading one extracts into a fresh mount, parses, and only then swaps in the graph and the workspace together, so a patch that fails to parse leaves the current one untouched.

goofi session save patches/eeg-bands.gfi
goofi session manifest              # the same patch as YAML, diffable

When the backend is not on your machine

The Save and Open dialogs each have a second option, Download a copy and Open from this computer…, which pass the .gfi through the browser instead of the backend. Both are copies: the patch's remembered file is left alone, so Ctrl+S never silently retargets to a download.

Undo is exact

A write op is undoable and may ride in a batch; an effect runs alone. Undo and redo carry exact inverses and are filtered per session, so two people editing one patch each undo only their own work.

goofi - reads ops from stdin and applies them as one batch, so the whole batch is a single undo step.

goofi - <<'OPS'
node add Buffer
node add Psd
link add buffer.out psd.data
OPS

Sub-patches

Grouping nodes makes a sub-patch, and it talks to the patch around it through boundary ports. One nodes map carries leaves, sub-patch facades and boundary ports alike, each naming its scope, and a port's inner wire is in links like any other cable, so the API describes a sub-patch with the same two maps it uses for everything else.

This reference describes goofi 3.1.0(537cd394), generated from a running instance on 2026-09-06.