Skip to content

Commit 554ca51

Browse files
Merge pull request #68 from codacy/mcp-settings
feat: add guardrails settings to enable/disable analysis
2 parents a6617dd + ddeec43 commit 554ca51

6 files changed

Lines changed: 62 additions & 10 deletions

File tree

package.json

Lines changed: 39 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@
9090
"when": "Codacy:RepositoryManagerStateContext != NeedsAuthentication && codacy:supportsMCP",
9191
"icon": "$(gear)",
9292
"initialSize": 2
93-
}
93+
}
9494
]
9595
},
9696
"viewsWelcome": [
@@ -138,7 +138,7 @@
138138
"view": "codacy:mcp",
139139
"contents": "Codacy Guardrails MCP Server is enabled\n[Reset MCP Server](command:codacy.configureMCP.reset)",
140140
"when": "Codacy:RepositoryManagerStateContext == Loaded && codacy:supportsMCP && codacy:mcpConfigured"
141-
}
141+
}
142142
],
143143
"commands": [
144144
{
@@ -309,6 +309,42 @@
309309
"codacy.apiToken": {
310310
"type": "string",
311311
"description": "API Personal Token"
312+
},
313+
"codacy.guardrails.analyzeGeneratedCode": {
314+
"type": "string",
315+
"title": "Automatically analyze generated code with Codacy Guardrails",
316+
"description": "This feature ensures that your generated code is analyzed by Codacy Guardrails.",
317+
"enum": [
318+
"enabled",
319+
"disabled"
320+
],
321+
"default": "enabled"
322+
},
323+
"codacy.guardrails.rulesFile": {
324+
"type": "string",
325+
"title": "Generate rules file for the AI Agent",
326+
"description": "Allow the extension to generate Codacy specific rules for the AI Agent. Disabling this option will impact the user experience of Codacy Guardrails.",
327+
"enum": [
328+
"enabled",
329+
"disabled"
330+
],
331+
"default": "enabled"
332+
},
333+
"codacy.cli.cliVersion": {
334+
"type": "string",
335+
"description": "The version of the Codacy CLI to use",
336+
"default": "1.0.0-main.251.1952e73"
337+
},
338+
"codacy.cli.analysisMode": {
339+
"type": "string",
340+
"title": "Local code analysis",
341+
"description": "This feature allows you to analyze your code locally using the Codacy CLI.",
342+
"enum": [
343+
"enabled",
344+
"only on saved files",
345+
"disabled"
346+
],
347+
"default": "enabled"
312348
}
313349
}
314350
},
@@ -339,7 +375,7 @@
339375
"@types/lodash": "^4.14.196",
340376
"@types/mocha": "^10.0.1",
341377
"@types/node": "20.4.7",
342-
"@types/sarif": "2.1.7",
378+
"@types/sarif": "2.1.7",
343379
"@types/sinon": "^10.0.16",
344380
"@types/temp": "^0.9.1",
345381
"@types/vscode": "^1.81.0",

src/commands/configureMCP.ts

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import Logger from '../common/logger'
1111
interface Rule {
1212
when: string
1313
enforce: string[]
14+
scope: 'guardrails' | 'general'
1415
}
1516

1617
interface RuleConfig {
@@ -19,7 +20,7 @@ interface RuleConfig {
1920
rules: Rule[]
2021
}
2122

22-
const newRulesTemplate = (repository?: Repository): RuleConfig => {
23+
const newRulesTemplate = (repository?: Repository, excludedScopes?: ('guardrails' | 'general')[]): RuleConfig => {
2324
const repositoryRules: Rule[] = []
2425
if (repository) {
2526
const { provider, owner: organization, name } = repository
@@ -28,12 +29,14 @@ const newRulesTemplate = (repository?: Repository): RuleConfig => {
2829
enforce: [
2930
`use ${provider} for provider, ${organization} for organization and ${name} for repository, and avoid calling 'git remote -v' unless really necessary`,
3031
],
32+
scope: 'general',
3133
})
3234
}
3335

3436
const commonRules: Rule[] = [
3537
{
3638
when: 'after ANY successful edit_file or reapply tool call',
39+
scope: 'guardrails',
3740
enforce: [
3841
'IMMEDIATELY run codacy_cli_analyze tool for each edited file with:',
3942
'1. rootPath set to the workspace path',
@@ -48,6 +51,7 @@ const newRulesTemplate = (repository?: Repository): RuleConfig => {
4851
},
4952
{
5053
when: 'after adding new dependencies, libraries or packages',
54+
scope: 'guardrails',
5155
enforce: [
5256
'IMMEDIATELY run codacy_cli_analyze tool for Trivy for:',
5357
'1. rootPath set to the workspace path',
@@ -58,14 +62,15 @@ const newRulesTemplate = (repository?: Repository): RuleConfig => {
5862
},
5963
{
6064
when: 'a call to a Codacy tool that has repository or organization as parameter returns 404 error',
65+
scope: 'general',
6166
enforce: ['run codacy_setup_repository tool and then retry the action that failed'],
6267
},
6368
]
6469

6570
return {
6671
name: 'Codacy Rules',
6772
description: 'Configuration for AI behavior when interacting with Codacy',
68-
rules: [...repositoryRules, ...commonRules],
73+
rules: [...repositoryRules, ...commonRules].filter((rule) => !excludedScopes?.includes(rule.scope)),
6974
}
7075
}
7176

@@ -132,7 +137,9 @@ const addRulesToGitignore = (rulesPath: string) => {
132137
}
133138
}
134139
export async function createRules(repository: Repository) {
135-
const newRules = newRulesTemplate(repository)
140+
const analyzeGeneratedCode = vscode.workspace.getConfiguration().get('codacy.guardrails.analyzeGeneratedCode')
141+
142+
const newRules = newRulesTemplate(repository, analyzeGeneratedCode === 'disabled' ? ['guardrails'] : [])
136143

137144
try {
138145
const { path: rulesPath, format } = getCorrectRulesInfo()
@@ -219,6 +226,7 @@ export function isMCPConfigured(): boolean {
219226
}
220227

221228
export async function configureMCP(repository: Repository) {
229+
const generateRules = vscode.workspace.getConfiguration().get('codacy.guardrails.rulesFile')
222230
const ideConfig = getCorrectMcpConfig()
223231
try {
224232
const apiToken = Config.apiToken
@@ -267,7 +275,9 @@ export async function configureMCP(repository: Repository) {
267275
fs.writeFileSync(filePath, JSON.stringify(modifiedConfig, null, 2))
268276

269277
vscode.window.showInformationMessage('Codacy MCP server added successfully. Please restart the IDE.')
270-
await createRules(repository)
278+
if (generateRules === 'enabled') {
279+
await createRules(repository)
280+
}
271281
await installCodacyCLI(repository)
272282
} catch (error: unknown) {
273283
const errorMessage = error instanceof Error ? error.message : 'Unknown error occurred'

src/commands/installAnalysisCLI.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,11 @@ const MAX_BUFFER_SIZE = 1024 * 1024 * 10
1515

1616
const execAsync = (command: string) => {
1717
const workspacePath = vscode.workspace.workspaceFolders?.[0]?.uri.fsPath || ''
18+
const cliVersion = vscode.workspace.getConfiguration().get('codacy.cli.cliVersion')
1819

1920
return new Promise((resolve, reject) => {
2021
exec(
21-
`CODACY_CLI_V2_VERSION=1.0.0-main.232.a6a6368 ${command}`,
22+
`${cliVersion ? `CODACY_CLI_V2_VERSION=${cliVersion}` : ''} ${command}`,
2223
{
2324
cwd: workspacePath,
2425
maxBuffer: MAX_BUFFER_SIZE, // To solve: stdout maxBuffer exceeded

src/commands/runCodacyAnalyze.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ export async function runCodacyAnalyze(filePath?: string) {
1818
try {
1919
// Get workspace folder (to solve: mkdir error)
2020
const workspaceFolders = vscode.workspace.workspaceFolders
21+
const cliVersion = vscode.workspace.getConfiguration().get('codacy.cli.cliVersion')
2122
if (!workspaceFolders || workspaceFolders.length === 0) {
2223
throw new Error('No workspace folder found')
2324
}
@@ -27,7 +28,7 @@ export async function runCodacyAnalyze(filePath?: string) {
2728
const relativeFilePath = sanitizeFilePath(workspaceRoot, filePath)
2829

2930
// Construct the command
30-
const command = `CODACY_CLI_V2_VERSION=1.0.0-main.232.a6a6368 .codacy/cli.sh analyze --format sarif ${
31+
const command = `${cliVersion ? `CODACY_CLI_V2_VERSION=${cliVersion}` : ''} .codacy/cli.sh analyze --format sarif ${
3132
relativeFilePath || ''
3233
}`
3334

src/extension.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -251,7 +251,8 @@ export async function activate(context: vscode.ExtensionContext) {
251251
)
252252

253253
repositoryManager.onDidLoadRepository(async ({ repository }) => {
254-
if (isMCPConfigured()) {
254+
const generateRules = vscode.workspace.getConfiguration().get('codacy.guardrails.rulesFile')
255+
if (isMCPConfigured() && generateRules === 'enabled') {
255256
await createRules(repository)
256257
}
257258
})

src/views/ProblemsDiagnosticCollection.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,12 +104,15 @@ export class ProblemsDiagnosticCollection implements vscode.Disposable {
104104
})
105105

106106
GitProvider.instance?.onDidChangeTextDocument(async (e) => {
107+
const analysisMode = vscode.workspace.getConfiguration().get('codacy.cli.analysisMode')
108+
107109
// avoid if the document is a .git file
108110
if (e.document.uri.fsPath.endsWith('.git')) return
109111

110112
// update positions of remote issues in the document
111113
this.updateApiIssuesPositions(e.document)
112114

115+
if (analysisMode === 'disabled' || (analysisMode === 'only on saved files' && e.document.isDirty)) return
113116
// run local analysis for available tools
114117
await this.runAnalysisAndUpdateDiagnostics(e.document)
115118
})

0 commit comments

Comments
 (0)