mcp-docs-service 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2023 Your Name
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,214 @@
1
+ # MCP Documentation Service
2
+
3
+ The MCP Documentation Service is a custom implementation of the Model Context Protocol that allows AI assistants to interact with documentation. This service enables the creation, reading, updating, and deletion of documentation files, as well as searching and analyzing the documentation.
4
+
5
+ ## Features
6
+
7
+ - **Document Management**: Create, read, update, and delete markdown documentation files
8
+ - **Metadata Management**: Work with document frontmatter (YAML metadata)
9
+ - **Search**: Search through documentation using keywords and filters
10
+ - **Analytics**: Analyze documentation health and get suggestions for improvement
11
+ - **Custom Directory Support**: Specify a custom docs directory and create it if it doesn't exist
12
+
13
+ ## Installation
14
+
15
+ ### Via npx (Recommended)
16
+
17
+ The easiest way to use MCP Documentation Service is through npx:
18
+
19
+ ```bash
20
+ # Use default docs directory (./docs)
21
+ npx mcp-docs-service
22
+
23
+ # Specify a custom docs directory
24
+ npx mcp-docs-service --docs-dir ./my-custom-docs
25
+
26
+ # Create the directory if it doesn't exist
27
+ npx mcp-docs-service --docs-dir ./my-custom-docs --create-dir
28
+
29
+ # Show help
30
+ npx mcp-docs-service --help
31
+ ```
32
+
33
+ ### Global Installation
34
+
35
+ You can also install it globally:
36
+
37
+ ```bash
38
+ npm install -g mcp-docs-service
39
+
40
+ # Then use it with the same options as npx
41
+ mcp-docs-service --docs-dir ./my-custom-docs --create-dir
42
+ ```
43
+
44
+ ### Local Installation
45
+
46
+ If you prefer to install it locally in your project:
47
+
48
+ ```bash
49
+ npm install mcp-docs-service
50
+ ```
51
+
52
+ ### Command-Line Options
53
+
54
+ The MCP Documentation Service supports the following command-line options:
55
+
56
+ - `--docs-dir <path>`: Specify the docs directory (default: ./docs)
57
+ - `--create-dir`: Create the docs directory if it doesn't exist
58
+ - `--help`, `-h`: Show help message
59
+
60
+ ## Integration
61
+
62
+ ### With Cursor IDE
63
+
64
+ Add this to your `.cursor/mcp.json` file:
65
+
66
+ ```json
67
+ {
68
+ "mcpServers": {
69
+ "docs-manager": {
70
+ "command": "npx",
71
+ "args": ["-y", "mcp-docs-service"]
72
+ }
73
+ }
74
+ }
75
+ ```
76
+
77
+ To specify a custom docs directory:
78
+
79
+ ```json
80
+ {
81
+ "mcpServers": {
82
+ "docs-manager": {
83
+ "command": "npx",
84
+ "args": [
85
+ "-y",
86
+ "mcp-docs-service",
87
+ "--docs-dir",
88
+ "./my-custom-docs",
89
+ "--create-dir"
90
+ ]
91
+ }
92
+ }
93
+ }
94
+ ```
95
+
96
+ ### With Claude Desktop
97
+
98
+ Add this to your `claude_desktop_config.json` file:
99
+
100
+ ```json
101
+ {
102
+ "mcpServers": {
103
+ "docs-manager": {
104
+ "command": "npx",
105
+ "args": ["-y", "mcp-docs-service"]
106
+ }
107
+ }
108
+ }
109
+ ```
110
+
111
+ To specify a custom docs directory:
112
+
113
+ ```json
114
+ {
115
+ "mcpServers": {
116
+ "docs-manager": {
117
+ "command": "npx",
118
+ "args": [
119
+ "-y",
120
+ "mcp-docs-service",
121
+ "--docs-dir",
122
+ "./my-custom-docs",
123
+ "--create-dir"
124
+ ]
125
+ }
126
+ }
127
+ }
128
+ ```
129
+
130
+ ## Programmatic Usage
131
+
132
+ You can also use MCP Documentation Service programmatically in your Node.js application:
133
+
134
+ ```javascript
135
+ const { MCPDocsServer } = require("mcp-docs-service");
136
+
137
+ // Create a new MCP server instance with default docs directory
138
+ const server = new MCPDocsServer("./docs");
139
+
140
+ // Or with a custom docs directory
141
+ const customServer = new MCPDocsServer("./my-custom-docs", {
142
+ createIfNotExists: true, // Create the directory if it doesn't exist
143
+ fileExtensions: [".md", ".mdx"], // Specify file extensions to consider (optional)
144
+ });
145
+
146
+ // Execute a query
147
+ async function example() {
148
+ try {
149
+ const result = await server.executeQuery("list_files");
150
+ console.log(result);
151
+ } catch (error) {
152
+ console.error(error);
153
+ }
154
+ }
155
+
156
+ example();
157
+ ```
158
+
159
+ You can also use the query function directly:
160
+
161
+ ```javascript
162
+ const { query } = require("mcp-docs-service");
163
+
164
+ // Execute a query with a custom docs directory
165
+ async function example() {
166
+ try {
167
+ const result = await query("list_files", {
168
+ docsDir: "./my-custom-docs",
169
+ createIfNotExists: true,
170
+ });
171
+ console.log(result);
172
+ } catch (error) {
173
+ console.error(error);
174
+ }
175
+ }
176
+
177
+ example();
178
+ ```
179
+
180
+ ## Query Format
181
+
182
+ The service uses a SQL-like query format to execute commands:
183
+
184
+ ```
185
+ command_name(param1="value1", param2="value2")
186
+ ```
187
+
188
+ For example:
189
+
190
+ ```
191
+ get_document(path="architecture/overview.md")
192
+ ```
193
+
194
+ ## Available Commands
195
+
196
+ ### Document Operations
197
+
198
+ - **list_files(directory="")**: List all markdown files (optionally in a specific directory)
199
+ - **list_directories(directory="")**: List all directories (optionally in a specific directory)
200
+ - **get_document(path="path/to/doc.md")**: Get a document's content and metadata
201
+ - **create_document(path="path/to/doc.md", content="content", metadata={...})**: Create a new document
202
+ - **update_document(path="path/to/doc.md", content="updated content", metadata={...})**: Update an existing document
203
+ - **delete_document(path="path/to/doc.md")**: Delete a document
204
+
205
+ ### Search & Analysis
206
+
207
+ - **search_documents(query="search term", directory="", tags=["tag1"], status="published")**: Search documents
208
+ - **analyze_docs(directory="")**: Analyze documentation health
209
+ - **get_health_score()**: Get overall documentation health score
210
+ - **get_suggestions()**: Get suggestions for improving documentation
211
+
212
+ ## License
213
+
214
+ MIT
@@ -0,0 +1,6 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * MCP Documentation Management Service CLI
4
+ * This is the entry point for the CLI when run via npx
5
+ */
6
+ export {};
@@ -0,0 +1,49 @@
1
+ #!/usr/bin/env node
2
+ "use strict";
3
+ /**
4
+ * MCP Documentation Management Service CLI
5
+ * This is the entry point for the CLI when run via npx
6
+ */
7
+ Object.defineProperty(exports, "__esModule", { value: true });
8
+ const index_js_1 = require("./index.js");
9
+ // Parse command line arguments
10
+ const args = process.argv.slice(2);
11
+ const options = {
12
+ docsDir: "./docs",
13
+ createIfNotExists: false,
14
+ help: false,
15
+ };
16
+ // Process arguments
17
+ for (let i = 0; i < args.length; i++) {
18
+ const arg = args[i];
19
+ if (arg === "--docs-dir" && i + 1 < args.length) {
20
+ options.docsDir = args[++i];
21
+ }
22
+ else if (arg === "--create-dir") {
23
+ options.createIfNotExists = true;
24
+ }
25
+ else if (arg === "--help" || arg === "-h") {
26
+ options.help = true;
27
+ }
28
+ }
29
+ // Show help if requested
30
+ if (options.help) {
31
+ console.log(`
32
+ MCP Documentation Service
33
+
34
+ Usage:
35
+ npx mcp-docs-service [options]
36
+
37
+ Options:
38
+ --docs-dir <path> Specify the docs directory (default: ./docs)
39
+ --create-dir Create the docs directory if it doesn't exist
40
+ --help, -h Show this help message
41
+ `);
42
+ process.exit(0);
43
+ }
44
+ // Start the main process
45
+ (0, index_js_1.main)(options).catch((error) => {
46
+ console.error("Fatal error:", error);
47
+ process.exit(1);
48
+ });
49
+ //# sourceMappingURL=bin.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bin.js","sourceRoot":"","sources":["../../src/cli/bin.ts"],"names":[],"mappings":";;AAEA;;;GAGG;;AAEH,yCAAkC;AAElC,+BAA+B;AAC/B,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;AACnC,MAAM,OAAO,GAAG;IACd,OAAO,EAAE,QAAQ;IACjB,iBAAiB,EAAE,KAAK;IACxB,IAAI,EAAE,KAAK;CACZ,CAAC;AAEF,oBAAoB;AACpB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;IACpC,MAAM,GAAG,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;IAEpB,IAAI,GAAG,KAAK,YAAY,IAAI,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE;QAC/C,OAAO,CAAC,OAAO,GAAG,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC;KAC7B;SAAM,IAAI,GAAG,KAAK,cAAc,EAAE;QACjC,OAAO,CAAC,iBAAiB,GAAG,IAAI,CAAC;KAClC;SAAM,IAAI,GAAG,KAAK,QAAQ,IAAI,GAAG,KAAK,IAAI,EAAE;QAC3C,OAAO,CAAC,IAAI,GAAG,IAAI,CAAC;KACrB;CACF;AAED,yBAAyB;AACzB,IAAI,OAAO,CAAC,IAAI,EAAE;IAChB,OAAO,CAAC,GAAG,CAAC;;;;;;;;;;GAUX,CAAC,CAAC;IACH,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;CACjB;AAED,yBAAyB;AACzB,IAAA,eAAI,EAAC,OAAO,CAAC,CAAC,KAAK,CAAC,CAAC,KAAK,EAAE,EAAE;IAC5B,OAAO,CAAC,KAAK,CAAC,cAAc,EAAE,KAAK,CAAC,CAAC;IACrC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC,CAAC,CAAC"}
@@ -0,0 +1,16 @@
1
+ /**
2
+ * CLI interface for the MCP Documentation Management Service
3
+ *
4
+ * This script is meant to be run from the command line to start the MCP server.
5
+ * It reads queries from stdin, processes them, and writes results to stdout.
6
+ *
7
+ * Usage:
8
+ * npx mcp-docs-service [options]
9
+ */
10
+ /**
11
+ * Main function to process stdin commands
12
+ */
13
+ export declare function main(options?: {
14
+ docsDir: string;
15
+ createIfNotExists: boolean;
16
+ }): Promise<void>;
@@ -0,0 +1,96 @@
1
+ "use strict";
2
+ /**
3
+ * CLI interface for the MCP Documentation Management Service
4
+ *
5
+ * This script is meant to be run from the command line to start the MCP server.
6
+ * It reads queries from stdin, processes them, and writes results to stdout.
7
+ *
8
+ * Usage:
9
+ * npx mcp-docs-service [options]
10
+ */
11
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
12
+ if (k2 === undefined) k2 = k;
13
+ var desc = Object.getOwnPropertyDescriptor(m, k);
14
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
15
+ desc = { enumerable: true, get: function() { return m[k]; } };
16
+ }
17
+ Object.defineProperty(o, k2, desc);
18
+ }) : (function(o, m, k, k2) {
19
+ if (k2 === undefined) k2 = k;
20
+ o[k2] = m[k];
21
+ }));
22
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
23
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
24
+ }) : function(o, v) {
25
+ o["default"] = v;
26
+ });
27
+ var __importStar = (this && this.__importStar) || function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ Object.defineProperty(exports, "__esModule", { value: true });
35
+ exports.main = void 0;
36
+ const index_js_1 = require("../index.js");
37
+ const readline = __importStar(require("readline"));
38
+ /**
39
+ * Main function to process stdin commands
40
+ */
41
+ async function main(options = {
42
+ docsDir: "./docs",
43
+ createIfNotExists: false,
44
+ }) {
45
+ console.error("MCP Documentation Management Service started.");
46
+ console.error(`Using docs directory: ${options.docsDir}`);
47
+ if (options.createIfNotExists) {
48
+ console.error("Will create directory if it doesn't exist");
49
+ }
50
+ console.error("Reading from stdin, writing results to stdout...");
51
+ // Create a custom query function that uses the specified docs directory
52
+ const query = (sql) => (0, index_js_1.query)(sql, {
53
+ docsDir: options.docsDir,
54
+ createIfNotExists: options.createIfNotExists,
55
+ });
56
+ // Create readline interface
57
+ const rl = readline.createInterface({
58
+ input: process.stdin,
59
+ output: process.stdout,
60
+ terminal: false,
61
+ });
62
+ // Handle process termination
63
+ process.on("SIGINT", () => {
64
+ console.error("\nMCP Documentation Management Service terminated.");
65
+ process.exit(0);
66
+ });
67
+ // Process lines from stdin
68
+ rl.on("line", async (line) => {
69
+ if (line.trim()) {
70
+ try {
71
+ // Process the command and write the result to stdout
72
+ const result = await query(line.trim());
73
+ console.log(JSON.stringify(result));
74
+ }
75
+ catch (error) {
76
+ // Log errors to stderr and write error result to stdout
77
+ console.error(`Error processing command: ${error instanceof Error ? error.message : String(error)}`);
78
+ console.log(JSON.stringify({
79
+ success: false,
80
+ error: error instanceof Error ? error.message : String(error),
81
+ }));
82
+ }
83
+ }
84
+ });
85
+ // Handle end of input
86
+ rl.on("close", () => {
87
+ console.error("Input stream closed. Waiting for output to flush...");
88
+ // Add a delay before exiting to ensure all output is flushed
89
+ setTimeout(() => {
90
+ console.error("Exiting...");
91
+ process.exit(0);
92
+ }, 1000);
93
+ });
94
+ }
95
+ exports.main = main;
96
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/cli/index.ts"],"names":[],"mappings":";AAAA;;;;;;;;GAQG;;;;;;;;;;;;;;;;;;;;;;;;;;AAEH,0CAAqD;AACrD,mDAAqC;AAErC;;GAEG;AACI,KAAK,UAAU,IAAI,CACxB,UAGI;IACF,OAAO,EAAE,QAAQ;IACjB,iBAAiB,EAAE,KAAK;CACzB;IAED,OAAO,CAAC,KAAK,CAAC,+CAA+C,CAAC,CAAC;IAC/D,OAAO,CAAC,KAAK,CAAC,yBAAyB,OAAO,CAAC,OAAO,EAAE,CAAC,CAAC;IAC1D,IAAI,OAAO,CAAC,iBAAiB,EAAE;QAC7B,OAAO,CAAC,KAAK,CAAC,2CAA2C,CAAC,CAAC;KAC5D;IACD,OAAO,CAAC,KAAK,CAAC,kDAAkD,CAAC,CAAC;IAElE,wEAAwE;IACxE,MAAM,KAAK,GAAG,CAAC,GAAW,EAAE,EAAE,CAC5B,IAAA,gBAAa,EAAC,GAAG,EAAE;QACjB,OAAO,EAAE,OAAO,CAAC,OAAO;QACxB,iBAAiB,EAAE,OAAO,CAAC,iBAAiB;KAC7C,CAAC,CAAC;IAEL,4BAA4B;IAC5B,MAAM,EAAE,GAAG,QAAQ,CAAC,eAAe,CAAC;QAClC,KAAK,EAAE,OAAO,CAAC,KAAK;QACpB,MAAM,EAAE,OAAO,CAAC,MAAM;QACtB,QAAQ,EAAE,KAAK;KAChB,CAAC,CAAC;IAEH,6BAA6B;IAC7B,OAAO,CAAC,EAAE,CAAC,QAAQ,EAAE,GAAG,EAAE;QACxB,OAAO,CAAC,KAAK,CAAC,oDAAoD,CAAC,CAAC;QACpE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC,CAAC,CAAC;IAEH,2BAA2B;IAC3B,EAAE,CAAC,EAAE,CAAC,MAAM,EAAE,KAAK,EAAE,IAAI,EAAE,EAAE;QAC3B,IAAI,IAAI,CAAC,IAAI,EAAE,EAAE;YACf,IAAI;gBACF,qDAAqD;gBACrD,MAAM,MAAM,GAAG,MAAM,KAAK,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC;gBACxC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC;aACrC;YAAC,OAAO,KAAc,EAAE;gBACvB,wDAAwD;gBACxD,OAAO,CAAC,KAAK,CACX,6BACE,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CACvD,EAAE,CACH,CAAC;gBACF,OAAO,CAAC,GAAG,CACT,IAAI,CAAC,SAAS,CAAC;oBACb,OAAO,EAAE,KAAK;oBACd,KAAK,EAAE,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC;iBAC9D,CAAC,CACH,CAAC;aACH;SACF;IACH,CAAC,CAAC,CAAC;IAEH,sBAAsB;IACtB,EAAE,CAAC,EAAE,CAAC,OAAO,EAAE,GAAG,EAAE;QAClB,OAAO,CAAC,KAAK,CAAC,qDAAqD,CAAC,CAAC;QACrE,6DAA6D;QAC7D,UAAU,CAAC,GAAG,EAAE;YACd,OAAO,CAAC,KAAK,CAAC,YAAY,CAAC,CAAC;YAC5B,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC,EAAE,IAAI,CAAC,CAAC;IACX,CAAC,CAAC,CAAC;AACL,CAAC;AArED,oBAqEC"}
@@ -0,0 +1,25 @@
1
+ /**
2
+ * Document Analyzer for generating insights about documentation
3
+ */
4
+ import { DocAnalysisResult } from "../types/index.js";
5
+ import { DocManager } from "./docManager.js";
6
+ export declare class DocAnalyzer {
7
+ private docManager;
8
+ constructor(docManager: DocManager);
9
+ /**
10
+ * Analyze the documentation and generate insights
11
+ */
12
+ analyzeDocumentation(directory?: string): Promise<DocAnalysisResult>;
13
+ /**
14
+ * Find documentation gaps (directories with few or no documents)
15
+ */
16
+ findDocumentationGaps(): Promise<Record<string, number>>;
17
+ /**
18
+ * Calculate overall documentation health score (0-100)
19
+ */
20
+ calculateHealthScore(): Promise<number>;
21
+ /**
22
+ * Generate suggestions for improving documentation
23
+ */
24
+ generateSuggestions(): Promise<string[]>;
25
+ }
@@ -0,0 +1,118 @@
1
+ "use strict";
2
+ /**
3
+ * Document Analyzer for generating insights about documentation
4
+ */
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.DocAnalyzer = void 0;
7
+ class DocAnalyzer {
8
+ constructor(docManager) {
9
+ this.docManager = docManager;
10
+ }
11
+ /**
12
+ * Analyze the documentation and generate insights
13
+ */
14
+ async analyzeDocumentation(directory) {
15
+ const summaries = await this.docManager.getAllDocumentSummaries(directory);
16
+ // Count documents by status
17
+ const byStatus = {};
18
+ summaries.forEach((doc) => {
19
+ const status = doc.status || "undefined";
20
+ byStatus[status] = (byStatus[status] || 0) + 1;
21
+ });
22
+ // Count documents by directory
23
+ const byDirectory = {};
24
+ summaries.forEach((doc) => {
25
+ const dirPath = doc.path.split("/").slice(0, -1).join("/");
26
+ byDirectory[dirPath] = (byDirectory[dirPath] || 0) + 1;
27
+ });
28
+ // Find documents missing descriptions
29
+ const missingDescriptions = summaries.filter((doc) => !doc.description);
30
+ // Find recently updated documents (if lastUpdated is available)
31
+ let recentlyUpdated = [];
32
+ const docsWithDates = summaries.filter((doc) => doc.lastUpdated);
33
+ if (docsWithDates.length > 0) {
34
+ recentlyUpdated = docsWithDates
35
+ .sort((a, b) => {
36
+ const dateA = a.lastUpdated ? new Date(a.lastUpdated).getTime() : 0;
37
+ const dateB = b.lastUpdated ? new Date(b.lastUpdated).getTime() : 0;
38
+ return dateB - dateA;
39
+ })
40
+ .slice(0, 5); // Get the 5 most recently updated
41
+ }
42
+ return {
43
+ documentCount: summaries.length,
44
+ byStatus,
45
+ byDirectory,
46
+ recentlyUpdated,
47
+ missingDescriptions,
48
+ };
49
+ }
50
+ /**
51
+ * Find documentation gaps (directories with few or no documents)
52
+ */
53
+ async findDocumentationGaps() {
54
+ const directories = await this.docManager.listDirectories();
55
+ const gaps = {};
56
+ for (const dir of directories) {
57
+ const files = await this.docManager.listMarkdownFiles(dir);
58
+ if (files.length < 2) {
59
+ // Consider a directory with less than 2 docs as a gap
60
+ gaps[dir] = files.length;
61
+ }
62
+ }
63
+ return gaps;
64
+ }
65
+ /**
66
+ * Calculate overall documentation health score (0-100)
67
+ */
68
+ async calculateHealthScore() {
69
+ const summaries = await this.docManager.getAllDocumentSummaries();
70
+ if (summaries.length === 0) {
71
+ return 0; // No documents
72
+ }
73
+ // Calculate metrics
74
+ const withDescription = summaries.filter((doc) => doc.description).length;
75
+ const withTags = summaries.filter((doc) => doc.tags && doc.tags.length > 0).length;
76
+ const withStatus = summaries.filter((doc) => doc.status).length;
77
+ // Calculate score components (each worth up to 33.3 points)
78
+ const descriptionScore = (withDescription / summaries.length) * 33.3;
79
+ const tagsScore = (withTags / summaries.length) * 33.3;
80
+ const statusScore = (withStatus / summaries.length) * 33.3;
81
+ // Calculate the overall score
82
+ const healthScore = descriptionScore + tagsScore + statusScore;
83
+ return Math.round(healthScore);
84
+ }
85
+ /**
86
+ * Generate suggestions for improving documentation
87
+ */
88
+ async generateSuggestions() {
89
+ const analysis = await this.analyzeDocumentation();
90
+ const gaps = await this.findDocumentationGaps();
91
+ const healthScore = await this.calculateHealthScore();
92
+ const suggestions = [];
93
+ // Suggest adding descriptions to documents that lack them
94
+ if (analysis.missingDescriptions &&
95
+ analysis.missingDescriptions.length > 0) {
96
+ suggestions.push(`Add descriptions to ${analysis.missingDescriptions.length} documents that are missing them.`);
97
+ }
98
+ // Suggest creating documents in empty or sparse directories
99
+ if (Object.keys(gaps).length > 0) {
100
+ for (const [dir, count] of Object.entries(gaps)) {
101
+ suggestions.push(`Add more documentation to the ${dir} directory (currently has ${count} documents).`);
102
+ }
103
+ }
104
+ // General suggestions based on health score
105
+ if (healthScore < 50) {
106
+ suggestions.push("Improve overall documentation quality by adding proper metadata to existing documents.");
107
+ }
108
+ // Suggestion for adding status to documents
109
+ if (analysis.byStatus &&
110
+ analysis.byStatus["undefined"] &&
111
+ analysis.byStatus["undefined"] > 0) {
112
+ suggestions.push(`Add status (draft, review, or published) to ${analysis.byStatus["undefined"]} documents.`);
113
+ }
114
+ return suggestions;
115
+ }
116
+ }
117
+ exports.DocAnalyzer = DocAnalyzer;
118
+ //# sourceMappingURL=docAnalyzer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"docAnalyzer.js","sourceRoot":"","sources":["../../src/core/docAnalyzer.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,48 @@
1
+ /**
2
+ * Document Manager for handling file operations
3
+ */
4
+ import { DocContent, DocCreateParams, DocSummary, DocUpdateParams, SearchOptions } from "../types/index.js";
5
+ export declare class DocManager {
6
+ private baseDir;
7
+ private options;
8
+ constructor(baseDir?: string, options?: {
9
+ createIfNotExists?: boolean;
10
+ fileExtensions?: string[];
11
+ });
12
+ /**
13
+ * Initialize the docs directory
14
+ */
15
+ private initializeDirectory;
16
+ /**
17
+ * List all markdown files in a directory recursively
18
+ */
19
+ listMarkdownFiles(dir?: string): Promise<string[]>;
20
+ /**
21
+ * Get document content and metadata
22
+ */
23
+ getDocument(filePath: string): Promise<DocContent | null>;
24
+ /**
25
+ * List directories in the docs folder
26
+ */
27
+ listDirectories(dir?: string): Promise<string[]>;
28
+ /**
29
+ * Create a new document
30
+ */
31
+ createDocument(params: DocCreateParams): Promise<boolean>;
32
+ /**
33
+ * Update an existing document
34
+ */
35
+ updateDocument(params: DocUpdateParams): Promise<boolean>;
36
+ /**
37
+ * Delete a document
38
+ */
39
+ deleteDocument(filePath: string): Promise<boolean>;
40
+ /**
41
+ * Basic search for documents matching query
42
+ */
43
+ searchDocuments(options: SearchOptions): Promise<DocSummary[]>;
44
+ /**
45
+ * Get all documents as summaries
46
+ */
47
+ getAllDocumentSummaries(directory?: string): Promise<DocSummary[]>;
48
+ }