NoteFlow · CLI reference

Your notes,
headless.

The whole notebook from any terminal — a single Node.js script, zero dependencies, same files as the desktop app.

pi@homelab: ~
~ $ noteflow --helpNoteFlow CLI — quick notes from your terminalusage: noteflow <command> [options]  add · new · list · get · read · set  sections · section · move · groups · folders  login · push · pull · migrate · self-update · status~ $ noteflow add "It works." --section Ideas✓ Added to "07-07-2026" · Ideas
01 / install

One script, zero dependencies

The NoteFlow CLI is a single standalone Node.js script — cli/noteflow.js, no npm packages. It reads and writes the same files as the desktop app: same notes directory, same format, no daemon in between. That makes it perfect for servers, Raspberry Pis and any box without a screen.

Linux / Raspberry Pi (headless)

install
$ curl -fsSL https://raw.githubusercontent.com/yagoid/noteflow/main/cli/install-cli.sh | sudo bash

Linux desktop / Windows

Nothing to do — the CLI installs automatically with NoteFlow’s .deb and .exe desktop installers.

Only requirement: Node.js ≥ 18. To update a standalone install later, run noteflow self-update.

02 / notes dir

Where your notes live

The CLI operates directly on the NoteFlow notes directory — plain files on your disk, no database:

PlatformPath
Linux ~/.local/share/noteflow-notes/
Windows / macOS ~/noteflow-notes/

The NOTEFLOW_NOTES_DIR environment variable points the CLI at a different directory — useful for scripting and testing against a sandbox.

03 / format

Note format (v2 — folder per note)

Every note is a directory named <slug>-<id>/ holding a note.md (frontmatter only: metadata + section index) and one .md file per section (pure markdown):

noteflow-notes/
project-alpha-abc12345/  note.md       ← metadata anchor + section index  sec001.md     ← body of section "Note"  sec002.md     ← body of section "Tasks"
  • Each section’s content lives in its own <sectionId>.md — no frontmatter, just markdown.
  • The updated: field in note.md is the canonical sync timestamp for the whole note.
  • isRawMode: true means raw/markdown mode; false means rich text (TipTap HTML).
  • Notes with an encryption: block in note.md are encrypted (the folder only contains note.md) — the CLI ignores them.
  • A .noteflow-format marker file (containing 2) at the root of the notes directory flags the v2 format.

Coming from the old flat v1 layout? A single noteflow migrate converts everything — see the commands table.

04 / commands

Command reference

Everything is addressed by name: note titles plus section names — you never touch ids. Titles can be partial (on multiple matches the CLI lists them and asks for precision), and duplicate section names are targeted with a 1-based suffix like "Tasks#2". Quote names containing spaces.

Notes

CommandWhat it does
noteflow add <text> [options]

Append text to today’s daily note (title DD-MM-YYYY) — or to any note via --title. Creates the note if it doesn’t exist; the text is appended to the end of the section, separated by a newline.

--title <title>
Write into the note with that title instead of today’s.
--section <name>
Target section/tab. Created if missing. Default: Note.
--tag <tag>
Add this tag to the note (if it doesn’t have it yet).
--group <name>
Assign the note to a group.
--folder <name>
Place the note in a folder of that group (requires --group).
--raw / --rich
New section in raw/markdown mode (default) or rich text.
$ noteflow add "Fix: CORS on /api/notes"$ noteflow add "Check server logs" --section Tasks --tag urgent
noteflow new <title> [options]

Create an empty note.

--section <name>
Name of the first section. Default: Note.
--group <name>
Assign to a group.
--folder <name>
Place in a folder of that group (requires --group).
--json
Print { id, title, dirname } as JSON.
$ noteflow new "Sprint 14" --group backend --section Planning
noteflow list [options]

List notes sorted by updated desc. Archived notes are excluded by default.

--tag <tag>
Filter by tag.
--group <name>
Filter by group.
--folder <name>
Filter by folder (disambiguate with --group if the name repeats).
--archived
Include archived notes.
--json
JSON array with full metadata per note (id, title, tags, group, folder, dates, sections…).
$ noteflow list --tag urgent --json
noteflow get <title> [options]

Pretty-print a note for humans (indented, decorated). The title can be partial — on multiple matches it lists them and asks for more precision. For piping or agents, use read instead.

--section <name>
Show only that section.
--json
Full JSON with every section and its content.
noteflow read <title> [section]

Print content verbatim to stdout — no indentation, no decoration. The recommended way to read a section for pipes and agents. Duplicate section names are addressed with a 1-based suffix, e.g. "Tasks#2".

--section <name>
Flag form of the positional section (handy with multi-word titles).
--json
JSON with every section (or just one if targeted).
$ noteflow read "Project Alpha" Tasks$ noteflow read "Project Alpha" --json | jq '.sections[].name'
noteflow set <title> <section> [source] [--rich]

Replace a section’s content (creating it if missing) — the complement of add, which only appends. The recommended way to edit a section. On ambiguous duplicate names without a #n suffix, it fails instead of guessing.

--text "<content>"
Inline text (first source present wins).
--file <path>
Read the content from a file — the most reliable route on Windows/PowerShell.
--stdin
Read from stdin (also used automatically when piped).
--rich
If the section is created, create it in rich-text mode (default: raw).
$ noteflow set "Project Alpha" Tasks --text "- [ ] deploy"$ cat todo.md | noteflow set "Project Alpha" Tasks --stdin
noteflow delete <title> [--yes]

Delete a note (alias: rm). Asks for confirmation unless --yes. With sync active it also removes it from the GitHub repo.

noteflow rename <current-title> <new-title>

Update the note’s title field. The folder name on disk doesn’t change (it contains the id).

noteflow favorite <title>

Toggle the favorited flag (alias: pin). The desktop app shows favorites at the top of the list.

noteflow archive <title>

Toggle the archived state. Archived notes don’t show in list unless --archived.

Sections

CommandWhat it does
noteflow sections <title>

List a note’s sections with name, line count and mode (raw/rich). section list is an alias.

noteflow section add <title> <name> [--rich]

Create an empty section (raw by default; --rich for rich text). Sections are managed by name — no ids needed.

$ noteflow section add "Project Alpha" "Meeting Notes"
noteflow section rename <title> <old> <new>

Rename a section (the file on disk doesn’t change — it’s addressed by id).

noteflow section delete <title> <name> [--yes]

Delete a section (confirmation unless --yes). Refuses to delete the last one. Disambiguate duplicates with "Tasks#2".

Organization

CommandWhat it does
noteflow move <title> --group <g> [--folder <f>]

Move a note between groups and folders — the CLI equivalent of the app’s drag-and-drop. --group alone moves it to the group root (clearing the folder); --ungroup takes it out of both.

$ noteflow move "Sprint 14" --group backend --folder Planning$ noteflow move "Sprint 14" --ungroup
noteflow groups [--json]

List groups.

noteflow group create <name> [--color <color>]

Create a group. Colors: accent (default), accent-2, red, cyan, purple, text, orange, pink.

$ noteflow group create backend --color cyan
noteflow group delete <name> [--yes]

Delete a group. Its notes are left ungrouped (not deleted). Its folders are deleted too — folders only exist inside a group.

noteflow folders [--group <g>] [--json]

List folders — all of them grouped by group, or only one group’s with --group.

noteflow folder create <name> --group <g>

Create a folder. --group is required — a folder can’t exist outside a group.

$ noteflow folder create Planning --group backend
noteflow folder rename <name> <new-name> [--group <g>]

Rename a folder. Use --group to disambiguate if the name repeats across groups.

noteflow folder delete <name> [--group <g>] [--yes]

Delete a folder. Its notes fall to the group root (they keep the group, lose the folder) — nothing is deleted.

GitHub sync

CommandWhat it does
noteflow login [repo-name]

Connect to GitHub via Device Flow OAuth — it prints a code and a URL to authorize from any browser (perfect for headless boxes). Default repo: noteflow-notes. The CLI keeps its own token, separate from the desktop app’s.

noteflow logout

Disconnect from GitHub.

noteflow push

Upload every note to the repo.

noteflow pull

Download notes from the repo (alias: update). Only overwrites a local note when the remote updated timestamp is newer.

Maintenance

CommandWhat it does
noteflow migrate

One-time migration from the flat v1 layout (<slug>-<id>.md) to the v2 folder-per-note format. Writes the .noteflow-format marker and, with an accessible sync token, pushes the new layout and removes the flat files from the remote. Idempotent — the desktop app runs the same local migration on startup.

noteflow self-update

Download the latest cli/noteflow.js from GitHub and replace the current script. Uses the public repo API — no sync login needed. Handy on a headless RPi with no installer.

noteflow status [--json]

Show note count, notes directory, groups, GitHub state and last sync. JSON shape: { notesDir, noteCount, github: { owner, repo, lastSync, tokenAccessible }, groups }.

noteflow help [command]

General help, or detailed help for one command (help new, help folder…).

05 / flags

Global flags, colors & env vars

A few flags repeat across commands with the same meaning everywhere:

FlagApplies toDescription
--json list · get · read · new · groups · folders · status Machine-readable JSON output.
--yes delete · group delete · folder delete · section delete Skip the interactive confirmation.
--archived list Include archived notes.
--section <name> read · get · add · set Target a section by name.
--group <name> add · new · move · list · folders · folder * Target / filter by a group.
--folder <name> add · new · move · list Target / filter by a folder (requires a group).
--ungroup move Take the note out of its group and folder.
--text / --file / --stdin set Source of the content to write (first one present wins).
--rich add · set · section add Create the new section in rich-text mode (default: raw).

Group colors

The palette accepted by group create --color — the same color tokens the desktop app uses for group dots and note accents:

accentaccent-2redcyanpurpletextorangepink

Environment variables

VariableEffect
NOTEFLOW_NOTES_DIR Redirect the notes directory (scripting / testing).
NOTEFLOW_NO_APP_CHECK Set to 1 to silence the stderr warning when mutating groups/folders while the desktop app is running.
06 / agents

A tool built for AI agents

The CLI is deliberately agent-friendly: every read command takes --json for machine-readable output, results go to stdout and errors to stderr, and the exit code is 0 on success, 1 on error. Since everything is addressed by note title and section name, an agent never needs to track ids.

Two conventions matter: read vs getget is for humans (indented, decorated) while read emits content verbatim, so agents should always use read. And set vs addset replaces a section, add appends to it.

Typical agent flow

agent session
# 1 · discover notes and section names$ noteflow list --json# 2 · read one section, raw (pipe-safe)$ noteflow read "Project Alpha" "Tasks"# 3 · overwrite it — or append with `add`$ noteflow set "Project Alpha" "Tasks" --text "- [x] deploy"# 4 · sync$ noteflow push

Install the skill

Running Claude Code or another skills-compatible agent? Install the NoteFlow CLI skill and your agent gets the full command reference, gotchas included:

skills
$ npx skills add yagoid/noteflow/cli/noteflow-cli
07 / caveats

Caveats worth knowing

Desktop app open ⇒ group/folder changes can be lost

The app keeps groups.json / folders.json in memory and rewrites them on its own cycles (saves and the 5-minute auto-sync), overwriting groups and folders created from the CLI while it runs. Note-level changes — content, sections, favorite, archive — do survive: they live in per-note folders. The CLI warns on stderr when it detects NoteFlow running while you mutate groups/folders (silence it with NOTEFLOW_NO_APP_CHECK=1). For reliable structural changes, close the app first — or make them in the app.

PowerShell: multiline --text can truncate silently

On Windows/PowerShell, passing --text with newlines may be truncated to the first line without warning. For anything beyond a single line use --file <path> (the most reliable route) or --stdin. Rule of thumb: non-trivial content → --file.

BOM on --stdin

PowerShell prepends a BOM to pipes and here-strings; the CLI strips it automatically, so piped content arrives clean.

08 / troubleshooting

Troubleshooting

“noteflow: command not found”
The headless install script places the CLI at /usr/local/bin/noteflow — make sure that’s on your PATH. On desktop it ships with the .deb / .exe installers; open a fresh terminal after installing.
I’m logged in in the app, but the CLI asks me to log in
Expected: the CLI can’t decrypt tokens the desktop app stores with Electron’s safeStorage. It keeps its own token — run noteflow login once.
A note doesn’t show up in list / read
Encrypted notes (an encryption: block in note.md) are ignored by every read command, by design. Decrypt the note in the desktop app if you need CLI access to it.
My CLI-made groups or folders vanished / pull didn’t change anything
Two sync rules: the desktop app’s auto-sync rewrites groups.json / folders.json while it runs (see caveats), and pull only overwrites a local note when the remote updated: timestamp is newer. Close the app for structural changes, and check noteflow status for the last sync.