mcp-docs-service 0.2.0 → 0.2.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/CHANGELOG.md +43 -0
- package/LICENSE +1 -1
- package/README.md +29 -57
- package/dist/handlers/docs.d.ts +17 -0
- package/dist/handlers/docs.js +280 -0
- package/dist/handlers/docs.js.map +1 -0
- package/dist/handlers/file.d.ts +32 -0
- package/dist/handlers/file.js +222 -0
- package/dist/handlers/file.js.map +1 -0
- package/dist/handlers/index.d.ts +1 -0
- package/dist/handlers/index.js +3 -0
- package/dist/handlers/index.js.map +1 -0
- package/dist/index.d.ts +2 -24
- package/dist/index.js +431 -49
- package/dist/index.js.map +1 -1
- package/dist/schemas/index.d.ts +1 -0
- package/dist/schemas/index.js +3 -0
- package/dist/schemas/index.js.map +1 -0
- package/dist/schemas/tools.d.ts +141 -0
- package/dist/schemas/tools.js +46 -0
- package/dist/schemas/tools.js.map +1 -0
- package/dist/types/docs.d.ts +49 -0
- package/dist/types/docs.js +2 -0
- package/dist/types/docs.js.map +1 -0
- package/dist/types/file.d.ts +21 -0
- package/dist/types/file.js +2 -0
- package/dist/types/file.js.map +1 -0
- package/dist/types/index.d.ts +34 -43
- package/dist/types/index.js +3 -5
- package/dist/types/index.js.map +1 -1
- package/dist/types/tools.d.ts +11 -0
- package/dist/types/tools.js +2 -0
- package/dist/types/tools.js.map +1 -0
- package/dist/utils/file.d.ts +24 -0
- package/dist/utils/file.js +94 -0
- package/dist/utils/file.js.map +1 -0
- package/dist/utils/index.d.ts +1 -60
- package/dist/utils/index.js +2 -151
- package/dist/utils/index.js.map +1 -1
- package/dist/utils/path.d.ts +16 -0
- package/dist/utils/path.js +39 -0
- package/dist/utils/path.js.map +1 -0
- package/package.json +20 -8
- package/dist/cli/bin.d.ts +0 -6
- package/dist/cli/bin.js +0 -49
- package/dist/cli/bin.js.map +0 -1
- package/dist/cli/index.d.ts +0 -16
- package/dist/cli/index.js +0 -108
- package/dist/cli/index.js.map +0 -1
- package/dist/cli/jsonrpc.d.ts +0 -29
- package/dist/cli/jsonrpc.js +0 -121
- package/dist/cli/jsonrpc.js.map +0 -1
- package/dist/core/docAnalyzer.d.ts +0 -25
- package/dist/core/docAnalyzer.js +0 -118
- package/dist/core/docAnalyzer.js.map +0 -1
- package/dist/core/docManager.d.ts +0 -48
- package/dist/core/docManager.js +0 -257
- package/dist/core/docManager.js.map +0 -1
- package/dist/core/docProcessor.d.ts +0 -20
- package/dist/core/docProcessor.js +0 -127
- package/dist/core/docProcessor.js.map +0 -1
- package/dist/core/mcpDocsServer.d.ts +0 -61
- package/dist/core/mcpDocsServer.js +0 -395
- package/dist/core/mcpDocsServer.js.map +0 -1
@@ -0,0 +1,46 @@
|
|
1
|
+
import { z } from "zod";
|
2
|
+
// Base schema for tool inputs
|
3
|
+
export const ToolInputSchema = z.object({
|
4
|
+
path: z.string().optional(),
|
5
|
+
});
|
6
|
+
// Documentation schemas
|
7
|
+
export const ReadDocumentSchema = ToolInputSchema.extend({
|
8
|
+
path: z.string(),
|
9
|
+
});
|
10
|
+
export const ListDocumentsSchema = ToolInputSchema.extend({
|
11
|
+
basePath: z.string().optional(),
|
12
|
+
});
|
13
|
+
export const GetStructureSchema = ToolInputSchema.extend({
|
14
|
+
basePath: z.string().optional(),
|
15
|
+
});
|
16
|
+
export const GetNavigationSchema = ToolInputSchema.extend({
|
17
|
+
basePath: z.string().optional(),
|
18
|
+
});
|
19
|
+
export const GetDocsKnowledgeBaseSchema = ToolInputSchema.extend({
|
20
|
+
basePath: z.string().optional(),
|
21
|
+
includeSummaries: z.boolean().optional(),
|
22
|
+
maxSummaryLength: z.number().optional(),
|
23
|
+
});
|
24
|
+
export const WriteDocumentSchema = ToolInputSchema.extend({
|
25
|
+
path: z.string(),
|
26
|
+
content: z.string(),
|
27
|
+
metadata: z.record(z.any()).optional(),
|
28
|
+
});
|
29
|
+
export const EditDocumentSchema = ToolInputSchema.extend({
|
30
|
+
path: z.string(),
|
31
|
+
edits: z.array(z.object({
|
32
|
+
oldText: z.string(),
|
33
|
+
newText: z.string(),
|
34
|
+
})),
|
35
|
+
});
|
36
|
+
export const DeleteDocumentSchema = ToolInputSchema.extend({
|
37
|
+
path: z.string(),
|
38
|
+
});
|
39
|
+
export const SearchDocumentsSchema = ToolInputSchema.extend({
|
40
|
+
basePath: z.string().optional(),
|
41
|
+
query: z.string().optional(),
|
42
|
+
excludePatterns: z.array(z.string()).optional(),
|
43
|
+
tags: z.array(z.string()).optional(),
|
44
|
+
status: z.string().optional(),
|
45
|
+
});
|
46
|
+
//# sourceMappingURL=tools.js.map
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"tools.js","sourceRoot":"","sources":["../../src/schemas/tools.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,8BAA8B;AAC9B,MAAM,CAAC,MAAM,eAAe,GAAG,CAAC,CAAC,MAAM,CAAC;IACtC,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;CAC5B,CAAC,CAAC;AAEH,wBAAwB;AACxB,MAAM,CAAC,MAAM,kBAAkB,GAAG,eAAe,CAAC,MAAM,CAAC;IACvD,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE;CACjB,CAAC,CAAC;AAEH,MAAM,CAAC,MAAM,mBAAmB,GAAG,eAAe,CAAC,MAAM,CAAC;IACxD,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;CAChC,CAAC,CAAC;AAEH,MAAM,CAAC,MAAM,kBAAkB,GAAG,eAAe,CAAC,MAAM,CAAC;IACvD,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;CAChC,CAAC,CAAC;AAEH,MAAM,CAAC,MAAM,mBAAmB,GAAG,eAAe,CAAC,MAAM,CAAC;IACxD,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;CAChC,CAAC,CAAC;AAEH,MAAM,CAAC,MAAM,0BAA0B,GAAG,eAAe,CAAC,MAAM,CAAC;IAC/D,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IAC/B,gBAAgB,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,QAAQ,EAAE;IACxC,gBAAgB,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;CACxC,CAAC,CAAC;AAEH,MAAM,CAAC,MAAM,mBAAmB,GAAG,eAAe,CAAC,MAAM,CAAC;IACxD,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE;IAChB,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE;IACnB,QAAQ,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,QAAQ,EAAE;CACvC,CAAC,CAAC;AAEH,MAAM,CAAC,MAAM,kBAAkB,GAAG,eAAe,CAAC,MAAM,CAAC;IACvD,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE;IAChB,KAAK,EAAE,CAAC,CAAC,KAAK,CACZ,CAAC,CAAC,MAAM,CAAC;QACP,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE;QACnB,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE;KACpB,CAAC,CACH;CACF,CAAC,CAAC;AAEH,MAAM,CAAC,MAAM,oBAAoB,GAAG,eAAe,CAAC,MAAM,CAAC;IACzD,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE;CACjB,CAAC,CAAC;AAEH,MAAM,CAAC,MAAM,qBAAqB,GAAG,eAAe,CAAC,MAAM,CAAC;IAC1D,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IAC/B,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IAC5B,eAAe,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,QAAQ,EAAE;IAC/C,IAAI,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,QAAQ,EAAE;IACpC,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;CAC9B,CAAC,CAAC"}
|
@@ -0,0 +1,49 @@
|
|
1
|
+
/**
|
2
|
+
* Metadata for documentation files
|
3
|
+
*/
|
4
|
+
export interface DocumentMetadata {
|
5
|
+
title?: string;
|
6
|
+
order?: number;
|
7
|
+
description?: string;
|
8
|
+
author?: string;
|
9
|
+
date?: Date;
|
10
|
+
tags?: string[];
|
11
|
+
status?: string;
|
12
|
+
[key: string]: any;
|
13
|
+
}
|
14
|
+
/**
|
15
|
+
* Entry for a documentation file
|
16
|
+
*/
|
17
|
+
export interface DocumentEntry {
|
18
|
+
path: string;
|
19
|
+
name: string;
|
20
|
+
metadata: DocumentMetadata;
|
21
|
+
}
|
22
|
+
/**
|
23
|
+
* Tree entry for documentation structure
|
24
|
+
*/
|
25
|
+
export interface TreeEntry {
|
26
|
+
name: string;
|
27
|
+
path: string;
|
28
|
+
type: string;
|
29
|
+
metadata?: DocumentMetadata;
|
30
|
+
children: TreeEntry[];
|
31
|
+
error?: string;
|
32
|
+
}
|
33
|
+
/**
|
34
|
+
* Navigation item for documentation
|
35
|
+
*/
|
36
|
+
export interface NavigationItem {
|
37
|
+
title: string;
|
38
|
+
path: string | null;
|
39
|
+
order: number;
|
40
|
+
}
|
41
|
+
/**
|
42
|
+
* Navigation section for documentation
|
43
|
+
*/
|
44
|
+
export interface NavigationSection {
|
45
|
+
title: string;
|
46
|
+
path: string | null;
|
47
|
+
items: NavigationItem[];
|
48
|
+
order: number;
|
49
|
+
}
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"docs.js","sourceRoot":"","sources":["../../src/types/docs.ts"],"names":[],"mappings":""}
|
@@ -0,0 +1,21 @@
|
|
1
|
+
/**
|
2
|
+
* File information structure
|
3
|
+
*/
|
4
|
+
export interface FileInfo {
|
5
|
+
size: number;
|
6
|
+
created: Date;
|
7
|
+
modified: Date;
|
8
|
+
accessed: Date;
|
9
|
+
isDirectory: boolean;
|
10
|
+
isFile: boolean;
|
11
|
+
permissions: string;
|
12
|
+
}
|
13
|
+
/**
|
14
|
+
* Tree entry for directory structure
|
15
|
+
*/
|
16
|
+
export interface FileTreeEntry {
|
17
|
+
name: string;
|
18
|
+
path: string;
|
19
|
+
type: "file" | "directory";
|
20
|
+
children?: FileTreeEntry[];
|
21
|
+
}
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"file.js","sourceRoot":"","sources":["../../src/types/file.ts"],"names":[],"mappings":""}
|
package/dist/types/index.d.ts
CHANGED
@@ -1,53 +1,44 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
export interface DocMetadata {
|
5
|
-
title: string;
|
1
|
+
export interface DocumentMetadata {
|
2
|
+
title?: string;
|
3
|
+
order?: number;
|
6
4
|
description?: string;
|
5
|
+
author?: string;
|
6
|
+
date?: Date;
|
7
7
|
tags?: string[];
|
8
|
-
|
9
|
-
|
10
|
-
globs?: string[];
|
11
|
-
alwaysApply?: boolean;
|
12
|
-
}
|
13
|
-
export interface DocContent {
|
14
|
-
metadata: DocMetadata;
|
15
|
-
content: string;
|
16
|
-
path: string;
|
17
|
-
}
|
18
|
-
export interface SearchOptions {
|
19
|
-
query: string;
|
20
|
-
tags?: string[];
|
21
|
-
status?: "draft" | "review" | "published";
|
22
|
-
directory?: string;
|
8
|
+
status?: string;
|
9
|
+
[key: string]: any;
|
23
10
|
}
|
24
|
-
export interface
|
11
|
+
export interface DocumentEntry {
|
25
12
|
path: string;
|
26
|
-
|
27
|
-
metadata
|
13
|
+
name: string;
|
14
|
+
metadata: DocumentMetadata;
|
28
15
|
}
|
29
|
-
export interface
|
16
|
+
export interface TreeEntry {
|
17
|
+
name: string;
|
30
18
|
path: string;
|
31
|
-
|
32
|
-
metadata
|
33
|
-
|
34
|
-
export interface MCPQueryResult {
|
35
|
-
success: boolean;
|
36
|
-
data?: any;
|
19
|
+
type: string;
|
20
|
+
metadata?: DocumentMetadata;
|
21
|
+
children: TreeEntry[];
|
37
22
|
error?: string;
|
38
23
|
}
|
39
|
-
export interface
|
24
|
+
export interface NavigationItem {
|
40
25
|
title: string;
|
41
|
-
|
42
|
-
|
43
|
-
lastUpdated?: string;
|
44
|
-
tags?: string[];
|
45
|
-
status?: "draft" | "review" | "published";
|
46
|
-
}
|
47
|
-
export interface DocAnalysisResult {
|
48
|
-
documentCount: number;
|
49
|
-
byStatus?: Record<string, number>;
|
50
|
-
byDirectory?: Record<string, number>;
|
51
|
-
recentlyUpdated?: DocSummary[];
|
52
|
-
missingDescriptions?: DocSummary[];
|
26
|
+
path: string | null;
|
27
|
+
order: number;
|
53
28
|
}
|
29
|
+
export interface NavigationSection {
|
30
|
+
title: string;
|
31
|
+
path: string | null;
|
32
|
+
items: NavigationItem[];
|
33
|
+
order: number;
|
34
|
+
}
|
35
|
+
export type ToolResponse = {
|
36
|
+
content: Array<{
|
37
|
+
type: string;
|
38
|
+
text: string;
|
39
|
+
}>;
|
40
|
+
metadata?: Record<string, any>;
|
41
|
+
isError?: boolean;
|
42
|
+
};
|
43
|
+
export * from "./docs.js";
|
44
|
+
export * from "./tools.js";
|
package/dist/types/index.js
CHANGED
@@ -1,6 +1,4 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
*
|
4
|
-
*/
|
5
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
1
|
+
// Re-export all types from specialized modules
|
2
|
+
export * from "./docs.js";
|
3
|
+
export * from "./tools.js";
|
6
4
|
//# sourceMappingURL=index.js.map
|
package/dist/types/index.js.map
CHANGED
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/types/index.ts"],"names":[],"mappings":";
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/types/index.ts"],"names":[],"mappings":"AAiDA,+CAA+C;AAC/C,cAAc,WAAW,CAAC;AAC1B,cAAc,YAAY,CAAC"}
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"tools.js","sourceRoot":"","sources":["../../src/types/tools.ts"],"names":[],"mappings":""}
|
@@ -0,0 +1,24 @@
|
|
1
|
+
import { FileInfo } from "../types/file.js";
|
2
|
+
/**
|
3
|
+
* Gets file statistics and information
|
4
|
+
*/
|
5
|
+
export declare function getFileStats(filePath: string): Promise<FileInfo>;
|
6
|
+
/**
|
7
|
+
* Searches for files matching a pattern
|
8
|
+
*/
|
9
|
+
export declare function searchFiles(rootPath: string, pattern: string, excludePatterns?: string[]): Promise<string[]>;
|
10
|
+
/**
|
11
|
+
* Normalizes line endings to LF
|
12
|
+
*/
|
13
|
+
export declare function normalizeLineEndings(text: string): string;
|
14
|
+
/**
|
15
|
+
* Creates a unified diff between two text contents
|
16
|
+
*/
|
17
|
+
export declare function createUnifiedDiff(originalContent: string, newContent: string, filepath?: string): string;
|
18
|
+
/**
|
19
|
+
* Applies edits to a file
|
20
|
+
*/
|
21
|
+
export declare function applyFileEdits(filePath: string, edits: Array<{
|
22
|
+
oldText: string;
|
23
|
+
newText: string;
|
24
|
+
}>, dryRun?: boolean): Promise<string>;
|
@@ -0,0 +1,94 @@
|
|
1
|
+
import fs from "fs/promises";
|
2
|
+
import path from "path";
|
3
|
+
import { createTwoFilesPatch } from "diff";
|
4
|
+
import { minimatch } from "minimatch";
|
5
|
+
/**
|
6
|
+
* Gets file statistics and information
|
7
|
+
*/
|
8
|
+
export async function getFileStats(filePath) {
|
9
|
+
const stats = await fs.stat(filePath);
|
10
|
+
// Convert file mode to permission string (e.g., "rwxr-xr-x")
|
11
|
+
const mode = stats.mode;
|
12
|
+
const permissions = [
|
13
|
+
stats.mode & 0o400 ? "r" : "-",
|
14
|
+
stats.mode & 0o200 ? "w" : "-",
|
15
|
+
stats.mode & 0o100 ? "x" : "-",
|
16
|
+
stats.mode & 0o040 ? "r" : "-",
|
17
|
+
stats.mode & 0o020 ? "w" : "-",
|
18
|
+
stats.mode & 0o010 ? "x" : "-",
|
19
|
+
stats.mode & 0o004 ? "r" : "-",
|
20
|
+
stats.mode & 0o002 ? "w" : "-",
|
21
|
+
stats.mode & 0o001 ? "x" : "-",
|
22
|
+
].join("");
|
23
|
+
return {
|
24
|
+
size: stats.size,
|
25
|
+
created: stats.birthtime,
|
26
|
+
modified: stats.mtime,
|
27
|
+
accessed: stats.atime,
|
28
|
+
isDirectory: stats.isDirectory(),
|
29
|
+
isFile: stats.isFile(),
|
30
|
+
permissions,
|
31
|
+
};
|
32
|
+
}
|
33
|
+
/**
|
34
|
+
* Searches for files matching a pattern
|
35
|
+
*/
|
36
|
+
export async function searchFiles(rootPath, pattern, excludePatterns = []) {
|
37
|
+
const results = [];
|
38
|
+
async function search(currentPath) {
|
39
|
+
const entries = await fs.readdir(currentPath, { withFileTypes: true });
|
40
|
+
for (const entry of entries) {
|
41
|
+
const entryPath = path.join(currentPath, entry.name);
|
42
|
+
const relativePath = path.relative(rootPath, entryPath);
|
43
|
+
// Check if path should be excluded
|
44
|
+
if (excludePatterns.some((excludePattern) => minimatch(relativePath, excludePattern))) {
|
45
|
+
continue;
|
46
|
+
}
|
47
|
+
if (entry.isDirectory()) {
|
48
|
+
await search(entryPath);
|
49
|
+
}
|
50
|
+
else if (minimatch(relativePath, pattern)) {
|
51
|
+
results.push(entryPath);
|
52
|
+
}
|
53
|
+
}
|
54
|
+
}
|
55
|
+
await search(rootPath);
|
56
|
+
return results;
|
57
|
+
}
|
58
|
+
/**
|
59
|
+
* Normalizes line endings to LF
|
60
|
+
*/
|
61
|
+
export function normalizeLineEndings(text) {
|
62
|
+
return text.replace(/\r\n/g, "\n");
|
63
|
+
}
|
64
|
+
/**
|
65
|
+
* Creates a unified diff between two text contents
|
66
|
+
*/
|
67
|
+
export function createUnifiedDiff(originalContent, newContent, filepath = "file") {
|
68
|
+
return createTwoFilesPatch(filepath, filepath, normalizeLineEndings(originalContent), normalizeLineEndings(newContent), "", "", { context: 3 });
|
69
|
+
}
|
70
|
+
/**
|
71
|
+
* Applies edits to a file
|
72
|
+
*/
|
73
|
+
export async function applyFileEdits(filePath, edits, dryRun = false) {
|
74
|
+
let content = await fs.readFile(filePath, "utf-8");
|
75
|
+
content = normalizeLineEndings(content);
|
76
|
+
// Apply all edits
|
77
|
+
for (const edit of edits) {
|
78
|
+
const { oldText, newText } = edit;
|
79
|
+
const normalizedOldText = normalizeLineEndings(oldText);
|
80
|
+
if (!content.includes(normalizedOldText)) {
|
81
|
+
throw new Error(`Edit failed: Could not find text to replace in ${filePath}`);
|
82
|
+
}
|
83
|
+
content = content.replace(normalizedOldText, normalizeLineEndings(newText));
|
84
|
+
}
|
85
|
+
// Create a diff to show changes
|
86
|
+
const originalContent = await fs.readFile(filePath, "utf-8");
|
87
|
+
const diff = createUnifiedDiff(originalContent, content, filePath);
|
88
|
+
// Write the changes if not a dry run
|
89
|
+
if (!dryRun) {
|
90
|
+
await fs.writeFile(filePath, content);
|
91
|
+
}
|
92
|
+
return diff;
|
93
|
+
}
|
94
|
+
//# sourceMappingURL=file.js.map
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"file.js","sourceRoot":"","sources":["../../src/utils/file.ts"],"names":[],"mappings":"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"}
|
package/dist/utils/index.d.ts
CHANGED
@@ -1,60 +1 @@
|
|
1
|
-
|
2
|
-
* Utility functions for the MCP Documentation Service
|
3
|
-
*/
|
4
|
-
/**
|
5
|
-
* Check if a path is valid
|
6
|
-
* @param path - Path to check
|
7
|
-
* @returns True if the path is valid, false otherwise
|
8
|
-
*/
|
9
|
-
export declare function isValidPath(path: string): boolean;
|
10
|
-
/**
|
11
|
-
* Normalize a path
|
12
|
-
* @param path - Path to normalize
|
13
|
-
* @returns Normalized path
|
14
|
-
*/
|
15
|
-
export declare function normalizePath(path: string): string;
|
16
|
-
/**
|
17
|
-
* Get file extension
|
18
|
-
* @param path - Path to get extension from
|
19
|
-
* @returns File extension
|
20
|
-
*/
|
21
|
-
export declare function getFileExtension(path: string): string;
|
22
|
-
/**
|
23
|
-
* Get file name
|
24
|
-
* @param path - Path to get name from
|
25
|
-
* @returns File name
|
26
|
-
*/
|
27
|
-
export declare function getFileName(path: string): string;
|
28
|
-
/**
|
29
|
-
* Get directory name
|
30
|
-
* @param path - Path to get directory name from
|
31
|
-
* @returns Directory name
|
32
|
-
*/
|
33
|
-
export declare function getDirectoryName(path: string): string;
|
34
|
-
/**
|
35
|
-
* Join paths
|
36
|
-
* @param paths - Paths to join
|
37
|
-
* @returns Joined path
|
38
|
-
*/
|
39
|
-
export declare function joinPaths(...paths: string[]): string;
|
40
|
-
/**
|
41
|
-
* Escape regex special characters
|
42
|
-
* @param str - String to escape
|
43
|
-
* @returns Escaped string
|
44
|
-
*/
|
45
|
-
export declare function escapeRegex(str: string): string;
|
46
|
-
/**
|
47
|
-
* Calculate relevance score
|
48
|
-
* @param text - Text to search in
|
49
|
-
* @param query - Query to search for
|
50
|
-
* @returns Relevance score (0-1)
|
51
|
-
*/
|
52
|
-
export declare function calculateRelevance(text: string, query: string): number;
|
53
|
-
/**
|
54
|
-
* Generate excerpt
|
55
|
-
* @param text - Text to generate excerpt from
|
56
|
-
* @param query - Query to highlight
|
57
|
-
* @param length - Excerpt length
|
58
|
-
* @returns Excerpt
|
59
|
-
*/
|
60
|
-
export declare function generateExcerpt(text: string, query: string, length?: number): string;
|
1
|
+
export * from "./path.js";
|
package/dist/utils/index.js
CHANGED
@@ -1,152 +1,3 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
* Utility functions for the MCP Documentation Service
|
4
|
-
*/
|
5
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
6
|
-
exports.generateExcerpt = exports.calculateRelevance = exports.escapeRegex = exports.joinPaths = exports.getDirectoryName = exports.getFileName = exports.getFileExtension = exports.normalizePath = exports.isValidPath = void 0;
|
7
|
-
/**
|
8
|
-
* Check if a path is valid
|
9
|
-
* @param path - Path to check
|
10
|
-
* @returns True if the path is valid, false otherwise
|
11
|
-
*/
|
12
|
-
function isValidPath(path) {
|
13
|
-
// Ensure path doesn't contain invalid characters or sequences
|
14
|
-
return !path.includes("..") && !path.includes("//") && !path.startsWith("/");
|
15
|
-
}
|
16
|
-
exports.isValidPath = isValidPath;
|
17
|
-
/**
|
18
|
-
* Normalize a path
|
19
|
-
* @param path - Path to normalize
|
20
|
-
* @returns Normalized path
|
21
|
-
*/
|
22
|
-
function normalizePath(path) {
|
23
|
-
// Replace backslashes with forward slashes
|
24
|
-
path = path.replace(/\\/g, "/");
|
25
|
-
// Remove leading and trailing slashes
|
26
|
-
path = path.replace(/^\/+|\/+$/g, "");
|
27
|
-
// Replace multiple slashes with a single slash
|
28
|
-
path = path.replace(/\/+/g, "/");
|
29
|
-
return path;
|
30
|
-
}
|
31
|
-
exports.normalizePath = normalizePath;
|
32
|
-
/**
|
33
|
-
* Get file extension
|
34
|
-
* @param path - Path to get extension from
|
35
|
-
* @returns File extension
|
36
|
-
*/
|
37
|
-
function getFileExtension(path) {
|
38
|
-
const match = path.match(/\.([^.]+)$/);
|
39
|
-
return match ? `.${match[1].toLowerCase()}` : "";
|
40
|
-
}
|
41
|
-
exports.getFileExtension = getFileExtension;
|
42
|
-
/**
|
43
|
-
* Get file name
|
44
|
-
* @param path - Path to get name from
|
45
|
-
* @returns File name
|
46
|
-
*/
|
47
|
-
function getFileName(path) {
|
48
|
-
const match = path.match(/([^/]+)$/);
|
49
|
-
return match ? match[1] : "";
|
50
|
-
}
|
51
|
-
exports.getFileName = getFileName;
|
52
|
-
/**
|
53
|
-
* Get directory name
|
54
|
-
* @param path - Path to get directory name from
|
55
|
-
* @returns Directory name
|
56
|
-
*/
|
57
|
-
function getDirectoryName(path) {
|
58
|
-
const match = path.match(/([^/]+)\/[^/]+$/);
|
59
|
-
return match ? match[1] : "";
|
60
|
-
}
|
61
|
-
exports.getDirectoryName = getDirectoryName;
|
62
|
-
/**
|
63
|
-
* Join paths
|
64
|
-
* @param paths - Paths to join
|
65
|
-
* @returns Joined path
|
66
|
-
*/
|
67
|
-
function joinPaths(...paths) {
|
68
|
-
return normalizePath(paths.join("/"));
|
69
|
-
}
|
70
|
-
exports.joinPaths = joinPaths;
|
71
|
-
/**
|
72
|
-
* Escape regex special characters
|
73
|
-
* @param str - String to escape
|
74
|
-
* @returns Escaped string
|
75
|
-
*/
|
76
|
-
function escapeRegex(str) {
|
77
|
-
return str.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
78
|
-
}
|
79
|
-
exports.escapeRegex = escapeRegex;
|
80
|
-
/**
|
81
|
-
* Calculate relevance score
|
82
|
-
* @param text - Text to search in
|
83
|
-
* @param query - Query to search for
|
84
|
-
* @returns Relevance score (0-1)
|
85
|
-
*/
|
86
|
-
function calculateRelevance(text, query) {
|
87
|
-
if (!query || !text)
|
88
|
-
return 0;
|
89
|
-
// Convert to lowercase for case-insensitive matching
|
90
|
-
const lowerText = text.toLowerCase();
|
91
|
-
const lowerQuery = query.toLowerCase();
|
92
|
-
// Check if the query is in the text
|
93
|
-
if (!lowerText.includes(lowerQuery))
|
94
|
-
return 0;
|
95
|
-
// Calculate relevance based on frequency and position
|
96
|
-
const frequency = (lowerText.match(new RegExp(escapeRegex(lowerQuery), "g")) || []).length;
|
97
|
-
const position = lowerText.indexOf(lowerQuery);
|
98
|
-
const textLength = text.length;
|
99
|
-
// Higher relevance for:
|
100
|
-
// - More occurrences of the query
|
101
|
-
// - Earlier position of the query
|
102
|
-
// - Shorter text (query is more significant in shorter text)
|
103
|
-
const frequencyFactor = Math.min(frequency / 5, 1); // Cap at 1
|
104
|
-
const positionFactor = 1 - position / textLength;
|
105
|
-
const lengthFactor = 1 - Math.min(textLength / 1000, 0.9); // Cap at 0.9
|
106
|
-
return frequencyFactor * 0.4 + positionFactor * 0.4 + lengthFactor * 0.2;
|
107
|
-
}
|
108
|
-
exports.calculateRelevance = calculateRelevance;
|
109
|
-
/**
|
110
|
-
* Generate excerpt
|
111
|
-
* @param text - Text to generate excerpt from
|
112
|
-
* @param query - Query to highlight
|
113
|
-
* @param length - Excerpt length
|
114
|
-
* @returns Excerpt
|
115
|
-
*/
|
116
|
-
function generateExcerpt(text, query, length = 150) {
|
117
|
-
if (!text)
|
118
|
-
return "";
|
119
|
-
if (!query)
|
120
|
-
return text.substring(0, length);
|
121
|
-
// Find the position of the query
|
122
|
-
const lowerText = text.toLowerCase();
|
123
|
-
const lowerQuery = query.toLowerCase();
|
124
|
-
const position = lowerText.indexOf(lowerQuery);
|
125
|
-
if (position === -1) {
|
126
|
-
// Query not found, return the beginning of the text
|
127
|
-
return text.substring(0, length) + (text.length > length ? "..." : "");
|
128
|
-
}
|
129
|
-
// Calculate start and end positions for the excerpt
|
130
|
-
const halfLength = Math.floor(length / 2);
|
131
|
-
let start = Math.max(0, position - halfLength);
|
132
|
-
let end = Math.min(text.length, position + query.length + halfLength);
|
133
|
-
// Adjust if the excerpt is shorter than the desired length
|
134
|
-
if (end - start < length) {
|
135
|
-
if (start === 0) {
|
136
|
-
end = Math.min(text.length, length);
|
137
|
-
}
|
138
|
-
else if (end === text.length) {
|
139
|
-
start = Math.max(0, text.length - length);
|
140
|
-
}
|
141
|
-
}
|
142
|
-
// Generate the excerpt
|
143
|
-
let excerpt = text.substring(start, end);
|
144
|
-
// Add ellipsis if needed
|
145
|
-
if (start > 0)
|
146
|
-
excerpt = "..." + excerpt;
|
147
|
-
if (end < text.length)
|
148
|
-
excerpt = excerpt + "...";
|
149
|
-
return excerpt;
|
150
|
-
}
|
151
|
-
exports.generateExcerpt = generateExcerpt;
|
1
|
+
// Re-export all utility functions
|
2
|
+
export * from "./path.js";
|
152
3
|
//# sourceMappingURL=index.js.map
|
package/dist/utils/index.js.map
CHANGED
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/utils/index.ts"],"names":[],"mappings":"
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/utils/index.ts"],"names":[],"mappings":"AAAA,kCAAkC;AAClC,cAAc,WAAW,CAAC"}
|
@@ -0,0 +1,16 @@
|
|
1
|
+
/**
|
2
|
+
* Normalizes a path consistently
|
3
|
+
*/
|
4
|
+
export declare function normalizePath(p: string): string;
|
5
|
+
/**
|
6
|
+
* Expands the home directory tilde (~) in a path
|
7
|
+
*/
|
8
|
+
export declare function expandHome(filepath: string): string;
|
9
|
+
/**
|
10
|
+
* Validates that a path is within allowed directories
|
11
|
+
* @param p The path to validate
|
12
|
+
* @param allowedDirectories Array of allowed directory paths
|
13
|
+
* @returns The normalized path if valid
|
14
|
+
* @throws Error if path is not within allowed directories
|
15
|
+
*/
|
16
|
+
export declare function validatePath(p: string, allowedDirectories: string[]): Promise<string>;
|