vaultctl 0.1.0

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.
@@ -0,0 +1,3 @@
1
+ import type { Command } from 'commander';
2
+ export declare function registerCreateCommand(program: Command): void;
3
+ //# sourceMappingURL=create.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"create.d.ts","sourceRoot":"","sources":["../../src/commands/create.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAOzC,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAsD5D"}
@@ -0,0 +1,64 @@
1
+ import { writeFile, mkdir } from 'fs/promises';
2
+ import { join, dirname } from 'path';
3
+ import { existsSync } from 'fs';
4
+ import { resolveVaultPath, listTemplates, renderTemplate } from '@vaultctl/core';
5
+ import { formatOutput } from '../format.js';
6
+ export function registerCreateCommand(program) {
7
+ program
8
+ .command('create [title]')
9
+ .description('Create a new note from a template')
10
+ .option('--template <name>', 'Template name (e.g. project, daily)')
11
+ .option('--folder <folder>', 'Target folder relative to vault root')
12
+ .option('--list', 'List available templates')
13
+ .action(async (title, opts, cmd) => {
14
+ try {
15
+ const globalOpts = cmd.parent.opts();
16
+ const format = (globalOpts.format ?? 'json');
17
+ const vaultPath = resolveVaultPath(globalOpts.vault);
18
+ if (opts.list) {
19
+ const templates = await listTemplates(vaultPath);
20
+ const output = templates.map(t => ({ name: t.name, file: t.path }));
21
+ console.log(formatOutput(output, format));
22
+ return;
23
+ }
24
+ if (!opts.template) {
25
+ console.error('Error: --template is required. Use --list to see available templates.');
26
+ process.exit(1);
27
+ }
28
+ const templateName = opts.template;
29
+ const content = await renderTemplate(vaultPath, templateName, title);
30
+ const today = new Date().toISOString().split('T')[0];
31
+ const filename = title
32
+ ? `${title.toLowerCase().replace(/\s+/g, '-')}.md`
33
+ : `${today}.md`;
34
+ const folder = opts.folder ?? inferFolder(templateName);
35
+ const relativePath = folder ? `${folder}/${filename}` : filename;
36
+ const fullPath = join(vaultPath, relativePath);
37
+ const dir = dirname(fullPath);
38
+ if (!existsSync(dir)) {
39
+ await mkdir(dir, { recursive: true });
40
+ }
41
+ if (existsSync(fullPath)) {
42
+ console.error(`Error: File already exists: ${relativePath}`);
43
+ process.exit(1);
44
+ }
45
+ await writeFile(fullPath, content, 'utf-8');
46
+ console.log(formatOutput({ created: relativePath }, format));
47
+ }
48
+ catch (err) {
49
+ console.error(String(err));
50
+ process.exit(1);
51
+ }
52
+ });
53
+ }
54
+ function inferFolder(templateName) {
55
+ const folderMap = {
56
+ project: '01_Projects',
57
+ daily: '05_Journal',
58
+ concept: '03_Resources/concepts',
59
+ tool: '03_Resources/tools',
60
+ inbox: '00_Inbox',
61
+ };
62
+ return folderMap[templateName] ?? '00_Inbox';
63
+ }
64
+ //# sourceMappingURL=create.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"create.js","sourceRoot":"","sources":["../../src/commands/create.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import type { Command } from 'commander';
2
+ export declare function registerHealthCommand(program: Command): void;
3
+ //# sourceMappingURL=health.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"health.d.ts","sourceRoot":"","sources":["../../src/commands/health.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAIzC,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAgC5D"}
@@ -0,0 +1,33 @@
1
+ import { resolveVaultPath, loadVault, checkHealth } from '@vaultctl/core';
2
+ import { formatOutput } from '../format.js';
3
+ export function registerHealthCommand(program) {
4
+ program
5
+ .command('health')
6
+ .description('Run vault health checks')
7
+ .option('--check <checks>', 'Comma-separated checks: broken-links,orphans,stale,frontmatter')
8
+ .option('--days <days>', 'Stale threshold in days', '30')
9
+ .action(async (opts, cmd) => {
10
+ try {
11
+ const globalOpts = cmd.parent.opts();
12
+ const format = (globalOpts.format ?? 'json');
13
+ const vaultPath = resolveVaultPath(globalOpts.vault);
14
+ const notes = await loadVault(vaultPath);
15
+ const checks = opts.check
16
+ ? opts.check.split(',').map(c => c.trim())
17
+ : undefined;
18
+ const issues = checkHealth(notes, checks, {
19
+ staleDays: parseInt(opts.days, 10),
20
+ });
21
+ if (issues.length === 0) {
22
+ console.log(formatOutput({ status: 'healthy', issues: [] }, format));
23
+ return;
24
+ }
25
+ console.log(formatOutput({ status: 'issues-found', count: issues.length, issues }, format));
26
+ }
27
+ catch (err) {
28
+ console.error(String(err));
29
+ process.exit(1);
30
+ }
31
+ });
32
+ }
33
+ //# sourceMappingURL=health.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"health.js","sourceRoot":"","sources":["../../src/commands/health.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,gBAAgB,EAAE,SAAS,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAC1E,OAAO,EAAE,YAAY,EAAqB,MAAM,cAAc,CAAC;AAE/D,MAAM,UAAU,qBAAqB,CAAC,OAAgB;IACpD,OAAO;SACJ,OAAO,CAAC,QAAQ,CAAC;SACjB,WAAW,CAAC,yBAAyB,CAAC;SACtC,MAAM,CAAC,kBAAkB,EAAE,gEAAgE,CAAC;SAC5F,MAAM,CAAC,eAAe,EAAE,yBAAyB,EAAE,IAAI,CAAC;SACxD,MAAM,CAAC,KAAK,EAAE,IAA4B,EAAE,GAAY,EAAE,EAAE;QAC3D,IAAI,CAAC;YACH,MAAM,UAAU,GAAG,GAAG,CAAC,MAAO,CAAC,IAAI,EAAE,CAAC;YACtC,MAAM,MAAM,GAAG,CAAC,UAAU,CAAC,MAAM,IAAI,MAAM,CAAiB,CAAC;YAC7D,MAAM,SAAS,GAAG,gBAAgB,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC;YACrD,MAAM,KAAK,GAAG,MAAM,SAAS,CAAC,SAAS,CAAC,CAAC;YAEzC,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK;gBACvB,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAU;gBACnD,CAAC,CAAC,SAAS,CAAC;YAEd,MAAM,MAAM,GAAG,WAAW,CAAC,KAAK,EAAE,MAAM,EAAE;gBACxC,SAAS,EAAE,QAAQ,CAAC,IAAI,CAAC,IAAI,EAAE,EAAE,CAAC;aACnC,CAAC,CAAC;YAEH,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;gBACxB,OAAO,CAAC,GAAG,CAAC,YAAY,CAAC,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,EAAE,EAAE,EAAE,MAAM,CAAC,CAAC,CAAC;gBACrE,OAAO;YACT,CAAC;YAED,OAAO,CAAC,GAAG,CAAC,YAAY,CAAC,EAAE,MAAM,EAAE,cAAc,EAAE,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,EAAE,MAAM,CAAC,CAAC,CAAC;QAC9F,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,OAAO,CAAC,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC;YAC3B,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;IACH,CAAC,CAAC,CAAC;AACP,CAAC"}
@@ -0,0 +1,3 @@
1
+ import type { Command } from 'commander';
2
+ export declare function registerInfoCommand(program: Command): void;
3
+ //# sourceMappingURL=info.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"info.d.ts","sourceRoot":"","sources":["../../src/commands/info.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAKzC,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAwC1D"}
@@ -0,0 +1,41 @@
1
+ import { resolveVaultPath, loadVault, listTags, checkHealth } from '@vaultctl/core';
2
+ import { formatOutput } from '../format.js';
3
+ export function registerInfoCommand(program) {
4
+ program
5
+ .command('info')
6
+ .description('Show vault overview statistics')
7
+ .action(async (_opts, cmd) => {
8
+ try {
9
+ const globalOpts = cmd.parent.opts();
10
+ const format = (globalOpts.format ?? 'json');
11
+ const vaultPath = resolveVaultPath(globalOpts.vault);
12
+ const notes = await loadVault(vaultPath);
13
+ const tags = listTags(notes);
14
+ const issues = checkHealth(notes);
15
+ const brokenLinks = issues.filter(i => i.check === 'broken-links').length;
16
+ const orphanedNotes = issues.filter(i => i.check === 'orphans').length;
17
+ const notesByType = {};
18
+ const notesByStatus = {};
19
+ for (const note of notes) {
20
+ const type = note.frontmatter.type ?? 'unknown';
21
+ const status = note.frontmatter.status ?? 'unknown';
22
+ notesByType[type] = (notesByType[type] ?? 0) + 1;
23
+ notesByStatus[status] = (notesByStatus[status] ?? 0) + 1;
24
+ }
25
+ const stats = {
26
+ totalNotes: notes.length,
27
+ notesByType,
28
+ notesByStatus,
29
+ totalTags: tags.size,
30
+ brokenLinks,
31
+ orphanedNotes,
32
+ };
33
+ console.log(formatOutput(stats, format));
34
+ }
35
+ catch (err) {
36
+ console.error(String(err));
37
+ process.exit(1);
38
+ }
39
+ });
40
+ }
41
+ //# sourceMappingURL=info.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"info.js","sourceRoot":"","sources":["../../src/commands/info.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,gBAAgB,EAAE,SAAS,EAAE,QAAQ,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AACpF,OAAO,EAAE,YAAY,EAAqB,MAAM,cAAc,CAAC;AAG/D,MAAM,UAAU,mBAAmB,CAAC,OAAgB;IAClD,OAAO;SACJ,OAAO,CAAC,MAAM,CAAC;SACf,WAAW,CAAC,gCAAgC,CAAC;SAC7C,MAAM,CAAC,KAAK,EAAE,KAA6B,EAAE,GAAY,EAAE,EAAE;QAC5D,IAAI,CAAC;YACH,MAAM,UAAU,GAAG,GAAG,CAAC,MAAO,CAAC,IAAI,EAAE,CAAC;YACtC,MAAM,MAAM,GAAG,CAAC,UAAU,CAAC,MAAM,IAAI,MAAM,CAAiB,CAAC;YAC7D,MAAM,SAAS,GAAG,gBAAgB,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC;YACrD,MAAM,KAAK,GAAG,MAAM,SAAS,CAAC,SAAS,CAAC,CAAC;YAEzC,MAAM,IAAI,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC;YAC7B,MAAM,MAAM,GAAG,WAAW,CAAC,KAAK,CAAC,CAAC;YAClC,MAAM,WAAW,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK,KAAK,cAAc,CAAC,CAAC,MAAM,CAAC;YAC1E,MAAM,aAAa,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK,KAAK,SAAS,CAAC,CAAC,MAAM,CAAC;YAEvE,MAAM,WAAW,GAA2B,EAAE,CAAC;YAC/C,MAAM,aAAa,GAA2B,EAAE,CAAC;YACjD,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;gBACzB,MAAM,IAAI,GAAI,IAAI,CAAC,WAAW,CAAC,IAAe,IAAI,SAAS,CAAC;gBAC5D,MAAM,MAAM,GAAI,IAAI,CAAC,WAAW,CAAC,MAAiB,IAAI,SAAS,CAAC;gBAChE,WAAW,CAAC,IAAI,CAAC,GAAG,CAAC,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC;gBACjD,aAAa,CAAC,MAAM,CAAC,GAAG,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC;YAC3D,CAAC;YAED,MAAM,KAAK,GAAe;gBACxB,UAAU,EAAE,KAAK,CAAC,MAAM;gBACxB,WAAW;gBACX,aAAa;gBACb,SAAS,EAAE,IAAI,CAAC,IAAI;gBACpB,WAAW;gBACX,aAAa;aACd,CAAC;YAEF,OAAO,CAAC,GAAG,CAAC,YAAY,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC,CAAC;QAC3C,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,OAAO,CAAC,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC;YAC3B,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;IACH,CAAC,CAAC,CAAC;AACP,CAAC"}
@@ -0,0 +1,3 @@
1
+ import type { Command } from 'commander';
2
+ export declare function registerReadCommand(program: Command): void;
3
+ //# sourceMappingURL=read.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"read.d.ts","sourceRoot":"","sources":["../../src/commands/read.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAIzC,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CA2B1D"}
@@ -0,0 +1,30 @@
1
+ import { resolveVaultPath, loadVault } from '@vaultctl/core';
2
+ export function registerReadCommand(program) {
3
+ program
4
+ .command('read <path>')
5
+ .description('Read a note and output its parsed content')
6
+ .action(async (notePath, _opts, cmd) => {
7
+ try {
8
+ const globalOpts = cmd.parent.opts();
9
+ const format = (globalOpts.format ?? 'json');
10
+ const vaultPath = resolveVaultPath(globalOpts.vault);
11
+ const notes = await loadVault(vaultPath);
12
+ const note = notes.find(n => n.path === notePath);
13
+ if (!note) {
14
+ console.error(`Note not found: ${notePath}`);
15
+ process.exit(1);
16
+ }
17
+ if (format === 'json') {
18
+ console.log(JSON.stringify(note, null, 2));
19
+ }
20
+ else {
21
+ console.log(note.body);
22
+ }
23
+ }
24
+ catch (err) {
25
+ console.error(String(err));
26
+ process.exit(1);
27
+ }
28
+ });
29
+ }
30
+ //# sourceMappingURL=read.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"read.js","sourceRoot":"","sources":["../../src/commands/read.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,gBAAgB,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAG7D,MAAM,UAAU,mBAAmB,CAAC,OAAgB;IAClD,OAAO;SACJ,OAAO,CAAC,aAAa,CAAC;SACtB,WAAW,CAAC,2CAA2C,CAAC;SACxD,MAAM,CAAC,KAAK,EAAE,QAAgB,EAAE,KAA6B,EAAE,GAAY,EAAE,EAAE;QAC9E,IAAI,CAAC;YACH,MAAM,UAAU,GAAG,GAAG,CAAC,MAAO,CAAC,IAAI,EAAE,CAAC;YACtC,MAAM,MAAM,GAAG,CAAC,UAAU,CAAC,MAAM,IAAI,MAAM,CAAiB,CAAC;YAC7D,MAAM,SAAS,GAAG,gBAAgB,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC;YACrD,MAAM,KAAK,GAAG,MAAM,SAAS,CAAC,SAAS,CAAC,CAAC;YAEzC,MAAM,IAAI,GAAG,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,QAAQ,CAAC,CAAC;YAClD,IAAI,CAAC,IAAI,EAAE,CAAC;gBACV,OAAO,CAAC,KAAK,CAAC,mBAAmB,QAAQ,EAAE,CAAC,CAAC;gBAC7C,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;YAClB,CAAC;YAED,IAAI,MAAM,KAAK,MAAM,EAAE,CAAC;gBACtB,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;YAC7C,CAAC;iBAAM,CAAC;gBACN,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YACzB,CAAC;QACH,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,OAAO,CAAC,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC;YAC3B,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;IACH,CAAC,CAAC,CAAC;AACP,CAAC"}
@@ -0,0 +1,3 @@
1
+ import type { Command } from 'commander';
2
+ export declare function registerSearchCommand(program: Command): void;
3
+ //# sourceMappingURL=search.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"search.d.ts","sourceRoot":"","sources":["../../src/commands/search.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAIzC,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAiC5D"}
@@ -0,0 +1,35 @@
1
+ import { resolveVaultPath, loadVault, searchNotes } from '@vaultctl/core';
2
+ import { formatOutput, formatNoteRow } from '../format.js';
3
+ export function registerSearchCommand(program) {
4
+ program
5
+ .command('search [query]')
6
+ .description('Search vault notes by content, frontmatter, or tags')
7
+ .option('--type <type>', 'Filter by frontmatter type')
8
+ .option('--status <status>', 'Filter by frontmatter status')
9
+ .option('--tag <tag>', 'Filter by tag')
10
+ .action(async (query, opts, cmd) => {
11
+ try {
12
+ const globalOpts = cmd.parent.opts();
13
+ const format = (globalOpts.format ?? 'json');
14
+ const vaultPath = resolveVaultPath(globalOpts.vault);
15
+ const notes = await loadVault(vaultPath);
16
+ const results = searchNotes(notes, {
17
+ query,
18
+ type: opts.type,
19
+ status: opts.status,
20
+ tag: opts.tag,
21
+ });
22
+ if (results.length === 0) {
23
+ console.log(formatOutput([], format));
24
+ process.exit(2);
25
+ }
26
+ const output = results.map(n => formatNoteRow(n, format));
27
+ console.log(formatOutput(output, format));
28
+ }
29
+ catch (err) {
30
+ console.error(String(err));
31
+ process.exit(1);
32
+ }
33
+ });
34
+ }
35
+ //# sourceMappingURL=search.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"search.js","sourceRoot":"","sources":["../../src/commands/search.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,gBAAgB,EAAE,SAAS,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAC1E,OAAO,EAAE,YAAY,EAAE,aAAa,EAAqB,MAAM,cAAc,CAAC;AAE9E,MAAM,UAAU,qBAAqB,CAAC,OAAgB;IACpD,OAAO;SACJ,OAAO,CAAC,gBAAgB,CAAC;SACzB,WAAW,CAAC,qDAAqD,CAAC;SAClE,MAAM,CAAC,eAAe,EAAE,4BAA4B,CAAC;SACrD,MAAM,CAAC,mBAAmB,EAAE,8BAA8B,CAAC;SAC3D,MAAM,CAAC,aAAa,EAAE,eAAe,CAAC;SACtC,MAAM,CAAC,KAAK,EAAE,KAAyB,EAAE,IAA4B,EAAE,GAAY,EAAE,EAAE;QACtF,IAAI,CAAC;YACH,MAAM,UAAU,GAAG,GAAG,CAAC,MAAO,CAAC,IAAI,EAAE,CAAC;YACtC,MAAM,MAAM,GAAG,CAAC,UAAU,CAAC,MAAM,IAAI,MAAM,CAAiB,CAAC;YAC7D,MAAM,SAAS,GAAG,gBAAgB,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC;YACrD,MAAM,KAAK,GAAG,MAAM,SAAS,CAAC,SAAS,CAAC,CAAC;YAEzC,MAAM,OAAO,GAAG,WAAW,CAAC,KAAK,EAAE;gBACjC,KAAK;gBACL,IAAI,EAAE,IAAI,CAAC,IAAI;gBACf,MAAM,EAAE,IAAI,CAAC,MAAM;gBACnB,GAAG,EAAE,IAAI,CAAC,GAAG;aACd,CAAC,CAAC;YAEH,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;gBACzB,OAAO,CAAC,GAAG,CAAC,YAAY,CAAC,EAAE,EAAE,MAAM,CAAC,CAAC,CAAC;gBACtC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;YAClB,CAAC;YAED,MAAM,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,aAAa,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,CAAC;YAC1D,OAAO,CAAC,GAAG,CAAC,YAAY,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;QAC5C,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,OAAO,CAAC,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC;YAC3B,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;IACH,CAAC,CAAC,CAAC;AACP,CAAC"}
@@ -0,0 +1,3 @@
1
+ import type { Command } from 'commander';
2
+ export declare function registerTagsCommand(program: Command): void;
3
+ //# sourceMappingURL=tags.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tags.d.ts","sourceRoot":"","sources":["../../src/commands/tags.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAMzC,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CA2H1D"}
@@ -0,0 +1,121 @@
1
+ import { readFile, writeFile } from 'fs/promises';
2
+ import { join } from 'path';
3
+ import { resolveVaultPath, loadVault, listTags, findByTag, addTag, removeTag, renameTag } from '@vaultctl/core';
4
+ import { formatOutput, formatNoteRow } from '../format.js';
5
+ export function registerTagsCommand(program) {
6
+ const tags = program
7
+ .command('tags')
8
+ .description('Tag operations');
9
+ tags
10
+ .command('list')
11
+ .description('List all tags with counts')
12
+ .action(async (_opts, cmd) => {
13
+ try {
14
+ const globalOpts = cmd.parent.parent.opts();
15
+ const format = (globalOpts.format ?? 'json');
16
+ const vaultPath = resolveVaultPath(globalOpts.vault);
17
+ const notes = await loadVault(vaultPath);
18
+ const tagMap = listTags(notes);
19
+ const output = Array.from(tagMap.entries())
20
+ .sort((a, b) => b[1] - a[1])
21
+ .map(([tag, count]) => ({ tag, count }));
22
+ console.log(formatOutput(output, format));
23
+ }
24
+ catch (err) {
25
+ console.error(String(err));
26
+ process.exit(1);
27
+ }
28
+ });
29
+ tags
30
+ .command('find <tag>')
31
+ .description('Find notes with a specific tag')
32
+ .action(async (tag, _opts, cmd) => {
33
+ try {
34
+ const globalOpts = cmd.parent.parent.opts();
35
+ const format = (globalOpts.format ?? 'json');
36
+ const vaultPath = resolveVaultPath(globalOpts.vault);
37
+ const notes = await loadVault(vaultPath);
38
+ const results = findByTag(notes, tag);
39
+ if (results.length === 0) {
40
+ console.log(formatOutput([], format));
41
+ process.exit(2);
42
+ }
43
+ const output = results.map(n => formatNoteRow(n, format));
44
+ console.log(formatOutput(output, format));
45
+ }
46
+ catch (err) {
47
+ console.error(String(err));
48
+ process.exit(1);
49
+ }
50
+ });
51
+ tags
52
+ .command('add <path> <tag>')
53
+ .description('Add a tag to a note')
54
+ .action(async (notePath, tag, _opts, cmd) => {
55
+ try {
56
+ const globalOpts = cmd.parent.parent.opts();
57
+ const format = (globalOpts.format ?? 'json');
58
+ const vaultPath = resolveVaultPath(globalOpts.vault);
59
+ const fullPath = join(vaultPath, notePath);
60
+ const content = await readFile(fullPath, 'utf-8');
61
+ const updated = addTag(content, tag);
62
+ await writeFile(fullPath, updated, 'utf-8');
63
+ console.log(formatOutput({ path: notePath, action: 'added', tag }, format));
64
+ }
65
+ catch (err) {
66
+ console.error(String(err));
67
+ process.exit(1);
68
+ }
69
+ });
70
+ tags
71
+ .command('remove <path> <tag>')
72
+ .description('Remove a tag from a note')
73
+ .action(async (notePath, tag, _opts, cmd) => {
74
+ try {
75
+ const globalOpts = cmd.parent.parent.opts();
76
+ const format = (globalOpts.format ?? 'json');
77
+ const vaultPath = resolveVaultPath(globalOpts.vault);
78
+ const fullPath = join(vaultPath, notePath);
79
+ const content = await readFile(fullPath, 'utf-8');
80
+ const updated = removeTag(content, tag);
81
+ await writeFile(fullPath, updated, 'utf-8');
82
+ console.log(formatOutput({ path: notePath, action: 'removed', tag }, format));
83
+ }
84
+ catch (err) {
85
+ console.error(String(err));
86
+ process.exit(1);
87
+ }
88
+ });
89
+ tags
90
+ .command('rename <oldTag> <newTag>')
91
+ .description('Rename a tag across the entire vault')
92
+ .option('--yes', 'Execute without confirmation')
93
+ .action(async (oldTag, newTag, opts, cmd) => {
94
+ try {
95
+ const globalOpts = cmd.parent.parent.opts();
96
+ const format = (globalOpts.format ?? 'json');
97
+ const vaultPath = resolveVaultPath(globalOpts.vault);
98
+ const notes = await loadVault(vaultPath);
99
+ const affected = renameTag(notes, oldTag, newTag);
100
+ if (affected.length === 0) {
101
+ console.log(formatOutput({ message: `No notes found with tag: ${oldTag}` }, format));
102
+ process.exit(2);
103
+ }
104
+ if (!opts.yes) {
105
+ const summary = affected.map(a => ({ path: a.path, action: `${oldTag} → ${newTag}` }));
106
+ console.log(formatOutput({ dryRun: true, affected: summary, message: 'Pass --yes to execute' }, format));
107
+ return;
108
+ }
109
+ for (const change of affected) {
110
+ const fullPath = join(vaultPath, change.path);
111
+ await writeFile(fullPath, change.newContent, 'utf-8');
112
+ }
113
+ console.log(formatOutput({ renamed: affected.length, from: oldTag, to: newTag }, format));
114
+ }
115
+ catch (err) {
116
+ console.error(String(err));
117
+ process.exit(1);
118
+ }
119
+ });
120
+ }
121
+ //# sourceMappingURL=tags.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tags.js","sourceRoot":"","sources":["../../src/commands/tags.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,7 @@
1
+ export type OutputFormat = 'json' | 'table';
2
+ export declare function formatOutput(data: unknown, format: OutputFormat): string;
3
+ export declare function formatNoteRow(note: {
4
+ path: string;
5
+ frontmatter: Record<string, unknown>;
6
+ }, format: OutputFormat): Record<string, unknown>;
7
+ //# sourceMappingURL=format.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"format.d.ts","sourceRoot":"","sources":["../src/format.ts"],"names":[],"mappings":"AAEA,MAAM,MAAM,YAAY,GAAG,MAAM,GAAG,OAAO,CAAC;AAE5C,wBAAgB,YAAY,CAAC,IAAI,EAAE,OAAO,EAAE,MAAM,EAAE,YAAY,GAAG,MAAM,CAKxE;AAwBD,wBAAgB,aAAa,CAAC,IAAI,EAAE;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;CAAE,EAAE,MAAM,EAAE,YAAY,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAOzI"}
package/dist/format.js ADDED
@@ -0,0 +1,37 @@
1
+ import chalk from 'chalk';
2
+ export function formatOutput(data, format) {
3
+ if (format === 'json') {
4
+ return JSON.stringify(data, null, 2);
5
+ }
6
+ return formatTable(data);
7
+ }
8
+ function formatTable(data) {
9
+ if (Array.isArray(data)) {
10
+ if (data.length === 0)
11
+ return chalk.dim('No results.');
12
+ return data.map(item => formatTableRow(item)).join('\n');
13
+ }
14
+ if (typeof data === 'object' && data !== null) {
15
+ return formatTableRow(data);
16
+ }
17
+ return String(data);
18
+ }
19
+ function formatTableRow(obj) {
20
+ const entries = Object.entries(obj);
21
+ return entries
22
+ .map(([key, value]) => {
23
+ const label = chalk.bold(key.padEnd(12));
24
+ const val = Array.isArray(value) ? value.join(', ') : String(value ?? '');
25
+ return `${label} ${val}`;
26
+ })
27
+ .join('\n');
28
+ }
29
+ export function formatNoteRow(note, format) {
30
+ return {
31
+ path: note.path,
32
+ type: note.frontmatter.type ?? '',
33
+ status: note.frontmatter.status ?? '',
34
+ tags: note.frontmatter.tags ?? [],
35
+ };
36
+ }
37
+ //# sourceMappingURL=format.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"format.js","sourceRoot":"","sources":["../src/format.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAI1B,MAAM,UAAU,YAAY,CAAC,IAAa,EAAE,MAAoB;IAC9D,IAAI,MAAM,KAAK,MAAM,EAAE,CAAC;QACtB,OAAO,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC;IACvC,CAAC;IACD,OAAO,WAAW,CAAC,IAAI,CAAC,CAAC;AAC3B,CAAC;AAED,SAAS,WAAW,CAAC,IAAa;IAChC,IAAI,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC;QACxB,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO,KAAK,CAAC,GAAG,CAAC,aAAa,CAAC,CAAC;QACvD,OAAO,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,cAAc,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAC3D,CAAC;IACD,IAAI,OAAO,IAAI,KAAK,QAAQ,IAAI,IAAI,KAAK,IAAI,EAAE,CAAC;QAC9C,OAAO,cAAc,CAAC,IAA+B,CAAC,CAAC;IACzD,CAAC;IACD,OAAO,MAAM,CAAC,IAAI,CAAC,CAAC;AACtB,CAAC;AAED,SAAS,cAAc,CAAC,GAA4B;IAClD,MAAM,OAAO,GAAG,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;IACpC,OAAO,OAAO;SACX,GAAG,CAAC,CAAC,CAAC,GAAG,EAAE,KAAK,CAAC,EAAE,EAAE;QACpB,MAAM,KAAK,GAAG,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC;QACzC,MAAM,GAAG,GAAG,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,IAAI,EAAE,CAAC,CAAC;QAC1E,OAAO,GAAG,KAAK,IAAI,GAAG,EAAE,CAAC;IAC3B,CAAC,CAAC;SACD,IAAI,CAAC,IAAI,CAAC,CAAC;AAChB,CAAC;AAED,MAAM,UAAU,aAAa,CAAC,IAA4D,EAAE,MAAoB;IAC9G,OAAO;QACL,IAAI,EAAE,IAAI,CAAC,IAAI;QACf,IAAI,EAAE,IAAI,CAAC,WAAW,CAAC,IAAI,IAAI,EAAE;QACjC,MAAM,EAAE,IAAI,CAAC,WAAW,CAAC,MAAM,IAAI,EAAE;QACrC,IAAI,EAAE,IAAI,CAAC,WAAW,CAAC,IAAI,IAAI,EAAE;KAClC,CAAC;AACJ,CAAC"}
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env node
2
+ export {};
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":""}
package/dist/index.js ADDED
@@ -0,0 +1,23 @@
1
+ #!/usr/bin/env node
2
+ import { Command } from 'commander';
3
+ import { registerSearchCommand } from './commands/search.js';
4
+ import { registerTagsCommand } from './commands/tags.js';
5
+ import { registerHealthCommand } from './commands/health.js';
6
+ import { registerCreateCommand } from './commands/create.js';
7
+ import { registerReadCommand } from './commands/read.js';
8
+ import { registerInfoCommand } from './commands/info.js';
9
+ const program = new Command();
10
+ program
11
+ .name('vaultctl')
12
+ .description('Structured Obsidian vault operations without MCP servers')
13
+ .version('0.1.0')
14
+ .option('--vault <path>', 'Path to Obsidian vault')
15
+ .option('--format <format>', 'Output format: json or table', 'json');
16
+ registerSearchCommand(program);
17
+ registerTagsCommand(program);
18
+ registerHealthCommand(program);
19
+ registerCreateCommand(program);
20
+ registerReadCommand(program);
21
+ registerInfoCommand(program);
22
+ program.parse();
23
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAEA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,qBAAqB,EAAE,MAAM,sBAAsB,CAAC;AAC7D,OAAO,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AACzD,OAAO,EAAE,qBAAqB,EAAE,MAAM,sBAAsB,CAAC;AAC7D,OAAO,EAAE,qBAAqB,EAAE,MAAM,sBAAsB,CAAC;AAC7D,OAAO,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AACzD,OAAO,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AAEzD,MAAM,OAAO,GAAG,IAAI,OAAO,EAAE,CAAC;AAE9B,OAAO;KACJ,IAAI,CAAC,UAAU,CAAC;KAChB,WAAW,CAAC,0DAA0D,CAAC;KACvE,OAAO,CAAC,OAAO,CAAC;KAChB,MAAM,CAAC,gBAAgB,EAAE,wBAAwB,CAAC;KAClD,MAAM,CAAC,mBAAmB,EAAE,8BAA8B,EAAE,MAAM,CAAC,CAAC;AAEvE,qBAAqB,CAAC,OAAO,CAAC,CAAC;AAC/B,mBAAmB,CAAC,OAAO,CAAC,CAAC;AAC7B,qBAAqB,CAAC,OAAO,CAAC,CAAC;AAC/B,qBAAqB,CAAC,OAAO,CAAC,CAAC;AAC/B,mBAAmB,CAAC,OAAO,CAAC,CAAC;AAC7B,mBAAmB,CAAC,OAAO,CAAC,CAAC;AAE7B,OAAO,CAAC,KAAK,EAAE,CAAC"}
package/package.json ADDED
@@ -0,0 +1,17 @@
1
+ {
2
+ "name": "vaultctl",
3
+ "version": "0.1.0",
4
+ "type": "module",
5
+ "files": ["dist"],
6
+ "bin": {
7
+ "vaultctl": "./dist/index.js"
8
+ },
9
+ "scripts": {
10
+ "build": "tsc"
11
+ },
12
+ "dependencies": {
13
+ "@vaultctl/core": "^0.1.0",
14
+ "chalk": "^5.4.0",
15
+ "commander": "^13.0.0"
16
+ }
17
+ }