@bitbonsai/mcpvault 0.12.6 → 0.14.1
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 +6 -14
- package/dist/src/createServer.d.ts.map +1 -1
- package/dist/src/createServer.js +43 -0
- package/dist/src/filesystem.d.ts +3 -1
- package/dist/src/filesystem.d.ts.map +1 -1
- package/dist/src/filesystem.js +111 -0
- package/dist/src/pathfilter.d.ts.map +1 -1
- package/dist/src/pathfilter.js +5 -3
- package/dist/src/types.d.ts +10 -0
- package/dist/src/types.d.ts.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,6 +1,4 @@
|
|
|
1
|
-
<div align="center">
|
|
2
|
-
<img width="256" height="256" alt="image" src="https://github.com/user-attachments/assets/1e21d898-811b-42c2-a810-bf921dde0f58" />
|
|
3
|
-
</div>
|
|
1
|
+
<div align="center"> <img width="256" height="256" alt="image" src="https://github.com/user-attachments/assets/1e21d898-811b-42c2-a810-bf921dde0f58" /> </div>
|
|
4
2
|
|
|
5
3
|
# MCPVault
|
|
6
4
|
|
|
@@ -18,12 +16,7 @@ A universal AI bridge for Obsidian vaults using the Model Context Protocol (MCP)
|
|
|
18
16
|
|
|
19
17
|
<div align="center">
|
|
20
18
|
|
|
21
|
-
[](https://github.com/bitbonsai/mcpvault)
|
|
22
|
-
[](https://www.npmjs.com/package/@bitbonsai/mcpvault)
|
|
23
|
-
[](https://www.npmjs.com/package/@bitbonsai/mcpvault)
|
|
24
|
-
[](https://github.com/sponsors/bitbonsai)
|
|
25
|
-
[](https://ko-fi.com/bitbonsai)
|
|
26
|
-
[](https://liberapay.com/bitbonsai/)
|
|
19
|
+
[](https://github.com/bitbonsai/mcpvault) [](https://www.npmjs.com/package/@bitbonsai/mcpvault) [](https://www.npmjs.com/package/@bitbonsai/mcpvault) [](https://github.com/sponsors/bitbonsai) [](https://ko-fi.com/bitbonsai) [](https://liberapay.com/bitbonsai/)
|
|
27
20
|
|
|
28
21
|
</div>
|
|
29
22
|
|
|
@@ -126,8 +119,9 @@ MCP is an open protocol. You're not tied to any specific vendor or platform. You
|
|
|
126
119
|
|
|
127
120
|
- ✅ Safe frontmatter parsing and validation using gray-matter with AST-aware updates that preserve raw formatting for unmodified fields
|
|
128
121
|
- ✅ Path filtering to exclude `.obsidian` directory and other system files
|
|
129
|
-
- ✅ **Complete MCP toolkit**:
|
|
122
|
+
- ✅ **Complete MCP toolkit**: 18 tools covering all vault operations
|
|
130
123
|
- File operations: `read_note`, `write_note`, `patch_note`, `delete_note`, `move_note`, `move_file`
|
|
124
|
+
- Partial reads: `get_note_outline` (headings without loading the full file), `read_note_lines` (a specific line range)
|
|
131
125
|
- Directory operations: `list_directory`
|
|
132
126
|
- Batch operations: `read_multiple_notes`
|
|
133
127
|
- Search: `search_notes` with multi-word matching and BM25 relevance reranking
|
|
@@ -283,8 +277,7 @@ _Note: ChatGPT Desktop's MCP integration is currently limited to enterprise subs
|
|
|
283
277
|
|
|
284
278
|
Claude Code uses `.claude.json` configuration file:
|
|
285
279
|
|
|
286
|
-
**User-scoped (recommended):**
|
|
287
|
-
Edit `~/.claude.json`:
|
|
280
|
+
**User-scoped (recommended):** Edit `~/.claude.json`:
|
|
288
281
|
|
|
289
282
|
```json
|
|
290
283
|
{
|
|
@@ -298,8 +291,7 @@ Edit `~/.claude.json`:
|
|
|
298
291
|
}
|
|
299
292
|
```
|
|
300
293
|
|
|
301
|
-
**Project-scoped:**
|
|
302
|
-
Edit `.claude.json` in your project or add to the projects section:
|
|
294
|
+
**Project-scoped:** Edit `.claude.json` in your project or add to the projects section:
|
|
303
295
|
|
|
304
296
|
```json
|
|
305
297
|
{
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"createServer.d.ts","sourceRoot":"","sources":["../../src/createServer.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,2CAA2C,CAAC;AAMnE,OAAO,EAAE,kBAAkB,EAAoB,MAAM,kBAAkB,CAAC;AACxE,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAK7C,MAAM,WAAW,mBAAmB;IAClC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,UAAU,CAAC,EAAE,UAAU,CAAC;IACxB,kBAAkB,CAAC,EAAE,kBAAkB,CAAC;CACzC;AAED,wBAAgB,YAAY,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,GAAE,mBAAwB,GAAG,MAAM,
|
|
1
|
+
{"version":3,"file":"createServer.d.ts","sourceRoot":"","sources":["../../src/createServer.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,2CAA2C,CAAC;AAMnE,OAAO,EAAE,kBAAkB,EAAoB,MAAM,kBAAkB,CAAC;AACxE,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAK7C,MAAM,WAAW,mBAAmB;IAClC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,UAAU,CAAC,EAAE,UAAU,CAAC;IACxB,kBAAkB,CAAC,EAAE,kBAAkB,CAAC;CACzC;AAED,wBAAgB,YAAY,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,GAAE,mBAAwB,GAAG,MAAM,CAudzF"}
|
package/dist/src/createServer.js
CHANGED
|
@@ -230,6 +230,32 @@ export function createServer(vaultPath, options = {}) {
|
|
|
230
230
|
},
|
|
231
231
|
required: ["document"]
|
|
232
232
|
}
|
|
233
|
+
},
|
|
234
|
+
{
|
|
235
|
+
name: "get_note_outline",
|
|
236
|
+
description: "Get the heading structure of a note without reading its full content. Returns headings with level, text, and line number. Use this first to navigate large notes efficiently, then call read_note_lines to read only the section you need.",
|
|
237
|
+
inputSchema: {
|
|
238
|
+
type: "object",
|
|
239
|
+
properties: {
|
|
240
|
+
path: { type: "string", description: "Path to the note relative to vault root" },
|
|
241
|
+
prettyPrint: { type: "boolean", description: "Format JSON response with indentation (default: false)", default: false }
|
|
242
|
+
},
|
|
243
|
+
required: ["path"]
|
|
244
|
+
}
|
|
245
|
+
},
|
|
246
|
+
{
|
|
247
|
+
name: "read_note_lines",
|
|
248
|
+
description: "Read a specific line range from a note. Use after get_note_outline to read only the section you need instead of the full file.",
|
|
249
|
+
inputSchema: {
|
|
250
|
+
type: "object",
|
|
251
|
+
properties: {
|
|
252
|
+
path: { type: "string", description: "Path to the note relative to vault root" },
|
|
253
|
+
startLine: { type: "number", description: "First line to read (1-indexed, inclusive)" },
|
|
254
|
+
endLine: { type: "number", description: "Last line to read (1-indexed, inclusive)" },
|
|
255
|
+
prettyPrint: { type: "boolean", description: "Format JSON response with indentation (default: false)", default: false }
|
|
256
|
+
},
|
|
257
|
+
required: ["path", "startLine", "endLine"]
|
|
258
|
+
}
|
|
233
259
|
}
|
|
234
260
|
]
|
|
235
261
|
};
|
|
@@ -394,6 +420,23 @@ export function createServer(vaultPath, options = {}) {
|
|
|
394
420
|
}
|
|
395
421
|
case "wiki_link":
|
|
396
422
|
return await handleWikiLinkTool(fileSystem, trimmedArgs);
|
|
423
|
+
case "get_note_outline": {
|
|
424
|
+
const headings = await fileSystem.getNoteOutline(trimmedArgs.path);
|
|
425
|
+
const indent = trimmedArgs.prettyPrint ? 2 : undefined;
|
|
426
|
+
return {
|
|
427
|
+
content: [{ type: "text", text: JSON.stringify(headings, null, indent) }]
|
|
428
|
+
};
|
|
429
|
+
}
|
|
430
|
+
case "read_note_lines": {
|
|
431
|
+
const text = await fileSystem.readNoteLines({
|
|
432
|
+
path: trimmedArgs.path,
|
|
433
|
+
startLine: trimmedArgs.startLine,
|
|
434
|
+
endLine: trimmedArgs.endLine
|
|
435
|
+
});
|
|
436
|
+
return {
|
|
437
|
+
content: [{ type: "text", text }]
|
|
438
|
+
};
|
|
439
|
+
}
|
|
397
440
|
default:
|
|
398
441
|
throw new Error(`Unknown tool: ${toolName}`);
|
|
399
442
|
}
|
package/dist/src/filesystem.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { FrontmatterHandler } from './frontmatter.js';
|
|
2
2
|
import { PathFilter } from './pathfilter.js';
|
|
3
|
-
import type { ParsedNote, DirectoryListing, NoteWriteParams, DeleteNoteParams, DeleteResult, MoveNoteParams, MoveFileParams, MoveResult, BatchReadParams, BatchReadResult, UpdateFrontmatterParams, NoteInfo, TagManagementParams, TagManagementResult, PatchNoteParams, PatchNoteResult, VaultStats } from './types.js';
|
|
3
|
+
import type { ParsedNote, DirectoryListing, NoteWriteParams, DeleteNoteParams, DeleteResult, MoveNoteParams, MoveFileParams, MoveResult, BatchReadParams, BatchReadResult, UpdateFrontmatterParams, NoteInfo, TagManagementParams, TagManagementResult, PatchNoteParams, PatchNoteResult, VaultStats, NoteHeading, ReadNoteLinesParams } from './types.js';
|
|
4
4
|
/**
|
|
5
5
|
* Map a filesystem write failure to a clear, accurate Error.
|
|
6
6
|
*
|
|
@@ -53,6 +53,8 @@ export declare class FileSystemService {
|
|
|
53
53
|
* Throws only on caller misuse (empty name).
|
|
54
54
|
*/
|
|
55
55
|
findPathForWikiLink(wikiLinkName: string): Promise<string[]>;
|
|
56
|
+
getNoteOutline(path: string): Promise<NoteHeading[]>;
|
|
57
|
+
readNoteLines(params: ReadNoteLinesParams): Promise<string>;
|
|
56
58
|
getVaultStats(recentCount?: number): Promise<VaultStats>;
|
|
57
59
|
listAllTags(): Promise<Array<{
|
|
58
60
|
tag: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"filesystem.d.ts","sourceRoot":"","sources":["../../src/filesystem.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AACtD,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAE7C,OAAO,KAAK,EAAE,UAAU,EAAE,gBAAgB,EAAE,eAAe,EAAE,gBAAgB,EAAE,YAAY,EAAE,cAAc,EAAE,cAAc,EAAE,UAAU,EAAE,eAAe,EAAE,eAAe,EAAE,uBAAuB,EAAE,QAAQ,EAAE,mBAAmB,EAAE,mBAAmB,EAAE,eAAe,EAAE,eAAe,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"filesystem.d.ts","sourceRoot":"","sources":["../../src/filesystem.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AACtD,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAE7C,OAAO,KAAK,EAAE,UAAU,EAAE,gBAAgB,EAAE,eAAe,EAAE,gBAAgB,EAAE,YAAY,EAAE,cAAc,EAAE,cAAc,EAAE,UAAU,EAAE,eAAe,EAAE,eAAe,EAAE,uBAAuB,EAAE,QAAQ,EAAE,mBAAmB,EAAE,mBAAmB,EAAE,eAAe,EAAE,eAAe,EAAE,UAAU,EAAE,WAAW,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAC;AAE3V;;;;;;;;GAQG;AACH,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,GAAG,KAAK,CAiBtE;AAoBD,qBAAa,iBAAiB;IAK1B,OAAO,CAAC,SAAS;IAJnB,OAAO,CAAC,kBAAkB,CAAqB;IAC/C,OAAO,CAAC,UAAU,CAAa;IAE/B,YACU,SAAS,EAAE,MAAM,EACzB,UAAU,CAAC,EAAE,UAAU,EACvB,kBAAkB,CAAC,EAAE,kBAAkB,EAWxC;IAED;;;;OAIG;IACH,OAAO,CAAC,aAAa;IAsBrB,OAAO,CAAC,WAAW;IAkDb,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC,CA+BhD;IAEK,SAAS,CAAC,MAAM,EAAE,eAAe,GAAG,OAAO,CAAC,IAAI,CAAC,CA0EtD;IAEK,SAAS,CAAC,MAAM,EAAE,eAAe,GAAG,OAAO,CAAC,eAAe,CAAC,CA4FjE;IAEK,aAAa,CAAC,IAAI,GAAE,MAAW,GAAG,OAAO,CAAC,gBAAgB,CAAC,CA4DhE;IAEK,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAc3C;IAEK,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAchD;IAEK,UAAU,CAAC,MAAM,EAAE,gBAAgB,GAAG,OAAO,CAAC,YAAY,CAAC,CAyGhE;IAEK,QAAQ,CAAC,MAAM,EAAE,cAAc,GAAG,OAAO,CAAC,UAAU,CAAC,CAoF1D;IAEK,QAAQ,CAAC,MAAM,EAAE,cAAc,GAAG,OAAO,CAAC,UAAU,CAAC,CA+H1D;IAEK,iBAAiB,CAAC,MAAM,EAAE,eAAe,GAAG,OAAO,CAAC,eAAe,CAAC,CA+CzE;IAEK,iBAAiB,CAAC,MAAM,EAAE,uBAAuB,GAAG,OAAO,CAAC,IAAI,CAAC,CAoCtE;IAEK,YAAY,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,QAAQ,EAAE,CAAC,CA0CvD;IAEK,UAAU,CAAC,MAAM,EAAE,mBAAmB,GAAG,OAAO,CAAC,mBAAmB,CAAC,CAqG1E;IAED,YAAY,IAAI,MAAM,CAErB;IAED;;;;;;;;;;;;;;OAcG;IACG,mBAAmB,CAAC,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CA+CjE;IAEK,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,EAAE,CAAC,CA+EzD;IAEK,aAAa,CAAC,MAAM,EAAE,mBAAmB,GAAG,OAAO,CAAC,MAAM,CAAC,CAehE;IAEK,aAAa,CAAC,WAAW,GAAE,MAAU,GAAG,OAAO,CAAC,UAAU,CAAC,CAuDhE;IAEK,WAAW,IAAI,OAAO,CAAC,KAAK,CAAC;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC,CAiDlE;CACF"}
|
package/dist/src/filesystem.js
CHANGED
|
@@ -33,6 +33,23 @@ export function classifyWriteError(error, path) {
|
|
|
33
33
|
}
|
|
34
34
|
return new Error(`Failed to write file: ${path} - ${error instanceof Error ? error.message : 'Unknown error'}`);
|
|
35
35
|
}
|
|
36
|
+
/**
|
|
37
|
+
* Strip an ATX heading's optional closing sequence of #s per CommonMark: it
|
|
38
|
+
* must be preceded by a space (or the text is nothing but #s, i.e. an empty
|
|
39
|
+
* heading with a closer and no content) and followed only by trailing spaces
|
|
40
|
+
* (already removed by the caller's trim). A closer with no preceding space
|
|
41
|
+
* (e.g. "Heading###") is not a valid closer and stays as literal text.
|
|
42
|
+
*/
|
|
43
|
+
function stripAtxClosingSequence(text) {
|
|
44
|
+
const withPrecedingSpace = /^(.*[ \t])#+$/.exec(text);
|
|
45
|
+
if (withPrecedingSpace) {
|
|
46
|
+
return withPrecedingSpace[1].replace(/[ \t]+$/, '');
|
|
47
|
+
}
|
|
48
|
+
if (/^#+$/.test(text)) {
|
|
49
|
+
return '';
|
|
50
|
+
}
|
|
51
|
+
return text;
|
|
52
|
+
}
|
|
36
53
|
export class FileSystemService {
|
|
37
54
|
vaultPath;
|
|
38
55
|
frontmatterHandler;
|
|
@@ -946,6 +963,100 @@ export class FileSystemService {
|
|
|
946
963
|
});
|
|
947
964
|
return matches;
|
|
948
965
|
}
|
|
966
|
+
async getNoteOutline(path) {
|
|
967
|
+
path = this.normalizePath(path);
|
|
968
|
+
if (!this.pathFilter.isAllowed(path)) {
|
|
969
|
+
throw new Error(`Access denied: ${path}. This path is restricted (system files like .obsidian, .git, and dotfiles are not accessible).`);
|
|
970
|
+
}
|
|
971
|
+
const fullPath = this.resolvePath(path);
|
|
972
|
+
const raw = await readFile(fullPath, 'utf-8');
|
|
973
|
+
const lines = raw.split('\n');
|
|
974
|
+
const headings = [];
|
|
975
|
+
// Per CommonMark ATX headings: up to 3 leading spaces are allowed before
|
|
976
|
+
// the #s; the heading may have no text at all (bare `#`); and an optional
|
|
977
|
+
// closing sequence of #s (preceded by a space, followed only by trailing
|
|
978
|
+
// spaces) is stripped from the returned text rather than kept literally.
|
|
979
|
+
const headingRegex = /^ {0,3}(#{1,6})(?:[ \t]+(.*))?$/;
|
|
980
|
+
// Frontmatter delimiters (---) can themselves look like content but never
|
|
981
|
+
// contain real headings; skip the block so YAML comments (# ...) inside it
|
|
982
|
+
// can't be misdetected as headings. Handles both LF and CRLF line endings,
|
|
983
|
+
// since split('\n') leaves a trailing \r on each line for CRLF files.
|
|
984
|
+
let inFrontmatter = false;
|
|
985
|
+
let frontmatterEnded = false;
|
|
986
|
+
// Fenced code blocks (``` or ~~~) can contain lines that look like
|
|
987
|
+
// headings (e.g. a shell comment or markdown example) but aren't real
|
|
988
|
+
// structure; track fence state and skip everything inside one.
|
|
989
|
+
// Per CommonMark: a fence marker may be indented up to 3 spaces; the
|
|
990
|
+
// opener records both its character and its length, and only a line
|
|
991
|
+
// with the *same* character, at least as many markers, and nothing but
|
|
992
|
+
// trailing whitespace after them closes it (mismatched length, a
|
|
993
|
+
// different character, or trailing content like a language tag on a
|
|
994
|
+
// would-be closer must NOT end the block).
|
|
995
|
+
let inFence = false;
|
|
996
|
+
let fenceChar = '';
|
|
997
|
+
let fenceLength = 0;
|
|
998
|
+
const fenceRegex = /^ {0,3}(`{3,}|~{3,})(.*)$/;
|
|
999
|
+
for (let i = 0; i < lines.length; i++) {
|
|
1000
|
+
const line = lines[i];
|
|
1001
|
+
const trimmed = line.replace(/\r$/, '');
|
|
1002
|
+
if (!frontmatterEnded && i === 0 && trimmed === '---') {
|
|
1003
|
+
inFrontmatter = true;
|
|
1004
|
+
continue;
|
|
1005
|
+
}
|
|
1006
|
+
if (inFrontmatter) {
|
|
1007
|
+
if (trimmed === '---') {
|
|
1008
|
+
inFrontmatter = false;
|
|
1009
|
+
frontmatterEnded = true;
|
|
1010
|
+
}
|
|
1011
|
+
continue;
|
|
1012
|
+
}
|
|
1013
|
+
frontmatterEnded = true;
|
|
1014
|
+
const fenceMatch = fenceRegex.exec(trimmed);
|
|
1015
|
+
if (fenceMatch) {
|
|
1016
|
+
const markers = fenceMatch[1];
|
|
1017
|
+
const trailing = fenceMatch[2];
|
|
1018
|
+
const char = markers.charAt(0);
|
|
1019
|
+
if (!inFence) {
|
|
1020
|
+
inFence = true;
|
|
1021
|
+
fenceChar = char;
|
|
1022
|
+
fenceLength = markers.length;
|
|
1023
|
+
}
|
|
1024
|
+
else if (char === fenceChar && markers.length >= fenceLength && trailing.trim() === '') {
|
|
1025
|
+
inFence = false;
|
|
1026
|
+
fenceChar = '';
|
|
1027
|
+
fenceLength = 0;
|
|
1028
|
+
}
|
|
1029
|
+
// Any other fence-like line while inFence (mismatched char, too
|
|
1030
|
+
// short, or has trailing content) is just code-block content.
|
|
1031
|
+
continue;
|
|
1032
|
+
}
|
|
1033
|
+
if (inFence) {
|
|
1034
|
+
continue;
|
|
1035
|
+
}
|
|
1036
|
+
const match = headingRegex.exec(trimmed);
|
|
1037
|
+
if (match) {
|
|
1038
|
+
const rawText = (match[2] ?? '').trim();
|
|
1039
|
+
headings.push({ level: match[1].length, text: stripAtxClosingSequence(rawText), line: i + 1 });
|
|
1040
|
+
}
|
|
1041
|
+
}
|
|
1042
|
+
return headings;
|
|
1043
|
+
}
|
|
1044
|
+
async readNoteLines(params) {
|
|
1045
|
+
const path = this.normalizePath(params.path);
|
|
1046
|
+
if (!this.pathFilter.isAllowed(path)) {
|
|
1047
|
+
throw new Error(`Access denied: ${path}. This path is restricted (system files like .obsidian, .git, and dotfiles are not accessible).`);
|
|
1048
|
+
}
|
|
1049
|
+
const fullPath = this.resolvePath(path);
|
|
1050
|
+
const raw = await readFile(fullPath, 'utf-8');
|
|
1051
|
+
const lines = raw.split('\n');
|
|
1052
|
+
// Both bounds are clamped into [1, lines.length] rather than trusting
|
|
1053
|
+
// caller-supplied indices directly - out-of-range start/end (0, negative,
|
|
1054
|
+
// or past EOF) previously either threw or silently wrapped via
|
|
1055
|
+
// Array.slice's negative-index behavior instead of clamping like end did.
|
|
1056
|
+
const clampedStart = Math.min(Math.max(params.startLine, 1), lines.length);
|
|
1057
|
+
const clampedEnd = Math.min(Math.max(params.endLine, clampedStart), lines.length);
|
|
1058
|
+
return lines.slice(clampedStart - 1, clampedEnd).join('\n');
|
|
1059
|
+
}
|
|
949
1060
|
async getVaultStats(recentCount = 5) {
|
|
950
1061
|
let totalNotes = 0;
|
|
951
1062
|
let totalFolders = 0;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pathfilter.d.ts","sourceRoot":"","sources":["../../src/pathfilter.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAEnD,qBAAa,UAAU;IAOrB,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,mBAAmB,CAMxC;IAEH,OAAO,CAAC,eAAe,CAAW;IAClC,OAAO,CAAC,iBAAiB,CAAW;IAEpC,YAAY,MAAM,CAAC,EAAE,OAAO,CAAC,gBAAgB,CAAC,EAuB7C;IAED,OAAO,CAAC,eAAe;IAoBvB;;;;;;OAMG;IACH,OAAO,CAAC,oBAAoB;IAQ5B,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAuB/B;IAED,mBAAmB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAUzC;IAED,OAAO,CAAC,aAAa;
|
|
1
|
+
{"version":3,"file":"pathfilter.d.ts","sourceRoot":"","sources":["../../src/pathfilter.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAEnD,qBAAa,UAAU;IAOrB,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,mBAAmB,CAMxC;IAEH,OAAO,CAAC,eAAe,CAAW;IAClC,OAAO,CAAC,iBAAiB,CAAW;IAEpC,YAAY,MAAM,CAAC,EAAE,OAAO,CAAC,gBAAgB,CAAC,EAuB7C;IAED,OAAO,CAAC,eAAe;IAoBvB;;;;;;OAMG;IACH,OAAO,CAAC,oBAAoB;IAQ5B,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAuB/B;IAED,mBAAmB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAUzC;IAED,OAAO,CAAC,aAAa;IA+BrB,OAAO,CAAC,MAAM;IA0Bd,WAAW,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,MAAM,EAAE,CAErC;CACF"}
|
package/dist/src/pathfilter.js
CHANGED
|
@@ -99,10 +99,12 @@ export class PathFilter {
|
|
|
99
99
|
// (".Git/config", ".git./config", ".git /config") cannot bypass the deny-list
|
|
100
100
|
// on case-insensitive / Windows filesystems.
|
|
101
101
|
const canonicalPath = this.canonicalizeForMatch(normalizedPath);
|
|
102
|
-
// Deny restricted directories/files at any depth
|
|
103
|
-
//
|
|
102
|
+
// Deny hidden paths and restricted directories/files at any depth. Dotfiles
|
|
103
|
+
// are outside the public vault-note surface even when their suffix looks
|
|
104
|
+
// like an allowed note extension (for example, `.secrets.md`).
|
|
104
105
|
for (const segment of canonicalPath.split('/')) {
|
|
105
|
-
if (
|
|
106
|
+
if (segment.startsWith('.') ||
|
|
107
|
+
PathFilter.RESTRICTED_SEGMENTS.has(segment.toLowerCase())) {
|
|
106
108
|
return true;
|
|
107
109
|
}
|
|
108
110
|
}
|
package/dist/src/types.d.ts
CHANGED
|
@@ -128,6 +128,16 @@ export interface TagManagementResult {
|
|
|
128
128
|
success: boolean;
|
|
129
129
|
message?: string;
|
|
130
130
|
}
|
|
131
|
+
export interface NoteHeading {
|
|
132
|
+
level: number;
|
|
133
|
+
text: string;
|
|
134
|
+
line: number;
|
|
135
|
+
}
|
|
136
|
+
export interface ReadNoteLinesParams {
|
|
137
|
+
path: string;
|
|
138
|
+
startLine: number;
|
|
139
|
+
endLine: number;
|
|
140
|
+
}
|
|
131
141
|
export interface VaultStats {
|
|
132
142
|
totalNotes: number;
|
|
133
143
|
totalFolders: number;
|
package/dist/src/types.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/types.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/types.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED