README.md / complete reference
Documentation
Install JotMD, learn the keyboard-first terminal workflow, configure your vault, automate safe note updates, and give supported coding agents durable Markdown memory.
Requirements
The Homebrew package is the shortest path on macOS or Linux. Building from source requires Go 1.26 or newer and just.
JotMD opens notes in the editor chosen by --editor, then $JOTMD_EDITOR, configuration, $EDITOR, and finally vi.
Installation
Homebrew
brew install gonfff/tap/jotmd
Build from source
git clone https://github.com/gonfff/jotmd.git
cd jotmd
just install
just install writes the binary to ~/.local/bin/jotmd.
Quick start
Run JotMD once. On first launch it asks where your notes live, creates the directory if needed, and stores the choice in the JotMD configuration directory.
jotmd
To skip the prompt, create a vault and pass it explicitly:
mkdir -p ~/vault
jotmd --notes-dir ~/vault
Layout & focus
The main screen keeps a directory tree beside a wrapping Markdown preview. Select a Markdown file to render it; expand directories in place and press Tab to move focus between the tree, table of contents, and preview.
The bottom status line shows the current note and context-sensitive help. Press ? to see all effective bindings or Shift+P to open the command palette.
Working with notes
JotMD works directly with directories and .md files. There is no database or import format, so Git, sync tools, scripts, and other editors can use the same vault.
- Create notes and directories with n and N.
- Edit the selected note with e.
- Rename, copy, move, trash, restore, or permanently delete items through the command palette.
- Reload notes, configuration, and key bindings without restarting the TUI.
Permanent deletion cannot be undone. Prefer the trash action unless the file must be removed immediately.
Search & views
Press / to search note names and contents. Results retain the live preview, so you can evaluate matches without leaving the search flow.
Markdown headers appear in a table of contents. Use Tab to focus it and jump between sections. A raw view is also available when you need the underlying Markdown rather than the rendered preview.
Key bindings
| Context | Key | Action | Config key |
|---|---|---|---|
| Tree | k / ↑ | Move up | tree.up |
| Tree | j / ↓ | Move down | tree.down |
| Tree | Home | Jump to first item | tree.first |
| Tree | End | Jump to last item | tree.last |
| Tree | h / ← | Collapse directory | tree.collapse |
| Tree | l / → | Expand directory | tree.expand |
| Tree | Backspace | Go to parent directory | tree.parent |
| Tree | Enter / Space | Open note or toggle directory | tree.open |
| Notes | e | Edit selected note | note.edit |
| Notes | n | Create note | note.new |
| Notes | N | Create directory | directory.new |
| Notes | r | Rename selected item | note.rename |
| Notes | c | Copy selected item | note.copy |
| Notes | m | Move selected item | note.move |
| Notes | d | Move selected item to trash | note.trash |
| Notes | D | Permanently delete selected item | note.delete |
| Application | Tab | Cycle focus | app.focus |
| Application | R | Reload notes, configuration, and key bindings | app.reload |
| Application | ? | Open help | app.help |
| Application | t | Open theme selector | theme.select |
| Application | / | Open search | search.open |
| Application | Shift+P | Open command palette | app.palette |
| Preview | v | Toggle rendered and raw Markdown | preview.raw |
| Preview | w | Toggle line wrapping | preview.wrap |
| Preview | s | Cycle render style | preview.style |
| Application | a | Show or hide agent memory | view.agent_memory |
| Application | q | Quit | app.quit |
| Help | Esc | Close help | help.close |
| Theme selector | ↑ / Ctrl+P | Previous theme | theme.up |
| Theme selector | ↓ / Ctrl+N | Next theme | theme.down |
| Theme selector | Enter | Apply theme | theme.apply |
| Theme selector | Esc | Close without applying | theme.close |
Bindings are configurable in ~/.config/jotmd/keybindings.toml. Each entry replaces the defaults for that action. Print the effective bindings with:
jotmd --dump-keys
Configuration
CLI flags override environment variables, which override config.toml and built-in defaults. Configuration lives under ~/.config/jotmd/, or $XDG_CONFIG_HOME/jotmd/ when that variable is set.
config.toml | CLI flag | Environment | Default | What it does |
|---|---|---|---|---|
notes_dir | --notes-dir PATH | JOTMD_NOTES_DIR | ~/vault | Directory containing the Markdown vault. |
editor | --editor COMMAND | JOTMD_EDITOR, EDITOR (fallback) | vi | Command used to edit notes. |
theme | --theme NAME | JOTMD_THEME | jotmd | Bundled or custom theme name. |
theme_colors | --theme-colors COLORS | JOTMD_THEME_COLORS | — | Overrides individual semantic colors in the active theme. |
tree_width | --tree-width PERCENT | JOTMD_TREE_WIDTH | 20 | Tree width percentage from 1 to 100; the rendered pane is clamped to 24–48 columns. |
no_color | --no-color | JOTMD_NO_COLOR, NO_COLOR | false | Disables color output. Any non-empty NO_COLOR also enables it. |
show_hidden | --show-hidden | JOTMD_SHOW_HIDDEN | false | Includes hidden files and directories. |
show_agent_memory | --show-agent-memory | JOTMD_SHOW_AGENT_MEMORY | false | Shows the reserved agent-memory tree at startup. |
ignore | --ignore LIST | JOTMD_IGNORE | [".obsidian", ".git"] | Names excluded from the vault tree. CLI and environment values use the OS path-list separator. |
sort | --sort ORDER | JOTMD_SORT | name | Sort order. Currently only name sorting is supported. |
directories_first | --directories-first | JOTMD_DIRECTORIES_FIRST | true | Keeps directories before notes; currently must remain enabled. |
status_bar | --status-bar | JOTMD_STATUS_BAR | true | Shows the bottom status bar. |
watch | --watch | JOTMD_WATCH | true | Reloads the vault when files change on disk. |
preview.wrap | --preview-wrap | JOTMD_PREVIEW_WRAP | true | Wraps long lines in the preview. |
preview.render_style | --preview-render-style STYLE | JOTMD_PREVIEW_RENDER_STYLE | quiet | Markdown style: quiet, surface, or structural. |
preview.max_bytes | --preview-max-bytes BYTES | JOTMD_PREVIEW_MAX_BYTES | 2097152 | Largest note rendered in preview, up to 67108864 bytes. |
Boolean environment values accept forms such as true/false and 1/0; boolean CLI flags also accept explicit values such as --watch=false. Theme color overrides use a TOML inline table such as { accent = "#77AD91" }. Generate templates, inspect the effective result, or validate a file with:
jotmd --init-config
jotmd --dump-config
jotmd config check
jotmd config check /path/to/config.toml
Themes
JotMD ships with 11 themes. Press t in the TUI to select one, or set theme in config.toml.
Use a bundled theme
jotmd --list-themes
jotmd --theme catppuccin-mocha
Create a custom theme
Export the bundled themes, copy one, and edit it. Existing files are never overwritten by --init-themes. The filename becomes the theme name used by --theme.
jotmd --init-themes
cp ~/.config/jotmd/themes/jotmd.toml \
~/.config/jotmd/themes/my-theme.toml
If XDG_CONFIG_HOME is set, use $XDG_CONFIG_HOME/jotmd/themes/ instead. A complete theme defines its Markdown syntax style and every semantic palette color:
name = "my-theme"
syntax_style = "rose-pine"
[palette]
foreground = "#E9E2D5"
muted = "#6E6E6B"
border = "#45504A"
border_focus = "#77AD91"
selection_background = "#77AD91"
selection_foreground = "#101512"
accent = "#77AD91"
directory = "#E1B866"
heading = "#E1B866"
link = "#7FA8B8"
code = "#D88762"
status = "#77AD91"
background is optional. Colors use hexadecimal notation. Unknown fields, missing required colors, and unsupported syntax styles are rejected.
jotmd --dump-theme my-theme
jotmd --theme my-theme
Override a few colors
For a small adjustment, keep the base theme and override only selected semantic colors in config.toml:
theme = "jotmd"
theme_colors = { accent = "#CBA6F7", heading = "#F9E2AF" }
CLI
The CLI can launch the TUI, inspect configuration, manage themes, or work with notes non-interactively while Markdown files remain the source of truth.
General commands
| Command | What it does |
|---|---|
jotmd | Open the interactive TUI. |
jotmd --help | Print command and option help. |
jotmd --version | Print the installed version. |
jotmd --init-config | Create missing configuration and key-binding templates. |
jotmd --init-themes | Export missing bundled themes for customization. |
jotmd --list-themes | List available bundled and custom themes. |
jotmd --dump-theme NAME | Print one effective theme as TOML. |
jotmd --dump-config | Print the effective configuration. |
jotmd --dump-keys | Print the effective key bindings. |
jotmd config check [PATH] | Validate configuration, key bindings, editor, and theme. |
Note commands
jotmd [--notes-dir PATH] search [--limit N] QUERY [--json]
jotmd [--notes-dir PATH] get PATH [--json]
jotmd [--notes-dir PATH] write [--if-revision REVISION] PATH [--json]
jotmd [--notes-dir PATH] delete --if-revision REVISION PATH [--json]
| Command | What it does | Options |
|---|---|---|
search QUERY | Search note paths and contents. | --limit N accepts 1–200 and defaults to 20; --json returns structured results. |
get PATH | Read an exact note and its revision. | --json returns content and metadata. |
write PATH | Read content from stdin and create or update a note. | Existing notes require --if-revision REVISION; --json returns metadata. |
delete PATH | Permanently delete one note. | --if-revision REVISION is required; --json returns metadata. |
Safe updates
write without --if-revision creates a missing note and refuses to overwrite an existing one. To update safely, read the current revision and send it back:
jotmd --notes-dir ./notes search "refresh token redis" --json
jotmd --notes-dir ./notes get projects/foo/pitfalls.md --json > /tmp/note.json
jq -rj '.content' /tmp/note.json > /tmp/note.md
revision=$(jq -r '.revision' /tmp/note.json)
# Edit /tmp/note.md, then update only if the note is unchanged.
jotmd --notes-dir ./notes write projects/foo/pitfalls.md \
--if-revision "$revision" < /tmp/note.md
delete applies the same revision check and permanently removes one note. With --json, successes use stdout and errors use stderr.
Agent memory
The optional jot-memory skill lets Codex, Claude Code, and OpenCode recall and maintain durable Markdown notes through the JotMD CLI. The agent decides when substantial work needs recall and whether its result is useful enough to preserve.
Prerequisite
Install JotMD, confirm it is on PATH, and run it once to select the vault used by both the TUI and agents:
brew install gonfff/tap/jotmd
command -v jotmd
jotmd
Agent-managed notes live below a reserved top-level directory:
agent-memory/
├── global/
└── projects/<project-id>/
Reserved directory. Before enabling the integration, move unrelated user content out of agent-memory/ or explicitly adopt it as agent-managed memory. Case variants are rejected.
JotMD hides this tree by default. Press a to show or hide it, or set show_agent_memory = true in config.toml to show it at startup.
Agent memory: Codex
Install
codex plugin marketplace add gonfff/jotmd
codex plugin add jot-memory@jotmd
Start a new Codex thread so the skill is loaded. Use codex plugin list to inspect the configured marketplace and plugin.
Update
brew upgrade jotmd
codex plugin marketplace upgrade jotmd
codex plugin add jot-memory@jotmd
Remove
codex plugin remove jot-memory@jotmd
codex plugin marketplace remove jotmd
Agent memory: Claude Code
Install
claude plugin marketplace add gonfff/jotmd
claude plugin install jot-memory@jotmd
Restart Claude Code after installation or update. Use claude plugin list to verify the plugin.
Update
brew upgrade jotmd
claude plugin marketplace update jotmd
claude plugin update jot-memory@jotmd
Remove
claude plugin uninstall jot-memory@jotmd
claude plugin marketplace remove jotmd
Agent memory: OpenCode
OpenCode discovers global skills under ~/.config/opencode/skills/<name>/SKILL.md. Keep a shallow checkout and link the skill so updates remain one command.
Install
git clone --depth 1 https://github.com/gonfff/jotmd.git ~/.local/share/jotmd
mkdir -p ~/.config/opencode/skills
ln -s ~/.local/share/jotmd/skills/jot-memory \
~/.config/opencode/skills/jot-memory
Update
brew upgrade jotmd
git -C ~/.local/share/jotmd pull --ff-only
Remove
unlink ~/.config/opencode/skills/jot-memory
Restart OpenCode after installation or update.
Verify agent memory
Start a new agent session in a Git repository and ask it to perform substantial research or implementation. The agent should consider memory before the work and report every memory note it changes afterward. Trivial requests intentionally skip memory.
Memory is ordinary Markdown: you can inspect and edit it directly, and JotMD can reveal it in the same vault when needed.
Development
just run # run from the checkout
just build # build bin/jotmd
just test # run tests
just check # format check, vet, and tests
Source code, releases, and issue tracking live on GitHub. JotMD is distributed under the MIT License.