Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
178 changes: 126 additions & 52 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,40 @@
# NotesMD CLI

> **Note**: With the release of the official Obsidian CLI., this project has been renamed from "Obsidian CLI" to "NotesMD CLI" to avoid confusion. NotesMD CLI works **without requiring Obsidian to be running**, making it perfect for scripting, automation, and terminal-only environments.
> **Note**: With the release of the official Obsidian CLI, this project has been renamed from "Obsidian CLI" to "NotesMD CLI" to avoid confusion. NotesMD CLI works **without requiring Obsidian to be running**, making it perfect for scripting, automation, and terminal-only environments.

---

## Table of Contents

- [Description](#description)
- [Install](#install)
- [Windows](#windows)
- [Mac and Linux](#mac-and-linux)
- [Arch Linux (AUR)](#arch-linux-aur)
- [Build from Source](#build-from-source)
- [Headless / No Obsidian Installed](#headless--no-obsidian-installed)
- [Migrating from Obsidian CLI](#migrating-from-obsidian-cli)
- [Usage](#usage)
- [Help](#help)
- [Editor Flag](#editor-flag)
- [Add Vault](#add-vault)
- [Remove Vault](#remove-vault)
- [List Vaults](#list-vaults)
- [Set Default Vault and Open Type](#set-default-vault-and-open-type)
- [Open Note](#open-note)
- [Daily Note](#daily-note)
- [Search Note](#search-note)
- [Search Note Content](#search-note-content)
- [List Vault Contents](#list-vault-contents)
- [Print Note](#print-note)
- [Create / Update Note](#create--update-note)
- [Move / Rename Note](#move--rename-note)
- [Delete Note](#delete-note)
- [Frontmatter](#frontmatter)
- [Deprecated Commands](#deprecated-commands)
- [Excluded Files](#excluded-files)
- [Contribution](#contribution)
- [License](#license)

---

Expand Down Expand Up @@ -62,12 +96,35 @@ go build -o notesmd-cli .
sudo install -m 755 notesmd-cli /usr/local/bin/
```

### Headless / No Obsidian Installed
### Headless / No Obsidian Installed

If you're running on a headless server or don't have Obsidian installed (e.g., server environments, containers, or systems without a GUI), you can still use this CLI. Obsidian requires a GUI, so this section explains how to set up the required configuration manually.
If you're running on a headless server or don't have Obsidian installed (e.g., server environments, containers, or systems without a GUI), you can still use this CLI. When Obsidian is installed, it registers vaults automatically. For headless environments, you register them via the CLI instead.

**Setup Instructions:**

```bash
# Register your vault directory
notesmd-cli add-vault /home/user/vaults/my-brain

# Set it as default
notesmd-cli set-default-vault "my-brain"

# Or do both in one step
notesmd-cli add-vault /home/user/vaults/my-brain --set-default
```

For multiple vaults:
```bash
notesmd-cli add-vault /home/user/vaults/personal
notesmd-cli add-vault /home/user/vaults/work
notesmd-cli set-default-vault "personal"
```

You can then pass `--vault "work"` to target a specific vault.

<details>
<summary>Manual setup (without CLI commands)</summary>

1. Create the Obsidian config directory:
```bash
mkdir -p ~/.config/obsidian
Expand All @@ -83,22 +140,9 @@ If you're running on a headless server or don't have Obsidian installed (e.g., s
}
}
```
The key (`any-unique-id`) can be anything — the CLI uses the **directory name** as the vault name (e.g., `my-brain` above). Use the **absolute path** — do not use `~` as the CLI does not expand it to your home directory.
The key (`any-unique-id`) can be anything. The CLI uses the **directory name** as the vault name (e.g., `my-brain` above). Use the **absolute path**. Do not use `~` as the CLI does not expand it to your home directory.

**Multiple vaults:**
```json
{
"vaults": {
"vault-1": {
"path": "/home/user/vaults/personal"
},
"vault-2": {
"path": "/home/user/vaults/work"
}
}
}
```
You can then use `notesmd-cli set-default "personal"` or pass `--vault "work"` to target a specific vault.
</details>

---

Expand Down Expand Up @@ -145,66 +189,86 @@ notesmd-cli move "old.md" "new.md" --open --editor
To avoid passing `--editor` every time, configure it as the default open type once:

```bash
notesmd-cli set-default --open-type editor
notesmd-cli set-default-vault --open-type editor
```

### Set Default Vault and Open Type
### Add Vault

Defines the default vault and/or open type for future usage. If no default vault is set, pass `--vault` with other commands to specify which vault to use.
Registers a directory as an Obsidian vault. Creates the Obsidian config file (`~/.config/obsidian/obsidian.json`) if it does not exist. Alias: `av`

```bash
# Set default vault (vault name only, not the path)
notesmd-cli set-default "{vault-name}"
If you have Obsidian installed, vaults are registered automatically when you open them. You only need this command for headless setups or environments where Obsidian is not installed (servers, containers, CI).

# Set default open type: 'obsidian' (default) or 'editor'
notesmd-cli set-default --open-type editor
```bash
# Register a vault
notesmd-cli add-vault /path/to/vault

# Set both at once
notesmd-cli set-default "{vault-name}" --open-type editor
# Register and set as default
notesmd-cli add-vault /path/to/vault --set-default
```

When `default_open_type` is set to `editor`, commands that support `--open` will open notes in `$EDITOR` automatically, without needing to pass `--editor` each time.
### Remove Vault

Note: `open` and other commands in `notesmd-cli` use this vault's base directory as the working directory, not the current working directory of your terminal.
Removes a vault from the Obsidian config. Does not delete any files on disk. If the removed vault was the default, the default is cleared. Alias: `rv`

### Print Default Vault
```bash
# Remove by vault name
notesmd-cli remove-vault "{vault-name}"

Prints default vault and path. Please set this with `set-default` command if not set.
# Remove by vault path
notesmd-cli remove-vault /path/to/vault
```

### List Vaults

Lists all registered Obsidian vaults. The default vault is marked with `(default)`. Alias: `lv`

```bash
# print the default vault name and path
notesmd-cli print-default
# Lists all vaults (name and path, default marked)
notesmd-cli list-vaults

# print only the vault path
notesmd-cli print-default --path-only
# Outputs vaults as JSON
notesmd-cli list-vaults --json

# Outputs only vault paths (useful for scripting)
notesmd-cli list-vaults --path-only

# Show only the default vault (name, path, open type)
notesmd-cli list-vaults --default

# Get just the default vault path (useful for scripting)
notesmd-cli list-vaults --default --path-only
```

You can add this to your shell configuration file (like `~/.zshrc`) to quickly navigate to the default vault:

```bash
obs_cd() {
local result=$(notesmd-cli print-default --path-only)
local result=$(notesmd-cli list-vaults --default --path-only)
[ -n "$result" ] && cd -- "$result"
}
```

Then you can use `obs_cd` to navigate to the default vault directory within your terminal.

### List Vaults
### Set Default Vault and Open Type

Lists all registered Obsidian vaults. Alias: `lv`
Defines the default vault and/or open type for future usage. If no default vault is set, pass `--vault` with other commands to specify which vault to use.

```bash
# Lists all vaults (name and path)
notesmd-cli list-vaults
# Set default vault (by name or path)
notesmd-cli set-default-vault "{vault-name}"

# Outputs vaults as JSON
notesmd-cli list-vaults --json
# Set default open type: 'obsidian' (default) or 'editor'
notesmd-cli set-default-vault --open-type editor

# Outputs only vault paths (useful for scripting)
notesmd-cli list-vaults --path-only
# Set both at once
notesmd-cli set-default-vault "{vault-name}" --open-type editor
```

When `default_open_type` is set to `editor`, commands that support `--open` will open notes in `$EDITOR` automatically, without needing to pass `--editor` each time.

Note: `open` and other commands in `notesmd-cli` use this vault's base directory as the working directory, not the current working directory of your terminal.

### Open Note

Open given note name in Obsidian (or your default editor). Note can also be an absolute path from top level of vault.
Expand All @@ -227,7 +291,7 @@ notesmd-cli open "{note-name}" --editor

### Daily Note

Creates or opens today's daily note directly on disk **Obsidian does not need to be running**. If `.obsidian/daily-notes.json` exists in the vault, the CLI reads `folder`, `format` (Moment.js date format, default `YYYY-MM-DD`), and `template` from it. A template file's content is used when creating a new daily note. If the config is missing or unreadable, defaults are used (vault root, `YYYY-MM-DD`, no template).
Creates or opens today's daily note directly on disk. **Obsidian does not need to be running**. If `.obsidian/daily-notes.json` exists in the vault, the CLI reads `folder`, `format` (Moment.js date format, default `YYYY-MM-DD`), and `template` from it. A template file's content is used when creating a new daily note. If the config is missing or unreadable, defaults are used (vault root, `YYYY-MM-DD`, no template).

```bash
# Creates / opens daily note in obsidian vault
Expand Down Expand Up @@ -318,7 +382,7 @@ notesmd-cli print "{note-name}" --vault "{vault-name}"

### Create / Update Note

Creates a note (can also be a path with name) directly on disk **Obsidian does not need to be running**. If the note already exists and neither `--overwrite` nor `--append` is passed, the file is left unchanged. Intermediate directories are created automatically.
Creates a note (can also be a path with name) directly on disk. **Obsidian does not need to be running**. If the note already exists and neither `--overwrite` nor `--append` is passed, the file is left unchanged. Intermediate directories are created automatically.

When the note name has no explicit path (no `/`), the CLI reads `.obsidian/app.json` from the vault to check for a configured default folder (`newFileLocation: "folder"` and `newFileFolderPath`). If configured, the note is placed in that folder. If the config is missing or unreadable, the note is created at the vault root.

Expand Down Expand Up @@ -369,10 +433,10 @@ notesmd-cli move "{current-note-path}" "{new-note-path}" --open --editor
Deletes a given note (path from top level of vault).

```bash
# Renames a note in default obsidian
# Deletes a note in default vault
notesmd-cli delete "{note-path}"

# Renames a note in given obsidian
# Deletes a note in specified vault
notesmd-cli delete "{note-path}" --vault "{vault-name}"
```

Expand All @@ -394,12 +458,22 @@ notesmd-cli frontmatter "{note-name}" --delete --key "draft"
notesmd-cli frontmatter "{note-name}" --print --vault "{vault-name}"
```

## Deprecated Commands

The following commands still work but print a deprecation warning to stderr (so pipes and scripts are unaffected). They will be removed in the next major version.

| Old command | Replacement |
|---|---|
| `set-default` | `set-default-vault` |
| `print-default` | `list-vaults --default` |
| `print-default --path-only` | `list-vaults --default --path-only` |

## Excluded Files

The CLI respects Obsidian's **Excluded Files** setting (`Settings Files & Links Excluded Files`).
The CLI respects Obsidian's **Excluded Files** setting (`Settings > Files & Links > Excluded Files`).

- `search` excluded notes won't appear in the fuzzy finder
- `search-content` excluded folders won't be searched
- `search` - excluded notes won't appear in the fuzzy finder
- `search-content` - excluded folders won't be searched

All other commands (`open`, `move`, `print`, `frontmatter`, etc.) still access excluded files as they refer to notes by name.

Expand Down
41 changes: 41 additions & 0 deletions cmd/add_vault.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
package cmd

import (
"fmt"
"log"
"path/filepath"

"github.com/Yakitrak/notesmd-cli/pkg/obsidian"
"github.com/spf13/cobra"
)

var addVaultCmd = &cobra.Command{
Use: "add-vault <path>",
Aliases: []string{"av"},
Short: "Register a vault directory",
Long: "Registers a directory as an Obsidian vault. Creates the Obsidian config file if it does not exist.",
Args: cobra.ExactArgs(1),
Run: func(cmd *cobra.Command, args []string) {
absPath, err := obsidian.AddVault(args[0])
if err != nil {
log.Fatal(err)
}

name := filepath.Base(absPath)
fmt.Printf("Vault %q registered at: %s\n", name, absPath)

setDefault, _ := cmd.Flags().GetBool("set-default")
if setDefault {
v := obsidian.Vault{Name: name}
if err := v.SetDefaultName(name); err != nil {
log.Fatal(err)
}
fmt.Println("Default vault set to:", name)
}
},
}

func init() {
addVaultCmd.Flags().Bool("set-default", false, "set the added vault as the default")
rootCmd.AddCommand(addVaultCmd)
}
Loading
Loading