vaultctl 0.3.0 → 0.3.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +148 -0
- package/dist/commands/search.js +1 -1
- package/dist/commands/tags.js +1 -1
- package/dist/format.d.ts +1 -1
- package/dist/format.js +1 -1
- package/dist/index.js +1 -1
- package/package.json +2 -2
package/README.md
ADDED
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
# vaultctl
|
|
2
|
+
|
|
3
|
+
Structured Obsidian vault operations without MCP servers.
|
|
4
|
+
|
|
5
|
+
`vaultctl` is a CLI tool that gives [Claude Code](https://claude.com/claude-code) and other AI agents structured access to Obsidian vaults — search, tag management, health checks, and template-based note creation — without running a persistent MCP server process.
|
|
6
|
+
|
|
7
|
+
## Why?
|
|
8
|
+
|
|
9
|
+
MCP servers for Obsidian + Claude Code CLI are [fundamentally broken](https://github.com/anthropics/claude-code/issues/9176). Claude Code's stdio pipe lifecycle management kills server connections before they initialise, causing `BrokenPipeError` on every session. Meanwhile, Obsidian vaults are just directories of markdown files — there's no reason to run a persistent server process to read them.
|
|
10
|
+
|
|
11
|
+
`vaultctl` replaces MCP with stateless CLI commands. Every invocation reads the filesystem, does its thing, and exits. No pipes, no zombie processes, no lifecycle bugs.
|
|
12
|
+
|
|
13
|
+
## Install
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
npm install -g vaultctl
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
Then set your vault path in `~/.zshrc` or `~/.bashrc`:
|
|
20
|
+
|
|
21
|
+
```bash
|
|
22
|
+
export VAULTCTL_PATH="$HOME/path/to/your/vault"
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
### From Source
|
|
26
|
+
|
|
27
|
+
```bash
|
|
28
|
+
git clone https://github.com/testing-in-production/vaultctl.git
|
|
29
|
+
cd vaultctl
|
|
30
|
+
npm install
|
|
31
|
+
npm run build
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
Then add to your shell profile:
|
|
35
|
+
|
|
36
|
+
```bash
|
|
37
|
+
export VAULTCTL_PATH="$HOME/path/to/your/vault"
|
|
38
|
+
alias vaultctl="node $HOME/vaultctl/packages/cli/dist/index.js"
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
## Usage
|
|
42
|
+
|
|
43
|
+
### Search
|
|
44
|
+
|
|
45
|
+
```bash
|
|
46
|
+
# Full-text content search
|
|
47
|
+
vaultctl search "meeting notes"
|
|
48
|
+
|
|
49
|
+
# Filter by frontmatter fields
|
|
50
|
+
vaultctl search --type project --status active
|
|
51
|
+
|
|
52
|
+
# Filter by tag
|
|
53
|
+
vaultctl search --tag "status/active"
|
|
54
|
+
|
|
55
|
+
# Combine filters
|
|
56
|
+
vaultctl search "quarterly" --type project --status active
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
### Tags
|
|
60
|
+
|
|
61
|
+
```bash
|
|
62
|
+
# List all tags with counts
|
|
63
|
+
vaultctl tags list
|
|
64
|
+
|
|
65
|
+
# Find notes with a specific tag
|
|
66
|
+
vaultctl tags find status/active
|
|
67
|
+
|
|
68
|
+
# Add/remove tags
|
|
69
|
+
vaultctl tags add 01_Projects/my-project.md priority/high
|
|
70
|
+
vaultctl tags remove 01_Projects/my-project.md priority/high
|
|
71
|
+
|
|
72
|
+
# Rename a tag across the entire vault (dry-run first)
|
|
73
|
+
vaultctl tags rename status/active status/in-progress
|
|
74
|
+
vaultctl tags rename status/active status/in-progress --yes
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
### Health
|
|
78
|
+
|
|
79
|
+
```bash
|
|
80
|
+
# Run all health checks
|
|
81
|
+
vaultctl health
|
|
82
|
+
|
|
83
|
+
# Run specific checks
|
|
84
|
+
vaultctl health --check broken-links
|
|
85
|
+
vaultctl health --check orphans
|
|
86
|
+
vaultctl health --check stale --days 90
|
|
87
|
+
vaultctl health --check frontmatter
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
### Create
|
|
91
|
+
|
|
92
|
+
```bash
|
|
93
|
+
# Create a note from a template
|
|
94
|
+
vaultctl create --template project "My New Project"
|
|
95
|
+
vaultctl create --template daily
|
|
96
|
+
|
|
97
|
+
# Specify target folder
|
|
98
|
+
vaultctl create --template concept --folder 03_Resources/concepts "Zettelkasten"
|
|
99
|
+
|
|
100
|
+
# List available templates
|
|
101
|
+
vaultctl create --list
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
### Read & Info
|
|
105
|
+
|
|
106
|
+
```bash
|
|
107
|
+
# Read a note (parsed with frontmatter, wikilinks, tags)
|
|
108
|
+
vaultctl read 01_Projects/my-project.md
|
|
109
|
+
|
|
110
|
+
# Vault overview statistics
|
|
111
|
+
vaultctl info
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
## Output
|
|
115
|
+
|
|
116
|
+
JSON by default (designed for AI agent consumption). Add `--format table` for human-readable output.
|
|
117
|
+
|
|
118
|
+
Exit codes: `0` = success, `1` = error, `2` = no results found.
|
|
119
|
+
|
|
120
|
+
## Vault Discovery
|
|
121
|
+
|
|
122
|
+
`vaultctl` finds your vault in this order:
|
|
123
|
+
|
|
124
|
+
1. `--vault /path/to/vault` flag
|
|
125
|
+
2. `VAULTCTL_PATH` environment variable
|
|
126
|
+
3. Walk up from current directory looking for `.obsidian/`
|
|
127
|
+
4. `~/.vaultctlrc` config file
|
|
128
|
+
|
|
129
|
+
## Features
|
|
130
|
+
|
|
131
|
+
- **Search** — Full-text content search with type, status, and tag filters
|
|
132
|
+
- **Tags** — List, find, add, remove, and rename tags (frontmatter + inline `#tags` unified)
|
|
133
|
+
- **Health** — Broken `[[wikilinks]]`, orphaned notes, stale notes, missing frontmatter
|
|
134
|
+
- **Templates** — Create notes from `_templates/tpl-*.md` with date/title substitution
|
|
135
|
+
- **Wikilink resolution** — All `[[links]]` resolved to file paths or flagged as broken
|
|
136
|
+
- **Path traversal protection** — All write operations validated against vault root
|
|
137
|
+
|
|
138
|
+
## Architecture
|
|
139
|
+
|
|
140
|
+
This is the CLI wrapper package. The core logic lives in [`@vaultctl/core`](https://www.npmjs.com/package/@vaultctl/core) — a pure TypeScript library with zero CLI dependencies that can be imported by other tools.
|
|
141
|
+
|
|
142
|
+
## Blog Post
|
|
143
|
+
|
|
144
|
+
Read the full story: [I Replaced My Obsidian MCP Server With a CLI](https://www.testinginproduction.co/blog/i-replaced-mcp-with-a-cli)
|
|
145
|
+
|
|
146
|
+
## License
|
|
147
|
+
|
|
148
|
+
MIT
|
package/dist/commands/search.js
CHANGED
|
@@ -23,7 +23,7 @@ export function registerSearchCommand(program) {
|
|
|
23
23
|
console.log(formatOutput([], format));
|
|
24
24
|
process.exit(2);
|
|
25
25
|
}
|
|
26
|
-
const output = results.map(n => formatNoteRow(n
|
|
26
|
+
const output = results.map(n => formatNoteRow(n));
|
|
27
27
|
console.log(formatOutput(output, format));
|
|
28
28
|
}
|
|
29
29
|
catch (err) {
|
package/dist/commands/tags.js
CHANGED
|
@@ -39,7 +39,7 @@ export function registerTagsCommand(program) {
|
|
|
39
39
|
console.log(formatOutput([], format));
|
|
40
40
|
process.exit(2);
|
|
41
41
|
}
|
|
42
|
-
const output = results.map(n => formatNoteRow(n
|
|
42
|
+
const output = results.map(n => formatNoteRow(n));
|
|
43
43
|
console.log(formatOutput(output, format));
|
|
44
44
|
}
|
|
45
45
|
catch (err) {
|
package/dist/format.d.ts
CHANGED
|
@@ -3,5 +3,5 @@ export declare function formatOutput(data: unknown, format: OutputFormat): strin
|
|
|
3
3
|
export declare function formatNoteRow(note: {
|
|
4
4
|
path: string;
|
|
5
5
|
frontmatter: Record<string, unknown>;
|
|
6
|
-
}
|
|
6
|
+
}): Record<string, unknown>;
|
|
7
7
|
//# sourceMappingURL=format.d.ts.map
|
package/dist/format.js
CHANGED
package/dist/index.js
CHANGED
|
@@ -10,7 +10,7 @@ const program = new Command();
|
|
|
10
10
|
program
|
|
11
11
|
.name('vaultctl')
|
|
12
12
|
.description('Structured Obsidian vault operations without MCP servers')
|
|
13
|
-
.version('0.3.
|
|
13
|
+
.version('0.3.2')
|
|
14
14
|
.option('--vault <path>', 'Path to Obsidian vault')
|
|
15
15
|
.option('--format <format>', 'Output format: json or table', 'json');
|
|
16
16
|
registerSearchCommand(program);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "vaultctl",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.2",
|
|
4
4
|
"description": "CLI for structured Obsidian vault operations — search, tags, health checks, templates — without MCP servers",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -25,7 +25,7 @@
|
|
|
25
25
|
"prepublishOnly": "npm run build"
|
|
26
26
|
},
|
|
27
27
|
"dependencies": {
|
|
28
|
-
"@vaultctl/core": "^0.3.
|
|
28
|
+
"@vaultctl/core": "^0.3.2",
|
|
29
29
|
"chalk": "^5.4.0",
|
|
30
30
|
"commander": "^13.0.0"
|
|
31
31
|
}
|