Skip to content

Commit 0a37154

Browse files
committed
wire data-extension-development prompt and fix type errors
- Register data-extension-development.prompt.md in prompt-loader - Add index signature to PromptResult for MCP SDK compat - Fix startServer HTTP branch to return Promise<McpServer> - Add hints field to QueryFilesResult interface - Narrow unknown types in mermaid graph evaluator - Update EXPECTED_PROMPT_FILES in prompt-loader tests - Add test for object-based mermaid graph tuples
1 parent b573add commit 0a37154

12 files changed

Lines changed: 128 additions & 139 deletions

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

Lines changed: 11 additions & 5 deletions
Large diffs are not rendered by default.

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

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

server/src/codeql-development-mcp-server.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -144,10 +144,10 @@ export async function startServer(mode: 'stdio' | 'http' = 'stdio'): Promise<Mcp
144144
const port = Number(process.env.HTTP_PORT || process.env.PORT) || 3000;
145145

146146
// Return a promise that keeps the process alive
147-
return new Promise<void>((resolve, reject) => {
147+
return new Promise<McpServer>((resolve, reject) => {
148148
const httpServer = app.listen(port, host, () => {
149149
logger.info(`HTTP server listening on http://${host}:${port}/mcp`);
150-
resolve();
150+
resolve(server);
151151
});
152152

153153
httpServer.on('error', (error) => {

server/src/lib/query-results-evaluator.ts

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -268,7 +268,8 @@ function generateMermaidFromGraphResults(queryResults: unknown, metadata: QueryM
268268
}
269269

270270
// Check if results have the expected structure for graph queries
271-
const tuples = queryResults.tuples || queryResults;
271+
const resultsObj = queryResults as Record<string, unknown>;
272+
const tuples = resultsObj.tuples || queryResults;
272273

273274
if (!Array.isArray(tuples) || tuples.length === 0) {
274275
mermaidContent += '```mermaid\ngraph TD\n A[No Graph Data]\n```\n';
@@ -305,9 +306,10 @@ function generateMermaidFromGraphResults(queryResults: unknown, metadata: QueryM
305306
}
306307
} else if (typeof tuple === 'object' && tuple !== null) {
307308
// Handle object-based results
308-
const source = sanitizeNodeId(tuple.source?.toString() || tuple.from?.toString() || `node_${index}_src`);
309-
const target = sanitizeNodeId(tuple.target?.toString() || tuple.to?.toString() || `node_${index}_tgt`);
310-
const label = tuple.label?.toString() || tuple.relation?.toString() || '';
309+
const obj = tuple as Record<string, unknown>;
310+
const source = sanitizeNodeId(obj.source?.toString() || obj.from?.toString() || `node_${index}_src`);
311+
const target = sanitizeNodeId(obj.target?.toString() || obj.to?.toString() || `node_${index}_tgt`);
312+
const label = obj.label?.toString() || obj.relation?.toString() || '';
311313

312314
nodes.add(source);
313315
nodes.add(target);

server/src/prompts/data-extension-development.prompt.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,9 @@ For language-specific guidance, read the corresponding `codeql://languages/<lang
1717
- Library name and version: {{libraryName}}
1818
- Target language: {{language}}
1919
- Determine the model format:
20-
- **MaD tuple format** (9–10 column tuples): C/C++ (`codeql/cpp-all`), C# (`codeql/csharp-all`), Go (`codeql/go-all`), Java/Kotlin (`codeql/java-all`)
20+
- **MaD tuple format** (9–10 column tuples): C/C++ (`codeql/cpp-all`), C# (`codeql/csharp-all`), Go (`codeql/go-all`), Java/Kotlin (`codeql/java-all`), Swift (`codeql/swift-all`)
2121
- **API Graph format** (3–5 column tuples): JavaScript/TypeScript (`codeql/javascript-all`), Python (`codeql/python-all`), Ruby (`codeql/ruby-all`)
22+
- **Rust format**: Rust (`codeql/rust-all`) uses its own crate-path-based model format; follow `codeql://languages/rust/library-modeling`
2223
- Using the wrong format will cause the extension to silently fail to load.
2324

2425
- [ ] **Locate a CodeQL database**

server/src/prompts/prompt-loader.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
// Static imports — esbuild inlines the file contents as string literals.
1111
import checkForDuplicatedCode from './check-for-duplicated-code.prompt.md';
1212
import compareOverlappingAlerts from './compare-overlapping-alerts.prompt.md';
13+
import dataExtensionDevelopment from './data-extension-development.prompt.md';
1314
import documentCodeqlQuery from './document-codeql-query.prompt.md';
1415
import explainCodeqlQuery from './explain-codeql-query.prompt.md';
1516
import findOverlappingQueries from './find-overlapping-queries.prompt.md';
@@ -32,6 +33,7 @@ import workshopCreationWorkflow from './workshop-creation-workflow.prompt.md';
3233
const PROMPT_TEMPLATES: Record<string, string> = {
3334
'check-for-duplicated-code.prompt.md': checkForDuplicatedCode,
3435
'compare-overlapping-alerts.prompt.md': compareOverlappingAlerts,
36+
'data-extension-development.prompt.md': dataExtensionDevelopment,
3537
'document-codeql-query.prompt.md': documentCodeqlQuery,
3638
'explain-codeql-query.prompt.md': explainCodeqlQuery,
3739
'find-overlapping-queries.prompt.md': findOverlappingQueries,

server/src/prompts/workflow-prompts.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -481,6 +481,7 @@ export const qlLspIterativeDevelopmentSchema = z.object({
481481
* Prompt result shape returned by every workflow prompt handler.
482482
*/
483483
interface PromptResult {
484+
[key: string]: unknown;
484485
messages: Array<{
485486
role: 'user';
486487
content: { type: 'text'; text: string };

server/src/types/codeql.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,9 @@ export interface QueryFilesResult {
9292
};
9393
};
9494

95+
// Contextual hints for LLM consumers
96+
hints?: string[];
97+
9598
// Library path information (from codeql resolve library-path)
9699
libraryPaths?: string[]; // Resolved library paths for the query
97100

server/test/src/lib/query-results-evaluator.test.ts

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -290,6 +290,40 @@ import javascript`;
290290
expect(result.success).toBe(false);
291291
expect(result.error).toContain('Failed to parse query results JSON');
292292
});
293+
294+
it('should handle object-based tuple results with source/target properties', async () => {
295+
const queryContent = `/**
296+
* @name Object Graph
297+
* @description Graph with object-based tuples
298+
* @kind graph
299+
*/
300+
301+
import javascript`;
302+
303+
writeFileSync(testQueryPath, queryContent);
304+
305+
const mockJsonResults = JSON.stringify({
306+
tuples: [
307+
{ source: 'NodeA', target: 'NodeB', label: 'calls' },
308+
{ source: 'NodeB', target: 'NodeC', relation: 'depends_on' },
309+
]
310+
});
311+
312+
mockExecuteCodeQLCommand.mockResolvedValue({
313+
success: true,
314+
stdout: mockJsonResults,
315+
stderr: '',
316+
exitCode: 0
317+
});
318+
319+
const result = await evaluateWithMermaidGraph(testBqrsPath, testQueryPath);
320+
321+
expect(result.success).toBe(true);
322+
expect(result.content).toContain('```mermaid\ngraph TD');
323+
expect(result.content).toContain('NodeA');
324+
expect(result.content).toContain('NodeB');
325+
expect(result.content).toContain('NodeC');
326+
});
293327
});
294328

295329
describe('evaluateQueryResults', () => {

server/test/src/prompts/prompt-loader.test.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,16 @@ import { loadPromptTemplate, processPromptTemplate } from '../../../src/prompts/
77

88
/** All prompt template filenames that must be embedded in the bundle. */
99
const EXPECTED_PROMPT_FILES = [
10+
'check-for-duplicated-code.prompt.md',
11+
'compare-overlapping-alerts.prompt.md',
12+
'data-extension-development.prompt.md',
1013
'document-codeql-query.prompt.md',
1114
'explain-codeql-query.prompt.md',
15+
'find-overlapping-queries.prompt.md',
1216
'ql-lsp-iterative-development.prompt.md',
1317
'ql-tdd-advanced.prompt.md',
1418
'ql-tdd-basic.prompt.md',
19+
'run-query-and-summarize-false-positives.prompt.md',
1520
'sarif-rank-false-positives.prompt.md',
1621
'sarif-rank-true-positives.prompt.md',
1722
'tools-query-workflow.prompt.md',

0 commit comments

Comments
 (0)