devsmind-mcp 1.2.1 → 2.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/LICENSE +21 -21
- package/README.md +55 -47
- package/dist/cli/runner.js +232 -151
- package/dist/cli/runner.js.map +1 -1
- package/dist/db/database.d.ts +15 -1
- package/dist/db/database.js +420 -74
- package/dist/db/database.js.map +1 -1
- package/dist/db/schema.js +33 -33
- package/dist/mcp/server.js +21 -9
- package/dist/mcp/server.js.map +1 -1
- package/dist/mcp/visualizer_2d.html +635 -635
- package/dist/mcp/visualizer_3d.html +628 -628
- package/dist/utils/json.d.ts +16 -0
- package/dist/utils/json.js +151 -0
- package/dist/utils/json.js.map +1 -0
- package/package.json +7 -3
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Extracts the outermost JSON structure (object or array) from a string.
|
|
3
|
+
* This handles cases where the LLM wraps JSON in markdown blocks (e.g. ```json ... ```)
|
|
4
|
+
* or outputs conversational text before/after the actual JSON response.
|
|
5
|
+
*/
|
|
6
|
+
export declare function extractJsonBlock(text: string): string;
|
|
7
|
+
/**
|
|
8
|
+
* Repairs a truncated or incomplete JSON string by closing unclosed string literals
|
|
9
|
+
* and appending matching closing braces/brackets for any unclosed structures.
|
|
10
|
+
*/
|
|
11
|
+
export declare function repairJson(str: string): string;
|
|
12
|
+
/**
|
|
13
|
+
* Safely parses a JSON string, extracting the JSON block and repairing it if necessary.
|
|
14
|
+
* Returns the fallback value if parsing fails.
|
|
15
|
+
*/
|
|
16
|
+
export declare function safeJsonParse<T>(text: string, fallback: T): T;
|
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.extractJsonBlock = extractJsonBlock;
|
|
4
|
+
exports.repairJson = repairJson;
|
|
5
|
+
exports.safeJsonParse = safeJsonParse;
|
|
6
|
+
/**
|
|
7
|
+
* Extracts the outermost JSON structure (object or array) from a string.
|
|
8
|
+
* This handles cases where the LLM wraps JSON in markdown blocks (e.g. ```json ... ```)
|
|
9
|
+
* or outputs conversational text before/after the actual JSON response.
|
|
10
|
+
*/
|
|
11
|
+
function extractJsonBlock(text) {
|
|
12
|
+
let cleaned = text.trim();
|
|
13
|
+
// Remove markdown code block wrappers if present
|
|
14
|
+
if (cleaned.startsWith('```')) {
|
|
15
|
+
const firstNewline = cleaned.indexOf('\n');
|
|
16
|
+
if (firstNewline !== -1) {
|
|
17
|
+
cleaned = cleaned.substring(firstNewline + 1);
|
|
18
|
+
}
|
|
19
|
+
else {
|
|
20
|
+
cleaned = cleaned.substring(3);
|
|
21
|
+
}
|
|
22
|
+
if (cleaned.endsWith('```')) {
|
|
23
|
+
cleaned = cleaned.substring(0, cleaned.length - 3);
|
|
24
|
+
}
|
|
25
|
+
cleaned = cleaned.trim();
|
|
26
|
+
}
|
|
27
|
+
// Locate the start of the JSON object or array
|
|
28
|
+
const firstBrace = cleaned.indexOf('{');
|
|
29
|
+
const firstBracket = cleaned.indexOf('[');
|
|
30
|
+
let startIdx = -1;
|
|
31
|
+
let endChar = '}';
|
|
32
|
+
if (firstBrace !== -1 && (firstBracket === -1 || firstBrace < firstBracket)) {
|
|
33
|
+
startIdx = firstBrace;
|
|
34
|
+
endChar = '}';
|
|
35
|
+
}
|
|
36
|
+
else if (firstBracket !== -1) {
|
|
37
|
+
startIdx = firstBracket;
|
|
38
|
+
endChar = ']';
|
|
39
|
+
}
|
|
40
|
+
if (startIdx === -1) {
|
|
41
|
+
return cleaned; // Fallback to raw text if no JSON character is found
|
|
42
|
+
}
|
|
43
|
+
const lastEndIdx = cleaned.lastIndexOf(endChar);
|
|
44
|
+
if (lastEndIdx !== -1 && lastEndIdx > startIdx) {
|
|
45
|
+
return cleaned.substring(startIdx, lastEndIdx + 1);
|
|
46
|
+
}
|
|
47
|
+
// If there's a starting brace/bracket but no matching ending brace/bracket,
|
|
48
|
+
// return from the start index to the end (repairJson will close it).
|
|
49
|
+
return cleaned.substring(startIdx);
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Repairs a truncated or incomplete JSON string by closing unclosed string literals
|
|
53
|
+
* and appending matching closing braces/brackets for any unclosed structures.
|
|
54
|
+
*/
|
|
55
|
+
function repairJson(str) {
|
|
56
|
+
let s = str.trim();
|
|
57
|
+
if (!s)
|
|
58
|
+
return '{}';
|
|
59
|
+
let inString = false;
|
|
60
|
+
let isEscaped = false;
|
|
61
|
+
const stack = [];
|
|
62
|
+
for (let i = 0; i < s.length; i++) {
|
|
63
|
+
const char = s[i];
|
|
64
|
+
if (inString) {
|
|
65
|
+
if (isEscaped) {
|
|
66
|
+
isEscaped = false;
|
|
67
|
+
}
|
|
68
|
+
else if (char === '\\') {
|
|
69
|
+
isEscaped = true;
|
|
70
|
+
}
|
|
71
|
+
else if (char === '"') {
|
|
72
|
+
inString = false;
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
else {
|
|
76
|
+
if (char === '"') {
|
|
77
|
+
inString = true;
|
|
78
|
+
isEscaped = false;
|
|
79
|
+
}
|
|
80
|
+
else if (char === '{') {
|
|
81
|
+
stack.push('{');
|
|
82
|
+
}
|
|
83
|
+
else if (char === '[') {
|
|
84
|
+
stack.push('[');
|
|
85
|
+
}
|
|
86
|
+
else if (char === '}') {
|
|
87
|
+
if (stack.length > 0 && stack[stack.length - 1] === '{') {
|
|
88
|
+
stack.pop();
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
else if (char === ']') {
|
|
92
|
+
if (stack.length > 0 && stack[stack.length - 1] === '[') {
|
|
93
|
+
stack.pop();
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
// If the string ended with a dangling escape backslash, remove it
|
|
99
|
+
// so it doesn't escape the closing quote we are about to add.
|
|
100
|
+
if (inString && s.endsWith('\\') && isEscaped) {
|
|
101
|
+
s = s.slice(0, -1);
|
|
102
|
+
}
|
|
103
|
+
let repaired = s;
|
|
104
|
+
if (inString) {
|
|
105
|
+
repaired += '"';
|
|
106
|
+
}
|
|
107
|
+
// Close open brackets/braces in reverse order
|
|
108
|
+
while (stack.length > 0) {
|
|
109
|
+
const open = stack.pop();
|
|
110
|
+
if (open === '{') {
|
|
111
|
+
repaired += '}';
|
|
112
|
+
}
|
|
113
|
+
else if (open === '[') {
|
|
114
|
+
repaired += ']';
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
return repaired;
|
|
118
|
+
}
|
|
119
|
+
/**
|
|
120
|
+
* Safely parses a JSON string, extracting the JSON block and repairing it if necessary.
|
|
121
|
+
* Returns the fallback value if parsing fails.
|
|
122
|
+
*/
|
|
123
|
+
function safeJsonParse(text, fallback) {
|
|
124
|
+
if (!text || typeof text !== 'string') {
|
|
125
|
+
return fallback;
|
|
126
|
+
}
|
|
127
|
+
try {
|
|
128
|
+
// 1. Direct parse check
|
|
129
|
+
return JSON.parse(text);
|
|
130
|
+
}
|
|
131
|
+
catch (err) {
|
|
132
|
+
// Direct parse failed, let's try extraction and repair
|
|
133
|
+
try {
|
|
134
|
+
const extracted = extractJsonBlock(text);
|
|
135
|
+
return JSON.parse(extracted);
|
|
136
|
+
}
|
|
137
|
+
catch (err2) {
|
|
138
|
+
try {
|
|
139
|
+
const extracted = extractJsonBlock(text);
|
|
140
|
+
const repaired = repairJson(extracted);
|
|
141
|
+
return JSON.parse(repaired);
|
|
142
|
+
}
|
|
143
|
+
catch (err3) {
|
|
144
|
+
// Logging the parsing failure so developers are aware
|
|
145
|
+
console.warn(`[JSON Parse Warning] Failed to parse repaired JSON. Error: ${err3.message}`);
|
|
146
|
+
return fallback;
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
//# sourceMappingURL=json.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"json.js","sourceRoot":"","sources":["../../src/utils/json.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "devsmind-mcp",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "2.0.0",
|
|
4
4
|
"description": "DevsMind — Team AI Brain",
|
|
5
5
|
"main": "dist/cli/index.js",
|
|
6
6
|
"bin": {
|
|
7
|
-
"devsmind": "
|
|
7
|
+
"devsmind": "dist/cli/index.js"
|
|
8
8
|
},
|
|
9
9
|
"type": "commonjs",
|
|
10
10
|
"files": [
|
|
@@ -43,7 +43,7 @@
|
|
|
43
43
|
"dependencies": {
|
|
44
44
|
"@modelcontextprotocol/sdk": "^1.0.1",
|
|
45
45
|
"@types/express": "^5.0.6",
|
|
46
|
-
"better-sqlite3": "^11.1
|
|
46
|
+
"better-sqlite3": "^12.11.1",
|
|
47
47
|
"commander": "^12.1.0",
|
|
48
48
|
"dotenv": "^16.4.5",
|
|
49
49
|
"express": "^5.2.1",
|
|
@@ -55,5 +55,9 @@
|
|
|
55
55
|
"@types/prompts": "^2.4.9",
|
|
56
56
|
"tsx": "^4.16.0",
|
|
57
57
|
"typescript": "^5.5.2"
|
|
58
|
+
},
|
|
59
|
+
"allowScripts": {
|
|
60
|
+
"better-sqlite3@12.11.1": true,
|
|
61
|
+
"esbuild@0.28.1": true
|
|
58
62
|
}
|
|
59
63
|
}
|