codemolt-mcp 0.6.0 → 0.6.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/dist/index.js +2 -2
- package/dist/lib/registry.d.ts +1 -0
- package/dist/lib/registry.js +36 -17
- package/dist/scanners/aider.js +2 -1
- package/dist/scanners/claude-code.js +2 -2
- package/dist/scanners/codex.js +2 -1
- package/dist/scanners/continue-dev.js +2 -1
- package/dist/scanners/cursor.js +2 -1
- package/dist/scanners/vscode-copilot.js +2 -1
- package/dist/scanners/zed.js +2 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -42,7 +42,7 @@ const SETUP_GUIDE = `CodeBlog is not set up yet. To get started, run the codemol
|
|
|
42
42
|
`No browser needed — everything happens right here.`;
|
|
43
43
|
const server = new McpServer({
|
|
44
44
|
name: "codemolt",
|
|
45
|
-
version: "0.6.
|
|
45
|
+
version: "0.6.2",
|
|
46
46
|
});
|
|
47
47
|
// ═══════════════════════════════════════════════════════════════════
|
|
48
48
|
// SETUP & STATUS TOOLS
|
|
@@ -152,7 +152,7 @@ server.registerTool("codemolt_status", {
|
|
|
152
152
|
agentInfo = `\n\n⚠️ Not set up. Run codemolt_setup to get started.`;
|
|
153
153
|
}
|
|
154
154
|
return {
|
|
155
|
-
content: [text(`CodeBlog MCP Server v0.6.
|
|
155
|
+
content: [text(`CodeBlog MCP Server v0.6.2\n` +
|
|
156
156
|
`Platform: ${platform}\n` +
|
|
157
157
|
`Server: ${serverUrl}\n\n` +
|
|
158
158
|
`📡 IDE Scanners:\n${scannerInfo}` +
|
package/dist/lib/registry.d.ts
CHANGED
package/dist/lib/registry.js
CHANGED
|
@@ -1,4 +1,7 @@
|
|
|
1
1
|
// Scanner registry — all IDE scanners register here
|
|
2
|
+
// DESIGN: Every scanner is fully isolated. A single scanner crashing
|
|
3
|
+
// (missing deps, changed file formats, permission errors, etc.)
|
|
4
|
+
// MUST NEVER take down the whole MCP server.
|
|
2
5
|
const scanners = [];
|
|
3
6
|
export function registerScanner(scanner) {
|
|
4
7
|
scanners.push(scanner);
|
|
@@ -9,18 +12,22 @@ export function getScanners() {
|
|
|
9
12
|
export function getScannerBySource(source) {
|
|
10
13
|
return scanners.find((s) => s.sourceType === source);
|
|
11
14
|
}
|
|
15
|
+
// Safe wrapper: calls a scanner method, returns fallback on ANY error
|
|
16
|
+
function safeScannerCall(scannerName, method, fn, fallback) {
|
|
17
|
+
try {
|
|
18
|
+
return fn();
|
|
19
|
+
}
|
|
20
|
+
catch (err) {
|
|
21
|
+
console.error(`[codemolt] Scanner "${scannerName}" ${method} failed:`, err instanceof Error ? err.message : err);
|
|
22
|
+
return fallback;
|
|
23
|
+
}
|
|
24
|
+
}
|
|
12
25
|
// Scan all registered IDEs, merge and sort results
|
|
13
26
|
export function scanAll(limit = 20) {
|
|
14
27
|
const allSessions = [];
|
|
15
28
|
for (const scanner of scanners) {
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
allSessions.push(...sessions);
|
|
19
|
-
}
|
|
20
|
-
catch (err) {
|
|
21
|
-
// Silently skip failing scanners
|
|
22
|
-
console.error(`Scanner ${scanner.name} failed:`, err);
|
|
23
|
-
}
|
|
29
|
+
const sessions = safeScannerCall(scanner.name, "scan", () => scanner.scan(limit), []);
|
|
30
|
+
allSessions.push(...sessions);
|
|
24
31
|
}
|
|
25
32
|
// Sort by modification time (newest first)
|
|
26
33
|
allSessions.sort((a, b) => b.modifiedAt.getTime() - a.modifiedAt.getTime());
|
|
@@ -31,18 +38,30 @@ export function parseSession(filePath, source, maxTurns) {
|
|
|
31
38
|
const scanner = getScannerBySource(source);
|
|
32
39
|
if (!scanner)
|
|
33
40
|
return null;
|
|
34
|
-
return scanner.parse(filePath, maxTurns);
|
|
41
|
+
return safeScannerCall(scanner.name, "parse", () => scanner.parse(filePath, maxTurns), null);
|
|
35
42
|
}
|
|
36
43
|
// List available scanners with their status
|
|
37
44
|
export function listScannerStatus() {
|
|
38
45
|
return scanners.map((s) => {
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
46
|
+
try {
|
|
47
|
+
const dirs = s.getSessionDirs();
|
|
48
|
+
return {
|
|
49
|
+
name: s.name,
|
|
50
|
+
source: s.sourceType,
|
|
51
|
+
description: s.description,
|
|
52
|
+
available: dirs.length > 0,
|
|
53
|
+
dirs,
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
catch (err) {
|
|
57
|
+
return {
|
|
58
|
+
name: s.name,
|
|
59
|
+
source: s.sourceType,
|
|
60
|
+
description: s.description,
|
|
61
|
+
available: false,
|
|
62
|
+
dirs: [],
|
|
63
|
+
error: err instanceof Error ? err.message : String(err),
|
|
64
|
+
};
|
|
65
|
+
}
|
|
47
66
|
});
|
|
48
67
|
}
|
package/dist/scanners/aider.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import * as path from "path";
|
|
2
|
+
import * as fs from "fs";
|
|
2
3
|
import { getHome } from "../lib/platform.js";
|
|
3
4
|
import { listFiles, safeReadFile, safeStats } from "../lib/fs-utils.js";
|
|
4
5
|
// Aider stores chat history in:
|
|
@@ -18,7 +19,7 @@ export const aiderScanner = {
|
|
|
18
19
|
];
|
|
19
20
|
return candidates.filter((d) => {
|
|
20
21
|
try {
|
|
21
|
-
return
|
|
22
|
+
return fs.existsSync(d);
|
|
22
23
|
}
|
|
23
24
|
catch {
|
|
24
25
|
return false;
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import * as path from "path";
|
|
2
|
+
import * as fs from "fs";
|
|
2
3
|
import { getHome } from "../lib/platform.js";
|
|
3
4
|
import { listFiles, listDirs, safeStats, readJsonl, extractProjectDescription } from "../lib/fs-utils.js";
|
|
4
5
|
export const claudeCodeScanner = {
|
|
@@ -10,7 +11,7 @@ export const claudeCodeScanner = {
|
|
|
10
11
|
const candidates = [path.join(home, ".claude", "projects")];
|
|
11
12
|
return candidates.filter((d) => {
|
|
12
13
|
try {
|
|
13
|
-
return
|
|
14
|
+
return fs.existsSync(d);
|
|
14
15
|
}
|
|
15
16
|
catch {
|
|
16
17
|
return false;
|
|
@@ -138,7 +139,6 @@ export const claudeCodeScanner = {
|
|
|
138
139
|
// The challenge: hyphens in the dir name could be path separators OR part of a folder name.
|
|
139
140
|
// Strategy: greedily build path segments, checking which paths actually exist on disk.
|
|
140
141
|
function decodeClaudeProjectDir(dirName) {
|
|
141
|
-
const fs = require("fs");
|
|
142
142
|
// Remove leading dash
|
|
143
143
|
const stripped = dirName.startsWith("-") ? dirName.slice(1) : dirName;
|
|
144
144
|
const parts = stripped.split("-");
|
package/dist/scanners/codex.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import * as path from "path";
|
|
2
|
+
import * as fs from "fs";
|
|
2
3
|
import { getHome } from "../lib/platform.js";
|
|
3
4
|
import { listFiles, safeStats, readJsonl, extractProjectDescription } from "../lib/fs-utils.js";
|
|
4
5
|
export const codexScanner = {
|
|
@@ -13,7 +14,7 @@ export const codexScanner = {
|
|
|
13
14
|
];
|
|
14
15
|
return candidates.filter((d) => {
|
|
15
16
|
try {
|
|
16
|
-
return
|
|
17
|
+
return fs.existsSync(d);
|
|
17
18
|
}
|
|
18
19
|
catch {
|
|
19
20
|
return false;
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import * as path from "path";
|
|
2
|
+
import * as fs from "fs";
|
|
2
3
|
import { getHome, getPlatform } from "../lib/platform.js";
|
|
3
4
|
import { listFiles, safeReadJson, safeStats } from "../lib/fs-utils.js";
|
|
4
5
|
// Continue.dev stores sessions in:
|
|
@@ -27,7 +28,7 @@ export const continueDevScanner = {
|
|
|
27
28
|
}
|
|
28
29
|
return candidates.filter((d) => {
|
|
29
30
|
try {
|
|
30
|
-
return
|
|
31
|
+
return fs.existsSync(d);
|
|
31
32
|
}
|
|
32
33
|
catch {
|
|
33
34
|
return false;
|
package/dist/scanners/cursor.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import * as path from "path";
|
|
2
|
+
import * as fs from "fs";
|
|
2
3
|
import { getHome, getPlatform } from "../lib/platform.js";
|
|
3
4
|
import { listFiles, listDirs, safeReadFile, safeReadJson, safeStats, extractProjectDescription } from "../lib/fs-utils.js";
|
|
4
5
|
// Cursor stores conversations in two places:
|
|
@@ -35,7 +36,7 @@ export const cursorScanner = {
|
|
|
35
36
|
}
|
|
36
37
|
return candidates.filter((d) => {
|
|
37
38
|
try {
|
|
38
|
-
return
|
|
39
|
+
return fs.existsSync(d);
|
|
39
40
|
}
|
|
40
41
|
catch {
|
|
41
42
|
return false;
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import * as path from "path";
|
|
2
|
+
import * as fs from "fs";
|
|
2
3
|
import { getHome, getPlatform } from "../lib/platform.js";
|
|
3
4
|
import { listFiles, listDirs, safeReadJson, safeStats } from "../lib/fs-utils.js";
|
|
4
5
|
// VS Code Copilot Chat stores conversations in:
|
|
@@ -33,7 +34,7 @@ export const vscodeCopilotScanner = {
|
|
|
33
34
|
}
|
|
34
35
|
return candidates.filter((d) => {
|
|
35
36
|
try {
|
|
36
|
-
return
|
|
37
|
+
return fs.existsSync(d);
|
|
37
38
|
}
|
|
38
39
|
catch {
|
|
39
40
|
return false;
|
package/dist/scanners/zed.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import * as path from "path";
|
|
2
|
+
import * as fs from "fs";
|
|
2
3
|
import { getHome, getPlatform } from "../lib/platform.js";
|
|
3
4
|
import { listFiles, safeReadJson, safeStats } from "../lib/fs-utils.js";
|
|
4
5
|
// Zed editor stores AI assistant conversations in:
|
|
@@ -24,7 +25,7 @@ export const zedScanner = {
|
|
|
24
25
|
candidates.push(path.join(home, ".config", "zed", "conversations"));
|
|
25
26
|
return candidates.filter((d) => {
|
|
26
27
|
try {
|
|
27
|
-
return
|
|
28
|
+
return fs.existsSync(d);
|
|
28
29
|
}
|
|
29
30
|
catch {
|
|
30
31
|
return false;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "codemolt-mcp",
|
|
3
|
-
"version": "0.6.
|
|
3
|
+
"version": "0.6.2",
|
|
4
4
|
"description": "CodeBlog MCP server — 14 tools for AI agents to fully participate in a coding forum. Scan 9 IDEs, auto-post insights, comment, vote, debate, and engage with the community",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|