mobbdev 1.0.184 → 1.0.186
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.mjs +165 -57
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -1692,6 +1692,7 @@ var IssueType_Enum = /* @__PURE__ */ ((IssueType_Enum2) => {
|
|
|
1692
1692
|
IssueType_Enum2["DeclareVariableExplicitly"] = "DECLARE_VARIABLE_EXPLICITLY";
|
|
1693
1693
|
IssueType_Enum2["DefaultRightsInObjDefinition"] = "DEFAULT_RIGHTS_IN_OBJ_DEFINITION";
|
|
1694
1694
|
IssueType_Enum2["DeprecatedFunction"] = "DEPRECATED_FUNCTION";
|
|
1695
|
+
IssueType_Enum2["DjangoBlankFieldNeedsNullOrDefault"] = "DJANGO_BLANK_FIELD_NEEDS_NULL_OR_DEFAULT";
|
|
1695
1696
|
IssueType_Enum2["DosStringBuilder"] = "DOS_STRING_BUILDER";
|
|
1696
1697
|
IssueType_Enum2["DoNotRaiseException"] = "DO_NOT_RAISE_EXCEPTION";
|
|
1697
1698
|
IssueType_Enum2["DoNotThrowGenericException"] = "DO_NOT_THROW_GENERIC_EXCEPTION";
|
|
@@ -2916,7 +2917,8 @@ var fixDetailsData = {
|
|
|
2916
2917
|
["FUNCTION_CALL_WITHOUT_PARENTHESES" /* FunctionCallWithoutParentheses */]: void 0,
|
|
2917
2918
|
["SPRING_DEFAULT_PERMIT" /* SpringDefaultPermit */]: void 0,
|
|
2918
2919
|
["RETURN_IN_INIT" /* ReturnInInit */]: void 0,
|
|
2919
|
-
["ACTION_NOT_PINNED_TO_COMMIT_SHA" /* ActionNotPinnedToCommitSha */]: void 0
|
|
2920
|
+
["ACTION_NOT_PINNED_TO_COMMIT_SHA" /* ActionNotPinnedToCommitSha */]: void 0,
|
|
2921
|
+
["DJANGO_BLANK_FIELD_NEEDS_NULL_OR_DEFAULT" /* DjangoBlankFieldNeedsNullOrDefault */]: void 0
|
|
2920
2922
|
};
|
|
2921
2923
|
|
|
2922
2924
|
// src/features/analysis/scm/shared/src/getIssueType.ts
|
|
@@ -3054,7 +3056,8 @@ var issueTypeMap = {
|
|
|
3054
3056
|
["FUNCTION_CALL_WITHOUT_PARENTHESES" /* FunctionCallWithoutParentheses */]: "Function Call Without Parentheses",
|
|
3055
3057
|
["SPRING_DEFAULT_PERMIT" /* SpringDefaultPermit */]: "Spring Default Permit",
|
|
3056
3058
|
["RETURN_IN_INIT" /* ReturnInInit */]: "Return in Init",
|
|
3057
|
-
["ACTION_NOT_PINNED_TO_COMMIT_SHA" /* ActionNotPinnedToCommitSha */]: "Action Not Pinned to Commit Sha"
|
|
3059
|
+
["ACTION_NOT_PINNED_TO_COMMIT_SHA" /* ActionNotPinnedToCommitSha */]: "Action Not Pinned to Commit Sha",
|
|
3060
|
+
["DJANGO_BLANK_FIELD_NEEDS_NULL_OR_DEFAULT" /* DjangoBlankFieldNeedsNullOrDefault */]: "Django Blank Field Needs Null or Default"
|
|
3058
3061
|
};
|
|
3059
3062
|
var issueTypeZ = z.nativeEnum(IssueType_Enum);
|
|
3060
3063
|
var getIssueTypeFriendlyString = (issueType) => {
|
|
@@ -12373,6 +12376,12 @@ var WorkspaceService = class {
|
|
|
12373
12376
|
static getKnownWorkspacePath() {
|
|
12374
12377
|
return this.knownWorkspacePath;
|
|
12375
12378
|
}
|
|
12379
|
+
/**
|
|
12380
|
+
* Clears the known workspace path cache
|
|
12381
|
+
*/
|
|
12382
|
+
static clearKnownWorkspacePath() {
|
|
12383
|
+
this.knownWorkspacePath = void 0;
|
|
12384
|
+
}
|
|
12376
12385
|
/**
|
|
12377
12386
|
* Gets the workspace folder path from known path or environment variables
|
|
12378
12387
|
* @returns The workspace folder path or undefined if none found
|
|
@@ -13357,52 +13366,119 @@ var gitInfo = {
|
|
|
13357
13366
|
name: runCommand("git config user.name"),
|
|
13358
13367
|
email: runCommand("git config user.email")
|
|
13359
13368
|
};
|
|
13360
|
-
var
|
|
13369
|
+
var getClaudeWorkspacePaths = () => {
|
|
13370
|
+
const home = os3.homedir();
|
|
13371
|
+
const claudeIdePath = path11.join(home, ".claude", "ide");
|
|
13372
|
+
const workspacePaths = [];
|
|
13373
|
+
if (!fs10.existsSync(claudeIdePath)) {
|
|
13374
|
+
return workspacePaths;
|
|
13375
|
+
}
|
|
13376
|
+
try {
|
|
13377
|
+
const lockFiles = fs10.readdirSync(claudeIdePath).filter((file) => file.endsWith(".lock"));
|
|
13378
|
+
for (const lockFile of lockFiles) {
|
|
13379
|
+
const lockFilePath = path11.join(claudeIdePath, lockFile);
|
|
13380
|
+
try {
|
|
13381
|
+
const lockContent = JSON.parse(fs10.readFileSync(lockFilePath, "utf8"));
|
|
13382
|
+
if (lockContent.workspaceFolders && Array.isArray(lockContent.workspaceFolders)) {
|
|
13383
|
+
workspacePaths.push(...lockContent.workspaceFolders);
|
|
13384
|
+
}
|
|
13385
|
+
} catch (error) {
|
|
13386
|
+
logWarn(
|
|
13387
|
+
`[UsageService] Failed to read Claude lock file: ${lockFilePath}`
|
|
13388
|
+
);
|
|
13389
|
+
}
|
|
13390
|
+
}
|
|
13391
|
+
} catch (error) {
|
|
13392
|
+
logWarn(
|
|
13393
|
+
`[UsageService] Failed to read Claude IDE directory: ${claudeIdePath}`
|
|
13394
|
+
);
|
|
13395
|
+
}
|
|
13396
|
+
return workspacePaths;
|
|
13397
|
+
};
|
|
13398
|
+
var getMCPConfigPaths = (hostName) => {
|
|
13361
13399
|
const home = os3.homedir();
|
|
13400
|
+
const currentDir = process.env["WORKSPACE_FOLDER_PATHS"] || process.env["PWD"] || process.cwd();
|
|
13362
13401
|
switch (hostName.toLowerCase()) {
|
|
13363
13402
|
case "cursor":
|
|
13364
|
-
return
|
|
13403
|
+
return [
|
|
13404
|
+
path11.join(currentDir, ".cursor", "mcp.json"),
|
|
13405
|
+
// local first
|
|
13406
|
+
path11.join(home, ".cursor", "mcp.json")
|
|
13407
|
+
];
|
|
13365
13408
|
case "windsurf":
|
|
13366
|
-
return
|
|
13409
|
+
return [
|
|
13410
|
+
path11.join(currentDir, ".codeium", "mcp_config.json"),
|
|
13411
|
+
// local first
|
|
13412
|
+
path11.join(home, ".codeium", "windsurf", "mcp_config.json")
|
|
13413
|
+
];
|
|
13367
13414
|
case "webstorm":
|
|
13368
|
-
return
|
|
13415
|
+
return [];
|
|
13369
13416
|
case "visualstudiocode":
|
|
13370
13417
|
case "vscode":
|
|
13371
|
-
return
|
|
13372
|
-
|
|
13373
|
-
|
|
13374
|
-
"
|
|
13375
|
-
|
|
13376
|
-
|
|
13377
|
-
|
|
13378
|
-
|
|
13379
|
-
|
|
13380
|
-
|
|
13418
|
+
return [
|
|
13419
|
+
path11.join(currentDir, ".vscode", "mcp.json"),
|
|
13420
|
+
// local first
|
|
13421
|
+
process.platform === "win32" ? path11.join(home, "AppData", "Roaming", "Code", "User", "mcp.json") : path11.join(
|
|
13422
|
+
home,
|
|
13423
|
+
"Library",
|
|
13424
|
+
"Application Support",
|
|
13425
|
+
"Code",
|
|
13426
|
+
"User",
|
|
13427
|
+
"mcp.json"
|
|
13428
|
+
)
|
|
13429
|
+
];
|
|
13430
|
+
case "claude": {
|
|
13431
|
+
const claudePaths = [
|
|
13432
|
+
path11.join(currentDir, ".claude.json"),
|
|
13433
|
+
// local first
|
|
13434
|
+
path11.join(home, ".claude.json")
|
|
13435
|
+
];
|
|
13436
|
+
const workspacePaths = getClaudeWorkspacePaths();
|
|
13437
|
+
for (const workspacePath of workspacePaths) {
|
|
13438
|
+
claudePaths.push(path11.join(workspacePath, ".mcp.json"));
|
|
13439
|
+
}
|
|
13440
|
+
return claudePaths;
|
|
13441
|
+
}
|
|
13381
13442
|
default:
|
|
13382
13443
|
throw new Error(`Unknown hostName: ${hostName}`);
|
|
13383
13444
|
}
|
|
13384
13445
|
};
|
|
13385
|
-
var
|
|
13386
|
-
const filePath = getMCPConfigPath(hostName);
|
|
13446
|
+
var readConfigFile = (filePath) => {
|
|
13387
13447
|
if (!fs10.existsSync(filePath)) return null;
|
|
13388
|
-
|
|
13389
|
-
|
|
13390
|
-
|
|
13391
|
-
|
|
13392
|
-
|
|
13393
|
-
|
|
13394
|
-
|
|
13395
|
-
|
|
13396
|
-
|
|
13397
|
-
|
|
13448
|
+
try {
|
|
13449
|
+
return JSON.parse(fs10.readFileSync(filePath, "utf8"));
|
|
13450
|
+
} catch (error) {
|
|
13451
|
+
logWarn(`[UsageService] Failed to read MCP config: ${filePath}`);
|
|
13452
|
+
return null;
|
|
13453
|
+
}
|
|
13454
|
+
};
|
|
13455
|
+
var readMCPConfig = (hostName) => {
|
|
13456
|
+
const configPaths = getMCPConfigPaths(hostName);
|
|
13457
|
+
const mergedConfig = {};
|
|
13458
|
+
for (const configPath of configPaths) {
|
|
13459
|
+
const config4 = readConfigFile(configPath);
|
|
13460
|
+
if (hostName === "claude" && config4?.projects) {
|
|
13461
|
+
const allMcpServers = {};
|
|
13462
|
+
for (const projectPath in config4.projects) {
|
|
13463
|
+
const project = config4.projects[projectPath];
|
|
13464
|
+
if (project?.mcpServers) {
|
|
13465
|
+
Object.assign(allMcpServers, project.mcpServers);
|
|
13398
13466
|
}
|
|
13399
13467
|
}
|
|
13468
|
+
mergedConfig.mcpServers = { ...mergedConfig.mcpServers, ...allMcpServers };
|
|
13469
|
+
continue;
|
|
13470
|
+
}
|
|
13471
|
+
if (config4?.mcpServers) {
|
|
13472
|
+
mergedConfig.mcpServers = {
|
|
13473
|
+
...mergedConfig.mcpServers,
|
|
13474
|
+
...config4.mcpServers
|
|
13475
|
+
};
|
|
13476
|
+
}
|
|
13477
|
+
if (config4?.servers) {
|
|
13478
|
+
mergedConfig.servers = { ...mergedConfig.servers, ...config4.servers };
|
|
13400
13479
|
}
|
|
13401
|
-
return {
|
|
13402
|
-
mcpServers: allMcpServers
|
|
13403
|
-
};
|
|
13404
13480
|
}
|
|
13405
|
-
return
|
|
13481
|
+
return Object.keys(mergedConfig).length > 0 ? mergedConfig : null;
|
|
13406
13482
|
};
|
|
13407
13483
|
var getRunningProcesses = () => {
|
|
13408
13484
|
try {
|
|
@@ -13816,6 +13892,7 @@ var McpServer = class {
|
|
|
13816
13892
|
__publicField(this, "eventHandlers", /* @__PURE__ */ new Map());
|
|
13817
13893
|
__publicField(this, "parentProcessCheckInterval");
|
|
13818
13894
|
__publicField(this, "parentPid");
|
|
13895
|
+
__publicField(this, "socketEventHandlers", /* @__PURE__ */ new Map());
|
|
13819
13896
|
__publicField(this, "mcpUsageService");
|
|
13820
13897
|
this.parentPid = process.ppid;
|
|
13821
13898
|
this.mcpUsageService = govOrgId ? new McpUsageService(govOrgId) : null;
|
|
@@ -13936,31 +14013,43 @@ var McpServer = class {
|
|
|
13936
14013
|
logInfo("Setting up parent process monitoring", {
|
|
13937
14014
|
parentPid: this.parentPid
|
|
13938
14015
|
});
|
|
13939
|
-
|
|
14016
|
+
const stdinCloseHandler = async () => {
|
|
13940
14017
|
logDebug("stdin closed - parent likely terminated");
|
|
13941
14018
|
await this.handleParentProcessDeath("stdin-close");
|
|
13942
|
-
}
|
|
13943
|
-
|
|
14019
|
+
};
|
|
14020
|
+
const stdinEndHandler = async () => {
|
|
13944
14021
|
logDebug("stdin ended - parent likely terminated");
|
|
13945
14022
|
await this.handleParentProcessDeath("stdin-end");
|
|
13946
|
-
}
|
|
13947
|
-
|
|
14023
|
+
};
|
|
14024
|
+
const stdoutErrorHandler = async (...args) => {
|
|
14025
|
+
const error = args[0];
|
|
13948
14026
|
logWarn("stdout error - parent may have terminated", { error });
|
|
13949
14027
|
if (error.message.includes("EPIPE") || error.message.includes("ECONNRESET")) {
|
|
13950
14028
|
await this.handleParentProcessDeath("stdout-error");
|
|
13951
14029
|
}
|
|
13952
|
-
}
|
|
13953
|
-
|
|
14030
|
+
};
|
|
14031
|
+
const stderrErrorHandler = async (...args) => {
|
|
14032
|
+
const error = args[0];
|
|
13954
14033
|
logWarn("stderr error - parent may have terminated", { error });
|
|
13955
14034
|
if (error.message.includes("EPIPE") || error.message.includes("ECONNRESET")) {
|
|
13956
14035
|
await this.handleParentProcessDeath("stderr-error");
|
|
13957
14036
|
}
|
|
13958
|
-
}
|
|
14037
|
+
};
|
|
14038
|
+
const disconnectHandler = async () => {
|
|
14039
|
+
logDebug("IPC disconnected - parent terminated");
|
|
14040
|
+
await this.handleParentProcessDeath("ipc-disconnect");
|
|
14041
|
+
};
|
|
14042
|
+
this.socketEventHandlers.set("stdin-close", stdinCloseHandler);
|
|
14043
|
+
this.socketEventHandlers.set("stdin-end", stdinEndHandler);
|
|
14044
|
+
this.socketEventHandlers.set("stdout-error", stdoutErrorHandler);
|
|
14045
|
+
this.socketEventHandlers.set("stderr-error", stderrErrorHandler);
|
|
14046
|
+
this.socketEventHandlers.set("disconnect", disconnectHandler);
|
|
14047
|
+
process.stdin.on("close", stdinCloseHandler);
|
|
14048
|
+
process.stdin.on("end", stdinEndHandler);
|
|
14049
|
+
process.stdout.on("error", stdoutErrorHandler);
|
|
14050
|
+
process.stderr.on("error", stderrErrorHandler);
|
|
13959
14051
|
if (process.send) {
|
|
13960
|
-
process.on("disconnect",
|
|
13961
|
-
logDebug("IPC disconnected - parent terminated");
|
|
13962
|
-
await this.handleParentProcessDeath("ipc-disconnect");
|
|
13963
|
-
});
|
|
14052
|
+
process.on("disconnect", disconnectHandler);
|
|
13964
14053
|
logDebug("IPC monitoring enabled");
|
|
13965
14054
|
} else {
|
|
13966
14055
|
logDebug("IPC not available - skipping IPC monitoring");
|
|
@@ -14027,6 +14116,7 @@ var McpServer = class {
|
|
|
14027
14116
|
logError("Failed to connect to the API, skipping background scan");
|
|
14028
14117
|
return;
|
|
14029
14118
|
}
|
|
14119
|
+
WorkspaceService.clearKnownWorkspacePath();
|
|
14030
14120
|
const workspacePath = WorkspaceService.getWorkspaceFolderPath();
|
|
14031
14121
|
if (workspacePath) {
|
|
14032
14122
|
try {
|
|
@@ -14183,6 +14273,31 @@ var McpServer = class {
|
|
|
14183
14273
|
this.parentProcessCheckInterval = void 0;
|
|
14184
14274
|
logDebug("Parent process check interval cleared");
|
|
14185
14275
|
}
|
|
14276
|
+
this.socketEventHandlers.forEach((handler, eventType) => {
|
|
14277
|
+
try {
|
|
14278
|
+
switch (eventType) {
|
|
14279
|
+
case "stdin-close":
|
|
14280
|
+
process.stdin.removeListener("close", handler);
|
|
14281
|
+
break;
|
|
14282
|
+
case "stdin-end":
|
|
14283
|
+
process.stdin.removeListener("end", handler);
|
|
14284
|
+
break;
|
|
14285
|
+
case "stdout-error":
|
|
14286
|
+
process.stdout.removeListener("error", handler);
|
|
14287
|
+
break;
|
|
14288
|
+
case "stderr-error":
|
|
14289
|
+
process.stderr.removeListener("error", handler);
|
|
14290
|
+
break;
|
|
14291
|
+
case "disconnect":
|
|
14292
|
+
process.removeListener("disconnect", handler);
|
|
14293
|
+
break;
|
|
14294
|
+
}
|
|
14295
|
+
} catch (error) {
|
|
14296
|
+
logWarn(`Failed to remove ${eventType} listener`, { error });
|
|
14297
|
+
}
|
|
14298
|
+
});
|
|
14299
|
+
this.socketEventHandlers.clear();
|
|
14300
|
+
logDebug("Socket event handlers cleaned up");
|
|
14186
14301
|
this.eventHandlers.forEach((handler, signal) => {
|
|
14187
14302
|
process.removeListener(signal, handler);
|
|
14188
14303
|
});
|
|
@@ -15901,28 +16016,21 @@ var PatchApplicationService = class {
|
|
|
15901
16016
|
let finalContent = content;
|
|
15902
16017
|
if (MCP_AUTO_FIX_DEBUG_MODE) {
|
|
15903
16018
|
const fixType = fix.safeIssueType || "Security Issue";
|
|
15904
|
-
let fixLink;
|
|
15905
|
-
if (fix.fixUrl) {
|
|
15906
|
-
fixLink = fix.fixUrl;
|
|
15907
|
-
} else {
|
|
15908
|
-
const apiUrl = process.env["API_URL"] || MCP_DEFAULT_API_URL;
|
|
15909
|
-
const appBaseUrl = apiUrl.replace("/v1/graphql", "").replace("api.", "");
|
|
15910
|
-
fixLink = `${appBaseUrl}/fixes/${fix.id}`;
|
|
15911
|
-
}
|
|
15912
16019
|
const commentPrefix = this.getCommentSyntax(filePath);
|
|
15913
16020
|
const lines = content.split("\n");
|
|
15914
16021
|
const lastLine = lines[lines.length - 1]?.trim() || "";
|
|
15915
16022
|
const isMobbComment = lastLine.includes("Mobb security fix applied:");
|
|
15916
16023
|
const spacing = isMobbComment ? "\n" : "\n\n";
|
|
16024
|
+
const fixComment = `Mobb security fix applied: ${fixType} ${fix.fixUrl || ""}`;
|
|
15917
16025
|
let comment;
|
|
15918
16026
|
if (commentPrefix === "<!--") {
|
|
15919
|
-
comment = `${spacing}<!--
|
|
16027
|
+
comment = `${spacing}<!-- ${fixComment} -->`;
|
|
15920
16028
|
} else if (commentPrefix === "/*") {
|
|
15921
|
-
comment = `${spacing}/*
|
|
16029
|
+
comment = `${spacing}/* ${fixComment} */`;
|
|
15922
16030
|
} else if (commentPrefix === "(*") {
|
|
15923
|
-
comment = `${spacing}(*
|
|
16031
|
+
comment = `${spacing}(* ${fixComment} *)`;
|
|
15924
16032
|
} else {
|
|
15925
|
-
comment = `${spacing}${commentPrefix}
|
|
16033
|
+
comment = `${spacing}${commentPrefix} ${fixComment}`;
|
|
15926
16034
|
}
|
|
15927
16035
|
finalContent = content + comment;
|
|
15928
16036
|
logInfo(
|
|
@@ -15930,7 +16038,7 @@ var PatchApplicationService = class {
|
|
|
15930
16038
|
{
|
|
15931
16039
|
fixId: fix.id,
|
|
15932
16040
|
fixType,
|
|
15933
|
-
fixLink,
|
|
16041
|
+
fixLink: fix.fixUrl,
|
|
15934
16042
|
commentSyntax: commentPrefix,
|
|
15935
16043
|
spacing: isMobbComment ? "single line" : "empty line above"
|
|
15936
16044
|
}
|