@dougis/markdown-lint-mcp 1.0.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/CHANGELOG.md +80 -0
- package/CONTRIBUTING.md +474 -0
- package/LICENSE +21 -0
- package/README.md +240 -0
- package/USAGE.md +40 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +39 -0
- package/dist/index.js.map +1 -0
- package/dist/rules/index.d.ts +22 -0
- package/dist/rules/index.d.ts.map +1 -0
- package/dist/rules/index.js +144 -0
- package/dist/rules/index.js.map +1 -0
- package/dist/rules/md001.d.ts +25 -0
- package/dist/rules/md001.d.ts.map +1 -0
- package/dist/rules/md001.js +79 -0
- package/dist/rules/md001.js.map +1 -0
- package/dist/rules/md003.d.ts +41 -0
- package/dist/rules/md003.d.ts.map +1 -0
- package/dist/rules/md003.js +130 -0
- package/dist/rules/md003.js.map +1 -0
- package/dist/rules/md004.d.ts +28 -0
- package/dist/rules/md004.d.ts.map +1 -0
- package/dist/rules/md004.js +79 -0
- package/dist/rules/md004.js.map +1 -0
- package/dist/rules/md005.d.ts +21 -0
- package/dist/rules/md005.d.ts.map +1 -0
- package/dist/rules/md005.js +88 -0
- package/dist/rules/md005.js.map +1 -0
- package/dist/rules/md007.d.ts +21 -0
- package/dist/rules/md007.d.ts.map +1 -0
- package/dist/rules/md007.js +66 -0
- package/dist/rules/md007.js.map +1 -0
- package/dist/rules/md009.d.ts +35 -0
- package/dist/rules/md009.d.ts.map +1 -0
- package/dist/rules/md009.js +122 -0
- package/dist/rules/md009.js.map +1 -0
- package/dist/rules/md010.d.ts +34 -0
- package/dist/rules/md010.d.ts.map +1 -0
- package/dist/rules/md010.js +75 -0
- package/dist/rules/md010.js.map +1 -0
- package/dist/rules/md011.d.ts +30 -0
- package/dist/rules/md011.d.ts.map +1 -0
- package/dist/rules/md011.js +123 -0
- package/dist/rules/md011.js.map +1 -0
- package/dist/rules/md012.d.ts +33 -0
- package/dist/rules/md012.d.ts.map +1 -0
- package/dist/rules/md012.js +125 -0
- package/dist/rules/md012.js.map +1 -0
- package/dist/rules/md013.d.ts +26 -0
- package/dist/rules/md013.d.ts.map +1 -0
- package/dist/rules/md013.js +32 -0
- package/dist/rules/md013.js.map +1 -0
- package/dist/rules/md014.d.ts +29 -0
- package/dist/rules/md014.d.ts.map +1 -0
- package/dist/rules/md014.js +176 -0
- package/dist/rules/md014.js.map +1 -0
- package/dist/rules/md018.d.ts +22 -0
- package/dist/rules/md018.d.ts.map +1 -0
- package/dist/rules/md018.js +27 -0
- package/dist/rules/md018.js.map +1 -0
- package/dist/rules/md019.d.ts +22 -0
- package/dist/rules/md019.d.ts.map +1 -0
- package/dist/rules/md019.js +27 -0
- package/dist/rules/md019.js.map +1 -0
- package/dist/rules/md020.d.ts +22 -0
- package/dist/rules/md020.d.ts.map +1 -0
- package/dist/rules/md020.js +27 -0
- package/dist/rules/md020.js.map +1 -0
- package/dist/rules/md021.d.ts +22 -0
- package/dist/rules/md021.d.ts.map +1 -0
- package/dist/rules/md021.js +27 -0
- package/dist/rules/md021.js.map +1 -0
- package/dist/rules/md022.d.ts +21 -0
- package/dist/rules/md022.d.ts.map +1 -0
- package/dist/rules/md022.js +43 -0
- package/dist/rules/md022.js.map +1 -0
- package/dist/rules/md023.d.ts +21 -0
- package/dist/rules/md023.d.ts.map +1 -0
- package/dist/rules/md023.js +34 -0
- package/dist/rules/md023.js.map +1 -0
- package/dist/rules/md024.d.ts +30 -0
- package/dist/rules/md024.d.ts.map +1 -0
- package/dist/rules/md024.js +123 -0
- package/dist/rules/md024.js.map +1 -0
- package/dist/rules/md025.d.ts +34 -0
- package/dist/rules/md025.d.ts.map +1 -0
- package/dist/rules/md025.js +134 -0
- package/dist/rules/md025.js.map +1 -0
- package/dist/rules/md026.d.ts +21 -0
- package/dist/rules/md026.d.ts.map +1 -0
- package/dist/rules/md026.js +31 -0
- package/dist/rules/md026.js.map +1 -0
- package/dist/rules/md027.d.ts +22 -0
- package/dist/rules/md027.d.ts.map +1 -0
- package/dist/rules/md027.js +27 -0
- package/dist/rules/md027.js.map +1 -0
- package/dist/rules/md028.d.ts +37 -0
- package/dist/rules/md028.d.ts.map +1 -0
- package/dist/rules/md028.js +84 -0
- package/dist/rules/md028.js.map +1 -0
- package/dist/rules/md029.d.ts +30 -0
- package/dist/rules/md029.d.ts.map +1 -0
- package/dist/rules/md029.js +36 -0
- package/dist/rules/md029.js.map +1 -0
- package/dist/rules/md030.d.ts +28 -0
- package/dist/rules/md030.d.ts.map +1 -0
- package/dist/rules/md030.js +76 -0
- package/dist/rules/md030.js.map +1 -0
- package/dist/rules/md031.d.ts +22 -0
- package/dist/rules/md031.d.ts.map +1 -0
- package/dist/rules/md031.js +55 -0
- package/dist/rules/md031.js.map +1 -0
- package/dist/rules/md032.d.ts +21 -0
- package/dist/rules/md032.d.ts.map +1 -0
- package/dist/rules/md032.js +69 -0
- package/dist/rules/md032.js.map +1 -0
- package/dist/rules/md033.d.ts +28 -0
- package/dist/rules/md033.d.ts.map +1 -0
- package/dist/rules/md033.js +34 -0
- package/dist/rules/md033.js.map +1 -0
- package/dist/rules/md034.d.ts +28 -0
- package/dist/rules/md034.d.ts.map +1 -0
- package/dist/rules/md034.js +100 -0
- package/dist/rules/md034.js.map +1 -0
- package/dist/rules/md035.d.ts +23 -0
- package/dist/rules/md035.d.ts.map +1 -0
- package/dist/rules/md035.js +52 -0
- package/dist/rules/md035.js.map +1 -0
- package/dist/rules/md036.d.ts +34 -0
- package/dist/rules/md036.d.ts.map +1 -0
- package/dist/rules/md036.js +112 -0
- package/dist/rules/md036.js.map +1 -0
- package/dist/rules/md037.d.ts +28 -0
- package/dist/rules/md037.d.ts.map +1 -0
- package/dist/rules/md037.js +122 -0
- package/dist/rules/md037.js.map +1 -0
- package/dist/rules/md038.d.ts +28 -0
- package/dist/rules/md038.d.ts.map +1 -0
- package/dist/rules/md038.js +62 -0
- package/dist/rules/md038.js.map +1 -0
- package/dist/rules/md039.d.ts +21 -0
- package/dist/rules/md039.d.ts.map +1 -0
- package/dist/rules/md039.js +34 -0
- package/dist/rules/md039.js.map +1 -0
- package/dist/rules/md040.d.ts +21 -0
- package/dist/rules/md040.d.ts.map +1 -0
- package/dist/rules/md040.js +46 -0
- package/dist/rules/md040.js.map +1 -0
- package/dist/rules/md041.d.ts +33 -0
- package/dist/rules/md041.d.ts.map +1 -0
- package/dist/rules/md041.js +92 -0
- package/dist/rules/md041.js.map +1 -0
- package/dist/rules/md042.d.ts +22 -0
- package/dist/rules/md042.d.ts.map +1 -0
- package/dist/rules/md042.js +50 -0
- package/dist/rules/md042.js.map +1 -0
- package/dist/rules/md043.d.ts +39 -0
- package/dist/rules/md043.d.ts.map +1 -0
- package/dist/rules/md043.js +116 -0
- package/dist/rules/md043.js.map +1 -0
- package/dist/rules/md044.d.ts +40 -0
- package/dist/rules/md044.d.ts.map +1 -0
- package/dist/rules/md044.js +167 -0
- package/dist/rules/md044.js.map +1 -0
- package/dist/rules/md045.d.ts +22 -0
- package/dist/rules/md045.d.ts.map +1 -0
- package/dist/rules/md045.js +57 -0
- package/dist/rules/md045.js.map +1 -0
- package/dist/rules/md046.d.ts +23 -0
- package/dist/rules/md046.d.ts.map +1 -0
- package/dist/rules/md046.js +174 -0
- package/dist/rules/md046.js.map +1 -0
- package/dist/rules/md047.d.ts +22 -0
- package/dist/rules/md047.d.ts.map +1 -0
- package/dist/rules/md047.js +35 -0
- package/dist/rules/md047.js.map +1 -0
- package/dist/rules/md048.d.ts +22 -0
- package/dist/rules/md048.d.ts.map +1 -0
- package/dist/rules/md048.js +80 -0
- package/dist/rules/md048.js.map +1 -0
- package/dist/rules/md049.d.ts +33 -0
- package/dist/rules/md049.d.ts.map +1 -0
- package/dist/rules/md049.js +189 -0
- package/dist/rules/md049.js.map +1 -0
- package/dist/rules/md050.d.ts +22 -0
- package/dist/rules/md050.d.ts.map +1 -0
- package/dist/rules/md050.js +32 -0
- package/dist/rules/md050.js.map +1 -0
- package/dist/rules/md051.d.ts +23 -0
- package/dist/rules/md051.d.ts.map +1 -0
- package/dist/rules/md051.js +63 -0
- package/dist/rules/md051.js.map +1 -0
- package/dist/rules/md052.d.ts +21 -0
- package/dist/rules/md052.d.ts.map +1 -0
- package/dist/rules/md052.js +71 -0
- package/dist/rules/md052.js.map +1 -0
- package/dist/rules/md053.d.ts +21 -0
- package/dist/rules/md053.d.ts.map +1 -0
- package/dist/rules/md053.js +95 -0
- package/dist/rules/md053.js.map +1 -0
- package/dist/rules/md054.d.ts +21 -0
- package/dist/rules/md054.d.ts.map +1 -0
- package/dist/rules/md054.js +87 -0
- package/dist/rules/md054.js.map +1 -0
- package/dist/rules/md055.d.ts +22 -0
- package/dist/rules/md055.d.ts.map +1 -0
- package/dist/rules/md055.js +157 -0
- package/dist/rules/md055.js.map +1 -0
- package/dist/rules/md056.d.ts +21 -0
- package/dist/rules/md056.d.ts.map +1 -0
- package/dist/rules/md056.js +154 -0
- package/dist/rules/md056.js.map +1 -0
- package/dist/rules/md058.d.ts +27 -0
- package/dist/rules/md058.d.ts.map +1 -0
- package/dist/rules/md058.js +71 -0
- package/dist/rules/md058.js.map +1 -0
- package/dist/rules/md059.d.ts +22 -0
- package/dist/rules/md059.d.ts.map +1 -0
- package/dist/rules/md059.js +161 -0
- package/dist/rules/md059.js.map +1 -0
- package/dist/rules/rule-interface.d.ts +51 -0
- package/dist/rules/rule-interface.d.ts.map +1 -0
- package/dist/rules/rule-interface.js +2 -0
- package/dist/rules/rule-interface.js.map +1 -0
- package/dist/server.d.ts +59 -0
- package/dist/server.d.ts.map +1 -0
- package/dist/server.js +419 -0
- package/dist/server.js.map +1 -0
- package/dist/types.d.ts +74 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +14 -0
- package/dist/types.js.map +1 -0
- package/dist/utils/file.d.ts +39 -0
- package/dist/utils/file.d.ts.map +1 -0
- package/dist/utils/file.js +124 -0
- package/dist/utils/file.js.map +1 -0
- package/dist/utils/logger.d.ts +61 -0
- package/dist/utils/logger.d.ts.map +1 -0
- package/dist/utils/logger.js +85 -0
- package/dist/utils/logger.js.map +1 -0
- package/dist/utils/safe-match.d.ts +4 -0
- package/dist/utils/safe-match.d.ts.map +1 -0
- package/dist/utils/safe-match.js +51 -0
- package/dist/utils/safe-match.js.map +1 -0
- package/package.json +85 -0
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { Rule } from './rule-interface';
|
|
2
|
+
/**
|
|
3
|
+
* MD056: Table column count
|
|
4
|
+
*
|
|
5
|
+
* This rule ensures that all rows in a Markdown table have the same number
|
|
6
|
+
* of columns. Tables with inconsistent column counts can render unpredictably.
|
|
7
|
+
*/
|
|
8
|
+
export declare const name = "MD056";
|
|
9
|
+
export declare const description = "Table column count";
|
|
10
|
+
/**
|
|
11
|
+
* Fix tables to ensure all rows have the same number of columns
|
|
12
|
+
* @param lines Array of string lines to fix
|
|
13
|
+
* @returns Fixed lines array with consistent table column counts
|
|
14
|
+
*/
|
|
15
|
+
export declare function fix(lines: string[]): string[];
|
|
16
|
+
/**
|
|
17
|
+
* Rule implementation for MD056
|
|
18
|
+
*/
|
|
19
|
+
export declare const rule: Rule;
|
|
20
|
+
export default rule;
|
|
21
|
+
//# sourceMappingURL=md056.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"md056.d.ts","sourceRoot":"","sources":["../../src/rules/md056.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;AAExC;;;;;GAKG;AACH,eAAO,MAAM,IAAI,UAAU,CAAC;AAC5B,eAAO,MAAM,WAAW,uBAAuB,CAAC;AAqDhD;;;;GAIG;AACH,wBAAgB,GAAG,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,MAAM,EAAE,CAqC7C;AA0DD;;GAEG;AACH,eAAO,MAAM,IAAI,EAAE,IAIlB,CAAC;AAEF,eAAe,IAAI,CAAC"}
|
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* MD056: Table column count
|
|
3
|
+
*
|
|
4
|
+
* This rule ensures that all rows in a Markdown table have the same number
|
|
5
|
+
* of columns. Tables with inconsistent column counts can render unpredictably.
|
|
6
|
+
*/
|
|
7
|
+
export const name = 'MD056';
|
|
8
|
+
export const description = 'Table column count';
|
|
9
|
+
/**
|
|
10
|
+
* Check if a line appears to be part of a table
|
|
11
|
+
* @param line The line to check
|
|
12
|
+
* @returns True if the line is part of a table
|
|
13
|
+
*/
|
|
14
|
+
function isTableLine(line) {
|
|
15
|
+
// Tables typically have pipe characters
|
|
16
|
+
return line.trim().includes('|');
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Check if a line is a table separator row (contains only -, |, and :)
|
|
20
|
+
* @param line The line to check
|
|
21
|
+
* @returns True if the line is a table separator row
|
|
22
|
+
*/
|
|
23
|
+
function isTableSeparator(line) {
|
|
24
|
+
return /^\s*\|?(\s*:?-+:?\s*\|)+\s*:?-+:?\s*\|?\s*$/.test(line);
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Count the number of columns in a table row
|
|
28
|
+
* @param line The table row line
|
|
29
|
+
* @returns The number of columns
|
|
30
|
+
*/
|
|
31
|
+
function countTableColumns(line) {
|
|
32
|
+
// Remove escaped pipe characters (they don't count as column separators)
|
|
33
|
+
const lineWithoutEscapedPipes = line.replace(/\\\|/g, '');
|
|
34
|
+
// Count columns by counting pipe characters
|
|
35
|
+
const trimmed = lineWithoutEscapedPipes.trim();
|
|
36
|
+
let pipeCount = 0;
|
|
37
|
+
for (let i = 0; i < trimmed.length; i++) {
|
|
38
|
+
if (trimmed[i] === '|') {
|
|
39
|
+
pipeCount++;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
// If the line starts and ends with pipes, we have (pipeCount - 1) columns
|
|
43
|
+
// Otherwise, we have pipeCount + 1 columns (when line doesn't have surrounding pipes)
|
|
44
|
+
if (trimmed.startsWith('|') && trimmed.endsWith('|')) {
|
|
45
|
+
return Math.max(0, pipeCount - 1);
|
|
46
|
+
}
|
|
47
|
+
else if (trimmed.startsWith('|')) {
|
|
48
|
+
return pipeCount;
|
|
49
|
+
}
|
|
50
|
+
else if (trimmed.endsWith('|')) {
|
|
51
|
+
return pipeCount;
|
|
52
|
+
}
|
|
53
|
+
else {
|
|
54
|
+
return pipeCount + 1;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Fix tables to ensure all rows have the same number of columns
|
|
59
|
+
* @param lines Array of string lines to fix
|
|
60
|
+
* @returns Fixed lines array with consistent table column counts
|
|
61
|
+
*/
|
|
62
|
+
export function fix(lines) {
|
|
63
|
+
if (lines.length === 0)
|
|
64
|
+
return lines;
|
|
65
|
+
const result = [...lines];
|
|
66
|
+
let inTable = false;
|
|
67
|
+
let columnCount = -1;
|
|
68
|
+
for (let i = 0; i < lines.length; i++) {
|
|
69
|
+
const line = lines[i];
|
|
70
|
+
// Check if this line is part of a table
|
|
71
|
+
if (isTableLine(line)) {
|
|
72
|
+
// If we're not already in a table, this is the start of a new table
|
|
73
|
+
if (!inTable) {
|
|
74
|
+
inTable = true;
|
|
75
|
+
columnCount = countTableColumns(line);
|
|
76
|
+
}
|
|
77
|
+
// Check column count against the first row's count
|
|
78
|
+
const lineColumnCount = countTableColumns(line);
|
|
79
|
+
// Skip fixing separator lines, they should be adjusted based on content rows
|
|
80
|
+
if (!isTableSeparator(line) && lineColumnCount !== columnCount) {
|
|
81
|
+
// We need to fix this row to match the column count
|
|
82
|
+
const fixedLine = fixTableRow(line, columnCount);
|
|
83
|
+
result[i] = fixedLine;
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
else {
|
|
87
|
+
// If we were in a table and now we're not, reset table tracking
|
|
88
|
+
if (inTable) {
|
|
89
|
+
inTable = false;
|
|
90
|
+
columnCount = -1;
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
return result;
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
97
|
+
* Fix a table row to have the specified number of columns
|
|
98
|
+
* @param line The table row to fix
|
|
99
|
+
* @param targetColumnCount The target number of columns
|
|
100
|
+
* @returns A fixed table row with the correct number of columns
|
|
101
|
+
*/
|
|
102
|
+
function fixTableRow(line, targetColumnCount) {
|
|
103
|
+
const trimmed = line.trim();
|
|
104
|
+
const indentation = line.slice(0, line.indexOf(trimmed));
|
|
105
|
+
// Split by pipe characters
|
|
106
|
+
const parts = trimmed.split('|');
|
|
107
|
+
// Handle surrounding pipes
|
|
108
|
+
const startWithPipe = trimmed.startsWith('|');
|
|
109
|
+
const endWithPipe = trimmed.endsWith('|');
|
|
110
|
+
// Extract actual cell contents
|
|
111
|
+
let cells = [];
|
|
112
|
+
if (startWithPipe && endWithPipe) {
|
|
113
|
+
// Remove empty first and last parts that result from surrounding pipes
|
|
114
|
+
cells = parts.slice(1, -1);
|
|
115
|
+
}
|
|
116
|
+
else if (startWithPipe) {
|
|
117
|
+
cells = parts.slice(1);
|
|
118
|
+
}
|
|
119
|
+
else if (endWithPipe) {
|
|
120
|
+
cells = parts.slice(0, -1);
|
|
121
|
+
}
|
|
122
|
+
else {
|
|
123
|
+
cells = parts;
|
|
124
|
+
}
|
|
125
|
+
// If we have too few columns, add empty cells
|
|
126
|
+
while (cells.length < targetColumnCount) {
|
|
127
|
+
cells.push(' ');
|
|
128
|
+
}
|
|
129
|
+
// If we have too many columns, remove excess cells
|
|
130
|
+
if (cells.length > targetColumnCount) {
|
|
131
|
+
cells = cells.slice(0, targetColumnCount);
|
|
132
|
+
}
|
|
133
|
+
// Reconstruct the line
|
|
134
|
+
let fixedLine = cells.join('|');
|
|
135
|
+
// Add surrounding pipes if the original line had them
|
|
136
|
+
if (startWithPipe) {
|
|
137
|
+
fixedLine = '|' + fixedLine;
|
|
138
|
+
}
|
|
139
|
+
if (endWithPipe || startWithPipe) {
|
|
140
|
+
// If the line starts with a pipe, it should also end with a pipe for proper table formatting
|
|
141
|
+
fixedLine = fixedLine + '|';
|
|
142
|
+
}
|
|
143
|
+
return indentation + fixedLine;
|
|
144
|
+
}
|
|
145
|
+
/**
|
|
146
|
+
* Rule implementation for MD056
|
|
147
|
+
*/
|
|
148
|
+
export const rule = {
|
|
149
|
+
name,
|
|
150
|
+
description,
|
|
151
|
+
fix,
|
|
152
|
+
};
|
|
153
|
+
export default rule;
|
|
154
|
+
//# sourceMappingURL=md056.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"md056.js","sourceRoot":"","sources":["../../src/rules/md056.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { Rule } from './rule-interface';
|
|
2
|
+
/**
|
|
3
|
+
* MD058: Tables should be surrounded by blank lines
|
|
4
|
+
*
|
|
5
|
+
* This rule is triggered when tables are not preceded or followed by a blank line.
|
|
6
|
+
* Surrounding tables with blank lines improves readability by visually separating
|
|
7
|
+
* them from other content.
|
|
8
|
+
*/
|
|
9
|
+
export declare const name = "MD058";
|
|
10
|
+
export declare const description = "Tables should be surrounded by blank lines";
|
|
11
|
+
/**
|
|
12
|
+
* Checks if a line is a table divider row (contains only |, -, :, and spaces)
|
|
13
|
+
* @param line The line to check
|
|
14
|
+
* @returns True if the line is a table divider
|
|
15
|
+
*/
|
|
16
|
+
/**
|
|
17
|
+
* Fix tables by ensuring they have blank lines before and after
|
|
18
|
+
* @param lines Array of string lines to fix
|
|
19
|
+
* @returns Fixed lines array with blank lines added around tables
|
|
20
|
+
*/
|
|
21
|
+
export declare function fix(lines: string[]): string[];
|
|
22
|
+
/**
|
|
23
|
+
* Rule implementation for MD058
|
|
24
|
+
*/
|
|
25
|
+
export declare const rule: Rule;
|
|
26
|
+
export default rule;
|
|
27
|
+
//# sourceMappingURL=md058.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"md058.d.ts","sourceRoot":"","sources":["../../src/rules/md058.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;AAExC;;;;;;GAMG;AACH,eAAO,MAAM,IAAI,UAAU,CAAC;AAC5B,eAAO,MAAM,WAAW,+CAA+C,CAAC;AAaxE;;;;GAIG;AACH;;;;GAIG;AACH,wBAAgB,GAAG,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,MAAM,EAAE,CAsC7C;AAED;;GAEG;AACH,eAAO,MAAM,IAAI,EAAE,IAIlB,CAAC;AAEF,eAAe,IAAI,CAAC"}
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* MD058: Tables should be surrounded by blank lines
|
|
3
|
+
*
|
|
4
|
+
* This rule is triggered when tables are not preceded or followed by a blank line.
|
|
5
|
+
* Surrounding tables with blank lines improves readability by visually separating
|
|
6
|
+
* them from other content.
|
|
7
|
+
*/
|
|
8
|
+
export const name = 'MD058';
|
|
9
|
+
export const description = 'Tables should be surrounded by blank lines';
|
|
10
|
+
/**
|
|
11
|
+
* Checks if a line appears to be part of a table
|
|
12
|
+
* Tables in markdown typically start with | or have a line with |---|---| pattern
|
|
13
|
+
* @param line The line to check
|
|
14
|
+
* @returns True if the line appears to be part of a table
|
|
15
|
+
*/
|
|
16
|
+
function isTableLine(line) {
|
|
17
|
+
// Table lines either start with | or have | inside them with spaces/dashes in between
|
|
18
|
+
return line.trim().startsWith('|') || /^\s*\|.*\|/.test(line);
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Checks if a line is a table divider row (contains only |, -, :, and spaces)
|
|
22
|
+
* @param line The line to check
|
|
23
|
+
* @returns True if the line is a table divider
|
|
24
|
+
*/
|
|
25
|
+
/**
|
|
26
|
+
* Fix tables by ensuring they have blank lines before and after
|
|
27
|
+
* @param lines Array of string lines to fix
|
|
28
|
+
* @returns Fixed lines array with blank lines added around tables
|
|
29
|
+
*/
|
|
30
|
+
export function fix(lines) {
|
|
31
|
+
if (lines.length === 0)
|
|
32
|
+
return lines;
|
|
33
|
+
const result = [];
|
|
34
|
+
let inTable = false;
|
|
35
|
+
let tableStartIndex = -1;
|
|
36
|
+
// Process each line to identify table boundaries
|
|
37
|
+
for (let i = 0; i < lines.length; i++) {
|
|
38
|
+
const line = lines[i];
|
|
39
|
+
// Check for table start
|
|
40
|
+
if (!inTable && isTableLine(line)) {
|
|
41
|
+
inTable = true;
|
|
42
|
+
tableStartIndex = result.length;
|
|
43
|
+
// Add a blank line before the table if needed
|
|
44
|
+
if (tableStartIndex > 0 && result[tableStartIndex - 1].trim() !== '') {
|
|
45
|
+
result.splice(tableStartIndex, 0, '');
|
|
46
|
+
tableStartIndex++;
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
// Add the current line
|
|
50
|
+
result.push(line);
|
|
51
|
+
// Check for table end
|
|
52
|
+
if (inTable && (i === lines.length - 1 || !isTableLine(lines[i + 1]))) {
|
|
53
|
+
inTable = false;
|
|
54
|
+
// Add a blank line after the table if needed
|
|
55
|
+
if (i < lines.length - 1 && lines[i + 1].trim() !== '') {
|
|
56
|
+
result.push('');
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
return result;
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Rule implementation for MD058
|
|
64
|
+
*/
|
|
65
|
+
export const rule = {
|
|
66
|
+
name,
|
|
67
|
+
description,
|
|
68
|
+
fix,
|
|
69
|
+
};
|
|
70
|
+
export default rule;
|
|
71
|
+
//# sourceMappingURL=md058.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"md058.js","sourceRoot":"","sources":["../../src/rules/md058.ts"],"names":[],"mappings":"AAEA;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,IAAI,GAAG,OAAO,CAAC;AAC5B,MAAM,CAAC,MAAM,WAAW,GAAG,4CAA4C,CAAC;AAExE;;;;;GAKG;AACH,SAAS,WAAW,CAAC,IAAY;IAC/B,sFAAsF;IACtF,OAAO,IAAI,CAAC,IAAI,EAAE,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAChE,CAAC;AAED;;;;GAIG;AACH;;;;GAIG;AACH,MAAM,UAAU,GAAG,CAAC,KAAe;IACjC,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,KAAK,CAAC;IAErC,MAAM,MAAM,GAAa,EAAE,CAAC;IAC5B,IAAI,OAAO,GAAG,KAAK,CAAC;IACpB,IAAI,eAAe,GAAG,CAAC,CAAC,CAAC;IAEzB,iDAAiD;IACjD,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACtC,MAAM,IAAI,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;QAEtB,wBAAwB;QACxB,IAAI,CAAC,OAAO,IAAI,WAAW,CAAC,IAAI,CAAC,EAAE,CAAC;YAClC,OAAO,GAAG,IAAI,CAAC;YACf,eAAe,GAAG,MAAM,CAAC,MAAM,CAAC;YAEhC,8CAA8C;YAC9C,IAAI,eAAe,GAAG,CAAC,IAAI,MAAM,CAAC,eAAe,GAAG,CAAC,CAAC,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC;gBACrE,MAAM,CAAC,MAAM,CAAC,eAAe,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC;gBACtC,eAAe,EAAE,CAAC;YACpB,CAAC;QACH,CAAC;QAED,uBAAuB;QACvB,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAElB,sBAAsB;QACtB,IAAI,OAAO,IAAI,CAAC,CAAC,KAAK,KAAK,CAAC,MAAM,GAAG,CAAC,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;YACtE,OAAO,GAAG,KAAK,CAAC;YAEhB,6CAA6C;YAC7C,IAAI,CAAC,GAAG,KAAK,CAAC,MAAM,GAAG,CAAC,IAAI,KAAK,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC;gBACvD,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;YAClB,CAAC;QACH,CAAC;IACH,CAAC;IAED,OAAO,MAAM,CAAC;AAChB,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,MAAM,IAAI,GAAS;IACxB,IAAI;IACJ,WAAW;IACX,GAAG;CACJ,CAAC;AAEF,eAAe,IAAI,CAAC"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { Rule } from './rule-interface';
|
|
2
|
+
/**
|
|
3
|
+
* MD059: Link text should be descriptive
|
|
4
|
+
*
|
|
5
|
+
* This rule is triggered when link text is non-descriptive, such as "click here",
|
|
6
|
+
* "more", "link", etc. These generic terms don't provide context about where the
|
|
7
|
+
* link will take the user, which is important for accessibility.
|
|
8
|
+
*/
|
|
9
|
+
export declare const name = "MD059";
|
|
10
|
+
export declare const description = "Link text should be descriptive";
|
|
11
|
+
/**
|
|
12
|
+
* Fix non-descriptive link text in Markdown files
|
|
13
|
+
* @param lines Array of string lines to fix
|
|
14
|
+
* @returns Fixed lines array with more descriptive link text
|
|
15
|
+
*/
|
|
16
|
+
export declare function fix(lines: string[]): string[];
|
|
17
|
+
/**
|
|
18
|
+
* Rule implementation for MD059
|
|
19
|
+
*/
|
|
20
|
+
export declare const rule: Rule;
|
|
21
|
+
export default rule;
|
|
22
|
+
//# sourceMappingURL=md059.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"md059.d.ts","sourceRoot":"","sources":["../../src/rules/md059.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;AAExC;;;;;;GAMG;AACH,eAAO,MAAM,IAAI,UAAU,CAAC;AAC5B,eAAO,MAAM,WAAW,oCAAoC,CAAC;AAiH7D;;;;GAIG;AACH,wBAAgB,GAAG,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,MAAM,EAAE,CA6C7C;AAED;;GAEG;AACH,eAAO,MAAM,IAAI,EAAE,IAIlB,CAAC;AAEF,eAAe,IAAI,CAAC"}
|
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* MD059: Link text should be descriptive
|
|
3
|
+
*
|
|
4
|
+
* This rule is triggered when link text is non-descriptive, such as "click here",
|
|
5
|
+
* "more", "link", etc. These generic terms don't provide context about where the
|
|
6
|
+
* link will take the user, which is important for accessibility.
|
|
7
|
+
*/
|
|
8
|
+
export const name = 'MD059';
|
|
9
|
+
export const description = 'Link text should be descriptive';
|
|
10
|
+
/**
|
|
11
|
+
* Non-descriptive link text patterns that should be avoided
|
|
12
|
+
*/
|
|
13
|
+
const NON_DESCRIPTIVE_PATTERNS = [
|
|
14
|
+
/^click here$/i,
|
|
15
|
+
/^click$/i,
|
|
16
|
+
/^here$/i,
|
|
17
|
+
/^link$/i,
|
|
18
|
+
/^this link$/i,
|
|
19
|
+
/^more$/i,
|
|
20
|
+
/^more here$/i,
|
|
21
|
+
/^details$/i,
|
|
22
|
+
/^learn more$/i,
|
|
23
|
+
/^read more$/i,
|
|
24
|
+
/^source$/i,
|
|
25
|
+
/^link text$/i,
|
|
26
|
+
/^go$/i,
|
|
27
|
+
/^page$/i,
|
|
28
|
+
/^this$/i,
|
|
29
|
+
/^website$/i,
|
|
30
|
+
/^visit$/i,
|
|
31
|
+
/^info$/i,
|
|
32
|
+
];
|
|
33
|
+
/**
|
|
34
|
+
* Regular expression to find Markdown links
|
|
35
|
+
* Captures the link text in capture group 1
|
|
36
|
+
*/
|
|
37
|
+
const LINK_REGEX = /\[([^\]]+)\]\([^)]+\)/g;
|
|
38
|
+
/**
|
|
39
|
+
* Check if link text is non-descriptive
|
|
40
|
+
* @param text Link text to check
|
|
41
|
+
* @returns True if the text is non-descriptive
|
|
42
|
+
*/
|
|
43
|
+
function isNonDescriptive(text) {
|
|
44
|
+
const trimmed = text.trim();
|
|
45
|
+
// Very short link text (1-2 characters) is likely non-descriptive
|
|
46
|
+
if (trimmed.length <= 2) {
|
|
47
|
+
return true;
|
|
48
|
+
}
|
|
49
|
+
// Check against known non-descriptive patterns
|
|
50
|
+
for (const pattern of NON_DESCRIPTIVE_PATTERNS) {
|
|
51
|
+
if (pattern.test(trimmed)) {
|
|
52
|
+
return true;
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
return false;
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Suggest more descriptive link text by adding context
|
|
59
|
+
* @param linkText Original link text
|
|
60
|
+
* @param surroundingText Text surrounding the link for context
|
|
61
|
+
* @returns Improved link text or null if no improvement needed
|
|
62
|
+
*/
|
|
63
|
+
function suggestImprovedLinkText(linkText, surroundingText) {
|
|
64
|
+
// If link text is already descriptive, no change needed
|
|
65
|
+
if (!isNonDescriptive(linkText)) {
|
|
66
|
+
return null;
|
|
67
|
+
}
|
|
68
|
+
// Try to find context from surrounding text
|
|
69
|
+
// Get 5 words before and after the link
|
|
70
|
+
const contextWords = surroundingText.split(/\s+/);
|
|
71
|
+
const linkWordIndex = contextWords.findIndex(word => word.includes(`[${linkText}]`));
|
|
72
|
+
if (linkWordIndex === -1) {
|
|
73
|
+
// Fallback improvement if we can't find context
|
|
74
|
+
return `More information about ${linkText}`;
|
|
75
|
+
}
|
|
76
|
+
// Get words before the link (up to 5)
|
|
77
|
+
const startIndex = Math.max(0, linkWordIndex - 5);
|
|
78
|
+
const beforeWords = contextWords.slice(startIndex, linkWordIndex).join(' ');
|
|
79
|
+
// Get words after the link (up to 5)
|
|
80
|
+
const endIndex = Math.min(contextWords.length, linkWordIndex + 6);
|
|
81
|
+
const afterWords = contextWords.slice(linkWordIndex + 1, endIndex).join(' ');
|
|
82
|
+
// Try to form an improved link text using context
|
|
83
|
+
let improvedText = '';
|
|
84
|
+
// Check for context in surrounding text
|
|
85
|
+
const topicMatch = surroundingText.match(/(?:about|regarding|on|for)\s+(\w+(?:\s+\w+){0,4})/i);
|
|
86
|
+
if (topicMatch && topicMatch[1]) {
|
|
87
|
+
improvedText = `${linkText} about ${topicMatch[1]}`;
|
|
88
|
+
}
|
|
89
|
+
else if (beforeWords && afterWords) {
|
|
90
|
+
// Combine some context before and after
|
|
91
|
+
const beforeContext = beforeWords.split(/\s+/).slice(-2).join(' ');
|
|
92
|
+
const afterContext = afterWords.split(/\s+/).slice(0, 2).join(' ');
|
|
93
|
+
improvedText = `${beforeContext} ${linkText} ${afterContext}`.trim();
|
|
94
|
+
}
|
|
95
|
+
else if (beforeWords) {
|
|
96
|
+
// Use context from before
|
|
97
|
+
const relevantBefore = beforeWords.split(/\s+/).slice(-3).join(' ');
|
|
98
|
+
improvedText = `${relevantBefore} ${linkText}`.trim();
|
|
99
|
+
}
|
|
100
|
+
else if (afterWords) {
|
|
101
|
+
// Use context from after
|
|
102
|
+
const relevantAfter = afterWords.split(/\s+/).slice(0, 3).join(' ');
|
|
103
|
+
improvedText = `${linkText} ${relevantAfter}`.trim();
|
|
104
|
+
}
|
|
105
|
+
else {
|
|
106
|
+
// Fallback if no context is found
|
|
107
|
+
improvedText = `More information about ${linkText}`;
|
|
108
|
+
}
|
|
109
|
+
return improvedText;
|
|
110
|
+
}
|
|
111
|
+
/**
|
|
112
|
+
* Fix non-descriptive link text in Markdown files
|
|
113
|
+
* @param lines Array of string lines to fix
|
|
114
|
+
* @returns Fixed lines array with more descriptive link text
|
|
115
|
+
*/
|
|
116
|
+
export function fix(lines) {
|
|
117
|
+
return lines.map((line, _index) => {
|
|
118
|
+
// Skip lines that don't have any links
|
|
119
|
+
if (!line.includes('[') || !line.includes('](')) {
|
|
120
|
+
return line;
|
|
121
|
+
}
|
|
122
|
+
let result = line;
|
|
123
|
+
let match;
|
|
124
|
+
let offset = 0;
|
|
125
|
+
// Reset the regex lastIndex
|
|
126
|
+
LINK_REGEX.lastIndex = 0;
|
|
127
|
+
// Process each link in the line
|
|
128
|
+
while ((match = LINK_REGEX.exec(line)) !== null) {
|
|
129
|
+
const [fullMatch, linkText] = match;
|
|
130
|
+
// Check if link text is non-descriptive
|
|
131
|
+
if (isNonDescriptive(linkText)) {
|
|
132
|
+
// Use surrounding text for context
|
|
133
|
+
const improvedText = suggestImprovedLinkText(linkText, line);
|
|
134
|
+
if (improvedText) {
|
|
135
|
+
// Create the new link text
|
|
136
|
+
const newText = fullMatch.replace(`[${linkText}]`, `[${improvedText}]`);
|
|
137
|
+
// Replace at the correct position with the offset applied
|
|
138
|
+
const startPos = match.index + offset;
|
|
139
|
+
const endPos = startPos + fullMatch.length;
|
|
140
|
+
// Update the result string
|
|
141
|
+
result = result.substring(0, startPos) + newText + result.substring(endPos);
|
|
142
|
+
// Update the offset for subsequent replacements
|
|
143
|
+
offset += newText.length - fullMatch.length;
|
|
144
|
+
// Update the lastIndex to account for the change in string length
|
|
145
|
+
LINK_REGEX.lastIndex += newText.length - fullMatch.length;
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
return result;
|
|
150
|
+
});
|
|
151
|
+
}
|
|
152
|
+
/**
|
|
153
|
+
* Rule implementation for MD059
|
|
154
|
+
*/
|
|
155
|
+
export const rule = {
|
|
156
|
+
name,
|
|
157
|
+
description,
|
|
158
|
+
fix,
|
|
159
|
+
};
|
|
160
|
+
export default rule;
|
|
161
|
+
//# sourceMappingURL=md059.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"md059.js","sourceRoot":"","sources":["../../src/rules/md059.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Represents a rule violation detected by a rule
|
|
3
|
+
*/
|
|
4
|
+
export interface RuleViolation {
|
|
5
|
+
/**
|
|
6
|
+
* Line number where the violation was found (1-based)
|
|
7
|
+
*/
|
|
8
|
+
lineNumber: number;
|
|
9
|
+
/**
|
|
10
|
+
* Details about the violation
|
|
11
|
+
*/
|
|
12
|
+
details: string;
|
|
13
|
+
/**
|
|
14
|
+
* Range [startIndex, length] where the violation occurs
|
|
15
|
+
*/
|
|
16
|
+
range?: [number, number];
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Interface for rule implementations
|
|
20
|
+
*/
|
|
21
|
+
export interface Rule {
|
|
22
|
+
/**
|
|
23
|
+
* Rule name
|
|
24
|
+
*/
|
|
25
|
+
name: string;
|
|
26
|
+
/**
|
|
27
|
+
* Rule description
|
|
28
|
+
*/
|
|
29
|
+
description: string;
|
|
30
|
+
/**
|
|
31
|
+
* Validate function that checks an array of lines for violations
|
|
32
|
+
* @param lines Array of string lines to validate
|
|
33
|
+
* @param config Optional rule configuration
|
|
34
|
+
* @returns Array of rule violations
|
|
35
|
+
*/
|
|
36
|
+
validate?: (lines: string[], config?: any) => RuleViolation[];
|
|
37
|
+
/**
|
|
38
|
+
* Fix function that applies the rule to an array of lines
|
|
39
|
+
* @param lines Array of string lines to fix
|
|
40
|
+
* @param config Optional rule configuration
|
|
41
|
+
* @returns Fixed lines array
|
|
42
|
+
*/
|
|
43
|
+
fix?: (lines: string[], config?: any) => string[];
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Type for the rules map
|
|
47
|
+
*/
|
|
48
|
+
export interface RuleMap {
|
|
49
|
+
[key: string]: Rule;
|
|
50
|
+
}
|
|
51
|
+
//# sourceMappingURL=rule-interface.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rule-interface.d.ts","sourceRoot":"","sources":["../../src/rules/rule-interface.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B;;OAEG;IACH,UAAU,EAAE,MAAM,CAAC;IAEnB;;OAEG;IACH,OAAO,EAAE,MAAM,CAAC;IAEhB;;OAEG;IACH,KAAK,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAC1B;AAED;;GAEG;AAEH,MAAM,WAAW,IAAI;IACnB;;OAEG;IACH,IAAI,EAAE,MAAM,CAAC;IAEb;;OAEG;IACH,WAAW,EAAE,MAAM,CAAC;IAEpB;;;;;OAKG;IACH,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,EAAE,MAAM,CAAC,EAAE,GAAG,KAAK,aAAa,EAAE,CAAC;IAE9D;;;;;OAKG;IACH,GAAG,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,EAAE,MAAM,CAAC,EAAE,GAAG,KAAK,MAAM,EAAE,CAAC;CACnD;AAGD;;GAEG;AACH,MAAM,WAAW,OAAO;IACtB,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC;CACrB"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rule-interface.js","sourceRoot":"","sources":["../../src/rules/rule-interface.ts"],"names":[],"mappings":""}
|
package/dist/server.d.ts
ADDED
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* MCP server for markdownlint functionality
|
|
3
|
+
* Provides tools for linting and fixing markdown files
|
|
4
|
+
*/
|
|
5
|
+
export declare class MarkdownLintServer {
|
|
6
|
+
private server;
|
|
7
|
+
/**
|
|
8
|
+
* Initialize the markdownlint MCP server
|
|
9
|
+
*/
|
|
10
|
+
constructor();
|
|
11
|
+
/**
|
|
12
|
+
* Set up handlers for MCP tool requests
|
|
13
|
+
*/
|
|
14
|
+
private setupToolHandlers;
|
|
15
|
+
/**
|
|
16
|
+
* Lint a markdown file and report issues
|
|
17
|
+
* @param filePath Path to the markdown file
|
|
18
|
+
* @returns MCP content response with linting results
|
|
19
|
+
*/
|
|
20
|
+
lintMarkdown(filePath: string): Promise<{
|
|
21
|
+
content: {
|
|
22
|
+
type: string;
|
|
23
|
+
text: string;
|
|
24
|
+
}[];
|
|
25
|
+
}>;
|
|
26
|
+
/**
|
|
27
|
+
* Fix markdown issues in a file
|
|
28
|
+
* @param filePath Path to the markdown file
|
|
29
|
+
* @param writeToFile Whether to write fixes back to the file
|
|
30
|
+
* @returns MCP content response with fix results
|
|
31
|
+
*/
|
|
32
|
+
fixMarkdown(filePath: string, writeToFile: boolean): Promise<{
|
|
33
|
+
content: {
|
|
34
|
+
type: string;
|
|
35
|
+
text: string;
|
|
36
|
+
}[];
|
|
37
|
+
}>;
|
|
38
|
+
/**
|
|
39
|
+
* Get the current markdownlint configuration
|
|
40
|
+
* @returns MCP content response with configuration details
|
|
41
|
+
*/
|
|
42
|
+
getConfiguration(): Promise<{
|
|
43
|
+
content: {
|
|
44
|
+
type: string;
|
|
45
|
+
text: string;
|
|
46
|
+
}[];
|
|
47
|
+
}>;
|
|
48
|
+
/**
|
|
49
|
+
* Start the MCP server
|
|
50
|
+
*/
|
|
51
|
+
run(): Promise<void>;
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Create and return a new MarkdownLint server instance
|
|
55
|
+
* @returns A new MarkdownLintServer instance
|
|
56
|
+
*/
|
|
57
|
+
export declare function createServer(): MarkdownLintServer;
|
|
58
|
+
export default MarkdownLintServer;
|
|
59
|
+
//# sourceMappingURL=server.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAsBA;;;GAGG;AACH,qBAAa,kBAAkB;IAC7B,OAAO,CAAC,MAAM,CAAS;IAEvB;;OAEG;;IAwBH;;OAEG;IACH,OAAO,CAAC,iBAAiB;IAkGzB;;;;OAIG;IACU,YAAY,CAAC,QAAQ,EAAE,MAAM;;;;;;IA+F1C;;;;;OAKG;IACU,WAAW,CAAC,QAAQ,EAAE,MAAM,EAAE,WAAW,EAAE,OAAO;;;;;;IAoN/D;;;OAGG;IACU,gBAAgB;;;;;;IAc7B;;OAEG;IACU,GAAG;CAMjB;AAED;;;GAGG;AACH,wBAAgB,YAAY,IAAI,kBAAkB,CAEjD;AAED,eAAe,kBAAkB,CAAC"}
|