codeql-development-mcp-server 2.24.2 → 2.24.3-rc1
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/README.md +6 -4
- package/dist/codeql-development-mcp-server.js +663 -264
- package/dist/codeql-development-mcp-server.js.map +4 -4
- package/package.json +5 -5
- package/ql/actions/tools/src/codeql-pack.yml +1 -1
- package/ql/cpp/tools/src/codeql-pack.yml +1 -1
- package/ql/csharp/tools/src/codeql-pack.yml +1 -1
- package/ql/go/tools/src/codeql-pack.yml +1 -1
- package/ql/java/tools/src/codeql-pack.yml +1 -1
- package/ql/javascript/tools/src/codeql-pack.yml +1 -1
- package/ql/python/tools/src/codeql-pack.yml +1 -1
- package/ql/ruby/tools/src/codeql-pack.yml +1 -1
- package/ql/swift/tools/src/codeql-pack.yml +1 -1
|
@@ -31254,10 +31254,10 @@ var require_view = __commonJS({
|
|
|
31254
31254
|
var debug = require_src()("express:view");
|
|
31255
31255
|
var path4 = __require("node:path");
|
|
31256
31256
|
var fs3 = __require("node:fs");
|
|
31257
|
-
var
|
|
31257
|
+
var dirname8 = path4.dirname;
|
|
31258
31258
|
var basename7 = path4.basename;
|
|
31259
31259
|
var extname2 = path4.extname;
|
|
31260
|
-
var
|
|
31260
|
+
var join18 = path4.join;
|
|
31261
31261
|
var resolve13 = path4.resolve;
|
|
31262
31262
|
module.exports = View;
|
|
31263
31263
|
function View(name, options) {
|
|
@@ -31293,7 +31293,7 @@ var require_view = __commonJS({
|
|
|
31293
31293
|
for (var i = 0; i < roots.length && !path5; i++) {
|
|
31294
31294
|
var root = roots[i];
|
|
31295
31295
|
var loc = resolve13(root, name);
|
|
31296
|
-
var dir =
|
|
31296
|
+
var dir = dirname8(loc);
|
|
31297
31297
|
var file = basename7(loc);
|
|
31298
31298
|
path5 = this.resolve(dir, file);
|
|
31299
31299
|
}
|
|
@@ -31319,12 +31319,12 @@ var require_view = __commonJS({
|
|
|
31319
31319
|
};
|
|
31320
31320
|
View.prototype.resolve = function resolve14(dir, file) {
|
|
31321
31321
|
var ext = this.ext;
|
|
31322
|
-
var path5 =
|
|
31322
|
+
var path5 = join18(dir, file);
|
|
31323
31323
|
var stat = tryStat(path5);
|
|
31324
31324
|
if (stat && stat.isFile()) {
|
|
31325
31325
|
return path5;
|
|
31326
31326
|
}
|
|
31327
|
-
path5 =
|
|
31327
|
+
path5 = join18(dir, basename7(file, ext), "index" + ext);
|
|
31328
31328
|
stat = tryStat(path5);
|
|
31329
31329
|
if (stat && stat.isFile()) {
|
|
31330
31330
|
return path5;
|
|
@@ -34969,7 +34969,7 @@ var require_send = __commonJS({
|
|
|
34969
34969
|
var Stream = __require("stream");
|
|
34970
34970
|
var util2 = __require("util");
|
|
34971
34971
|
var extname2 = path4.extname;
|
|
34972
|
-
var
|
|
34972
|
+
var join18 = path4.join;
|
|
34973
34973
|
var normalize = path4.normalize;
|
|
34974
34974
|
var resolve13 = path4.resolve;
|
|
34975
34975
|
var sep2 = path4.sep;
|
|
@@ -35141,7 +35141,7 @@ var require_send = __commonJS({
|
|
|
35141
35141
|
return res;
|
|
35142
35142
|
}
|
|
35143
35143
|
parts = path5.split(sep2);
|
|
35144
|
-
path5 = normalize(
|
|
35144
|
+
path5 = normalize(join18(root, path5));
|
|
35145
35145
|
} else {
|
|
35146
35146
|
if (UP_PATH_REGEXP.test(path5)) {
|
|
35147
35147
|
debug('malicious path "%s"', path5);
|
|
@@ -35274,7 +35274,7 @@ var require_send = __commonJS({
|
|
|
35274
35274
|
if (err) return self.onStatError(err);
|
|
35275
35275
|
return self.error(404);
|
|
35276
35276
|
}
|
|
35277
|
-
var p =
|
|
35277
|
+
var p = join18(path5, self._index[i]);
|
|
35278
35278
|
debug('stat "%s"', p);
|
|
35279
35279
|
fs3.stat(p, function(err2, stat) {
|
|
35280
35280
|
if (err2) return next(err2);
|
|
@@ -38159,12 +38159,14 @@ __export(cli_executor_exports, {
|
|
|
38159
38159
|
buildCodeQLArgs: () => buildCodeQLArgs,
|
|
38160
38160
|
buildQLTArgs: () => buildQLTArgs,
|
|
38161
38161
|
disableTestCommands: () => disableTestCommands,
|
|
38162
|
+
discoverVsCodeCodeQLDistribution: () => discoverVsCodeCodeQLDistribution,
|
|
38162
38163
|
enableTestCommands: () => enableTestCommands,
|
|
38163
38164
|
executeCLICommand: () => executeCLICommand,
|
|
38164
38165
|
executeCodeQLCommand: () => executeCodeQLCommand,
|
|
38165
38166
|
executeQLTCommand: () => executeQLTCommand,
|
|
38166
38167
|
getCommandHelp: () => getCommandHelp,
|
|
38167
38168
|
getResolvedCodeQLDir: () => getResolvedCodeQLDir,
|
|
38169
|
+
getVsCodeGlobalStorageCandidates: () => getVsCodeGlobalStorageCandidates,
|
|
38168
38170
|
resetResolvedCodeQLBinary: () => resetResolvedCodeQLBinary,
|
|
38169
38171
|
resolveCodeQLBinary: () => resolveCodeQLBinary,
|
|
38170
38172
|
sanitizeCLIArgument: () => sanitizeCLIArgument,
|
|
@@ -38173,8 +38175,9 @@ __export(cli_executor_exports, {
|
|
|
38173
38175
|
validateCommandExists: () => validateCommandExists
|
|
38174
38176
|
});
|
|
38175
38177
|
import { execFile } from "child_process";
|
|
38176
|
-
import { existsSync as existsSync2 } from "fs";
|
|
38177
|
-
import { basename, delimiter as delimiter4, dirname as dirname2, isAbsolute as isAbsolute2 } from "path";
|
|
38178
|
+
import { accessSync, constants as fsConstants, existsSync as existsSync2, readdirSync, readFileSync as readFileSync2, statSync } from "fs";
|
|
38179
|
+
import { basename, delimiter as delimiter4, dirname as dirname2, isAbsolute as isAbsolute2, join as join4 } from "path";
|
|
38180
|
+
import { homedir } from "os";
|
|
38178
38181
|
import { promisify } from "util";
|
|
38179
38182
|
function enableTestCommands() {
|
|
38180
38183
|
testCommands = /* @__PURE__ */ new Set([
|
|
@@ -38191,12 +38194,103 @@ function disableTestCommands() {
|
|
|
38191
38194
|
function isCommandAllowed(command) {
|
|
38192
38195
|
return ALLOWED_COMMANDS.has(command) || testCommands !== null && testCommands.has(command);
|
|
38193
38196
|
}
|
|
38194
|
-
function
|
|
38197
|
+
function getVsCodeGlobalStorageCandidates() {
|
|
38198
|
+
const home = homedir();
|
|
38199
|
+
const candidates = [];
|
|
38200
|
+
for (const appName of VSCODE_APP_NAMES) {
|
|
38201
|
+
if (process.platform === "darwin") {
|
|
38202
|
+
candidates.push(join4(home, "Library", "Application Support", appName, "User", "globalStorage"));
|
|
38203
|
+
} else if (process.platform === "win32") {
|
|
38204
|
+
const appData = process.env.APPDATA ?? join4(home, "AppData", "Roaming");
|
|
38205
|
+
candidates.push(join4(appData, appName, "User", "globalStorage"));
|
|
38206
|
+
} else {
|
|
38207
|
+
candidates.push(join4(home, ".config", appName, "User", "globalStorage"));
|
|
38208
|
+
}
|
|
38209
|
+
}
|
|
38210
|
+
return candidates;
|
|
38211
|
+
}
|
|
38212
|
+
function discoverVsCodeCodeQLDistribution(candidateStorageRoots) {
|
|
38213
|
+
const globalStorageCandidates = candidateStorageRoots ?? getVsCodeGlobalStorageCandidates();
|
|
38214
|
+
for (const gsRoot of globalStorageCandidates) {
|
|
38215
|
+
for (const dirName of VSCODE_CODEQL_STORAGE_DIR_NAMES) {
|
|
38216
|
+
const codeqlStorage = join4(gsRoot, dirName);
|
|
38217
|
+
if (!existsSync2(codeqlStorage)) continue;
|
|
38218
|
+
const hintResult = discoverFromDistributionJson(codeqlStorage);
|
|
38219
|
+
if (hintResult) return hintResult;
|
|
38220
|
+
const scanResult = discoverFromDistributionScan(codeqlStorage);
|
|
38221
|
+
if (scanResult) return scanResult;
|
|
38222
|
+
}
|
|
38223
|
+
}
|
|
38224
|
+
return void 0;
|
|
38225
|
+
}
|
|
38226
|
+
function discoverFromDistributionJson(codeqlStorage) {
|
|
38227
|
+
try {
|
|
38228
|
+
const jsonPath = join4(codeqlStorage, "distribution.json");
|
|
38229
|
+
if (!existsSync2(jsonPath)) return void 0;
|
|
38230
|
+
const content = readFileSync2(jsonPath, "utf-8");
|
|
38231
|
+
const data = JSON.parse(content);
|
|
38232
|
+
if (typeof data.folderIndex !== "number") return void 0;
|
|
38233
|
+
const binaryPath = join4(
|
|
38234
|
+
codeqlStorage,
|
|
38235
|
+
`distribution${data.folderIndex}`,
|
|
38236
|
+
"codeql",
|
|
38237
|
+
CODEQL_BINARY_NAME
|
|
38238
|
+
);
|
|
38239
|
+
if (isExecutableBinary(binaryPath)) {
|
|
38240
|
+
logger.debug(`Discovered CLI via distribution.json (folderIndex=${data.folderIndex})`);
|
|
38241
|
+
return binaryPath;
|
|
38242
|
+
}
|
|
38243
|
+
logger.debug(`distribution.json hint (folderIndex=${data.folderIndex}) exists but is not a usable executable; falling through to scan`);
|
|
38244
|
+
} catch {
|
|
38245
|
+
}
|
|
38246
|
+
return void 0;
|
|
38247
|
+
}
|
|
38248
|
+
function discoverFromDistributionScan(codeqlStorage) {
|
|
38249
|
+
try {
|
|
38250
|
+
const entries = readdirSync(codeqlStorage, { withFileTypes: true });
|
|
38251
|
+
const distDirs = entries.filter((e) => e.isDirectory() && /^distribution\d+$/.test(e.name)).map((e) => ({
|
|
38252
|
+
name: e.name,
|
|
38253
|
+
num: parseInt(e.name.replace("distribution", ""), 10)
|
|
38254
|
+
})).sort((a, b) => b.num - a.num);
|
|
38255
|
+
for (const dir of distDirs) {
|
|
38256
|
+
const binaryPath = join4(
|
|
38257
|
+
codeqlStorage,
|
|
38258
|
+
dir.name,
|
|
38259
|
+
"codeql",
|
|
38260
|
+
CODEQL_BINARY_NAME
|
|
38261
|
+
);
|
|
38262
|
+
if (isExecutableBinary(binaryPath)) {
|
|
38263
|
+
logger.debug(`Discovered CLI via distribution scan: ${dir.name}`);
|
|
38264
|
+
return binaryPath;
|
|
38265
|
+
}
|
|
38266
|
+
}
|
|
38267
|
+
} catch {
|
|
38268
|
+
}
|
|
38269
|
+
return void 0;
|
|
38270
|
+
}
|
|
38271
|
+
function isExecutableBinary(binaryPath) {
|
|
38272
|
+
try {
|
|
38273
|
+
const stat = statSync(binaryPath);
|
|
38274
|
+
if (!stat.isFile()) return false;
|
|
38275
|
+
accessSync(binaryPath, fsConstants.X_OK);
|
|
38276
|
+
return true;
|
|
38277
|
+
} catch {
|
|
38278
|
+
return false;
|
|
38279
|
+
}
|
|
38280
|
+
}
|
|
38281
|
+
function resolveCodeQLBinary(candidateStorageRoots) {
|
|
38195
38282
|
if (resolvedBinaryResult !== void 0) {
|
|
38196
38283
|
return resolvedBinaryResult;
|
|
38197
38284
|
}
|
|
38198
38285
|
const envPath = process.env.CODEQL_PATH;
|
|
38199
38286
|
if (!envPath) {
|
|
38287
|
+
const discovered = discoverVsCodeCodeQLDistribution(candidateStorageRoots);
|
|
38288
|
+
if (discovered) {
|
|
38289
|
+
resolvedCodeQLDir = dirname2(discovered);
|
|
38290
|
+
resolvedBinaryResult = "codeql";
|
|
38291
|
+
logger.info(`CodeQL CLI auto-discovered via vscode-codeql distribution: ${discovered} (dir: ${resolvedCodeQLDir})`);
|
|
38292
|
+
return resolvedBinaryResult;
|
|
38293
|
+
}
|
|
38200
38294
|
resolvedCodeQLDir = null;
|
|
38201
38295
|
resolvedBinaryResult = "codeql";
|
|
38202
38296
|
return resolvedBinaryResult;
|
|
@@ -38443,7 +38537,7 @@ async function validateCommandExists(command) {
|
|
|
38443
38537
|
return false;
|
|
38444
38538
|
}
|
|
38445
38539
|
}
|
|
38446
|
-
var execFileAsync, ALLOWED_COMMANDS, testCommands, SAFE_ENV_VARS, SAFE_ENV_PREFIXES, DANGEROUS_CONTROL_CHARS, resolvedCodeQLDir, resolvedBinaryResult, FRESH_PROCESS_SUBCOMMANDS;
|
|
38540
|
+
var execFileAsync, ALLOWED_COMMANDS, testCommands, SAFE_ENV_VARS, SAFE_ENV_PREFIXES, DANGEROUS_CONTROL_CHARS, resolvedCodeQLDir, resolvedBinaryResult, CODEQL_BINARY_NAME, VSCODE_APP_NAMES, VSCODE_CODEQL_STORAGE_DIR_NAMES, FRESH_PROCESS_SUBCOMMANDS;
|
|
38447
38541
|
var init_cli_executor = __esm({
|
|
38448
38542
|
"src/lib/cli-executor.ts"() {
|
|
38449
38543
|
"use strict";
|
|
@@ -38492,6 +38586,9 @@ var init_cli_executor = __esm({
|
|
|
38492
38586
|
];
|
|
38493
38587
|
DANGEROUS_CONTROL_CHARS = /[\x01-\x08\x0B\x0C\x0E-\x1F]/;
|
|
38494
38588
|
resolvedCodeQLDir = null;
|
|
38589
|
+
CODEQL_BINARY_NAME = process.platform === "win32" ? "codeql.exe" : "codeql";
|
|
38590
|
+
VSCODE_APP_NAMES = ["Code", "Code - Insiders", "VSCodium"];
|
|
38591
|
+
VSCODE_CODEQL_STORAGE_DIR_NAMES = ["github.vscode-codeql", "GitHub.vscode-codeql"];
|
|
38495
38592
|
FRESH_PROCESS_SUBCOMMANDS = /* @__PURE__ */ new Set([
|
|
38496
38593
|
"database analyze",
|
|
38497
38594
|
"database create",
|
|
@@ -40430,8 +40527,8 @@ var require_adm_zip = __commonJS({
|
|
|
40430
40527
|
return null;
|
|
40431
40528
|
}
|
|
40432
40529
|
function fixPath(zipPath) {
|
|
40433
|
-
const { join:
|
|
40434
|
-
return
|
|
40530
|
+
const { join: join18, normalize, sep: sep2 } = pth.posix;
|
|
40531
|
+
return join18(".", normalize(sep2 + zipPath.split("\\").join(sep2) + sep2));
|
|
40435
40532
|
}
|
|
40436
40533
|
function filenameFilter(filterfn) {
|
|
40437
40534
|
if (filterfn instanceof RegExp) {
|
|
@@ -53775,6 +53872,147 @@ var ExperimentalServerTasks = class {
|
|
|
53775
53872
|
requestStream(request, resultSchema, options) {
|
|
53776
53873
|
return this._server.requestStream(request, resultSchema, options);
|
|
53777
53874
|
}
|
|
53875
|
+
/**
|
|
53876
|
+
* Sends a sampling request and returns an AsyncGenerator that yields response messages.
|
|
53877
|
+
* The generator is guaranteed to end with either a 'result' or 'error' message.
|
|
53878
|
+
*
|
|
53879
|
+
* For task-augmented requests, yields 'taskCreated' and 'taskStatus' messages
|
|
53880
|
+
* before the final result.
|
|
53881
|
+
*
|
|
53882
|
+
* @example
|
|
53883
|
+
* ```typescript
|
|
53884
|
+
* const stream = server.experimental.tasks.createMessageStream({
|
|
53885
|
+
* messages: [{ role: 'user', content: { type: 'text', text: 'Hello' } }],
|
|
53886
|
+
* maxTokens: 100
|
|
53887
|
+
* }, {
|
|
53888
|
+
* onprogress: (progress) => {
|
|
53889
|
+
* // Handle streaming tokens via progress notifications
|
|
53890
|
+
* console.log('Progress:', progress.message);
|
|
53891
|
+
* }
|
|
53892
|
+
* });
|
|
53893
|
+
*
|
|
53894
|
+
* for await (const message of stream) {
|
|
53895
|
+
* switch (message.type) {
|
|
53896
|
+
* case 'taskCreated':
|
|
53897
|
+
* console.log('Task created:', message.task.taskId);
|
|
53898
|
+
* break;
|
|
53899
|
+
* case 'taskStatus':
|
|
53900
|
+
* console.log('Task status:', message.task.status);
|
|
53901
|
+
* break;
|
|
53902
|
+
* case 'result':
|
|
53903
|
+
* console.log('Final result:', message.result);
|
|
53904
|
+
* break;
|
|
53905
|
+
* case 'error':
|
|
53906
|
+
* console.error('Error:', message.error);
|
|
53907
|
+
* break;
|
|
53908
|
+
* }
|
|
53909
|
+
* }
|
|
53910
|
+
* ```
|
|
53911
|
+
*
|
|
53912
|
+
* @param params - The sampling request parameters
|
|
53913
|
+
* @param options - Optional request options (timeout, signal, task creation params, onprogress, etc.)
|
|
53914
|
+
* @returns AsyncGenerator that yields ResponseMessage objects
|
|
53915
|
+
*
|
|
53916
|
+
* @experimental
|
|
53917
|
+
*/
|
|
53918
|
+
createMessageStream(params, options) {
|
|
53919
|
+
const clientCapabilities = this._server.getClientCapabilities();
|
|
53920
|
+
if ((params.tools || params.toolChoice) && !clientCapabilities?.sampling?.tools) {
|
|
53921
|
+
throw new Error("Client does not support sampling tools capability.");
|
|
53922
|
+
}
|
|
53923
|
+
if (params.messages.length > 0) {
|
|
53924
|
+
const lastMessage = params.messages[params.messages.length - 1];
|
|
53925
|
+
const lastContent = Array.isArray(lastMessage.content) ? lastMessage.content : [lastMessage.content];
|
|
53926
|
+
const hasToolResults = lastContent.some((c) => c.type === "tool_result");
|
|
53927
|
+
const previousMessage = params.messages.length > 1 ? params.messages[params.messages.length - 2] : void 0;
|
|
53928
|
+
const previousContent = previousMessage ? Array.isArray(previousMessage.content) ? previousMessage.content : [previousMessage.content] : [];
|
|
53929
|
+
const hasPreviousToolUse = previousContent.some((c) => c.type === "tool_use");
|
|
53930
|
+
if (hasToolResults) {
|
|
53931
|
+
if (lastContent.some((c) => c.type !== "tool_result")) {
|
|
53932
|
+
throw new Error("The last message must contain only tool_result content if any is present");
|
|
53933
|
+
}
|
|
53934
|
+
if (!hasPreviousToolUse) {
|
|
53935
|
+
throw new Error("tool_result blocks are not matching any tool_use from the previous message");
|
|
53936
|
+
}
|
|
53937
|
+
}
|
|
53938
|
+
if (hasPreviousToolUse) {
|
|
53939
|
+
const toolUseIds = new Set(previousContent.filter((c) => c.type === "tool_use").map((c) => c.id));
|
|
53940
|
+
const toolResultIds = new Set(lastContent.filter((c) => c.type === "tool_result").map((c) => c.toolUseId));
|
|
53941
|
+
if (toolUseIds.size !== toolResultIds.size || ![...toolUseIds].every((id) => toolResultIds.has(id))) {
|
|
53942
|
+
throw new Error("ids of tool_result blocks and tool_use blocks from previous message do not match");
|
|
53943
|
+
}
|
|
53944
|
+
}
|
|
53945
|
+
}
|
|
53946
|
+
return this.requestStream({
|
|
53947
|
+
method: "sampling/createMessage",
|
|
53948
|
+
params
|
|
53949
|
+
}, CreateMessageResultSchema, options);
|
|
53950
|
+
}
|
|
53951
|
+
/**
|
|
53952
|
+
* Sends an elicitation request and returns an AsyncGenerator that yields response messages.
|
|
53953
|
+
* The generator is guaranteed to end with either a 'result' or 'error' message.
|
|
53954
|
+
*
|
|
53955
|
+
* For task-augmented requests (especially URL-based elicitation), yields 'taskCreated'
|
|
53956
|
+
* and 'taskStatus' messages before the final result.
|
|
53957
|
+
*
|
|
53958
|
+
* @example
|
|
53959
|
+
* ```typescript
|
|
53960
|
+
* const stream = server.experimental.tasks.elicitInputStream({
|
|
53961
|
+
* mode: 'url',
|
|
53962
|
+
* message: 'Please authenticate',
|
|
53963
|
+
* elicitationId: 'auth-123',
|
|
53964
|
+
* url: 'https://example.com/auth'
|
|
53965
|
+
* }, {
|
|
53966
|
+
* task: { ttl: 300000 } // Task-augmented for long-running auth flow
|
|
53967
|
+
* });
|
|
53968
|
+
*
|
|
53969
|
+
* for await (const message of stream) {
|
|
53970
|
+
* switch (message.type) {
|
|
53971
|
+
* case 'taskCreated':
|
|
53972
|
+
* console.log('Task created:', message.task.taskId);
|
|
53973
|
+
* break;
|
|
53974
|
+
* case 'taskStatus':
|
|
53975
|
+
* console.log('Task status:', message.task.status);
|
|
53976
|
+
* break;
|
|
53977
|
+
* case 'result':
|
|
53978
|
+
* console.log('User action:', message.result.action);
|
|
53979
|
+
* break;
|
|
53980
|
+
* case 'error':
|
|
53981
|
+
* console.error('Error:', message.error);
|
|
53982
|
+
* break;
|
|
53983
|
+
* }
|
|
53984
|
+
* }
|
|
53985
|
+
* ```
|
|
53986
|
+
*
|
|
53987
|
+
* @param params - The elicitation request parameters
|
|
53988
|
+
* @param options - Optional request options (timeout, signal, task creation params, etc.)
|
|
53989
|
+
* @returns AsyncGenerator that yields ResponseMessage objects
|
|
53990
|
+
*
|
|
53991
|
+
* @experimental
|
|
53992
|
+
*/
|
|
53993
|
+
elicitInputStream(params, options) {
|
|
53994
|
+
const clientCapabilities = this._server.getClientCapabilities();
|
|
53995
|
+
const mode = params.mode ?? "form";
|
|
53996
|
+
switch (mode) {
|
|
53997
|
+
case "url": {
|
|
53998
|
+
if (!clientCapabilities?.elicitation?.url) {
|
|
53999
|
+
throw new Error("Client does not support url elicitation.");
|
|
54000
|
+
}
|
|
54001
|
+
break;
|
|
54002
|
+
}
|
|
54003
|
+
case "form": {
|
|
54004
|
+
if (!clientCapabilities?.elicitation?.form) {
|
|
54005
|
+
throw new Error("Client does not support form elicitation.");
|
|
54006
|
+
}
|
|
54007
|
+
break;
|
|
54008
|
+
}
|
|
54009
|
+
}
|
|
54010
|
+
const normalizedParams = mode === "form" && params.mode === void 0 ? { ...params, mode: "form" } : params;
|
|
54011
|
+
return this.requestStream({
|
|
54012
|
+
method: "elicitation/create",
|
|
54013
|
+
params: normalizedParams
|
|
54014
|
+
}, ElicitResultSchema, options);
|
|
54015
|
+
}
|
|
53778
54016
|
/**
|
|
53779
54017
|
* Gets the current status of a task.
|
|
53780
54018
|
*
|
|
@@ -55420,15 +55658,17 @@ var Response2 = class _Response {
|
|
|
55420
55658
|
this.#init = init;
|
|
55421
55659
|
}
|
|
55422
55660
|
if (typeof body === "string" || typeof body?.getReader !== "undefined" || body instanceof Blob || body instanceof Uint8Array) {
|
|
55423
|
-
|
|
55424
|
-
this[cacheKey] = [init?.status || 200, body, headers];
|
|
55661
|
+
;
|
|
55662
|
+
this[cacheKey] = [init?.status || 200, body, headers || init?.headers];
|
|
55425
55663
|
}
|
|
55426
55664
|
}
|
|
55427
55665
|
get headers() {
|
|
55428
55666
|
const cache = this[cacheKey];
|
|
55429
55667
|
if (cache) {
|
|
55430
55668
|
if (!(cache[2] instanceof Headers)) {
|
|
55431
|
-
cache[2] = new Headers(
|
|
55669
|
+
cache[2] = new Headers(
|
|
55670
|
+
cache[2] || { "content-type": "text/plain; charset=UTF-8" }
|
|
55671
|
+
);
|
|
55432
55672
|
}
|
|
55433
55673
|
return cache[2];
|
|
55434
55674
|
}
|
|
@@ -55553,15 +55793,32 @@ var flushHeaders = (outgoing) => {
|
|
|
55553
55793
|
};
|
|
55554
55794
|
var responseViaCache = async (res, outgoing) => {
|
|
55555
55795
|
let [status, body, header] = res[cacheKey];
|
|
55556
|
-
|
|
55796
|
+
let hasContentLength = false;
|
|
55797
|
+
if (!header) {
|
|
55798
|
+
header = { "content-type": "text/plain; charset=UTF-8" };
|
|
55799
|
+
} else if (header instanceof Headers) {
|
|
55800
|
+
hasContentLength = header.has("content-length");
|
|
55557
55801
|
header = buildOutgoingHttpHeaders(header);
|
|
55802
|
+
} else if (Array.isArray(header)) {
|
|
55803
|
+
const headerObj = new Headers(header);
|
|
55804
|
+
hasContentLength = headerObj.has("content-length");
|
|
55805
|
+
header = buildOutgoingHttpHeaders(headerObj);
|
|
55806
|
+
} else {
|
|
55807
|
+
for (const key in header) {
|
|
55808
|
+
if (key.length === 14 && key.toLowerCase() === "content-length") {
|
|
55809
|
+
hasContentLength = true;
|
|
55810
|
+
break;
|
|
55811
|
+
}
|
|
55812
|
+
}
|
|
55558
55813
|
}
|
|
55559
|
-
if (
|
|
55560
|
-
|
|
55561
|
-
|
|
55562
|
-
|
|
55563
|
-
|
|
55564
|
-
|
|
55814
|
+
if (!hasContentLength) {
|
|
55815
|
+
if (typeof body === "string") {
|
|
55816
|
+
header["Content-Length"] = Buffer.byteLength(body);
|
|
55817
|
+
} else if (body instanceof Uint8Array) {
|
|
55818
|
+
header["Content-Length"] = body.byteLength;
|
|
55819
|
+
} else if (body instanceof Blob) {
|
|
55820
|
+
header["Content-Length"] = body.size;
|
|
55821
|
+
}
|
|
55565
55822
|
}
|
|
55566
55823
|
outgoing.writeHead(status, header);
|
|
55567
55824
|
if (typeof body === "string" || body instanceof Uint8Array) {
|
|
@@ -55870,6 +56127,7 @@ data:
|
|
|
55870
56127
|
async handleGetRequest(req) {
|
|
55871
56128
|
const acceptHeader = req.headers.get("accept");
|
|
55872
56129
|
if (!acceptHeader?.includes("text/event-stream")) {
|
|
56130
|
+
this.onerror?.(new Error("Not Acceptable: Client must accept text/event-stream"));
|
|
55873
56131
|
return this.createJsonErrorResponse(406, -32e3, "Not Acceptable: Client must accept text/event-stream");
|
|
55874
56132
|
}
|
|
55875
56133
|
const sessionError = this.validateSession(req);
|
|
@@ -55887,6 +56145,7 @@ data:
|
|
|
55887
56145
|
}
|
|
55888
56146
|
}
|
|
55889
56147
|
if (this._streamMapping.get(this._standaloneSseStreamId) !== void 0) {
|
|
56148
|
+
this.onerror?.(new Error("Conflict: Only one SSE stream is allowed per session"));
|
|
55890
56149
|
return this.createJsonErrorResponse(409, -32e3, "Conflict: Only one SSE stream is allowed per session");
|
|
55891
56150
|
}
|
|
55892
56151
|
const encoder = new TextEncoder();
|
|
@@ -55926,6 +56185,7 @@ data:
|
|
|
55926
56185
|
*/
|
|
55927
56186
|
async replayEvents(lastEventId) {
|
|
55928
56187
|
if (!this._eventStore) {
|
|
56188
|
+
this.onerror?.(new Error("Event store not configured"));
|
|
55929
56189
|
return this.createJsonErrorResponse(400, -32e3, "Event store not configured");
|
|
55930
56190
|
}
|
|
55931
56191
|
try {
|
|
@@ -55933,9 +56193,11 @@ data:
|
|
|
55933
56193
|
if (this._eventStore.getStreamIdForEventId) {
|
|
55934
56194
|
streamId = await this._eventStore.getStreamIdForEventId(lastEventId);
|
|
55935
56195
|
if (!streamId) {
|
|
56196
|
+
this.onerror?.(new Error("Invalid event ID format"));
|
|
55936
56197
|
return this.createJsonErrorResponse(400, -32e3, "Invalid event ID format");
|
|
55937
56198
|
}
|
|
55938
56199
|
if (this._streamMapping.get(streamId) !== void 0) {
|
|
56200
|
+
this.onerror?.(new Error("Conflict: Stream already has an active connection"));
|
|
55939
56201
|
return this.createJsonErrorResponse(409, -32e3, "Conflict: Stream already has an active connection");
|
|
55940
56202
|
}
|
|
55941
56203
|
}
|
|
@@ -56001,7 +56263,8 @@ data:
|
|
|
56001
56263
|
`;
|
|
56002
56264
|
controller.enqueue(encoder.encode(eventData));
|
|
56003
56265
|
return true;
|
|
56004
|
-
} catch {
|
|
56266
|
+
} catch (error2) {
|
|
56267
|
+
this.onerror?.(error2);
|
|
56005
56268
|
return false;
|
|
56006
56269
|
}
|
|
56007
56270
|
}
|
|
@@ -56009,6 +56272,7 @@ data:
|
|
|
56009
56272
|
* Handles unsupported requests (PUT, PATCH, etc.)
|
|
56010
56273
|
*/
|
|
56011
56274
|
handleUnsupportedRequest() {
|
|
56275
|
+
this.onerror?.(new Error("Method not allowed."));
|
|
56012
56276
|
return new Response(JSON.stringify({
|
|
56013
56277
|
jsonrpc: "2.0",
|
|
56014
56278
|
error: {
|
|
@@ -56031,14 +56295,17 @@ data:
|
|
|
56031
56295
|
try {
|
|
56032
56296
|
const acceptHeader = req.headers.get("accept");
|
|
56033
56297
|
if (!acceptHeader?.includes("application/json") || !acceptHeader.includes("text/event-stream")) {
|
|
56298
|
+
this.onerror?.(new Error("Not Acceptable: Client must accept both application/json and text/event-stream"));
|
|
56034
56299
|
return this.createJsonErrorResponse(406, -32e3, "Not Acceptable: Client must accept both application/json and text/event-stream");
|
|
56035
56300
|
}
|
|
56036
56301
|
const ct = req.headers.get("content-type");
|
|
56037
56302
|
if (!ct || !ct.includes("application/json")) {
|
|
56303
|
+
this.onerror?.(new Error("Unsupported Media Type: Content-Type must be application/json"));
|
|
56038
56304
|
return this.createJsonErrorResponse(415, -32e3, "Unsupported Media Type: Content-Type must be application/json");
|
|
56039
56305
|
}
|
|
56040
56306
|
const requestInfo = {
|
|
56041
|
-
headers: Object.fromEntries(req.headers.entries())
|
|
56307
|
+
headers: Object.fromEntries(req.headers.entries()),
|
|
56308
|
+
url: new URL(req.url)
|
|
56042
56309
|
};
|
|
56043
56310
|
let rawMessage;
|
|
56044
56311
|
if (options?.parsedBody !== void 0) {
|
|
@@ -56047,6 +56314,7 @@ data:
|
|
|
56047
56314
|
try {
|
|
56048
56315
|
rawMessage = await req.json();
|
|
56049
56316
|
} catch {
|
|
56317
|
+
this.onerror?.(new Error("Parse error: Invalid JSON"));
|
|
56050
56318
|
return this.createJsonErrorResponse(400, -32700, "Parse error: Invalid JSON");
|
|
56051
56319
|
}
|
|
56052
56320
|
}
|
|
@@ -56058,14 +56326,17 @@ data:
|
|
|
56058
56326
|
messages = [JSONRPCMessageSchema.parse(rawMessage)];
|
|
56059
56327
|
}
|
|
56060
56328
|
} catch {
|
|
56329
|
+
this.onerror?.(new Error("Parse error: Invalid JSON-RPC message"));
|
|
56061
56330
|
return this.createJsonErrorResponse(400, -32700, "Parse error: Invalid JSON-RPC message");
|
|
56062
56331
|
}
|
|
56063
56332
|
const isInitializationRequest = messages.some(isInitializeRequest);
|
|
56064
56333
|
if (isInitializationRequest) {
|
|
56065
56334
|
if (this._initialized && this.sessionId !== void 0) {
|
|
56335
|
+
this.onerror?.(new Error("Invalid Request: Server already initialized"));
|
|
56066
56336
|
return this.createJsonErrorResponse(400, -32600, "Invalid Request: Server already initialized");
|
|
56067
56337
|
}
|
|
56068
56338
|
if (messages.length > 1) {
|
|
56339
|
+
this.onerror?.(new Error("Invalid Request: Only one initialization request is allowed"));
|
|
56069
56340
|
return this.createJsonErrorResponse(400, -32600, "Invalid Request: Only one initialization request is allowed");
|
|
56070
56341
|
}
|
|
56071
56342
|
this.sessionId = this.sessionIdGenerator?.();
|
|
@@ -56191,13 +56462,16 @@ data:
|
|
|
56191
56462
|
return void 0;
|
|
56192
56463
|
}
|
|
56193
56464
|
if (!this._initialized) {
|
|
56465
|
+
this.onerror?.(new Error("Bad Request: Server not initialized"));
|
|
56194
56466
|
return this.createJsonErrorResponse(400, -32e3, "Bad Request: Server not initialized");
|
|
56195
56467
|
}
|
|
56196
56468
|
const sessionId = req.headers.get("mcp-session-id");
|
|
56197
56469
|
if (!sessionId) {
|
|
56470
|
+
this.onerror?.(new Error("Bad Request: Mcp-Session-Id header is required"));
|
|
56198
56471
|
return this.createJsonErrorResponse(400, -32e3, "Bad Request: Mcp-Session-Id header is required");
|
|
56199
56472
|
}
|
|
56200
56473
|
if (sessionId !== this.sessionId) {
|
|
56474
|
+
this.onerror?.(new Error("Session not found"));
|
|
56201
56475
|
return this.createJsonErrorResponse(404, -32001, "Session not found");
|
|
56202
56476
|
}
|
|
56203
56477
|
return void 0;
|
|
@@ -56218,6 +56492,7 @@ data:
|
|
|
56218
56492
|
validateProtocolVersion(req) {
|
|
56219
56493
|
const protocolVersion = req.headers.get("mcp-protocol-version");
|
|
56220
56494
|
if (protocolVersion !== null && !SUPPORTED_PROTOCOL_VERSIONS.includes(protocolVersion)) {
|
|
56495
|
+
this.onerror?.(new Error(`Bad Request: Unsupported protocol version: ${protocolVersion} (supported versions: ${SUPPORTED_PROTOCOL_VERSIONS.join(", ")})`));
|
|
56221
56496
|
return this.createJsonErrorResponse(400, -32e3, `Bad Request: Unsupported protocol version: ${protocolVersion} (supported versions: ${SUPPORTED_PROTOCOL_VERSIONS.join(", ")})`);
|
|
56222
56497
|
}
|
|
56223
56498
|
return void 0;
|
|
@@ -56438,7 +56713,7 @@ init_logger();
|
|
|
56438
56713
|
// src/lib/query-results-evaluator.ts
|
|
56439
56714
|
init_cli_executor();
|
|
56440
56715
|
init_logger();
|
|
56441
|
-
import { writeFileSync, readFileSync as
|
|
56716
|
+
import { writeFileSync, readFileSync as readFileSync3 } from "fs";
|
|
56442
56717
|
import { dirname as dirname3, isAbsolute as isAbsolute3 } from "path";
|
|
56443
56718
|
import { mkdirSync as mkdirSync3 } from "fs";
|
|
56444
56719
|
var BUILT_IN_EVALUATORS = {
|
|
@@ -56448,7 +56723,7 @@ var BUILT_IN_EVALUATORS = {
|
|
|
56448
56723
|
};
|
|
56449
56724
|
async function extractQueryMetadata(queryPath) {
|
|
56450
56725
|
try {
|
|
56451
|
-
const queryContent =
|
|
56726
|
+
const queryContent = readFileSync3(queryPath, "utf-8");
|
|
56452
56727
|
const metadata = {};
|
|
56453
56728
|
const kindMatch = queryContent.match(/@kind\s+([^\s]+)/);
|
|
56454
56729
|
if (kindMatch) metadata.kind = kindMatch[1];
|
|
@@ -56698,7 +56973,7 @@ async function evaluateWithCustomScript(_bqrsPath, _queryPath, _scriptPath, _out
|
|
|
56698
56973
|
// src/lib/log-directory-manager.ts
|
|
56699
56974
|
init_temp_dir();
|
|
56700
56975
|
import { mkdirSync as mkdirSync4, existsSync as existsSync3 } from "fs";
|
|
56701
|
-
import { join as
|
|
56976
|
+
import { join as join5, resolve as resolve3 } from "path";
|
|
56702
56977
|
import { randomBytes } from "crypto";
|
|
56703
56978
|
function ensurePathWithinBase(baseDir, targetPath) {
|
|
56704
56979
|
const absBase = resolve3(baseDir);
|
|
@@ -56722,7 +56997,7 @@ function getOrCreateLogDirectory(logDir) {
|
|
|
56722
56997
|
}
|
|
56723
56998
|
const timestamp2 = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-");
|
|
56724
56999
|
const uniqueId = randomBytes(4).toString("hex");
|
|
56725
|
-
const uniqueLogDir =
|
|
57000
|
+
const uniqueLogDir = join5(baseLogDir, `query-run-${timestamp2}-${uniqueId}`);
|
|
56726
57001
|
mkdirSync4(uniqueLogDir, { recursive: true });
|
|
56727
57002
|
return uniqueLogDir;
|
|
56728
57003
|
}
|
|
@@ -56731,7 +57006,7 @@ function getOrCreateLogDirectory(logDir) {
|
|
|
56731
57006
|
init_package_paths();
|
|
56732
57007
|
init_temp_dir();
|
|
56733
57008
|
import { writeFileSync as writeFileSync2, rmSync, existsSync as existsSync4, mkdirSync as mkdirSync5 } from "fs";
|
|
56734
|
-
import { basename as basename2, dirname as dirname4, isAbsolute as isAbsolute4, join as
|
|
57009
|
+
import { basename as basename2, dirname as dirname4, isAbsolute as isAbsolute4, join as join6, resolve as resolve4 } from "path";
|
|
56735
57010
|
var defaultCLIResultProcessor = (result, _params) => {
|
|
56736
57011
|
if (!result.success) {
|
|
56737
57012
|
return `Command failed (exit code ${result.exitCode || "unknown"}):
|
|
@@ -56900,7 +57175,7 @@ function registerCLITool(server, definition) {
|
|
|
56900
57175
|
try {
|
|
56901
57176
|
tempDir = createProjectTempDir("codeql-external-");
|
|
56902
57177
|
tempDirsToCleanup.push(tempDir);
|
|
56903
|
-
csvPath =
|
|
57178
|
+
csvPath = join6(tempDir, "selectedSourceFiles.csv");
|
|
56904
57179
|
const csvContent = filePaths.join("\n") + "\n";
|
|
56905
57180
|
writeFileSync2(csvPath, csvContent, "utf8");
|
|
56906
57181
|
} catch (err) {
|
|
@@ -56920,7 +57195,7 @@ function registerCLITool(server, definition) {
|
|
|
56920
57195
|
try {
|
|
56921
57196
|
tempDir = createProjectTempDir("codeql-external-");
|
|
56922
57197
|
tempDirsToCleanup.push(tempDir);
|
|
56923
|
-
csvPath =
|
|
57198
|
+
csvPath = join6(tempDir, "sourceFunction.csv");
|
|
56924
57199
|
const csvContent = functionNames.join("\n") + "\n";
|
|
56925
57200
|
writeFileSync2(csvPath, csvContent, "utf8");
|
|
56926
57201
|
} catch (err) {
|
|
@@ -56940,7 +57215,7 @@ function registerCLITool(server, definition) {
|
|
|
56940
57215
|
try {
|
|
56941
57216
|
tempDir = createProjectTempDir("codeql-external-");
|
|
56942
57217
|
tempDirsToCleanup.push(tempDir);
|
|
56943
|
-
csvPath =
|
|
57218
|
+
csvPath = join6(tempDir, "targetFunction.csv");
|
|
56944
57219
|
const csvContent = functionNames.join("\n") + "\n";
|
|
56945
57220
|
writeFileSync2(csvPath, csvContent, "utf8");
|
|
56946
57221
|
} catch (err) {
|
|
@@ -56973,21 +57248,21 @@ function registerCLITool(server, definition) {
|
|
|
56973
57248
|
if (name === "codeql_query_run" || name === "codeql_test_run" || name === "codeql_database_analyze") {
|
|
56974
57249
|
queryLogDir = getOrCreateLogDirectory(customLogDir);
|
|
56975
57250
|
logger.info(`Using log directory for ${name}: ${queryLogDir}`);
|
|
56976
|
-
const timestampPath =
|
|
57251
|
+
const timestampPath = join6(queryLogDir, "timestamp");
|
|
56977
57252
|
writeFileSync2(timestampPath, Date.now().toString(), "utf8");
|
|
56978
57253
|
options.logdir = queryLogDir;
|
|
56979
57254
|
if (!options.verbosity) {
|
|
56980
57255
|
options.verbosity = "progress+";
|
|
56981
57256
|
}
|
|
56982
57257
|
if (!options["evaluator-log"]) {
|
|
56983
|
-
options["evaluator-log"] =
|
|
57258
|
+
options["evaluator-log"] = join6(queryLogDir, "evaluator-log.jsonl");
|
|
56984
57259
|
}
|
|
56985
57260
|
if (options["tuple-counting"] === void 0) {
|
|
56986
57261
|
options["tuple-counting"] = true;
|
|
56987
57262
|
}
|
|
56988
57263
|
if (name === "codeql_query_run") {
|
|
56989
57264
|
if (!options.output) {
|
|
56990
|
-
options.output =
|
|
57265
|
+
options.output = join6(queryLogDir, "results.bqrs");
|
|
56991
57266
|
}
|
|
56992
57267
|
}
|
|
56993
57268
|
if (options.output && typeof options.output === "string") {
|
|
@@ -57018,7 +57293,7 @@ function registerCLITool(server, definition) {
|
|
|
57018
57293
|
}
|
|
57019
57294
|
if (name === "codeql_query_run" && result.success && queryLogDir) {
|
|
57020
57295
|
const bqrsPath = options.output;
|
|
57021
|
-
const sarifPath =
|
|
57296
|
+
const sarifPath = join6(queryLogDir, "results-interpreted.sarif");
|
|
57022
57297
|
const queryFilePath = positionalArgs.length > 0 ? positionalArgs[positionalArgs.length - 1] : void 0;
|
|
57023
57298
|
if (existsSync4(bqrsPath) && queryFilePath) {
|
|
57024
57299
|
try {
|
|
@@ -60562,8 +60837,8 @@ var codeqlGenerateQueryHelpTool = {
|
|
|
60562
60837
|
};
|
|
60563
60838
|
|
|
60564
60839
|
// src/tools/codeql/list-databases.ts
|
|
60565
|
-
import { existsSync as existsSync6, readdirSync as
|
|
60566
|
-
import { join as
|
|
60840
|
+
import { existsSync as existsSync6, readdirSync as readdirSync3, readFileSync as readFileSync5, statSync as statSync3 } from "fs";
|
|
60841
|
+
import { join as join8 } from "path";
|
|
60567
60842
|
|
|
60568
60843
|
// src/lib/discovery-config.ts
|
|
60569
60844
|
function parsePathList(envValue) {
|
|
@@ -60586,7 +60861,7 @@ function getQueryRunResultsDirs() {
|
|
|
60586
60861
|
init_logger();
|
|
60587
60862
|
function parseDatabaseYml(ymlPath) {
|
|
60588
60863
|
try {
|
|
60589
|
-
const content =
|
|
60864
|
+
const content = readFileSync5(ymlPath, "utf-8");
|
|
60590
60865
|
const info = {};
|
|
60591
60866
|
for (const line of content.split("\n")) {
|
|
60592
60867
|
const trimmed = line.trim();
|
|
@@ -60619,20 +60894,20 @@ async function discoverDatabases(baseDirs, language) {
|
|
|
60619
60894
|
}
|
|
60620
60895
|
let entries;
|
|
60621
60896
|
try {
|
|
60622
|
-
entries =
|
|
60897
|
+
entries = readdirSync3(baseDir);
|
|
60623
60898
|
} catch {
|
|
60624
60899
|
continue;
|
|
60625
60900
|
}
|
|
60626
60901
|
for (const entry of entries) {
|
|
60627
|
-
const entryPath =
|
|
60902
|
+
const entryPath = join8(baseDir, entry);
|
|
60628
60903
|
try {
|
|
60629
|
-
if (!
|
|
60904
|
+
if (!statSync3(entryPath).isDirectory()) {
|
|
60630
60905
|
continue;
|
|
60631
60906
|
}
|
|
60632
60907
|
} catch {
|
|
60633
60908
|
continue;
|
|
60634
60909
|
}
|
|
60635
|
-
const ymlPath =
|
|
60910
|
+
const ymlPath = join8(entryPath, "codeql-database.yml");
|
|
60636
60911
|
if (!existsSync6(ymlPath)) {
|
|
60637
60912
|
continue;
|
|
60638
60913
|
}
|
|
@@ -60715,8 +60990,8 @@ function registerListDatabasesTool(server) {
|
|
|
60715
60990
|
}
|
|
60716
60991
|
|
|
60717
60992
|
// src/tools/codeql/list-mrva-run-results.ts
|
|
60718
|
-
import { existsSync as existsSync7, readdirSync as
|
|
60719
|
-
import { join as
|
|
60993
|
+
import { existsSync as existsSync7, readdirSync as readdirSync4, readFileSync as readFileSync6, statSync as statSync4 } from "fs";
|
|
60994
|
+
import { join as join9 } from "path";
|
|
60720
60995
|
init_logger();
|
|
60721
60996
|
var NUMERIC_DIR_PATTERN = /^\d+$/;
|
|
60722
60997
|
var SKIP_DIRS = /* @__PURE__ */ new Set([".DS_Store", "exported-results"]);
|
|
@@ -60728,14 +61003,14 @@ async function discoverMrvaRunResults(resultsDirs, runId) {
|
|
|
60728
61003
|
}
|
|
60729
61004
|
let entries;
|
|
60730
61005
|
try {
|
|
60731
|
-
entries =
|
|
61006
|
+
entries = readdirSync4(dir);
|
|
60732
61007
|
} catch {
|
|
60733
61008
|
continue;
|
|
60734
61009
|
}
|
|
60735
61010
|
for (const entry of entries) {
|
|
60736
|
-
const entryPath =
|
|
61011
|
+
const entryPath = join9(dir, entry);
|
|
60737
61012
|
try {
|
|
60738
|
-
if (!
|
|
61013
|
+
if (!statSync4(entryPath).isDirectory()) {
|
|
60739
61014
|
continue;
|
|
60740
61015
|
}
|
|
60741
61016
|
} catch {
|
|
@@ -60748,10 +61023,10 @@ async function discoverMrvaRunResults(resultsDirs, runId) {
|
|
|
60748
61023
|
continue;
|
|
60749
61024
|
}
|
|
60750
61025
|
let timestamp2;
|
|
60751
|
-
const timestampPath =
|
|
61026
|
+
const timestampPath = join9(entryPath, "timestamp");
|
|
60752
61027
|
if (existsSync7(timestampPath)) {
|
|
60753
61028
|
try {
|
|
60754
|
-
timestamp2 =
|
|
61029
|
+
timestamp2 = readFileSync6(timestampPath, "utf-8").trim();
|
|
60755
61030
|
} catch {
|
|
60756
61031
|
}
|
|
60757
61032
|
}
|
|
@@ -60770,7 +61045,7 @@ function discoverRepoResults(runPath) {
|
|
|
60770
61045
|
const repos = [];
|
|
60771
61046
|
let ownerEntries;
|
|
60772
61047
|
try {
|
|
60773
|
-
ownerEntries =
|
|
61048
|
+
ownerEntries = readdirSync4(runPath);
|
|
60774
61049
|
} catch {
|
|
60775
61050
|
return repos;
|
|
60776
61051
|
}
|
|
@@ -60778,9 +61053,9 @@ function discoverRepoResults(runPath) {
|
|
|
60778
61053
|
if (SKIP_DIRS.has(ownerEntry)) {
|
|
60779
61054
|
continue;
|
|
60780
61055
|
}
|
|
60781
|
-
const ownerPath =
|
|
61056
|
+
const ownerPath = join9(runPath, ownerEntry);
|
|
60782
61057
|
try {
|
|
60783
|
-
if (!
|
|
61058
|
+
if (!statSync4(ownerPath).isDirectory()) {
|
|
60784
61059
|
continue;
|
|
60785
61060
|
}
|
|
60786
61061
|
} catch {
|
|
@@ -60788,14 +61063,14 @@ function discoverRepoResults(runPath) {
|
|
|
60788
61063
|
}
|
|
60789
61064
|
let repoEntries;
|
|
60790
61065
|
try {
|
|
60791
|
-
repoEntries =
|
|
61066
|
+
repoEntries = readdirSync4(ownerPath);
|
|
60792
61067
|
} catch {
|
|
60793
61068
|
continue;
|
|
60794
61069
|
}
|
|
60795
61070
|
for (const repoEntry of repoEntries) {
|
|
60796
|
-
const repoPath =
|
|
61071
|
+
const repoPath = join9(ownerPath, repoEntry);
|
|
60797
61072
|
try {
|
|
60798
|
-
if (!
|
|
61073
|
+
if (!statSync4(repoPath).isDirectory()) {
|
|
60799
61074
|
continue;
|
|
60800
61075
|
}
|
|
60801
61076
|
} catch {
|
|
@@ -60804,10 +61079,10 @@ function discoverRepoResults(runPath) {
|
|
|
60804
61079
|
const fullName = `${ownerEntry}/${repoEntry}`;
|
|
60805
61080
|
let analysisStatus;
|
|
60806
61081
|
let resultCount;
|
|
60807
|
-
const repoTaskPath =
|
|
61082
|
+
const repoTaskPath = join9(repoPath, "repo_task.json");
|
|
60808
61083
|
if (existsSync7(repoTaskPath)) {
|
|
60809
61084
|
try {
|
|
60810
|
-
const raw =
|
|
61085
|
+
const raw = readFileSync6(repoTaskPath, "utf-8");
|
|
60811
61086
|
const task = JSON.parse(raw);
|
|
60812
61087
|
if (typeof task.analysisStatus === "string") {
|
|
60813
61088
|
analysisStatus = task.analysisStatus;
|
|
@@ -60818,8 +61093,8 @@ function discoverRepoResults(runPath) {
|
|
|
60818
61093
|
} catch {
|
|
60819
61094
|
}
|
|
60820
61095
|
}
|
|
60821
|
-
const hasSarif = existsSync7(
|
|
60822
|
-
const hasBqrs = existsSync7(
|
|
61096
|
+
const hasSarif = existsSync7(join9(repoPath, "results", "results.sarif"));
|
|
61097
|
+
const hasBqrs = existsSync7(join9(repoPath, "results", "results.bqrs"));
|
|
60823
61098
|
repos.push({
|
|
60824
61099
|
analysisStatus,
|
|
60825
61100
|
fullName,
|
|
@@ -60902,8 +61177,8 @@ function registerListMrvaRunResultsTool(server) {
|
|
|
60902
61177
|
}
|
|
60903
61178
|
|
|
60904
61179
|
// src/tools/codeql/list-query-run-results.ts
|
|
60905
|
-
import { existsSync as existsSync8, readdirSync as
|
|
60906
|
-
import { join as
|
|
61180
|
+
import { existsSync as existsSync8, readdirSync as readdirSync5, readFileSync as readFileSync7, statSync as statSync5 } from "fs";
|
|
61181
|
+
import { join as join10 } from "path";
|
|
60907
61182
|
init_logger();
|
|
60908
61183
|
var QUERY_RUN_DIR_PATTERN = /^(.+\.ql)-(.+)$/;
|
|
60909
61184
|
var RUN_QUERY_PATTERN = /runQuery called with\s+(\S+)/;
|
|
@@ -60944,14 +61219,14 @@ async function discoverQueryRunResults(resultsDirs, filter) {
|
|
|
60944
61219
|
}
|
|
60945
61220
|
let entries;
|
|
60946
61221
|
try {
|
|
60947
|
-
entries =
|
|
61222
|
+
entries = readdirSync5(dir);
|
|
60948
61223
|
} catch {
|
|
60949
61224
|
continue;
|
|
60950
61225
|
}
|
|
60951
61226
|
for (const entry of entries) {
|
|
60952
|
-
const entryPath =
|
|
61227
|
+
const entryPath = join10(dir, entry);
|
|
60953
61228
|
try {
|
|
60954
|
-
if (!
|
|
61229
|
+
if (!statSync5(entryPath).isDirectory()) {
|
|
60955
61230
|
continue;
|
|
60956
61231
|
}
|
|
60957
61232
|
} catch {
|
|
@@ -60965,23 +61240,23 @@ async function discoverQueryRunResults(resultsDirs, filter) {
|
|
|
60965
61240
|
if (normalizedFilter?.queryName && name !== normalizedFilter.queryName) {
|
|
60966
61241
|
continue;
|
|
60967
61242
|
}
|
|
60968
|
-
const hasEvaluatorLog = existsSync8(
|
|
60969
|
-
const hasBqrs = existsSync8(
|
|
60970
|
-
const hasSarif = existsSync8(
|
|
60971
|
-
const hasQueryLog = existsSync8(
|
|
60972
|
-
const hasSummaryLog = existsSync8(
|
|
61243
|
+
const hasEvaluatorLog = existsSync8(join10(entryPath, "evaluator-log.jsonl"));
|
|
61244
|
+
const hasBqrs = existsSync8(join10(entryPath, "results.bqrs"));
|
|
61245
|
+
const hasSarif = existsSync8(join10(entryPath, "results-interpreted.sarif"));
|
|
61246
|
+
const hasQueryLog = existsSync8(join10(entryPath, "query.log"));
|
|
61247
|
+
const hasSummaryLog = existsSync8(join10(entryPath, "evaluator-log.summary.jsonl"));
|
|
60973
61248
|
let timestamp2;
|
|
60974
|
-
const timestampPath =
|
|
61249
|
+
const timestampPath = join10(entryPath, "timestamp");
|
|
60975
61250
|
if (existsSync8(timestampPath)) {
|
|
60976
61251
|
try {
|
|
60977
|
-
timestamp2 =
|
|
61252
|
+
timestamp2 = readFileSync7(timestampPath, "utf-8").trim();
|
|
60978
61253
|
} catch {
|
|
60979
61254
|
}
|
|
60980
61255
|
}
|
|
60981
61256
|
let metadata = {};
|
|
60982
61257
|
if (hasQueryLog) {
|
|
60983
61258
|
try {
|
|
60984
|
-
const logContent =
|
|
61259
|
+
const logContent = readFileSync7(join10(entryPath, "query.log"), "utf-8");
|
|
60985
61260
|
metadata = parseQueryLogMetadata(logContent);
|
|
60986
61261
|
} catch {
|
|
60987
61262
|
}
|
|
@@ -61089,7 +61364,7 @@ function registerListQueryRunResultsTool(server) {
|
|
|
61089
61364
|
if (run.queryPath) parts.push(` Query: ${run.queryPath}`);
|
|
61090
61365
|
if (run.databasePath) parts.push(` Database: ${run.databasePath}`);
|
|
61091
61366
|
parts.push(` Artifacts: ${artifacts.length > 0 ? artifacts.join(", ") : "none"}`);
|
|
61092
|
-
if (run.hasBqrs) parts.push(` BQRS: ${
|
|
61367
|
+
if (run.hasBqrs) parts.push(` BQRS: ${join10(run.path, "results.bqrs")}`);
|
|
61093
61368
|
return parts.join("\n");
|
|
61094
61369
|
})
|
|
61095
61370
|
];
|
|
@@ -61155,11 +61430,11 @@ var codeqlPackLsTool = {
|
|
|
61155
61430
|
|
|
61156
61431
|
// src/tools/codeql/profile-codeql-query-from-logs.ts
|
|
61157
61432
|
import { existsSync as existsSync9, mkdirSync as mkdirSync6, writeFileSync as writeFileSync3 } from "fs";
|
|
61158
|
-
import { basename as basename4, dirname as dirname6, join as
|
|
61433
|
+
import { basename as basename4, dirname as dirname6, join as join11 } from "path";
|
|
61159
61434
|
|
|
61160
61435
|
// src/lib/evaluator-log-parser.ts
|
|
61161
61436
|
init_logger();
|
|
61162
|
-
import { readFileSync as
|
|
61437
|
+
import { readFileSync as readFileSync8 } from "fs";
|
|
61163
61438
|
function detectLogFormat(firstEvent) {
|
|
61164
61439
|
if (typeof firstEvent.type === "string") {
|
|
61165
61440
|
return "raw";
|
|
@@ -61186,7 +61461,7 @@ function splitJsonObjects(content) {
|
|
|
61186
61461
|
});
|
|
61187
61462
|
}
|
|
61188
61463
|
function parseJsonObjects(logPath) {
|
|
61189
|
-
const content =
|
|
61464
|
+
const content = readFileSync8(logPath, "utf-8");
|
|
61190
61465
|
const objectStrings = splitJsonObjects(content);
|
|
61191
61466
|
const results = [];
|
|
61192
61467
|
for (const objStr of objectStrings) {
|
|
@@ -61549,13 +61824,13 @@ function registerProfileCodeQLQueryFromLogsTool(server) {
|
|
|
61549
61824
|
const profile = parseEvaluatorLog(evaluatorLog);
|
|
61550
61825
|
const profileOutputDir = outputDir ?? dirname6(evaluatorLog);
|
|
61551
61826
|
mkdirSync6(profileOutputDir, { recursive: true });
|
|
61552
|
-
const jsonPath =
|
|
61827
|
+
const jsonPath = join11(
|
|
61553
61828
|
profileOutputDir,
|
|
61554
61829
|
"query-evaluation-profile.json"
|
|
61555
61830
|
);
|
|
61556
61831
|
writeFileSync3(jsonPath, formatAsJson(profile));
|
|
61557
61832
|
logger.info(`Profile JSON written to: ${jsonPath}`);
|
|
61558
|
-
const mdPath =
|
|
61833
|
+
const mdPath = join11(
|
|
61559
61834
|
profileOutputDir,
|
|
61560
61835
|
"query-evaluation-profile.md"
|
|
61561
61836
|
);
|
|
@@ -61596,11 +61871,11 @@ function registerProfileCodeQLQueryFromLogsTool(server) {
|
|
|
61596
61871
|
// src/tools/codeql/profile-codeql-query.ts
|
|
61597
61872
|
init_cli_executor();
|
|
61598
61873
|
init_logger();
|
|
61599
|
-
import { writeFileSync as writeFileSync4, readFileSync as
|
|
61600
|
-
import { join as
|
|
61874
|
+
import { writeFileSync as writeFileSync4, readFileSync as readFileSync9, existsSync as existsSync10 } from "fs";
|
|
61875
|
+
import { join as join12, dirname as dirname7, basename as basename5 } from "path";
|
|
61601
61876
|
import { mkdirSync as mkdirSync7 } from "fs";
|
|
61602
61877
|
function parseEvaluatorLog2(logPath) {
|
|
61603
|
-
const logContent =
|
|
61878
|
+
const logContent = readFileSync9(logPath, "utf-8");
|
|
61604
61879
|
const jsonObjects = logContent.split("\n\n").filter((s) => s.trim());
|
|
61605
61880
|
const events = jsonObjects.map((obj) => {
|
|
61606
61881
|
try {
|
|
@@ -61734,11 +62009,11 @@ function registerProfileCodeQLQueryTool(server) {
|
|
|
61734
62009
|
let sarifPath;
|
|
61735
62010
|
if (!logPath) {
|
|
61736
62011
|
logger.info("No evaluator log provided, running query to generate one");
|
|
61737
|
-
const defaultOutputDir = outputDir ||
|
|
62012
|
+
const defaultOutputDir = outputDir || join12(dirname7(query), "profile-output");
|
|
61738
62013
|
mkdirSync7(defaultOutputDir, { recursive: true });
|
|
61739
|
-
logPath =
|
|
61740
|
-
bqrsPath =
|
|
61741
|
-
sarifPath =
|
|
62014
|
+
logPath = join12(defaultOutputDir, "evaluator-log.jsonl");
|
|
62015
|
+
bqrsPath = join12(defaultOutputDir, "query-results.bqrs");
|
|
62016
|
+
sarifPath = join12(defaultOutputDir, "query-results.sarif");
|
|
61742
62017
|
const queryResult = await executeCodeQLCommand(
|
|
61743
62018
|
"query run",
|
|
61744
62019
|
{
|
|
@@ -61791,11 +62066,11 @@ function registerProfileCodeQLQueryTool(server) {
|
|
|
61791
62066
|
const profile = parseEvaluatorLog2(logPath);
|
|
61792
62067
|
const profileOutputDir = outputDir || dirname7(logPath);
|
|
61793
62068
|
mkdirSync7(profileOutputDir, { recursive: true });
|
|
61794
|
-
const jsonPath =
|
|
62069
|
+
const jsonPath = join12(profileOutputDir, "query-evaluation-profile.json");
|
|
61795
62070
|
const jsonContent = formatAsJson2(profile);
|
|
61796
62071
|
writeFileSync4(jsonPath, jsonContent);
|
|
61797
62072
|
logger.info(`Profile JSON written to: ${jsonPath}`);
|
|
61798
|
-
const mdPath =
|
|
62073
|
+
const mdPath = join12(profileOutputDir, "query-evaluation-profile.md");
|
|
61799
62074
|
const mdContent = formatAsMermaid2(profile);
|
|
61800
62075
|
writeFileSync4(mdPath, mdContent);
|
|
61801
62076
|
logger.info(`Profile Mermaid diagram written to: ${mdPath}`);
|
|
@@ -61946,7 +62221,7 @@ var codeqlQueryRunTool = {
|
|
|
61946
62221
|
};
|
|
61947
62222
|
|
|
61948
62223
|
// src/tools/codeql/quick-evaluate.ts
|
|
61949
|
-
import { join as
|
|
62224
|
+
import { join as join13, resolve as resolve6 } from "path";
|
|
61950
62225
|
init_logger();
|
|
61951
62226
|
init_temp_dir();
|
|
61952
62227
|
async function quickEvaluate({
|
|
@@ -61965,7 +62240,7 @@ async function quickEvaluate({
|
|
|
61965
62240
|
throw new Error(`Symbol '${symbol}' not found as class or predicate in file: ${file}`);
|
|
61966
62241
|
}
|
|
61967
62242
|
}
|
|
61968
|
-
const resolvedOutput = resolve6(output_path ||
|
|
62243
|
+
const resolvedOutput = resolve6(output_path || join13(getProjectTmpDir("quickeval"), "quickeval.bqrs"));
|
|
61969
62244
|
return resolvedOutput;
|
|
61970
62245
|
} catch (error2) {
|
|
61971
62246
|
throw new Error(`CodeQL evaluation failed: ${error2 instanceof Error ? error2.message : "Unknown error"}`, { cause: error2 });
|
|
@@ -62005,8 +62280,8 @@ function registerQuickEvaluateTool(server) {
|
|
|
62005
62280
|
|
|
62006
62281
|
// src/tools/codeql/read-database-source.ts
|
|
62007
62282
|
var import_adm_zip = __toESM(require_adm_zip(), 1);
|
|
62008
|
-
import { existsSync as existsSync11, readdirSync as
|
|
62009
|
-
import { join as
|
|
62283
|
+
import { existsSync as existsSync11, readdirSync as readdirSync6, readFileSync as readFileSync10, statSync as statSync6 } from "fs";
|
|
62284
|
+
import { join as join14, resolve as resolve7 } from "path";
|
|
62010
62285
|
import { fileURLToPath as fileURLToPath2 } from "url";
|
|
62011
62286
|
init_logger();
|
|
62012
62287
|
var DEFAULT_MAX_LISTING_ENTRIES = 1e3;
|
|
@@ -62022,9 +62297,9 @@ function toFilesystemPath(uri) {
|
|
|
62022
62297
|
return uri;
|
|
62023
62298
|
}
|
|
62024
62299
|
function* walkDirectory(dir, base = dir) {
|
|
62025
|
-
for (const entry of
|
|
62026
|
-
const fullPath =
|
|
62027
|
-
if (
|
|
62300
|
+
for (const entry of readdirSync6(dir)) {
|
|
62301
|
+
const fullPath = join14(dir, entry);
|
|
62302
|
+
if (statSync6(fullPath).isDirectory()) {
|
|
62028
62303
|
yield* walkDirectory(fullPath, base);
|
|
62029
62304
|
} else {
|
|
62030
62305
|
yield fullPath.slice(base.length).replace(/\\/g, "/").replace(/^\//, "");
|
|
@@ -62090,8 +62365,8 @@ async function readDatabaseSource(params) {
|
|
|
62090
62365
|
if (!existsSync11(resolvedDbPath)) {
|
|
62091
62366
|
throw new Error(`Database path does not exist: ${databasePath}`);
|
|
62092
62367
|
}
|
|
62093
|
-
const srcZipPath =
|
|
62094
|
-
const srcDirPath =
|
|
62368
|
+
const srcZipPath = join14(resolvedDbPath, "src.zip");
|
|
62369
|
+
const srcDirPath = join14(resolvedDbPath, "src");
|
|
62095
62370
|
const hasSrcZip = existsSync11(srcZipPath);
|
|
62096
62371
|
const hasSrcDir = existsSync11(srcDirPath);
|
|
62097
62372
|
if (!hasSrcZip && !hasSrcDir) {
|
|
@@ -62166,8 +62441,8 @@ Archive contains ${availableEntries.length} entries. Use read_database_source wi
|
|
|
62166
62441
|
Directory contains ${availableEntries.length} entries. Use read_database_source without filePath to list available entries.`
|
|
62167
62442
|
);
|
|
62168
62443
|
}
|
|
62169
|
-
const fullPath =
|
|
62170
|
-
const rawContent =
|
|
62444
|
+
const fullPath = join14(srcDirPath, matchedRelative);
|
|
62445
|
+
const rawContent = readFileSync10(fullPath, "utf-8");
|
|
62171
62446
|
const { content, effectiveEnd, effectiveStart, totalLines } = applyLineRange(
|
|
62172
62447
|
rawContent,
|
|
62173
62448
|
startLine,
|
|
@@ -62762,76 +63037,198 @@ function registerCodeQLTools(server) {
|
|
|
62762
63037
|
registerRegisterDatabaseTool(server);
|
|
62763
63038
|
}
|
|
62764
63039
|
|
|
63040
|
+
// src/resources/dataflow-migration-v1-to-v2.md
|
|
63041
|
+
var dataflow_migration_v1_to_v2_default = '# Dataflow API Migration: v1 to v2\n\nGuide for migrating CodeQL queries from the legacy v1 (class-based) dataflow API to the modern v2 (module-based) shared dataflow API. This applies to all supported languages.\n\n## Why Migrate\n\nThe v1 `DataFlow::Configuration` class-based API is deprecated. The v2 `DataFlow::ConfigSig` module-based API is the current standard across all languages. Queries using v1 will eventually stop compiling as the legacy API is removed.\n\n## API Changes Summary\n\n| v1 (Legacy) | v2 (Modern) | Notes |\n| ------------------------------------------------ | ------------------------------------------------ | --------------------------------------- |\n| `class MyConfig extends DataFlow::Configuration` | `module MyConfig implements DataFlow::ConfigSig` | Module-based, not class-based |\n| `MyConfig() { this = "MyConfig" }` | _(removed)_ | No constructor needed |\n| `override predicate isSanitizer(...)` | `predicate isBarrier(...)` | Renamed |\n| `override predicate isAdditionalTaintStep(...)` | `predicate isAdditionalFlowStep(...)` | Renamed |\n| `config.hasFlowPath(source, sink)` | `MyFlow::flowPath(source, sink)` | Module-level predicate |\n| `DataFlow::PathNode` | `MyFlow::PathNode` | Path nodes scoped to flow module |\n| `isSanitizerGuard` | _(removed \u2014 use `isBarrier` with guard logic)_ | Fold guard into barrier |\n| `FlowLabel` (JS) | `FlowState` | Renamed; use `DataFlow::StateConfigSig` |\n\n## v1 Pattern\n\n```ql\nclass MyConfig extends DataFlow::Configuration {\n MyConfig() { this = "MyConfig" }\n override predicate isSource(DataFlow::Node source) { ... }\n override predicate isSink(DataFlow::Node sink) { ... }\n override predicate isSanitizer(DataFlow::Node node) { ... }\n override predicate isAdditionalTaintStep(DataFlow::Node n1, DataFlow::Node n2) { ... }\n}\n\nfrom MyConfig config, DataFlow::PathNode source, DataFlow::PathNode sink\nwhere config.hasFlowPath(source, sink)\nselect sink, source, sink, "Message"\n```\n\n## v2 Pattern\n\n```ql\nmodule MyConfig implements DataFlow::ConfigSig {\n predicate isSource(DataFlow::Node source) { ... }\n predicate isSink(DataFlow::Node sink) { ... }\n predicate isBarrier(DataFlow::Node node) { ... }\n predicate isAdditionalFlowStep(DataFlow::Node n1, DataFlow::Node n2) { ... }\n}\n\nmodule MyFlow = TaintTracking::Global<MyConfig>;\nimport MyFlow::PathGraph\n\nfrom MyFlow::PathNode source, MyFlow::PathNode sink\nwhere MyFlow::flowPath(source, sink)\nselect sink.getNode(), source, sink, "Message"\n```\n\n## Migration Workflow\n\n1. **Capture baseline**: Run `codeql_test_run` on existing tests and save current `.expected` files\n2. **Rewrite config**: Replace the `class extends Configuration` with `module implements ConfigSig`, rename predicates per the table above\n3. **Instantiate module**: Add `module MyFlow = TaintTracking::Global<MyConfig>;` (or `DataFlow::Global<MyConfig>` for pure data flow)\n4. **Update select clause**: Replace `config.hasFlowPath(source, sink)` with `MyFlow::flowPath(source, sink)` and `DataFlow::PathNode` with `MyFlow::PathNode`\n5. **Handle flow state**: If the query uses `FlowLabel` (JS) or state-sensitive predicates, switch to `DataFlow::StateConfigSig` and `TaintTracking::GlobalWithState<MyConfig>`\n6. **Compile**: Run `codeql_query_compile` to catch syntax errors\n7. **Test**: Run `codeql_test_run` and verify results match the v1 baseline exactly\n8. **Accept**: Once equivalent, run `codeql_test_accept` to finalize\n\n## Language-Specific Notes\n\n### C/C++\n\n- Import paths stay the same (`semmle.code.cpp.dataflow.TaintTracking`); only the API usage changes.\n- Pointer indirection: use `asIndirectExpr()` in `isAdditionalFlowStep` to track through dereferences.\n- Track `std::move` operations as additional flow steps when relevant.\n- `IndirectParameterNode` usage is unchanged between v1 and v2.\n\n### C\\#\n\n- Use `semmle.code.csharp.dataflow.TaintTracking` (same import for v1 and v2).\n- `LibraryTypeDataFlow` extensions for custom library flow are unchanged.\n- Test LINQ, async/await, and property accessor patterns \u2014 these can surface subtle differences.\n- ASP.NET `[FromBody]`/`[FromQuery]` parameter annotations work identically.\n\n### Go\n\n- Node types (`ExprNode`, `ParameterNode`, `InstructionNode`) and AST/IR conversions (`asExpr()`, `asInstruction()`) are unchanged.\n- `RemoteFlowSource` and `UntrustedFlowSource` work identically in v2.\n- Channel send/receive and goroutine flow require `isAdditionalFlowStep`; these patterns are unchanged.\n- Error-handling tuples: use `ResultNode` with `hasResultIndex(0)` for the value element.\n- Interface type assertions (`TypeAssertExpr`) need explicit flow steps.\n\n### Java / Kotlin\n\n- `InstanceParameterNode` (implicit `this`) is unchanged.\n- Spring `@RequestParam`/`@PathVariable`/`@RequestBody` annotations work identically.\n- Stream/lambda/method-reference flows and boxing/unboxing steps carry over directly.\n- Kotlin `when` expressions and extension function receiver flow require explicit `isAdditionalFlowStep`.\n\n### JavaScript / TypeScript\n\n- **Flow labels \u2192 Flow states**: If the v1 query uses `FlowLabel`, switch to `DataFlow::StateConfigSig` with `class FlowState = string;` and `TaintTracking::GlobalWithState<MyConfig>`.\n- **Sanitizer guards \u2192 Barrier guards**: `isSanitizerGuard` becomes `isBarrierGuard` with `DataFlow::BarrierGuard`.\n- **Behavioral changes**: v2 taint steps propagate all flow states (not just `taint`). Jump steps across function boundaries (callbacks, Promises) may behave differently \u2014 watch for new or missing results.\n- Promise `.then()` and async/await flow, prototype pollution via `Object.assign`/spread, and module import/export flow are unchanged.\n\n### Python\n\n- Python has multiple dataflow nodes per expression due to CFG splitting. This behavior is identical in v2.\n- `CfgNode` / `CallCfgNode` / `getCfgNode()` conversions are unchanged.\n- API graph navigation (`API::moduleImport("pkg").getMember(...)`) is unchanged.\n- Django ORM, Flask routing, and FastAPI dependency injection patterns carry over directly.\n\n### Ruby\n\n- `asExpr()` returns `CfgNodes::ExprCfgNode` (CFG node, not AST). Use `.getExpr()` to get the AST node. This is unchanged between v1 and v2.\n- Rails `params`, ActiveRecord queries, and metaprogramming (`send`, `define_method`, `eval`) patterns carry over directly.\n- String interpolation and block/lambda flows are unchanged.\n\n### Swift\n\n- Import paths differ from other languages: `codeql.swift.dataflow.DataFlow`, `codeql.swift.dataflow.TaintTracking`, `codeql.swift.dataflow.FlowSources`.\n- Unique node types: `PatternNode`, `CaptureNode`, `InoutReturnNode`, `SsaDefinitionNode`.\n- `RemoteFlowSource` and `LocalFlowSource` from `codeql.swift.dataflow.FlowSources` work identically.\n- Requires macOS with Xcode for test extraction. Supports Swift 5.4\u20136.2.\n\n## Critical: Result Equivalence\n\nMigrated queries **must** produce identical results to the v1 version. Differences indicate a semantic change in the migration. Common causes:\n\n- **Barrier scope**: v2 barriers block all flow states; v1 sanitizers may have been state-specific\n- **Additional flow steps**: v2 uses `isAdditionalFlowStep` for both data flow and taint; v1 had separate `isAdditionalTaintStep`\n- **Jump steps** (JS): Taint propagation across function boundaries may differ\n';
|
|
63042
|
+
|
|
63043
|
+
// src/resources/learning-query-basics.md
|
|
63044
|
+
var learning_query_basics_default = '# Writing CodeQL Queries\n\nThis resource is a practical reference for writing CodeQL queries using the MCP server\'s tools. It covers query structure, metadata annotations, common QL patterns, compilation, testing, and the file conventions used by the CodeQL test framework.\n\n## Query Structure\n\nEvery CodeQL query has three main clauses:\n\n```ql\n/**\n * @name Descriptive name of what the query finds\n * @description Longer explanation of the vulnerability or pattern\n * @kind problem\n * @problem.severity warning\n * @precision medium\n * @id lang/query-id\n * @tags security\n * correctness\n */\n\nimport language\n\nfrom SourceType source, SinkType sink\nwhere <conditions linking source to sink>\nselect <result expression>, <message string>\n```\n\n### `from` Clause\n\nDeclares typed variables. Each variable ranges over all values of its type in the database:\n\n```ql\nfrom Function f, FunctionCall call\n```\n\n### `where` Clause\n\nFilters the cross-product of `from` variables using predicates:\n\n```ql\nwhere call.getTarget() = f\n and f.getName() = "eval"\n```\n\n### `select` Clause\n\nDefines the output columns. The first expression is the "element" (the location in source code), followed by a message string:\n\n```ql\nselect call, "Call to dangerous function " + f.getName()\n```\n\n## Metadata Annotations\n\nMetadata goes in a QLDoc comment block (`/** ... */`) at the top of the query file:\n\n| Annotation | Required | Description |\n| -------------------- | ---------------------------- | ------------------------------------------------------------ |\n| `@name` | Yes | Short human-readable name |\n| `@description` | Yes | Explanation of the query\'s purpose |\n| `@kind` | Yes | Output format: `problem`, `path-problem`, `table`, `graph` |\n| `@id` | Yes | Unique identifier (e.g., `js/sql-injection`) |\n| `@problem.severity` | For `problem`/`path-problem` | `error`, `warning`, or `recommendation` |\n| `@security-severity` | For security queries | CVSS score (e.g., `8.8`) |\n| `@precision` | Recommended | `very-high`, `high`, `medium`, or `low` |\n| `@tags` | Recommended | Categories like `security`, `correctness`, `maintainability` |\n\nUse `codeql_resolve_metadata` to extract and validate a query\'s metadata.\n\n## Common `@kind` Values\n\n- **`problem`** \u2014 Reports a single location with a message. Use `select element, message`.\n- **`path-problem`** \u2014 Reports a source-to-sink data flow path. Requires a `PathGraph` import and `select sink, source, sink, message`.\n- **`table`** \u2014 Generic tabular output (no alert interpretation).\n- **`graph`** \u2014 Structural output (AST, CFG, call graphs). Used by `PrintAST`, `PrintCFG`, `CallGraphFrom`, `CallGraphTo` tool queries.\n\n## Common QL Patterns\n\n### Predicate Definition\n\n```ql\npredicate isUserInput(DataFlow::Node node) {\n exists(Parameter p | p = node.asParameter() |\n p.getFunction().isPublic()\n )\n}\n```\n\n### Class Definition\n\n```ql\nclass DangerousCall extends MethodCall {\n DangerousCall() {\n this.getMethodName() = ["exec", "eval", "system"]\n }\n}\n```\n\n### Existential Quantifier (`exists`)\n\n```ql\nwhere exists(Assignment a | a.getLhs() = var and a.getRhs() instanceof NullLiteral)\n```\n\n### Aggregates\n\n```ql\nselect f, count(FunctionCall call | call.getTarget() = f) as callCount\n order by callCount desc\n```\n\n## Taint Tracking / Data Flow Configuration (v2 API)\n\n```ql\nmodule MyFlowConfig implements DataFlow::ConfigSig {\n predicate isSource(DataFlow::Node source) {\n // define sources\n }\n\n predicate isSink(DataFlow::Node sink) {\n // define sinks\n }\n\n predicate isBarrier(DataFlow::Node node) {\n // define sanitizers (optional)\n }\n}\n\nmodule MyFlow = TaintTracking::Global<MyFlowConfig>;\n```\n\n## Query Compilation and Validation\n\nUse these tools to validate queries at different fidelity levels:\n\n| Tool | Speed | Fidelity | When to Use |\n| ------------------------ | ------- | ------------------ | ----------------------------------------------------------------- |\n| `validate_codeql_query` | Instant | Heuristic only | Quick structure check (no compilation) |\n| `codeql_query_compile` | Fast | Full compilation | Syntax and type checking |\n| `codeql_lsp_diagnostics` | Fast | Full (single file) | Real-time validation during editing (cannot resolve pack imports) |\n\nTypical workflow:\n\n1. `validate_codeql_query` \u2014 quick structural check\n2. `codeql_query_compile` with `checkOnly: true` \u2014 full compilation\n3. `codeql_lsp_diagnostics` \u2014 interactive feedback during editing\n\n## Test File Conventions\n\nCodeQL query tests use this directory layout:\n\n```text\npack-root/\n\u251C\u2500\u2500 src/\n\u2502 \u251C\u2500\u2500 codeql-pack.yml # Source pack\n\u2502 \u2514\u2500\u2500 MyQuery/\n\u2502 \u2514\u2500\u2500 MyQuery.ql # The query\n\u2514\u2500\u2500 test/\n \u251C\u2500\u2500 codeql-pack.yml # Test pack\n \u2514\u2500\u2500 MyQuery/\n \u251C\u2500\u2500 MyQuery.qlref # Points to ../../src/MyQuery/MyQuery.ql\n \u251C\u2500\u2500 test.js # Test source code (language-appropriate)\n \u2514\u2500\u2500 MyQuery.expected # Expected query output\n```\n\n- **`.qlref` file**: Contains the relative path from the test pack\'s `src/` directory to the query file.\n- **`.expected` file**: Contains the expected output of running the query against the test code. Use `codeql_test_accept` to generate or update this file.\n- **Test source code**: Write code with both positive cases (should trigger the query) and negative cases (should not trigger).\n\n### Running Tests\n\n1. `codeql_test_run` \u2014 run tests and compare against `.expected` files\n2. `codeql_test_accept` \u2014 update `.expected` files when results are verified correct\n3. `codeql_resolve_tests` \u2014 discover and validate test structure\n\n## Related Resources\n\n- `codeql://server/overview` \u2014 MCP server orientation guide\n- `codeql://server/queries` \u2014 Bundled tools queries (PrintAST, PrintCFG, CallGraphFrom, CallGraphTo)\n- `codeql://server/tools` \u2014 Complete tool reference\n- `codeql://templates/security` \u2014 Security query templates\n- `codeql://learning/test-driven-development` \u2014 TDD workflow for CodeQL queries\n';
|
|
63045
|
+
|
|
63046
|
+
// src/resources/performance-patterns.md
|
|
63047
|
+
var performance_patterns_default = '# Performance Optimization Patterns\n\nThis resource describes how to evaluate and improve the performance of CodeQL queries using the MCP server\'s profiling tools. Rather than prescribing generic optimization rules, it focuses on using the `profile_codeql_query_from_logs` tool and the `explain_codeql_query` prompt to make evidence-based performance improvements.\n\n## Primary Performance Tool: `profile_codeql_query_from_logs`\n\nThe `profile_codeql_query_from_logs` tool is the primary means of evaluating the actual performance of a CodeQL query. It parses existing CodeQL evaluator logs into a structured performance profile without re-running the query.\n\n### Workflow\n\n1. **Run the query**: Use `codeql_query_run` with `evaluationOutput` set to a directory path. This generates evaluator log files.\n2. **Generate a log summary**: Use `codeql_generate_log-summary` to create a human-readable summary of the evaluator log.\n3. **Profile**: Use `profile_codeql_query_from_logs` to parse the evaluator log into a structured performance profile identifying expensive predicates, pipeline stages, and tuple counts.\n4. **Identify bottlenecks**: Review the profile output for predicates with high evaluation times or unexpectedly large result sets.\n5. **Refine**: Modify the query to address identified bottlenecks, then re-run and re-profile to verify improvements.\n\n### What the Profile Shows\n\n- **Predicate evaluation times** \u2014 which predicates are the most expensive\n- **Tuple counts** \u2014 how many intermediate results each predicate produces\n- **Pipeline stages** \u2014 the internal evaluation plan chosen by the CodeQL engine\n- **RA (relational algebra) operations** \u2014 join orders, aggregation steps, and recursive evaluations\n\n## Using `explain_codeql_query` for Performance Understanding\n\nThe `explain_codeql_query` prompt generates a detailed explanation of a query, including Mermaid evaluation diagrams that visualize the data flow and evaluation order. This is useful for understanding _why_ a query may be slow before profiling.\n\n## Key Performance Concepts\n\nThe following concepts are relevant when interpreting profiling output. Verify these against actual profiling data rather than applying them blindly.\n\n### Large Intermediate Result Sets\n\nWhen a predicate produces significantly more tuples than expected, it may indicate:\n\n- Missing or insufficiently restrictive filter conditions in the `where` clause\n- A cross-product between two large relations that should be joined more tightly\n\n**How to detect**: Look for predicates in the profile output with high tuple counts relative to their expected output size.\n\n### Recursive Predicate Costs\n\nRecursive predicates (e.g., transitive closures via `+` or `*`) can be expensive when the underlying relation is large. The profiler shows iteration counts and per-iteration tuple growth.\n\n**How to detect**: Look for recursive predicates with many iterations or high per-iteration costs in the profile output.\n\n### Join Order Sensitivity\n\nThe CodeQL evaluator chooses a join order for predicates in the `where` clause. In some cases, the chosen order may not be optimal.\n\n**How to detect**: Look for pipeline stages where a large intermediate result is produced before being filtered down. The profiler shows tuple counts at each stage.\n\n### Improving "Performance" \u2014 Two Dimensions\n\nThe word "performance" for CodeQL queries has two meanings:\n\n1. **Runtime efficiency** \u2014 how fast the query evaluates. Addressed by reducing tuple counts, improving join orders, and simplifying recursive predicates.\n2. **Result quality** \u2014 how accurate the query\'s output is (precision and recall). Addressed by refining source/sink/sanitizer definitions, adding or removing filter conditions, and testing against diverse codebases.\n\nThe `profile_codeql_query_from_logs` tool addresses runtime efficiency. For result quality, use the `run_query_and_summarize_false_positives` prompt and the `sarif_rank_false_positives` / `sarif_rank_true_positives` prompts.\n\n## Performance Review for GitHub Actions CodeQL Scans\n\nWhen reviewing CodeQL performance in the context of GitHub Actions CI/CD scans, key areas to examine include:\n\n### Code Exclusion\n\nExcluding non-essential files from analysis (vendored dependencies, generated code, test files) is one of the most impactful performance improvements. Any interpreted language or compiled language using `build-mode: none` can use a `paths-ignore` array in the CodeQL configuration file to exclude paths.\n\n### Hardware Sizing\n\nRecommended runner sizes based on lines of code:\n\n- Small (< 100K lines): 8 GB RAM, 2 cores\n- Medium (100K\u20131M lines): 16 GB RAM, 4\u20138 cores\n- Large (> 1M lines): 64 GB RAM, 8 cores\n\n### Monorepo Splitting\n\nFor monorepos with multiple independent applications separated by process/network boundaries, consider splitting CodeQL scans by application. This reduces database size and enables parallel scanning via Actions matrix strategies.\n\n## Related Tools and Prompts\n\n| Tool / Prompt | Purpose |\n| ------------------------------------------------ | -------------------------------------------------------- |\n| `profile_codeql_query_from_logs` | Profile from existing evaluator logs (no re-run needed) |\n| `codeql_generate_log-summary` | Generate a human-readable evaluator log summary |\n| `codeql_query_run` | Execute a query (set `evaluationOutput` to capture logs) |\n| `explain_codeql_query` prompt | Understand query evaluation flow with Mermaid diagrams |\n| `run_query_and_summarize_false_positives` prompt | Assess result quality (precision) |\n\n## Related Resources\n\n- `codeql://server/overview` \u2014 MCP server orientation guide\n- `codeql://learning/query-basics` \u2014 Query structure and compilation tools\n- `codeql://server/tools` \u2014 Complete tool reference\n- `codeql://learning/test-driven-development` \u2014 TDD workflow for iterative query improvement\n';
|
|
63048
|
+
|
|
63049
|
+
// src/resources/ql-test-driven-development.md
|
|
63050
|
+
var ql_test_driven_development_default = "# Test-Driven Development for CodeQL Queries\n\nThis resource explains the theory and value of test-driven development (TDD) for CodeQL queries, and how the MCP server's tools and prompts support the TDD workflow. It is a conceptual overview \u2014 for step-by-step guided workflows, use the `test_driven_development`, `ql_tdd_basic`, or `ql_tdd_advanced` prompts.\n\n## Why TDD for CodeQL?\n\nCodeQL queries are programs that search for patterns in source code. Like any program, they can have bugs: false positives (flagging safe code), false negatives (missing vulnerable code), and runtime performance issues. TDD addresses all three by establishing a feedback loop between expected and actual behavior.\n\n### Why TDD Makes LLMs More Effective\n\nLLMs generating CodeQL queries face two challenges:\n\n1. **Syntactic correctness** \u2014 QL has unique syntax (classes, predicates, `exists`, aggregates) that differs from mainstream languages. Compilation via `codeql_query_compile` catches syntax errors early.\n2. **Semantic correctness** \u2014 A query that compiles may still produce wrong results. Test cases with `.expected` files provide ground truth that the LLM can compare against, enabling iterative refinement.\n\nTDD provides the LLM with a concrete, automated signal (tests pass / tests fail) at every iteration, replacing guesswork with evidence. This is especially valuable for data flow and taint tracking queries where the correctness of source/sink/sanitizer definitions can only be verified by running the query against representative code.\n\n## The TDD Cycle\n\n```text\n\u250C\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510\n\u2502 1. Write Tests \u2502 \u2190 Define expected behavior through test cases\n\u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252C\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518\n \u25BC\n\u250C\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510\n\u2502 2. Run (Red) \u2502 \u2190 Verify tests fail (no query logic yet)\n\u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252C\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518\n \u25BC\n\u250C\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510\n\u2502 3. Implement \u2502 \u2190 Write minimal query logic to pass tests\n\u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252C\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518\n \u25BC\n\u250C\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510\n\u2502 4. Run (Green) \u2502 \u2190 Verify tests pass\n\u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252C\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518\n \u25BC\n\u250C\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510\n\u2502 5. Refactor \u2502 \u2190 Improve query while keeping tests green\n\u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252C\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518\n \u25BC\n\u250C\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510\n\u2502 6. Repeat \u2502 \u2190 Add more tests for additional scenarios\n\u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518\n```\n\n## The Value of AST Data in Test Code\n\nA critical step in the TDD workflow is running `PrintAST` on test source code before writing the query. The AST output reveals how the CodeQL database represents the test code \u2014 which QL classes correspond to which source constructs, and which predicates are available for matching.\n\nWithout AST data, the LLM must guess which classes and predicates to use, leading to trial-and-error. With AST data, the LLM can:\n\n- **Map source patterns to QL classes**: See exactly which QL class represents a `for` loop, a method call, or an assignment\n- **Discover available predicates**: Learn what methods are available on each AST node type\n- **Write precise `from`/`where` clauses**: Use the correct class names and predicate calls from the start\n\nUse `codeql_query_run` with `queryName=\"PrintAST\"` to generate AST data for test source files. The `ql_tdd_advanced` prompt guides this step in detail.\n\n## MCP Tools for TDD\n\n| Step | Tool | Purpose |\n| ------------ | ------------------------------------- | ---------------------------------------------------- |\n| Scaffold | `create_codeql_query` | Generate query, test, and `.qlref` files |\n| Dependencies | `codeql_pack_install` | Install pack dependencies for src and test packs |\n| Extract | `codeql_test_extract` | Create a test database from test source files |\n| AST Analysis | `codeql_query_run` (PrintAST) | Understand test code structure via AST |\n| CFG Analysis | `codeql_query_run` (PrintCFG) | Understand control flow (advanced) |\n| Call Graph | `codeql_query_run` (CallGraphFrom/To) | Trace call relationships (advanced) |\n| Compile | `codeql_query_compile` | Validate query syntax before testing |\n| Test | `codeql_test_run` | Run tests and compare against `.expected` |\n| Accept | `codeql_test_accept` | Update `.expected` when results are verified correct |\n| Profile | `profile_codeql_query_from_logs` | Analyze query performance from evaluator logs |\n| Format | `codeql_query_format` | Auto-format query source code |\n| Metadata | `codeql_resolve_metadata` | Validate query metadata annotations |\n\n## MCP Prompts for TDD\n\n| Prompt | When to Use |\n| ------------------------- | ---------------------------------------------------------- |\n| `test_driven_development` | End-to-end TDD workflow with required `language` parameter |\n| `ql_tdd_basic` | Standalone TDD checklist (all parameters optional) |\n| `ql_tdd_advanced` | Extended TDD with AST/CFG/call graph analysis |\n| `tools_query_workflow` | Focused exploration of code structure via tool queries |\n| `explain_codeql_query` | Understand an existing query's logic before modifying it |\n\n## Writing Effective Test Cases\n\n### Structure\n\nEach test directory contains:\n\n- **Test source code** (e.g., `test.js`) \u2014 code that the query will analyze\n- **`.qlref` file** \u2014 points to the query being tested\n- **`.expected` file** \u2014 the expected query output\n\n### Best Practices\n\n1. **Include both positive and negative cases**: Write code that should trigger the query (vulnerable patterns) and code that should not (safe patterns)\n2. **Start simple**: Begin with the most obvious positive and negative cases, then add edge cases\n3. **Use realistic code**: Test against code patterns that occur in real-world projects\n4. **One concept per test directory**: Each test should verify one specific behavior\n5. **Document intent**: Use comments in test code to explain why each case should or should not match\n\n### Example Test Structure\n\n```text\ntest/SqlInjection/\n\u251C\u2500\u2500 SqlInjection.qlref # Points to src/SqlInjection/SqlInjection.ql\n\u251C\u2500\u2500 test.py # Test source code\n\u2514\u2500\u2500 SqlInjection.expected # Expected results\n```\n\nThe `.expected` file contains one line per query result, matching the `select` clause output.\n\n## Related Resources\n\n- `codeql://server/overview` \u2014 MCP server orientation and quick-start guide\n- `codeql://learning/query-basics` \u2014 Query structure, metadata, and compilation reference\n- `codeql://server/tools` \u2014 Complete tool reference\n- `codeql://templates/security` \u2014 Security query templates with TDD workflow\n- `codeql://patterns/performance` \u2014 Performance profiling tools\n- `codeql://languages/{language}/ast` \u2014 Language-specific AST class reference\n- `codeql://languages/{language}/security` \u2014 Language-specific security patterns\n";
|
|
63051
|
+
|
|
63052
|
+
// src/resources/codeql-query-unit-testing.md
|
|
63053
|
+
var codeql_query_unit_testing_default = '# CodeQL Query Unit Testing\n\nGuide for creating and running unit tests for CodeQL queries. For the broader TDD workflow (write tests, implement, iterate), see the `test_driven_development` resource and `ql_tdd_basic` / `ql_tdd_advanced` prompts.\n\n## Test Directory Layout\n\nThere is no one single way to arrange CodeQL unit tests, though there are some commonalities.\n\nFor a recommended setup that uses separate "qlpacks" for CodeQL queries versus tests, a given CodeQL query and associated unit test may be laid out on the filesystem like:\n\n```text\n<query-pack-root>/<optional-queries-subdir>/{QueryName}/\n\u251C\u2500\u2500 {QueryName}.{md,qhelp} # Recommended query documentation file\n\u251C\u2500\u2500 {QueryName}.ql # Required query implementation file\n\u2514\u2500\u2500 {QueryName}.qll # Optional query-specific library file\n<test-pack-root>/<optional-tests-subdir>/{QueryOrTestName}/\n\u251C\u2500\u2500 {QueryName}.qlref # qlref file contents point to the path of the query, relative to <query-pack-root>\n\u251C\u2500\u2500 Example1.{ext} # Test source code (positive + negative cases)\n\u251C\u2500\u2500 {QueryName}.actual # Actual test results; created dynamically via `codeql_test_run` tool\n\u251C\u2500\u2500 {QueryName}.expected # Expected query results; defined prior to calling `codeql_test_run` tool\n\u2514\u2500\u2500 {QueryName}.testproj/ # Test database; auto-created by `codeql_test_extract` or `codeql_test_run` tools\n```\n\n## File Extensions by Language\n\n| Language | Test source extension(s) | Notes |\n| ---------- | ------------------------ | ---------------------------------------- |\n| C/C++ | `.cpp`, `.c`, `.h` | Use header files for shared declarations |\n| C# | `.cs` | |\n| Go | `.go` | Must include `package` declaration |\n| Java | `.java` | Must include `class` matching filename |\n| JavaScript | `.js` | Use `.ts` for TypeScript |\n| Python | `.py` | |\n| Ruby | `.rb` | |\n| Swift | `.swift` | |\n\n## Creating a Test\n\n### 1. Query Reference File (`{QueryName}.qlref`)\n\nSingle line with the path to the query, relative to the query pack root:\n\n```sh\nsrc/{QueryName}/{QueryName}.ql\n```\n\n### 2. Test Source Code\n\nWrite test source files containing:\n\n- **Positive cases**: Code patterns the query **should** detect\n- **Negative cases**: Safe code the query **should not** flag\n- **Edge cases**: Boundary conditions and unusual but valid patterns\n\nAdd comments to describe what each section tests.\n\n### 3. Expected Results (`{QueryName}.expected`)\n\nTabular format matching the query\'s `select` clause columns:\n\n```text\n| file | line | col | endLine | endCol | message |\n| Example1.js | 5 | 1 | 7 | 2 | Function: myFunc |\n```\n\nLeave the file empty or create it with a placeholder initially \u2014 run the query to generate actual results, then baseline with `codeql_test_accept`.\n\n## Language-Specific Notes\n\n### C/C++\n\n- Use an `options` file in the test directory to set the C++ standard (e.g., `--std=c++17`).\n- Include header files with include guards when testing patterns that span headers.\n- Test pointer/reference, smart pointer, template instantiation, and STL container patterns as relevant.\n- Key AST nodes: `Function`, `MemberFunction`, `Constructor`, `Class`, `Struct`, `PointerDereferenceExpr`, `FunctionCall`, `NewExpr`, `DeleteExpr`, `TemplateClass`, `TemplateFunction`.\n\n### C\\#\n\n- Always include required `using` statements so test code compiles.\n- Test .NET-specific patterns: LINQ, async/await, properties, pattern matching, ASP.NET controllers, Entity Framework.\n- Key AST nodes: `Class`, `Method`, `Property`, `MethodCall`, `QueryExpr`, `AwaitExpr`, `Annotation`.\n\n### Go\n\n- Every test file must have a `package` declaration (typically `package main`).\n- Test goroutine, channel, interface assertion, and error-handling patterns as relevant.\n- Key AST nodes: `Function`, `CallExpr`, `SelectorExpr`, `GoStmt`, `SendStmt`, `TypeAssertExpr`.\n\n### Java\n\n- Each `.java` test file must contain a `public class` matching the filename.\n- Test annotations, generics, lambda expressions, streams, and try-with-resources as relevant.\n- Supports Spring, Servlet, and Jakarta EE framework patterns.\n- Key AST nodes: `Method`, `Constructor`, `Class`, `MethodCall`, `LambdaExpr`, `MethodReference`, `Annotation`, `TypeVariable`.\n\n### JavaScript / TypeScript\n\n- Both CommonJS (`require`) and ES modules (`import`) are supported.\n- Use `.ts` for TypeScript; JSX is supported in `.jsx`/`.tsx` files.\n- Test browser APIs (DOM, `document.write`), Node.js APIs (`child_process`, `fs`), and framework patterns (Express, React) as relevant.\n- Test async/await, Promises, and callback patterns.\n- Key AST nodes: `Function`, `ArrowFunctionExpr`, `CallExpr`, `MethodCallExpr`, `PropAccess`, `AwaitExpr`, `TemplateLiteral`.\n\n### Python\n\n- Supports both Python 2 and Python 3 syntax.\n- Test decorators, async/await, type hints, and dynamic code execution (`eval`, `exec`) as relevant.\n- Test framework patterns: Django (ORM, templates), Flask (request, routing), FastAPI (dependency injection).\n- Key AST nodes: `FunctionDef`, `ClassDef`, `Call`, `Attribute`, `Name`, `Lambda`, `Await`.\n\n### Ruby\n\n- Test metaprogramming (`send`, `define_method`, `eval`), blocks/lambdas, and string interpolation as relevant.\n- Test Rails patterns (params, ActiveRecord, ActionView) and gem-specific APIs (Sinatra, Grape).\n- Note: `asExpr()` in Ruby returns `CfgNodes::ExprCfgNode` (CFG node), not an AST node; use `.getExpr()` to get the AST node.\n- Key AST nodes: `MethodCall`, `Block`, `StringInterpolation`, `ConstantReadAccess`.\n\n### Swift\n\n- Requires macOS with Xcode installed for test extraction.\n- Supports Swift 5.4 through 6.2.\n- Test iOS/macOS framework patterns: Foundation, UIKit, Security, CryptoKit, WKWebView.\n- Test actors, property wrappers, async/await, and result builders as relevant.\n- Key AST nodes: `ClassDecl`, `StructDecl`, `FuncDecl`, `CallExpr`, `MemberRefExpr`, `ClosureExpr`, `GuardStmt`.\n\n## MCP Tool Workflow\n\n| Step | Tool | Purpose |\n| --------------------- | ----------------------------- | ----------------------------------------- |\n| Create test files | `create_codeql_query` | Scaffold query + test + `.qlref` |\n| Install dependencies | `codeql_pack_install` | Install pack dependencies |\n| Extract test database | `codeql_test_extract` | Build test DB from source files |\n| Inspect AST | `codeql_query_run` (PrintAST) | Understand how test code is represented |\n| Run tests | `codeql_test_run` | Compare actual vs. expected results |\n| Accept results | `codeql_test_accept` | Baseline correct results into `.expected` |\n';
|
|
63054
|
+
|
|
63055
|
+
// src/resources/security-templates.md
|
|
63056
|
+
var security_templates_default = '# Security Query Templates\n\nThis resource provides actionable security query templates for multiple languages and vulnerability classes. Each template shows the recommended query structure, explains how to adapt it, and references the MCP tools and TDD workflow to use during development.\n\n## General Workflow for Security Queries\n\n1. **Scaffold**: Use `create_codeql_query` to generate the query, test, and `.qlref` files\n2. **Write tests**: Create test source code with vulnerable (positive) and safe (negative) examples\n3. **Analyze AST**: Use `codeql_query_run` with `queryName="PrintAST"` to understand code representation\n4. **Implement**: Write the query using the taint tracking / data flow template below\n5. **Compile**: Use `codeql_query_compile` to validate syntax\n6. **Test**: Use `codeql_test_run` to run tests; iterate until all pass\n7. **Accept**: Use `codeql_test_accept` to baseline correct results\n\nSee the `test_driven_development` or `ql_tdd_basic` prompts for guided step-by-step workflows.\n\n## Taint Tracking Template (v2 API)\n\nMost security queries use taint tracking to find data flowing from untrusted sources to dangerous sinks. The standard template structure for all languages is:\n\n```ql\n/**\n * @name <Vulnerability Name>\n * @description <Description of the vulnerability>\n * @kind path-problem\n * @problem.severity error\n * @security-severity <CVSS score>\n * @precision high\n * @id <lang>/<vulnerability-id>\n * @tags security\n * external/cwe/cwe-<NNN>\n */\n\nimport <language>\n\nmodule MyFlowConfig implements DataFlow::ConfigSig {\n predicate isSource(DataFlow::Node source) {\n // Define untrusted input sources\n }\n\n predicate isSink(DataFlow::Node sink) {\n // Define dangerous sinks\n }\n\n predicate isBarrier(DataFlow::Node node) {\n // Define sanitizers that make data safe (optional)\n }\n}\n\nmodule MyFlow = TaintTracking::Global<MyFlowConfig>;\n\nimport MyFlow::PathGraph\n\nfrom MyFlow::PathNode source, MyFlow::PathNode sink\nwhere MyFlow::flowPath(source, sink)\nselect sink.getNode(), source, sink, "Tainted data from $@ reaches this sink.",\n source.getNode(), "user-provided value"\n```\n\n### Adapting the Template\n\n1. **Choose sources**: Identify where untrusted data enters (HTTP parameters, file reads, environment variables)\n2. **Choose sinks**: Identify where data becomes dangerous (SQL queries, command execution, HTML output)\n3. **Add sanitizers**: Identify validation or encoding functions that neutralize the threat\n4. **Adjust metadata**: Set appropriate `@security-severity`, `@id`, and CWE tags\n\n## Source, Sink, and Sanitizer Patterns\n\n### Defining Sources\n\nSources represent entry points for untrusted data. The most common pattern uses `RemoteFlowSource`:\n\n```ql\npredicate isSource(DataFlow::Node source) {\n source instanceof RemoteFlowSource\n}\n```\n\n### Defining Sinks\n\nSinks are locations where untrusted data causes harm. Identify the dangerous API call and pin the taint to the relevant argument position:\n\n```ql\npredicate isSink(DataFlow::Node sink) {\n exists(CallExpr dangerousCall |\n dangerousCall.getTarget().hasName("vulnerableFunction") and\n sink.asExpr() = dangerousCall.getArgument(0)\n )\n}\n```\n\n### Defining Sanitizers (Barriers)\n\nSanitizers stop taint propagation when data is validated or encoded. Return `true` for nodes where the taint is neutralized:\n\n```ql\npredicate isBarrier(DataFlow::Node node) {\n exists(CallExpr validationCall |\n validationCall.getTarget().hasName("sanitize") and\n node.asExpr() = validationCall\n )\n}\n```\n\n## Language-Specific Guidance\n\nEach language has pre-built security libraries in the CodeQL standard library. Import these instead of writing source/sink definitions from scratch when possible.\n\n### Go\n\n- **SQL Injection**: Import `semmle.go.security.SqlInjection` \u2014 provides `SqlInjection::Flow` module with pre-defined sources and sinks. Tag with CWE-089, severity 8.8.\n- **Command Injection**: Import `semmle.go.security.CommandInjection`.\n- See `codeql://languages/go/security` for Go-specific framework modeling.\n\n### JavaScript / TypeScript\n\n- **DOM-based XSS**: Import `semmle.javascript.security.dataflow.DomBasedXss` \u2014 provides `DomBasedXss::Flow` module. Tag with CWE-079, severity 6.1.\n- **SQL Injection**: Import `semmle.javascript.security.dataflow.SqlInjection`.\n- See `codeql://languages/javascript/security` for JavaScript-specific patterns.\n\n### Python\n\n- **Command Injection**: Import `semmle.python.security.dataflow.CommandInjection`. Tag with CWE-078, severity 9.8.\n- **SQL Injection**: Import `semmle.python.security.dataflow.SqlInjection`.\n- See `codeql://languages/python/security` for Python-specific patterns.\n\n### Java / Kotlin\n\n- **SQL Injection**: Import `semmle.java.security.SqlInjectionQuery` \u2014 provides `SqlInjectionFlow` module. Tag with CWE-089, severity 8.8.\n- **SSRF**: Import `semmle.java.security.RequestForgery`.\n\n### C# (.NET)\n\n- **Path Traversal**: Import `semmle.csharp.security.dataflow.PathInjection`. Tag with CWE-022, severity 7.5.\n- **SQL Injection**: Import `semmle.csharp.security.dataflow.SqlInjection`.\n- See `codeql://languages/csharp/security` for C#-specific patterns.\n\n### C / C++\n\n- **Buffer Overflow**: Import `semmle.code.cpp.security.BufferAccess`. Tag with CWE-120, severity 9.8.\n- See `codeql://languages/cpp/security` for C/C++-specific patterns.\n\n## Vulnerability Classes Reference\n\n| Vulnerability | CWE | Typical Sources | Typical Sinks |\n| ----------------- | ------- | ---------------------------------- | ----------------------------- |\n| SQL Injection | CWE-089 | HTTP parameters, form data | Database query functions |\n| XSS | CWE-079 | HTTP parameters, URL data | HTML output, DOM writes |\n| Command Injection | CWE-078 | HTTP parameters, config files | `exec`, `system`, `popen` |\n| Path Traversal | CWE-022 | HTTP parameters, file names | File system access functions |\n| SSRF | CWE-918 | HTTP parameters, user URLs | HTTP client request functions |\n| Code Injection | CWE-094 | HTTP parameters, deserialized data | `eval`, template engines |\n| LDAP Injection | CWE-090 | HTTP parameters | LDAP query functions |\n| XML Injection | CWE-091 | HTTP parameters | XML parsers, XPath queries |\n\n## Related Resources\n\n- `codeql://learning/query-basics` \u2014 Query structure and metadata reference\n- `codeql://learning/test-driven-development` \u2014 TDD workflow for developing queries\n- `codeql://patterns/performance` \u2014 Performance optimization guidance\n- `codeql://languages/{language}/security` \u2014 Language-specific security patterns and framework modeling\n';
|
|
63057
|
+
|
|
63058
|
+
// src/resources/server-overview.md
|
|
63059
|
+
var server_overview_default = '# CodeQL Development MCP Server \u2014 Getting Started\n\nThis resource is the primary onboarding guide for LLM clients connecting to the CodeQL Development MCP Server. It explains what the server provides, which tools and prompts are available, and how to orchestrate common workflows.\n\n## What This Server Does\n\nThe CodeQL Development MCP Server wraps the CodeQL CLI and supporting utilities behind the Model Context Protocol (MCP). It exposes **tools** (executable actions), **prompts** (reusable workflow templates), and **resources** (reference material) that enable an LLM to develop, test, and analyze CodeQL queries without direct shell access.\n\n## Available Resources\n\nRead these resources via `resources/read` to deepen your understanding:\n\n| URI | Purpose |\n| --------------------------------------------- | --------------------------------------------------- |\n| `codeql://server/overview` | This guide \u2014 MCP server orientation |\n| `codeql://server/queries` | Bundled tools queries (PrintAST, PrintCFG, etc.) |\n| `codeql://server/tools` | Complete default tool reference |\n| `codeql://server/prompts` | Complete prompt reference |\n| `codeql://learning/query-basics` | QL query writing reference (syntax, metadata, etc.) |\n| `codeql://learning/test-driven-development` | TDD theory and workflow for CodeQL |\n| `codeql://templates/security` | Security query templates (multi-language) |\n| `codeql://patterns/performance` | Performance profiling and optimization |\n| `codeql://guides/query-unit-testing` | Guide for creating and running CodeQL query tests |\n| `codeql://guides/dataflow-migration-v1-to-v2` | Migrating from v1 to v2 dataflow API |\n| `codeql://languages/{language}/ast` | Language-specific AST class reference |\n| `codeql://languages/{language}/security` | Language-specific security patterns |\n\n## Quick-Start Workflows\n\n### 1. Create a New Query (TDD Approach)\n\nUse the `test_driven_development` prompt (or `ql_tdd_basic` / `ql_tdd_advanced`):\n\n1. `create_codeql_query` \u2014 scaffold query, test files, and `.qlref`\n2. `codeql_pack_install` \u2014 install pack dependencies\n3. Write test code with positive and negative cases\n4. `codeql_test_run` \u2014 run tests (expect failure initially)\n5. Implement query logic\n6. `codeql_query_compile` \u2014 validate syntax\n7. `codeql_test_run` \u2014 iterate until tests pass\n8. `codeql_test_accept` \u2014 accept correct results as baseline\n\n### 2. Understand Code Structure\n\nUse the `tools_query_workflow` prompt:\n\n1. `codeql_query_run` with `queryName="PrintAST"` \u2014 visualize the AST\n2. `codeql_query_run` with `queryName="PrintCFG"` \u2014 visualize control flow\n3. `codeql_query_run` with `queryName="CallGraphFrom"` / `"CallGraphTo"` \u2014 trace call relationships\n\n### 3. Analyze Query Quality\n\n1. `codeql_database_analyze` \u2014 run queries against a database\n2. `profile_codeql_query` or `profile_codeql_query_from_logs` \u2014 analyze performance\n3. `run_query_and_summarize_false_positives` prompt \u2014 assess precision\n4. `sarif_rank_false_positives` / `sarif_rank_true_positives` prompts \u2014 rank results\n\n### 4. Iterative Development with LSP\n\nUse the `ql_lsp_iterative_development` prompt:\n\n1. `codeql_lsp_completion` \u2014 get code completions while writing QL\n2. `codeql_lsp_definition` \u2014 navigate to symbol definitions\n3. `codeql_lsp_references` \u2014 find all references to a symbol\n4. `codeql_lsp_diagnostics` \u2014 real-time syntax and semantic validation\n\n## Tool Categories\n\nThe server provides default tools across these categories (see `codeql://server/tools` for the full reference):\n\n- **CodeQL CLI tools** \u2014 Database creation, query compilation, execution, result decoding, pack management\n- **LSP tools** \u2014 Code completion, go-to-definition, find references, diagnostics\n- **Query development tools** \u2014 Scaffolding, validation, profiling, quick evaluation, database registration\n\n## Prompt Categories\n\nThe server provides **11 prompts** (see `codeql://server/prompts` for the full reference):\n\n- **Test-driven development** \u2014 `test_driven_development`, `ql_tdd_basic`, `ql_tdd_advanced`\n- **Code understanding** \u2014 `tools_query_workflow`, `explain_codeql_query`\n- **Iterative development** \u2014 `ql_lsp_iterative_development`\n- **Documentation and quality** \u2014 `document_codeql_query`, `run_query_and_summarize_false_positives`, `sarif_rank_false_positives`, `sarif_rank_true_positives`\n- **Workshop creation** \u2014 `workshop_creation_workflow`\n\n## Key Concepts\n\n- **CodeQL database**: A relational representation of source code created by `codeql_database_create`. All queries execute against a database.\n- **QL pack**: A directory containing `codeql-pack.yml` with query or library code. Use `codeql_pack_install` to resolve dependencies.\n- **`.qlref` file**: A test reference that points from a test directory to the query being tested.\n- **`.expected` file**: The expected output of a query test. Use `codeql_test_accept` to update it when results are correct.\n- **BQRS**: Binary Query Result Sets \u2014 the native output format of `codeql_query_run`. Decode with `codeql_bqrs_decode` or interpret with `codeql_bqrs_interpret`.\n- **SARIF**: Static Analysis Results Interchange Format \u2014 the standard output format for `codeql_database_analyze`.\n\n## Supported Languages\n\nThe server supports CodeQL queries for: `actions`, `cpp`, `csharp`, `go`, `java`, `javascript`, `python`, `ruby`, `swift`.\n';
|
|
63060
|
+
|
|
63061
|
+
// src/resources/server-prompts.md
|
|
63062
|
+
var server_prompts_default = "# MCP Server Prompts\n\nThis resource provides a complete reference of the prompts exposed by the CodeQL Development MCP Server. Prompts are reusable workflow templates that guide the LLM through common CodeQL development tasks. Invoke a prompt via the MCP `prompts/get` protocol.\n\n## Prompt Reference\n\n| Prompt | Description |\n| ----------------------------------------- | ------------------------------------------------------------------------------------------------------------- |\n| `document_codeql_query` | Create or update standardized markdown documentation for a CodeQL query |\n| `explain_codeql_query` | Generate a detailed explanation of a CodeQL query with Mermaid evaluation diagrams |\n| `ql_lsp_iterative_development` | Iterative CodeQL query development using LSP tools for completion, navigation, and validation |\n| `ql_tdd_advanced` | Advanced test-driven CodeQL development with AST visualization, control flow, and call graph analysis |\n| `ql_tdd_basic` | Test-driven CodeQL query development checklist \u2014 write tests first, implement query, iterate until tests pass |\n| `run_query_and_summarize_false_positives` | Run a CodeQL query and summarize its false positives by root cause |\n| `sarif_rank_false_positives` | Analyze SARIF results to identify and rank likely false positives |\n| `sarif_rank_true_positives` | Analyze SARIF results to identify and rank likely true positives |\n| `test_driven_development` | End-to-end test-driven development workflow for CodeQL queries using MCP tools |\n| `tools_query_workflow` | Guide for using PrintAST, PrintCFG, CallGraphFrom, and CallGraphTo tool queries to understand code structure |\n| `workshop_creation_workflow` | Guide for creating multi-exercise CodeQL query development workshops from production-grade queries |\n\n## Prompt Categories\n\n### Test-Driven Development\n\n- **`test_driven_development`** \u2014 The primary TDD prompt. Requires a `language` parameter and optionally accepts `queryName`. Loads the `ql-tdd-basic.prompt.md` template and walks through the complete TDD cycle: scaffold \u2192 write tests \u2192 implement \u2192 compile \u2192 test \u2192 iterate.\n- **`ql_tdd_basic`** \u2014 A standalone TDD checklist. All parameters are optional. Covers the core loop: write test cases, implement the query, run tests, iterate.\n- **`ql_tdd_advanced`** \u2014 Extends basic TDD with AST visualization (`PrintAST`), control flow graph analysis (`PrintCFG`), and call graph exploration (`CallGraphFrom`, `CallGraphTo`). Optionally accepts a `database` path for immediate analysis.\n\n### Code Understanding\n\n- **`tools_query_workflow`** \u2014 Orchestrates the four built-in tool queries (PrintAST, PrintCFG, CallGraphFrom, CallGraphTo) to explore how source code is represented in a CodeQL database. Requires `language` and `database` parameters.\n- **`explain_codeql_query`** \u2014 Produces a verbal explanation of a query's logic and generates Mermaid diagrams showing the evaluation flow. Requires `queryPath` and `language`.\n\n### Iterative Development\n\n- **`ql_lsp_iterative_development`** \u2014 Combines LSP-based code completions (`codeql_lsp_completion`), go-to-definition (`codeql_lsp_definition`), find-references (`codeql_lsp_references`), and diagnostics (`codeql_lsp_diagnostics`) for an interactive development loop.\n\n### Documentation and Quality\n\n- **`document_codeql_query`** \u2014 Generates standardized markdown documentation as a sibling `.md` file to a query. Requires `queryPath` and `language`.\n- **`run_query_and_summarize_false_positives`** \u2014 Runs a CodeQL query on a database and groups results into false-positive categories by root cause.\n- **`sarif_rank_false_positives`** / **`sarif_rank_true_positives`** \u2014 Analyze SARIF output to assess query precision by ranking results as likely true or false positives.\n\n### Workshop Creation\n\n- **`workshop_creation_workflow`** \u2014 Guides the creation of multi-exercise workshops that teach CodeQL query development. Requires `queryPath` and `language`, optionally accepts `workshopName` and `numStages`.\n\n## Related Resources\n\n- `codeql://server/overview` \u2014 MCP server orientation guide\n- `codeql://server/tools` \u2014 Complete tool reference\n- `codeql://learning/test-driven-development` \u2014 TDD theory and workflow overview\n";
|
|
63063
|
+
|
|
63064
|
+
// src/resources/server-queries.md
|
|
63065
|
+
var server_queries_default = '# MCP Server Bundled Queries\n\nThis resource describes the tools queries bundled with the CodeQL Development MCP Server. These queries run via `codeql_query_run` and provide structural insight into how source code is represented in a CodeQL database. Use them to understand code structure before writing detection queries.\n\nFor general QL query writing guidance (syntax, metadata, `from`/`where`/`select`, testing conventions), see `codeql://learning/query-basics`.\n\n## Bundled Tools Queries\n\nThe server bundles four tools queries that operate on CodeQL databases:\n\n| Query | Purpose | Output Format |\n| --------------- | ------------------------------------------------- | ------------------------- |\n| `PrintAST` | Visualize the Abstract Syntax Tree of source code | `@kind graph` (graphtext) |\n| `PrintCFG` | Visualize the Control Flow Graph of a function | `@kind graph` (graphtext) |\n| `CallGraphFrom` | Show all functions called FROM a given function | `@kind graph` (graphtext) |\n| `CallGraphTo` | Show all call sites that call TO a given function | `@kind graph` (graphtext) |\n\nAll four queries use `@kind graph` metadata and produce output in graphtext format.\n\n## PrintAST\n\n**Purpose**: Outputs a hierarchical representation of the Abstract Syntax Tree showing parent-child relationships between declarations, statements, and expressions.\n\n**When to use**: Before writing any CodeQL query, run `PrintAST` on your test source code to understand which QL classes represent which source constructs and which predicates are available for matching.\n\n**How to run**:\n\n```text\nTool: codeql_query_run\nParameters:\n queryName: "PrintAST"\n queryLanguage: "<language>"\n database: "<path-to-database>"\n sourceFiles: "<comma-separated-filenames>" (optional \u2014 filter to specific files)\n format: "graphtext"\n interpretedOutput: "<output-directory>"\n```\n\n**Output**: A tree showing each AST node with its QL class name, properties, and position in the hierarchy. This reveals exactly which QL classes and predicates to use in `from`/`where`/`select` clauses.\n\n## PrintCFG\n\n**Purpose**: Produces a Control Flow Graph representation showing the order in which statements and expressions execute, including branching paths.\n\n**When to use**: When writing queries that reason about execution order, reachability, or branching logic (e.g., "is this check always performed before this call?").\n\n**How to run**:\n\n```text\nTool: codeql_query_run\nParameters:\n queryName: "PrintCFG"\n queryLanguage: "<language>"\n database: "<path-to-database>"\n sourceFunction: "<function-name>" (optional \u2014 target a specific function)\n format: "graphtext"\n interpretedOutput: "<output-directory>"\n```\n\n**Output**: Nodes representing CFG basic blocks and edges representing possible execution transitions (successor relationships).\n\n## CallGraphFrom\n\n**Purpose**: Shows all functions called FROM a specified source function \u2014 the outbound call dependencies.\n\n**When to use**: When analyzing what a function does by tracing the functions it invokes. Useful for understanding call chains and identifying potential data flow paths.\n\n**How to run**:\n\n```text\nTool: codeql_query_run\nParameters:\n queryName: "CallGraphFrom"\n queryLanguage: "<language>"\n database: "<path-to-database>"\n sourceFunction: "<function-name>"\n format: "graphtext"\n interpretedOutput: "<output-directory>"\n```\n\n**Output**: A graph showing each call site within the source function and the target function being called.\n\n## CallGraphTo\n\n**Purpose**: Shows all call sites that invoke a specified target function \u2014 the inbound callers.\n\n**When to use**: When performing impact analysis to understand where a function is used, or when identifying all locations that pass data to a particular sink function.\n\n**How to run**:\n\n```text\nTool: codeql_query_run\nParameters:\n queryName: "CallGraphTo"\n queryLanguage: "<language>"\n database: "<path-to-database>"\n targetFunction: "<function-name>"\n format: "graphtext"\n interpretedOutput: "<output-directory>"\n```\n\n**Output**: A graph showing each caller function and the specific call site where the target function is invoked.\n\n## Language Support\n\n| Language | PrintAST | PrintCFG | CallGraphFrom | CallGraphTo |\n| ---------- | :------: | :------: | :-----------: | :---------: |\n| actions | \u2713 | \u2713 | | |\n| cpp | \u2713 | \u2713 | \u2713 | \u2713 |\n| csharp | \u2713 | \u2713 | \u2713 | \u2713 |\n| go | \u2713 | \u2713 | \u2713 | \u2713 |\n| java | \u2713 | \u2713 | \u2713 | \u2713 |\n| javascript | \u2713 | \u2713 | \u2713 | \u2713 |\n| python | \u2713 | \u2713 | \u2713 | \u2713 |\n| ruby | \u2713 | \u2713 | \u2713 | \u2713 |\n| swift | \u2713 | \u2713 | \u2713 | \u2713 |\n\nNote: The `actions` language supports PrintAST and PrintCFG only (no call graph queries).\n\n## Recommended Workflow\n\nUse the `tools_query_workflow` prompt for a guided step-by-step workflow:\n\n1. **Identify or create a database**: Use `list_codeql_databases` or `codeql_database_create`\n2. **Run PrintAST**: Understand how the source code maps to QL classes\n3. **Run PrintCFG**: Understand control flow for the functions of interest\n4. **Run CallGraphFrom / CallGraphTo**: Trace call relationships to identify sources and sinks\n5. **Write detection queries**: Use the insights from steps 2\u20134 to select the right QL classes and predicates\n\n## Related Resources\n\n- `codeql://learning/query-basics` \u2014 QL query writing reference (syntax, metadata, patterns, testing)\n- `codeql://server/overview` \u2014 MCP server orientation guide\n- `codeql://server/tools` \u2014 Complete tool reference\n- `codeql://learning/test-driven-development` \u2014 TDD workflow for CodeQL queries\n- `codeql://languages/{language}/ast` \u2014 Language-specific AST class reference\n';
|
|
63066
|
+
|
|
63067
|
+
// src/resources/server-tools.md
|
|
63068
|
+
var server_tools_default = '# MCP Server Tools\n\nThis resource provides a complete reference of the default tools exposed by the CodeQL Development MCP Server. These tools wrap the CodeQL CLI and supporting utilities, enabling an LLM to develop, test, and analyze CodeQL queries programmatically.\n\n## CodeQL CLI Tools\n\n| Tool | Description |\n| ----------------------------- | ---------------------------------------------------------------------------------------------------------------------------- |\n| `codeql_bqrs_decode` | Decode BQRS result files to human-readable formats (text, csv, json). Supports `--result-set` and `--rows` for pagination |\n| `codeql_bqrs_info` | Get metadata about BQRS result files: result sets, column types, row counts |\n| `codeql_bqrs_interpret` | Interpret BQRS result files according to query metadata and generate output in specified formats (CSV, SARIF, graph formats) |\n| `codeql_database_analyze` | Run queries or query suites against CodeQL databases. Produces evaluator logs, BQRS, and SARIF output |\n| `codeql_database_create` | Create a CodeQL database from source code |\n| `codeql_generate_log-summary` | Create a summary of a structured JSON evaluator event log file |\n| `codeql_generate_query-help` | Generate query help documentation from QLDoc comments |\n| `codeql_pack_install` | Install CodeQL pack dependencies |\n| `codeql_pack_ls` | List CodeQL packs under a local directory path |\n| `codeql_query_compile` | Compile and validate CodeQL queries |\n| `codeql_query_format` | Automatically format CodeQL source code files |\n| `codeql_query_run` | Execute a CodeQL query against a database |\n| `codeql_resolve_database` | Resolve database path and validate database structure |\n| `codeql_resolve_languages` | List installed CodeQL extractor packs |\n| `codeql_resolve_library-path` | Resolve library path for CodeQL queries and libraries |\n| `codeql_resolve_metadata` | Resolve and return key-value metadata pairs from a CodeQL query source file |\n| `codeql_resolve_qlref` | Resolve `.qlref` files to their corresponding query files |\n| `codeql_resolve_queries` | List available CodeQL queries found on the local filesystem |\n| `codeql_resolve_tests` | Resolve the local filesystem paths of unit tests and/or queries under a base directory |\n| `codeql_test_accept` | Accept new test results as the expected baseline |\n| `codeql_test_extract` | Extract test databases for CodeQL query tests |\n| `codeql_test_run` | Run CodeQL query tests |\n\n## Language Server Protocol (LSP) Tools\n\n| Tool | Description |\n| ------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |\n| `codeql_lsp_completion` | Get code completions at a cursor position in a CodeQL file |\n| `codeql_lsp_definition` | Go to the definition of a CodeQL symbol at a given position |\n| `codeql_lsp_diagnostics` | Syntax and semantic validation of CodeQL code via the Language Server. Note: inline `ql_code` cannot resolve pack imports; use `codeql_query_compile` for files with imports |\n| `codeql_lsp_references` | Find all references to a CodeQL symbol at a given position |\n\n## Query Development Tools\n\n| Tool | Description |\n| -------------------------------- | ------------------------------------------------------------------------------------------------------------ |\n| `create_codeql_query` | Create directory structure and files for a new CodeQL query with tests |\n| `find_class_position` | Find the start/end line and column of a class for quick evaluation |\n| `find_codeql_query_files` | Find and track all files and directories related to a CodeQL query, including resolved metadata |\n| `find_predicate_position` | Find the start/end line and column of a predicate for quick evaluation |\n| `list_codeql_databases` | List CodeQL databases discovered in configured base directories |\n| `list_mrva_run_results` | List MRVA (Multi-Repository Variant Analysis) run results with per-repo details |\n| `list_query_run_results` | List query run result directories with artifact inventory. Filter by `queryName`, `language`, or `queryPath` |\n| `profile_codeql_query` | Profile the performance of a CodeQL query run against a specific database by analyzing the evaluator log |\n| `profile_codeql_query_from_logs` | Parse existing CodeQL evaluator logs into a performance profile without re-running the query |\n| `quick_evaluate` | Quick evaluate either a class or a predicate in a CodeQL query for debugging |\n| `read_database_source` | Read source file contents from a CodeQL database source archive. Omit `filePath` to list all files |\n| `register_database` | Register a CodeQL database given a local path to the database directory |\n| `validate_codeql_query` | Quick heuristic validation for CodeQL query structure (does not compile the query) |\n\n## Common Tool Workflows\n\n### Create and Test a Query\n\n1. `create_codeql_query` \u2014 scaffold files\n2. `codeql_pack_install` \u2014 install dependencies\n3. `codeql_query_compile` \u2014 validate syntax\n4. `codeql_test_run` \u2014 run tests\n5. `codeql_test_accept` \u2014 accept correct results\n\n### Understand Code Structure\n\n1. `codeql_query_run` with `queryName="PrintAST"` \u2014 visualize the AST\n2. `codeql_query_run` with `queryName="PrintCFG"` \u2014 visualize control flow\n3. `codeql_query_run` with `queryName="CallGraphFrom"` / `"CallGraphTo"` \u2014 trace call relationships\n\n### Profile Query Performance\n\n1. `codeql_query_run` with `evaluationOutput` \u2014 run query and capture evaluator logs\n2. `profile_codeql_query_from_logs` \u2014 analyze evaluator logs for bottlenecks\n3. `codeql_generate_log-summary` \u2014 generate a human-readable log summary\n\n### Interactive Development\n\n1. `codeql_lsp_completion` \u2014 get QL code completions\n2. `codeql_lsp_definition` \u2014 navigate to definitions\n3. `codeql_lsp_references` \u2014 find all references\n4. `codeql_lsp_diagnostics` \u2014 real-time validation\n\n## Tool Input Conventions\n\n- **LSP tools** use **0-based** line and column positions for input. Output uses 1-based `startLine`/`endLine`.\n- **`find_predicate_position`** and **`find_class_position`** return **1-based** positions.\n- **`workspace_uri`** for LSP tools must be a **plain directory path** to the pack root containing `codeql-pack.yml`, not a `file://` URI.\n\n## Related Resources\n\n- `codeql://server/overview` \u2014 MCP server orientation guide\n- `codeql://server/prompts` \u2014 Complete prompt reference\n- `codeql://learning/query-basics` \u2014 Query writing reference\n- `codeql://patterns/performance` \u2014 Performance profiling guide\n';
|
|
63069
|
+
|
|
62765
63070
|
// src/lib/resources.ts
|
|
62766
|
-
|
|
62767
|
-
|
|
62768
|
-
import { fileURLToPath as fileURLToPath3 } from "url";
|
|
62769
|
-
var __filename2 = fileURLToPath3(import.meta.url);
|
|
62770
|
-
var __dirname2 = dirname8(__filename2);
|
|
62771
|
-
function getGettingStartedGuide() {
|
|
62772
|
-
try {
|
|
62773
|
-
return readFileSync10(join15(__dirname2, "../resources/getting-started.md"), "utf-8");
|
|
62774
|
-
} catch {
|
|
62775
|
-
return "Getting started guide not available";
|
|
62776
|
-
}
|
|
63071
|
+
function getLearningQueryBasics() {
|
|
63072
|
+
return learning_query_basics_default;
|
|
62777
63073
|
}
|
|
62778
|
-
function
|
|
62779
|
-
|
|
62780
|
-
return readFileSync10(join15(__dirname2, "../resources/query-basics.md"), "utf-8");
|
|
62781
|
-
} catch {
|
|
62782
|
-
return "Query basics guide not available";
|
|
62783
|
-
}
|
|
63074
|
+
function getPerformancePatterns() {
|
|
63075
|
+
return performance_patterns_default;
|
|
62784
63076
|
}
|
|
62785
63077
|
function getSecurityTemplates() {
|
|
62786
|
-
|
|
62787
|
-
return readFileSync10(join15(__dirname2, "../resources/security-templates.md"), "utf-8");
|
|
62788
|
-
} catch {
|
|
62789
|
-
return "Security templates not available";
|
|
62790
|
-
}
|
|
63078
|
+
return security_templates_default;
|
|
62791
63079
|
}
|
|
62792
|
-
function
|
|
62793
|
-
|
|
62794
|
-
|
|
62795
|
-
|
|
62796
|
-
|
|
62797
|
-
|
|
63080
|
+
function getServerOverview() {
|
|
63081
|
+
return server_overview_default;
|
|
63082
|
+
}
|
|
63083
|
+
function getServerPrompts() {
|
|
63084
|
+
return server_prompts_default;
|
|
63085
|
+
}
|
|
63086
|
+
function getServerQueries() {
|
|
63087
|
+
return server_queries_default;
|
|
63088
|
+
}
|
|
63089
|
+
function getServerTools() {
|
|
63090
|
+
return server_tools_default;
|
|
63091
|
+
}
|
|
63092
|
+
function getTestDrivenDevelopment() {
|
|
63093
|
+
return ql_test_driven_development_default;
|
|
63094
|
+
}
|
|
63095
|
+
function getQueryUnitTesting() {
|
|
63096
|
+
return codeql_query_unit_testing_default;
|
|
63097
|
+
}
|
|
63098
|
+
function getDataflowMigration() {
|
|
63099
|
+
return dataflow_migration_v1_to_v2_default;
|
|
62798
63100
|
}
|
|
62799
63101
|
|
|
62800
63102
|
// src/tools/codeql-resources.ts
|
|
62801
63103
|
function registerCodeQLResources(server) {
|
|
62802
63104
|
server.resource(
|
|
62803
|
-
"CodeQL
|
|
62804
|
-
"codeql://learning/
|
|
63105
|
+
"CodeQL Query Basics",
|
|
63106
|
+
"codeql://learning/query-basics",
|
|
62805
63107
|
{
|
|
62806
|
-
description: "
|
|
63108
|
+
description: "QL query writing reference: syntax, metadata, from/where/select, common patterns, testing conventions",
|
|
62807
63109
|
mimeType: "text/markdown"
|
|
62808
63110
|
},
|
|
62809
63111
|
async () => {
|
|
62810
63112
|
return {
|
|
62811
63113
|
contents: [
|
|
62812
63114
|
{
|
|
62813
|
-
uri: "codeql://learning/
|
|
63115
|
+
uri: "codeql://learning/query-basics",
|
|
62814
63116
|
mimeType: "text/markdown",
|
|
62815
|
-
text:
|
|
63117
|
+
text: getLearningQueryBasics()
|
|
62816
63118
|
}
|
|
62817
63119
|
]
|
|
62818
63120
|
};
|
|
62819
63121
|
}
|
|
62820
63122
|
);
|
|
62821
63123
|
server.resource(
|
|
62822
|
-
"CodeQL
|
|
62823
|
-
"codeql://learning/
|
|
63124
|
+
"CodeQL Test-Driven Development",
|
|
63125
|
+
"codeql://learning/test-driven-development",
|
|
62824
63126
|
{
|
|
62825
|
-
description: "
|
|
63127
|
+
description: "TDD theory and workflow for developing CodeQL queries with MCP tools",
|
|
62826
63128
|
mimeType: "text/markdown"
|
|
62827
63129
|
},
|
|
62828
63130
|
async () => {
|
|
62829
63131
|
return {
|
|
62830
63132
|
contents: [
|
|
62831
63133
|
{
|
|
62832
|
-
uri: "codeql://learning/
|
|
63134
|
+
uri: "codeql://learning/test-driven-development",
|
|
63135
|
+
mimeType: "text/markdown",
|
|
63136
|
+
text: getTestDrivenDevelopment()
|
|
63137
|
+
}
|
|
63138
|
+
]
|
|
63139
|
+
};
|
|
63140
|
+
}
|
|
63141
|
+
);
|
|
63142
|
+
server.resource(
|
|
63143
|
+
"CodeQL Performance Patterns",
|
|
63144
|
+
"codeql://patterns/performance",
|
|
63145
|
+
{
|
|
63146
|
+
description: "Performance profiling and optimization for CodeQL queries",
|
|
63147
|
+
mimeType: "text/markdown"
|
|
63148
|
+
},
|
|
63149
|
+
async () => {
|
|
63150
|
+
return {
|
|
63151
|
+
contents: [
|
|
63152
|
+
{
|
|
63153
|
+
uri: "codeql://patterns/performance",
|
|
63154
|
+
mimeType: "text/markdown",
|
|
63155
|
+
text: getPerformancePatterns()
|
|
63156
|
+
}
|
|
63157
|
+
]
|
|
63158
|
+
};
|
|
63159
|
+
}
|
|
63160
|
+
);
|
|
63161
|
+
server.resource(
|
|
63162
|
+
"CodeQL Server Overview",
|
|
63163
|
+
"codeql://server/overview",
|
|
63164
|
+
{
|
|
63165
|
+
description: "MCP server orientation guide: available tools, prompts, resources, and workflows",
|
|
63166
|
+
mimeType: "text/markdown"
|
|
63167
|
+
},
|
|
63168
|
+
async () => {
|
|
63169
|
+
return {
|
|
63170
|
+
contents: [
|
|
63171
|
+
{
|
|
63172
|
+
uri: "codeql://server/overview",
|
|
63173
|
+
mimeType: "text/markdown",
|
|
63174
|
+
text: getServerOverview()
|
|
63175
|
+
}
|
|
63176
|
+
]
|
|
63177
|
+
};
|
|
63178
|
+
}
|
|
63179
|
+
);
|
|
63180
|
+
server.resource(
|
|
63181
|
+
"CodeQL Server Prompts",
|
|
63182
|
+
"codeql://server/prompts",
|
|
63183
|
+
{
|
|
63184
|
+
description: "Complete reference of MCP prompts for CodeQL development workflows",
|
|
63185
|
+
mimeType: "text/markdown"
|
|
63186
|
+
},
|
|
63187
|
+
async () => {
|
|
63188
|
+
return {
|
|
63189
|
+
contents: [
|
|
63190
|
+
{
|
|
63191
|
+
uri: "codeql://server/prompts",
|
|
63192
|
+
mimeType: "text/markdown",
|
|
63193
|
+
text: getServerPrompts()
|
|
63194
|
+
}
|
|
63195
|
+
]
|
|
63196
|
+
};
|
|
63197
|
+
}
|
|
63198
|
+
);
|
|
63199
|
+
server.resource(
|
|
63200
|
+
"CodeQL Server Queries",
|
|
63201
|
+
"codeql://server/queries",
|
|
63202
|
+
{
|
|
63203
|
+
description: "Overview of bundled tools queries: PrintAST, PrintCFG, CallGraphFrom, CallGraphTo",
|
|
63204
|
+
mimeType: "text/markdown"
|
|
63205
|
+
},
|
|
63206
|
+
async () => {
|
|
63207
|
+
return {
|
|
63208
|
+
contents: [
|
|
63209
|
+
{
|
|
63210
|
+
uri: "codeql://server/queries",
|
|
62833
63211
|
mimeType: "text/markdown",
|
|
62834
|
-
text:
|
|
63212
|
+
text: getServerQueries()
|
|
63213
|
+
}
|
|
63214
|
+
]
|
|
63215
|
+
};
|
|
63216
|
+
}
|
|
63217
|
+
);
|
|
63218
|
+
server.resource(
|
|
63219
|
+
"CodeQL Server Tools",
|
|
63220
|
+
"codeql://server/tools",
|
|
63221
|
+
{
|
|
63222
|
+
description: "Complete reference of default MCP tools for CodeQL development",
|
|
63223
|
+
mimeType: "text/markdown"
|
|
63224
|
+
},
|
|
63225
|
+
async () => {
|
|
63226
|
+
return {
|
|
63227
|
+
contents: [
|
|
63228
|
+
{
|
|
63229
|
+
uri: "codeql://server/tools",
|
|
63230
|
+
mimeType: "text/markdown",
|
|
63231
|
+
text: getServerTools()
|
|
62835
63232
|
}
|
|
62836
63233
|
]
|
|
62837
63234
|
};
|
|
@@ -62841,7 +63238,7 @@ function registerCodeQLResources(server) {
|
|
|
62841
63238
|
"CodeQL Security Templates",
|
|
62842
63239
|
"codeql://templates/security",
|
|
62843
63240
|
{
|
|
62844
|
-
description: "
|
|
63241
|
+
description: "Security query templates for multiple languages and vulnerability classes",
|
|
62845
63242
|
mimeType: "text/markdown"
|
|
62846
63243
|
},
|
|
62847
63244
|
async () => {
|
|
@@ -62857,19 +63254,38 @@ function registerCodeQLResources(server) {
|
|
|
62857
63254
|
}
|
|
62858
63255
|
);
|
|
62859
63256
|
server.resource(
|
|
62860
|
-
"CodeQL
|
|
62861
|
-
"codeql://
|
|
63257
|
+
"CodeQL Query Unit Testing",
|
|
63258
|
+
"codeql://guides/query-unit-testing",
|
|
62862
63259
|
{
|
|
62863
|
-
description: "
|
|
63260
|
+
description: "Guide for creating and running CodeQL query unit tests across all supported languages",
|
|
62864
63261
|
mimeType: "text/markdown"
|
|
62865
63262
|
},
|
|
62866
63263
|
async () => {
|
|
62867
63264
|
return {
|
|
62868
63265
|
contents: [
|
|
62869
63266
|
{
|
|
62870
|
-
uri: "codeql://
|
|
63267
|
+
uri: "codeql://guides/query-unit-testing",
|
|
62871
63268
|
mimeType: "text/markdown",
|
|
62872
|
-
text:
|
|
63269
|
+
text: getQueryUnitTesting()
|
|
63270
|
+
}
|
|
63271
|
+
]
|
|
63272
|
+
};
|
|
63273
|
+
}
|
|
63274
|
+
);
|
|
63275
|
+
server.resource(
|
|
63276
|
+
"CodeQL Dataflow Migration v1 to v2",
|
|
63277
|
+
"codeql://guides/dataflow-migration-v1-to-v2",
|
|
63278
|
+
{
|
|
63279
|
+
description: "Guide for migrating CodeQL queries from legacy v1 dataflow API to modern v2 module-based API",
|
|
63280
|
+
mimeType: "text/markdown"
|
|
63281
|
+
},
|
|
63282
|
+
async () => {
|
|
63283
|
+
return {
|
|
63284
|
+
contents: [
|
|
63285
|
+
{
|
|
63286
|
+
uri: "codeql://guides/dataflow-migration-v1-to-v2",
|
|
63287
|
+
mimeType: "text/markdown",
|
|
63288
|
+
text: getDataflowMigration()
|
|
62873
63289
|
}
|
|
62874
63290
|
]
|
|
62875
63291
|
};
|
|
@@ -63251,83 +63667,107 @@ function registerLSPTools(server) {
|
|
|
63251
63667
|
);
|
|
63252
63668
|
}
|
|
63253
63669
|
|
|
63254
|
-
// src/resources/
|
|
63255
|
-
|
|
63256
|
-
|
|
63670
|
+
// src/resources/languages/actions_ast.md
|
|
63671
|
+
var actions_ast_default = '# CodeQL AST nodes for `actions` language\n\n## CodeQL\'s core AST classes for `actions` language\n\nBased on analysis of CodeQL\'s Actions AST test results from local test files, here are the core AST classes for GitHub Actions analysis:\n\n### Top-Level Action and Workflow Structures\n\n**Action Files (action.yml):**\n\n- `CompositeActionImpl` - Root composite action declaration (e.g., `name: "Hello World"`)\n- Action metadata including name, description, and runtime configuration\n\n**Workflow Files (.github/workflows/\\*.yml):**\n\n- `WorkflowImpl` - Root workflow declaration (e.g., `name: Reusable workflow example`)\n- Complete workflow structure with events, jobs, and steps\n\n### Event Handling\n\n**Event Triggers:**\n\n- `OnImpl` - Event trigger definitions (e.g., `workflow_call:`)\n- `EventImpl` - Specific event types (e.g., `workflow_call`)\n- Event configuration with inputs, outputs, and secrets\n\n### Input and Output Management\n\n**Input Structures:**\n\n- `InputsImpl` - Input containers for actions and workflows\n- `InputImpl` - Individual input definitions (e.g., `who-to-greet`, `config-path`)\n- Input properties: description, required, type, default values\n\n**Output Structures:**\n\n- `OutputsImpl` - Output containers for workflows and jobs\n- Output value expressions and job output references\n\n### Job Management\n\n**Job Structure:**\n\n- `JobImpl` - Job definitions (e.g., `Job: job1`)\n- Job configuration including runner, outputs, and steps\n- Job-level environment and dependency management\n\n**Job Execution Environment:**\n\n- Runner specifications (e.g., `ubuntu-latest`)\n- Job outputs and step output references\n\n### Step Execution\n\n**Step Types:**\n\n- `StepImpl` - Generic step containers\n- `Run Step` - Steps with shell commands and scripts\n- `Uses Step` - Steps using external actions\n\n**Step Components:**\n\n- Step identification and naming\n- Shell command execution\n- External action usage (e.g., `tj-actions/changed-files@v40`)\n\n### Environment and Variable Management\n\n**Environment Variables:**\n\n- `EnvImpl` - Environment variable definitions\n- Environment variable scoping (step-level, job-level)\n- Variable interpolation and expression evaluation\n\n### Expression System\n\n**Expression Handling:**\n\n- `ExpressionImpl` - GitHub Actions expressions (e.g., `inputs.who-to-greet`, `jobs.job1.outputs.job-output1`)\n- Expression contexts: inputs, steps, jobs, github, env\n- Complex expression evaluation and context access\n\n**Expression Contexts:**\n\n- Input references: `inputs.config-path`, `inputs.who-to-greet`\n- Step output references: `steps.step1.outputs.step-output`, `steps.step2.outputs.all_changed_files`\n- Job output references: `jobs.job1.outputs.job-output1`\n\n### Value and Data Types\n\n**Scalar Values:**\n\n- `ScalarValueImpl` - String literals, booleans, and scalar data\n- Configuration values (e.g., `"Hello World"`, `"composite"`, `true`)\n- Command strings and action references\n\n**Value Types:**\n\n- String values for names, descriptions, commands\n- Boolean values for required flags and conditions\n- Action references and version specifications\n\n### Action Runtime Configuration\n\n**Composite Actions:**\n\n- `using: "composite"` runtime specification\n- Step sequence execution within composite actions\n- Input parameter passing and environment setup\n\n**Action Metadata:**\n\n- Action names and descriptions\n- Input/output specifications\n- Runtime environment configuration\n\n### Shell and Command Execution\n\n**Command Execution:**\n\n- Shell command strings (e.g., `echo "Hello $INPUT_WHO_TO_GREET."`)\n- Shell specification (e.g., `bash`)\n- Multi-line command support\n\n**Environment Integration:**\n\n- Environment variable usage in commands\n- Variable substitution and expansion\n- Input-to-environment variable mapping\n\n### External Action Integration\n\n**Action Usage:**\n\n- External action references (e.g., `tj-actions/changed-files@v40`)\n- Version pinning and action marketplace integration\n- Action parameter passing and configuration\n\n### Workflow Reusability\n\n**Reusable Workflows:**\n\n- Workflow call triggers and parameters\n- Input/output parameter definitions\n- Secret management and passing\n\n**Workflow Composition:**\n\n- Job dependencies and sequencing\n- Output propagation between jobs\n- Workflow-level input and output management\n\n### Security and Secrets\n\n**Secret Management:**\n\n- Secret declarations and requirements\n- Secret passing in reusable workflows\n- Secure environment variable handling\n\n### Example AST Hierarchy\n\nBased on CodeQL\'s GitHub Actions analysis capabilities:\n\n```\nWorkflowImpl (root workflow)\n\u251C\u2500\u2500 OnImpl (event triggers)\n\u2502 \u2514\u2500\u2500 EventImpl (specific events like workflow_call)\n\u251C\u2500\u2500 InputsImpl (workflow inputs)\n\u2502 \u2514\u2500\u2500 InputImpl (individual inputs)\n\u251C\u2500\u2500 OutputsImpl (workflow outputs)\n\u251C\u2500\u2500 JobImpl (job definitions)\n\u2502 \u251C\u2500\u2500 OutputsImpl (job outputs)\n\u2502 \u2514\u2500\u2500 StepImpl (job steps)\n\u2502 \u251C\u2500\u2500 EnvImpl (step environment)\n\u2502 \u2514\u2500\u2500 ScalarValueImpl (step commands/actions)\n\u2514\u2500\u2500 ScalarValueImpl (scalar values throughout)\n\nCompositeActionImpl (root action)\n\u251C\u2500\u2500 InputsImpl (action inputs)\n\u251C\u2500\u2500 RunsImpl (execution configuration)\n\u2514\u2500\u2500 StepImpl (action steps)\n \u251C\u2500\u2500 EnvImpl (step environment)\n \u2514\u2500\u2500 ScalarValueImpl (commands and values)\n\nExpressionImpl (expressions like ${{ inputs.name }})\n\u2514\u2500\u2500 Context access (inputs, steps, jobs, github, env)\n```\n\n## Expected test results for local `PrintAst.ql` query\n\nThis repo contains a variant of the open-source `PrintAst.ql` query for `actions` language, with modifications for local testing:\n\n- Use the `codeql_query_run` tool with `queryName="PrintAST"` and `language="actions"` to run the bundled PrintAST query\n- Use the `codeql_test_run` tool to run the PrintAST test and compare against expected results\n';
|
|
63672
|
+
|
|
63673
|
+
// src/resources/languages/cpp_ast.md
|
|
63674
|
+
var cpp_ast_default = '# CodeQL AST nodes for `cpp` language\n\n## CodeQL\'s core AST classes for `cpp` language\n\nBased on comprehensive analysis of CodeQL\'s C++ AST test results from both local and GitHub test files, here are the core AST classes for C/C++ analysis:\n\n### Function and Method Declarations\n\n**Function Types:**\n\n- `TopLevelFunction` - Global functions (e.g., `void fun3(someClass*)`, `int main()`)\n- `MemberFunction` - Class member functions (e.g., `void someClass::f()`, `int someClass::g(int, int)`)\n- `VirtualFunction` - Virtual functions with dynamic dispatch (e.g., `virtual void Base::v()`)\n- `ConstMemberFunction` - Const member functions (e.g., `char const* std::type_info::name() const`)\n- `FormattingFunction` - Functions with format string checking (e.g., `int printf(char const*)`)\n- `TemplateFunction` - Template function declarations\n\n**Constructors and Destructors:**\n\n- `Constructor` - Class constructors (e.g., `void C::C(int)`)\n- `CopyConstructor` - Copy constructors (e.g., `void C::C(C const&)`)\n- `CopyAssignmentOperator` - Copy assignment operators (e.g., `C& C::operator=(C const&)`)\n- `MoveAssignmentOperator` - Move assignment operators (e.g., `C& C::operator=(C&&)`)\n- `Destructor` - Destructor declarations\n- `DestructorCall` - Explicit and implicit destructor calls (e.g., `call to ~C`)\n\n**Operator Functions:**\n\n- `Operator` - Operator overloads (e.g., `void operator delete(void*)`, `void* operator new(unsigned long)`)\n\n### Statements\n\n**Control Flow Statements:**\n\n- `BlockStmt` - Block statements containing multiple statements (e.g., `{ ... }`)\n- `IfStmt` - Conditional statements with condition and branches\n- `ForStmt` - For loops with initialization, condition, and increment\n- `ReturnStmt` - Return statements with optional expressions\n- `GotoStmt` - Goto statements for jumping to labels\n- `LabelStmt` - Label statements for goto targets\n\n**Declaration Statements:**\n\n- `DeclStmt` - Declaration statements containing variable and type declarations\n- `VariableDeclarationEntry` - Individual variable declarations (e.g., `definition of i`)\n- `TypeDeclarationEntry` - Type declarations (e.g., `definition of u`)\n\n**Expression Statements:**\n\n- `ExprStmt` - Statement wrappers for expressions\n\n**Variable Length Array Support:**\n\n- `VlaDimensionStmt` - VLA dimension size statements\n- `VlaDeclStmt` - VLA declaration statements\n\n### Expressions\n\n**Primary Expressions:**\n\n- `Literal` - Literal values (e.g., `1`, `2`, `42`, `"hello"`)\n- `StringLiteral` - String literals (e.g., `"int"`, `"string"`)\n- `VariableAccess` - Variable references (e.g., `sc`, `i`, `args`)\n- `ThisExpr` - The `this` keyword in member functions\n\n**Function Calls:**\n\n- `FunctionCall` - Function calls (e.g., `call to f`, `call to printf`)\n- `FormattingFunctionCall` - Calls to format string functions with type checking\n- `MethodCall` - Method calls on objects\n- `ConstructorCall` - Constructor calls (e.g., `call to C`)\n\n**Operators and Assignments:**\n\n- `AssignExpr` - Assignment expressions (e.g., `... = ...`)\n- `AddExpr` - Addition expressions (e.g., `... + ...`)\n- `MulExpr` - Multiplication expressions (e.g., `... * ...`)\n- `SubExpr` - Subtraction expressions\n\n**Object Creation and Destruction:**\n\n- `ClassInstanceExpr` - Object instantiation expressions\n- `NewExpr` - Dynamic memory allocation with `new`\n- `DeleteExpr` - Dynamic memory deallocation with `delete`\n- `VacuousDestructorCall` - Vacuous destructor calls for trivial types\n\n**Array and Pointer Operations:**\n\n- `ArrayExpr` - Array access expressions (e.g., `access to array`)\n- `PointerDereferenceExpr` - Pointer dereference (e.g., `* ...`)\n- `AddressOfExpr` - Address-of operator (e.g., `& ...`)\n- `ArrayToPointerConversion` - Implicit array to pointer conversions\n\n**Field Access:**\n\n- `ValueFieldAccess` - Value-based field access (e.g., `obj.field`)\n- `PointerFieldAccess` - Pointer-based field access (e.g., `ptr->field`)\n\n**Type Casting:**\n\n- `CStyleCast` - C-style casts (e.g., `(int)...`, `(char)...`)\n- `StaticCast` - Static casts for safe conversions\n- `DynamicCast` - Dynamic casts for runtime type checking (e.g., `dynamic_cast<Derived *>...`)\n- `ConstCast` - Const casts (e.g., `const_cast<T *>...`)\n- `ReinterpretCast` - Reinterpret casts (e.g., `reinterpret_cast<S *>...`)\n\n**Reference Operations:**\n\n- `ReferenceToExpr` - Reference creation (e.g., `(reference to)`)\n- `ReferenceDereferenceExpr` - Reference dereference (e.g., `(reference dereference)`)\n\n**Type Information:**\n\n- `TypeidOperator` - Runtime type information (e.g., `typeid ...`)\n\n**Modern C++ Features:**\n\n- `ParenthesizedExpr` - Parenthesized expressions for grouping\n\n### Type System\n\n**Basic Types:**\n\n- `IntType` - Integer types (e.g., `int`)\n- `VoidType` - Void type\n- `FloatType` - Floating-point types\n- `LongType` - Long integer types (e.g., `unsigned long`)\n- `PlainCharType` - Plain char type\n- `CharType` - Character types\n\n**Pointer Types:**\n\n- `PointerType` - Pointer types (e.g., `someClass *`, `Base *`)\n- `IntPointerType` - Integer pointer types (e.g., `int *`)\n- `CharPointerType` - Character pointer types (e.g., `char *`)\n- `VoidPointerType` - Void pointer types (e.g., `void *`)\n- `FunctionPointerType` - Function pointer types\n\n**Reference Types:**\n\n- `LValueReferenceType` - L-value references (e.g., `const someClass &`)\n- `RValueReferenceType` - R-value references (e.g., `someClass &&`)\n\n**Array Types:**\n\n- `ArrayType` - Array types (e.g., `char[]`, `char[4]`)\n\n**Class and Struct Types:**\n\n- `Class` - Class types (e.g., `Base`, `Derived`)\n- `Struct` - Struct types\n- `NestedClass` - Nested class types\n- `LocalUnion` - Local union types\n\n**Template Types:**\n\n- `TypeTemplateParameter` - Template type parameters (e.g., `T`)\n\n**Advanced Types:**\n\n- `SpecifiedType` - Type qualifiers (e.g., `const type_info`)\n- `CTypedefType` - C typedef types (e.g., `va_list`, `MYINT`)\n\n### C11 Generic Support\n\n**Generic Expressions:**\n\n- `C11GenericExpr` - C11 \\_Generic expressions for type-based selection\n- `ReuseExpr` - Expression reuse in generic contexts\n- `TypeName` - Type names in generic associations\n\n### Parameters and Initializers\n\n**Parameter Handling:**\n\n- `Parameter` - Function parameters with types (e.g., `i`, `j`, `sc`)\n- Support for unnamed parameters and default arguments\n\n**Initialization:**\n\n- `Initializer` - Variable initializers (e.g., `initializer for i`)\n- Constructor initialization lists\n- Field initialization\n\n### Built-in Functions\n\n**Variable Arguments:**\n\n- `BuiltInVarArgsStart` - `__builtin_va_start` for variadic functions\n- `BuiltInVarArgsEnd` - `__builtin_va_end` for cleanup\n\n### Type Conversions\n\n**Implicit Conversions:**\n\n- `IntegralConversion` - Integer type conversions\n- `PointerConversion` - Pointer type conversions\n- `BaseClassConversion` - Base class conversions for inheritance\n- `GlvalueConversion` - Glvalue conversions\n\n**Explicit Conversions:**\n\n- Support for all cast types with conversion tracking\n- Value category preservation through conversions\n\n### Value Categories and Properties\n\n**Value Categories:**\n\n- `prvalue` - Pure r-values (temporary values)\n- `lvalue` - L-values (addressable values)\n- `prvalue(load)` - Loaded values from memory\n\n**Type Properties:**\n\n- Type information preservation through all expressions\n- Conversion tracking for type safety analysis\n\n### Example AST Hierarchy\n\nBased on CodeQL\'s comprehensive C++ analysis capabilities:\n\n```\nTopLevelFunction (global functions)\n\u251C\u2500\u2500 Parameter (function parameters)\n\u251C\u2500\u2500 BlockStmt (function body)\n\u2502 \u251C\u2500\u2500 DeclStmt (declarations)\n\u2502 \u2502 \u2514\u2500\u2500 VariableDeclarationEntry (variable definitions)\n\u2502 \u251C\u2500\u2500 ExprStmt (expression statements)\n\u2502 \u2502 \u251C\u2500\u2500 FunctionCall (function calls)\n\u2502 \u2502 \u251C\u2500\u2500 AssignExpr (assignments)\n\u2502 \u2502 \u2514\u2500\u2500 VariableAccess (variable references)\n\u2502 \u2514\u2500\u2500 ReturnStmt (return statements)\n\u2514\u2500\u2500 Type information (IntType, PointerType, etc.)\n\nClass (class declarations)\n\u251C\u2500\u2500 Constructor/Destructor (special members)\n\u251C\u2500\u2500 MemberFunction (methods)\n\u251C\u2500\u2500 CopyAssignmentOperator (copy operations)\n\u2514\u2500\u2500 MoveAssignmentOperator (move operations)\n\nExpression hierarchy with full type and conversion tracking\n\u251C\u2500\u2500 Primary expressions (literals, variables)\n\u251C\u2500\u2500 Operators (arithmetic, logical, comparison)\n\u251C\u2500\u2500 Casts (static, dynamic, const, reinterpret)\n\u251C\u2500\u2500 Object operations (new, delete, field access)\n\u2514\u2500\u2500 Type operations (sizeof, typeid, alignof)\n```\n\n## Expected test results for local `PrintAst.ql` query\n\nThis repo contains a variant of the open-source `PrintAst.ql` query for `cpp` language, with modifications for local testing:\n\n- Use the `codeql_query_run` tool with `queryName="PrintAST"` and `language="cpp"` to run the bundled PrintAST query\n- Use the `codeql_test_run` tool to run the PrintAST test and compare against expected results\n\n## Expected test results for open-source `PrintAst.ql` query\n\nThe following links can be fetched to get the expected results for different unit tests of the open-source `PrintAst.ql` query for the `cpp` language:\n\n- [library-tests/destructors/PrintAST.expected](https://github.com/github/codeql/blob/main/cpp/ql/test/library-tests/destructors/PrintAST.expected)\n- [library-tests/c11_generic/PrintAST.expected](https://github.com/github/codeql/blob/main/cpp/ql/test/library-tests/c11_generic/PrintAST.expected)\n- [library-tests/ir/ir/PrintAST.expected](https://github.com/github/codeql/blob/main/cpp/ql/test/library-tests/ir/ir/PrintAST.expected)\n- [library-tests/ir/no-function-calls/PrintAST.expected](https://github.com/github/codeql/blob/main/cpp/ql/test/library-tests/ir/no-function-calls/PrintAST.expected)\n- [examples/expressions/PrintAST.expected](https://github.com/github/codeql/blob/main/cpp/ql/test/examples/expressions/PrintAST.expected)\n';
|
|
63675
|
+
|
|
63676
|
+
// src/resources/languages/cpp_security_query_guide.md
|
|
63677
|
+
var cpp_security_query_guide_default = "# C++ Security Query Guide\n\nLanguage-specific notes for writing C++ security queries in CodeQL. For the general taint-tracking template and workflow, see the `security_templates` resource.\n\n## Imports\n\n```ql\nimport cpp\nimport semmle.code.cpp.dataflow.new.DataFlow\nimport semmle.code.cpp.dataflow.new.TaintTracking\n```\n\nFor path-problem queries add `import MyFlow::PathGraph` after defining your flow module.\n\n## Sources and Sinks\n\n- **Sources**: Use the `RemoteFlowSource` class from `semmle.code.cpp.security.FlowSources`, or model custom sources as `DataFlow::Node` subclasses.\n- **Sinks**: Model as `DataFlow::Node` subclasses matching the dangerous API (e.g., buffer writes, system calls, SQL execution).\n- **Barriers**: Use `semmle.code.cpp.controlflow.Guards` to model guard conditions that sanitize tainted data.\n\n## Key Library Modules\n\n| Module | Purpose |\n| -------------------------------------------- | ------------------------------------- |\n| `semmle.code.cpp.dataflow.new.DataFlow` | Data flow nodes and global analysis |\n| `semmle.code.cpp.dataflow.new.TaintTracking` | Taint tracking analysis |\n| `semmle.code.cpp.controlflow.Guards` | Guard-condition analysis for barriers |\n| `semmle.code.cpp.security.BufferWrite` | Buffer-write sink modeling |\n| `semmle.code.cpp.security.FlowSources` | Remote and local flow sources |\n";
|
|
63678
|
+
|
|
63679
|
+
// src/resources/languages/csharp_ast.md
|
|
63680
|
+
var csharp_ast_default = '# CodeQL AST nodes for `csharp` language\n\n## CodeQL\'s core AST classes for `csharp` language\n\nBased on the C# PrintAst.expected test results, here are the core CodeQL AST classes for the C# language:\n\n### Declarations and Members\n\n- **`Class`** - Class declaration\n- **`NamespaceDeclaration`** - Namespace declaration\n- **`Method`** - Method declaration\n- **`Property`** - Property declaration\n- **`Field`** - Field declaration\n- **`Parameter`** - Method parameter\n- **`DelegateType`** - Delegate type declaration\n- **`InstanceConstructor`** - Instance constructor\n- **`StaticConstructor`** - Static constructor\n- **`Destructor`** - Destructor/finalizer\n\n### Type System\n\n- **`TypeMention`** - Reference to a type\n- **`TypeParameter`** - Generic type parameter\n- **`TypeAccess`** - Access to a type\n- **`TypeAccessPatternExpr`** - Type access in pattern expressions\n\n### Statements\n\n- **`BlockStmt`** - Block statement `{...}`\n- **`ExprStmt`** - Expression statement\n- **`LocalVariableDeclStmt`** - Local variable declaration statement\n- **`ReturnStmt`** - Return statement\n- **`IfStmt`** - If statement\n- **`TryStmt`** - Try statement\n- **`ThrowStmt`** - Throw statement\n- **`UsingBlockStmt`** - Using statement with block\n- **`FixedStmt`** - Fixed statement (for unsafe code)\n- **`LabelStmt`** - Label statement\n- **`EmptyStmt`** - Empty statement `;`\n\n### Expressions\n\n- **`LocalVariableDeclAndInitExpr`** - Local variable declaration and initialization\n- **`LocalVariableAccess`** - Access to local variable\n- **`ParameterAccess`** - Access to parameter\n- **`FieldAccess`** - Access to field\n- **`PropertyCall`** - Property access/call\n- **`MethodCall`** - Method call\n- **`MethodAccess`** - Method access\n- **`ObjectCreation`** - Object creation expression `new T()`\n- **`AnonymousObjectCreation`** - Anonymous object creation\n- **`ArrayCreation`** - Array creation expression\n- **`ArrayAccess`** - Array element access\n- **`AssignExpr`** - Assignment expression `=`\n- **`AssignAddExpr`** - Addition assignment `+=`\n- **`AssignSubExpr`** - Subtraction assignment `-=`\n- **`ThisAccess`** - `this` access\n- **`CastExpr`** - Type cast expression\n- **`IsExpr`** - Type check expression `is`\n- **`DefaultValueExpr`** - Default value expression `default(...)`\n\n### Arithmetic and Logical Expressions\n\n- **`AddExpr`** - Addition expression `+`\n- **`SubExpr`** - Subtraction expression `-`\n- **`DivExpr`** - Division expression `/`\n- **`BitwiseAndExpr`** - Bitwise AND expression `&`\n- **`LogicalOrExpr`** - Logical OR expression `||`\n- **`LTExpr`** - Less than expression `<`\n- **`GEExpr`** - Greater than or equal expression `>=`\n- **`PostIncrExpr`** - Post-increment expression `++`\n- **`OperatorCall`** - Operator call\n\n### Literals\n\n- **`IntLiteral`** - Integer literal\n- **`StringLiteralUtf16`** - String literal\n- **`BoolLiteral`** - Boolean literal (`true`/`false`)\n- **`DoubleLiteral`** - Double literal\n- **`CharLiteral`** - Character literal\n- **`NullLiteral`** - Null literal\n\n### Object and Collection Initialization\n\n- **`ObjectInitializer`** - Object initializer `{ ... }`\n- **`MemberInitializer`** - Member initializer in object initializer\n- **`CollectionInitializer`** - Collection initializer `{ ..., ... }`\n- **`ElementInitializer`** - Element initializer in collection\n- **`ArrayInitializer`** - Array initializer `{ ..., ... }`\n\n### Delegates and Events\n\n- **`DelegateCall`** - Delegate call\n- **`ImplicitDelegateCreation`** - Implicit delegate creation\n- **`ExplicitDelegateCreation`** - Explicit delegate creation\n- **`EventAccess`** - Event access\n- **`EventCall`** - Event call\n- **`AddEventExpr`** - Event subscription `+=`\n- **`RemoveEventExpr`** - Event unsubscription `-=`\n\n### Properties and Accessors\n\n- **`Getter`** - Property getter\n- **`Setter`** - Property setter\n\n### Special Members and Access\n\n- **`MemberConstantAccess`** - Access to member constant\n- **`LocalFunctionAccess`** - Access to local function\n- **`AddressOfExpr`** - Address-of expression `&` (unsafe code)\n\n## Expected test results for local `PrintAst.ql` query\n\nThis repo contains a variant of the open-source `PrintAst.ql` query for `csharp` language, with modifications for local testing:\n\n- Use the `codeql_query_run` tool with `queryName="PrintAST"` and `language="csharp"` to run the bundled PrintAST query\n- Use the `codeql_test_run` tool to run the PrintAST test and compare against expected results\n\n## Expected test results for open-source `PrintAst.ql` query\n\nThe following links can be fetched to get the expected results for different unit tests of the open-source `PrintAst.ql` query for the `csharp` language:\n\n- [library-tests/arguments/PrintAst.expected](https://github.com/github/codeql/blob/main/csharp/ql/test/library-tests/arguments/PrintAst.expected)\n- [library-tests/assignments/PrintAst.expected](https://github.com/github/codeql/blob/main/csharp/ql/test/library-tests/assignments/PrintAst.expected)\n- [library-tests/attributes/PrintAst.expected](https://github.com/github/codeql/blob/main/csharp/ql/test/library-tests/attributes/PrintAst.expected)\n- [library-tests/comments/PrintAst.expected](https://github.com/github/codeql/blob/main/csharp/ql/test/library-tests/comments/PrintAst.expected)\n- [library-tests/constructors/PrintAst.expected](https://github.com/github/codeql/blob/main/csharp/ql/test/library-tests/constructors/PrintAst.expected)\n- [library-tests/conversion/operator/PrintAst.expected](https://github.com/github/codeql/blob/main/csharp/ql/test/library-tests/conversion/operator/PrintAst.expected)\n- [library-tests/csharp6/PrintAst.expected](https://github.com/github/codeql/blob/main/csharp/ql/test/library-tests/csharp6/PrintAst.expected)\n- [library-tests/csharp7/PrintAst.expected](https://github.com/github/codeql/blob/main/csharp/ql/test/library-tests/csharp7/PrintAst.expected)\n- [library-tests/csharp7.1/PrintAst.expected](https://github.com/github/codeql/blob/main/csharp/ql/test/library-tests/csharp7.1/PrintAst.expected)\n- [library-tests/csharp7.2/PrintAst.expected](https://github.com/github/codeql/blob/main/csharp/ql/test/library-tests/csharp7.2/PrintAst.expected)\n- [library-tests/csharp7.3/PrintAst.expected](https://github.com/github/codeql/blob/main/csharp/ql/test/library-tests/csharp7.3/PrintAst.expected)\n- [library-tests/csharp8/PrintAst.expected](https://github.com/github/codeql/blob/main/csharp/ql/test/library-tests/csharp8/PrintAst.expected)\n- [library-tests/csharp9/PrintAst.expected](https://github.com/github/codeql/blob/main/csharp/ql/test/library-tests/csharp9/PrintAst.expected)\n- [library-tests/csharp11/PrintAst.expected](https://github.com/github/codeql/blob/main/csharp/ql/test/library-tests/csharp11/PrintAst.expected)\n- [library-tests/dataflow/implicittostring/PrintAst.expected](https://github.com/github/codeql/blob/main/csharp/ql/test/library-tests/dataflow/implicittostring/PrintAst.expected)\n- [library-tests/dataflow/tuples/PrintAst.expected](https://github.com/github/codeql/blob/main/csharp/ql/test/library-tests/dataflow/tuples/PrintAst.expected)\n- [library-tests/definitions/PrintAst.expected](https://github.com/github/codeql/blob/main/csharp/ql/test/library-tests/definitions/PrintAst.expected)\n- [library-tests/delegates/PrintAst.expected](https://github.com/github/codeql/blob/main/csharp/ql/test/library-tests/delegates/PrintAst.expected)\n- [library-tests/dynamic/PrintAst.expected](https://github.com/github/codeql/blob/main/csharp/ql/test/library-tests/dynamic/PrintAst.expected)\n- [library-tests/enums/PrintAst.expected](https://github.com/github/codeql/blob/main/csharp/ql/test/library-tests/enums/PrintAst.expected)\n- [library-tests/exceptions/PrintAst.expected](https://github.com/github/codeql/blob/main/csharp/ql/test/library-tests/exceptions/PrintAst.expected)\n- [library-tests/expressions/PrintAst.expected](https://github.com/github/codeql/blob/main/csharp/ql/test/library-tests/expressions/PrintAst.expected)\n- [library-tests/events/PrintAst.expected](https://github.com/github/codeql/blob/main/csharp/ql/test/library-tests/events/PrintAst.expected)\n- [library-tests/fields/PrintAst.expected](https://github.com/github/codeql/blob/main/csharp/ql/test/library-tests/fields/PrintAst.expected)\n- [library-tests/generics/PrintAst.expected](https://github.com/github/codeql/blob/main/csharp/ql/test/library-tests/generics/PrintAst.expected)\n- [library-tests/goto/PrintAst.expected](https://github.com/github/codeql/blob/main/csharp/ql/test/library-tests/goto/PrintAst.expected)\n- [library-tests/indexers/PrintAst.expected](https://github.com/github/codeql/blob/main/csharp/ql/test/library-tests/indexers/PrintAst.expected)\n- [library-tests/initializers/PrintAst.expected](https://github.com/github/codeql/blob/main/csharp/ql/test/library-tests/initializers/PrintAst.expected)\n- [library-tests/linq/PrintAst.expected](https://github.com/github/codeql/blob/main/csharp/ql/test/library-tests/linq/PrintAst.expected)\n- [library-tests/members/PrintAst.expected](https://github.com/github/codeql/blob/main/csharp/ql/test/library-tests/members/PrintAst.expected)\n- [library-tests/methods/PrintAst.expected](https://github.com/github/codeql/blob/main/csharp/ql/test/library-tests/methods/PrintAst.expected)\n- [library-tests/namespaces/PrintAst.expected](https://github.com/github/codeql/blob/main/csharp/ql/test/library-tests/namespaces/PrintAst.expected)\n- [library-tests/nestedtypes/PrintAst.expected](https://github.com/github/codeql/blob/main/csharp/ql/test/library-tests/nestedtypes/PrintAst.expected)\n- [library-tests/operators/PrintAst.expected](https://github.com/github/codeql/blob/main/csharp/ql/test/library-tests/operators/PrintAst.expected)\n- [library-tests/partial/PrintAst.expected](https://github.com/github/codeql/blob/main/csharp/ql/test/library-tests/partial/PrintAst.expected)\n- [library-tests/properties/PrintAst.expected](https://github.com/github/codeql/blob/main/csharp/ql/test/library-tests/properties/PrintAst.expected)\n- [library-tests/statements/PrintAst.expected](https://github.com/github/codeql/blob/main/csharp/ql/test/library-tests/statements/PrintAst.expected)\n- [library-tests/stringinterpolation/PrintAst.expected](https://github.com/github/codeql/blob/main/csharp/ql/test/library-tests/stringinterpolation/PrintAst.expected)\n- [library-tests/types/PrintAst.expected](https://github.com/github/codeql/blob/main/csharp/ql/test/library-tests/types/PrintAst.expected)\n- [library-tests/unsafe/PrintAst.expected](https://github.com/github/codeql/blob/main/csharp/ql/test/library-tests/unsafe/PrintAst.expected)\n';
|
|
63681
|
+
|
|
63682
|
+
// src/resources/languages/csharp_security_query_guide.md
|
|
63683
|
+
var csharp_security_query_guide_default = "# C# Security Query Guide\n\nLanguage-specific notes for writing C# security queries in CodeQL. For the general taint-tracking template and workflow, see the `security_templates` resource.\n\n## Imports\n\n```ql\nimport csharp\nimport semmle.code.csharp.dataflow.DataFlow\nimport semmle.code.csharp.dataflow.TaintTracking\n```\n\nFor path-problem queries add `import MyFlow::PathGraph` after defining your flow module.\n\n## Sources and Sinks\n\n- **Sources**: Use `RemoteFlowSource` from `semmle.code.csharp.security.dataflow.flowsources.Remote`, or model custom sources as `DataFlow::Node` subclasses.\n- **Sinks**: Use or extend existing sink libraries under `semmle.code.csharp.security.dataflow` (e.g., `SqlInjectionQuery`, `flowsinks.Html`, `UrlRedirectQuery`), or model custom sinks as `DataFlow::Node` subclasses.\n- **Sanitizers**: Use `semmle.code.csharp.security.Sanitizers` for common encoding and validation barriers.\n\n## Key Library Modules\n\n| Module | Purpose |\n| ------------------------------------------- | ---------------------------------------- |\n| `semmle.code.csharp.dataflow.DataFlow` | Data flow nodes and global analysis |\n| `semmle.code.csharp.dataflow.TaintTracking` | Taint tracking analysis |\n| `semmle.code.csharp.security.Sanitizers` | Common sanitizer predicates |\n| `semmle.code.csharp.security.dataflow.*` | Pre-built vulnerability-specific configs |\n| `semmle.code.csharp.frameworks.system.*` | .NET framework API models |\n";
|
|
63684
|
+
|
|
63685
|
+
// src/resources/languages/go_ast.md
|
|
63686
|
+
var go_ast_default = '# CodeQL AST Classes for Go Programs\n\n## Purpose\n\nWrite CodeQL queries over Go by navigating the Go AST classes. Model: Syntax \u2192 CodeQL class hierarchy; use predicates to access parts (condition, body, operands). Pattern: `get<Part>()`, `getA<Part>()`, `get<Left/Right>Operand>()`, `getAnArgument()`, `getCallee()`.\n\n## Core Namespaces\n\n- **Statements**: subclasses of `Stmt`\n- **Expressions**: subclasses of `Expr` (literals, unary, binary, calls, selectors, etc.)\n- **Declarations**: `FuncDecl`, `GenDecl` (+ `ImportSpec`, `TypeSpec`, `ValueSpec`)\n- **Types**: `TypeExpr` nodes (`ArrayTypeExpr`, `StructTypeExpr`, `FuncTypeExpr`, `InterfaceTypeExpr`, `MapTypeExpr`, `ChanTypeExpr` variants)\n- **Names/Selectors**: `SimpleName`, `SelectorExpr`; Name hierarchy: `PackageName`, `TypeName`, `ValueName`, `LabelName`\n\n## Statements (Stmt)\n\n### Basic Statements\n\n- **`EmptyStmt`** - Empty statement ";"\n- **`ExprStmt`** - Expression used as statement\n- **`BlockStmt`** - Block statement "{\u2026}"\n- **`DeclStmt`** - Declaration statement\n\n### Control Flow Statements\n\n- **`IfStmt`** - if condition then [else]; supports init; Then/Else are blocks or statements\n - `getCondition()`, `getThen()`, `getElse()`, `getInit()`\n- **`ForStmt`** - Classic init/cond/post; `LoopStmt` superclass\n - `getInit()`, `getCondition()`, `getPost()`, `getBody()`\n- **`RangeStmt`** - "for k,v := range expr { \u2026 }"\n - `getKey()`, `getValue()`, `getDomain()`, `getBody()`\n\n### Switch and Select Statements\n\n- **`SwitchStmt`/`ExpressionSwitchStmt`** - Expression-based switch\n- **`TypeSwitchStmt`** - Type-based switch\n- **`CaseClause`** - Case clause inside switch statements\n - `getExpr(i)`, `getStmt(i)`\n- **`SelectStmt`** - Select statement for channel operations\n- **`CommClause`** - Communication clause in select statement\n\n### Channel and Concurrency Statements\n\n- **`SendStmt`** - Channel send "ch <- x"\n- **`RecvStmt`** - Channel receive "x = <-ch"\n- **`GoStmt`** - Goroutine launch "go f()"\n- **`DeferStmt`** - Deferred function call "defer f()"\n\n### Assignment and Increment Statements\n\n- **`SimpleAssignStmt`** - Simple assignment "="\n- **`DefineStmt`** - Short variable declaration ":="\n- **`CompoundAssignStmt`** - Compound assignment (+=, -=, \\*=, /=, %=, &=, |=, ^=, <<=, >>=, &^=)\n- **`IncStmt`** - Increment "x++"\n- **`DecStmt`** - Decrement "x--"\n\n### Jump Statements\n\n- **`LabeledStmt`** - Labeled statement\n- **`BreakStmt`** - Break statement\n- **`ContinueStmt`** - Continue statement\n- **`GotoStmt`** - Goto statement\n- **`FallthroughStmt`** - Fallthrough statement\n- **`ReturnStmt`** - Return statement\n - `getResult(i)` to access return values\n\n## Expressions (Expr)\n\n### Literals\n\n- **`BasicLit`** subclasses:\n - **`IntLit`** - Integer literal\n - **`FloatLit`** - Floating point literal\n - **`ImagLit`** - Imaginary literal\n - **`CharLit`/`RuneLit`** - Character/rune literal\n - **`StringLit`** - String literal\n- **`CompositeLit`** - Composite literals:\n - **`StructLit`** - Struct literal "T{\u2026}"\n - **`MapLit`** - Map literal "map[K]V{\u2026}"\n- **`FuncLit`** - Function literal (anonymous function)\n\n### Unary Expressions\n\n- **`PlusExpr`** - Unary plus "+x"\n- **`MinusExpr`** - Unary minus "-x"\n- **`NotExpr`** - Logical not "!x"\n- **`ComplementExpr`** - Bitwise complement "^x"\n- **`AddressExpr`** - Address-of "&x"\n- **`RecvExpr`** - Channel receive "<-x"\n\n### Binary Expressions\n\n- **Arithmetic**: `MulExpr`, `QuoExpr`, `RemExpr`, `AddExpr`, `SubExpr`\n- **Shift**: `ShlExpr` "<<", `ShrExpr` ">>"\n- **Logical**: `LandExpr` "&&", `LorExpr` "||"\n- **Relational**: `LssExpr` "<", `GtrExpr` ">", `LeqExpr` "<=", `GeqExpr` ">="\n- **Equality**: `EqlExpr` "==", `NeqExpr` "!="\n- **Bitwise**: `AndExpr` "&", `OrExpr` "|", `XorExpr` "^", `AndNotExpr` "&^"\n\n### Access and Call Expressions\n\n- **`SelectorExpr`** - Field/method access "X.Y"\n - `getBase()`, `getSelector()`\n- **`CallExpr`** - Function/method call\n - `getCallee()`, `getAnArgument()`, `getArgument(i)`\n- **`IndexExpr`** - Array/slice/map index "a[i]"\n- **`SliceExpr`** - Slice expression "a[i:j:k]"\n- **`KeyValueExpr`** - Key-value pair in composite literals\n\n### Type-related Expressions\n\n- **`ParenExpr`** - Parenthesized expression\n- **`StarExpr`** - Pointer dereference/type\n- **`TypeAssertExpr`** - Type assertion "x.(T)"\n- **`Conversion`** - Type conversion "T(x)"\n\n## Type Expressions (no common superclass)\n\n- **`ArrayTypeExpr`** - Array type "[N]T" or slice type "[]T"\n- **`StructTypeExpr`** - Struct type "struct{\u2026}"\n- **`FuncTypeExpr`** - Function type "func(\u2026) \u2026"\n- **`InterfaceTypeExpr`** - Interface type\n- **`MapTypeExpr`** - Map type\n- **`ChanTypeExpr`** variants:\n - **`SendChanTypeExpr`** - Send-only channel\n - **`RecvChanTypeExpr`** - Receive-only channel\n - **`SendRecvChanTypeExpr`** - Bidirectional channel\n\n## Names and Identifiers\n\n### Name Hierarchy\n\n- **`Name`** subclasses:\n - **`SimpleName`** - Simple identifier\n - **`QualifiedName`** - Package-qualified name\n- **`ValueName`** subclasses:\n - **`ConstantName`** - Constant identifier\n - **`VariableName`** - Variable identifier\n - **`FunctionName`** - Function identifier\n\n### Specialized Names\n\n- **`PackageName`** - Package name identifier\n- **`TypeName`** - Type name identifier\n- **`LabelName`** - Label identifier\n\n## Declarations\n\n### Function Declarations\n\n- **`FuncDecl`/`FuncLit`** via **`FuncDef`**:\n - `getBody()`, `getName()`, `getParameter(i)`, `getResultVar(i)`, `getACall()`\n\n### General Declarations\n\n- **`GenDecl`** with:\n - **`ImportSpec`** - Import specification\n - **`TypeSpec`** - Type specification\n - **`ValueSpec`** - Variable/constant specification\n- **`Field`/`FieldList`** - For parameters, results, struct/interface fields\n\n## Navigation Idioms and Patterns\n\n### Control Flow Navigation\n\n- **If statements**: `getCondition()`, `getThen()`, `getElse()`\n- **For/Range loops**: inspect `getInit()`/`getCondition()`/`getPost()` or range expression\n- **Switch statements**: use `CaseClause`, `getExpr(i)`/`getStmt(i)`\n- **Select statements**: use `CommClause`\n\n### Function and Method Calls\n\n```ql\n// Method calls by name\nfrom CallExpr call, SelectorExpr sel\nwhere call.getCallee() = sel and sel.getMemberName() = "Close"\nselect call\n\n// Method vs function calls\n// SelectorExpr callee = method call\n// SimpleName callee = function call\n```\n\n### Assignment Operations\n\n- **Assignment**: match `AssignStmt` subclasses\n- **Short variable declaration**: `DefineStmt` for ":="\n- **Compound assignment**: `CompoundAssignStmt` for "+=", etc.\n\n### Binary and Unary Operations\n\n- Use specific subclasses or operator accessors\n- Access operands via `getLeftOperand()`, `getRightOperand()`\n\n### Literals and Composite Expressions\n\n- **Basic literals**: filter `BasicLit` subclasses\n- **Composite literals**: `CompositeLit` elements via keys/values\n- **Struct literals**: `StructLit` with type information\n\n## Common Query Patterns\n\n### Finding Specific Constructs\n\n```ql\n// Range over map/slice\nfrom RangeStmt r select r\n\n// Defer calls\nfrom DeferStmt d, CallExpr c\nwhere d.getExpr() = c\nselect d, c\n\n// Struct literal of specific type\nfrom StructLit lit\nwhere lit.getType().getName() = "Point"\nselect lit\n\n// Channel operations\nfrom SendStmt s select s // ch <- x\nfrom RecvStmt r select r // x = <-ch\n```\n\n### Method Resolution\n\n```ql\n// Find method calls on specific receiver types\nfrom CallExpr call, SelectorExpr sel\nwhere call.getCallee() = sel and\n sel.getBase().getType().toString() = "MyType"\nselect call\n```\n\n## File and Module Navigation\n\n- **`GoFile`** - Represents a Go source file\n- **`GoModFile`** - Represents a go.mod file\n- **`GoModModuleLine`** - Module declaration in go.mod\n- **`GoModGoLine`** - Go version declaration in go.mod\n\n## Comments and Documentation\n\n- **`CommentGroup`** - Group of related comments\n- **`DocComment`** - Documentation comment group (typically for functions/types)\n- **`SlashSlashComment`** - Single-line comment (//) within comment groups\n\n## Advanced Features\n\n### Generics Support\n\n- **`TypeParamDecl`** - Type parameter declaration with constraints\n- Generic type parameters and constraints for Go generics\n- Support for type inference and constraint satisfaction\n\n### Concurrency Constructs\n\n- **Goroutines**: `GoStmt` for "go f()" patterns\n- **Channels**: `SendStmt`, `RecvStmt`, `RecvExpr` for channel operations\n- **Select**: `SelectStmt` with `CommClause` for channel multiplexing\n- **Defer**: `DeferStmt` for cleanup patterns\n\n## Tips and Best Practices\n\n### Preferred Patterns\n\n- **Class tests over string parsing**: Use specific AST classes rather than string matching\n- **Type conversion disambiguation**: `CallExpr` callee is a `TypeExpr` for type conversions\n- **Statement vs expression**: Inc/Dec are statements, not expressions\n- **Assignment variants**: Handle ":=" vs "=" separately with `DefineStmt` vs `SimpleAssignStmt`\n- **Error handling**: Exclude `BadStmt`/`BadExpr` from analysis\n\n### Syntax to Class Mapping Cheatsheet\n\n- **Control Flow**: If\u2192`IfStmt`, For\u2192`ForStmt`, Range\u2192`RangeStmt`, Switch\u2192`SwitchStmt`/`ExpressionSwitchStmt`, Type switch\u2192`TypeSwitchStmt`, Select\u2192`SelectStmt`\n- **Cases**: Case\u2192`CaseClause`, Select case\u2192`CommClause`\n- **Assignment**: `=`\u2192`SimpleAssignStmt`, `:=`\u2192`DefineStmt`, `+=` etc.\u2192`CompoundAssignStmt`\n- **Increment**: `++`\u2192`IncStmt`, `--`\u2192`DecStmt`\n- **Access**: Call\u2192`CallExpr`, Selector\u2192`SelectorExpr`, Index\u2192`IndexExpr`, Slice\u2192`SliceExpr`\n- **Type operations**: Type assert\u2192`TypeAssertExpr`, Conversion\u2192`Conversion`\n- **Unary/Binary**: Specific subclasses of `UnaryExpr`/`BinaryExpr`\n- **Literals**: `IntLit`, `FloatLit`, `StringLit`, `StructLit`, `MapLit`, `FuncLit`\n- **Types**: `ArrayTypeExpr`, `StructTypeExpr`, `FuncTypeExpr`, `InterfaceTypeExpr`, `MapTypeExpr`, `ChanTypeExpr`\n\n## Expected test results for local `PrintAst.ql` query\n\nThis repo contains a variant of the open-source `PrintAst.ql` query for `go` language, with modifications for local testing:\n\n- Use the `codeql_query_run` tool with `queryName="PrintAST"` and `language="go"` to run the bundled PrintAST query\n- Use the `codeql_test_run` tool to run the PrintAST test and compare against expected results\n\n## Expected test results for open-source `PrintAst.ql` query\n\nThe following links can be fetched to get the expected results for different unit tests of the open-source `PrintAst.ql` query for the `go` language:\n\n- [library-tests/semmle/go/PrintAst/PrintAst.expected](https://github.com/github/codeql/blob/main/go/ql/test/library-tests/semmle/go/PrintAst/PrintAst.expected)\n- [library-tests/semmle/go/PrintAst/PrintAstExcludeComments.expected](https://github.com/github/codeql/blob/main/go/ql/test/library-tests/semmle/go/PrintAst/PrintAstExcludeComments.expected)\n- [library-tests/semmle/go/PrintAst/PrintAstNestedFunction.expected](https://github.com/github/codeql/blob/main/go/ql/test/library-tests/semmle/go/PrintAst/PrintAstNestedFunction.expected)\n- [library-tests/semmle/go/PrintAst/PrintAstRestrictFile.expected](https://github.com/github/codeql/blob/main/go/ql/test/library-tests/semmle/go/PrintAst/PrintAstRestrictFile.expected)\n- [library-tests/semmle/go/PrintAst/PrintAstRestrictFunction.expected](https://github.com/github/codeql/blob/main/go/ql/test/library-tests/semmle/go/PrintAst/PrintAstRestrictFunction.expected)\n';
|
|
63687
|
+
|
|
63688
|
+
// src/resources/languages/go_basic_queries.md
|
|
63689
|
+
var go_basic_queries_default = '# Basic CodeQL Query Examples for Go\n\n## Purpose\n\nMinimal Go query examples in VS Code; variables, constraints, and results for concrete bug patterns. Demonstrates query structure and common Go programming pattern detection.\n\n## Basic Query Structure\n\n### Query Components (SQL-like analogy)\n\n- **`import`**: Include standard Go library (`import go`)\n- **`from`**: Declare typed variables to range over (`Method`, `Variable`, `Write`, `Field`)\n- **`where`**: Constrain relationships among variables with predicates\n- **`select`**: Emit results; message can concatenate strings and AST entities\n\n### Template Structure\n\n```ql\nimport go\n\nfrom <Type1> var1, <Type2> var2, ...\nwhere <conditions and relationships>\nselect <results>, "<message with " + var1 + " references>"\n```\n\n## Example 1: Value Receiver Method Modifications\n\n### Target Pattern\n\nMethods defined on value receivers that write to a field have no effect (receiver is copied). Should use pointer receiver instead.\n\n### Query\n\n```ql\nimport go\n\nfrom Method m, Variable recv, Write w, Field f\nwhere recv = m.getReceiver() and\n w.writesField(recv.getARead(), f, _) and\n not recv.getType() instanceof PointerType\nselect w, "This update to " + f + " has no effect, because " + recv + " is not a pointer."\n```\n\n### Key Predicates\n\n- **`Method.getReceiver()`**: Receiver variable of a method\n- **`Write.writesField(baseRead, field, idx)`**: Write whose LHS writes field of base expression\n- **`Variable.getARead()`**: Read expression of the variable\n- **`PointerType`**: Type test to exclude pointer receivers\n\n## Example 2: Missing Error Handling\n\n### Target Pattern\n\nFunction calls that return errors but the error is ignored.\n\n### Query\n\n```ql\nimport go\n\nfrom CallExpr call, AssignStmt assign\nwhere call.getType().toString().matches("%error%") and\n assign.getRhs() = call and\n assign.getLhs().(Ident).getName() = "_"\nselect call, "Error from " + call.getTarget().getName() + " is ignored"\n```\n\n## Example 3: Nil Pointer Dereference Risk\n\n### Target Pattern\n\nPointer dereference without nil check.\n\n### Query\n\n```ql\nimport go\n\nfrom StarExpr deref, Variable ptr\nwhere deref.getExpr() = ptr.getARead() and\n not exists(IfStmt guard, NeqExpr check |\n check.getLeftOperand() = ptr.getARead() and\n check.getRightOperand().(Ident).getName() = "nil" and\n guard.getCondition() = check and\n deref.getParent*() = guard.getThen()\n )\nselect deref, "Potential nil pointer dereference of " + ptr\n```\n\n## Example 4: Goroutine Without Context\n\n### Target Pattern\n\nGoroutines launched without context cancellation mechanism.\n\n### Query\n\n```ql\nimport go\n\nfrom GoStmt goStmt, FuncLit funcLit\nwhere goStmt.getExpr() = funcLit and\n not exists(Parameter ctx |\n ctx = funcLit.getParameter(0) and\n ctx.getType().toString().matches("%context.Context%")\n )\nselect goStmt, "Goroutine launched without context parameter"\n```\n\n## Example 5: Unsafe Type Assertion\n\n### Target Pattern\n\nType assertions without the "ok" idiom to check success.\n\n### Query\n\n```ql\nimport go\n\nfrom TypeAssertExpr assert\nwhere not exists(TupleExpr tuple, VariableName ok |\n tuple = assert.getParent() and\n tuple.getElement(1) = ok.getARead() and\n ok.getName() = "ok"\n )\nselect assert, "Type assertion without ok check: " + assert.toString()\n```\n\n## Example 6: Resource Leak - Missing Close\n\n### Target Pattern\n\nFiles opened without corresponding defer close.\n\n### Query\n\n```ql\nimport go\n\nfrom CallExpr open, VariableName file\nwhere open.getTarget().hasQualifiedName("os", "Open") and\n open.getARead() = file.getARead() and\n not exists(DeferStmt defer, CallExpr close |\n close.getTarget().getName() = "Close" and\n close.getReceiver() = file.getARead() and\n defer.getExpr() = close\n )\nselect open, "File opened without defer close: " + file\n```\n\n## Example 7: SQL Injection Risk\n\n### Target Pattern\n\nString concatenation used to build SQL queries.\n\n### Query\n\n```ql\nimport go\n\nfrom CallExpr dbCall, AddExpr concat, StringLit sqlPart\nwhere dbCall.getTarget().hasQualifiedName("database/sql", ["Query", "Exec"]) and\n dbCall.getArgument(0) = concat and\n concat.getAnOperand() = sqlPart and\n sqlPart.getValue().matches("%SELECT%")\nselect concat, "SQL query built by concatenation, potential injection risk"\n```\n\n## Example 8: Command Injection Risk\n\n### Target Pattern\n\nUser input used directly in command execution.\n\n### Query\n\n```ql\nimport go\n\nfrom CallExpr execCall, CallExpr inputCall\nwhere execCall.getTarget().hasQualifiedName("os/exec", "Command") and\n inputCall.getTarget().hasQualifiedName("os", "Getenv") and\n DataFlow::localFlow(DataFlow::exprNode(inputCall), DataFlow::exprNode(execCall.getAnArgument()))\nselect execCall, "Environment variable flows to command execution"\n```\n\n## Example 9: Range Over Map in Goroutine\n\n### Target Pattern\n\nRange over map in goroutine without copying the value (race condition risk).\n\n### Query\n\n```ql\nimport go\n\nfrom GoStmt goStmt, RangeStmt rangeStmt, Variable mapVar\nwhere goStmt.getExpr().(FuncLit).getBody().getAStmt*() = rangeStmt and\n rangeStmt.getDomain() = mapVar.getARead() and\n mapVar.getType().toString().matches("map[%")\nselect rangeStmt, "Range over map " + mapVar + " in goroutine may cause race condition"\n```\n\n## Example 10: Slice Bounds Check Missing\n\n### Target Pattern\n\nSlice access without bounds checking.\n\n### Query\n\n```ql\nimport go\n\nfrom IndexExpr index, Variable slice\nwhere index.getBase() = slice.getARead() and\n slice.getType().toString().matches("[]%") and\n not exists(IfStmt guard, CallExpr lenCall, RelationalComparisonExpr compare |\n lenCall.getTarget().getName() = "len" and\n lenCall.getArgument(0) = slice.getARead() and\n compare.getAnOperand() = index.getIndex() and\n compare.getAnOperand() = lenCall and\n guard.getCondition() = compare\n )\nselect index, "Slice access without bounds check: " + slice\n```\n\n## Usage Patterns\n\n### Finding Specific Function Calls\n\n```ql\n// Find all calls to specific function\nfrom CallExpr call\nwhere call.getTarget().hasQualifiedName("fmt", "Printf")\nselect call\n\n// Find method calls on specific type\nfrom CallExpr call, SelectorExpr sel\nwhere call.getCallee() = sel and\n sel.getBase().getType().toString() = "MyType" and\n sel.getSelector().getName() = "MyMethod"\nselect call\n```\n\n### Working with Control Flow\n\n```ql\n// Find if statements with specific conditions\nfrom IfStmt ifStmt, EqlExpr eq\nwhere ifStmt.getCondition() = eq and\n eq.getRightOperand().(Ident).getName() = "nil"\nselect ifStmt\n\n// Find loops with range\nfrom RangeStmt rangeStmt\nwhere rangeStmt.getKey().getName() != "_" and\n rangeStmt.getValue().getName() != "_"\nselect rangeStmt\n```\n\n### Package and Import Analysis\n\n```ql\n// Find specific imports\nfrom ImportSpec spec\nwhere spec.getPath().getValue() = "unsafe"\nselect spec, "Unsafe package imported"\n\n// Find package-level variables\nfrom Variable v\nwhere v.isPackageLevel() and\n v.getName().matches("debug%")\nselect v\n```\n\n## Testing and Refinement\n\n### Running Queries in VS Code\n\n1. Open VS Code with CodeQL extension\n2. Paste query after `import go`\n3. Click "Run Query" or use Ctrl+Shift+P \u2192 "CodeQL: Run Query"\n4. Click results to jump to code locations\n\n### Refining Results\n\n```ql\n// Add guards to exclude false positives\nwhere not exists(CommentGroup comment |\n comment.getText().matches("%TODO%") and\n comment.getLocation().getStartLine() < result.getLocation().getStartLine()\n )\n\n// Restrict to specific files or packages\nwhere result.getFile().getBaseName().matches("%.go") and\n not result.getFile().getAbsolutePath().matches("%test%")\n```\n\n### Extensions and Improvements\n\n- Add guards to exclude writes to temporary copies\n- Restrict to exported methods/types\n- Focus on specific packages with `hasQualifiedName`\n- Convert to path queries to show data flow\n- Add more specific type checking\n\nThese examples provide practical starting points for finding real Go programming issues and can be customized for specific codebases and requirements.\n';
|
|
63690
|
+
|
|
63691
|
+
// src/resources/languages/go_dataflow.md
|
|
63692
|
+
var go_dataflow_default = '# Analyzing Data Flow in Go\n\n## Purpose\n\nUse CodeQL\'s Go data-flow libraries to find how values and taint propagate through Go programs. Cover local flow/taint (intra-procedural) and global flow/taint (inter-procedural), with configurable sources/sinks/barriers.\n\n## Core Concepts\n\n### Data Flow vs Taint Tracking\n\n- **Data Flow**: Tracks exact value preservation through assignments, calls, and returns\n- **Taint Tracking**: Tracks influence/contamination, including non-value-preserving operations like concatenation\n\n### Node Hierarchy\n\n- **`Node`** - Base class for data flow nodes\n - **`ExprNode`** - Expression in the AST\n - **`ParameterNode`** - Function parameter\n - **`InstructionNode`** - Intermediate representation instruction\n\n### Node Conversion\n\n- **AST to DataFlow**: `DataFlow::exprNode(expr)`, `DataFlow::parameterNode(param)`\n- **DataFlow to AST**: `node.asExpr()`, `node.asParameter()`, `node.asInstruction()`\n\n## Local Data Flow\n\n### Basic Predicates\n\n- **`localFlowStep(Node a, Node b)`** - Direct flow from `a` to `b` within same function\n- **`localFlow(Node a, Node b)`** - Transitive closure (`localFlowStep*`)\n\n### Example: Tracking to Function Arguments\n\n```ql\nimport go\nfrom Function osOpen, CallExpr call, Expr src\nwhere osOpen.hasQualifiedName("os","Open") and\n call.getTarget() = osOpen and\n DataFlow::localFlow(DataFlow::exprNode(src), DataFlow::exprNode(call.getArgument(0)))\nselect src, "flows to os.Open argument"\n```\n\n### Local Flow Patterns\n\n```ql\n// Variable assignment flow\nfrom Variable v, Expr source, Expr use\nwhere DataFlow::localFlow(DataFlow::exprNode(source), DataFlow::exprNode(use)) and\n source = v.getAnAssignment() and\n use = v.getARead()\nselect source, use\n\n// Parameter to return flow\nfrom Function f, Parameter p, ReturnStmt ret\nwhere DataFlow::localFlow(DataFlow::parameterNode(p), DataFlow::exprNode(ret.getAResult()))\nselect p, ret\n```\n\n## Local Taint Tracking\n\n### Basic Predicates\n\n- **`localTaintStep(Node a, Node b)`** - Direct taint from `a` to `b`\n- **`localTaint(Node a, Node b)`** - Transitive taint closure\n\n### Taint vs Flow Examples\n\n```ql\n// String concatenation - taint but not flow\nfrom Expr source, Expr concat\nwhere concat.(AddExpr).getAnOperand() = source and\n TaintTracking::localTaint(DataFlow::exprNode(source), DataFlow::exprNode(concat))\nselect source, concat\n\n// Array element access - taint propagation\nfrom Expr array, Expr element\nwhere element.(IndexExpr).getBase() = array and\n TaintTracking::localTaint(DataFlow::exprNode(array), DataFlow::exprNode(element))\nselect array, element\n```\n\n## Global Data Flow\n\n### Configuration Interface\n\nImplement `DataFlow::ConfigSig`:\n\n```ql\nmodule MyConfig implements DataFlow::ConfigSig {\n predicate isSource(DataFlow::Node source) {\n // Define where flow starts\n }\n\n predicate isSink(DataFlow::Node sink) {\n // Define where flow ends\n }\n\n predicate isBarrier(DataFlow::Node node) {\n // Optional: block flow through certain nodes\n }\n\n predicate isAdditionalFlowStep(DataFlow::Node node1, DataFlow::Node node2) {\n // Optional: add custom flow edges\n }\n}\n\nmodule MyFlow = DataFlow::Global<MyConfig>;\n```\n\n### Usage Pattern\n\n```ql\nfrom DataFlow::Node source, DataFlow::Node sink\nwhere MyFlow::flow(source, sink)\nselect source, "flows to $@", sink, "sink"\n```\n\n### Complete Example: Hard-coded Strings to URL Parse\n\n```ql\nmodule StringToUrlConfig implements DataFlow::ConfigSig {\n predicate isSource(DataFlow::Node source) {\n source.asExpr() instanceof StringLit\n }\n\n predicate isSink(DataFlow::Node sink) {\n exists(CallExpr call |\n call.getTarget().hasQualifiedName("net/url", "Parse") and\n sink.asExpr() = call.getArgument(0)\n )\n }\n}\n\nmodule StringToUrlFlow = DataFlow::Global<StringToUrlConfig>;\n\nfrom DataFlow::Node source, DataFlow::Node sink\nwhere StringToUrlFlow::flow(source, sink)\nselect source, "String literal flows to URL parse $@", sink, "here"\n```\n\n## Global Taint Tracking\n\n### Configuration Interface\n\nSame as data flow but with taint semantics:\n\n```ql\nmodule MyTaintConfig implements TaintTracking::ConfigSig {\n predicate isSource(DataFlow::Node source) {\n source instanceof RemoteFlowSource // Built-in remote sources\n }\n\n predicate isSink(DataFlow::Node sink) {\n exists(CallExpr call |\n call.getTarget().hasQualifiedName("os/exec", "Command") and\n sink.asExpr() = call.getAnArgument()\n )\n }\n}\n\nmodule MyTaintFlow = TaintTracking::Global<MyTaintConfig>;\n```\n\n### Built-in Sources\n\n```ql\n// RemoteFlowSource covers common user input sources\nclass MyRemoteSource extends RemoteFlowSource {\n MyRemoteSource() {\n // Additional remote sources beyond built-ins\n }\n}\n```\n\n## Advanced Flow Configuration\n\n### Custom Flow Steps\n\n```ql\npredicate isAdditionalFlowStep(DataFlow::Node node1, DataFlow::Node node2) {\n // Custom builder pattern\n exists(CallExpr call |\n call.getTarget().getName() = "WithValue" and\n node1.asExpr() = call.getReceiver() and\n node2.asExpr() = call\n )\n or\n // Flow through slice append\n exists(CallExpr append |\n append.getTarget().getName() = "append" and\n node1.asExpr() = append.getAnArgument() and\n node2.asExpr() = append\n )\n}\n```\n\n### Barriers and Sanitizers\n\n```ql\npredicate isBarrier(DataFlow::Node node) {\n // Block flow through validation functions\n exists(CallExpr call |\n call.getTarget().getName().matches("%Validate%") and\n node.asExpr() = call\n )\n or\n // Block at error checks\n exists(IfStmt guard, NeqExpr check |\n check.getRightOperand().(Ident).getName() = "nil" and\n guard.getCondition() = check and\n node.asExpr().getParent*() = guard.getThen()\n )\n}\n```\n\n## Common Data Flow Patterns\n\n### Environment Variables to Sinks\n\n```ql\nclass GetenvSource extends DataFlow::Node {\n GetenvSource() {\n exists(CallExpr call |\n call.getTarget().hasQualifiedName("os", "Getenv") and\n this.asExpr() = call\n )\n }\n}\n\nmodule EnvToSinkConfig implements DataFlow::ConfigSig {\n predicate isSource(DataFlow::Node source) { source instanceof GetenvSource }\n predicate isSink(DataFlow::Node sink) { /* define sinks */ }\n}\n```\n\n### Command Line Arguments\n\n```ql\nclass CommandLineArgSource extends DataFlow::Node {\n CommandLineArgSource() {\n exists(IndexExpr access |\n access.getBase().(Ident).getName() = "Args" and\n access.getBase().getType().toString() = "[]string" and\n this.asExpr() = access\n )\n }\n}\n```\n\n### HTTP Request Data\n\n```ql\nclass HttpRequestSource extends DataFlow::Node {\n HttpRequestSource() {\n exists(CallExpr call, SelectorExpr sel |\n sel.getBase().getType().toString().matches("%Request%") and\n sel.getSelector().getName() in ["FormValue", "PostFormValue", "Header"] and\n call.getCallee() = sel and\n this.asExpr() = call\n )\n }\n}\n```\n\n### Database Queries\n\n```ql\npredicate isDatabaseQuerySink(DataFlow::Node sink) {\n exists(CallExpr call, Function target |\n call.getTarget() = target and\n target.hasQualifiedName("database/sql", ["Query", "QueryRow", "Exec", "Prepare"]) and\n sink.asExpr() = call.getArgument(0)\n )\n}\n```\n\n## Path Queries for Better Results\n\n### Basic Path Query Structure\n\n```ql\n/**\n * @kind path-problem\n */\nimport go\nimport DataFlow::PathGraph\n\n// ... config definition ...\n\nfrom MyFlow::PathNode source, MyFlow::PathNode sink\nwhere MyFlow::flowPath(source, sink)\nselect sink.getNode(), source, sink,\n "Value from $@ reaches sink", source.getNode(), "source"\n```\n\n### Multi-step Flow Analysis\n\n```ql\n// First: literal to getenv parameter\nmodule LiteralToGetenvConfig implements DataFlow::ConfigSig {\n predicate isSource(DataFlow::Node source) { source.asExpr() instanceof StringLit }\n predicate isSink(DataFlow::Node sink) {\n exists(CallExpr call |\n call.getTarget().hasQualifiedName("os", "Getenv") and\n sink.asExpr() = call.getArgument(0)\n )\n }\n}\n\n// Second: getenv result to url.Parse\nmodule GetenvToUrlConfig implements DataFlow::ConfigSig {\n predicate isSource(DataFlow::Node source) {\n exists(CallExpr call |\n call.getTarget().hasQualifiedName("os", "Getenv") and\n source.asExpr() = call\n )\n }\n predicate isSink(DataFlow::Node sink) {\n exists(CallExpr call |\n call.getTarget().hasQualifiedName("net/url", "Parse") and\n sink.asExpr() = call.getArgument(0)\n )\n }\n}\n```\n\n## Performance and Precision Tips\n\n### Query Optimization\n\n- Start with local flow/taint for better performance\n- Use specific predicates rather than broad matching\n- Prefer `hasQualifiedName` over string patterns\n- Add barriers to reduce false paths\n\n### Debugging Flow\n\n```ql\n// Debug: show intermediate flow steps\nfrom DataFlow::Node n1, DataFlow::Node n2\nwhere DataFlow::localFlowStep(n1, n2) and\n n1.getFile().getBaseName() = "target.go"\nselect n1, n2\n```\n\n### Testing Configurations\n\n```ql\n// Test source identification\nfrom DataFlow::Node source\nwhere MyConfig::isSource(source)\nselect source\n\n// Test sink identification\nfrom DataFlow::Node sink\nwhere MyConfig::isSink(sink)\nselect sink\n```\n\n## Integration with Security Queries\n\n### Combining Multiple Configurations\n\n```ql\n// Union of different taint sources\npredicate isAnyTaintSource(DataFlow::Node source) {\n source instanceof RemoteFlowSource or\n source instanceof GetenvSource or\n source instanceof CommandLineArgSource\n}\n\n// Combined configuration\nmodule UnifiedTaintConfig implements TaintTracking::ConfigSig {\n predicate isSource(DataFlow::Node source) { isAnyTaintSource(source) }\n predicate isSink(DataFlow::Node sink) { /* any dangerous sink */ }\n}\n```\n\n### Framework-specific Flow\n\n```ql\n// Framework method chaining\npredicate isFrameworkFlowStep(DataFlow::Node node1, DataFlow::Node node2) {\n exists(CallExpr call |\n call.getReceiver() = node1.asExpr() and\n call.getTarget().getName().regexpMatch("With|Set|Add") and\n node2.asExpr() = call\n )\n}\n```\n\nThis provides the foundation for building sophisticated security queries that can track how untrusted data flows through Go programs to reach dangerous operations.\n';
|
|
63693
|
+
|
|
63694
|
+
// src/resources/languages/go_library_modeling.md
|
|
63695
|
+
var go_library_modeling_default = "# Customizing Library Models for Go\n\n## Purpose\n\nCustomize data-flow/taint analysis for Go by modeling frameworks/libraries via data extensions (YAML) and model packs. This enables accurate flow tracking through third-party libraries not included in CodeQL databases.\n\n## Data Extensions Overview\n\n### Structure\n\nData extensions use YAML format to extend CodeQL's knowledge of library behavior:\n\n```yaml\nextensions:\n - addsTo:\n pack: codeql/go-all\n extensible: <extensible-predicate>\n data:\n - <tuple1>\n - <tuple2>\n```\n\n### Union Semantics\n\n- Multiple YAML files are combined\n- Rows are merged across files\n- Duplicates are automatically removed\n- Order of files doesn't matter\n\n## Extensible Predicates for Go\n\n### Source Models\n\n**`sourceModel(package, type, subtypes, name, signature, ext, output, kind, provenance)`**\n\nDefine sources of untrusted data (e.g., user input):\n\n- **package**: Go package path (e.g., \"net/http\")\n- **type**: Type name (\"\" for package-level functions)\n- **subtypes**: Include subtypes (true/false)\n- **name**: Function/method name\n- **signature**: Function signature (\"\" for any)\n- **ext**: External library marker (\"\" for stdlib)\n- **output**: Access path where taint emerges\n- **kind**: Threat model category\n- **provenance**: Origin marker (manual/ai-manual/etc.)\n\n**Example**: HTTP request as source\n\n```yaml\n- ['net/http', 'Request', false, 'FormValue', '', '', 'ReturnValue', 'remote', 'manual']\n```\n\n### Sink Models\n\n**`sinkModel(package, type, subtypes, name, signature, ext, input, kind, provenance)`**\n\nDefine dangerous operations (sinks):\n\n- **input**: Access path where taint is dangerous\n\n**Example**: Command execution sink\n\n```yaml\n- ['os/exec', '', false, 'Command', '', '', 'Argument[1]', 'command-injection', 'manual']\n```\n\n### Summary Models\n\n**`summaryModel(package, type, subtypes, name, signature, ext, input, output, kind, provenance)`**\n\nDefine how data flows through functions when dependency code isn't in the database:\n\n- **input**: Where data enters the function\n- **output**: Where data exits the function\n\n**Example**: String builder flow\n\n```yaml\n- ['strings', 'Builder', false, 'WriteString', '', '', 'Argument[0]', 'Receiver', 'taint', 'manual']\n```\n\n### Neutral Models\n\n**`neutralModel(package, type, name, signature, kind, provenance)`**\n\nDefine low-impact flows to reduce over-taint/noise:\n\n**Example**: Safe string operations\n\n```yaml\n- ['strings', '', 'ToUpper', '', 'value', 'manual']\n```\n\n## Access Paths\n\n### Basic Access Paths\n\n- **`Argument[i]`** - ith argument (0-indexed)\n- **`ReturnValue`** - Function return value\n- **`Receiver`** - Method receiver\n- **`Qualifier`** - Object being called on\n\n### Complex Access Paths\n\n- **`Argument[i].Field[\"name\"]`** - Field of argument\n- **`Argument[i].ArrayElement`** - Array/slice elements\n- **`ReturnValue.ArrayElement`** - Elements of returned array/slice\n- **`Field[\"name\"].ArrayElement`** - Elements of field array\n\n### Examples\n\n```yaml\n# Array/slice element flow\n- ['slices', '', false, 'Max', '', '', 'Argument[0].ArrayElement', 'ReturnValue', 'value', 'manual']\n\n# Nested array flow\n- [\n 'slices',\n '',\n false,\n 'Concat',\n '',\n '',\n 'Argument[0].ArrayElement.ArrayElement',\n 'ReturnValue.ArrayElement',\n 'value',\n 'manual'\n ]\n\n# Struct field flow\n- [\n 'encoding/json',\n '',\n false,\n 'Unmarshal',\n '',\n '',\n 'Argument[0]',\n 'Argument[1].Field[*]',\n 'taint',\n 'manual'\n ]\n```\n\n## Flow Kinds\n\n### Value vs Taint\n\n- **\"value\"**: Moves whole values (precise data flow)\n- **\"taint\"**: Propagates taint only (influence tracking)\n\n### Security Categories\n\nCommon `kind` values for threat modeling:\n\n- **\"remote\"**: Remote user input\n- **\"command-injection\"**: Command execution\n- **\"sql-injection\"**: Database queries\n- **\"path-injection\"**: File system access\n- **\"code-injection\"**: Code execution\n- **\"xss\"**: Cross-site scripting\n\n## Complete Examples\n\n### HTTP Framework Modeling\n\n```yaml\nextensions:\n - addsTo:\n pack: codeql/go-all\n extensible: sourceModel\n data:\n # HTTP request sources\n - ['net/http', 'Request', false, 'FormValue', '', '', 'ReturnValue', 'remote', 'manual']\n - ['net/http', 'Request', false, 'PostFormValue', '', '', 'ReturnValue', 'remote', 'manual']\n - ['net/http', 'Request', false, 'Header', '', '', 'ReturnValue', 'remote', 'manual']\n - ['net/http', 'Request', false, 'URL', '', '', 'ReturnValue.Field[*]', 'remote', 'manual']\n\n - addsTo:\n pack: codeql/go-all\n extensible: sinkModel\n data:\n # HTTP response sinks\n - ['net/http', 'ResponseWriter', false, 'Write', '', '', 'Argument[0]', 'xss', 'manual']\n - [\n 'net/http',\n 'ResponseWriter',\n false,\n 'Header',\n '',\n '',\n 'ReturnValue',\n 'response-header',\n 'manual'\n ]\n```\n\n### Database Library Modeling\n\n```yaml\nextensions:\n - addsTo:\n pack: codeql/go-all\n extensible: summaryModel\n data:\n # Database query builders\n - [\n 'github.com/jmoiron/sqlx',\n 'DB',\n false,\n 'Query',\n '',\n '',\n 'Argument[0]',\n 'ReturnValue.Field[*]',\n 'taint',\n 'manual'\n ]\n - [\n 'github.com/jmoiron/sqlx',\n 'DB',\n false,\n 'Select',\n '',\n '',\n 'Argument[1]',\n 'Argument[0].Field[*]',\n 'taint',\n 'manual'\n ]\n\n - addsTo:\n pack: codeql/go-all\n extensible: sinkModel\n data:\n # SQL injection sinks\n - [\n 'github.com/jmoiron/sqlx',\n 'DB',\n false,\n 'Query',\n '',\n '',\n 'Argument[0]',\n 'sql-injection',\n 'manual'\n ]\n - [\n 'github.com/jmoiron/sqlx',\n 'DB',\n false,\n 'Exec',\n '',\n '',\n 'Argument[0]',\n 'sql-injection',\n 'manual'\n ]\n```\n\n### JSON Processing\n\n```yaml\nextensions:\n - addsTo:\n pack: codeql/go-all\n extensible: summaryModel\n data:\n # JSON unmarshaling\n - [\n 'encoding/json',\n '',\n false,\n 'Unmarshal',\n '',\n '',\n 'Argument[0]',\n 'Argument[1].Field[*]',\n 'taint',\n 'manual'\n ]\n - [\n 'encoding/json',\n '',\n false,\n 'Marshal',\n '',\n '',\n 'Argument[0].Field[*]',\n 'ReturnValue',\n 'taint',\n 'manual'\n ]\n\n - addsTo:\n pack: codeql/go-all\n extensible: sourceModel\n data:\n # JSON from HTTP as source\n - [\n 'encoding/json',\n 'Decoder',\n false,\n 'Decode',\n '',\n '',\n 'Argument[0].Field[*]',\n 'remote',\n 'manual'\n ]\n```\n\n### String Processing Libraries\n\n```yaml\nextensions:\n - addsTo:\n pack: codeql/go-all\n extensible: summaryModel\n data:\n # String builder patterns\n - [\n 'strings',\n 'Builder',\n false,\n 'WriteString',\n '',\n '',\n 'Argument[0]',\n 'Receiver',\n 'taint',\n 'manual'\n ]\n - [\n 'strings',\n 'Builder',\n false,\n 'String',\n '',\n '',\n 'Receiver',\n 'ReturnValue',\n 'taint',\n 'manual'\n ]\n\n # Template processing\n - [\n 'text/template',\n 'Template',\n false,\n 'Execute',\n '',\n '',\n 'Argument[1].Field[*]',\n 'Argument[0]',\n 'taint',\n 'manual'\n ]\n - [\n 'html/template',\n 'Template',\n false,\n 'Execute',\n '',\n '',\n 'Argument[1].Field[*]',\n 'Argument[0]',\n 'taint',\n 'manual'\n ]\n```\n\n## Model Packs\n\n### Pack Structure\n\nCreate a CodeQL model pack to group and distribute YAML files:\n\n```yaml\n# codeql-pack.yml\nname: my-org/go-security-models\nversion: 1.0.0\ndependencies:\n codeql/go-all: '*'\ndataExtensions: '*.yml'\n```\n\n### Directory Structure\n\n```\nmy-go-models/\n\u251C\u2500\u2500 codeql-pack.yml\n\u251C\u2500\u2500 http-frameworks.yml\n\u251C\u2500\u2500 database-orms.yml\n\u2514\u2500\u2500 json-libraries.yml\n```\n\n### Publishing to GitHub Container Registry\n\n```bash\ncodeql pack publish\n```\n\n### Consuming Model Packs\n\n```yaml\n# In consumer's codeql-pack.yml\ndependencies:\n my-org/go-security-models: '^1.0.0'\n```\n\nOr via CLI:\n\n```bash\ncodeql database analyze --packs my-org/go-security-models\n```\n\n## Advanced Patterns\n\n### Framework-specific Source Patterns\n\n```yaml\n# Gin framework\n- ['github.com/gin-gonic/gin', 'Context', false, 'Param', '', '', 'ReturnValue', 'remote', 'manual']\n- ['github.com/gin-gonic/gin', 'Context', false, 'Query', '', '', 'ReturnValue', 'remote', 'manual']\n- [\n 'github.com/gin-gonic/gin',\n 'Context',\n false,\n 'PostForm',\n '',\n '',\n 'ReturnValue',\n 'remote',\n 'manual'\n ]\n\n# Echo framework\n- [\n 'github.com/labstack/echo/v4',\n 'Context',\n false,\n 'Param',\n '',\n '',\n 'ReturnValue',\n 'remote',\n 'manual'\n ]\n- [\n 'github.com/labstack/echo/v4',\n 'Context',\n false,\n 'QueryParam',\n '',\n '',\n 'ReturnValue',\n 'remote',\n 'manual'\n ]\n- [\n 'github.com/labstack/echo/v4',\n 'Context',\n false,\n 'FormValue',\n '',\n '',\n 'ReturnValue',\n 'remote',\n 'manual'\n ]\n```\n\n### ORM and Query Builder Models\n\n```yaml\n# GORM models\n- ['gorm.io/gorm', 'DB', false, 'Raw', '', '', 'Argument[0]', 'ReturnValue', 'taint', 'manual']\n- ['gorm.io/gorm', 'DB', false, 'Exec', '', '', 'Argument[0]', '', 'sql-injection', 'manual']\n\n# Squirrel query builder\n- [\n 'github.com/Masterminds/squirrel',\n 'SelectBuilder',\n false,\n 'Where',\n '',\n '',\n 'Argument[0]',\n 'Receiver',\n 'taint',\n 'manual'\n ]\n- [\n 'github.com/Masterminds/squirrel',\n 'SelectBuilder',\n false,\n 'ToSql',\n '',\n '',\n 'Receiver',\n 'ReturnValue',\n 'taint',\n 'manual'\n ]\n```\n\n### Utility Library Flows\n\n```yaml\n# Viper configuration\n- ['github.com/spf13/viper', '', false, 'GetString', '', '', '', 'ReturnValue', 'config', 'manual']\n- ['github.com/spf13/viper', '', false, 'Get', '', '', '', 'ReturnValue', 'config', 'manual']\n\n# Cobra CLI arguments\n- [\n 'github.com/spf13/cobra',\n 'Command',\n false,\n 'Flags',\n '',\n '',\n '',\n 'ReturnValue',\n 'cli-input',\n 'manual'\n ]\n```\n\n## Workflow and Best Practices\n\n### Development Process\n\n1. **Identify Gap**: Find library calls that break data flow paths\n2. **Analyze Library**: Understand how data flows through the library\n3. **Create Models**: Start with summaries for common flows\n4. **Add Sources/Sinks**: Define security-relevant entry/exit points\n5. **Test and Iterate**: Validate with path queries and unit tests\n\n### Model Quality Guidelines\n\n- **Narrow Matching**: Use `hasQualifiedName` for precision\n- **Specific Access Paths**: Be precise about which fields/elements flow\n- **Appropriate Kinds**: Match `kind` to actual threat model\n- **Documentation**: Comment complex access paths\n- **Testing**: Validate with realistic code examples\n\n### Performance Considerations\n\n- Avoid overly broad models that create too many paths\n- Use `neutralModel` to reduce noise from safe operations\n- Consider performance impact of complex access paths\n- Test query performance with models enabled\n\n### Integration Testing\n\n```ql\n// Test model coverage\nfrom DataFlow::Node source, DataFlow::Node sink\nwhere MyFlow::flow(source, sink) and\n source.getFile().getBaseName() = \"test_library.go\"\nselect source, sink\n\n// Verify specific library modeling\nfrom CallExpr call\nwhere call.getTarget().hasQualifiedName(\"my/library\", \"MyFunction\")\nselect call, \"Library call found\"\n```\n\nThis comprehensive approach to library modeling enables accurate security analysis even when third-party library source code isn't available in the CodeQL database.\n";
|
|
63696
|
+
|
|
63697
|
+
// src/resources/languages/go_security_query_guide.md
|
|
63698
|
+
var go_security_query_guide_default = "# Go Security Query Guide\n\nLanguage-specific notes for writing Go security queries in CodeQL. For the general taint-tracking template and workflow, see the `security_templates` resource.\n\n## Imports\n\n```ql\nimport go\n```\n\nThe `go` top-level import re-exports data flow, taint tracking, and standard library models. For path-problem queries add `import MyFlow::PathGraph` after defining your flow module.\n\n## Sources and Sinks\n\n- **Sources**: Use `RemoteFlowSource` (covers `net/http` handlers, gRPC, and other HTTP frameworks). Also consider `UntrustedFlowSource` for broader input coverage.\n- **Sinks**: Model as `DataFlow::Node` subclasses matching dangerous APIs (e.g., `os/exec`, `database/sql`, `html/template`). Existing sink libraries live under `semmle.go.security.*`.\n- **Barriers**: Model sanitizers as `DataFlow::Node` subclasses and reference them in `isBarrier`.\n\n## Key Library Modules\n\n| Module | Purpose |\n| ---------------------------------- | ---------------------------------------- |\n| `semmle.go.dataflow.DataFlow` | Data flow nodes and global analysis |\n| `semmle.go.dataflow.TaintTracking` | Taint tracking analysis |\n| `semmle.go.security.*` | Pre-built vulnerability-specific configs |\n| `semmle.go.frameworks.*` | Framework-specific API models |\n";
|
|
63699
|
+
|
|
63700
|
+
// src/resources/languages/java_ast.md
|
|
63701
|
+
var java_ast_default = '# CodeQL AST nodes for `java` language\n\n## CodeQL\'s core AST classes for `java` language\n\nBased on comprehensive analysis of CodeQL\'s Java test results from GitHub, here are the core AST classes for Java analysis:\n\n### Compilation and Package Structure\n\n**Top-Level Units:**\n\n- `CompilationUnit` - Java source file compilation units (e.g., `CompilationUnit A`)\n- `ImportType` - Single type imports (e.g., `import HashMap`, `import IOException`)\n- `ImportOnDemandFromPackage` - Wildcard imports (e.g., `import java.util.*`)\n\n### Class and Interface Declarations\n\n**Class Structure:**\n\n- `Class` - Class declarations (e.g., `class A`, `class Test`)\n- `Interface` - Interface declarations (e.g., `interface Ann1`)\n- `GenericType` - Generic classes with type parameters\n- `ParameterizedType` - Parameterized types with specific type arguments\n\n**Generic Support:**\n\n- `TypeVariable` - Generic type parameters (e.g., `T`, `S extends Comparable`)\n- Generic class declarations and instantiations\n- Diamond operator support (`<>`) for type inference\n\n### Type System\n\n**Basic Type Access:**\n\n- `TypeAccess` - Type references (e.g., `String`, `int`, `void`, `Object`)\n- `ArrayTypeAccess` - Array types (e.g., `String[]`, `int[][]`)\n- Type access in generic contexts (e.g., `List<String>`, `Map<String,Integer>`)\n\n**Advanced Type Features:**\n\n- Parameterized types with multiple type arguments\n- Nested type access and inner class types\n- Array types with multiple dimensions\n\n### Field and Variable Declarations\n\n**Field Declarations:**\n\n- `FieldDeclaration` - Class field declarations (e.g., `String[] a;`, `float ff;`)\n- Field initialization with expressions\n- Generic field types (e.g., `List<> l`, `Map<String,Integer> m`)\n\n**Variable Declarations:**\n\n- `LocalVariableDeclStmt` - Local variable declaration statements\n- `LocalVariableDeclExpr` - Local variable declarator expressions\n- `Parameter` - Method and constructor parameters\n- `VarDecl` - Variable declaration identifiers\n\n### Method and Constructor Declarations\n\n**Method Structure:**\n\n- `Method` - Method declarations with return types and parameters\n- `Constructor` - Constructor declarations\n- Method signatures with generic types and varargs support\n\n**Parameter Handling:**\n\n- Parameter declarations with type access\n- Varargs parameters (e.g., `int... is`, `Object... os`)\n- Generic parameter types\n\n### Expressions\n\n**Primary Expressions:**\n\n- `IntegerLiteral` - Integer constants (e.g., `42`, `1`, `2`)\n- `FloatLiteral` - Floating-point literals (e.g., `2.3f`)\n- `StringLiteral` - String literals (e.g., `"hello"`, `"rawtypes"`)\n- `NullLiteral` - Null literal (`null`)\n- `BooleanLiteral` - Boolean literals (`true`, `false`)\n\n**Variable Access:**\n\n- `VarAccess` - Variable references (e.g., `thing`, `o`, `Initializers.SFIELD`)\n- Qualified variable access with type prefixes\n\n**Object Creation:**\n\n- `ClassInstanceExpr` - Object instantiation (e.g., `new ArrayList<>()`, `new LinkedHashMap<String,Integer>()`)\n- Constructor calls with type arguments\n- Anonymous class instances\n\n**Method Calls:**\n\n- `MethodCall` - Method invocations (e.g., `source()`, `sink()`)\n- Method calls with arguments and generic types\n\n**Type Operations:**\n\n- `CastExpr` - Type casting (e.g., `(E) thing`)\n- `InstanceOfExpr` - instanceof checks with pattern matching\n\n### Statements\n\n**Control Flow:**\n\n- `BlockStmt` - Block statements containing multiple statements\n- `IfStmt` - Conditional statements\n- `SwitchStmt` - Switch statements with traditional and pattern cases\n- `SwitchExpr` - Switch expressions with yield statements\n- `ReturnStmt` - Return statements\n- `YieldStmt` - Yield statements in switch expressions\n\n**Exception Handling:**\n\n- `TryStmt` - Try-catch-finally statements\n- `CatchClause` - Catch clauses with exception types\n- `ThrowStmt` - Throw statements\n- Multi-catch support for multiple exception types\n\n**Constructor Calls:**\n\n- `ThisConstructorInvocationStmt` - this() constructor calls\n- `SuperConstructorInvocationStmt` - super() constructor calls\n\n### Modern Java Features\n\n**Pattern Matching (Java 14+):**\n\n- `PatternCase` - Pattern matching in switch statements\n- `RecordPatternExpr` - Record pattern matching expressions\n- Pattern case declarations with local variables\n- Guarded patterns and complex pattern matching\n\n**Switch Expressions:**\n\n- `ConstCase` - Traditional constant cases\n- `DefaultCase` - Default cases in switch statements\n- Pattern-based case statements with guards\n\n**Records (Java 14+):**\n\n- Record declarations and pattern matching\n- Record component access and destructuring\n\n### Annotations and Documentation\n\n**Annotations:**\n\n- `Annotation` - Annotation usage (e.g., `@SuppressWarnings("rawtypes")`)\n- Annotation with arguments and values\n\n**Documentation:**\n\n- `Javadoc` - Javadoc comments (e.g., `/** A JavaDoc comment */`)\n- `JavadocText` - Text content within Javadoc\n- `JavadocTag` - Javadoc tags (e.g., `@author someone`)\n- Multi-line Javadoc support\n\n### Enum Support\n\n**Enumeration Features:**\n\n- Enum class declarations\n- Enum constant declarations with initialization\n- Enum constants with constructor arguments\n\n### Lambda Expressions and Functional Interfaces\n\n**Functional Programming:**\n\n- Anonymous class expressions for functional interfaces\n- Functional interface implementations (e.g., `BiFunction<Integer,Integer,Integer>`)\n- Lambda-style anonymous parameter handling\n\n### Advanced Expression Features\n\n**Complex Expressions:**\n\n- Parenthesized expressions for precedence control\n- Conditional expressions (ternary operator)\n- Assignment expressions and compound assignments\n\n**Array Operations:**\n\n- Array access and indexing expressions\n- Array initialization and manipulation\n- Multi-dimensional array support\n\n### Modifier Support\n\n**Access Modifiers:**\n\n- Support for `public`, `private`, `protected` modifiers\n- `static`, `final`, `abstract` modifier handling\n- Enum constant modifiers and initialization\n\n### Collection Framework Integration\n\n**Collections:**\n\n- Generic collection types (e.g., `List<String>`, `Map<String,Integer>`)\n- Collection instantiation with type inference\n- Iterator and collection method support\n\n### Error Handling and Diagnostics\n\n**Error Types:**\n\n- `ErrorExpr` - Error expressions for malformed code\n- `ErrorType` - Error types for type resolution failures\n- Error handling in generic contexts\n\n### Example AST Hierarchy\n\nA typical Java method declaration produces the following AST node hierarchy:\n\n```text\nCompilationUnit\n \u2514\u2500\u2500 ClassDecl\n \u251C\u2500\u2500 FieldDecl\n \u2502 \u251C\u2500\u2500 TypeAccess\n \u2502 \u2514\u2500\u2500 VarDeclExpr\n \u251C\u2500\u2500 MethodDecl\n \u2502 \u251C\u2500\u2500 TypeAccess (return type)\n \u2502 \u251C\u2500\u2500 Parameter\n \u2502 \u2502 \u2514\u2500\u2500 TypeAccess\n \u2502 \u2514\u2500\u2500 Block\n \u2502 \u251C\u2500\u2500 ExprStmt\n \u2502 \u2502 \u2514\u2500\u2500 MethodCall\n \u2502 \u2502 \u251C\u2500\u2500 VarAccess\n \u2502 \u2502 \u2514\u2500\u2500 StringLiteral\n \u2502 \u2514\u2500\u2500 ReturnStmt\n \u2502 \u2514\u2500\u2500 VarAccess\n \u2514\u2500\u2500 ConstructorDecl\n \u2514\u2500\u2500 Block\n```\n\nUse `PrintAST` on your test code to see the exact hierarchy for your specific source patterns.\n\n## Expected test results for local `PrintAst.ql` query\n\nThis repo contains a variant of the open-source `PrintAst.ql` query for `java` language, with modifications for local testing:\n\n- Use the `codeql_query_run` tool with `queryName="PrintAST"` and `language="java"` to run the bundled PrintAST query\n- Use the `codeql_test_run` tool to run the PrintAST test and compare against expected results\n\n## Expected test results for open-source `PrintAst.ql` query\n\nThe following links can be fetched to get the expected results for different unit tests of the open-source `PrintAst.ql` query for the `java` language:\n\n- [library-tests/comments/PrintAst.expected](https://github.com/github/codeql/blob/main/java/ql/test/library-tests/comments/PrintAst.expected)\n- [library-tests/dependency-counts/PrintAst.expected](https://github.com/github/codeql/blob/main/java/ql/test/library-tests/dependency-counts/PrintAst.expected)\n- [library-tests/generics/PrintAst.expected](https://github.com/github/codeql/blob/main/java/ql/test/library-tests/generics/PrintAst.expected)\n- [library-tests/java7/Diamond/PrintAst.expected](https://github.com/github/codeql/blob/main/java/ql/test/library-tests/java7/Diamond/PrintAst.expected)\n- [library-tests/java7/MultiCatch/PrintAst.expected](https://github.com/github/codeql/blob/main/java/ql/test/library-tests/java7/MultiCatch/PrintAst.expected)\n- [library-tests/modifiers/PrintAst.expected](https://github.com/github/codeql/blob/main/java/ql/test/library-tests/modifiers/PrintAst.expected)\n- [library-tests/guards12/PrintAst.expected](https://github.com/github/codeql/blob/main/java/ql/test/library-tests/guards12/PrintAst.expected)\n- [library-tests/pattern-instanceof/PrintAst.expected](https://github.com/github/codeql/blob/main/java/ql/test/library-tests/pattern-instanceof/PrintAst.expected)\n- [library-tests/typeaccesses/PrintAst.expected](https://github.com/github/codeql/blob/main/java/ql/test/library-tests/typeaccesses/PrintAst.expected)\n- [library-tests/JDK/PrintAst.expected](https://github.com/github/codeql/blob/main/java/ql/test/library-tests/JDK/PrintAst.expected)\n- [library-tests/constants/PrintAst.expected](https://github.com/github/codeql/blob/main/java/ql/test/library-tests/constants/PrintAst.expected)\n- [library-tests/errortype/PrintAst.expected](https://github.com/github/codeql/blob/main/java/ql/test/library-tests/errortype/PrintAst.expected)\n- [library-tests/comment-encoding/PrintAst.expected](https://github.com/github/codeql/blob/main/java/ql/test/library-tests/comment-encoding/PrintAst.expected)\n- [library-tests/dependency/PrintAst.expected](https://github.com/github/codeql/blob/main/java/ql/test/library-tests/dependency/PrintAst.expected)\n- [library-tests/errortype-with-params/PrintAst.expected](https://github.com/github/codeql/blob/main/java/ql/test/library-tests/errortype-with-params/PrintAst.expected)\n- [library-tests/printAst/PrintAst.expected](https://github.com/github/codeql/blob/main/java/ql/test/library-tests/printAst/PrintAst.expected)\n- [library-tests/constructors/PrintAst.expected](https://github.com/github/codeql/blob/main/java/ql/test/library-tests/constructors/PrintAst.expected)\n- [library-tests/arrays/PrintAst.expected](https://github.com/github/codeql/blob/main/java/ql/test/library-tests/arrays/PrintAst.expected)\n- [library-tests/errorexpr/PrintAst.expected](https://github.com/github/codeql/blob/main/java/ql/test/library-tests/errorexpr/PrintAst.expected)\n- [library-tests/fields/PrintAst.expected](https://github.com/github/codeql/blob/main/java/ql/test/library-tests/fields/PrintAst.expected)\n- [library-tests/javadoc/PrintAst.expected](https://github.com/github/codeql/blob/main/java/ql/test/library-tests/javadoc/PrintAst.expected)\n- [library-tests/collections/PrintAst.expected](https://github.com/github/codeql/blob/main/java/ql/test/library-tests/collections/PrintAst.expected)\n- [library-tests/varargs/PrintAst.expected](https://github.com/github/codeql/blob/main/java/ql/test/library-tests/varargs/PrintAst.expected)\n- [library-tests/reflection/PrintAst.expected](https://github.com/github/codeql/blob/main/java/ql/test/library-tests/reflection/PrintAst.expected)\n';
|
|
63702
|
+
|
|
63703
|
+
// src/resources/languages/javascript_ast.md
|
|
63704
|
+
var javascript_ast_default = '# CodeQL AST nodes for `javascript` language\n\n## CodeQL\'s core AST classes for `javascript` language\n\nBased on comprehensive analysis of CodeQL\'s JavaScript test results from GitHub, here are the core AST classes for JavaScript/TypeScript analysis:\n\n### Core Expression Classes\n\n**Primary Expressions:**\n\n- `Literal` - String, number, boolean, null literals (e.g., `"hello"`, `42`, `true`, `null`)\n- `VarRef` - Variable references (e.g., `x`, `myVar`)\n- `ThisExpr` - The `this` keyword\n- `ArrayExpr` - Array literals (e.g., `[1, 2, 3]`, `["source"]`)\n- `ObjectExpr` - Object literals with properties (e.g., `{rel: "noopener"}`)\n\n**Function and Call Expressions:**\n\n- `FunctionExpr` - Function expressions and arrow functions\n- `ArrowFunctionExpr` - Arrow function expressions (e.g., `(x) => x`, `() => true`)\n- `CallExpr` - Function calls (e.g., `func()`, `getResource()`)\n- `MethodCallExpr` - Method calls (e.g., `console.log()`, `arr.push()`)\n- `NewExpr` - Constructor calls (e.g., `new Date()`, `new C3<number>()`)\n\n**Access and Member Expressions:**\n\n- `DotExpr` - Property access (e.g., `obj.prop`, `console.log`, `arr.length`)\n- `IndexExpr` - Array/object indexing (e.g., `arr[0]`, `props["a:b"]`)\n- `SpreadElement` - Spread syntax (e.g., `...arr`, `...linkTypes`)\n\n**Operators and Assignments:**\n\n- `BinaryExpr` - Binary operations (e.g., `x + y`, `i < arr.length`, `typeof val !== "string"`)\n- `UnaryExpr` - Unary operations (e.g., `!condition`, `typeof val`, `++i`)\n- `AssignExpr` - Assignment expressions (e.g., `x = 5`, `test = 20`)\n- `CompoundAssignExpr` - Compound assignments (e.g., `a2 &&= a3`)\n- `UpdateExpr` - Increment/decrement (e.g., `i++`, `--count`)\n\n### Statement Classes\n\n**Declaration Statements:**\n\n- `DeclStmt` - Variable declarations (e.g., `var x = 5`, `const arr = []`)\n- `VariableDeclarator` - Individual variable declarators within declarations\n- `VarDecl` - Variable declaration identifiers\n- `FunctionDeclStmt` - Function declarations\n- `ClassDefinition` - Class declarations with constructors and methods\n\n**Control Flow Statements:**\n\n- `IfStmt` - Conditional statements with test expressions and blocks\n- `ForStmt` - For loops with initialization, condition, and update\n- `ForOfStmt` - For-of loops for iterating arrays and iterables\n- `WhileStmt` - While loops\n- `BlockStmt` - Block statements containing multiple statements\n- `ReturnStmt` - Return statements with optional expressions\n- `BreakStmt` - Break statements for loop control\n- `ContinueStmt` - Continue statements\n- `ThrowStmt` - Throw statements for error handling\n\n**Expression Statements:**\n\n- `ExprStmt` - Expression statements wrapping expressions\n\n### Modern JavaScript Features\n\n**ES6+ and Modern Syntax:**\n\n- `TemplateString` - Template literals with interpolation\n- `TaggedTemplateExpr` - Tagged template literals\n- `ParenthesizedExpr` - Parenthesized expressions\n- `ConditionalExpr` - Ternary conditional expressions\n\n**Resource Management (Modern):**\n\n- `ExplicitResource` - Using declarations for resource management (e.g., `using stream = getResource()`)\n- Resource management in async contexts and for loops\n\n### TypeScript-Specific AST Classes\n\n**Type Annotations:**\n\n- `KeywordTypeExpr` - Built-in types (e.g., `string`, `number`, `boolean`, `any`, `void`)\n- `ArrayTypeExpr` - Array types (e.g., `string[]`, `number[][]`)\n- `UnionTypeExpr` - Union types (e.g., `string | number | boolean`)\n- `IntersectionTypeExpr` - Intersection types (e.g., `string & number & boolean`)\n- `TupleTypeExpr` - Tuple types (e.g., `[number, string, boolean]`, `[...T, ...U]`)\n- `ParenthesizedTypeExpr` - Parenthesized types (e.g., `(string)`, `(boolean | string)`)\n\n**Advanced Types:**\n\n- `GenericTypeExpr` - Generic types (e.g., `Generic<number>`, `Generic<Leaf[]>`)\n- `LocalTypeAccess` - Local type references (e.g., `Interface`, `Generic`, `Leaf`)\n- `FunctionTypeExpr` - Function types (e.g., `() => number`, `new () => Object`)\n- `TypeofTypeExpr` - Typeof types (e.g., `typeof x`)\n- `IsTypeExpr` - Type predicate expressions (e.g., `x is Generic<Leaf[]>`, `this is Leaf`)\n- `PredicateTypeExpr` - Assertion signatures (e.g., `asserts condition`)\n- `RestTypeExpr` - Rest types in tuples (e.g., `...T`, `...number[]`)\n\n**Type Declarations:**\n\n- `TypeDefinition` - Type definitions and interfaces\n- `InterfaceDeclaration` - Interface declarations with properties\n- `TypeParameter` - Generic type parameters (e.g., `T`, `S extends number`)\n- `FieldDeclaration` - Interface/class field declarations\n\n**Type Access:**\n\n- `LocalVarTypeAccess` - Local variable type access (e.g., `x` in type position)\n- `ThisVarTypeAccess` - This type access (e.g., `this` in type predicates)\n\n### JSX Classes (React Support)\n\n**JSX Elements:**\n\n- `JsxElement` - JSX elements (e.g., `<div>`, `<MyComponent>`, `<Foo/>`)\n- `JsxFragment` - JSX fragments (e.g., `<>...</>`)\n- `JsxAttribute` - JSX attributes (e.g., `href={href}`, `target="_blank"`)\n- `JsxEmptyExpr` - Empty JSX expressions (e.g., `{/* comment */}`)\n\n**JSX Structure:**\n\n- JSX elements support attributes, spread attributes, and nested content\n- Namespaced attributes (e.g., `a:b="hello"`)\n- Component references and dot notation (e.g., `MyComponents.FancyLink`)\n\n### Decorator Support\n\n**Decorator Classes:**\n\n- `Decorator` - Decorator expressions (e.g., `@Dec()`)\n- Decorators on classes, methods, and properties\n- Support for decorator factories and complex decorator expressions\n\n### Pattern Matching\n\n**Destructuring Patterns:**\n\n- `ObjectPattern` - Object destructuring patterns\n- `ArrayPattern` - Array destructuring patterns\n- `PropertyPattern` - Property patterns in object destructuring\n- `RestElement` - Rest elements in destructuring\n\n### Array Methods and Operations\n\n**Array-Specific AST:**\n\n- Comprehensive support for array methods: `forEach`, `map`, `filter`, `find`, `findLast`, `findLastIndex`\n- Array method chaining with proper AST representation\n- Spread operations in arrays and function calls\n- Array manipulation methods: `push`, `pop`, `slice`, `splice`, `toSpliced`\n\n### Class and OOP Features\n\n**Class Components:**\n\n- `ClassInitializedMember` - Class members (methods, constructors)\n- `ConstructorDefinition` - Class constructors\n- `MethodDefinition` - Class methods\n- `FieldDeclaration` - Class fields and properties\n\n### Parameter Handling\n\n**Parameter Types:**\n\n- `SimpleParameter` - Simple function parameters\n- `Parameter` - General parameter interface\n- `RestParameter` - Rest parameters (e.g., `...args`)\n\n### Utility and Meta Classes\n\n**Labels and References:**\n\n- `Label` - Property names, method names, and identifiers\n- `Identifier` - General identifiers in various contexts\n\n**Parser Infrastructure:**\n\n- `Arguments` - Function call arguments container\n- `Parameters` - Function parameter container\n- `Body` - Statement body container\n- `Attributes` - JSX attributes container\n\n## Expected test results for local `PrintAst.ql` query\n\nThis repo contains a variant of the open-source `PrintAst.ql` query for `javascript` language, with modifications for local testing:\n\n- Use the `codeql_query_run` tool with `queryName="PrintAST"` and `language="javascript"` to run the bundled PrintAST query\n- Use the `codeql_test_run` tool to run the PrintAST test and compare against expected results\n\n## Expected test results for open-source `PrintAst.ql` query\n\nThe following links can be fetched to get the expected results for different unit tests of the open-source `PrintAst.ql` query for the `javascript` language:\n\n- [library-tests/RegExp/VFlagOperations/QuotedString/printAst.expected](https://github.com/github/codeql/blob/main/javascript/ql/test/library-tests/RegExp/VFlagOperations/QuotedString/printAst.expected)\n- [library-tests/RegExp/VFlagOperations/Subtraction/printAst.expected](https://github.com/github/codeql/blob/main/javascript/ql/test/library-tests/RegExp/VFlagOperations/Subtraction/printAst.expected)\n- [library-tests/RegExp/VFlagOperations/CombinationOfOperators/printAst.expected](https://github.com/github/codeql/blob/main/javascript/ql/test/library-tests/RegExp/VFlagOperations/CombinationOfOperators/printAst.expected)\n- [library-tests/RegExp/VFlagOperations/Intersection/printAst.expected](https://github.com/github/codeql/blob/main/javascript/ql/test/library-tests/RegExp/VFlagOperations/Intersection/printAst.expected)\n- [library-tests/TypeScript/TypeAnnotations/printAst.expected](https://github.com/github/codeql/blob/main/javascript/ql/test/library-tests/TypeScript/TypeAnnotations/printAst.expected)\n- [library-tests/HTML/HTMLElementAndHTMLAttribute/printAst.expected](https://github.com/github/codeql/blob/main/javascript/ql/test/library-tests/HTML/HTMLElementAndHTMLAttribute/printAst.expected)\n- [library-tests/JSON/printAst.expected](https://github.com/github/codeql/blob/main/javascript/ql/test/library-tests/JSON/printAst.expected)\n- [library-tests/Arrays/printAst.expected](https://github.com/github/codeql/blob/main/javascript/ql/test/library-tests/Arrays/printAst.expected)\n- [library-tests/AST/Decorators/printAst.expected](https://github.com/github/codeql/blob/main/javascript/ql/test/library-tests/AST/Decorators/printAst.expected)\n- [library-tests/AST/ExplicitResource/printAst.expected](https://github.com/github/codeql/blob/main/javascript/ql/test/library-tests/AST/ExplicitResource/printAst.expected)\n- [library-tests/YAML/printAst.expected](https://github.com/github/codeql/blob/main/javascript/ql/test/library-tests/YAML/printAst.expected)\n- [library-tests/frameworks/AngularJS/expressions/parsing/AstNodes.expected](https://github.com/github/codeql/blob/main/javascript/ql/test/library-tests/frameworks/AngularJS/expressions/parsing/AstNodes.expected)\n- [library-tests/JSX/printAst.expected](https://github.com/github/codeql/blob/main/javascript/ql/test/library-tests/JSX/printAst.expected)\n';
|
|
63705
|
+
|
|
63706
|
+
// src/resources/languages/javascript_security_query_guide.md
|
|
63707
|
+
var javascript_security_query_guide_default = "# JavaScript Security Query Guide\n\nLanguage-specific notes for writing JavaScript/TypeScript security queries in CodeQL. For the general taint-tracking template and workflow, see the `security_templates` resource.\n\n## Imports\n\n```ql\nimport javascript\n```\n\nThe `javascript` top-level import re-exports data flow, taint tracking, and framework models. For path-problem queries add `import MyFlow::PathGraph` after defining your flow module.\n\n## Sources and Sinks\n\n- **Sources**: Use `RemoteFlowSource` (covers Express, Koa, Hapi, Fastify, and other HTTP frameworks automatically).\n- **Sinks**: Use or extend existing sink classes from `semmle.javascript.security.dataflow.*` (e.g., `DomBasedXss`, `SqlInjection`, `ServerSideUrlRedirect`), or model custom sinks as `DataFlow::Node` subclasses.\n- **Sanitizers**: Extend `Sanitizer` classes in the relevant `semmle.javascript.security.dataflow.*` module.\n\n## Key Library Modules\n\n| Module | Purpose |\n| ------------------------------------------ | ---------------------------------------- |\n| `semmle.javascript.dataflow.DataFlow` | Data flow nodes and global analysis |\n| `semmle.javascript.dataflow.TaintTracking` | Taint tracking analysis |\n| `semmle.javascript.security.dataflow.*` | Pre-built vulnerability-specific configs |\n| `semmle.javascript.frameworks.*` | Framework-specific API models |\n";
|
|
63708
|
+
|
|
63709
|
+
// src/resources/languages/python_ast.md
|
|
63710
|
+
var python_ast_default = '# CodeQL AST nodes for `python` language\n\n## Expected test results for local `PrintAst.ql` query\n\nThis repo contains a variant of the open-source `PrintAst.ql` query for `python` language, with modifications for local testing:\n\n- Use the `codeql_query_run` tool with `queryName="PrintAST"` and `language="python"` to run the bundled PrintAST query\n- Use the `codeql_test_run` tool to run the PrintAST test and compare against expected results\n\n## CodeQL\'s core AST classes for `python` language\n\n### Expression Types\n\n- **`Call`** - Function/method calls (e.g., `func(args)`)\n- **`Attribute`** - Attribute access (e.g., `obj.attr`, `module.function`)\n- **`Subscript`** - Subscript operations (e.g., `obj[key]`, `list[0]`)\n- **`Name`** - Variable references and identifiers\n- **`StringLiteral`** - String literals (e.g., `"hello"`, `\'world\'`)\n- **`Bytes`** - Byte string literals\n- **`List`** - List literals (e.g., `[1, 2, 3]`)\n- **`Dict`** - Dictionary literals (e.g., `{"key": "value"}`)\n- **`KeyValuePair`** - Key-value pairs in dictionaries\n- **`BinOp`** - Binary operations (e.g., `+`, `-`, `*`)\n- **`UnaryExpr`** - Unary expressions (e.g., `not`, `-`)\n\n### Statement Types\n\n- **`FunctionDef`** - Function definitions\n- **`FunctionExpr`** - Function expressions\n- **`Function`** - Function objects\n- **`ClassDef`** - Class definitions\n- **`ClassExpr`** - Class expressions\n- **`Class`** - Class objects\n- **`Import`** - Import statements (`import module`)\n- **`ImportFrom`** - From-import statements (`from module import name`)\n- **`ImportExpr`** - Import expressions\n- **`Assign`** - Assignment statements (e.g., `x = y`)\n- **`AssignStmt`** - Assignment statement nodes\n- **`If`** - Conditional statements\n- **`For`** - For loop statements\n- **`While`** - While loop statements\n- **`Return`** - Return statements\n- **`ExprStmt`** - Expression statements\n- **`Pass`** - Pass statements\n\n### Parameters and Arguments\n\n- **`Parameter`** - Function parameters\n- **`arguments`** - Function argument lists\n- **`parameters`** - Function parameter lists\n\n### Control Flow\n\n- **`StmtList`** - Statement lists (body, orelse)\n- **`body`** - Statement body containers\n- **`orelse`** - Else clause containers\n\n### YAML Support (for configuration files)\n\n- **`YamlScalar`** - YAML scalar values\n- **`YamlMapping`** - YAML mapping/dictionary structures\n- **`YamlSequence`** - YAML sequence/list structures\n- **`YamlAliasNode`** - YAML alias references\n\n## Expected test results for open-source `PrintAst.ql` query\n\nThe following links can be fetched to get the expected results for different unit tests of the open-source `PrintAst.ql` query for the `python` language:\n\n- [github-codeql:python/ql/test/library-tests/taint/general/printAst.expected](https://github.com/github/codeql/blob/main/python/ql/test/library-tests/taint/general/printAst.expected)\n- [github-codeql:python/ql/test/library-tests/Yaml/printAst.expected](https://github.com/github/codeql/blob/main/python/ql/test/library-tests/Yaml/printAst.expected)\n';
|
|
63711
|
+
|
|
63712
|
+
// src/resources/languages/python_security_query_guide.md
|
|
63713
|
+
var python_security_query_guide_default = '# Python Security Query Guide\n\nLanguage-specific notes for writing Python security queries in CodeQL. For the general taint-tracking template and workflow, see the `security_templates` resource.\n\n## Imports\n\n```ql\nimport python\nimport semmle.python.dataflow.new.DataFlow\nimport semmle.python.dataflow.new.TaintTracking\nimport semmle.python.Concepts\nimport semmle.python.ApiGraphs\n```\n\nFor path-problem queries add `import MyFlow::PathGraph` after defining your flow module.\n\n## Sources and Sinks\n\n- **Sources**: Use `RemoteFlowSource` from `semmle.python.dataflow.new.RemoteFlowSources` (covers Flask, Django, FastAPI, and other HTTP frameworks).\n- **Sinks**: Use the `Concepts` module (e.g., `SqlExecution`, `SystemCommandExecution`, `FileSystemAccess`) or model custom sinks as `DataFlow::Node` subclasses.\n- **Barriers**: Use `semmle.python.dataflow.new.BarrierGuards` for common sanitizer patterns.\n\n## ApiGraph Navigation (Framework Modeling)\n\nUse `API::moduleImport("pkg")` to get a reference to an imported module, then chain `.getMember()`, `.getACall()`, `.getReturn()`, `.getParameter()`, and `.getASubclass()` to navigate the API surface. Convert to data flow nodes via `.asSource()` / `.asSink()`.\n\n## Key Library Modules\n\n| Module | Purpose |\n| ---------------------------------------------- | ------------------------------------------- |\n| `semmle.python.dataflow.new.DataFlow` | Data flow nodes and global analysis |\n| `semmle.python.dataflow.new.TaintTracking` | Taint tracking analysis |\n| `semmle.python.Concepts` | Abstract security concepts (sinks) |\n| `semmle.python.ApiGraphs` | API-graph navigation for framework modeling |\n| `semmle.python.dataflow.new.RemoteFlowSources` | Remote flow source definitions |\n';
|
|
63714
|
+
|
|
63715
|
+
// src/resources/languages/ruby_ast.md
|
|
63716
|
+
var ruby_ast_default = '# CodeQL AST nodes for `ruby` language\n\n## CodeQL\'s core AST classes for `ruby` language\n\nBased on comprehensive analysis of GitHub CodeQL Ruby AST test results\n\n### Expression Types\n\n#### Literal Expressions\n\n- **IntegerLiteral**: Numeric constants (1, 2, 100, -5)\n- **StringLiteral**: String constants with StringTextComponent and StringEscapeSequenceComponent\n- **BooleanLiteral**: true/false values\n- **NilLiteral**: nil value\n- **SymbolLiteral**: :foo, :"foo bar" symbols with StringTextComponent\n- **ArrayLiteral**: [1, 2, 3] arrays (desugared to Array.[])\n- **HashLiteral**: {:foo => 1} hashes (desugared to Hash.[])\n- **RegExpLiteral**: /foo.\\*/ regular expressions with RegExpSequence, RegExpConstant, RegExpStar, RegExpDot\n- **RangeLiteral**: 1..10, 1...10 ranges with getBegin/getEnd\n- **HereDoc**: <<SQL heredoc strings\n\n#### Variable Access\n\n- **LocalVariableAccess**: Local variable references\n- **InstanceVariableAccess**: @instance_var with getReceiver\n- **ClassVariableAccess**: @@class_var\n- **GlobalVariableAccess**: $global_var\n- **SelfVariableAccess**: self references\n\n#### Constant Access\n\n- **ConstantReadAccess**: Reading constants with optional getScopeExpr\n- **ConstantAssignment**: Assigning to constants with optional getScopeExpr\n\n#### Method and Call Expressions\n\n- **MethodCall**: Method invocations with getReceiver, getArgument, getBlock\n- **SetterMethodCall**: Setter method calls (foo=)\n- **SuperCall**: super calls with getArgument, getBlock\n\n#### Binary Operations\n\n- **AddExpr**: + addition\n- **SubExpr**: - subtraction\n- **MulExpr**: \\* multiplication\n- **DivExpr**: / division\n- **ModExpr**: % modulo\n- **PowerExpr**: \\*\\* exponentiation\n- **EqExpr**: == equality\n- **NeExpr**: != inequality\n- **LTExpr**: < less than\n- **LEExpr**: <= less than or equal\n- **GTExpr**: > greater than\n- **GEExpr**: >= greater than or equal\n- **SpaceshipExpr**: <=> spaceship operator\n- **RegExpMatchExpr**: =~ regex match\n- **NoRegExpMatchExpr**: !~ regex no match\n\n#### Logical Operations\n\n- **LogicalAndExpr**: && and \'and\'\n- **LogicalOrExpr**: || and \'or\'\n- **NotExpr**: ! negation\n\n#### Bitwise Operations\n\n- **BitwiseAndExpr**: & bitwise and\n- **BitwiseOrExpr**: | bitwise or\n- **BitwiseXorExpr**: ^ bitwise xor\n- **LeftShiftExpr**: << left shift\n- **RightShiftExpr**: >> right shift\n\n#### Unary Operations\n\n- **UnaryMinusExpr**: -value\n- **UnaryPlusExpr**: +value\n- **ComplementExpr**: ~value\n\n#### Assignment Operations\n\n- **AssignExpr**: = assignment\n- **AssignAddExpr**: += (desugared to = and +)\n- **AssignSubExpr**: -= (desugared to = and -)\n- **AssignMulExpr**: _= (desugared to = and _)\n- **AssignDivExpr**: /= (desugared to = and /)\n- **AssignModExpr**: %= (desugared to = and %)\n- **AssignPowerExpr**: **= (desugared to = and **)\n- **AssignLogicalAndExpr**: &&= (desugared to = and &&)\n- **AssignLogicalOrExpr**: ||= (desugared to = and ||)\n- **AssignBitwiseAndExpr**: &= (desugared to = and &)\n- **AssignBitwiseOrExpr**: |= (desugared to = and |)\n- **AssignBitwiseXorExpr**: ^= (desugared to = and ^)\n- **AssignLeftShiftExpr**: <<= (desugared to = and <<)\n- **AssignRightShiftExpr**: >>= (desugared to = and >>)\n\n#### Special Expressions\n\n- **TernaryIfExpr**: condition ? true_val : false_val\n- **SplatExpr**: \\*args splat operator\n- **HashSplatExpr**: \\*\\*kwargs hash splat\n- **DefinedExpr**: defined? operator\n- **DestructuredLhsExpr**: (a, b, c) destructuring assignment left side\n\n### Statement Types\n\n#### Method Definitions\n\n- **Method**: Regular method definitions with getParameter, getStmt\n- **SingletonMethod**: Class method definitions with getObject\n\n#### Class and Module Definitions\n\n- **ClassDeclaration**: Class definitions with optional getSuperclassExpr\n- **ModuleDeclaration**: Module definitions\n\n#### Control Flow Statements\n\n- **IfExpr**: if/elsif/else conditionals with getCondition, getThen, getElse\n- **UnlessExpr**: unless conditionals with getCondition, getThen, getElse\n- **IfModifierExpr**: statement if condition\n- **UnlessModifierExpr**: statement unless condition\n- **CaseExpr**: case statements with getValue, getBranch\n- **WhenClause**: when branches with getPattern, getBody\n- **InClause**: in pattern matching with getPattern, getCondition, getBody\n\n#### Loop Statements\n\n- **WhileExpr**: while loops with getCondition, getBody\n- **WhileModifierExpr**: statement while condition\n- **UntilExpr**: until loops with getCondition, getBody\n- **UntilModifierExpr**: statement until condition\n- **ForExpr**: for loops (desugared to each with blocks)\n\n#### Flow Control\n\n- **NextStmt**: next statement\n- **BreakStmt**: break statement\n- **ReturnStmt**: return statement\n- **RedoStmt**: redo statement\n- **RetryStmt**: retry statement\n\n#### Block Statements\n\n- **BeginExpr**: begin/rescue/ensure/end blocks\n- **RescueClause**: rescue clauses\n- **EnsureClause**: ensure clauses\n- **EndBlock**: END {} blocks\n\n#### Utility Statements\n\n- **UndefStmt**: undef method_name\n- **AliasStmt**: alias new_name old_name\n- **StmtSequence**: Statement sequences\n\n### Parameters\n\n#### Basic Parameters\n\n- **SimpleParameter**: Regular parameters with getDefiningAccess\n- **OptionalParameter**: Parameters with default values, getDefaultValue\n- **KeywordParameter**: Keyword parameters with optional getDefaultValue\n- **SplatParameter**: \\*args parameters with getDefiningAccess\n- **HashSplatParameter**: \\*\\*kwargs parameters with getDefiningAccess\n- **HashSplatNilParameter**: \\*\\*nil parameters\n- **BlockParameter**: &block parameters with getDefiningAccess\n- **DestructuredParameter**: (a, b) destructured parameters with getElement\n\n### Control Flow\n\n#### Conditional Expressions\n\n- **IfExpr**: Complete if/elsif/else with getBranch structure\n- **UnlessExpr**: unless statements with conditional logic\n- **CaseExpr**: case/when/else with pattern matching\n- **TernaryIfExpr**: Inline conditional expressions\n\n#### Loop Constructs\n\n- **WhileExpr**: while condition do body end\n- **UntilExpr**: until condition do body end\n- **ForExpr**: for var in collection (desugared to each)\n\n#### Block Constructs\n\n- **DoBlock**: do |params| body end blocks\n- **BraceBlock**: { |params| body } blocks\n- **Lambda**: -> { } and lambda { } constructs\n\n#### Pattern Matching\n\n- **ArrayPattern**: [a, b, *rest] array patterns\n- **AlternativePattern**: pattern1 | pattern2\n- **AsPattern**: pattern => variable\n- **CapturePattern**: Variable capture patterns\n\n#### Exception Handling\n\n- **BeginExpr**: begin/rescue/ensure structure\n- **RescueClause**: Exception rescue clauses\n- **EnsureClause**: Cleanup ensure clauses\n\n### Method Names and Identifiers\n\n- **MethodName**: Method name identifiers in various contexts\n- **Toplevel**: Top-level program scope\n\n## Expected test results for local `PrintAst.ql` query\n\nThis repo contains a variant of the open-source `PrintAst.ql` query for `ruby` language, with modifications for local testing:\n\n- Use the `codeql_query_run` tool with `queryName="PrintAST"` and `language="ruby"` to run the bundled PrintAST query\n- Use the `codeql_test_run` tool to run the PrintAST test and compare against expected results\n\n## Expected test results for open-source `PrintAst.ql` query\n\nThe following links can be fetched to get the expected results for different unit tests of the open-source `PrintAst.ql` query for the `ruby` language:\n\n- https://github.com/github/codeql/blob/main/ruby/ql/test/library-tests/ast/Ast.expected\n- https://github.com/github/codeql/blob/main/ruby/ql/test/library-tests/ast/AstDesugar.expected\n';
|
|
63257
63717
|
|
|
63258
63718
|
// src/types/language-types.ts
|
|
63259
63719
|
var LANGUAGE_RESOURCES = [
|
|
63260
63720
|
{
|
|
63261
63721
|
language: "actions",
|
|
63262
|
-
|
|
63722
|
+
astContent: actions_ast_default
|
|
63263
63723
|
},
|
|
63264
63724
|
{
|
|
63265
63725
|
language: "cpp",
|
|
63266
|
-
|
|
63267
|
-
|
|
63726
|
+
astContent: cpp_ast_default,
|
|
63727
|
+
securityContent: cpp_security_query_guide_default
|
|
63268
63728
|
},
|
|
63269
63729
|
{
|
|
63270
63730
|
language: "csharp",
|
|
63271
|
-
|
|
63272
|
-
|
|
63731
|
+
astContent: csharp_ast_default,
|
|
63732
|
+
securityContent: csharp_security_query_guide_default
|
|
63273
63733
|
},
|
|
63274
63734
|
{
|
|
63275
63735
|
language: "go",
|
|
63276
|
-
|
|
63277
|
-
|
|
63278
|
-
|
|
63279
|
-
"
|
|
63280
|
-
"
|
|
63281
|
-
"
|
|
63736
|
+
astContent: go_ast_default,
|
|
63737
|
+
securityContent: go_security_query_guide_default,
|
|
63738
|
+
additionalResources: {
|
|
63739
|
+
"basic-queries": go_basic_queries_default,
|
|
63740
|
+
"dataflow": go_dataflow_default,
|
|
63741
|
+
"library-modeling": go_library_modeling_default
|
|
63282
63742
|
}
|
|
63283
63743
|
},
|
|
63284
63744
|
{
|
|
63285
63745
|
language: "java",
|
|
63286
|
-
|
|
63746
|
+
astContent: java_ast_default
|
|
63287
63747
|
},
|
|
63288
63748
|
{
|
|
63289
63749
|
language: "javascript",
|
|
63290
|
-
|
|
63291
|
-
|
|
63750
|
+
astContent: javascript_ast_default,
|
|
63751
|
+
securityContent: javascript_security_query_guide_default
|
|
63292
63752
|
},
|
|
63293
63753
|
{
|
|
63294
63754
|
language: "python",
|
|
63295
|
-
|
|
63296
|
-
|
|
63297
|
-
},
|
|
63298
|
-
{
|
|
63299
|
-
language: "ql",
|
|
63300
|
-
astFile: "ql/languages/ql/tools/dev/ql_ast.prompt.md"
|
|
63755
|
+
astContent: python_ast_default,
|
|
63756
|
+
securityContent: python_security_query_guide_default
|
|
63301
63757
|
},
|
|
63302
63758
|
{
|
|
63303
63759
|
language: "ruby",
|
|
63304
|
-
|
|
63760
|
+
astContent: ruby_ast_default
|
|
63305
63761
|
}
|
|
63306
63762
|
];
|
|
63307
63763
|
|
|
63308
63764
|
// src/resources/language-resources.ts
|
|
63309
|
-
init_package_paths();
|
|
63310
63765
|
init_logger();
|
|
63311
|
-
function getQLBasePath() {
|
|
63312
|
-
return workspaceRootDir;
|
|
63313
|
-
}
|
|
63314
|
-
function loadResourceContent(relativePath) {
|
|
63315
|
-
try {
|
|
63316
|
-
const fullPath = join17(getQLBasePath(), relativePath);
|
|
63317
|
-
if (!existsSync12(fullPath)) {
|
|
63318
|
-
logger.warn(`Resource file not found: ${fullPath}`);
|
|
63319
|
-
return null;
|
|
63320
|
-
}
|
|
63321
|
-
return readFileSync11(fullPath, "utf-8");
|
|
63322
|
-
} catch (error2) {
|
|
63323
|
-
logger.error(`Error loading resource file ${relativePath}:`, error2);
|
|
63324
|
-
return null;
|
|
63325
|
-
}
|
|
63326
|
-
}
|
|
63327
63766
|
function registerLanguageASTResources(server) {
|
|
63328
63767
|
for (const langResource of LANGUAGE_RESOURCES) {
|
|
63329
|
-
if (!langResource.
|
|
63768
|
+
if (!langResource.astContent) continue;
|
|
63330
63769
|
const resourceUri = `codeql://languages/${langResource.language}/ast`;
|
|
63770
|
+
const content = langResource.astContent;
|
|
63331
63771
|
server.resource(
|
|
63332
63772
|
`${langResource.language.toUpperCase()} AST Reference`,
|
|
63333
63773
|
resourceUri,
|
|
@@ -63335,34 +63775,21 @@ function registerLanguageASTResources(server) {
|
|
|
63335
63775
|
description: `CodeQL AST class reference for ${langResource.language} programs`,
|
|
63336
63776
|
mimeType: "text/markdown"
|
|
63337
63777
|
},
|
|
63338
|
-
async () => {
|
|
63339
|
-
|
|
63340
|
-
|
|
63341
|
-
|
|
63342
|
-
|
|
63343
|
-
|
|
63344
|
-
|
|
63345
|
-
text: `# ${langResource.language.toUpperCase()} AST Reference
|
|
63346
|
-
|
|
63347
|
-
Resource file not found or could not be loaded.`
|
|
63348
|
-
}]
|
|
63349
|
-
};
|
|
63350
|
-
}
|
|
63351
|
-
return {
|
|
63352
|
-
contents: [{
|
|
63353
|
-
uri: resourceUri,
|
|
63354
|
-
mimeType: "text/markdown",
|
|
63355
|
-
text: content
|
|
63356
|
-
}]
|
|
63357
|
-
};
|
|
63358
|
-
}
|
|
63778
|
+
async () => ({
|
|
63779
|
+
contents: [{
|
|
63780
|
+
uri: resourceUri,
|
|
63781
|
+
mimeType: "text/markdown",
|
|
63782
|
+
text: content
|
|
63783
|
+
}]
|
|
63784
|
+
})
|
|
63359
63785
|
);
|
|
63360
63786
|
}
|
|
63361
63787
|
}
|
|
63362
63788
|
function registerLanguageSecurityResources(server) {
|
|
63363
63789
|
for (const langResource of LANGUAGE_RESOURCES) {
|
|
63364
|
-
if (!langResource.
|
|
63790
|
+
if (!langResource.securityContent) continue;
|
|
63365
63791
|
const resourceUri = `codeql://languages/${langResource.language}/security`;
|
|
63792
|
+
const content = langResource.securityContent;
|
|
63366
63793
|
server.resource(
|
|
63367
63794
|
`${langResource.language.toUpperCase()} Security Patterns`,
|
|
63368
63795
|
resourceUri,
|
|
@@ -63370,34 +63797,20 @@ function registerLanguageSecurityResources(server) {
|
|
|
63370
63797
|
description: `CodeQL security query patterns and framework modeling for ${langResource.language}`,
|
|
63371
63798
|
mimeType: "text/markdown"
|
|
63372
63799
|
},
|
|
63373
|
-
async () => {
|
|
63374
|
-
|
|
63375
|
-
|
|
63376
|
-
|
|
63377
|
-
|
|
63378
|
-
|
|
63379
|
-
|
|
63380
|
-
text: `# ${langResource.language.toUpperCase()} Security Patterns
|
|
63381
|
-
|
|
63382
|
-
Resource file not found or could not be loaded.`
|
|
63383
|
-
}]
|
|
63384
|
-
};
|
|
63385
|
-
}
|
|
63386
|
-
return {
|
|
63387
|
-
contents: [{
|
|
63388
|
-
uri: resourceUri,
|
|
63389
|
-
mimeType: "text/markdown",
|
|
63390
|
-
text: content
|
|
63391
|
-
}]
|
|
63392
|
-
};
|
|
63393
|
-
}
|
|
63800
|
+
async () => ({
|
|
63801
|
+
contents: [{
|
|
63802
|
+
uri: resourceUri,
|
|
63803
|
+
mimeType: "text/markdown",
|
|
63804
|
+
text: content
|
|
63805
|
+
}]
|
|
63806
|
+
})
|
|
63394
63807
|
);
|
|
63395
63808
|
}
|
|
63396
63809
|
}
|
|
63397
63810
|
function registerLanguageAdditionalResources(server) {
|
|
63398
63811
|
for (const langResource of LANGUAGE_RESOURCES) {
|
|
63399
|
-
if (!langResource.
|
|
63400
|
-
for (const [resourceType,
|
|
63812
|
+
if (!langResource.additionalResources) continue;
|
|
63813
|
+
for (const [resourceType, content] of Object.entries(langResource.additionalResources)) {
|
|
63401
63814
|
const resourceUri = `codeql://languages/${langResource.language}/${resourceType}`;
|
|
63402
63815
|
server.resource(
|
|
63403
63816
|
`${langResource.language.toUpperCase()} ${resourceType.replace("-", " ").replace(/\b\w/g, (l) => l.toUpperCase())}`,
|
|
@@ -63406,27 +63819,13 @@ function registerLanguageAdditionalResources(server) {
|
|
|
63406
63819
|
description: `CodeQL ${resourceType.replace("-", " ")} guide for ${langResource.language}`,
|
|
63407
63820
|
mimeType: "text/markdown"
|
|
63408
63821
|
},
|
|
63409
|
-
async () => {
|
|
63410
|
-
|
|
63411
|
-
|
|
63412
|
-
|
|
63413
|
-
|
|
63414
|
-
|
|
63415
|
-
|
|
63416
|
-
text: `# ${langResource.language.toUpperCase()} ${resourceType.replace("-", " ").replace(/\b\w/g, (l) => l.toUpperCase())}
|
|
63417
|
-
|
|
63418
|
-
Resource file not found or could not be loaded.`
|
|
63419
|
-
}]
|
|
63420
|
-
};
|
|
63421
|
-
}
|
|
63422
|
-
return {
|
|
63423
|
-
contents: [{
|
|
63424
|
-
uri: resourceUri,
|
|
63425
|
-
mimeType: "text/markdown",
|
|
63426
|
-
text: content
|
|
63427
|
-
}]
|
|
63428
|
-
};
|
|
63429
|
-
}
|
|
63822
|
+
async () => ({
|
|
63823
|
+
contents: [{
|
|
63824
|
+
uri: resourceUri,
|
|
63825
|
+
mimeType: "text/markdown",
|
|
63826
|
+
text: content
|
|
63827
|
+
}]
|
|
63828
|
+
})
|
|
63430
63829
|
);
|
|
63431
63830
|
}
|
|
63432
63831
|
}
|
|
@@ -64010,7 +64409,7 @@ var Low = class {
|
|
|
64010
64409
|
};
|
|
64011
64410
|
|
|
64012
64411
|
// ../node_modules/lowdb/lib/adapters/node/TextFile.js
|
|
64013
|
-
import { readFileSync as
|
|
64412
|
+
import { readFileSync as readFileSync11, renameSync, writeFileSync as writeFileSync6 } from "node:fs";
|
|
64014
64413
|
import path3 from "node:path";
|
|
64015
64414
|
var TextFileSync = class {
|
|
64016
64415
|
#tempFilename;
|
|
@@ -64023,7 +64422,7 @@ var TextFileSync = class {
|
|
|
64023
64422
|
read() {
|
|
64024
64423
|
let data;
|
|
64025
64424
|
try {
|
|
64026
|
-
data =
|
|
64425
|
+
data = readFileSync11(this.#filename, "utf-8");
|
|
64027
64426
|
} catch (e) {
|
|
64028
64427
|
if (e.code === "ENOENT") {
|
|
64029
64428
|
return null;
|
|
@@ -64074,7 +64473,7 @@ var JSONFileSync = class extends DataFileSync {
|
|
|
64074
64473
|
// src/lib/session-data-manager.ts
|
|
64075
64474
|
init_temp_dir();
|
|
64076
64475
|
import { mkdirSync as mkdirSync9, writeFileSync as writeFileSync7 } from "fs";
|
|
64077
|
-
import { join as
|
|
64476
|
+
import { join as join17 } from "path";
|
|
64078
64477
|
import { randomUUID as randomUUID2 } from "crypto";
|
|
64079
64478
|
|
|
64080
64479
|
// src/types/monitoring.ts
|
|
@@ -64218,7 +64617,7 @@ var SessionDataManager = class {
|
|
|
64218
64617
|
});
|
|
64219
64618
|
this.storageDir = this.config.storageLocation;
|
|
64220
64619
|
this.ensureStorageDirectory();
|
|
64221
|
-
const adapter = new JSONFileSync(
|
|
64620
|
+
const adapter = new JSONFileSync(join17(this.storageDir, "sessions.json"));
|
|
64222
64621
|
this.db = new Low(adapter, {
|
|
64223
64622
|
sessions: []
|
|
64224
64623
|
});
|
|
@@ -64250,9 +64649,9 @@ var SessionDataManager = class {
|
|
|
64250
64649
|
mkdirSync9(this.storageDir, { recursive: true });
|
|
64251
64650
|
const subdirs = ["sessions-archive", "exports"];
|
|
64252
64651
|
for (const subdir of subdirs) {
|
|
64253
|
-
mkdirSync9(
|
|
64652
|
+
mkdirSync9(join17(this.storageDir, subdir), { recursive: true });
|
|
64254
64653
|
}
|
|
64255
|
-
const configPath =
|
|
64654
|
+
const configPath = join17(this.storageDir, "config.json");
|
|
64256
64655
|
try {
|
|
64257
64656
|
writeFileSync7(configPath, JSON.stringify(this.config, null, 2), { flag: "wx" });
|
|
64258
64657
|
} catch (e) {
|
|
@@ -64431,9 +64830,9 @@ var SessionDataManager = class {
|
|
|
64431
64830
|
if (!session) return;
|
|
64432
64831
|
const date3 = new Date(session.endTime || session.startTime);
|
|
64433
64832
|
const monthDir = `${date3.getFullYear()}-${String(date3.getMonth() + 1).padStart(2, "0")}`;
|
|
64434
|
-
const archiveDir =
|
|
64833
|
+
const archiveDir = join17(this.storageDir, "sessions-archive", monthDir);
|
|
64435
64834
|
mkdirSync9(archiveDir, { recursive: true });
|
|
64436
|
-
const archiveFile =
|
|
64835
|
+
const archiveFile = join17(archiveDir, `${sessionId}.json`);
|
|
64437
64836
|
writeFileSync7(archiveFile, JSON.stringify(session, null, 2));
|
|
64438
64837
|
await this.db.read();
|
|
64439
64838
|
this.db.data.sessions = this.db.data.sessions.filter((s) => s.sessionId !== sessionId);
|
|
@@ -64485,7 +64884,7 @@ var SessionDataManager = class {
|
|
|
64485
64884
|
...this.config,
|
|
64486
64885
|
...configUpdate
|
|
64487
64886
|
});
|
|
64488
|
-
const configPath =
|
|
64887
|
+
const configPath = join17(this.storageDir, "config.json");
|
|
64489
64888
|
writeFileSync7(configPath, JSON.stringify(this.config, null, 2));
|
|
64490
64889
|
logger.info("Updated monitoring configuration");
|
|
64491
64890
|
}
|
|
@@ -64495,7 +64894,7 @@ function parseBoolEnv(envVar, defaultValue) {
|
|
|
64495
64894
|
return envVar.toLowerCase() === "true" || envVar === "1";
|
|
64496
64895
|
}
|
|
64497
64896
|
var sessionDataManager = new SessionDataManager({
|
|
64498
|
-
storageLocation: process.env.MONITORING_STORAGE_LOCATION ||
|
|
64897
|
+
storageLocation: process.env.MONITORING_STORAGE_LOCATION || join17(getProjectTmpBase(), ".ql-mcp-tracking"),
|
|
64499
64898
|
enableMonitoringTools: parseBoolEnv(process.env.ENABLE_MONITORING_TOOLS, false)
|
|
64500
64899
|
});
|
|
64501
64900
|
|
|
@@ -65371,7 +65770,7 @@ init_package_paths();
|
|
|
65371
65770
|
init_logger();
|
|
65372
65771
|
import_dotenv.default.config({ path: resolve12(packageRootDir, ".env"), quiet: true });
|
|
65373
65772
|
var PACKAGE_NAME = "codeql-development-mcp-server";
|
|
65374
|
-
var VERSION = "2.24.
|
|
65773
|
+
var VERSION = "2.24.3-rc1";
|
|
65375
65774
|
async function startServer(mode = "stdio") {
|
|
65376
65775
|
logger.info(`Starting CodeQL Development MCP McpServer v${VERSION} in ${mode} mode`);
|
|
65377
65776
|
const codeqlBinary = resolveCodeQLBinary();
|