Skip to content

Commit 7e6bf0d

Browse files
Copilotdata-douser
andauthored
feat: enable --dump-dil by default for codeql_query_compile tool
Add dump-dil parameter to the codeql_query_compile tool inputSchema and inject --dump-dil by default in registerCLITool handler unless explicitly disabled via dump-dil: false or --no-dump-dil in additionalArgs. Includes server unit tests and client integration test improvements. Agent-Logs-Url: https://github.com/advanced-security/codeql-development-mcp-server/sessions/7a489b70-8f73-406f-9a75-e8a15951cde2 Co-authored-by: data-douser <70299490+data-douser@users.noreply.github.com>
1 parent 9c89b29 commit 7e6bf0d

File tree

7 files changed

+225
-3
lines changed

7 files changed

+225
-3
lines changed
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
{
2+
"toolName": "codeql_query_compile",
3+
"arguments": {
4+
"query": "server/ql/javascript/examples/src/ExampleQuery1/ExampleQuery1.ql"
5+
}
6+
}

server/dist/codeql-development-mcp-server.js

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -193859,6 +193859,19 @@ function registerCLITool(server, definition) {
193859193859
break;
193860193860
}
193861193861
case "codeql_query_compile":
193862+
if (query) {
193863+
positionalArgs = [...positionalArgs, query];
193864+
}
193865+
if (options["dump-dil"] === void 0) {
193866+
const pending = Array.isArray(options.additionalArgs) ? options.additionalArgs : [];
193867+
const hasDilOverride = pending.some(
193868+
(arg) => arg === "--no-dump-dil" || arg === "--dump-dil"
193869+
);
193870+
if (!hasDilOverride) {
193871+
options["dump-dil"] = true;
193872+
}
193873+
}
193874+
break;
193862193875
case "codeql_resolve_metadata":
193863193876
if (query) {
193864193877
positionalArgs = [...positionalArgs, query];
@@ -196066,6 +196079,7 @@ var codeqlQueryCompileTool = {
196066196079
inputSchema: {
196067196080
query: external_exports.string().describe("Path to the CodeQL query file (.ql)"),
196068196081
database: external_exports.string().optional().describe("Path to the CodeQL database"),
196082+
"dump-dil": external_exports.boolean().optional().describe("Print the optimized DIL intermediate representation to standard output while compiling. Enabled by default; pass false or --no-dump-dil to disable."),
196069196083
library: external_exports.string().optional().describe("Path to query library"),
196070196084
output: external_exports.string().optional().describe("Output file path"),
196071196085
warnings: external_exports.enum(["hide", "show", "error"]).optional().describe("How to handle compilation warnings"),
@@ -196074,6 +196088,7 @@ var codeqlQueryCompileTool = {
196074196088
},
196075196089
examples: [
196076196090
"codeql query compile --database=/path/to/db MyQuery.ql",
196091+
"codeql query compile --dump-dil --database=/path/to/db MyQuery.ql",
196077196092
"codeql query compile --library=/path/to/lib --output=compiled.qlo MyQuery.ql"
196078196093
]
196079196094
};

server/dist/codeql-development-mcp-server.js.map

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

server/src/lib/cli-tool-registry.ts

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -459,8 +459,28 @@ export function registerCLITool(server: McpServer, definition: CLIToolDefinition
459459
}
460460

461461
case 'codeql_query_compile':
462+
// Handle query parameter as positional argument
463+
if (query) {
464+
positionalArgs = [...positionalArgs, query as string];
465+
}
466+
// Enable --dump-dil by default unless the user explicitly set
467+
// dump-dil to false or passed --no-dump-dil / --dump-dil in
468+
// additionalArgs (which takes precedence).
469+
if (options['dump-dil'] === undefined) {
470+
const pending = Array.isArray(options.additionalArgs)
471+
? options.additionalArgs as string[]
472+
: [];
473+
const hasDilOverride = pending.some(
474+
arg => arg === '--no-dump-dil' || arg === '--dump-dil'
475+
);
476+
if (!hasDilOverride) {
477+
options['dump-dil'] = true;
478+
}
479+
}
480+
break;
481+
462482
case 'codeql_resolve_metadata':
463-
// Handle query parameter as positional argument for query compilation and metadata tools
483+
// Handle query parameter as positional argument for metadata tools
464484
if (query) {
465485
positionalArgs = [...positionalArgs, query as string];
466486
}

server/src/tools/codeql/query-compile.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@ export const codeqlQueryCompileTool: CLIToolDefinition = {
1313
inputSchema: {
1414
query: z.string().describe('Path to the CodeQL query file (.ql)'),
1515
database: z.string().optional().describe('Path to the CodeQL database'),
16+
'dump-dil': z.boolean().optional()
17+
.describe('Print the optimized DIL intermediate representation to standard output while compiling. Enabled by default; pass false or --no-dump-dil to disable.'),
1618
library: z.string().optional().describe('Path to query library'),
1719
output: z.string().optional().describe('Output file path'),
1820
warnings: z.enum(['hide', 'show', 'error']).optional()
@@ -22,6 +24,7 @@ export const codeqlQueryCompileTool: CLIToolDefinition = {
2224
},
2325
examples: [
2426
'codeql query compile --database=/path/to/db MyQuery.ql',
27+
'codeql query compile --dump-dil --database=/path/to/db MyQuery.ql',
2528
'codeql query compile --library=/path/to/lib --output=compiled.qlo MyQuery.ql'
2629
]
2730
};

server/test/src/lib/cli-tool-registry.test.ts

Lines changed: 135 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -531,6 +531,141 @@ describe('registerCLITool handler behavior', () => {
531531
);
532532
});
533533

534+
it('should enable --dump-dil by default for codeql_query_compile', async () => {
535+
const definition: CLIToolDefinition = {
536+
name: 'codeql_query_compile',
537+
description: 'Compile query',
538+
command: 'codeql',
539+
subcommand: 'query compile',
540+
inputSchema: {
541+
query: z.string(),
542+
'dump-dil': z.boolean().optional(),
543+
additionalArgs: z.array(z.string()).optional()
544+
}
545+
};
546+
547+
registerCLITool(mockServer, definition);
548+
549+
const handler = (mockServer.registerTool as ReturnType<typeof vi.fn>).mock.calls[0][2];
550+
551+
executeCodeQLCommand.mockResolvedValueOnce({
552+
stdout: 'Compilation successful',
553+
stderr: '',
554+
success: true
555+
});
556+
557+
await handler({ query: '/path/to/query.ql' });
558+
559+
const call = executeCodeQLCommand.mock.calls[0];
560+
const options = call[1] as Record<string, unknown>;
561+
562+
// --dump-dil should be enabled by default
563+
expect(options['dump-dil']).toBe(true);
564+
});
565+
566+
it('should respect dump-dil: false for codeql_query_compile', async () => {
567+
const definition: CLIToolDefinition = {
568+
name: 'codeql_query_compile',
569+
description: 'Compile query',
570+
command: 'codeql',
571+
subcommand: 'query compile',
572+
inputSchema: {
573+
query: z.string(),
574+
'dump-dil': z.boolean().optional(),
575+
additionalArgs: z.array(z.string()).optional()
576+
}
577+
};
578+
579+
registerCLITool(mockServer, definition);
580+
581+
const handler = (mockServer.registerTool as ReturnType<typeof vi.fn>).mock.calls[0][2];
582+
583+
executeCodeQLCommand.mockResolvedValueOnce({
584+
stdout: 'Compilation successful',
585+
stderr: '',
586+
success: true
587+
});
588+
589+
await handler({ query: '/path/to/query.ql', 'dump-dil': false });
590+
591+
const call = executeCodeQLCommand.mock.calls[0];
592+
const options = call[1] as Record<string, unknown>;
593+
594+
// --dump-dil should not be injected when explicitly disabled;
595+
// buildCodeQLArgs skips false booleans so --dump-dil won't appear on CLI
596+
expect(options['dump-dil']).toBe(false);
597+
});
598+
599+
it('should not inject --dump-dil when --no-dump-dil is in additionalArgs for codeql_query_compile', async () => {
600+
const definition: CLIToolDefinition = {
601+
name: 'codeql_query_compile',
602+
description: 'Compile query',
603+
command: 'codeql',
604+
subcommand: 'query compile',
605+
inputSchema: {
606+
query: z.string(),
607+
'dump-dil': z.boolean().optional(),
608+
additionalArgs: z.array(z.string()).optional()
609+
}
610+
};
611+
612+
registerCLITool(mockServer, definition);
613+
614+
const handler = (mockServer.registerTool as ReturnType<typeof vi.fn>).mock.calls[0][2];
615+
616+
executeCodeQLCommand.mockResolvedValueOnce({
617+
stdout: 'Compilation successful',
618+
stderr: '',
619+
success: true
620+
});
621+
622+
await handler({ query: '/path/to/query.ql', additionalArgs: ['--no-dump-dil'] });
623+
624+
const call = executeCodeQLCommand.mock.calls[0];
625+
const options = call[1] as Record<string, unknown>;
626+
const positionalArgs = call[2] as string[];
627+
628+
// --dump-dil should not be in options when --no-dump-dil is in additionalArgs
629+
expect(options['dump-dil']).toBeUndefined();
630+
// --no-dump-dil should be passed through in the positional/additional args
631+
expect(positionalArgs).toContain('--no-dump-dil');
632+
});
633+
634+
it('should not inject --dump-dil when --dump-dil is already in additionalArgs for codeql_query_compile', async () => {
635+
const definition: CLIToolDefinition = {
636+
name: 'codeql_query_compile',
637+
description: 'Compile query',
638+
command: 'codeql',
639+
subcommand: 'query compile',
640+
inputSchema: {
641+
query: z.string(),
642+
'dump-dil': z.boolean().optional(),
643+
additionalArgs: z.array(z.string()).optional()
644+
}
645+
};
646+
647+
registerCLITool(mockServer, definition);
648+
649+
const handler = (mockServer.registerTool as ReturnType<typeof vi.fn>).mock.calls[0][2];
650+
651+
executeCodeQLCommand.mockResolvedValueOnce({
652+
stdout: 'Compilation successful',
653+
stderr: '',
654+
success: true
655+
});
656+
657+
await handler({ query: '/path/to/query.ql', additionalArgs: ['--dump-dil'] });
658+
659+
const call = executeCodeQLCommand.mock.calls[0];
660+
const options = call[1] as Record<string, unknown>;
661+
const positionalArgs = call[2] as string[];
662+
663+
// --dump-dil should not be duplicated in options when already in additionalArgs
664+
expect(options['dump-dil']).toBeUndefined();
665+
// The explicit --dump-dil from additionalArgs should be passed through
666+
expect(positionalArgs).toContain('--dump-dil');
667+
});
668+
534669
it('should pass format to CLI for codeql_bqrs_interpret', async () => {
535670
const definition: CLIToolDefinition = {
536671
name: 'codeql_bqrs_interpret',
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
/**
2+
* Tests for query-compile tool
3+
*/
4+
5+
import { describe, it, expect } from 'vitest';
6+
import { codeqlQueryCompileTool } from '../../../../src/tools/codeql/query-compile';
7+
8+
describe('Query Compile Tool', () => {
9+
describe('Tool Definition', () => {
10+
it('should have correct name', () => {
11+
expect(codeqlQueryCompileTool.name).toBe('codeql_query_compile');
12+
});
13+
14+
it('should have correct command and subcommand', () => {
15+
expect(codeqlQueryCompileTool.command).toBe('codeql');
16+
expect(codeqlQueryCompileTool.subcommand).toBe('query compile');
17+
});
18+
19+
it('should have input schema with expected fields', () => {
20+
const schema = codeqlQueryCompileTool.inputSchema;
21+
22+
expect(schema).toHaveProperty('query');
23+
expect(schema).toHaveProperty('database');
24+
expect(schema).toHaveProperty('dump-dil');
25+
expect(schema).toHaveProperty('library');
26+
expect(schema).toHaveProperty('output');
27+
expect(schema).toHaveProperty('warnings');
28+
expect(schema).toHaveProperty('verbose');
29+
expect(schema).toHaveProperty('additionalArgs');
30+
});
31+
32+
it('should have dump-dil as optional boolean parameter', () => {
33+
const dumpDil = codeqlQueryCompileTool.inputSchema['dump-dil'];
34+
expect(dumpDil).toBeDefined();
35+
expect(dumpDil.isOptional()).toBe(true);
36+
});
37+
38+
it('should have examples', () => {
39+
expect(codeqlQueryCompileTool.examples).toBeDefined();
40+
expect(codeqlQueryCompileTool.examples!.length).toBeGreaterThan(0);
41+
});
42+
});
43+
});

0 commit comments

Comments
 (0)