@sunub/obsidian-mcp-server 0.3.15 → 0.3.17
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/{build → dist}/config.d.ts +1 -1
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +59 -0
- package/dist/config.js.map +1 -0
- package/dist/db.js +58 -0
- package/dist/db.js.map +1 -0
- package/dist/index.js +52 -0
- package/dist/index.js.map +1 -0
- package/dist/server.js +42 -0
- package/dist/server.js.map +1 -0
- package/dist/setup.js +114 -0
- package/dist/setup.js.map +1 -0
- package/{build → dist}/tools/create_document_with_properties/index.d.ts +1 -1
- package/dist/tools/create_document_with_properties/index.js +115 -0
- package/dist/tools/create_document_with_properties/index.js.map +1 -0
- package/{build → dist}/tools/create_document_with_properties/params.d.ts +2 -2
- package/dist/tools/create_document_with_properties/params.js +33 -0
- package/dist/tools/create_document_with_properties/params.js.map +1 -0
- package/{build → dist}/tools/generate_property/index.d.ts +1 -1
- package/dist/tools/generate_property/index.js +86 -0
- package/dist/tools/generate_property/index.js.map +1 -0
- package/dist/tools/generate_property/params.js +55 -0
- package/dist/tools/generate_property/params.js.map +1 -0
- package/dist/tools/index.js +13 -0
- package/dist/tools/index.js.map +1 -0
- package/{build → dist}/tools/organize_attachments/index.d.ts +1 -1
- package/dist/tools/organize_attachments/index.js +86 -0
- package/dist/tools/organize_attachments/index.js.map +1 -0
- package/dist/tools/organize_attachments/params.js +61 -0
- package/dist/tools/organize_attachments/params.js.map +1 -0
- package/{build → dist}/tools/organize_attachments/utils.d.ts +1 -1
- package/dist/tools/organize_attachments/utils.js +66 -0
- package/dist/tools/organize_attachments/utils.js.map +1 -0
- package/{build → dist}/tools/vault/index.d.ts +1 -1
- package/dist/tools/vault/index.js +104 -0
- package/dist/tools/vault/index.js.map +1 -0
- package/dist/tools/vault/metrics.js +130 -0
- package/dist/tools/vault/metrics.js.map +1 -0
- package/{build → dist}/tools/vault/params.d.ts +2 -2
- package/dist/tools/vault/params.js +148 -0
- package/dist/tools/vault/params.js.map +1 -0
- package/dist/tools/vault/types/collect_context.js +103 -0
- package/dist/tools/vault/types/collect_context.js.map +1 -0
- package/dist/tools/vault/types/list_all.js +53 -0
- package/dist/tools/vault/types/list_all.js.map +1 -0
- package/dist/tools/vault/types/read_specific.js +41 -0
- package/dist/tools/vault/types/read_specific.js.map +1 -0
- package/dist/tools/vault/types/search.js +59 -0
- package/dist/tools/vault/types/search.js.map +1 -0
- package/dist/tools/vault/utils/actions/collect_context.d.ts +5 -0
- package/dist/tools/vault/utils/actions/collect_context.js +765 -0
- package/dist/tools/vault/utils/actions/collect_context.js.map +1 -0
- package/dist/tools/vault/utils/actions/index_rag.js +27 -0
- package/dist/tools/vault/utils/actions/index_rag.js.map +1 -0
- package/dist/tools/vault/utils/actions/list_all.d.ts +5 -0
- package/dist/tools/vault/utils/actions/list_all.js +43 -0
- package/dist/tools/vault/utils/actions/list_all.js.map +1 -0
- package/dist/tools/vault/utils/actions/load_memory.d.ts +5 -0
- package/dist/tools/vault/utils/actions/load_memory.js +186 -0
- package/dist/tools/vault/utils/actions/load_memory.js.map +1 -0
- package/{build → dist}/tools/vault/utils/actions/read.d.ts +2 -2
- package/dist/tools/vault/utils/actions/read.js +68 -0
- package/dist/tools/vault/utils/actions/read.js.map +1 -0
- package/{build → dist}/tools/vault/utils/actions/search.d.ts +2 -2
- package/dist/tools/vault/utils/actions/search.js +104 -0
- package/dist/tools/vault/utils/actions/search.js.map +1 -0
- package/{build → dist}/tools/vault/utils/actions/stats.d.ts +1 -1
- package/dist/tools/vault/utils/actions/stats.js +9 -0
- package/dist/tools/vault/utils/actions/stats.js.map +1 -0
- package/dist/tools/vault/utils/constants.js +3 -0
- package/dist/tools/vault/utils/constants.js.map +1 -0
- package/{build → dist}/tools/vault/utils/document.d.ts +3 -3
- package/dist/tools/vault/utils/document.js +50 -0
- package/dist/tools/vault/utils/document.js.map +1 -0
- package/{build → dist}/tools/vault/utils/shared.d.ts +1 -1
- package/dist/tools/vault/utils/shared.js +75 -0
- package/dist/tools/vault/utils/shared.js.map +1 -0
- package/dist/tools/vault/utils.d.ts +8 -0
- package/dist/tools/vault/utils.js +8 -0
- package/dist/tools/vault/utils.js.map +1 -0
- package/{build → dist}/tools/write_property/index.d.ts +1 -1
- package/dist/tools/write_property/index.js +120 -0
- package/dist/tools/write_property/index.js.map +1 -0
- package/dist/tools/write_property/params.js +52 -0
- package/dist/tools/write_property/params.js.map +1 -0
- package/{build → dist}/utils/DirectoryWalker.d.ts +1 -1
- package/dist/utils/DirectoryWalker.js +52 -0
- package/dist/utils/DirectoryWalker.js.map +1 -0
- package/dist/utils/Embedder.js +46 -0
- package/dist/utils/Embedder.js.map +1 -0
- package/{build → dist}/utils/Indexer.d.ts +2 -2
- package/dist/utils/Indexer.js +169 -0
- package/dist/utils/Indexer.js.map +1 -0
- package/dist/utils/LLMClient.js +112 -0
- package/dist/utils/LLMClient.js.map +1 -0
- package/dist/utils/LocalReranker.js +71 -0
- package/dist/utils/LocalReranker.js.map +1 -0
- package/{build → dist}/utils/RAGIndexer.d.ts +1 -1
- package/dist/utils/RAGIndexer.js +238 -0
- package/dist/utils/RAGIndexer.js.map +1 -0
- package/dist/utils/RerankerClient.js +89 -0
- package/dist/utils/RerankerClient.js.map +1 -0
- package/{build → dist}/utils/VaultManger/VaultManager.d.ts +3 -3
- package/dist/utils/VaultManger/VaultManager.js +459 -0
- package/dist/utils/VaultManger/VaultManager.js.map +1 -0
- package/dist/utils/VaultManger/VaultPathError.js +13 -0
- package/dist/utils/VaultManger/VaultPathError.js.map +1 -0
- package/dist/utils/VaultManger/index.d.ts +4 -0
- package/dist/utils/VaultManger/index.js +3 -0
- package/dist/utils/VaultManger/index.js.map +1 -0
- package/{build → dist}/utils/VaultManger/types.d.ts +1 -1
- package/dist/utils/VaultManger/types.js +2 -0
- package/dist/utils/VaultManger/types.js.map +1 -0
- package/dist/utils/VaultWatcher.js +60 -0
- package/dist/utils/VaultWatcher.js.map +1 -0
- package/dist/utils/VectorDB.js +268 -0
- package/dist/utils/VectorDB.js.map +1 -0
- package/dist/utils/constants.js +14 -0
- package/dist/utils/constants.js.map +1 -0
- package/dist/utils/createToolError.js +16 -0
- package/dist/utils/createToolError.js.map +1 -0
- package/dist/utils/getVaultManager.d.ts +3 -0
- package/dist/utils/getVaultManager.js +15 -0
- package/dist/utils/getVaultManager.js.map +1 -0
- package/dist/utils/processor/LinkExtractor.js +31 -0
- package/dist/utils/processor/LinkExtractor.js.map +1 -0
- package/dist/utils/processor/MatterParser.d.ts +3 -0
- package/dist/utils/processor/MatterParser.js +28 -0
- package/dist/utils/processor/MatterParser.js.map +1 -0
- package/dist/utils/processor/types.js +22 -0
- package/dist/utils/processor/types.js.map +1 -0
- package/dist/utils/semaphore.js +26 -0
- package/dist/utils/semaphore.js.map +1 -0
- package/package.json +19 -12
- package/build/config.d.ts.map +0 -1
- package/build/index.js +0 -127331
- package/build/index.js.map +0 -828
- package/build/lancedb.linux-x64-gnu-1e1af8yx.node +0 -0
- package/build/tools/vault/utils/actions/collect_context.d.ts +0 -5
- package/build/tools/vault/utils/actions/list_all.d.ts +0 -5
- package/build/tools/vault/utils/actions/load_memory.d.ts +0 -5
- package/build/tools/vault/utils.d.ts +0 -8
- package/build/utils/VaultManger/index.d.ts +0 -4
- package/build/utils/getVaultManager.d.ts +0 -3
- package/build/utils/processor/MatterParser.d.ts +0 -3
- /package/{build → dist}/db.d.ts +0 -0
- /package/{build → dist}/db.d.ts.map +0 -0
- /package/{build → dist}/index.d.ts +0 -0
- /package/{build → dist}/index.d.ts.map +0 -0
- /package/{build → dist}/server.d.ts +0 -0
- /package/{build → dist}/server.d.ts.map +0 -0
- /package/{build → dist}/setup.d.ts +0 -0
- /package/{build → dist}/setup.d.ts.map +0 -0
- /package/{build → dist}/tools/create_document_with_properties/index.d.ts.map +0 -0
- /package/{build → dist}/tools/create_document_with_properties/params.d.ts.map +0 -0
- /package/{build → dist}/tools/generate_property/index.d.ts.map +0 -0
- /package/{build → dist}/tools/generate_property/params.d.ts +0 -0
- /package/{build → dist}/tools/generate_property/params.d.ts.map +0 -0
- /package/{build → dist}/tools/index.d.ts +0 -0
- /package/{build → dist}/tools/index.d.ts.map +0 -0
- /package/{build → dist}/tools/organize_attachments/index.d.ts.map +0 -0
- /package/{build → dist}/tools/organize_attachments/params.d.ts +0 -0
- /package/{build → dist}/tools/organize_attachments/params.d.ts.map +0 -0
- /package/{build → dist}/tools/organize_attachments/utils.d.ts.map +0 -0
- /package/{build → dist}/tools/vault/index.d.ts.map +0 -0
- /package/{build → dist}/tools/vault/metrics.d.ts +0 -0
- /package/{build → dist}/tools/vault/metrics.d.ts.map +0 -0
- /package/{build → dist}/tools/vault/params.d.ts.map +0 -0
- /package/{build → dist}/tools/vault/types/collect_context.d.ts +0 -0
- /package/{build → dist}/tools/vault/types/collect_context.d.ts.map +0 -0
- /package/{build → dist}/tools/vault/types/list_all.d.ts +0 -0
- /package/{build → dist}/tools/vault/types/list_all.d.ts.map +0 -0
- /package/{build → dist}/tools/vault/types/read_specific.d.ts +0 -0
- /package/{build → dist}/tools/vault/types/read_specific.d.ts.map +0 -0
- /package/{build → dist}/tools/vault/types/search.d.ts +0 -0
- /package/{build → dist}/tools/vault/types/search.d.ts.map +0 -0
- /package/{build → dist}/tools/vault/utils/actions/collect_context.d.ts.map +0 -0
- /package/{build → dist}/tools/vault/utils/actions/index_rag.d.ts +0 -0
- /package/{build → dist}/tools/vault/utils/actions/index_rag.d.ts.map +0 -0
- /package/{build → dist}/tools/vault/utils/actions/list_all.d.ts.map +0 -0
- /package/{build → dist}/tools/vault/utils/actions/load_memory.d.ts.map +0 -0
- /package/{build → dist}/tools/vault/utils/actions/read.d.ts.map +0 -0
- /package/{build → dist}/tools/vault/utils/actions/search.d.ts.map +0 -0
- /package/{build → dist}/tools/vault/utils/actions/stats.d.ts.map +0 -0
- /package/{build → dist}/tools/vault/utils/constants.d.ts +0 -0
- /package/{build → dist}/tools/vault/utils/constants.d.ts.map +0 -0
- /package/{build → dist}/tools/vault/utils/document.d.ts.map +0 -0
- /package/{build → dist}/tools/vault/utils/shared.d.ts.map +0 -0
- /package/{build → dist}/tools/vault/utils.d.ts.map +0 -0
- /package/{build → dist}/tools/write_property/index.d.ts.map +0 -0
- /package/{build → dist}/tools/write_property/params.d.ts +0 -0
- /package/{build → dist}/tools/write_property/params.d.ts.map +0 -0
- /package/{build → dist}/utils/DirectoryWalker.d.ts.map +0 -0
- /package/{build → dist}/utils/Embedder.d.ts +0 -0
- /package/{build → dist}/utils/Embedder.d.ts.map +0 -0
- /package/{build → dist}/utils/Indexer.d.ts.map +0 -0
- /package/{build → dist}/utils/LLMClient.d.ts +0 -0
- /package/{build → dist}/utils/LLMClient.d.ts.map +0 -0
- /package/{build → dist}/utils/LocalReranker.d.ts +0 -0
- /package/{build → dist}/utils/LocalReranker.d.ts.map +0 -0
- /package/{build → dist}/utils/RAGIndexer.d.ts.map +0 -0
- /package/{build → dist}/utils/RerankerClient.d.ts +0 -0
- /package/{build → dist}/utils/RerankerClient.d.ts.map +0 -0
- /package/{build → dist}/utils/VaultManger/VaultManager.d.ts.map +0 -0
- /package/{build → dist}/utils/VaultManger/VaultPathError.d.ts +0 -0
- /package/{build → dist}/utils/VaultManger/VaultPathError.d.ts.map +0 -0
- /package/{build → dist}/utils/VaultManger/index.d.ts.map +0 -0
- /package/{build → dist}/utils/VaultManger/types.d.ts.map +0 -0
- /package/{build → dist}/utils/VaultWatcher.d.ts +0 -0
- /package/{build → dist}/utils/VaultWatcher.d.ts.map +0 -0
- /package/{build → dist}/utils/VectorDB.d.ts +0 -0
- /package/{build → dist}/utils/VectorDB.d.ts.map +0 -0
- /package/{build → dist}/utils/constants.d.ts +0 -0
- /package/{build → dist}/utils/constants.d.ts.map +0 -0
- /package/{build → dist}/utils/createToolError.d.ts +0 -0
- /package/{build → dist}/utils/createToolError.d.ts.map +0 -0
- /package/{build → dist}/utils/getVaultManager.d.ts.map +0 -0
- /package/{build → dist}/utils/processor/LinkExtractor.d.ts +0 -0
- /package/{build → dist}/utils/processor/LinkExtractor.d.ts.map +0 -0
- /package/{build → dist}/utils/processor/MatterParser.d.ts.map +0 -0
- /package/{build → dist}/utils/processor/types.d.ts +0 -0
- /package/{build → dist}/utils/processor/types.d.ts.map +0 -0
- /package/{build → dist}/utils/semaphore.d.ts +0 -0
- /package/{build → dist}/utils/semaphore.d.ts.map +0 -0
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
export async function getDocumentContent(vaultManager, filename, maxContentPreview) {
|
|
2
|
+
const doc = await vaultManager.getDocumentInfo(filename, {
|
|
3
|
+
includeStats: true,
|
|
4
|
+
maxContentPreview,
|
|
5
|
+
});
|
|
6
|
+
if (!doc)
|
|
7
|
+
return {};
|
|
8
|
+
return doc;
|
|
9
|
+
}
|
|
10
|
+
export function formatDocument(doc, includeContent, excerptLength) {
|
|
11
|
+
const hasContentProperty = "content" in doc && typeof doc.content === "string";
|
|
12
|
+
const sourceContentLength = "stats" in doc && doc.stats ? doc.stats.contentLength : doc.contentLength;
|
|
13
|
+
const contentIsTruncated = !!excerptLength &&
|
|
14
|
+
hasContentProperty &&
|
|
15
|
+
typeof sourceContentLength === "number" &&
|
|
16
|
+
sourceContentLength > doc.content.length;
|
|
17
|
+
const createContentObject = () => {
|
|
18
|
+
if (includeContent && hasContentProperty) {
|
|
19
|
+
const excerpt = excerptLength && doc.content?.length > excerptLength
|
|
20
|
+
? `${doc.content?.substring(0, excerptLength)}...`
|
|
21
|
+
: doc.content;
|
|
22
|
+
return {
|
|
23
|
+
full: doc.content,
|
|
24
|
+
excerpt,
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
return {
|
|
28
|
+
preview: "(Content not loaded)",
|
|
29
|
+
note: "Full content available with includeContent=true",
|
|
30
|
+
};
|
|
31
|
+
};
|
|
32
|
+
return {
|
|
33
|
+
filename: doc.filePath.split("/").pop() || doc.filePath,
|
|
34
|
+
fullPath: doc.filePath,
|
|
35
|
+
metadata: {
|
|
36
|
+
title: doc.frontmatter.title || "Untitled",
|
|
37
|
+
tags: doc.frontmatter.tags || [],
|
|
38
|
+
},
|
|
39
|
+
stats: "stats" in doc && doc.stats
|
|
40
|
+
? doc.stats
|
|
41
|
+
: {
|
|
42
|
+
contentLength: doc.contentLength,
|
|
43
|
+
hasContent: hasContentProperty,
|
|
44
|
+
wordCount: 0,
|
|
45
|
+
},
|
|
46
|
+
content: createContentObject(),
|
|
47
|
+
content_is_truncated: contentIsTruncated,
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
//# sourceMappingURL=document.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"document.js","sourceRoot":"","sources":["../../../../src/tools/vault/utils/document.ts"],"names":[],"mappings":"AAIA,MAAM,CAAC,KAAK,UAAU,kBAAkB,CACvC,YAA0B,EAC1B,QAAgB,EAChB,iBAA0B;IAE1B,MAAM,GAAG,GAAG,MAAM,YAAY,CAAC,eAAe,CAAC,QAAQ,EAAE;QACxD,YAAY,EAAE,IAAI;QAClB,iBAAiB;KACjB,CAAC,CAAC;IACH,IAAI,CAAC,GAAG;QAAE,OAAO,EAAE,CAAC;IACpB,OAAO,GAAG,CAAC;AACZ,CAAC;AAED,MAAM,UAAU,cAAc,CAC7B,GAAqC,EACrC,cAAuB,EACvB,aAAsB;IAEtB,MAAM,kBAAkB,GACvB,SAAS,IAAI,GAAG,IAAI,OAAO,GAAG,CAAC,OAAO,KAAK,QAAQ,CAAC;IACrD,MAAM,mBAAmB,GACxB,OAAO,IAAI,GAAG,IAAI,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,aAAa,CAAC,CAAC,CAAC,GAAG,CAAC,aAAa,CAAC;IAC3E,MAAM,kBAAkB,GACvB,CAAC,CAAC,aAAa;QACf,kBAAkB;QAClB,OAAO,mBAAmB,KAAK,QAAQ;QACvC,mBAAmB,GAAG,GAAG,CAAC,OAAO,CAAC,MAAM,CAAC;IAE1C,MAAM,mBAAmB,GAAG,GAAG,EAAE;QAChC,IAAI,cAAc,IAAI,kBAAkB,EAAE,CAAC;YAC1C,MAAM,OAAO,GACZ,aAAa,IAAI,GAAG,CAAC,OAAO,EAAE,MAAM,GAAG,aAAa;gBACnD,CAAC,CAAC,GAAG,GAAG,CAAC,OAAO,EAAE,SAAS,CAAC,CAAC,EAAE,aAAa,CAAC,KAAK;gBAClD,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC;YAChB,OAAO;gBACN,IAAI,EAAE,GAAG,CAAC,OAAO;gBACjB,OAAO;aACP,CAAC;QACH,CAAC;QAED,OAAO;YACN,OAAO,EAAE,sBAAsB;YAC/B,IAAI,EAAE,iDAAiD;SACvD,CAAC;IACH,CAAC,CAAC;IAEF,OAAO;QACN,QAAQ,EAAE,GAAG,CAAC,QAAQ,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,IAAI,GAAG,CAAC,QAAQ;QACvD,QAAQ,EAAE,GAAG,CAAC,QAAQ;QACtB,QAAQ,EAAE;YACT,KAAK,EAAE,GAAG,CAAC,WAAW,CAAC,KAAK,IAAI,UAAU;YAC1C,IAAI,EAAE,GAAG,CAAC,WAAW,CAAC,IAAI,IAAI,EAAE;SAChC;QACD,KAAK,EACJ,OAAO,IAAI,GAAG,IAAI,GAAG,CAAC,KAAK;YAC1B,CAAC,CAAC,GAAG,CAAC,KAAK;YACX,CAAC,CAAC;gBACA,aAAa,EAAE,GAAG,CAAC,aAAa;gBAChC,UAAU,EAAE,kBAAkB;gBAC9B,SAAS,EAAE,CAAC;aACZ;QACJ,OAAO,EAAE,mBAAmB,EAAE;QAC9B,oBAAoB,EAAE,kBAAkB;KACxC,CAAC;AACH,CAAC"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { ObsidianContentQueryParams } from "
|
|
1
|
+
import type { ObsidianContentQueryParams } from "../../../tools/vault/params.js";
|
|
2
2
|
export type CompressionMode = "aggressive" | "balanced" | "none";
|
|
3
3
|
export declare const SEARCH_DEFAULT_LIMIT: Record<Exclude<CompressionMode, "none">, number>;
|
|
4
4
|
export declare const SEARCH_DEFAULT_EXCERPT: Record<Exclude<CompressionMode, "none">, number>;
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
export const SEARCH_DEFAULT_LIMIT = {
|
|
2
|
+
aggressive: 3,
|
|
3
|
+
balanced: 5,
|
|
4
|
+
};
|
|
5
|
+
export const SEARCH_DEFAULT_EXCERPT = {
|
|
6
|
+
aggressive: 220,
|
|
7
|
+
balanced: 500,
|
|
8
|
+
};
|
|
9
|
+
export const READ_DEFAULT_CONTENT_MAX_CHARS = {
|
|
10
|
+
aggressive: 1200,
|
|
11
|
+
balanced: 2500,
|
|
12
|
+
};
|
|
13
|
+
export const READ_DEFAULT_BACKLINK_LIMIT = {
|
|
14
|
+
aggressive: 5,
|
|
15
|
+
balanced: 10,
|
|
16
|
+
};
|
|
17
|
+
export const ACTION_DEFAULT_MAX_OUTPUT_CHARS = {
|
|
18
|
+
search: {
|
|
19
|
+
aggressive: 1800,
|
|
20
|
+
balanced: 2500,
|
|
21
|
+
},
|
|
22
|
+
read: {
|
|
23
|
+
aggressive: 2200,
|
|
24
|
+
balanced: 4000,
|
|
25
|
+
},
|
|
26
|
+
collect_context: {
|
|
27
|
+
aggressive: 2800,
|
|
28
|
+
balanced: 5200,
|
|
29
|
+
},
|
|
30
|
+
load_memory: {
|
|
31
|
+
aggressive: 2000,
|
|
32
|
+
balanced: 3200,
|
|
33
|
+
},
|
|
34
|
+
};
|
|
35
|
+
export function resolveCompressionMode(params) {
|
|
36
|
+
return params.compressionMode ?? "balanced";
|
|
37
|
+
}
|
|
38
|
+
function estimateTokensByChars(chars) {
|
|
39
|
+
return Math.ceil(chars / 3);
|
|
40
|
+
}
|
|
41
|
+
export function finalizePayloadWithCompression(payload, compression) {
|
|
42
|
+
const output_chars = JSON.stringify(payload).length;
|
|
43
|
+
const estimated_tokens = estimateTokensByChars(output_chars);
|
|
44
|
+
return {
|
|
45
|
+
...payload,
|
|
46
|
+
compression: {
|
|
47
|
+
...compression,
|
|
48
|
+
output_chars,
|
|
49
|
+
estimated_tokens,
|
|
50
|
+
},
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
export function jsonCharLength(data) {
|
|
54
|
+
return JSON.stringify(data).length;
|
|
55
|
+
}
|
|
56
|
+
export function trimWithEllipsis(value, maxLength) {
|
|
57
|
+
if (value.length <= maxLength) {
|
|
58
|
+
return value;
|
|
59
|
+
}
|
|
60
|
+
return `${value.substring(0, maxLength)}...`;
|
|
61
|
+
}
|
|
62
|
+
export function normalizeWhitespace(value) {
|
|
63
|
+
return value.replace(/\s+/g, " ").trim();
|
|
64
|
+
}
|
|
65
|
+
export function stripFrontmatterBlock(content) {
|
|
66
|
+
if (!content.startsWith("---")) {
|
|
67
|
+
return content;
|
|
68
|
+
}
|
|
69
|
+
const end = content.indexOf("\n---", 3);
|
|
70
|
+
if (end === -1) {
|
|
71
|
+
return content;
|
|
72
|
+
}
|
|
73
|
+
return content.substring(end + 4).trimStart();
|
|
74
|
+
}
|
|
75
|
+
//# sourceMappingURL=shared.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"shared.js","sourceRoot":"","sources":["../../../../src/tools/vault/utils/shared.ts"],"names":[],"mappings":"AAIA,MAAM,CAAC,MAAM,oBAAoB,GAG7B;IACH,UAAU,EAAE,CAAC;IACb,QAAQ,EAAE,CAAC;CACX,CAAC;AAEF,MAAM,CAAC,MAAM,sBAAsB,GAG/B;IACH,UAAU,EAAE,GAAG;IACf,QAAQ,EAAE,GAAG;CACb,CAAC;AAEF,MAAM,CAAC,MAAM,8BAA8B,GAGvC;IACH,UAAU,EAAE,IAAI;IAChB,QAAQ,EAAE,IAAI;CACd,CAAC;AAEF,MAAM,CAAC,MAAM,2BAA2B,GAGpC;IACH,UAAU,EAAE,CAAC;IACb,QAAQ,EAAE,EAAE;CACZ,CAAC;AAEF,MAAM,CAAC,MAAM,+BAA+B,GAGxC;IACH,MAAM,EAAE;QACP,UAAU,EAAE,IAAI;QAChB,QAAQ,EAAE,IAAI;KACd;IACD,IAAI,EAAE;QACL,UAAU,EAAE,IAAI;QAChB,QAAQ,EAAE,IAAI;KACd;IACD,eAAe,EAAE;QAChB,UAAU,EAAE,IAAI;QAChB,QAAQ,EAAE,IAAI;KACd;IACD,WAAW,EAAE;QACZ,UAAU,EAAE,IAAI;QAChB,QAAQ,EAAE,IAAI;KACd;CACD,CAAC;AAEF,MAAM,UAAU,sBAAsB,CACrC,MAAkC;IAElC,OAAO,MAAM,CAAC,eAAe,IAAI,UAAU,CAAC;AAC7C,CAAC;AAED,SAAS,qBAAqB,CAAC,KAAa;IAC3C,OAAO,IAAI,CAAC,IAAI,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC;AAC7B,CAAC;AAED,MAAM,UAAU,8BAA8B,CAG7C,OAAU,EACV,WAMC;IAYD,MAAM,YAAY,GAAG,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC,MAAM,CAAC;IACpD,MAAM,gBAAgB,GAAG,qBAAqB,CAAC,YAAY,CAAC,CAAC;IAC7D,OAAO;QACN,GAAG,OAAO;QACV,WAAW,EAAE;YACZ,GAAG,WAAW;YACd,YAAY;YACZ,gBAAgB;SAChB;KACD,CAAC;AACH,CAAC;AAED,MAAM,UAAU,cAAc,CAAC,IAAa;IAC3C,OAAO,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC;AACpC,CAAC;AAED,MAAM,UAAU,gBAAgB,CAAC,KAAa,EAAE,SAAiB;IAChE,IAAI,KAAK,CAAC,MAAM,IAAI,SAAS,EAAE,CAAC;QAC/B,OAAO,KAAK,CAAC;IACd,CAAC;IACD,OAAO,GAAG,KAAK,CAAC,SAAS,CAAC,CAAC,EAAE,SAAS,CAAC,KAAK,CAAC;AAC9C,CAAC;AAED,MAAM,UAAU,mBAAmB,CAAC,KAAa;IAChD,OAAO,KAAK,CAAC,OAAO,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC;AAC1C,CAAC;AAED,MAAM,UAAU,qBAAqB,CAAC,OAAe;IACpD,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,KAAK,CAAC,EAAE,CAAC;QAChC,OAAO,OAAO,CAAC;IAChB,CAAC;IACD,MAAM,GAAG,GAAG,OAAO,CAAC,OAAO,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC;IACxC,IAAI,GAAG,KAAK,CAAC,CAAC,EAAE,CAAC;QAChB,OAAO,OAAO,CAAC;IAChB,CAAC;IACD,OAAO,OAAO,CAAC,SAAS,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC;AAC/C,CAAC"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export { collectContext } from "../../tools/vault/utils/actions/collect_context.js";
|
|
2
|
+
export { triggerIndexing } from "../../tools/vault/utils/actions/index_rag.js";
|
|
3
|
+
export { listAllDocuments } from "../../tools/vault/utils/actions/list_all.js";
|
|
4
|
+
export { loadMemory } from "../../tools/vault/utils/actions/load_memory.js";
|
|
5
|
+
export { readSpecificFile } from "../../tools/vault/utils/actions/read.js";
|
|
6
|
+
export { searchDocuments } from "../../tools/vault/utils/actions/search.js";
|
|
7
|
+
export { statsAllDocuments } from "../../tools/vault/utils/actions/stats.js";
|
|
8
|
+
//# sourceMappingURL=utils.d.ts.map
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export { collectContext } from "../../tools/vault/utils/actions/collect_context.js";
|
|
2
|
+
export { triggerIndexing } from "../../tools/vault/utils/actions/index_rag.js";
|
|
3
|
+
export { listAllDocuments } from "../../tools/vault/utils/actions/list_all.js";
|
|
4
|
+
export { loadMemory } from "../../tools/vault/utils/actions/load_memory.js";
|
|
5
|
+
export { readSpecificFile } from "../../tools/vault/utils/actions/read.js";
|
|
6
|
+
export { searchDocuments } from "../../tools/vault/utils/actions/search.js";
|
|
7
|
+
export { statsAllDocuments } from "../../tools/vault/utils/actions/stats.js";
|
|
8
|
+
//# sourceMappingURL=utils.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"utils.js","sourceRoot":"","sources":["../../../src/tools/vault/utils.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,gDAAgD,CAAC;AAChF,OAAO,EAAE,eAAe,EAAE,MAAM,0CAA0C,CAAC;AAC3E,OAAO,EAAE,gBAAgB,EAAE,MAAM,yCAAyC,CAAC;AAC3E,OAAO,EAAE,UAAU,EAAE,MAAM,4CAA4C,CAAC;AACxE,OAAO,EAAE,gBAAgB,EAAE,MAAM,qCAAqC,CAAC;AACvE,OAAO,EAAE,eAAe,EAAE,MAAM,uCAAuC,CAAC;AACxE,OAAO,EAAE,iBAAiB,EAAE,MAAM,sCAAsC,CAAC"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
2
2
|
import type { CallToolResult, ToolAnnotations } from "@modelcontextprotocol/sdk/types.js";
|
|
3
|
-
import { type ObsidianPropertyParams } from "
|
|
3
|
+
import { type ObsidianPropertyParams } from "../../tools/write_property/params.js";
|
|
4
4
|
export declare const name = "write_property";
|
|
5
5
|
export declare const annotations: ToolAnnotations;
|
|
6
6
|
export declare const description = "\n Description: Adds or updates properties within the frontmatter section at the top of a specified Obsidian markdown file. This tool is primarily used to apply metadata generated by the 'generate_property' tool to an actual file.\n \n Parameters:\n \n - filePath (string, required): The path to the target markdown file to which properties will be added or updated.\n Example: \"my-first-post.md\"\n \n - properties (object, required): A JSON object containing the key-value pairs to be written to the file's frontmatter. If a property with the same key already exists in the file, it will be overwritten with the new value.\n \n Example:\n \n JSON\n {\n \"title\": \"Optimizing I/O Handling in a Serverless Environment\",\n \"date\": \"2025-04-03\",\n \"tags\": [\"serverless\", \"optimization\"],\n \"summary\": \"A case study on optimizing I/O in a serverless environment by benchmarking Promise.all and Workers.\",\n \"completed\": true\n }\n\n Return Value:\n \n Upon successful execution, it returns a JSON object containing the status, a confirmation message, and the property object that was applied to the file.\n \n Example:\n \n JSON\n {\n \"status\": \"success\",\n \"message\": \"Successfully updated properties for my-first-post.md\",\n \"properties\": {\n \"title\": \"Optimizing I/O Handling in a Serverless Environment\",\n \"date\": \"2025-04-03\",\n \"tags\": [\"serverless\", \"optimization\"],\n \"summary\": \"A case study on optimizing I/O in a serverless environment by benchmarking Promise.all and Workers.\",\n \"completed\": true\n }\n }\n\n Dependencies & Requirements:\n \n - Input Data: The properties parameter should typically be the JSON object output from the 'generate_property' tool.\n - Environment Setup: The absolute path to the user's Obsidian Vault must be correctly set as an environment variable.\n";
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
import state from "../../config.js";
|
|
2
|
+
import { obsidianPropertyParamsSchema, } from "../../tools/write_property/params.js";
|
|
3
|
+
import { createToolError } from "../../utils/createToolError.js";
|
|
4
|
+
import { getGlobalVaultManager } from "../../utils/getVaultManager.js";
|
|
5
|
+
import { VaultPathError } from "../../utils/VaultManger/VaultPathError.js";
|
|
6
|
+
export const name = "write_property";
|
|
7
|
+
export const annotations = {
|
|
8
|
+
title: "Write Obsidian Property",
|
|
9
|
+
openWorldHint: true,
|
|
10
|
+
};
|
|
11
|
+
export const description = `
|
|
12
|
+
Description: Adds or updates properties within the frontmatter section at the top of a specified Obsidian markdown file. This tool is primarily used to apply metadata generated by the 'generate_property' tool to an actual file.
|
|
13
|
+
|
|
14
|
+
Parameters:
|
|
15
|
+
|
|
16
|
+
- filePath (string, required): The path to the target markdown file to which properties will be added or updated.
|
|
17
|
+
Example: "my-first-post.md"
|
|
18
|
+
|
|
19
|
+
- properties (object, required): A JSON object containing the key-value pairs to be written to the file's frontmatter. If a property with the same key already exists in the file, it will be overwritten with the new value.
|
|
20
|
+
|
|
21
|
+
Example:
|
|
22
|
+
|
|
23
|
+
JSON
|
|
24
|
+
{
|
|
25
|
+
"title": "Optimizing I/O Handling in a Serverless Environment",
|
|
26
|
+
"date": "2025-04-03",
|
|
27
|
+
"tags": ["serverless", "optimization"],
|
|
28
|
+
"summary": "A case study on optimizing I/O in a serverless environment by benchmarking Promise.all and Workers.",
|
|
29
|
+
"completed": true
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
Return Value:
|
|
33
|
+
|
|
34
|
+
Upon successful execution, it returns a JSON object containing the status, a confirmation message, and the property object that was applied to the file.
|
|
35
|
+
|
|
36
|
+
Example:
|
|
37
|
+
|
|
38
|
+
JSON
|
|
39
|
+
{
|
|
40
|
+
"status": "success",
|
|
41
|
+
"message": "Successfully updated properties for my-first-post.md",
|
|
42
|
+
"properties": {
|
|
43
|
+
"title": "Optimizing I/O Handling in a Serverless Environment",
|
|
44
|
+
"date": "2025-04-03",
|
|
45
|
+
"tags": ["serverless", "optimization"],
|
|
46
|
+
"summary": "A case study on optimizing I/O in a serverless environment by benchmarking Promise.all and Workers.",
|
|
47
|
+
"completed": true
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
Dependencies & Requirements:
|
|
52
|
+
|
|
53
|
+
- Input Data: The properties parameter should typically be the JSON object output from the 'generate_property' tool.
|
|
54
|
+
- Environment Setup: The absolute path to the user's Obsidian Vault must be correctly set as an environment variable.
|
|
55
|
+
`;
|
|
56
|
+
export const register = (mcpServer) => {
|
|
57
|
+
mcpServer.registerTool(name, {
|
|
58
|
+
title: annotations.title || name,
|
|
59
|
+
description: description,
|
|
60
|
+
inputSchema: obsidianPropertyParamsSchema.shape,
|
|
61
|
+
annotations: annotations,
|
|
62
|
+
}, execute);
|
|
63
|
+
};
|
|
64
|
+
export const execute = async (params) => {
|
|
65
|
+
const vaultDirPath = state.vaultPath;
|
|
66
|
+
if (!vaultDirPath) {
|
|
67
|
+
return createToolError("VAULT_DIR_PATH is not set. Cannot write properties to file.", "Set the VAULT_DIR_PATH environment variable to your Obsidian vault path.");
|
|
68
|
+
}
|
|
69
|
+
let vaultManager = null;
|
|
70
|
+
try {
|
|
71
|
+
vaultManager = getGlobalVaultManager();
|
|
72
|
+
}
|
|
73
|
+
catch (e) {
|
|
74
|
+
return createToolError(e.message);
|
|
75
|
+
}
|
|
76
|
+
try {
|
|
77
|
+
await vaultManager.writeDocument(params.filePath, params.properties);
|
|
78
|
+
if (params.quiet) {
|
|
79
|
+
return {
|
|
80
|
+
isError: false,
|
|
81
|
+
content: [
|
|
82
|
+
{ type: "text", text: JSON.stringify({ status: "success" }) },
|
|
83
|
+
],
|
|
84
|
+
};
|
|
85
|
+
}
|
|
86
|
+
return {
|
|
87
|
+
isError: false,
|
|
88
|
+
content: [
|
|
89
|
+
{
|
|
90
|
+
type: "text",
|
|
91
|
+
text: JSON.stringify({
|
|
92
|
+
status: "success",
|
|
93
|
+
message: `Successfully updated properties for ${params.filePath}`,
|
|
94
|
+
properties: params.properties,
|
|
95
|
+
}, null, 2),
|
|
96
|
+
},
|
|
97
|
+
],
|
|
98
|
+
};
|
|
99
|
+
}
|
|
100
|
+
catch (error) {
|
|
101
|
+
if (error instanceof VaultPathError) {
|
|
102
|
+
return createToolError("filePath is outside VAULT_DIR_PATH. Writing outside the vault is blocked.", `Use a filePath inside VAULT_DIR_PATH ("${error.vaultPath}"). Received filePath: "${error.inputPath}"`);
|
|
103
|
+
}
|
|
104
|
+
return createToolError(error.message || "An unknown error occurred.");
|
|
105
|
+
}
|
|
106
|
+
};
|
|
107
|
+
const shorthandDescription = {
|
|
108
|
+
ko: "지정된 마크다운 파일의 프론트매터 속성을 제공된 JSON 데이터로 추가하거나 업데이트(덮어쓰기)합니다. 주로 'generate_property' 도구로 생성된 메타데이터를 실제 파일에 적용할 때 사용됩니다.",
|
|
109
|
+
en: "Adds or overwrites Markdown frontmatter properties using provided JSON. Typically used to apply the output from 'generate_property'",
|
|
110
|
+
};
|
|
111
|
+
export default {
|
|
112
|
+
name,
|
|
113
|
+
description,
|
|
114
|
+
annotations,
|
|
115
|
+
inputSchema: obsidianPropertyParamsSchema.shape,
|
|
116
|
+
execute,
|
|
117
|
+
register,
|
|
118
|
+
shorthandDescription,
|
|
119
|
+
};
|
|
120
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/tools/write_property/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
// input properties
|
|
3
|
+
const obsidianCssClassesProperty = z
|
|
4
|
+
.array(z.string())
|
|
5
|
+
.describe("List of CSS classes associated with the document");
|
|
6
|
+
const obsidianTagsProperty = z
|
|
7
|
+
.array(z.string())
|
|
8
|
+
.describe("List of tags associated with the document");
|
|
9
|
+
const obsidianTitleProperty = z.string().describe("Title of the document");
|
|
10
|
+
const obsidianDateProperty = z
|
|
11
|
+
.string()
|
|
12
|
+
.describe("Creation date of the document in ISO 8601 format");
|
|
13
|
+
const obsidianSummaryProperty = z
|
|
14
|
+
.string()
|
|
15
|
+
.describe("Brief summary or abstract of the document");
|
|
16
|
+
const obsidianSlugProperty = z
|
|
17
|
+
.string()
|
|
18
|
+
.describe("URL-friendly identifier for the document");
|
|
19
|
+
const obsidianCategoryProperty = z
|
|
20
|
+
.string()
|
|
21
|
+
.describe("Category or classification of the document");
|
|
22
|
+
const obsidianCompletedProperty = z
|
|
23
|
+
.boolean()
|
|
24
|
+
.describe("Indicates whether a task or item is completed");
|
|
25
|
+
const quiteMode = z
|
|
26
|
+
.boolean()
|
|
27
|
+
.default(true)
|
|
28
|
+
.describe("If true, suppresses non-error output messages. Default is false.");
|
|
29
|
+
const obsidianPropertySchema = z
|
|
30
|
+
.object({
|
|
31
|
+
cssclasses: obsidianCssClassesProperty.optional(),
|
|
32
|
+
tags: obsidianTagsProperty.optional(),
|
|
33
|
+
title: obsidianTitleProperty.optional(),
|
|
34
|
+
date: obsidianDateProperty.optional(),
|
|
35
|
+
summary: obsidianSummaryProperty.optional(),
|
|
36
|
+
slug: obsidianSlugProperty.optional(),
|
|
37
|
+
category: obsidianCategoryProperty.optional(),
|
|
38
|
+
completed: obsidianCompletedProperty.optional(),
|
|
39
|
+
})
|
|
40
|
+
.describe("Schema for Obsidian frontmatter properties");
|
|
41
|
+
// input schema
|
|
42
|
+
export const obsidianPropertyParamsSchema = z
|
|
43
|
+
.object({
|
|
44
|
+
filePath: z
|
|
45
|
+
.string()
|
|
46
|
+
.min(1)
|
|
47
|
+
.describe("Path to the target markdown file within the Obsidian vault"),
|
|
48
|
+
properties: obsidianPropertySchema.describe("Key-value pairs to be written to the file's frontmatter"),
|
|
49
|
+
quiet: quiteMode.optional(),
|
|
50
|
+
})
|
|
51
|
+
.describe("Parameters for writing properties to an Obsidian markdown file");
|
|
52
|
+
//# sourceMappingURL=params.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"params.js","sourceRoot":"","sources":["../../../src/tools/write_property/params.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,mBAAmB;AACnB,MAAM,0BAA0B,GAAG,CAAC;KAClC,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC;KACjB,QAAQ,CAAC,kDAAkD,CAAC,CAAC;AAC/D,MAAM,oBAAoB,GAAG,CAAC;KAC5B,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC;KACjB,QAAQ,CAAC,2CAA2C,CAAC,CAAC;AACxD,MAAM,qBAAqB,GAAG,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,uBAAuB,CAAC,CAAC;AAC3E,MAAM,oBAAoB,GAAG,CAAC;KAC5B,MAAM,EAAE;KACR,QAAQ,CAAC,kDAAkD,CAAC,CAAC;AAC/D,MAAM,uBAAuB,GAAG,CAAC;KAC/B,MAAM,EAAE;KACR,QAAQ,CAAC,2CAA2C,CAAC,CAAC;AACxD,MAAM,oBAAoB,GAAG,CAAC;KAC5B,MAAM,EAAE;KACR,QAAQ,CAAC,0CAA0C,CAAC,CAAC;AACvD,MAAM,wBAAwB,GAAG,CAAC;KAChC,MAAM,EAAE;KACR,QAAQ,CAAC,4CAA4C,CAAC,CAAC;AACzD,MAAM,yBAAyB,GAAG,CAAC;KACjC,OAAO,EAAE;KACT,QAAQ,CAAC,+CAA+C,CAAC,CAAC;AAC5D,MAAM,SAAS,GAAG,CAAC;KACjB,OAAO,EAAE;KACT,OAAO,CAAC,IAAI,CAAC;KACb,QAAQ,CAAC,kEAAkE,CAAC,CAAC;AAE/E,MAAM,sBAAsB,GAAG,CAAC;KAC9B,MAAM,CAAC;IACP,UAAU,EAAE,0BAA0B,CAAC,QAAQ,EAAE;IACjD,IAAI,EAAE,oBAAoB,CAAC,QAAQ,EAAE;IACrC,KAAK,EAAE,qBAAqB,CAAC,QAAQ,EAAE;IACvC,IAAI,EAAE,oBAAoB,CAAC,QAAQ,EAAE;IACrC,OAAO,EAAE,uBAAuB,CAAC,QAAQ,EAAE;IAC3C,IAAI,EAAE,oBAAoB,CAAC,QAAQ,EAAE;IACrC,QAAQ,EAAE,wBAAwB,CAAC,QAAQ,EAAE;IAC7C,SAAS,EAAE,yBAAyB,CAAC,QAAQ,EAAE;CAC/C,CAAC;KACD,QAAQ,CAAC,4CAA4C,CAAC,CAAC;AAEzD,eAAe;AACf,MAAM,CAAC,MAAM,4BAA4B,GAAG,CAAC;KAC3C,MAAM,CAAC;IACP,QAAQ,EAAE,CAAC;SACT,MAAM,EAAE;SACR,GAAG,CAAC,CAAC,CAAC;SACN,QAAQ,CAAC,4DAA4D,CAAC;IACxE,UAAU,EAAE,sBAAsB,CAAC,QAAQ,CAC1C,yDAAyD,CACzD;IACD,KAAK,EAAE,SAAS,CAAC,QAAQ,EAAE;CAC3B,CAAC;KACD,QAAQ,CAAC,gEAAgE,CAAC,CAAC"}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { readdir } from "node:fs/promises";
|
|
2
|
+
import { extname, join } from "node:path";
|
|
3
|
+
export class DirectoryWalker {
|
|
4
|
+
allowedExtensions;
|
|
5
|
+
constructor(allowedExtensions = [".md", ".mdx"]) {
|
|
6
|
+
this.allowedExtensions = allowedExtensions;
|
|
7
|
+
}
|
|
8
|
+
async walk(dirPath, ioSemaphore) {
|
|
9
|
+
const filePaths = [];
|
|
10
|
+
let entries = [];
|
|
11
|
+
await ioSemaphore.acquire();
|
|
12
|
+
try {
|
|
13
|
+
entries = await readdir(dirPath, { withFileTypes: true });
|
|
14
|
+
}
|
|
15
|
+
finally {
|
|
16
|
+
ioSemaphore.release();
|
|
17
|
+
}
|
|
18
|
+
try {
|
|
19
|
+
const tasks = entries.map(async (entry) => {
|
|
20
|
+
// Ignore dotfiles, .obsidian, and node_modules
|
|
21
|
+
if (entry.name.startsWith(".") ||
|
|
22
|
+
entry.name === "node_modules" ||
|
|
23
|
+
entry.name === ".obsidian") {
|
|
24
|
+
return [];
|
|
25
|
+
}
|
|
26
|
+
const fullPath = join(dirPath, entry.name);
|
|
27
|
+
if (entry.isDirectory()) {
|
|
28
|
+
// 하위 디렉토리 재귀 탐색
|
|
29
|
+
return this.walk(fullPath, ioSemaphore);
|
|
30
|
+
}
|
|
31
|
+
else if (entry.isFile()) {
|
|
32
|
+
const ext = extname(entry.name).toLowerCase();
|
|
33
|
+
if (this.allowedExtensions.includes(ext)) {
|
|
34
|
+
return [fullPath];
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
return [];
|
|
38
|
+
});
|
|
39
|
+
const results = await Promise.all(tasks);
|
|
40
|
+
results.forEach((subPaths) => {
|
|
41
|
+
if (subPaths) {
|
|
42
|
+
filePaths.push(...subPaths);
|
|
43
|
+
}
|
|
44
|
+
});
|
|
45
|
+
}
|
|
46
|
+
catch (error) {
|
|
47
|
+
console.error(`디렉토리 탐색 중 오류 발생: ${dirPath}`, error);
|
|
48
|
+
}
|
|
49
|
+
return filePaths;
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
//# sourceMappingURL=DirectoryWalker.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"DirectoryWalker.js","sourceRoot":"","sources":["../../src/utils/DirectoryWalker.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAC3C,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAG1C,MAAM,OAAO,eAAe;IACV,iBAAiB,CAAW;IAE7C,YAAY,oBAA8B,CAAC,KAAK,EAAE,MAAM,CAAC;QACxD,IAAI,CAAC,iBAAiB,GAAG,iBAAiB,CAAC;IAC5C,CAAC;IAEM,KAAK,CAAC,IAAI,CAChB,OAAe,EACf,WAAsB;QAEtB,MAAM,SAAS,GAAa,EAAE,CAAC;QAC/B,IAAI,OAAO,GAAa,EAAE,CAAC;QAC3B,MAAM,WAAW,CAAC,OAAO,EAAE,CAAC;QAC5B,IAAI,CAAC;YACJ,OAAO,GAAG,MAAM,OAAO,CAAC,OAAO,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC,CAAC;QAC3D,CAAC;gBAAS,CAAC;YACV,WAAW,CAAC,OAAO,EAAE,CAAC;QACvB,CAAC;QACD,IAAI,CAAC;YACJ,MAAM,KAAK,GAAG,OAAO,CAAC,GAAG,CAAC,KAAK,EAAE,KAAK,EAAE,EAAE;gBACzC,+CAA+C;gBAC/C,IACC,KAAK,CAAC,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC;oBAC1B,KAAK,CAAC,IAAI,KAAK,cAAc;oBAC7B,KAAK,CAAC,IAAI,KAAK,WAAW,EACzB,CAAC;oBACF,OAAO,EAAE,CAAC;gBACX,CAAC;gBAED,MAAM,QAAQ,GAAG,IAAI,CAAC,OAAO,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC;gBAC3C,IAAI,KAAK,CAAC,WAAW,EAAE,EAAE,CAAC;oBACzB,gBAAgB;oBAChB,OAAO,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,WAAW,CAAC,CAAC;gBACzC,CAAC;qBAAM,IAAI,KAAK,CAAC,MAAM,EAAE,EAAE,CAAC;oBAC3B,MAAM,GAAG,GAAG,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,WAAW,EAAE,CAAC;oBAC9C,IAAI,IAAI,CAAC,iBAAiB,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC;wBAC1C,OAAO,CAAC,QAAQ,CAAC,CAAC;oBACnB,CAAC;gBACF,CAAC;gBACD,OAAO,EAAE,CAAC;YACX,CAAC,CAAC,CAAC;YAEH,MAAM,OAAO,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;YACzC,OAAO,CAAC,OAAO,CAAC,CAAC,QAAQ,EAAE,EAAE;gBAC5B,IAAI,QAAQ,EAAE,CAAC;oBACd,SAAS,CAAC,IAAI,CAAC,GAAG,QAAQ,CAAC,CAAC;gBAC7B,CAAC;YACF,CAAC,CAAC,CAAC;QACJ,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YAChB,OAAO,CAAC,KAAK,CAAC,oBAAoB,OAAO,EAAE,EAAE,KAAK,CAAC,CAAC;QACrD,CAAC;QACD,OAAO,SAAS,CAAC;IAClB,CAAC;CACD"}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { env, pipeline, } from "@huggingface/transformers";
|
|
2
|
+
import { MODELS_DIR } from "../utils/constants.js";
|
|
3
|
+
class EmbedderService {
|
|
4
|
+
modelName = "Xenova/paraphrase-multilingual-MiniLM-L12-v2";
|
|
5
|
+
extractor = null;
|
|
6
|
+
initPromise = null;
|
|
7
|
+
constructor() {
|
|
8
|
+
env.allowRemoteModels = false;
|
|
9
|
+
env.localModelPath = MODELS_DIR;
|
|
10
|
+
env.cacheDir = MODELS_DIR;
|
|
11
|
+
}
|
|
12
|
+
async checkModelPresence() {
|
|
13
|
+
try {
|
|
14
|
+
await pipeline("feature-extraction", this.modelName, {
|
|
15
|
+
local_files_only: true,
|
|
16
|
+
});
|
|
17
|
+
return true;
|
|
18
|
+
}
|
|
19
|
+
catch (_e) {
|
|
20
|
+
return false;
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
async init() {
|
|
24
|
+
if (this.initPromise)
|
|
25
|
+
return this.initPromise;
|
|
26
|
+
this.initPromise = (async () => {
|
|
27
|
+
this.extractor = await pipeline("feature-extraction", this.modelName);
|
|
28
|
+
})();
|
|
29
|
+
return this.initPromise;
|
|
30
|
+
}
|
|
31
|
+
async embed(text) {
|
|
32
|
+
if (!this.extractor) {
|
|
33
|
+
await this.init();
|
|
34
|
+
}
|
|
35
|
+
if (!this.extractor) {
|
|
36
|
+
throw new Error("Failed to initialize embedder");
|
|
37
|
+
}
|
|
38
|
+
const output = await this.extractor(text, {
|
|
39
|
+
pooling: "mean",
|
|
40
|
+
normalize: true,
|
|
41
|
+
});
|
|
42
|
+
return Array.from(output.data);
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
export const localEmbedder = new EmbedderService();
|
|
46
|
+
//# sourceMappingURL=Embedder.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Embedder.js","sourceRoot":"","sources":["../../src/utils/Embedder.ts"],"names":[],"mappings":"AAAA,OAAO,EACN,GAAG,EAEH,QAAQ,GACR,MAAM,2BAA2B,CAAC;AACnC,OAAO,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AAElD,MAAM,eAAe;IACZ,SAAS,GAAG,8CAA8C,CAAC;IAC3D,SAAS,GAAqC,IAAI,CAAC;IACnD,WAAW,GAAyB,IAAI,CAAC;IAEjD;QACC,GAAG,CAAC,iBAAiB,GAAG,KAAK,CAAC;QAC9B,GAAG,CAAC,cAAc,GAAG,UAAU,CAAC;QAChC,GAAG,CAAC,QAAQ,GAAG,UAAU,CAAC;IAC3B,CAAC;IAEM,KAAK,CAAC,kBAAkB;QAC9B,IAAI,CAAC;YACJ,MAAM,QAAQ,CAAC,oBAAoB,EAAE,IAAI,CAAC,SAAS,EAAE;gBACpD,gBAAgB,EAAE,IAAI;aACtB,CAAC,CAAC;YACH,OAAO,IAAI,CAAC;QACb,CAAC;QAAC,OAAO,EAAE,EAAE,CAAC;YACb,OAAO,KAAK,CAAC;QACd,CAAC;IACF,CAAC;IAEM,KAAK,CAAC,IAAI;QAChB,IAAI,IAAI,CAAC,WAAW;YAAE,OAAO,IAAI,CAAC,WAAW,CAAC;QAE9C,IAAI,CAAC,WAAW,GAAG,CAAC,KAAK,IAAI,EAAE;YAC9B,IAAI,CAAC,SAAS,GAAG,MAAM,QAAQ,CAAC,oBAAoB,EAAE,IAAI,CAAC,SAAS,CAAC,CAAC;QACvE,CAAC,CAAC,EAAE,CAAC;QAEL,OAAO,IAAI,CAAC,WAAW,CAAC;IACzB,CAAC;IAEM,KAAK,CAAC,KAAK,CAAC,IAAY;QAC9B,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,CAAC;YACrB,MAAM,IAAI,CAAC,IAAI,EAAE,CAAC;QACnB,CAAC;QAED,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,CAAC;YACrB,MAAM,IAAI,KAAK,CAAC,+BAA+B,CAAC,CAAC;QAClD,CAAC;QAED,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE;YACzC,OAAO,EAAE,MAAM;YACf,SAAS,EAAE,IAAI;SACf,CAAC,CAAC;QAEH,OAAO,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAa,CAAC;IAC5C,CAAC;CACD;AAED,MAAM,CAAC,MAAM,aAAa,GAAG,IAAI,eAAe,EAAE,CAAC"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import type { DocumentIndex } from "
|
|
2
|
-
import type { Semaphore } from "
|
|
1
|
+
import type { DocumentIndex } from "../utils/processor/types.js";
|
|
2
|
+
import type { Semaphore } from "../utils/semaphore.js";
|
|
3
3
|
export declare class Indexer {
|
|
4
4
|
private documentMap;
|
|
5
5
|
private backlinkIndex;
|
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
import { readFile, stat } from "node:fs/promises";
|
|
2
|
+
import { basename, extname, join } from "node:path";
|
|
3
|
+
import * as LinkExtractor from "../utils/processor/LinkExtractor.js";
|
|
4
|
+
import * as MatterParser from "../utils/processor/MatterParser.js";
|
|
5
|
+
export class Indexer {
|
|
6
|
+
documentMap = new Map();
|
|
7
|
+
backlinkIndex = new Map();
|
|
8
|
+
invertedIndex = new Map();
|
|
9
|
+
get totalFiles() {
|
|
10
|
+
return this.documentMap.size;
|
|
11
|
+
}
|
|
12
|
+
async build(filePaths, ioSemaphore) {
|
|
13
|
+
this.clear();
|
|
14
|
+
const tasks = filePaths.map((filePath) => this.processFile(filePath, ioSemaphore));
|
|
15
|
+
await Promise.all(tasks);
|
|
16
|
+
this.buildBacklinkIndex();
|
|
17
|
+
}
|
|
18
|
+
async upsertFile(filePath, ioSemaphore) {
|
|
19
|
+
this.removeFileEntries(filePath);
|
|
20
|
+
await this.processFile(filePath, ioSemaphore);
|
|
21
|
+
this.buildBacklinkIndex();
|
|
22
|
+
}
|
|
23
|
+
removeFileEntries(filePath) {
|
|
24
|
+
for (const [token, fileSet] of this.invertedIndex.entries()) {
|
|
25
|
+
if (fileSet.has(filePath)) {
|
|
26
|
+
fileSet.delete(filePath);
|
|
27
|
+
if (fileSet.size === 0) {
|
|
28
|
+
this.invertedIndex.delete(token);
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
this.documentMap.delete(filePath);
|
|
33
|
+
}
|
|
34
|
+
search(keyword) {
|
|
35
|
+
const lowerKeyword = keyword.toLowerCase().trim();
|
|
36
|
+
if (!lowerKeyword) {
|
|
37
|
+
return [];
|
|
38
|
+
}
|
|
39
|
+
const tokens = lowerKeyword.split(/\s+/).filter((t) => t.length > 0);
|
|
40
|
+
if (tokens.length === 0) {
|
|
41
|
+
return [];
|
|
42
|
+
}
|
|
43
|
+
// 첫 번째 토큰의 매칭 결과를 기준 집합으로 잡고,
|
|
44
|
+
// 나머지 토큰의 결과와 교집합(AND)을 구한다.
|
|
45
|
+
const firstMatch = this.invertedIndex.get(tokens[0]);
|
|
46
|
+
if (!firstMatch || firstMatch.size === 0) {
|
|
47
|
+
return [];
|
|
48
|
+
}
|
|
49
|
+
let resultPaths = new Set(firstMatch);
|
|
50
|
+
for (let i = 1; i < tokens.length; i++) {
|
|
51
|
+
const tokenMatch = this.invertedIndex.get(tokens[i]);
|
|
52
|
+
if (!tokenMatch || tokenMatch.size === 0) {
|
|
53
|
+
return [];
|
|
54
|
+
}
|
|
55
|
+
resultPaths = new Set([...resultPaths].filter((path) => tokenMatch.has(path)));
|
|
56
|
+
if (resultPaths.size === 0) {
|
|
57
|
+
return [];
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
return Array.from(resultPaths)
|
|
61
|
+
.map((filePath) => this.documentMap.get(filePath))
|
|
62
|
+
.filter((documentIndex) => documentIndex !== undefined);
|
|
63
|
+
}
|
|
64
|
+
getDocument(filePath) {
|
|
65
|
+
return this.documentMap.get(filePath) || null;
|
|
66
|
+
}
|
|
67
|
+
getAllDocuments() {
|
|
68
|
+
return Array.from(this.documentMap.values());
|
|
69
|
+
}
|
|
70
|
+
getBacklinks(filePath) {
|
|
71
|
+
const targetName = this.normalizeLink(join(filePath).split(/[/]/).pop() || "");
|
|
72
|
+
if (!targetName) {
|
|
73
|
+
return [];
|
|
74
|
+
}
|
|
75
|
+
const backlinks = this.backlinkIndex.get(targetName);
|
|
76
|
+
return backlinks ? Array.from(backlinks) : [];
|
|
77
|
+
}
|
|
78
|
+
clear() {
|
|
79
|
+
this.documentMap.clear();
|
|
80
|
+
this.invertedIndex.clear();
|
|
81
|
+
this.backlinkIndex.clear();
|
|
82
|
+
}
|
|
83
|
+
async processFile(filePath, ioSemaphore) {
|
|
84
|
+
await ioSemaphore.acquire();
|
|
85
|
+
try {
|
|
86
|
+
const fileContent = await readFile(filePath, "utf-8");
|
|
87
|
+
const fileStat = await stat(filePath);
|
|
88
|
+
const { frontmatter, content } = MatterParser.parse(filePath, fileStat.birthtime.toISOString(), fileContent);
|
|
89
|
+
const imageLinks = LinkExtractor.extractImageLinks(content);
|
|
90
|
+
const documentLinks = LinkExtractor.extractDocumentLinks(content);
|
|
91
|
+
const index = {
|
|
92
|
+
filePath,
|
|
93
|
+
frontmatter,
|
|
94
|
+
contentLength: content.length,
|
|
95
|
+
mtime: fileStat.mtime.getTime(),
|
|
96
|
+
imageLinks,
|
|
97
|
+
documentLinks,
|
|
98
|
+
};
|
|
99
|
+
this.documentMap.set(filePath, index);
|
|
100
|
+
this.buildInvertedIndexForFile(index, content);
|
|
101
|
+
}
|
|
102
|
+
catch (error) {
|
|
103
|
+
console.error(`파일 인덱싱 중 오류 발생: ${filePath}`, error);
|
|
104
|
+
}
|
|
105
|
+
finally {
|
|
106
|
+
ioSemaphore.release();
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
buildInvertedIndexForFile(index, content) {
|
|
110
|
+
const tokens = new Set();
|
|
111
|
+
const extension = extname(index.filePath);
|
|
112
|
+
const fileBasename = basename(index.filePath, extension);
|
|
113
|
+
tokens.add(fileBasename);
|
|
114
|
+
if (index.frontmatter.title) {
|
|
115
|
+
index.frontmatter.title
|
|
116
|
+
.toLowerCase()
|
|
117
|
+
.split(/\s+/)
|
|
118
|
+
.forEach((t) => {
|
|
119
|
+
t && tokens.add(t);
|
|
120
|
+
});
|
|
121
|
+
}
|
|
122
|
+
if (index.frontmatter.tags) {
|
|
123
|
+
index.frontmatter.tags.forEach((tag) => {
|
|
124
|
+
tokens.add(tag.toLowerCase());
|
|
125
|
+
});
|
|
126
|
+
}
|
|
127
|
+
content
|
|
128
|
+
.toLowerCase()
|
|
129
|
+
.match(/[a-z0-9가-힣]+/g)
|
|
130
|
+
?.forEach((token) => {
|
|
131
|
+
tokens.add(token);
|
|
132
|
+
});
|
|
133
|
+
const filename = index.filePath.split(/[/]/).pop() || "";
|
|
134
|
+
if (filename) {
|
|
135
|
+
tokens.add(filename.toLowerCase().replace(/\.mdx?$/, ""));
|
|
136
|
+
}
|
|
137
|
+
const headerRegex = /^#+\s+(.*)/gm;
|
|
138
|
+
let match = null;
|
|
139
|
+
match = headerRegex.exec(content);
|
|
140
|
+
while (match !== null) {
|
|
141
|
+
if (match[1]) {
|
|
142
|
+
tokens.add(match[1].toLowerCase().trim());
|
|
143
|
+
}
|
|
144
|
+
match = headerRegex.exec(content);
|
|
145
|
+
}
|
|
146
|
+
for (const token of tokens) {
|
|
147
|
+
if (!this.invertedIndex.has(token)) {
|
|
148
|
+
this.invertedIndex.set(token, new Set());
|
|
149
|
+
}
|
|
150
|
+
this.invertedIndex.get(token)?.add(index.filePath);
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
buildBacklinkIndex() {
|
|
154
|
+
this.backlinkIndex.clear();
|
|
155
|
+
for (const [sourcePath, sourceDoc] of this.documentMap.entries()) {
|
|
156
|
+
for (const targetLink of sourceDoc.documentLinks) {
|
|
157
|
+
const normalizedTarget = this.normalizeLink(targetLink);
|
|
158
|
+
if (!this.backlinkIndex.has(normalizedTarget)) {
|
|
159
|
+
this.backlinkIndex.set(normalizedTarget, new Set());
|
|
160
|
+
}
|
|
161
|
+
this.backlinkIndex.get(normalizedTarget)?.add(sourcePath);
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
normalizeLink(link) {
|
|
166
|
+
return link.toLowerCase().replace(/\.mdx?$/, "");
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
//# sourceMappingURL=Indexer.js.map
|