project-mcp 3.2.0 → 3.2.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,79 +1,79 @@
1
1
  {
2
- "name": "project-mcp",
3
- "version": "3.2.0",
4
- "description": "Intent-based MCP server for project documentation search. Maps natural language queries to the right sources automatically—no configuration needed. The standard for AI agent documentation search.",
5
- "type": "module",
6
- "main": "src/index.js",
7
- "bin": {
8
- "project-mcp": "src/index.js"
9
- },
10
- "scripts": {
11
- "start": "node src/index.js",
12
- "test": "node --test test/*.test.js",
13
- "lint": "node --check src/index.js",
14
- "format": "prettier --write \"**/*.{js,md,json}\"",
15
- "format:check": "prettier --check \"**/*.{js,md,json}\"",
16
- "prepublishOnly": "npm run lint && npm test"
17
- },
18
- "keywords": [
19
- "mcp",
20
- "model-context-protocol",
21
- "mcp-server",
22
- "documentation",
23
- "documentation-search",
24
- "docs-search",
25
- "search",
26
- "fuzzy-search",
27
- "semantic-search",
28
- "markdown",
29
- "markdown-search",
30
- "project-documentation",
31
- "project-management",
32
- "intent-based-search",
33
- "intent-mapping",
34
- "ai-agent",
35
- "ai-assistant",
36
- "claude",
37
- "cursor",
38
- "anthropic",
39
- "ai-tools",
40
- "developer-tools",
41
- "documentation-tools",
42
- "knowledge-base",
43
- "project-knowledge",
44
- "operational-truth",
45
- "reference-documentation",
46
- "fuse.js",
47
- "natural-language",
48
- "nlp",
49
- "zero-config",
50
- "automatic-indexing"
51
- ],
52
- "author": "",
53
- "license": "MIT",
54
- "repository": {
55
- "type": "git",
56
- "url": "git+https://github.com/pouyanafisi/project-mcp.git"
57
- },
58
- "bugs": {
59
- "url": "https://github.com/pouyanafisi/project-mcp/issues"
60
- },
61
- "homepage": "https://github.com/pouyanafisi/project-mcp#readme",
62
- "engines": {
63
- "node": ">=18.0.0"
64
- },
65
- "dependencies": {
66
- "@modelcontextprotocol/sdk": "^1.0.4",
67
- "fuse.js": "^7.0.0",
68
- "gray-matter": "^4.0.3",
69
- "mime-types": "^2.1.35"
70
- },
71
- "devDependencies": {
72
- "prettier": "^3.7.4"
73
- },
74
- "files": [
75
- "src/",
76
- "README.md",
77
- "LICENSE"
78
- ]
2
+ "name": "project-mcp",
3
+ "version": "3.2.2",
4
+ "description": "Intent-based MCP server for project documentation search. Maps natural language queries to the right sources automatically—no configuration needed. The standard for AI agent documentation search.",
5
+ "type": "module",
6
+ "main": "src/index.js",
7
+ "bin": {
8
+ "project-mcp": "src/index.js"
9
+ },
10
+ "scripts": {
11
+ "start": "node src/index.js",
12
+ "test": "node --test test/*.test.js",
13
+ "lint": "node --check src/index.js",
14
+ "format": "prettier --write \"**/*.{js,md,json}\"",
15
+ "format:check": "prettier --check \"**/*.{js,md,json}\"",
16
+ "prepublishOnly": "npm run lint && npm test"
17
+ },
18
+ "keywords": [
19
+ "mcp",
20
+ "model-context-protocol",
21
+ "mcp-server",
22
+ "documentation",
23
+ "documentation-search",
24
+ "docs-search",
25
+ "search",
26
+ "fuzzy-search",
27
+ "semantic-search",
28
+ "markdown",
29
+ "markdown-search",
30
+ "project-documentation",
31
+ "project-management",
32
+ "intent-based-search",
33
+ "intent-mapping",
34
+ "ai-agent",
35
+ "ai-assistant",
36
+ "claude",
37
+ "cursor",
38
+ "anthropic",
39
+ "ai-tools",
40
+ "developer-tools",
41
+ "documentation-tools",
42
+ "knowledge-base",
43
+ "project-knowledge",
44
+ "operational-truth",
45
+ "reference-documentation",
46
+ "fuse.js",
47
+ "natural-language",
48
+ "nlp",
49
+ "zero-config",
50
+ "automatic-indexing"
51
+ ],
52
+ "author": "",
53
+ "license": "MIT",
54
+ "repository": {
55
+ "type": "git",
56
+ "url": "git+https://github.com/pouyanafisi/project-mcp.git"
57
+ },
58
+ "bugs": {
59
+ "url": "https://github.com/pouyanafisi/project-mcp/issues"
60
+ },
61
+ "homepage": "https://github.com/pouyanafisi/project-mcp#readme",
62
+ "engines": {
63
+ "node": ">=18.0.0"
64
+ },
65
+ "dependencies": {
66
+ "@modelcontextprotocol/sdk": "^1.0.4",
67
+ "fuse.js": "^7.0.0",
68
+ "gray-matter": "^4.0.3",
69
+ "mime-types": "^2.1.35"
70
+ },
71
+ "devDependencies": {
72
+ "prettier": "^3.7.4"
73
+ },
74
+ "files": [
75
+ "src/",
76
+ "README.md",
77
+ "LICENSE"
78
+ ]
79
79
  }
@@ -12,6 +12,8 @@ export const PROJECT_DIR = join(PROJECT_ROOT, '.project');
12
12
  export const TODOS_DIR = join(PROJECT_DIR, 'todos');
13
13
  export const ARCHIVE_DIR = join(PROJECT_DIR, 'archive');
14
14
  export const BACKLOG_FILE = join(PROJECT_DIR, 'BACKLOG.md');
15
+ export const THOUGHTS_DIR = join(PROJECT_DIR, 'thoughts');
16
+ export const THOUGHTS_TODOS_DIR = join(THOUGHTS_DIR, 'todos');
15
17
 
16
18
  /**
17
19
  * Intent to source mapping.
package/src/lib/files.js CHANGED
@@ -5,7 +5,7 @@
5
5
  import { readFile, readdir, stat, writeFile, mkdir, unlink, rename } from 'fs/promises';
6
6
  import { join, extname, basename } from 'path';
7
7
  import matter from 'gray-matter';
8
- import { PROJECT_DIR, TODOS_DIR, ARCHIVE_DIR } from './constants.js';
8
+ import { PROJECT_DIR, TODOS_DIR, ARCHIVE_DIR, THOUGHTS_DIR, THOUGHTS_TODOS_DIR } from './constants.js';
9
9
 
10
10
  /**
11
11
  * Ensure .project directory exists
@@ -40,6 +40,28 @@ export async function ensureArchiveDir() {
40
40
  }
41
41
  }
42
42
 
43
+ /**
44
+ * Ensure .project/thoughts directory exists
45
+ */
46
+ export async function ensureThoughtsDir() {
47
+ try {
48
+ await mkdir(THOUGHTS_DIR, { recursive: true });
49
+ } catch (error) {
50
+ // Directory might already exist
51
+ }
52
+ }
53
+
54
+ /**
55
+ * Ensure .project/thoughts/todos directory exists
56
+ */
57
+ export async function ensureThoughtsTodosDir() {
58
+ try {
59
+ await mkdir(THOUGHTS_TODOS_DIR, { recursive: true });
60
+ } catch (error) {
61
+ // Directory might already exist
62
+ }
63
+ }
64
+
43
65
  /**
44
66
  * Check if a file exists
45
67
  * @param {string} filePath - Path to check
@@ -91,7 +113,7 @@ export function extractTitle(content) {
91
113
  * @returns {string|null}
92
114
  */
93
115
  export function extractDescription(content) {
94
- const lines = content.split('\n').filter((line) => line.trim());
116
+ const lines = content.split('\n').filter(line => line.trim());
95
117
  for (let i = 1; i < Math.min(5, lines.length); i++) {
96
118
  const line = lines[i].trim();
97
119
  if (line && !line.startsWith('#') && line.length > 20) {
package/src/lib/search.js CHANGED
@@ -32,9 +32,7 @@ export function detectIntent(query, explicitIntent) {
32
32
  const queryLower = query.toLowerCase();
33
33
 
34
34
  // Check for operational keywords
35
- if (
36
- /\b(plan|plans|todo|todos|roadmap|status|operational|current state|decisions)\b/.test(queryLower)
37
- ) {
35
+ if (/\b(plan|plans|todo|todos|roadmap|status|operational|current state|decisions)\b/.test(queryLower)) {
38
36
  return 'plan';
39
37
  }
40
38
 
@@ -161,7 +159,7 @@ export async function searchFiles(query, sources, maxResults = 10) {
161
159
  await loadAllFiles();
162
160
 
163
161
  // Filter files by source
164
- const filesToSearch = allFilesCache.filter((file) => sources.includes(file.source));
162
+ const filesToSearch = allFilesCache.filter(file => sources.includes(file.source));
165
163
 
166
164
  // Rebuild index with filtered files
167
165
  const index = new Fuse(filesToSearch, {
package/src/lib/tasks.js CHANGED
@@ -5,13 +5,7 @@
5
5
  import { readFile, readdir } from 'fs/promises';
6
6
  import { join } from 'path';
7
7
  import matter from 'gray-matter';
8
- import {
9
- TODOS_DIR,
10
- ARCHIVE_DIR,
11
- BACKLOG_FILE,
12
- PRIORITY_ORDER,
13
- PRIORITY_KEYWORDS,
14
- } from './constants.js';
8
+ import { TODOS_DIR, ARCHIVE_DIR, BACKLOG_FILE, PRIORITY_ORDER, PRIORITY_KEYWORDS } from './constants.js';
15
9
  import { ensureTodosDir, fileExists } from './files.js';
16
10
 
17
11
  /**
@@ -78,7 +72,7 @@ export async function loadAllTasks() {
78
72
  */
79
73
  export function areDependenciesMet(task, allTasks) {
80
74
  if (!task.depends_on || task.depends_on.length === 0) return true;
81
- const taskMap = new Map(allTasks.map((t) => [t.id, t]));
75
+ const taskMap = new Map(allTasks.map(t => [t.id, t]));
82
76
  for (const depId of task.depends_on) {
83
77
  const dep = taskMap.get(depId);
84
78
  if (!dep || dep.status !== 'done') return false;
@@ -218,7 +212,7 @@ export function parseTasksFromContent(content, project, defaultPriority) {
218
212
 
219
213
  if (isSubtask && currentParent) {
220
214
  // Add as subtask to parent
221
- const parent = tasks.find((t) => t.tempId === currentParent);
215
+ const parent = tasks.find(t => t.tempId === currentParent);
222
216
  if (parent) {
223
217
  parent.subtasks = parent.subtasks || [];
224
218
  parent.subtasks.push(title);
@@ -239,7 +233,7 @@ export function parseTasksFromContent(content, project, defaultPriority) {
239
233
  // Extract tags from brackets
240
234
  const tagMatch = title.match(/\[([^\]]+)\]/g);
241
235
  if (tagMatch) {
242
- task.tags = tagMatch.map((t) => t.slice(1, -1).toLowerCase());
236
+ task.tags = tagMatch.map(t => t.slice(1, -1).toLowerCase());
243
237
  task.title = title.replace(/\[[^\]]+\]/g, '').trim();
244
238
  }
245
239
 
@@ -211,7 +211,7 @@ export const prompts = [
211
211
  * @returns {string[]}
212
212
  */
213
213
  export function getPromptNames() {
214
- return prompts.map((p) => p.name);
214
+ return prompts.map(p => p.name);
215
215
  }
216
216
 
217
217
  /**
@@ -2,10 +2,7 @@
2
2
  * Prompt handlers for the MCP server.
3
3
  */
4
4
 
5
- import {
6
- ListPromptsRequestSchema,
7
- GetPromptRequestSchema,
8
- } from '@modelcontextprotocol/sdk/types.js';
5
+ import { ListPromptsRequestSchema, GetPromptRequestSchema } from '@modelcontextprotocol/sdk/types.js';
9
6
  import { prompts, promptToolMapping } from './definitions.js';
10
7
 
11
8
  /**
@@ -254,9 +251,9 @@ export function setupPrompts(server) {
254
251
  }));
255
252
 
256
253
  // Handle get prompt request
257
- server.setRequestHandler(GetPromptRequestSchema, async (request) => {
254
+ server.setRequestHandler(GetPromptRequestSchema, async request => {
258
255
  const { name, arguments: args } = request.params;
259
- const prompt = prompts.find((p) => p.name === name);
256
+ const prompt = prompts.find(p => p.name === name);
260
257
 
261
258
  if (!prompt) {
262
259
  throw new Error(`Prompt not found: ${name}`);
@@ -2,10 +2,7 @@
2
2
  * Resource handlers for the MCP server.
3
3
  */
4
4
 
5
- import {
6
- ListResourcesRequestSchema,
7
- ReadResourceRequestSchema,
8
- } from '@modelcontextprotocol/sdk/types.js';
5
+ import { ListResourcesRequestSchema, ReadResourceRequestSchema } from '@modelcontextprotocol/sdk/types.js';
9
6
  import { lookup } from 'mime-types';
10
7
  import { PROJECT_ROOT } from '../lib/constants.js';
11
8
  import { readFile, join } from '../lib/files.js';
@@ -19,7 +16,7 @@ async function listResources() {
19
16
  await loadAllFiles();
20
17
  const allFilesCache = getCachedFiles();
21
18
 
22
- return allFilesCache.map((doc) => ({
19
+ return allFilesCache.map(doc => ({
23
20
  uri: `project://${doc.path}`,
24
21
  name: doc.title,
25
22
  description: doc.description || `File: ${doc.path} [${doc.source}]`,
@@ -63,7 +60,7 @@ export function setupResources(server) {
63
60
  resources: await listResources(),
64
61
  }));
65
62
 
66
- server.setRequestHandler(ReadResourceRequestSchema, async (request) => {
63
+ server.setRequestHandler(ReadResourceRequestSchema, async request => {
67
64
  const { uri } = request.params;
68
65
  return await readResource(uri);
69
66
  });
package/src/server.js CHANGED
@@ -48,7 +48,7 @@ export class ProjectMCPServer {
48
48
  tools: toolDefinitions,
49
49
  }));
50
50
 
51
- this.server.setRequestHandler(CallToolRequestSchema, async (request) => {
51
+ this.server.setRequestHandler(CallToolRequestSchema, async request => {
52
52
  const { name, arguments: args } = request.params;
53
53
 
54
54
  try {
@@ -3,13 +3,7 @@
3
3
  * Handles: import_tasks, promote_task, archive_task, add_to_backlog, get_backlog, update_backlog_item, remove_from_backlog, list_archived_tasks, unarchive_task
4
4
  */
5
5
 
6
- import {
7
- PROJECT_ROOT,
8
- PROJECT_DIR,
9
- TODOS_DIR,
10
- ARCHIVE_DIR,
11
- BACKLOG_FILE,
12
- } from '../lib/constants.js';
6
+ import { PROJECT_ROOT, PROJECT_DIR, TODOS_DIR, ARCHIVE_DIR, BACKLOG_FILE } from '../lib/constants.js';
13
7
  import {
14
8
  readFile,
15
9
  writeFile,
@@ -42,8 +36,7 @@ export const definitions = [
42
36
  },
43
37
  source_type: {
44
38
  type: 'string',
45
- description:
46
- 'Type of source: "file" (path to file) or "content" (raw markdown). Default: "file".',
39
+ description: 'Type of source: "file" (path to file) or "content" (raw markdown). Default: "file".',
47
40
  enum: ['file', 'content'],
48
41
  default: 'file',
49
42
  },
@@ -63,8 +56,7 @@ export const definitions = [
63
56
  },
64
57
  dry_run: {
65
58
  type: 'boolean',
66
- description:
67
- 'If true, shows what would be imported without modifying BACKLOG.md. Default: false.',
59
+ description: 'If true, shows what would be imported without modifying BACKLOG.md. Default: false.',
68
60
  default: false,
69
61
  },
70
62
  },
@@ -329,7 +321,7 @@ async function importTasks(args) {
329
321
 
330
322
  // Filter by phase if specified
331
323
  if (filterPhase) {
332
- tasks = tasks.filter((t) => t.phase && t.phase.toLowerCase().includes(filterPhase.toLowerCase()));
324
+ tasks = tasks.filter(t => t.phase && t.phase.toLowerCase().includes(filterPhase.toLowerCase()));
333
325
  }
334
326
 
335
327
  if (tasks.length === 0) {
@@ -452,10 +444,7 @@ updated: ${getISODate()}
452
444
  }
453
445
 
454
446
  // Update timestamp
455
- backlogContent = backlogContent.replace(
456
- /\*\*Last Updated:\*\* .*/,
457
- `**Last Updated:** ${getCurrentDate()}`
458
- );
447
+ backlogContent = backlogContent.replace(/\*\*Last Updated:\*\* .*/, `**Last Updated:** ${getCurrentDate()}`);
459
448
  backlogContent = backlogContent.replace(/updated: .*/, `updated: ${getISODate()}`);
460
449
 
461
450
  await writeFile(BACKLOG_FILE, backlogContent, 'utf-8');
@@ -523,7 +512,7 @@ async function promoteTask(args) {
523
512
  }
524
513
 
525
514
  const title = match[1].trim();
526
- const tags = match[2] ? match[2].split(',').map((t) => t.trim()) : [];
515
+ const tags = match[2] ? match[2].split(',').map(t => t.trim()) : [];
527
516
  const phase = match[3] || null;
528
517
 
529
518
  // Detect priority from backlog section
@@ -720,10 +709,7 @@ updated: ${getISODate()}
720
709
  }
721
710
 
722
711
  // Update timestamp
723
- backlogContent = backlogContent.replace(
724
- /\*\*Last Updated:\*\* .*/,
725
- `**Last Updated:** ${getCurrentDate()}`
726
- );
712
+ backlogContent = backlogContent.replace(/\*\*Last Updated:\*\* .*/, `**Last Updated:** ${getCurrentDate()}`);
727
713
  backlogContent = backlogContent.replace(/updated: .*/, `updated: ${getISODate()}`);
728
714
 
729
715
  await writeFile(BACKLOG_FILE, backlogContent, 'utf-8');
@@ -763,15 +749,14 @@ async function getBacklog(args) {
763
749
 
764
750
  // Parse backlog items
765
751
  const items = [];
766
- const itemRegex =
767
- /^- \[([ x]|promoted)\] \*\*([A-Z]+-\d+)\*\*:\s*(.+?)(?:\s*\[([^\]]+)\])?(?:\s*\(([^)]+)\))?$/gm;
752
+ const itemRegex = /^- \[([ x]|promoted)\] \*\*([A-Z]+-\d+)\*\*:\s*(.+?)(?:\s*\[([^\]]+)\])?(?:\s*\(([^)]+)\))?$/gm;
768
753
  let match;
769
754
 
770
755
  while ((match = itemRegex.exec(backlogContent)) !== null) {
771
756
  const status = match[1] === ' ' ? 'pending' : match[1] === 'x' ? 'done' : 'promoted';
772
757
  const id = match[2];
773
758
  const title = match[3].trim();
774
- const tags = match[4] ? match[4].split(',').map((t) => t.trim()) : [];
759
+ const tags = match[4] ? match[4].split(',').map(t => t.trim()) : [];
775
760
  const phase = match[5] || null;
776
761
 
777
762
  // Detect priority from section
@@ -788,13 +773,13 @@ async function getBacklog(args) {
788
773
  // Apply filters
789
774
  let filtered = items;
790
775
  if (!include_promoted) {
791
- filtered = filtered.filter((i) => i.status !== 'promoted');
776
+ filtered = filtered.filter(i => i.status !== 'promoted');
792
777
  }
793
778
  if (priority) {
794
- filtered = filtered.filter((i) => i.priority === priority);
779
+ filtered = filtered.filter(i => i.priority === priority);
795
780
  }
796
781
  if (project) {
797
- filtered = filtered.filter((i) => i.id.startsWith(project.toUpperCase()));
782
+ filtered = filtered.filter(i => i.id.startsWith(project.toUpperCase()));
798
783
  }
799
784
 
800
785
  // Group by priority
@@ -866,7 +851,7 @@ async function updateBacklogItem(args) {
866
851
  }
867
852
 
868
853
  const currentTitle = match[2].trim();
869
- const currentTags = match[3] ? match[3].split(',').map((t) => t.trim()) : [];
854
+ const currentTags = match[3] ? match[3].split(',').map(t => t.trim()) : [];
870
855
  const currentPhase = match[4] || null;
871
856
 
872
857
  // Build new entry
@@ -919,7 +904,7 @@ async function updateBacklogItem(args) {
919
904
  await writeFile(BACKLOG_FILE, backlog, 'utf-8');
920
905
 
921
906
  let result = `## Updated Backlog Item: ${id}\n\n`;
922
- result += `**Changes:**\n${changes.map((c) => `- ${c}`).join('\n')}\n\n`;
907
+ result += `**Changes:**\n${changes.map(c => `- ${c}`).join('\n')}\n\n`;
923
908
  result += `✅ BACKLOG.md updated.`;
924
909
 
925
910
  return {
@@ -1000,12 +985,10 @@ async function listArchivedTasks(args) {
1000
985
  };
1001
986
  }
1002
987
 
1003
- const mdFiles = files.filter((f) => f.endsWith('.md'));
988
+ const mdFiles = files.filter(f => f.endsWith('.md'));
1004
989
  if (mdFiles.length === 0) {
1005
990
  return {
1006
- content: [
1007
- { type: 'text', text: `📦 Archive is empty. No completed tasks have been archived yet.` },
1008
- ],
991
+ content: [{ type: 'text', text: `📦 Archive is empty. No completed tasks have been archived yet.` }],
1009
992
  };
1010
993
  }
1011
994
 
@@ -1024,7 +1007,7 @@ async function listArchivedTasks(args) {
1024
1007
  // Filter by project if specified
1025
1008
  let filtered = tasks;
1026
1009
  if (project) {
1027
- filtered = filtered.filter((t) => t.project === project.toUpperCase());
1010
+ filtered = filtered.filter(t => t.project === project.toUpperCase());
1028
1011
  }
1029
1012
 
1030
1013
  // Sort by archived date (newest first)
@@ -7,16 +7,17 @@ import * as projectFiles from './project-files.js';
7
7
  import * as tasks from './tasks.js';
8
8
  import * as backlog from './backlog.js';
9
9
  import * as lint from './lint.js';
10
+ import * as thoughts from './thoughts.js';
10
11
 
11
12
  /**
12
13
  * All tool modules
13
14
  */
14
- const modules = [search, projectFiles, tasks, backlog, lint];
15
+ const modules = [search, projectFiles, tasks, backlog, lint, thoughts];
15
16
 
16
17
  /**
17
18
  * Combined tool definitions
18
19
  */
19
- export const definitions = modules.flatMap((m) => m.definitions);
20
+ export const definitions = modules.flatMap(m => m.definitions);
20
21
 
21
22
  /**
22
23
  * Combined handler map
package/src/tools/lint.js CHANGED
@@ -3,13 +3,7 @@
3
3
  * Handles: lint_project_docs, init_project
4
4
  */
5
5
 
6
- import {
7
- PROJECT_DIR,
8
- TODOS_DIR,
9
- ARCHIVE_DIR,
10
- VALID_STATUSES,
11
- VALID_PRIORITIES,
12
- } from '../lib/constants.js';
6
+ import { PROJECT_DIR, TODOS_DIR, ARCHIVE_DIR, VALID_STATUSES, VALID_PRIORITIES } from '../lib/constants.js';
13
7
  import {
14
8
  readFile,
15
9
  writeFile,
@@ -150,7 +144,7 @@ async function lintProjectDocs(args) {
150
144
  // Check task files
151
145
  if (scope === 'all' || scope === 'tasks') {
152
146
  const tasks = await loadAllTasks();
153
- const taskIds = new Set(tasks.map((t) => t.id));
147
+ const taskIds = new Set(tasks.map(t => t.id));
154
148
 
155
149
  // Required task fields
156
150
  const requiredFields = ['id', 'title', 'project', 'status', 'priority'];
@@ -290,8 +284,8 @@ async function lintProjectDocs(args) {
290
284
  // Check for orphaned tasks (done tasks that others depend on)
291
285
  for (const task of tasks) {
292
286
  if (task.status === 'done' && task.depends_on?.length > 0) {
293
- const unresolvedDeps = task.depends_on.filter((depId) => {
294
- const dep = tasks.find((t) => t.id === depId);
287
+ const unresolvedDeps = task.depends_on.filter(depId => {
288
+ const dep = tasks.find(t => t.id === depId);
295
289
  return dep && dep.status !== 'done';
296
290
  });
297
291
  if (unresolvedDeps.length > 0) {
@@ -306,8 +300,8 @@ async function lintProjectDocs(args) {
306
300
  }
307
301
 
308
302
  // Build result
309
- const errorCount = issues.filter((i) => i.type === 'error').length;
310
- const warningCount = issues.filter((i) => i.type === 'warning').length + warnings.length;
303
+ const errorCount = issues.filter(i => i.type === 'error').length;
304
+ const warningCount = issues.filter(i => i.type === 'warning').length + warnings.length;
311
305
 
312
306
  let result = `## Documentation Lint Results\n\n`;
313
307
  result += `**Scope:** ${scope} | **Strict:** ${strict} | **Auto-fix:** ${fix}\n\n`;