@vaultctl/core
v0.5.0
Published
Core library for structured Obsidian vault operations — frontmatter, wikilinks, tags, search, and health checks
Downloads
797
Maintainers
Readme
@vaultctl/core
Core library for structured Obsidian vault operations. Provides frontmatter parsing, wikilink resolution, tag management, search, health checks, and template rendering — all as pure TypeScript with zero CLI dependencies.
This is the library package. For the CLI tool, see vaultctl.
Install
npm install @vaultctl/coreUsage
import {
loadVault,
searchNotes,
listTags,
findByTag,
addTag,
removeTag,
renameTag,
checkHealth,
listTemplates,
renderTemplate,
parseNote,
safeJoin,
} from '@vaultctl/core';
// Load all notes from a vault
const notes = await loadVault('/path/to/vault');
// Search notes by content and frontmatter
const results = searchNotes(notes, {
query: 'meeting notes',
type: 'project',
status: 'active',
tag: 'work',
});
// Tag operations
const tags = listTags(notes); // all tags with counts
const tagged = findByTag(notes, 'status/active');
await addTag('/path/to/vault', '01_Projects/my-project.md', 'priority/high');
await removeTag('/path/to/vault', '01_Projects/my-project.md', 'priority/high');
const renamed = await renameTag('/path/to/vault', notes, 'old-tag', 'new-tag');
// Health checks
const issues = await checkHealth('/path/to/vault', notes);
const linksOnly = await checkHealth('/path/to/vault', notes, ['broken-links']);
// Templates
const templates = await listTemplates('/path/to/vault');
const content = await renderTemplate('/path/to/vault', 'project', 'My Project');
// Parse a single note
const note = parseNote('/path/to/vault', 'relative/path.md', fileContent);
// Safe path joining (prevents path traversal)
const safePath = safeJoin('/path/to/vault', 'notes/file.md');API
Vault
| Function | Description |
|----------|-------------|
| loadVault(path) | Load and parse all .md files in a vault |
| resolveVaultPath(options?) | Find vault root via flag, env, or directory walk |
| safeJoin(vaultPath, relativePath) | Join paths with traversal protection |
Search
| Function | Description |
|----------|-------------|
| searchNotes(notes, options) | Filter notes by query, type, status, and/or tag |
SearchOptions: { query?, type?, status?, tag? }
Tags
| Function | Description |
|----------|-------------|
| listTags(notes) | List all tags with usage counts |
| findByTag(notes, tag) | Find notes containing a tag |
| addTag(vault, path, tag) | Add a tag to a note's frontmatter |
| removeTag(vault, path, tag) | Remove a tag from a note |
| renameTag(vault, notes, old, new) | Rename a tag across the vault |
Tags are validated on write — must start with a letter and contain only letters, numbers, hyphens, underscores, or / for hierarchy.
Health
| Function | Description |
|----------|-------------|
| checkHealth(vault, notes, checks?) | Run health checks on the vault |
CheckName: 'broken-links' | 'orphans' | 'stale' | 'frontmatter'
Templates
| Function | Description |
|----------|-------------|
| listTemplates(vault) | List available _templates/tpl-*.md templates |
| renderTemplate(vault, name, title?) | Render a template with date/title substitution |
Parsing
| Function | Description |
|----------|-------------|
| parseNote(vault, path, content) | Parse a markdown file into a Note object |
| parseFrontmatter(content) | Extract YAML frontmatter |
| stringifyFrontmatter(fm, body) | Serialize frontmatter + body back to markdown |
| parseWikilinks(content) | Extract [[wikilinks]] from content |
| parseInlineTags(content) | Extract #hashtags from content |
Types
interface Note {
path: string;
filename: string;
folder: string;
frontmatter: Frontmatter;
body: string;
wikilinks: WikiLink[];
inlineTags: string[];
}
interface Frontmatter {
type?: string;
status?: string;
tags?: string[];
created?: string;
updated?: string;
[key: string]: unknown;
}
interface WikiLink {
raw: string;
target: string;
alias?: string;
resolved?: string | null;
}
interface HealthIssue {
check: string;
path: string;
message: string;
severity: 'error' | 'warning' | 'info';
}
interface VaultStats {
totalNotes: number;
notesByType: Record<string, number>;
notesByStatus: Record<string, number>;
totalTags: number;
brokenLinks: number;
orphanedNotes: number;
}License
MIT
