neuro-vault-mcp 1.7.0 → 1.7.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/dist/cli.d.ts +2 -0
- package/dist/cli.js +62 -13
- package/dist/cli.js.map +1 -1
- package/package.json +3 -2
package/dist/cli.d.ts
CHANGED
|
@@ -131,6 +131,7 @@ interface ReadNoteInput {
|
|
|
131
131
|
}
|
|
132
132
|
interface ReadNoteResult {
|
|
133
133
|
path: string;
|
|
134
|
+
frontmatter: Record<string, unknown> | null;
|
|
134
135
|
content: string;
|
|
135
136
|
}
|
|
136
137
|
interface CreateNoteInput {
|
|
@@ -151,6 +152,7 @@ interface EditNoteInput {
|
|
|
151
152
|
}
|
|
152
153
|
interface DailyNoteResult {
|
|
153
154
|
path: string;
|
|
155
|
+
frontmatter: Record<string, unknown> | null;
|
|
154
156
|
content: string;
|
|
155
157
|
}
|
|
156
158
|
interface AppendDailyInput {
|
package/dist/cli.js
CHANGED
|
@@ -14874,9 +14874,47 @@ async function createSemanticModule(config2, deps = {}) {
|
|
|
14874
14874
|
// src/modules/operations/obsidian-cli-provider.ts
|
|
14875
14875
|
import { execFile } from "child_process";
|
|
14876
14876
|
import { promisify } from "util";
|
|
14877
|
+
|
|
14878
|
+
// src/modules/operations/frontmatter.ts
|
|
14879
|
+
import { parse as parseYaml } from "yaml";
|
|
14880
|
+
var FRONTMATTER_OPEN = /^---[ \t]*\r?\n/;
|
|
14881
|
+
var FRONTMATTER_CLOSE = /(^|\r?\n)---[ \t]*(\r?\n|$)/;
|
|
14882
|
+
function splitFrontmatter(raw) {
|
|
14883
|
+
const openMatch = raw.match(FRONTMATTER_OPEN);
|
|
14884
|
+
if (!openMatch) {
|
|
14885
|
+
return { frontmatter: null, content: raw };
|
|
14886
|
+
}
|
|
14887
|
+
const afterOpen = raw.slice(openMatch[0].length);
|
|
14888
|
+
const closeMatch = afterOpen.match(FRONTMATTER_CLOSE);
|
|
14889
|
+
if (!closeMatch || closeMatch.index === void 0) {
|
|
14890
|
+
return { frontmatter: null, content: raw };
|
|
14891
|
+
}
|
|
14892
|
+
const yamlBody = afterOpen.slice(0, closeMatch.index);
|
|
14893
|
+
const content = afterOpen.slice(closeMatch.index + closeMatch[0].length);
|
|
14894
|
+
let parsed;
|
|
14895
|
+
try {
|
|
14896
|
+
parsed = parseYaml(yamlBody);
|
|
14897
|
+
} catch (err) {
|
|
14898
|
+
console.warn(
|
|
14899
|
+
`[neuro-vault] frontmatter YAML parse failed: ${err.message}; returning raw content`
|
|
14900
|
+
);
|
|
14901
|
+
return { frontmatter: null, content: raw };
|
|
14902
|
+
}
|
|
14903
|
+
if (parsed === null || parsed === void 0) {
|
|
14904
|
+
return { frontmatter: {}, content };
|
|
14905
|
+
}
|
|
14906
|
+
if (typeof parsed !== "object" || Array.isArray(parsed)) {
|
|
14907
|
+
console.warn(
|
|
14908
|
+
`[neuro-vault] frontmatter parsed to non-object (${typeof parsed}); returning raw content`
|
|
14909
|
+
);
|
|
14910
|
+
return { frontmatter: null, content: raw };
|
|
14911
|
+
}
|
|
14912
|
+
return { frontmatter: parsed, content };
|
|
14913
|
+
}
|
|
14914
|
+
|
|
14915
|
+
// src/modules/operations/obsidian-cli-provider.ts
|
|
14877
14916
|
var DEFAULT_BINARY = "obsidian";
|
|
14878
14917
|
var DEFAULT_TIMEOUT_MS = 1e4;
|
|
14879
|
-
var SEPARATOR = "\n---\n";
|
|
14880
14918
|
var execFileAsync = promisify(execFile);
|
|
14881
14919
|
var defaultExec = async (binary, args, options) => {
|
|
14882
14920
|
const result = await execFileAsync(binary, args, {
|
|
@@ -14903,8 +14941,10 @@ var ObsidianCLIProvider = class {
|
|
|
14903
14941
|
this.exec = opts.exec ?? defaultExec;
|
|
14904
14942
|
}
|
|
14905
14943
|
async readNote(input) {
|
|
14944
|
+
const path5 = await this.resolvePath(input.identifier);
|
|
14906
14945
|
const { stdout } = await this.runCommand("read", [identifierToArg(input.identifier)]);
|
|
14907
|
-
|
|
14946
|
+
const { frontmatter, content } = splitFrontmatter(stdout);
|
|
14947
|
+
return { path: path5, frontmatter, content };
|
|
14908
14948
|
}
|
|
14909
14949
|
async createNote(input) {
|
|
14910
14950
|
if (input.name === void 0 && input.path === void 0) {
|
|
@@ -14926,8 +14966,11 @@ var ObsidianCLIProvider = class {
|
|
|
14926
14966
|
]);
|
|
14927
14967
|
}
|
|
14928
14968
|
async readDaily() {
|
|
14969
|
+
const { stdout: pathStdout } = await this.runCommand("daily:path", []);
|
|
14970
|
+
const path5 = pathStdout.trim();
|
|
14929
14971
|
const { stdout } = await this.runCommand("daily:read", []);
|
|
14930
|
-
|
|
14972
|
+
const { frontmatter, content } = splitFrontmatter(stdout);
|
|
14973
|
+
return { path: path5, frontmatter, content };
|
|
14931
14974
|
}
|
|
14932
14975
|
async appendDaily(input) {
|
|
14933
14976
|
await this.runCommand("daily:append", [`content=${input.content}`]);
|
|
@@ -15108,15 +15151,21 @@ var ObsidianCLIProvider = class {
|
|
|
15108
15151
|
if (this.vaultName) args.push(`vault=${this.vaultName}`);
|
|
15109
15152
|
return args;
|
|
15110
15153
|
}
|
|
15111
|
-
|
|
15112
|
-
|
|
15113
|
-
|
|
15114
|
-
|
|
15154
|
+
async resolvePath(identifier) {
|
|
15155
|
+
if (identifier.kind === "path") return identifier.value;
|
|
15156
|
+
const { stdout } = await this.runCommand("file", [identifierToArg(identifier)]);
|
|
15157
|
+
for (const line of stdout.split(/\r?\n/)) {
|
|
15158
|
+
const idx = line.indexOf(" ");
|
|
15159
|
+
if (idx === -1) continue;
|
|
15160
|
+
if (line.slice(0, idx).trim() === "path") {
|
|
15161
|
+
return line.slice(idx + 1).trim();
|
|
15162
|
+
}
|
|
15115
15163
|
}
|
|
15116
|
-
|
|
15117
|
-
|
|
15118
|
-
|
|
15119
|
-
|
|
15164
|
+
throw new ToolHandlerError(
|
|
15165
|
+
"CLI_ERROR",
|
|
15166
|
+
`Could not resolve path for name '${identifier.value}': 'path' not found in obsidian file output`,
|
|
15167
|
+
{ details: { name: identifier.value, stdout: stdout.slice(0, 500) } }
|
|
15168
|
+
);
|
|
15120
15169
|
}
|
|
15121
15170
|
};
|
|
15122
15171
|
|
|
@@ -15371,7 +15420,7 @@ function buildOperationsTools(handlers) {
|
|
|
15371
15420
|
name: "read_note",
|
|
15372
15421
|
spec: {
|
|
15373
15422
|
title: "Read Note",
|
|
15374
|
-
description: "Read a note's contents. Provide either `name` (wikilink-style, resolves like Obsidian) or `path` (vault-relative, exact). Returns `{ path, content }
|
|
15423
|
+
description: "Read a note's contents. Provide either `name` (wikilink-style, resolves like Obsidian) or `path` (vault-relative, exact). Returns `{ path, frontmatter, content }` where `frontmatter` is the parsed YAML object (or `null` if absent/malformed) and `content` is the body without the YAML block.",
|
|
15375
15424
|
inputSchema: readNoteSchema
|
|
15376
15425
|
},
|
|
15377
15426
|
handler: async (args) => invokeTool(() => handlers.readNote(readNoteSchema.parse(args)))
|
|
@@ -15398,7 +15447,7 @@ function buildOperationsTools(handlers) {
|
|
|
15398
15447
|
name: "read_daily",
|
|
15399
15448
|
spec: {
|
|
15400
15449
|
title: "Read Daily",
|
|
15401
|
-
description: "Read today's daily note. Returns `{ path, content }
|
|
15450
|
+
description: "Read today's daily note. Returns `{ path, frontmatter, content }` where `frontmatter` is the parsed YAML object (or `null` if absent/malformed) and `content` is the body without the YAML block. Useful for 'what's on my agenda?' questions.",
|
|
15402
15451
|
inputSchema: readDailySchema
|
|
15403
15452
|
},
|
|
15404
15453
|
handler: async () => invokeTool(() => handlers.readDaily({}))
|