From 9ea4b14d8826d635e30451427173fc089abc145b Mon Sep 17 00:00:00 2001 From: Nathan Randall Date: Mon, 16 Feb 2026 21:58:01 -0700 Subject: [PATCH 01/14] Add VS Code extension and discovery tools Introduce a VS Code extension (extensions/vscode/) that automatically installs, configures, and manages the MCP server. It bridges with vscode-codeql to watch databases and query run results, resolves the CodeQL CLI, and provides an MCP server definition provider. Add two new MCP server tools: - list_codeql_databases: discovers databases in configured base dirs - list_query_run_results: discovers per-run result directories Supporting changes: - Add discovery-config module for env-var-based directory parsing - Set timeout: 0 for fresh-process CodeQL commands in cli-executor - Add .vscode workspace configuration (launch, tasks, mcp) - Add root tsconfig project reference for the extension - Add integration test fixtures for the new tools --- .vscode/launch.json | 34 + .vscode/mcp.json | 12 + .vscode/tasks.json | 51 + .../no_dirs_configured/README.md | 6 + .../after/monitoring-state.json | 14 + .../before/monitoring-state.json | 4 + .../no_dirs_configured/test-config.json | 4 + .../no_dirs_configured/README.md | 6 + .../after/monitoring-state.json | 14 + .../before/monitoring-state.json | 4 + .../no_dirs_configured/test-config.json | 4 + docs/ql-mcp/tools.md | 6 +- docs/vscode/extension.md | 66 ++ extensions/vscode/.vscodeignore | 15 + extensions/vscode/README.md | 3 + extensions/vscode/__mocks__/vscode.ts | 148 +++ extensions/vscode/esbuild.config.js | 67 ++ extensions/vscode/eslint.config.mjs | 106 ++ extensions/vscode/package.json | 138 +++ .../vscode/src/bridge/database-watcher.ts | 76 ++ .../vscode/src/bridge/environment-builder.ts | 94 ++ .../src/bridge/query-results-watcher.ts | 61 ++ extensions/vscode/src/bridge/storage-paths.ts | 64 ++ extensions/vscode/src/codeql/cli-resolver.ts | 118 +++ extensions/vscode/src/common/disposable.ts | 22 + extensions/vscode/src/common/logger.ts | 43 + extensions/vscode/src/extension.ts | 202 ++++ extensions/vscode/src/server/mcp-provider.ts | 68 ++ .../vscode/src/server/pack-installer.ts | 121 +++ .../vscode/src/server/server-manager.ts | 185 ++++ .../test/bridge/database-watcher.test.ts | 119 +++ .../test/bridge/environment-builder.test.ts | 127 +++ .../test/bridge/query-results-watcher.test.ts | 126 +++ .../vscode/test/bridge/storage-paths.test.ts | 50 + .../vscode/test/codeql/cli-resolver.test.ts | 167 ++++ extensions/vscode/test/extension.test.ts | 158 +++ extensions/vscode/test/helpers/vscode-mock.ts | 76 ++ .../vscode/test/server/mcp-provider.test.ts | 128 +++ .../vscode/test/server/pack-installer.test.ts | 189 ++++ .../vscode/test/server/server-manager.test.ts | 163 +++ extensions/vscode/test/setup.ts | 7 + .../test/suite/extension.integration.test.ts | 61 ++ extensions/vscode/test/suite/index.ts | 49 + extensions/vscode/test/tsconfig.json | 16 + extensions/vscode/tsconfig.json | 25 + extensions/vscode/vitest.config.ts | 20 + package-lock.json | 926 +++++++++++++++++- package.json | 18 +- server/dist/codeql-development-mcp-server.js | 917 +++++++++++------ .../dist/codeql-development-mcp-server.js.map | 8 +- server/src/lib/cli-executor.ts | 6 +- server/src/lib/discovery-config.ts | 48 + server/src/tools/codeql-tools.ts | 4 + server/src/tools/codeql/index.ts | 2 + server/src/tools/codeql/list-databases.ts | 196 ++++ .../tools/codeql/list-query-run-results.ts | 188 ++++ server/test/src/lib/discovery-config.test.ts | 86 ++ server/test/src/tools/codeql-tools.test.ts | 6 +- .../src/tools/codeql/list-databases.test.ts | 144 +++ .../codeql/list-query-run-results.test.ts | 141 +++ tsconfig.json | 3 + 61 files changed, 5583 insertions(+), 347 deletions(-) create mode 100644 .vscode/launch.json create mode 100644 .vscode/mcp.json create mode 100644 .vscode/tasks.json create mode 100644 client/integration-tests/primitives/tools/list_codeql_databases/no_dirs_configured/README.md create mode 100644 client/integration-tests/primitives/tools/list_codeql_databases/no_dirs_configured/after/monitoring-state.json create mode 100644 client/integration-tests/primitives/tools/list_codeql_databases/no_dirs_configured/before/monitoring-state.json create mode 100644 client/integration-tests/primitives/tools/list_codeql_databases/no_dirs_configured/test-config.json create mode 100644 client/integration-tests/primitives/tools/list_query_run_results/no_dirs_configured/README.md create mode 100644 client/integration-tests/primitives/tools/list_query_run_results/no_dirs_configured/after/monitoring-state.json create mode 100644 client/integration-tests/primitives/tools/list_query_run_results/no_dirs_configured/before/monitoring-state.json create mode 100644 client/integration-tests/primitives/tools/list_query_run_results/no_dirs_configured/test-config.json create mode 100644 docs/vscode/extension.md create mode 100644 extensions/vscode/.vscodeignore create mode 100644 extensions/vscode/README.md create mode 100644 extensions/vscode/__mocks__/vscode.ts create mode 100644 extensions/vscode/esbuild.config.js create mode 100644 extensions/vscode/eslint.config.mjs create mode 100644 extensions/vscode/package.json create mode 100644 extensions/vscode/src/bridge/database-watcher.ts create mode 100644 extensions/vscode/src/bridge/environment-builder.ts create mode 100644 extensions/vscode/src/bridge/query-results-watcher.ts create mode 100644 extensions/vscode/src/bridge/storage-paths.ts create mode 100644 extensions/vscode/src/codeql/cli-resolver.ts create mode 100644 extensions/vscode/src/common/disposable.ts create mode 100644 extensions/vscode/src/common/logger.ts create mode 100644 extensions/vscode/src/extension.ts create mode 100644 extensions/vscode/src/server/mcp-provider.ts create mode 100644 extensions/vscode/src/server/pack-installer.ts create mode 100644 extensions/vscode/src/server/server-manager.ts create mode 100644 extensions/vscode/test/bridge/database-watcher.test.ts create mode 100644 extensions/vscode/test/bridge/environment-builder.test.ts create mode 100644 extensions/vscode/test/bridge/query-results-watcher.test.ts create mode 100644 extensions/vscode/test/bridge/storage-paths.test.ts create mode 100644 extensions/vscode/test/codeql/cli-resolver.test.ts create mode 100644 extensions/vscode/test/extension.test.ts create mode 100644 extensions/vscode/test/helpers/vscode-mock.ts create mode 100644 extensions/vscode/test/server/mcp-provider.test.ts create mode 100644 extensions/vscode/test/server/pack-installer.test.ts create mode 100644 extensions/vscode/test/server/server-manager.test.ts create mode 100644 extensions/vscode/test/setup.ts create mode 100644 extensions/vscode/test/suite/extension.integration.test.ts create mode 100644 extensions/vscode/test/suite/index.ts create mode 100644 extensions/vscode/test/tsconfig.json create mode 100644 extensions/vscode/tsconfig.json create mode 100644 extensions/vscode/vitest.config.ts create mode 100644 server/src/lib/discovery-config.ts create mode 100644 server/src/tools/codeql/list-databases.ts create mode 100644 server/src/tools/codeql/list-query-run-results.ts create mode 100644 server/test/src/lib/discovery-config.test.ts create mode 100644 server/test/src/tools/codeql/list-databases.test.ts create mode 100644 server/test/src/tools/codeql/list-query-run-results.test.ts diff --git a/.vscode/launch.json b/.vscode/launch.json new file mode 100644 index 00000000..83509441 --- /dev/null +++ b/.vscode/launch.json @@ -0,0 +1,34 @@ +{ + "version": "0.2.0", + "configurations": [ + { + "name": "Run Extension", + "type": "extensionHost", + "request": "launch", + "args": [ + "--extensionDevelopmentPath=${workspaceFolder}/extensions/vscode" + ], + "outFiles": [ + "${workspaceFolder}/extensions/vscode/dist/**/*.js", + "${workspaceFolder}/extensions/vscode/dist/**/*.cjs" + ], + "preLaunchTask": "npm: bundle - extensions/vscode", + "sourceMaps": true + }, + { + "name": "Extension Tests", + "type": "extensionHost", + "request": "launch", + "args": [ + "--extensionDevelopmentPath=${workspaceFolder}/extensions/vscode", + "--extensionTestsPath=${workspaceFolder}/extensions/vscode/dist/test/suite/index.cjs" + ], + "outFiles": [ + "${workspaceFolder}/extensions/vscode/dist/**/*.js", + "${workspaceFolder}/extensions/vscode/dist/**/*.cjs" + ], + "preLaunchTask": "npm: bundle - extensions/vscode", + "sourceMaps": true + } + ] +} diff --git a/.vscode/mcp.json b/.vscode/mcp.json new file mode 100644 index 00000000..13c1b1a4 --- /dev/null +++ b/.vscode/mcp.json @@ -0,0 +1,12 @@ +{ + "servers": { + "ql-mcp": { + "type": "stdio", + "command": "node", + "args": [ + "/Users/data-douser/Git/advanced-security/codeql-development-mcp-server/server/dist/codeql-development-mcp-server.js" + ] + } + }, + "inputs": [] +} \ No newline at end of file diff --git a/.vscode/tasks.json b/.vscode/tasks.json new file mode 100644 index 00000000..ba55a021 --- /dev/null +++ b/.vscode/tasks.json @@ -0,0 +1,51 @@ +{ + "version": "2.0.0", + "tasks": [ + { + "type": "npm", + "script": "build", + "path": "extensions/vscode", + "label": "npm: build - extensions/vscode", + "group": "build", + "problemMatcher": [], + "detail": "Clean, lint, and bundle the VS Code extension" + }, + { + "type": "npm", + "script": "bundle", + "path": "extensions/vscode", + "label": "npm: bundle - extensions/vscode", + "group": "build", + "problemMatcher": [], + "detail": "Bundle the VS Code extension (no lint)" + }, + { + "type": "npm", + "script": "watch", + "path": "extensions/vscode", + "label": "npm: watch - extensions/vscode", + "group": "build", + "isBackground": true, + "problemMatcher": [], + "detail": "Watch and rebuild the VS Code extension on changes" + }, + { + "type": "npm", + "script": "test", + "path": "extensions/vscode", + "label": "npm: test - extensions/vscode", + "group": "test", + "problemMatcher": [], + "detail": "Run unit tests for the VS Code extension" + }, + { + "type": "npm", + "script": "build", + "path": "server", + "label": "npm: build - server", + "group": "build", + "problemMatcher": [], + "detail": "Build the MCP server" + } + ] +} diff --git a/client/integration-tests/primitives/tools/list_codeql_databases/no_dirs_configured/README.md b/client/integration-tests/primitives/tools/list_codeql_databases/no_dirs_configured/README.md new file mode 100644 index 00000000..020f3fe2 --- /dev/null +++ b/client/integration-tests/primitives/tools/list_codeql_databases/no_dirs_configured/README.md @@ -0,0 +1,6 @@ +# `list_codeql_databases` - no_dirs_configured + +## Purpose + +Tests the `list_codeql_databases` tool when `CODEQL_DATABASES_BASE_DIRS` is not set. +The tool should return a helpful message explaining how to configure it. diff --git a/client/integration-tests/primitives/tools/list_codeql_databases/no_dirs_configured/after/monitoring-state.json b/client/integration-tests/primitives/tools/list_codeql_databases/no_dirs_configured/after/monitoring-state.json new file mode 100644 index 00000000..200bd35a --- /dev/null +++ b/client/integration-tests/primitives/tools/list_codeql_databases/no_dirs_configured/after/monitoring-state.json @@ -0,0 +1,14 @@ +{ + "sessions": [ + { + "id": "integration_test_session", + "calls": [ + { + "tool": "list_codeql_databases", + "timestamp": "2025-09-25T16:06:00.000Z", + "status": "success" + } + ] + } + ] +} diff --git a/client/integration-tests/primitives/tools/list_codeql_databases/no_dirs_configured/before/monitoring-state.json b/client/integration-tests/primitives/tools/list_codeql_databases/no_dirs_configured/before/monitoring-state.json new file mode 100644 index 00000000..b216e005 --- /dev/null +++ b/client/integration-tests/primitives/tools/list_codeql_databases/no_dirs_configured/before/monitoring-state.json @@ -0,0 +1,4 @@ +{ + "sessions": [], + "parameters": {} +} diff --git a/client/integration-tests/primitives/tools/list_codeql_databases/no_dirs_configured/test-config.json b/client/integration-tests/primitives/tools/list_codeql_databases/no_dirs_configured/test-config.json new file mode 100644 index 00000000..036cea5a --- /dev/null +++ b/client/integration-tests/primitives/tools/list_codeql_databases/no_dirs_configured/test-config.json @@ -0,0 +1,4 @@ +{ + "toolName": "list_codeql_databases", + "arguments": {} +} diff --git a/client/integration-tests/primitives/tools/list_query_run_results/no_dirs_configured/README.md b/client/integration-tests/primitives/tools/list_query_run_results/no_dirs_configured/README.md new file mode 100644 index 00000000..537edefc --- /dev/null +++ b/client/integration-tests/primitives/tools/list_query_run_results/no_dirs_configured/README.md @@ -0,0 +1,6 @@ +# `list_query_run_results` - no_dirs_configured + +## Purpose + +Tests the `list_query_run_results` tool when `CODEQL_QUERY_RUN_RESULTS_DIRS` is not set. +The tool should return a helpful message explaining how to configure it. diff --git a/client/integration-tests/primitives/tools/list_query_run_results/no_dirs_configured/after/monitoring-state.json b/client/integration-tests/primitives/tools/list_query_run_results/no_dirs_configured/after/monitoring-state.json new file mode 100644 index 00000000..e1bec348 --- /dev/null +++ b/client/integration-tests/primitives/tools/list_query_run_results/no_dirs_configured/after/monitoring-state.json @@ -0,0 +1,14 @@ +{ + "sessions": [ + { + "id": "integration_test_session", + "calls": [ + { + "tool": "list_query_run_results", + "timestamp": "2025-09-25T16:06:00.000Z", + "status": "success" + } + ] + } + ] +} diff --git a/client/integration-tests/primitives/tools/list_query_run_results/no_dirs_configured/before/monitoring-state.json b/client/integration-tests/primitives/tools/list_query_run_results/no_dirs_configured/before/monitoring-state.json new file mode 100644 index 00000000..b216e005 --- /dev/null +++ b/client/integration-tests/primitives/tools/list_query_run_results/no_dirs_configured/before/monitoring-state.json @@ -0,0 +1,4 @@ +{ + "sessions": [], + "parameters": {} +} diff --git a/client/integration-tests/primitives/tools/list_query_run_results/no_dirs_configured/test-config.json b/client/integration-tests/primitives/tools/list_query_run_results/no_dirs_configured/test-config.json new file mode 100644 index 00000000..c1c1797e --- /dev/null +++ b/client/integration-tests/primitives/tools/list_query_run_results/no_dirs_configured/test-config.json @@ -0,0 +1,4 @@ +{ + "toolName": "list_query_run_results", + "arguments": {} +} diff --git a/docs/ql-mcp/tools.md b/docs/ql-mcp/tools.md index f2501c8c..84980810 100644 --- a/docs/ql-mcp/tools.md +++ b/docs/ql-mcp/tools.md @@ -4,9 +4,9 @@ ## Overview -The server exposes **34 always-on tools** and **11 optional monitoring tools**. Always-on tools are available in every session; monitoring tools require explicit opt-in (see [Monitoring and Reporting](../mcp-server-monitoring-and-reporting.md)). +The server exposes **36 default tools** and **11 opt-in monitoring tools**. Default tools are registered on startup; monitoring tools require explicit opt-in (see [Monitoring and Reporting](../mcp-server-monitoring-and-reporting.md)). Users control which tools are enabled in their MCP client configuration. -## Always-On Tools +## Default Tools ### CodeQL CLI Tools @@ -52,6 +52,8 @@ The server exposes **34 always-on tools** and **11 optional monitoring tools**. | `find_class_position` | Find the start/end line and column of a class for quick evaluation | | `find_codeql_query_files` | Find and track all files and directories related to a CodeQL query, including resolved metadata | | `find_predicate_position` | Find the start/end line and column of a predicate for quick evaluation | +| `list_codeql_databases` | List CodeQL databases discovered in configured base directories (`CODEQL_DATABASES_BASE_DIRS`) | +| `list_query_run_results` | List discovered query run result directories with artifact inventory (`CODEQL_QUERY_RUN_RESULTS_DIRS`) | | `profile_codeql_query` | Profile the performance of a CodeQL query run against a specific database by analyzing the evaluator log JSON file | | `quick_evaluate` | Quick evaluate either a class or a predicate in a CodeQL query for debugging | | `register_database` | Register a CodeQL database given a local path to the database directory | diff --git a/docs/vscode/extension.md b/docs/vscode/extension.md new file mode 100644 index 00000000..e6ee84cf --- /dev/null +++ b/docs/vscode/extension.md @@ -0,0 +1,66 @@ +# VS Code Extension + +The **CodeQL Development MCP Server** VS Code extension automates the setup and +configuration that the [manual installation](../getting-started.md) requires you +to do by hand. + +## Why use the extension? + +| Manual setup (`mcp.json`) | VS Code extension | +| -------------------------------------------------------- | ------------------------------------------------------------------- | +| Edit `mcp.json` with the correct paths | Registers the MCP server automatically | +| Run `codeql-development-mcp-server-setup-packs` yourself | Installs tool query packs on activation | +| Set `CODEQL_PATH` if CodeQL is not on `PATH` | Discovers the CodeQL CLI from the CodeQL extension | +| No awareness of CodeQL databases or query history | Discovers databases and query run results from the CodeQL extension | + +## Installation + +Install from the VS Code Marketplace: + +1. Open VS Code +2. Go to Extensions (`Ctrl+Shift+X` / `Cmd+Shift+X`) +3. Search **"CodeQL Development MCP Server"** +4. Click **Install** + +The extension requires the [CodeQL extension](https://marketplace.visualstudio.com/items?itemName=GitHub.vscode-codeql) (`GitHub.vscode-codeql`) and will prompt you to install it if missing. + +## What it does + +On activation the extension: + +1. **Finds the CodeQL CLI** — checks `CODEQL_PATH`, `PATH`, and known install + locations (including the CodeQL extension's managed CLI). +2. **Installs the MCP server** — downloads and caches the + `codeql-development-mcp-server` npm package in the extension's global storage. +3. **Installs CodeQL tool query packs** — runs `codeql pack install` for each + supported language so tools like PrintAST and CallGraph work immediately. +4. **Registers the MCP server** — provides a + `McpServerDefinitionProvider` so VS Code discovers the server without any + `mcp.json` edits. +5. **Bridges the CodeQL extension** — watches for databases and query results + created by the CodeQL extension and passes their locations to the MCP server + via `CODEQL_DATABASES_BASE_DIRS` and `CODEQL_QUERY_RUN_RESULTS_DIRS` + environment variables. + +## Settings + +| Setting | Default | Description | +| --------------------------------- | ---------- | -------------------------------------------------------------- | +| `codeql-mcp.autoInstall` | `true` | Automatically install/update the MCP server on activation | +| `codeql-mcp.serverVersion` | `"latest"` | npm version to install (`"latest"` or a specific version) | +| `codeql-mcp.watchCodeqlExtension` | `true` | Discover databases and query results from the CodeQL extension | +| `codeql-mcp.additionalEnv` | `{}` | Extra environment variables for the MCP server process | + +## Commands + +Open the Command Palette (`Ctrl+Shift+P` / `Cmd+Shift+P`) and type **CodeQL MCP**: + +- **Reinstall MCP Server** — re-download the MCP server package +- **Reinstall CodeQL Tool Query Packs** — re-run `codeql pack install` for all languages +- **Show Status** — display current server and CLI status + +## How it connects to GitHub Copilot + +Once the extension is active, the MCP server appears in Copilot's server list +(Command Palette → "GitHub Copilot: List MCP Servers"). All MCP tools, prompts, +and resources are available to Copilot automatically — no further configuration needed. diff --git a/extensions/vscode/.vscodeignore b/extensions/vscode/.vscodeignore new file mode 100644 index 00000000..383a8169 --- /dev/null +++ b/extensions/vscode/.vscodeignore @@ -0,0 +1,15 @@ +.vscode/** +.vscode-test/** +src/** +test/** +node_modules/** +.gitignore +tsconfig.json +test/tsconfig.json +vitest.config.ts +eslint.config.mjs +esbuild.config.js +**/*.test.ts +**/*.test.js +**/*.map +coverage/** diff --git a/extensions/vscode/README.md b/extensions/vscode/README.md new file mode 100644 index 00000000..df736e34 --- /dev/null +++ b/extensions/vscode/README.md @@ -0,0 +1,3 @@ +# VS Code Extension for `codeql-development-mcp-server` + +TODO diff --git a/extensions/vscode/__mocks__/vscode.ts b/extensions/vscode/__mocks__/vscode.ts new file mode 100644 index 00000000..c1706f83 --- /dev/null +++ b/extensions/vscode/__mocks__/vscode.ts @@ -0,0 +1,148 @@ +/** + * Mock for the `vscode` module. + * + * Used via resolve.alias in vitest.config.ts so that all imports of + * 'vscode' resolve to this file during tests. + * + * Does NOT use vi.fn() — uses plain functions/objects so it can be + * loaded as a regular module without vitest bootstrapping. + */ + +const noop = () => {}; +const noopReturn = (val: any) => () => val; + +function createEventEmitter() { + const listeners: Function[] = []; + return { + event: (listener: Function) => { + listeners.push(listener); + return { dispose: noop }; + }, + fire: (...args: unknown[]) => { + for (const l of listeners) l(...args); + }, + dispose: () => { listeners.length = 0; }, + }; +} + +function createOutputChannelMock() { + return { + appendLine: noop, append: noop, clear: noop, show: noop, + hide: noop, dispose: noop, info: noop, warn: noop, + error: noop, debug: noop, trace: noop, logLevel: 3, + name: 'CodeQL MCP', onDidChangeLogLevel: noop, + replace: noop, + }; +} + +function createFileSystemWatcherMock() { + return { + onDidCreate: noopReturn({ dispose: noop }), + onDidChange: noopReturn({ dispose: noop }), + onDidDelete: noopReturn({ dispose: noop }), + ignoreCreateEvents: false, + ignoreChangeEvents: false, + ignoreDeleteEvents: false, + dispose: noop, + }; +} + +function createConfigMock() { + return { + get: (_key: string, defaultVal?: any) => defaultVal, + has: () => false, + inspect: () => undefined, + update: () => Promise.resolve(), + }; +} + +export class EventEmitter { + private _emitter = createEventEmitter(); + get event() { return this._emitter.event; } + fire(...args: unknown[]) { this._emitter.fire(...args); } + dispose() { this._emitter.dispose(); } +} + +export const Uri = { + file: (p: string) => ({ fsPath: p, scheme: 'file', path: p }), + joinPath: (b: any, ...s: string[]) => ({ + fsPath: [b.fsPath, ...s].join('/'), + scheme: 'file', + path: [b.path, ...s].join('/'), + }), + parse: (v: string) => ({ fsPath: v, scheme: 'file', path: v }), +}; + +export const workspace = { + getConfiguration: () => createConfigMock(), + createFileSystemWatcher: () => createFileSystemWatcherMock(), + workspaceFolders: [] as any[], + onDidChangeConfiguration: noopReturn({ dispose: noop }), + onDidChangeWorkspaceFolders: noopReturn({ dispose: noop }), + onDidCreateFiles: noopReturn({ dispose: noop }), + onDidSaveTextDocument: noopReturn({ dispose: noop }), + fs: { stat: noop, readFile: noop, readDirectory: noop }, +}; + +export const window = { + createOutputChannel: () => createOutputChannelMock(), + showInformationMessage: noop, + showWarningMessage: noop, + showErrorMessage: noop, + createStatusBarItem: () => ({ + show: noop, hide: noop, dispose: noop, + text: '', tooltip: '', command: undefined, + }), + onDidChangeActiveTextEditor: noopReturn({ dispose: noop }), +}; + +export const commands = { + registerCommand: () => ({ dispose: noop }), + executeCommand: noop, +}; + +export const extensions = { + getExtension: () => undefined, + all: [], + onDidChange: noopReturn({ dispose: noop }), +}; + +export const tasks = { + onDidEndTask: noopReturn({ dispose: noop }), + onDidEndTaskProcess: noopReturn({ dispose: noop }), +}; + +export const languages = { + onDidChangeDiagnostics: noopReturn({ dispose: noop }), +}; + +export const lm = { + registerMcpServerDefinitionProvider: () => ({ dispose: noop }), +}; + +export class Disposable { + private _callOnDispose: () => void; + constructor(callOnDispose: () => void) { this._callOnDispose = callOnDispose; } + static from(...disposableLikes: Array<{ dispose: () => any }>) { + return new Disposable(() => { for (const d of disposableLikes) d.dispose(); }); + } + dispose() { this._callOnDispose(); } +} + +export const StatusBarAlignment = { Left: 1, Right: 2 }; +export const ConfigurationTarget = { Global: 1, Workspace: 2, WorkspaceFolder: 3 }; + +export class McpStdioServerDefinition { + label: string; + command: string; + args: string[]; + env: Record; + version?: string; + constructor(label: string, command: string, args?: string[], env?: Record, version?: string) { + this.label = label; + this.command = command; + this.args = args ?? []; + this.env = env ?? {}; + this.version = version; + } +} diff --git a/extensions/vscode/esbuild.config.js b/extensions/vscode/esbuild.config.js new file mode 100644 index 00000000..e29449af --- /dev/null +++ b/extensions/vscode/esbuild.config.js @@ -0,0 +1,67 @@ +import { build, context } from 'esbuild'; +import { existsSync } from 'fs'; +import { mkdir } from 'fs/promises'; + +const distDir = 'dist'; + +// Ensure dist directory exists +if (!existsSync(distDir)) { + await mkdir(distDir, { recursive: true }); +} + +const shared = { + bundle: true, + format: 'cjs', + platform: 'node', + target: 'node22', + sourcemap: true, + external: ['vscode'], + write: true, + metafile: false, + splitting: false, +}; + +// Main extension bundle +const extensionConfig = { + ...shared, + entryPoints: ['src/extension.ts'], + outfile: 'dist/extension.cjs', +}; + +// Integration test suite — each file is a separate output so the Mocha +// runner can discover them via glob at runtime. +const testSuiteConfig = { + ...shared, + entryPoints: [ + 'test/suite/index.ts', + 'test/suite/extension.integration.test.ts', + ], + outdir: 'dist/test/suite', + outfile: undefined, // outdir and outfile are mutually exclusive + outExtension: { '.js': '.cjs' }, + external: ['vscode'], + logOverride: { + 'require-resolve-not-external': 'silent', + }, +}; + +const isWatch = process.argv.includes('--watch'); + +if (isWatch) { + const ctx = await context(extensionConfig); + await ctx.watch(); + console.log('👀 Watching for changes...'); +} else { + try { + await build(extensionConfig); + console.log('✅ Extension build completed successfully'); + console.log(`📦 Generated: dist/extension.cjs`); + + await build(testSuiteConfig); + console.log('✅ Test suite build completed successfully'); + console.log(`📦 Generated: dist/test/suite/*.cjs`); + } catch (error) { + console.error('❌ Build failed:', error); + process.exit(1); + } +} diff --git a/extensions/vscode/eslint.config.mjs b/extensions/vscode/eslint.config.mjs new file mode 100644 index 00000000..e7eb367f --- /dev/null +++ b/extensions/vscode/eslint.config.mjs @@ -0,0 +1,106 @@ +import js from '@eslint/js'; +import typescript from 'typescript-eslint'; +import prettier from 'eslint-config-prettier'; + +export default [ + js.configs.recommended, + prettier, + { + files: ['src/**/*.ts'], + languageOptions: { + ecmaVersion: 2022, + sourceType: 'module', + parser: typescript.parser, + globals: { + process: 'readonly', + console: 'readonly', + Buffer: 'readonly', + __dirname: 'readonly', + __filename: 'readonly', + }, + parserOptions: { + tsconfigRootDir: import.meta.dirname, + project: ['./tsconfig.json'], + }, + }, + plugins: { + '@typescript-eslint': typescript.plugin, + }, + rules: { + ...typescript.configs.recommendedTypeChecked[0].rules, + '@typescript-eslint/no-unused-vars': ['error', { + argsIgnorePattern: '^_', + varsIgnorePattern: '^_', + caughtErrorsIgnorePattern: '^_', + }], + 'no-unused-vars': 'off', + '@typescript-eslint/explicit-function-return-type': 'off', + '@typescript-eslint/no-explicit-any': 'warn', + }, + }, + { + // Handle test files with their own tsconfig - more lenient rules for tests + files: ['test/**/*.ts'], + languageOptions: { + ecmaVersion: 2022, + sourceType: 'module', + parser: typescript.parser, + globals: { + process: 'readonly', + console: 'readonly', + Buffer: 'readonly', + __dirname: 'readonly', + __filename: 'readonly', + }, + parserOptions: { + tsconfigRootDir: import.meta.dirname, + project: ['./test/tsconfig.json'], + }, + }, + plugins: { + '@typescript-eslint': typescript.plugin, + }, + rules: { + ...typescript.configs.recommendedTypeChecked[0].rules, + '@typescript-eslint/no-unused-vars': ['error', { + argsIgnorePattern: '^_', + varsIgnorePattern: '^_', + caughtErrorsIgnorePattern: '^_', + }], + 'no-unused-vars': 'off', + '@typescript-eslint/explicit-function-return-type': 'off', + '@typescript-eslint/no-explicit-any': 'off', + }, + }, + { + files: ['*.config.{js,mjs,ts}', 'eslint.config.mjs'], + languageOptions: { + ecmaVersion: 2022, + sourceType: 'module', + }, + rules: {}, + }, + { + // Integration test suite files use Mocha globals (suite/test), + // not vitest, and don't need type-checked lint rules. + files: ['test/suite/**/*.ts'], + languageOptions: { + ecmaVersion: 2022, + sourceType: 'module', + globals: { + suite: 'readonly', + test: 'readonly', + setup: 'readonly', + teardown: 'readonly', + suiteSetup: 'readonly', + suiteTeardown: 'readonly', + }, + }, + rules: { + 'no-unused-vars': 'off', + }, + }, + { + ignores: ['dist/', 'node_modules/', 'esbuild.config.js'], + }, +]; diff --git a/extensions/vscode/package.json b/extensions/vscode/package.json new file mode 100644 index 00000000..a35a37bf --- /dev/null +++ b/extensions/vscode/package.json @@ -0,0 +1,138 @@ +{ + "name": "codeql-development-mcp-server-vscode", + "displayName": "CodeQL Development MCP Server", + "description": "Automatically installs, configures, and manages the CodeQL Development MCP Server in VS Code.", + "version": "2.24.1", + "publisher": "advanced-security", + "license": "SEE LICENSE IN LICENSE", + "repository": { + "type": "git", + "url": "git+https://github.com/advanced-security/codeql-development-mcp-server.git", + "directory": "extensions/vscode" + }, + "type": "module", + "homepage": "https://github.com/advanced-security/codeql-development-mcp-server#readme", + "bugs": { + "url": "https://github.com/advanced-security/codeql-development-mcp-server/issues" + }, + "engines": { + "vscode": "^1.99.0", + "node": ">=24.13.0" + }, + "categories": [ + "AI", + "Programming Languages", + "Other" + ], + "keywords": [ + "codeql", + "mcp", + "model-context-protocol", + "static-analysis", + "security" + ], + "activationEvents": [ + "onStartupFinished" + ], + "main": "./dist/extension.cjs", + "extensionDependencies": [ + "GitHub.vscode-codeql" + ], + "contributes": { + "mcpServerDefinitionProviders": [ + { + "id": "ql-mcp", + "label": "CodeQL Development MCP Server" + } + ], + "configuration": { + "title": "CodeQL MCP Server", + "properties": { + "codeql-mcp.autoInstall": { + "type": "boolean", + "default": true, + "description": "Automatically install and update the CodeQL Development MCP Server on activation." + }, + "codeql-mcp.serverVersion": { + "type": "string", + "default": "latest", + "description": "The npm version of codeql-development-mcp-server to install. Use 'latest' for the most recent release." + }, + "codeql-mcp.serverCommand": { + "type": "string", + "default": "npx", + "description": "Command to launch the MCP server. Override to 'node' for local development builds." + }, + "codeql-mcp.serverArgs": { + "type": "array", + "items": { "type": "string" }, + "default": [], + "description": "Custom arguments for the MCP server command. When empty, defaults to ['-y', 'codeql-development-mcp-server']. Set to e.g. ['/path/to/server/dist/codeql-development-mcp-server.js'] when using serverCommand='node' for local development." + }, + "codeql-mcp.watchCodeqlExtension": { + "type": "boolean", + "default": true, + "description": "Watch for CodeQL databases and query results created by the CodeQL extension." + }, + "codeql-mcp.additionalEnv": { + "type": "object", + "default": {}, + "description": "Additional environment variables to pass to the MCP server process.", + "additionalProperties": { + "type": "string" + } + } + } + }, + "commands": [ + { + "command": "codeql-mcp.reinstallServer", + "title": "Reinstall MCP Server", + "category": "CodeQL MCP" + }, + { + "command": "codeql-mcp.reinstallPacks", + "title": "Reinstall CodeQL Tool Query Packs", + "category": "CodeQL MCP" + }, + { + "command": "codeql-mcp.showStatus", + "title": "Show Status", + "category": "CodeQL MCP" + }, + { + "command": "codeql-mcp.showLogs", + "title": "Show Logs", + "category": "CodeQL MCP" + } + ] + }, + "scripts": { + "build": "npm run clean && npm run lint && npm run bundle", + "bundle": "node esbuild.config.js", + "clean": "rm -rf dist", + "lint": "eslint src/ test/", + "lint:fix": "eslint src/ test/ --fix", + "test": "vitest --run", + "test:coverage": "vitest --run --coverage", + "test:watch": "vitest --watch", + "watch": "node esbuild.config.js --watch" + }, + "devDependencies": { + "@eslint/js": "^9.39.2", + "@types/mocha": "^10.0.10", + "@types/node": "^22.15.0", + "@types/vscode": "^1.99.0", + "@vitest/coverage-v8": "^4.0.18", + "esbuild": "^0.27.3", + "eslint": "^9.39.2", + "eslint-config-prettier": "^10.1.8", + "eslint-plugin-prettier": "^5.5.5", + "glob": "^11.0.2", + "mocha": "^11.2.2", + "prettier": "^3.8.1", + "typescript": "^5.9.3", + "typescript-eslint": "^8.54.0", + "vitest": "^4.0.18" + } +} diff --git a/extensions/vscode/src/bridge/database-watcher.ts b/extensions/vscode/src/bridge/database-watcher.ts new file mode 100644 index 00000000..48c6ba20 --- /dev/null +++ b/extensions/vscode/src/bridge/database-watcher.ts @@ -0,0 +1,76 @@ +import * as vscode from 'vscode'; +import { DisposableObject } from '../common/disposable'; +import type { Logger } from '../common/logger'; +import type { StoragePaths } from './storage-paths'; + +/** + * Watches for CodeQL databases created by the `vscode-codeql` extension. + * + * Detection strategy combines: + * - `workspace.createFileSystemWatcher` for `codeql-database.yml` files + * - `workspace.onDidChangeWorkspaceFolders` for new workspace folders + * + * Data access is filesystem-only; notifications come from VS Code public APIs. + */ +export class DatabaseWatcher extends DisposableObject { + private readonly _onDidChange = new vscode.EventEmitter(); + readonly onDidChange = this._onDidChange.event; + + private readonly knownDatabases = new Set(); + + constructor( + private readonly storagePaths: StoragePaths, + private readonly logger: Logger, + ) { + super(); + this.push(this._onDidChange); + + // Watch for codeql-database.yml files being created anywhere in + // the workspace or under the vscode-codeql storage directory. + const watcher = vscode.workspace.createFileSystemWatcher( + '**/codeql-database.yml', + ); + + this.push(watcher); + + watcher.onDidCreate((uri) => { + this.handleDatabaseDiscovered(uri.fsPath); + }); + + watcher.onDidDelete((uri) => { + this.handleDatabaseRemoved(uri.fsPath); + }); + + // Also watch workspace folder changes + const wsFolderSub = vscode.workspace.onDidChangeWorkspaceFolders(() => { + this.logger.debug('Workspace folders changed — re-scanning for databases'); + this._onDidChange.fire(); + }); + if (wsFolderSub && typeof wsFolderSub.dispose === 'function') { + this.push(wsFolderSub as vscode.Disposable); + } + } + + /** Get all currently known database paths. */ + getKnownDatabases(): ReadonlySet { + return this.knownDatabases; + } + + private handleDatabaseDiscovered(ymlPath: string): void { + // The database root is the parent directory of codeql-database.yml + const dbRoot = ymlPath.replace(/\/codeql-database\.yml$/, ''); + if (!this.knownDatabases.has(dbRoot)) { + this.knownDatabases.add(dbRoot); + this.logger.info(`Database discovered: ${dbRoot}`); + this._onDidChange.fire(); + } + } + + private handleDatabaseRemoved(ymlPath: string): void { + const dbRoot = ymlPath.replace(/\/codeql-database\.yml$/, ''); + if (this.knownDatabases.delete(dbRoot)) { + this.logger.info(`Database removed: ${dbRoot}`); + this._onDidChange.fire(); + } + } +} diff --git a/extensions/vscode/src/bridge/environment-builder.ts b/extensions/vscode/src/bridge/environment-builder.ts new file mode 100644 index 00000000..e3fd4282 --- /dev/null +++ b/extensions/vscode/src/bridge/environment-builder.ts @@ -0,0 +1,94 @@ +import * as vscode from 'vscode'; +import { join } from 'path'; +import { DisposableObject } from '../common/disposable'; +import type { Logger } from '../common/logger'; +import type { CliResolver } from '../codeql/cli-resolver'; +import type { StoragePaths } from './storage-paths'; + +/** + * Assembles the environment variables for the MCP server process. + * + * Combines: + * - Resolved CodeQL CLI path + * - Workspace root path + * - vscode-codeql storage paths (for CODEQL_ADDITIONAL_PACKS) + * - User-configured additional env vars + * - Fixed transport mode (stdio) + * + * Results are cached. Call `invalidate()` when any input changes. + */ +export class EnvironmentBuilder extends DisposableObject { + private cachedEnv: Record | null = null; + + constructor( + private readonly context: vscode.ExtensionContext, + private readonly cliResolver: CliResolver, + private readonly storagePaths: StoragePaths, + private readonly logger: Logger, + ) { + super(); + } + + /** Invalidate the cached environment so the next `build()` recomputes. */ + invalidate(): void { + this.cachedEnv = null; + } + + /** Build the full environment object for the MCP server process. */ + async build(): Promise> { + if (this.cachedEnv) { + return this.cachedEnv; + } + + const env: Record = {}; + + // Transport mode is always stdio when launched from VS Code + env.TRANSPORT_MODE = 'stdio'; + + // CodeQL CLI path + const cliPath = await this.cliResolver.resolve(); + if (cliPath) { + env.CODEQL_PATH = cliPath; + } + + // Workspace root + const workspaceFolders = vscode.workspace.workspaceFolders; + if (workspaceFolders && workspaceFolders.length > 0) { + env.CODEQL_MCP_WORKSPACE = workspaceFolders[0].uri.fsPath; + } + + // Temp directory for MCP server scratch files + env.CODEQL_MCP_TMP_DIR = join( + this.context.globalStorageUri.fsPath, + 'tmp', + ); + + // Additional packs path — include vscode-codeql's database storage + // so the MCP server can discover databases registered there + const additionalPaths = [ + this.storagePaths.getDatabaseStoragePath(), + ]; + + // Also include workspace folder paths + if (workspaceFolders) { + for (const folder of workspaceFolders) { + additionalPaths.push(folder.uri.fsPath); + } + } + + env.CODEQL_ADDITIONAL_PACKS = additionalPaths.join(':'); + + // User-configured additional environment variables + const config = vscode.workspace.getConfiguration('codeql-mcp'); + const additionalEnv = config.get>('additionalEnv', {}); + for (const [key, value] of Object.entries(additionalEnv)) { + env[key] = value; + } + + this.logger.debug( + `Built MCP server environment: ${Object.keys(env).join(', ')}`, + ); + this.cachedEnv = env; + return env; + } +} diff --git a/extensions/vscode/src/bridge/query-results-watcher.ts b/extensions/vscode/src/bridge/query-results-watcher.ts new file mode 100644 index 00000000..b3b033e1 --- /dev/null +++ b/extensions/vscode/src/bridge/query-results-watcher.ts @@ -0,0 +1,61 @@ +import * as vscode from 'vscode'; +import { DisposableObject } from '../common/disposable'; +import type { Logger } from '../common/logger'; +import type { StoragePaths } from './storage-paths'; + +/** + * Watches for query results (BQRS and SARIF files) created by the + * `vscode-codeql` extension. + * + * Detection strategy: + * - `workspace.createFileSystemWatcher` for `*.bqrs` and `*-interpreted.sarif` + * - `tasks.onDidEndTask` as a signal that a query may have completed + */ +export class QueryResultsWatcher extends DisposableObject { + private readonly _onDidChange = new vscode.EventEmitter(); + readonly onDidChange = this._onDidChange.event; + + constructor( + private readonly storagePaths: StoragePaths, + private readonly logger: Logger, + ) { + super(); + this.push(this._onDidChange); + + // Watch for BQRS files + const bqrsWatcher = vscode.workspace.createFileSystemWatcher('**/*.bqrs'); + this.push(bqrsWatcher); + bqrsWatcher.onDidCreate((uri) => { + this.logger.info(`Query result (BQRS) created: ${uri.fsPath}`); + this._onDidChange.fire(); + }); + + // Watch for interpreted SARIF files + const sarifWatcher = vscode.workspace.createFileSystemWatcher( + '**/*-interpreted.sarif', + ); + this.push(sarifWatcher); + sarifWatcher.onDidCreate((uri) => { + this.logger.info(`Query result (SARIF) created: ${uri.fsPath}`); + this._onDidChange.fire(); + }); + + // Listen for task completions as a signal that queries may have finished + const taskSub = vscode.tasks.onDidEndTask((e) => { + const taskName = e.execution.task.name.toLowerCase(); + if ( + taskName.includes('codeql') || + taskName.includes('query') || + taskName.includes('test') + ) { + this.logger.debug( + `CodeQL-related task ended: ${e.execution.task.name}`, + ); + this._onDidChange.fire(); + } + }); + if (taskSub && typeof taskSub.dispose === 'function') { + this.push(taskSub as vscode.Disposable); + } + } +} diff --git a/extensions/vscode/src/bridge/storage-paths.ts b/extensions/vscode/src/bridge/storage-paths.ts new file mode 100644 index 00000000..c843831c --- /dev/null +++ b/extensions/vscode/src/bridge/storage-paths.ts @@ -0,0 +1,64 @@ +import * as vscode from 'vscode'; +import { join, dirname } from 'path'; +import { DisposableObject } from '../common/disposable'; + +const VSCODE_CODEQL_EXTENSION_ID = 'GitHub.vscode-codeql'; + +/** + * Resolves the filesystem paths used by the `vscode-codeql` extension + * for storing databases, query results, and other artifacts. + * + * These paths are computed deterministically from VS Code's global storage + * root — no API calls to the `vscode-codeql` extension are made. + * + * VS Code stores extension global data at: + * `/./` + * + * For `vscode-codeql`, this becomes: + * `/GitHub.vscode-codeql/` + */ +export class StoragePaths extends DisposableObject { + private readonly vsCodeGlobalStorageRoot: string; + + constructor(private readonly context: vscode.ExtensionContext) { + super(); + // Our extension's globalStorageUri is something like: + // ...//advanced-security.codeql-development-mcp-server-vscode/ + // The parent directory is the vscode global storage root. + this.vsCodeGlobalStorageRoot = dirname(context.globalStorageUri.fsPath); + } + + /** Global storage directory for the vscode-codeql extension. */ + getCodeqlGlobalStoragePath(): string { + return join(this.vsCodeGlobalStorageRoot, VSCODE_CODEQL_EXTENSION_ID); + } + + /** + * Directory where vscode-codeql stores downloaded/managed databases. + * Databases are stored directly under the global storage path. + */ + getDatabaseStoragePath(): string { + return this.getCodeqlGlobalStoragePath(); + } + + /** + * Directory where vscode-codeql stores query results. + * Path: `/queries/-/` + */ + getQueryStoragePath(): string { + return join(this.getCodeqlGlobalStoragePath(), 'queries'); + } + + /** + * Directory where vscode-codeql stores variant analysis results. + * Path: `/variant-analyses//` + */ + getVariantAnalysisStoragePath(): string { + return join(this.getCodeqlGlobalStoragePath(), 'variant-analyses'); + } + + /** The VS Code global storage root (parent of all extension storage dirs). */ + getGlobalStorageRoot(): string { + return this.vsCodeGlobalStorageRoot; + } +} diff --git a/extensions/vscode/src/codeql/cli-resolver.ts b/extensions/vscode/src/codeql/cli-resolver.ts new file mode 100644 index 00000000..41639d29 --- /dev/null +++ b/extensions/vscode/src/codeql/cli-resolver.ts @@ -0,0 +1,118 @@ +import { execFile } from 'child_process'; +import { access } from 'fs/promises'; +import { constants } from 'fs'; +import { DisposableObject } from '../common/disposable'; +import type { Logger } from '../common/logger'; + +/** Known filesystem locations where the CodeQL CLI may be installed. */ +const KNOWN_LOCATIONS = [ + '/usr/local/bin/codeql', + '/opt/homebrew/bin/codeql', + `${process.env.HOME}/.codeql/codeql`, + `${process.env.HOME}/codeql/codeql`, +]; + +/** + * Resolves the absolute path to the CodeQL CLI binary. + * + * Detection strategy (in order): + * 1. `CODEQL_PATH` environment variable + * 2. `codeql` on `$PATH` (via `which`) + * 3. Known filesystem locations + * + * Results are cached. Call `invalidateCache()` when the environment changes + * (e.g. `extensions.onDidChange` fires). + */ +export class CliResolver extends DisposableObject { + private cachedPath: string | undefined | null = null; // null = not yet resolved + + constructor(private readonly logger: Logger) { + super(); + } + + /** Resolve the CodeQL CLI path. Returns `undefined` if not found. */ + async resolve(): Promise { + if (this.cachedPath !== null) { + return this.cachedPath; + } + + this.logger.debug('Resolving CodeQL CLI path...'); + + // Strategy 1: CODEQL_PATH env var + const envPath = process.env.CODEQL_PATH; + if (envPath) { + const validated = await this.validateBinary(envPath); + if (validated) { + this.logger.info(`CodeQL CLI found via CODEQL_PATH: ${envPath}`); + this.cachedPath = envPath; + return envPath; + } + this.logger.warn(`CODEQL_PATH is set to '${envPath}' but it is not a valid CodeQL binary.`); + } + + // Strategy 2: which/command -v + const whichPath = await this.resolveFromPath(); + if (whichPath) { + this.logger.info(`CodeQL CLI found on PATH: ${whichPath}`); + this.cachedPath = whichPath; + return whichPath; + } + + // Strategy 3: known filesystem locations + for (const location of KNOWN_LOCATIONS) { + const validated = await this.validateBinary(location); + if (validated) { + this.logger.info(`CodeQL CLI found at known location: ${location}`); + this.cachedPath = location; + return location; + } + } + + this.logger.warn('CodeQL CLI not found. Install it or set CODEQL_PATH.'); + this.cachedPath = undefined; + return undefined; + } + + /** Clear the cached path so the next `resolve()` re-probes. */ + invalidateCache(): void { + this.cachedPath = null; + } + + /** Check if a path exists and responds to `--version`. */ + private async validateBinary(binaryPath: string): Promise { + try { + await access(binaryPath, constants.X_OK); + await this.getVersion(binaryPath); + return true; + } catch { + return false; + } + } + + /** Attempt to find `codeql` on PATH. */ + private resolveFromPath(): Promise { + return new Promise((resolve) => { + const cmd = process.platform === 'win32' ? 'where' : 'which'; + execFile(cmd, ['codeql'], (err, stdout) => { + if (err || !stdout.trim()) { + resolve(undefined); + return; + } + resolve(stdout.trim().split('\n')[0]); + }); + }); + } + + /** Run `codeql --version` to validate the binary. */ + private getVersion(binaryPath: string): Promise { + return new Promise((resolve, reject) => { + execFile(binaryPath, ['--version'], (err, stdout) => { + if (err) { + reject(err); + return; + } + resolve(stdout.trim()); + }); + }); + } +} diff --git a/extensions/vscode/src/common/disposable.ts b/extensions/vscode/src/common/disposable.ts new file mode 100644 index 00000000..d3df49e0 --- /dev/null +++ b/extensions/vscode/src/common/disposable.ts @@ -0,0 +1,22 @@ +import * as vscode from 'vscode'; + +/** + * Base class for objects that manage a set of VS Code Disposable resources. + * Subclasses call `this.push(disposable)` to register resources; calling + * `dispose()` tears them all down. + */ +export class DisposableObject implements vscode.Disposable { + private readonly _disposables: vscode.Disposable[] = []; + + protected push(disposable: T): T { + this._disposables.push(disposable); + return disposable; + } + + dispose(): void { + for (const d of this._disposables.reverse()) { + d.dispose(); + } + this._disposables.length = 0; + } +} diff --git a/extensions/vscode/src/common/logger.ts b/extensions/vscode/src/common/logger.ts new file mode 100644 index 00000000..7157c61f --- /dev/null +++ b/extensions/vscode/src/common/logger.ts @@ -0,0 +1,43 @@ +import * as vscode from 'vscode'; + +/** + * Thin wrapper around VS Code's LogOutputChannel. + * Provides structured logging for the extension. + */ +export class Logger implements vscode.Disposable { + private readonly channel: vscode.LogOutputChannel | undefined; + + constructor(name = 'CodeQL MCP') { + // createOutputChannel with { log: true } returns a LogOutputChannel. + // Wrap in try-catch for resilience in test environments. + try { + this.channel = vscode.window.createOutputChannel(name, { log: true }) as vscode.LogOutputChannel; + } catch { + // May fail in test environments + } + } + + info(message: string): void { + this.channel?.info(message); + } + + warn(message: string): void { + this.channel?.warn(message); + } + + error(message: string): void { + this.channel?.error(message); + } + + debug(message: string): void { + this.channel?.debug(message); + } + + show(): void { + this.channel?.show(); + } + + dispose(): void { + this.channel?.dispose(); + } +} diff --git a/extensions/vscode/src/extension.ts b/extensions/vscode/src/extension.ts new file mode 100644 index 00000000..bf1b7804 --- /dev/null +++ b/extensions/vscode/src/extension.ts @@ -0,0 +1,202 @@ +import * as vscode from 'vscode'; +import { Logger } from './common/logger'; +import { CliResolver } from './codeql/cli-resolver'; +import { ServerManager } from './server/server-manager'; +import { PackInstaller } from './server/pack-installer'; +import { McpProvider } from './server/mcp-provider'; +import { StoragePaths } from './bridge/storage-paths'; +import { DatabaseWatcher } from './bridge/database-watcher'; +import { QueryResultsWatcher } from './bridge/query-results-watcher'; +import { EnvironmentBuilder } from './bridge/environment-builder'; + +/** API surface returned from activate() for testing and interop. */ +export interface ExtensionApi { + readonly mcpProvider: McpProvider; +} + +const disposables: vscode.Disposable[] = []; + +export async function activate( + context: vscode.ExtensionContext, +): Promise { + const logger = new Logger(); + disposables.push(logger); + logger.info('CodeQL Development MCP Server extension activating...'); + + // --- Core components --- + const cliResolver = new CliResolver(logger); + const serverManager = new ServerManager(context, logger); + const packInstaller = new PackInstaller(cliResolver, serverManager, logger); + const storagePaths = new StoragePaths(context); + const envBuilder = new EnvironmentBuilder( + context, + cliResolver, + storagePaths, + logger, + ); + const mcpProvider = new McpProvider(serverManager, envBuilder, logger); + + disposables.push(cliResolver, serverManager, packInstaller, storagePaths, envBuilder, mcpProvider); + + // --- Bridge: filesystem watchers --- + const config = vscode.workspace.getConfiguration('codeql-mcp'); + const watchEnabled = config.get('watchCodeqlExtension', true); + + if (watchEnabled) { + try { + const dbWatcher = new DatabaseWatcher(storagePaths, logger); + const queryWatcher = new QueryResultsWatcher(storagePaths, logger); + disposables.push(dbWatcher, queryWatcher); + + // When databases or query results change, rebuild the environment and + // notify the MCP provider that the server definition has changed. + dbWatcher.onDidChange(() => { + envBuilder.invalidate(); + mcpProvider.fireDidChange(); + }); + queryWatcher.onDidChange(() => { + envBuilder.invalidate(); + mcpProvider.fireDidChange(); + }); + } catch (err) { + logger.warn( + `Failed to initialize file watchers: ${err instanceof Error ? err.message : String(err)}`, + ); + } + } + + // --- VS Code API event subscriptions --- + + // Re-probe CLI when extensions change (e.g. vscode-codeql installed/updated) + context.subscriptions.push( + vscode.extensions.onDidChange(() => { + logger.info('Extensions changed — invalidating CLI resolver cache'); + cliResolver.invalidateCache(); + envBuilder.invalidate(); + mcpProvider.fireDidChange(); + }), + ); + + // Re-compute env when config changes + context.subscriptions.push( + vscode.workspace.onDidChangeConfiguration((e) => { + if (e.affectsConfiguration('codeql-mcp')) { + logger.info('Configuration changed — rebuilding environment'); + envBuilder.invalidate(); + mcpProvider.fireDidChange(); + } + }), + ); + + // Re-scan when workspace folders change + context.subscriptions.push( + vscode.workspace.onDidChangeWorkspaceFolders(() => { + logger.info('Workspace folders changed — refreshing watchers'); + envBuilder.invalidate(); + mcpProvider.fireDidChange(); + }), + ); + + // --- Register MCP server definition provider --- + logger.info('Registering ql-mcp MCP server definition provider...'); + context.subscriptions.push( + vscode.lm.registerMcpServerDefinitionProvider('ql-mcp', mcpProvider), + ); + logger.info( + 'ql-mcp registered. The server will start when Copilot needs it, ' + + 'or start it manually via the MCP servers list.', + ); + + // --- Register commands --- + context.subscriptions.push( + vscode.commands.registerCommand('codeql-mcp.reinstallServer', async () => { + logger.info('Reinstalling MCP server (user command)...'); + logger.show(); + await vscode.window.withProgress( + { location: vscode.ProgressLocation.Notification, title: 'CodeQL MCP: Reinstalling server...' }, + async () => { + await serverManager.install({ force: true }); + await packInstaller.installAll(); + mcpProvider.fireDidChange(); + }, + ); + vscode.window.showInformationMessage('CodeQL MCP Server reinstalled successfully.'); + }), + vscode.commands.registerCommand('codeql-mcp.reinstallPacks', async () => { + logger.info('Reinstalling CodeQL tool query packs (user command)...'); + logger.show(); + await vscode.window.withProgress( + { location: vscode.ProgressLocation.Notification, title: 'CodeQL MCP: Installing query packs...' }, + async () => { + await packInstaller.installAll({ force: true }); + mcpProvider.fireDidChange(); + }, + ); + vscode.window.showInformationMessage('CodeQL tool query packs reinstalled successfully.'); + }), + vscode.commands.registerCommand('codeql-mcp.showStatus', async () => { + const cliPath = await cliResolver.resolve(); + const version = await serverManager.getInstalledVersion(); + const lines = [ + `Launch: ${serverManager.getDescription()}`, + `Local install: ${version ?? 'not yet installed'}`, + `CodeQL CLI: ${cliPath ?? 'not found'}`, + `vscode-codeql storage: ${storagePaths.getCodeqlGlobalStoragePath()}`, + `Query results: ${storagePaths.getQueryStoragePath()}`, + ]; + logger.info('--- Status ---'); + for (const line of lines) { + logger.info(line); + } + logger.show(); + vscode.window.showInformationMessage(lines.join(' | ')); + }), + vscode.commands.registerCommand('codeql-mcp.showLogs', () => { + logger.show(); + }), + ); + + // --- Auto-install on activation --- + const autoInstall = config.get('autoInstall', true); + if (autoInstall) { + logger.info('Auto-install enabled — starting background setup...'); + logger.info(`Install directory: ${serverManager.getInstallDir?.() ?? 'unknown'}`); + logger.info(`Server launch: ${serverManager.getDescription?.() ?? 'unknown'}`); + // Run in background — don't block activation + void (async () => { + try { + const freshInstall = await serverManager.ensureInstalled(); + if (freshInstall) { + logger.info('Fresh npm install completed — running CodeQL pack setup...'); + } else { + logger.info('npm package already present — checking CodeQL packs...'); + } + await packInstaller.installAll(); + mcpProvider.fireDidChange(); + logger.info('✅ MCP server setup complete. Server is ready to be started.'); + } catch (err) { + const msg = err instanceof Error ? err.message : String(err); + logger.error(`❌ Auto-install failed: ${msg}`); + vscode.window.showErrorMessage( + `CodeQL MCP setup failed: ${msg}. See "CodeQL MCP" output channel.`, + ); + } + })(); + } else { + logger.info('Auto-install disabled via codeql-mcp.autoInstall setting.'); + } + + logger.info('CodeQL Development MCP Server extension activated.'); + return { mcpProvider }; +} + +export function deactivate(): void { + for (const d of disposables) { + try { + d.dispose(); + } catch { + // Best-effort cleanup + } + } + disposables.length = 0; +} diff --git a/extensions/vscode/src/server/mcp-provider.ts b/extensions/vscode/src/server/mcp-provider.ts new file mode 100644 index 00000000..1f7d1007 --- /dev/null +++ b/extensions/vscode/src/server/mcp-provider.ts @@ -0,0 +1,68 @@ +import * as vscode from 'vscode'; +import { DisposableObject } from '../common/disposable'; +import type { Logger } from '../common/logger'; +import type { ServerManager } from './server-manager'; +import type { EnvironmentBuilder } from '../bridge/environment-builder'; + +/** + * Implements `McpServerDefinitionProvider` to programmatically register + * the `codeql-development-mcp-server` as an MCP server in VS Code. + * + * The server is launched via `npx -y codeql-development-mcp-server` by default, + * using the **published** npm package — not any local development build. + * Override via `codeql-mcp.serverCommand` / `codeql-mcp.serverArgs` settings. + */ +export class McpProvider + extends DisposableObject + implements vscode.McpServerDefinitionProvider +{ + private readonly _onDidChange = new vscode.EventEmitter(); + readonly onDidChangeMcpServerDefinitions = this._onDidChange.event; + + constructor( + private readonly serverManager: ServerManager, + private readonly envBuilder: EnvironmentBuilder, + private readonly logger: Logger, + ) { + super(); + this.push(this._onDidChange); + } + + /** Notify VS Code that the MCP server definitions have changed. */ + fireDidChange(): void { + this._onDidChange.fire(); + } + + async provideMcpServerDefinitions( + _token: vscode.CancellationToken, + ): Promise { + const command = this.serverManager.getCommand(); + const args = this.serverManager.getArgs(); + const env = await this.envBuilder.build(); + const version = this.serverManager.getVersion(); + + this.logger.info( + `Providing MCP server definition: ${command} ${args.join(' ')}`, + ); + + const definition = new vscode.McpStdioServerDefinition( + 'ql-mcp', + command, + args, + env, + version, + ); + + return [definition]; + } + + async resolveMcpServerDefinition( + server: vscode.McpStdioServerDefinition, + _token: vscode.CancellationToken, + ): Promise { + // Refresh environment in case it changed since provideMcpServerDefinitions + const env = await this.envBuilder.build(); + server.env = env; + return server; + } +} diff --git a/extensions/vscode/src/server/pack-installer.ts b/extensions/vscode/src/server/pack-installer.ts new file mode 100644 index 00000000..37445a9f --- /dev/null +++ b/extensions/vscode/src/server/pack-installer.ts @@ -0,0 +1,121 @@ +import { execFile } from 'child_process'; +import { access } from 'fs/promises'; +import { constants } from 'fs'; +import { join } from 'path'; +import { DisposableObject } from '../common/disposable'; +import type { Logger } from '../common/logger'; +import type { CliResolver } from '../codeql/cli-resolver'; +import type { ServerManager } from './server-manager'; + +export interface PackInstallOptions { + /** Force reinstall even if lock files exist. */ + force?: boolean; + /** Install only for specific languages. */ + languages?: string[]; +} + +/** + * Installs CodeQL pack dependencies for the bundled tool query packs + * shipped with the `codeql-development-mcp-server` npm package. + * + * The npm package bundles the qlpack source files (`.ql` + lock files), + * but their CodeQL library dependencies (e.g. `codeql/javascript-all`) + * must be fetched from GHCR via `codeql pack install`. This class + * automates the `codeql-development-mcp-server-setup-packs` step + * documented in the getting-started guide. + */ +export class PackInstaller extends DisposableObject { + static readonly SUPPORTED_LANGUAGES = [ + 'actions', + 'cpp', + 'csharp', + 'go', + 'java', + 'javascript', + 'python', + 'ruby', + 'swift', + ] as const; + + constructor( + private readonly cliResolver: CliResolver, + private readonly serverManager: ServerManager, + private readonly logger: Logger, + ) { + super(); + } + + /** + * Get the qlpack source directories for all languages under the + * locally installed npm package. + */ + getQlpackPaths(): string[] { + const packageRoot = this.serverManager.getPackageRoot(); + return PackInstaller.SUPPORTED_LANGUAGES.map((lang) => + join(packageRoot, 'ql', lang, 'tools', 'src'), + ); + } + + /** + * Install CodeQL pack dependencies for all (or specified) languages. + * Requires the npm package to be installed locally first (via ServerManager). + */ + async installAll(options?: PackInstallOptions): Promise { + const codeqlPath = await this.cliResolver.resolve(); + if (!codeqlPath) { + this.logger.warn( + 'CodeQL CLI not found — skipping pack installation. Install the CLI or set CODEQL_PATH.', + ); + return; + } + + const packageRoot = this.serverManager.getPackageRoot(); + const languages = + options?.languages ?? [...PackInstaller.SUPPORTED_LANGUAGES]; + + for (const lang of languages) { + const packDir = join(packageRoot, 'ql', lang, 'tools', 'src'); + + // Check if the pack directory exists + try { + await access(packDir, constants.R_OK); + } catch { + this.logger.debug(`Pack directory not found, skipping: ${packDir}`); + continue; + } + + this.logger.info(`Installing CodeQL pack dependencies for ${lang}...`); + try { + await this.runCodeqlPackInstall(codeqlPath, packDir); + this.logger.info(`Pack dependencies installed for ${lang}.`); + } catch (err) { + this.logger.error( + `Failed to install pack dependencies for ${lang}: ${err instanceof Error ? err.message : String(err)}`, + ); + } + } + } + + /** Run `codeql pack install` for a single pack directory. */ + private runCodeqlPackInstall( + codeqlPath: string, + packDir: string, + ): Promise { + return new Promise((resolve, reject) => { + execFile( + codeqlPath, + ['pack', 'install', '--no-strict-mode', packDir], + { timeout: 300_000 }, + (err, _stdout, stderr) => { + if (err) { + reject( + new Error(`codeql pack install failed: ${stderr || err.message}`), + ); + return; + } + resolve(); + }, + ); + }); + } +} diff --git a/extensions/vscode/src/server/server-manager.ts b/extensions/vscode/src/server/server-manager.ts new file mode 100644 index 00000000..69db37c4 --- /dev/null +++ b/extensions/vscode/src/server/server-manager.ts @@ -0,0 +1,185 @@ +import * as vscode from 'vscode'; +import { execFile } from 'child_process'; +import { access, readFile, mkdir } from 'fs/promises'; +import { constants } from 'fs'; +import { join } from 'path'; +import { DisposableObject } from '../common/disposable'; +import type { Logger } from '../common/logger'; + +const NPM_PACKAGE_NAME = 'codeql-development-mcp-server'; +const SERVER_SUBDIR = 'mcp-server'; + +export interface InstallOptions { + /** Force reinstall even if already installed. */ + force?: boolean; + /** Specific version to install. Defaults to 'latest'. */ + version?: string; +} + +/** + * Manages the local npm installation of `codeql-development-mcp-server` + * into the extension's global storage directory. + * + * The local install serves two purposes: + * 1. Provides the qlpack source files so PackInstaller can run + * `codeql pack install` to fetch their CodeQL library dependencies. + * 2. Provides a fallback entry point if npx is not available. + * + * The MCP server itself is launched via `npx -y codeql-development-mcp-server` + * (the published npm package) — NOT the local install. This keeps a clean + * separation between the extension and the MCP server code. + * + * To test with a local development build of the MCP server instead, + * set `codeql-mcp.serverCommand` and `codeql-mcp.serverArgs` in settings. + */ +export class ServerManager extends DisposableObject { + private readonly storageRoot: string; + + constructor( + private readonly context: vscode.ExtensionContext, + private readonly logger: Logger, + ) { + super(); + this.storageRoot = context.globalStorageUri.fsPath; + } + + // --------------------------------------------------------------------------- + // Local npm install (for qlpack access) + // --------------------------------------------------------------------------- + + /** Directory where the npm package is installed locally. */ + getInstallDir(): string { + return join(this.storageRoot, SERVER_SUBDIR); + } + + /** Root of the installed npm package (contains ql/, dist/, etc.). */ + getPackageRoot(): string { + return join(this.getInstallDir(), 'node_modules', NPM_PACKAGE_NAME); + } + + /** Check if the npm package is installed locally. */ + async isInstalled(): Promise { + try { + await access( + join(this.getPackageRoot(), 'package.json'), + constants.R_OK, + ); + return true; + } catch { + return false; + } + } + + /** Get the locally installed version, or undefined. */ + async getInstalledVersion(): Promise { + try { + const content = await readFile( + join(this.getPackageRoot(), 'package.json'), + 'utf-8', + ); + const pkg = JSON.parse(content) as { version?: string }; + return pkg.version; + } catch { + return undefined; + } + } + + /** + * Ensure the npm package is installed locally. + * Returns `true` if a fresh install was performed. + */ + async ensureInstalled(): Promise { + const config = vscode.workspace.getConfiguration('codeql-mcp'); + const targetVersion = config.get('serverVersion', 'latest'); + + if (await this.isInstalled()) { + const current = await this.getInstalledVersion(); + if (targetVersion === 'latest' || current === targetVersion) { + this.logger.info(`MCP server package already installed (v${current}).`); + return false; + } + } + + await this.install({ version: targetVersion }); + return true; + } + + /** Install (or reinstall) the npm package locally. */ + async install(options?: InstallOptions): Promise { + const version = options?.version ?? 'latest'; + const installDir = this.getInstallDir(); + const pkgSpec = + version === 'latest' + ? NPM_PACKAGE_NAME + : `${NPM_PACKAGE_NAME}@${version}`; + + this.logger.info(`Installing ${pkgSpec} into ${installDir}...`); + await mkdir(installDir, { recursive: true }); + await this.runNpm(['install', '--prefix', installDir, pkgSpec]); + this.logger.info(`Successfully installed ${pkgSpec}.`); + } + + // --------------------------------------------------------------------------- + // Server launch configuration (for McpProvider) + // --------------------------------------------------------------------------- + + /** + * Get the command used to launch the MCP server process. + * Defaults to `"npx"`. Override via `codeql-mcp.serverCommand` setting + * to use a local development build instead. + */ + getCommand(): string { + const config = vscode.workspace.getConfiguration('codeql-mcp'); + return config.get('serverCommand', 'npx'); + } + + /** + * Get the arguments for the MCP server launch command. + * Defaults to `["-y", "codeql-development-mcp-server"]` (or with + * `@` if `codeql-mcp.serverVersion` is pinned). + * Override via `codeql-mcp.serverArgs` for local development. + */ + getArgs(): string[] { + const config = vscode.workspace.getConfiguration('codeql-mcp'); + const customArgs = config.get('serverArgs'); + if (customArgs && customArgs.length > 0) { + return customArgs; + } + const version = config.get('serverVersion', 'latest'); + const pkg = + version === 'latest' + ? NPM_PACKAGE_NAME + : `${NPM_PACKAGE_NAME}@${version}`; + return ['-y', pkg]; + } + + /** Human-readable description of the current server launch config. */ + getDescription(): string { + return `${this.getCommand()} ${this.getArgs().join(' ')}`; + } + + /** Version string for the MCP definition, or undefined if using latest. */ + getVersion(): string | undefined { + const config = vscode.workspace.getConfiguration('codeql-mcp'); + const v = config.get('serverVersion', 'latest'); + return v === 'latest' ? undefined : v; + } + + // --------------------------------------------------------------------------- + // Internal helpers + // --------------------------------------------------------------------------- + + private runNpm(args: string[]): Promise { + return new Promise((resolve, reject) => { + const npmCmd = process.platform === 'win32' ? 'npm.cmd' : 'npm'; + execFile(npmCmd, args, { timeout: 120_000 }, (err, stdout, stderr) => { + if (err) { + this.logger.error(`npm ${args[0]} failed: ${stderr || err.message}`); + reject(new Error(`npm ${args[0]} failed: ${stderr || err.message}`)); + return; + } + resolve(stdout); + }); + }); + } +} diff --git a/extensions/vscode/test/bridge/database-watcher.test.ts b/extensions/vscode/test/bridge/database-watcher.test.ts new file mode 100644 index 00000000..c80e99f2 --- /dev/null +++ b/extensions/vscode/test/bridge/database-watcher.test.ts @@ -0,0 +1,119 @@ +import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest'; +import { DatabaseWatcher } from '../../src/bridge/database-watcher'; +import { workspace } from 'vscode'; + +/** Captures callbacks registered on a mock FileSystemWatcher. */ +function installCapturingWatcher() { + const captured: Record = {}; + const original = workspace.createFileSystemWatcher; + workspace.createFileSystemWatcher = (() => ({ + onDidCreate: (cb: Function) => { captured.create = cb; return { dispose: () => {} }; }, + onDidChange: (cb: Function) => { captured.change = cb; return { dispose: () => {} }; }, + onDidDelete: (cb: Function) => { captured.delete = cb; return { dispose: () => {} }; }, + dispose: () => {}, + })) as any; + return { captured, restore: () => { workspace.createFileSystemWatcher = original; } }; +} + +function createMockStoragePaths() { + return { + getCodeqlGlobalStoragePath: () => '/mock/global-storage/GitHub.vscode-codeql', + getDatabaseStoragePath: () => '/mock/global-storage/GitHub.vscode-codeql', + getQueryStoragePath: () => '/mock/global-storage/GitHub.vscode-codeql/queries', + getVariantAnalysisStoragePath: () => '/mock/global-storage/GitHub.vscode-codeql/variant-analyses', + getGlobalStorageRoot: () => '/mock/global-storage', + dispose: () => {}, + push: () => {}, + } as any; +} + +function createMockLogger() { + return { info: vi.fn(), warn: vi.fn(), error: vi.fn(), debug: vi.fn(), show: () => {}, dispose: () => {} } as any; +} + +describe('DatabaseWatcher', () => { + let watcher: DatabaseWatcher; + let captured: Record; + let restoreWatcher: () => void; + + beforeEach(() => { + const cap = installCapturingWatcher(); + captured = cap.captured; + restoreWatcher = cap.restore; + watcher = new DatabaseWatcher(createMockStoragePaths(), createMockLogger()); + }); + + afterEach(() => { + watcher.dispose(); + restoreWatcher(); + }); + + it('should be instantiable', () => { + expect(watcher).toBeDefined(); + }); + + it('should expose onDidChange event', () => { + expect(watcher.onDidChange).toBeDefined(); + }); + + it('should track discovered databases', () => { + expect(watcher.getKnownDatabases().size).toBe(0); + }); + + it('should add database when codeql-database.yml is created', () => { + const listener = vi.fn(); + watcher.onDidChange(listener); + + // Simulate file watcher firing + captured.create?.({ fsPath: '/workspace/my-db/codeql-database.yml' }); + + expect(watcher.getKnownDatabases().has('/workspace/my-db')).toBe(true); + expect(listener).toHaveBeenCalledTimes(1); + }); + + it('should not duplicate databases on repeated creation events', () => { + const listener = vi.fn(); + watcher.onDidChange(listener); + + captured.create?.({ fsPath: '/workspace/my-db/codeql-database.yml' }); + captured.create?.({ fsPath: '/workspace/my-db/codeql-database.yml' }); + + expect(watcher.getKnownDatabases().size).toBe(1); + expect(listener).toHaveBeenCalledTimes(1); // Only fires once + }); + + it('should remove database when codeql-database.yml is deleted', () => { + const listener = vi.fn(); + watcher.onDidChange(listener); + + captured.create?.({ fsPath: '/workspace/my-db/codeql-database.yml' }); + expect(watcher.getKnownDatabases().size).toBe(1); + + captured.delete?.({ fsPath: '/workspace/my-db/codeql-database.yml' }); + expect(watcher.getKnownDatabases().size).toBe(0); + expect(listener).toHaveBeenCalledTimes(2); // once for add, once for remove + }); + + it('should ignore delete for unknown databases', () => { + const listener = vi.fn(); + watcher.onDidChange(listener); + + captured.delete?.({ fsPath: '/workspace/unknown/codeql-database.yml' }); + + expect(listener).not.toHaveBeenCalled(); + }); + + it('should track multiple databases', () => { + captured.create?.({ fsPath: '/workspace/db1/codeql-database.yml' }); + captured.create?.({ fsPath: '/workspace/db2/codeql-database.yml' }); + + const known = watcher.getKnownDatabases(); + expect(known.size).toBe(2); + expect(known.has('/workspace/db1')).toBe(true); + expect(known.has('/workspace/db2')).toBe(true); + }); + + it('should be disposable', () => { + expect(() => watcher.dispose()).not.toThrow(); + }); +}); diff --git a/extensions/vscode/test/bridge/environment-builder.test.ts b/extensions/vscode/test/bridge/environment-builder.test.ts new file mode 100644 index 00000000..7c9342fd --- /dev/null +++ b/extensions/vscode/test/bridge/environment-builder.test.ts @@ -0,0 +1,127 @@ +import { describe, it, expect, vi, beforeEach } from 'vitest'; + + +import { EnvironmentBuilder } from '../../src/bridge/environment-builder'; + +function createMockContext() { + return { + globalStorageUri: { fsPath: '/mock/global-storage/codeql-mcp' }, + storageUri: { fsPath: '/mock/workspace-storage/codeql-mcp' }, + } as any; +} + +function createMockCliResolver() { + return { + resolve: vi.fn().mockResolvedValue('/usr/local/bin/codeql'), + invalidateCache: vi.fn(), + dispose: vi.fn(), + push: vi.fn(), + } as any; +} + +function createMockStoragePaths() { + return { + getCodeqlGlobalStoragePath: vi.fn().mockReturnValue('/mock/global-storage/GitHub.vscode-codeql'), + getDatabaseStoragePath: vi.fn().mockReturnValue('/mock/global-storage/GitHub.vscode-codeql'), + getQueryStoragePath: vi.fn().mockReturnValue('/mock/global-storage/GitHub.vscode-codeql/queries'), + getVariantAnalysisStoragePath: vi.fn().mockReturnValue('/mock/global-storage/GitHub.vscode-codeql/variant-analyses'), + getGlobalStorageRoot: vi.fn().mockReturnValue('/mock/global-storage'), + dispose: vi.fn(), + push: vi.fn(), + } as any; +} + +function createMockLogger() { + return { + info: vi.fn(), + warn: vi.fn(), + error: vi.fn(), + debug: vi.fn(), + show: vi.fn(), + dispose: vi.fn(), + } as any; +} + +describe('EnvironmentBuilder', () => { + let builder: EnvironmentBuilder; + let cliResolver: any; + + beforeEach(() => { + vi.resetAllMocks(); + cliResolver = createMockCliResolver(); + builder = new EnvironmentBuilder( + createMockContext(), + cliResolver, + createMockStoragePaths(), + createMockLogger(), + ); + }); + + it('should be instantiable', () => { + expect(builder).toBeDefined(); + }); + + it('should build environment with CODEQL_PATH', async () => { + const env = await builder.build(); + expect(env.CODEQL_PATH).toBe('/usr/local/bin/codeql'); + }); + + it('should build environment with TRANSPORT_MODE=stdio', async () => { + const env = await builder.build(); + expect(env.TRANSPORT_MODE).toBe('stdio'); + }); + + it('should include CODEQL_MCP_TMP_DIR under global storage', async () => { + const env = await builder.build(); + expect(env.CODEQL_MCP_TMP_DIR).toBe('/mock/global-storage/codeql-mcp/tmp'); + }); + + it('should include CODEQL_ADDITIONAL_PACKS with database storage path', async () => { + const env = await builder.build(); + expect(env.CODEQL_ADDITIONAL_PACKS).toBeDefined(); + expect(env.CODEQL_ADDITIONAL_PACKS).toContain('GitHub.vscode-codeql'); + }); + + it('should omit CODEQL_PATH when CLI is not found', async () => { + cliResolver.resolve.mockResolvedValue(undefined); + builder.invalidate(); + const env = await builder.build(); + expect(env.CODEQL_PATH).toBeUndefined(); + }); + + it('should include additional env from user settings', async () => { + const vscode = await import('vscode'); + const originalGetConfig = vscode.workspace.getConfiguration; + vscode.workspace.getConfiguration = () => ({ + get: (_key: string, defaultVal?: any) => { + if (_key === 'additionalEnv') return { CUSTOM_VAR: 'custom_value' }; + return defaultVal; + }, + has: () => false, + inspect: () => undefined as any, + update: () => Promise.resolve(), + }) as any; + + builder.invalidate(); // Clear cache so it re-reads config + const env = await builder.build(); + expect(env.CUSTOM_VAR).toBe('custom_value'); + + // Restore + vscode.workspace.getConfiguration = originalGetConfig; + }); + + it('should cache environment and honor invalidation', async () => { + const _env1 = await builder.build(); + const _env2 = await builder.build(); + // Should use cached result (resolve only called once) + expect(cliResolver.resolve).toHaveBeenCalledTimes(1); + + builder.invalidate(); + await builder.build(); + expect(cliResolver.resolve).toHaveBeenCalledTimes(2); + }); + + it('should be disposable', () => { + expect(() => builder.dispose()).not.toThrow(); + }); +}); diff --git a/extensions/vscode/test/bridge/query-results-watcher.test.ts b/extensions/vscode/test/bridge/query-results-watcher.test.ts new file mode 100644 index 00000000..678d59f0 --- /dev/null +++ b/extensions/vscode/test/bridge/query-results-watcher.test.ts @@ -0,0 +1,126 @@ +import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest'; +import { QueryResultsWatcher } from '../../src/bridge/query-results-watcher'; +import { workspace, tasks } from 'vscode'; + +function installCapturingWatchers() { + const captured: Record = {}; + const origFsw = workspace.createFileSystemWatcher; + let watcherIndex = 0; + workspace.createFileSystemWatcher = ((_pattern: string) => { + const prefix = watcherIndex === 0 ? 'bqrs' : 'sarif'; + watcherIndex++; + return { + onDidCreate: (cb: Function) => { captured[`${prefix}_create`] = cb; return { dispose: () => {} }; }, + onDidChange: (cb: Function) => { captured[`${prefix}_change`] = cb; return { dispose: () => {} }; }, + onDidDelete: (cb: Function) => { captured[`${prefix}_delete`] = cb; return { dispose: () => {} }; }, + dispose: () => {}, + }; + }) as any; + + let taskCallback: Function | undefined; + const origTask = tasks.onDidEndTask; + tasks.onDidEndTask = ((cb: Function) => { taskCallback = cb; return { dispose: () => {} }; }) as any; + + return { + captured, + fireTask: (name: string) => taskCallback?.({ execution: { task: { name } } }), + restore: () => { workspace.createFileSystemWatcher = origFsw; tasks.onDidEndTask = origTask; }, + }; +} + +function createMockStoragePaths() { + return { + getCodeqlGlobalStoragePath: () => '/mock/global-storage/GitHub.vscode-codeql', + getDatabaseStoragePath: () => '/mock/global-storage/GitHub.vscode-codeql', + getQueryStoragePath: () => '/mock/global-storage/GitHub.vscode-codeql/queries', + getVariantAnalysisStoragePath: () => '/mock/global-storage/GitHub.vscode-codeql/variant-analyses', + getGlobalStorageRoot: () => '/mock/global-storage', + dispose: () => {}, + push: () => {}, + } as any; +} + +function createMockLogger() { + return { info: vi.fn(), warn: vi.fn(), error: vi.fn(), debug: vi.fn(), show: () => {}, dispose: () => {} } as any; +} + +describe('QueryResultsWatcher', () => { + let watcher: QueryResultsWatcher; + let captured: Record; + let fireTask: (name: string) => void; + let restore: () => void; + let logger: any; + + beforeEach(() => { + logger = createMockLogger(); + const cap = installCapturingWatchers(); + captured = cap.captured; + fireTask = cap.fireTask; + restore = cap.restore; + watcher = new QueryResultsWatcher(createMockStoragePaths(), logger); + }); + + afterEach(() => { + watcher.dispose(); + restore(); + }); + + it('should be instantiable', () => { + expect(watcher).toBeDefined(); + }); + + it('should expose onDidChange event', () => { + expect(watcher.onDidChange).toBeDefined(); + }); + + it('should fire change event when BQRS file is created', () => { + const listener = vi.fn(); + watcher.onDidChange(listener); + + captured.bqrs_create?.({ fsPath: '/results/query.bqrs' }); + + expect(listener).toHaveBeenCalledTimes(1); + expect(logger.info).toHaveBeenCalledWith(expect.stringContaining('BQRS')); + }); + + it('should fire change event when SARIF file is created', () => { + const listener = vi.fn(); + watcher.onDidChange(listener); + + captured.sarif_create?.({ fsPath: '/results/query-interpreted.sarif' }); + + expect(listener).toHaveBeenCalledTimes(1); + expect(logger.info).toHaveBeenCalledWith(expect.stringContaining('SARIF')); + }); + + it('should fire change event when a CodeQL-related task ends', () => { + const listener = vi.fn(); + watcher.onDidChange(listener); + + fireTask('Run CodeQL Query'); + + expect(listener).toHaveBeenCalledTimes(1); + }); + + it('should NOT fire for unrelated tasks', () => { + const listener = vi.fn(); + watcher.onDidChange(listener); + + fireTask('npm build'); + + expect(listener).not.toHaveBeenCalled(); + }); + + it('should fire for tasks containing "test"', () => { + const listener = vi.fn(); + watcher.onDidChange(listener); + + fireTask('CodeQL Test Run'); + + expect(listener).toHaveBeenCalledTimes(1); + }); + + it('should be disposable', () => { + expect(() => watcher.dispose()).not.toThrow(); + }); +}); diff --git a/extensions/vscode/test/bridge/storage-paths.test.ts b/extensions/vscode/test/bridge/storage-paths.test.ts new file mode 100644 index 00000000..ed279acc --- /dev/null +++ b/extensions/vscode/test/bridge/storage-paths.test.ts @@ -0,0 +1,50 @@ +import { describe, it, expect, beforeEach } from 'vitest'; + + +import { StoragePaths } from '../../src/bridge/storage-paths'; + +function createMockContext() { + return { + globalStorageUri: { fsPath: '/mock/global-storage/advanced-security.codeql-development-mcp-server-vscode' }, + storageUri: { fsPath: '/mock/workspace-storage/advanced-security.codeql-development-mcp-server-vscode' }, + } as any; +} + +describe('StoragePaths', () => { + let paths: StoragePaths; + let ctx: any; + + beforeEach(() => { + ctx = createMockContext(); + paths = new StoragePaths(ctx); + }); + + it('should be instantiable', () => { + expect(paths).toBeDefined(); + }); + + it('should compute the vscode-codeql global storage path', () => { + const result = paths.getCodeqlGlobalStoragePath(); + // Should be a sibling directory to our extension's global storage + expect(result).toContain('GitHub.vscode-codeql'); + }); + + it('should compute the database storage path', () => { + const result = paths.getDatabaseStoragePath(); + expect(result).toContain('GitHub.vscode-codeql'); + }); + + it('should compute the query results storage path', () => { + const result = paths.getQueryStoragePath(); + expect(result).toContain('queries'); + }); + + it('should compute the variant analysis storage path', () => { + const result = paths.getVariantAnalysisStoragePath(); + expect(result).toContain('variant-analyses'); + }); + + it('should be disposable', () => { + expect(() => paths.dispose()).not.toThrow(); + }); +}); diff --git a/extensions/vscode/test/codeql/cli-resolver.test.ts b/extensions/vscode/test/codeql/cli-resolver.test.ts new file mode 100644 index 00000000..0bea37ee --- /dev/null +++ b/extensions/vscode/test/codeql/cli-resolver.test.ts @@ -0,0 +1,167 @@ +import { describe, it, expect, vi, beforeEach } from 'vitest'; +import { CliResolver } from '../../src/codeql/cli-resolver'; + +// Mock child_process +vi.mock('child_process', () => ({ + execFile: vi.fn(), +})); + +// Mock fs/promises +vi.mock('fs/promises', () => ({ + access: vi.fn(), +})); + +import { execFile } from 'child_process'; +import { access } from 'fs/promises'; + +function createMockLogger() { + return { + info: vi.fn(), + warn: vi.fn(), + error: vi.fn(), + debug: vi.fn(), + show: vi.fn(), + dispose: vi.fn(), + channel: {}, + } as any; +} + +describe('CliResolver', () => { + let resolver: CliResolver; + let logger: any; + + beforeEach(() => { + vi.resetAllMocks(); + logger = createMockLogger(); + resolver = new CliResolver(logger); + }); + + it('should be instantiable', () => { + expect(resolver).toBeDefined(); + }); + + it('should resolve from CODEQL_PATH env var when set', async () => { + const originalEnv = process.env.CODEQL_PATH; + process.env.CODEQL_PATH = '/usr/local/bin/codeql'; + + // Mock access to succeed (file exists) + vi.mocked(access).mockResolvedValueOnce(undefined); + + // Mock execFile to return a version + vi.mocked(execFile).mockImplementationOnce( + (_cmd: any, _args: any, callback: any) => { + callback(null, 'CodeQL command-line toolchain release 2.19.0.\n', ''); + return {} as any; + }, + ); + + const result = await resolver.resolve(); + expect(result).toBe('/usr/local/bin/codeql'); + + process.env.CODEQL_PATH = originalEnv; + }); + + it('should cache resolved path', async () => { + const originalEnv = process.env.CODEQL_PATH; + process.env.CODEQL_PATH = '/cached/codeql'; + + vi.mocked(access).mockResolvedValue(undefined); + vi.mocked(execFile).mockImplementation( + (_cmd: any, _args: any, callback: any) => { + callback(null, 'CodeQL command-line toolchain release 2.19.0.\n', ''); + return {} as any; + }, + ); + + const result1 = await resolver.resolve(); + const result2 = await resolver.resolve(); + + expect(result1).toBe('/cached/codeql'); + expect(result2).toBe('/cached/codeql'); + // access should only be called once due to caching + expect(access).toHaveBeenCalledTimes(1); + + process.env.CODEQL_PATH = originalEnv; + }); + + it('should invalidate cache when instructed', async () => { + const originalEnv = process.env.CODEQL_PATH; + process.env.CODEQL_PATH = '/cached/codeql'; + + vi.mocked(access).mockResolvedValue(undefined); + vi.mocked(execFile).mockImplementation( + (_cmd: any, _args: any, callback: any) => { + callback(null, 'CodeQL command-line toolchain release 2.19.0.\n', ''); + return {} as any; + }, + ); + + await resolver.resolve(); + resolver.invalidateCache(); + await resolver.resolve(); + + // access should be called twice (once before invalidation, once after) + expect(access).toHaveBeenCalledTimes(2); + + process.env.CODEQL_PATH = originalEnv; + }); + + it('should return undefined when no CLI is found', async () => { + const originalEnv = process.env.CODEQL_PATH; + delete process.env.CODEQL_PATH; + + // All access checks fail + vi.mocked(access).mockRejectedValue(new Error('ENOENT')); + + // execFile (which/command -v) also fails + vi.mocked(execFile).mockImplementation( + (_cmd: any, _args: any, callback: any) => { + callback(new Error('not found'), '', ''); + return {} as any; + }, + ); + + const result = await resolver.resolve(); + expect(result).toBeUndefined(); + expect(logger.warn).toHaveBeenCalledWith(expect.stringContaining('not found')); + + process.env.CODEQL_PATH = originalEnv; + }); + + it('should fall back to PATH when CODEQL_PATH is invalid', async () => { + const originalEnv = process.env.CODEQL_PATH; + process.env.CODEQL_PATH = '/nonexistent/codeql'; + + // CODEQL_PATH access fails + vi.mocked(access).mockImplementation((path: any) => { + if (String(path) === '/nonexistent/codeql') return Promise.reject(new Error('ENOENT')); + return Promise.resolve(undefined as any); + }); + + // which/command -v succeeds + let callCount = 0; + vi.mocked(execFile).mockImplementation( + (_cmd: any, _args: any, callback: any) => { + callCount++; + if (callCount === 1) { + // which codeql + callback(null, '/usr/local/bin/codeql\n', ''); + } else { + // codeql --version + callback(null, 'CodeQL CLI 2.19.0\n', ''); + } + return {} as any; + }, + ); + + const result = await resolver.resolve(); + expect(result).toBe('/usr/local/bin/codeql'); + expect(logger.warn).toHaveBeenCalledWith(expect.stringContaining('not a valid')); + + process.env.CODEQL_PATH = originalEnv; + }); + + it('should be disposable', () => { + expect(() => resolver.dispose()).not.toThrow(); + }); +}); diff --git a/extensions/vscode/test/extension.test.ts b/extensions/vscode/test/extension.test.ts new file mode 100644 index 00000000..df89133c --- /dev/null +++ b/extensions/vscode/test/extension.test.ts @@ -0,0 +1,158 @@ +import { describe, it, expect, vi, beforeEach } from 'vitest'; + + +// Mock all modules imported by extension.ts +// Note: Logger is NOT mocked here — it uses the real class which relies +// on the vscode mock from setup.ts for createOutputChannel. + +vi.mock('../src/codeql/cli-resolver', () => ({ + CliResolver: vi.fn().mockImplementation(() => ({ + resolve: vi.fn().mockResolvedValue('/mock/codeql'), + invalidateCache: vi.fn(), + dispose: vi.fn(), + })), +})); + +vi.mock('../src/server/server-manager', () => ({ + ServerManager: vi.fn().mockImplementation(() => ({ + ensureInstalled: vi.fn().mockResolvedValue(false), + install: vi.fn().mockResolvedValue(undefined), + isInstalled: vi.fn().mockResolvedValue(true), + getCommand: vi.fn().mockReturnValue('npx'), + getArgs: vi.fn().mockReturnValue(['-y', 'codeql-development-mcp-server']), + getVersion: vi.fn().mockReturnValue(undefined), + getDescription: vi.fn().mockReturnValue('npx -y codeql-development-mcp-server'), + getInstallDir: vi.fn().mockReturnValue('/mock/install'), + getPackageRoot: vi.fn().mockReturnValue('/mock/install/node_modules/codeql-development-mcp-server'), + getInstalledVersion: vi.fn().mockResolvedValue('2.24.1'), + dispose: vi.fn(), + })), +})); + +vi.mock('../src/server/pack-installer', () => ({ + PackInstaller: vi.fn().mockImplementation(() => ({ + installAll: vi.fn().mockResolvedValue(undefined), + getQlpackPaths: vi.fn().mockReturnValue([]), + dispose: vi.fn(), + })), +})); + +vi.mock('../src/server/mcp-provider', () => ({ + McpProvider: vi.fn().mockImplementation(() => ({ + provideMcpServerDefinitions: vi.fn().mockResolvedValue([]), + resolveMcpServerDefinition: vi.fn().mockResolvedValue(undefined), + onDidChangeMcpServerDefinitions: vi.fn(), + fireDidChange: vi.fn(), + dispose: vi.fn(), + })), +})); + +vi.mock('../src/bridge/storage-paths', () => ({ + StoragePaths: vi.fn().mockImplementation(() => ({ + getCodeqlGlobalStoragePath: vi.fn().mockReturnValue('/mock/codeql-storage'), + getDatabaseStoragePath: vi.fn().mockReturnValue('/mock/codeql-storage'), + getQueryStoragePath: vi.fn().mockReturnValue('/mock/codeql-storage/queries'), + getVariantAnalysisStoragePath: vi.fn().mockReturnValue('/mock/codeql-storage/variant-analyses'), + getGlobalStorageRoot: vi.fn().mockReturnValue('/mock/global-storage'), + dispose: vi.fn(), + })), +})); + +vi.mock('../src/bridge/database-watcher', () => ({ + DatabaseWatcher: vi.fn().mockImplementation(() => { + const listeners: Function[] = []; + return { + onDidChange: (listener: Function) => { listeners.push(listener); return { dispose: () => {} }; }, + getKnownDatabases: vi.fn().mockReturnValue(new Set()), + dispose: vi.fn(), + }; + }), +})); + +vi.mock('../src/bridge/query-results-watcher', () => ({ + QueryResultsWatcher: vi.fn().mockImplementation(() => { + const listeners: Function[] = []; + return { + onDidChange: (listener: Function) => { listeners.push(listener); return { dispose: () => {} }; }, + dispose: vi.fn(), + }; + }), +})); + +vi.mock('../src/bridge/environment-builder', () => ({ + EnvironmentBuilder: vi.fn().mockImplementation(() => ({ + build: vi.fn().mockResolvedValue({ CODEQL_PATH: '/mock/codeql' }), + invalidate: vi.fn(), + dispose: vi.fn(), + })), +})); + +import { activate, deactivate } from '../src/extension'; +import * as vscode from 'vscode'; + +function createMockContext(): vscode.ExtensionContext { + return { + globalStorageUri: { fsPath: '/mock/global-storage' }, + storageUri: { fsPath: '/mock/workspace-storage' }, + globalState: { + get: vi.fn(), + update: vi.fn().mockResolvedValue(undefined), + keys: vi.fn().mockReturnValue([]), + setKeysForSync: vi.fn(), + }, + workspaceState: { + get: vi.fn(), + update: vi.fn().mockResolvedValue(undefined), + keys: vi.fn().mockReturnValue([]), + }, + subscriptions: [], + extensionPath: '/mock/extension', + extensionUri: { fsPath: '/mock/extension' } as any, + extensionMode: 1, + extension: {} as any, + environmentVariableCollection: {} as any, + secrets: {} as any, + logUri: { fsPath: '/mock/log' } as any, + logPath: '/mock/log', + globalStoragePath: '/mock/global-storage', + storagePath: '/mock/workspace-storage', + asAbsolutePath: (p: string) => `/mock/extension/${p}`, + languageModelAccessInformation: {} as any, + } as unknown as vscode.ExtensionContext; +} + +describe('Extension', () => { + let ctx: vscode.ExtensionContext; + + beforeEach(() => { + vi.resetAllMocks(); + ctx = createMockContext(); + }); + + it('should activate and return an API object with mcpProvider', async () => { + const api = await activate(ctx); + expect(api).toBeDefined(); + expect(api.mcpProvider).toBeDefined(); + }); + + it('should register commands during activation', async () => { + await activate(ctx); + // Commands are registered via context.subscriptions + expect(ctx.subscriptions.length).toBeGreaterThan(0); + }); + + it('should register the MCP server definition provider', async () => { + await activate(ctx); + // The MCP provider registration adds to context.subscriptions + expect(ctx.subscriptions.length).toBeGreaterThan(0); + }); + + it('should deactivate without errors', async () => { + await activate(ctx); + expect(() => deactivate()).not.toThrow(); + }); + + it('should deactivate even if activate was never called', () => { + expect(() => deactivate()).not.toThrow(); + }); +}); diff --git a/extensions/vscode/test/helpers/vscode-mock.ts b/extensions/vscode/test/helpers/vscode-mock.ts new file mode 100644 index 00000000..de36d966 --- /dev/null +++ b/extensions/vscode/test/helpers/vscode-mock.ts @@ -0,0 +1,76 @@ +/** + * Shared vscode mock factory for test files. + * + * Usage in test files: + * import { vi } from 'vitest'; + * import { createVscodeMock } from '../helpers/vscode-mock'; + * vi.mock('vscode', () => createVscodeMock()); + * + * This MUST be called via vi.mock() in each test file that imports + * code which depends on the 'vscode' module. + */ + +import { vi } from 'vitest'; + +export function createVscodeMock() { + const createEventEmitter = () => { + const listeners: Array = []; + return { + event: (listener: Function) => { listeners.push(listener); return { dispose: () => {} }; }, + fire: (...args: unknown[]) => { for (const l of listeners) l(...args); }, + dispose: () => { listeners.length = 0; }, + }; + }; + + return { + EventEmitter: vi.fn().mockImplementation(() => createEventEmitter()), + Uri: { + file: (p: string) => ({ fsPath: p, scheme: 'file', path: p }), + joinPath: (b: any, ...s: string[]) => ({ fsPath: [b.fsPath, ...s].join('/'), scheme: 'file', path: [b.path, ...s].join('/') }), + parse: (v: string) => ({ fsPath: v, scheme: 'file', path: v }), + }, + workspace: { + getConfiguration: vi.fn().mockImplementation(() => ({ + get: vi.fn().mockImplementation((_k: string, d?: any) => d), + has: vi.fn().mockReturnValue(false), inspect: vi.fn(), update: vi.fn(), + })), + createFileSystemWatcher: vi.fn().mockImplementation(() => ({ + onDidCreate: vi.fn().mockReturnValue({ dispose: vi.fn() }), + onDidChange: vi.fn().mockReturnValue({ dispose: vi.fn() }), + onDidDelete: vi.fn().mockReturnValue({ dispose: vi.fn() }), + ignoreCreateEvents: false, ignoreChangeEvents: false, + ignoreDeleteEvents: false, dispose: vi.fn(), + })), + workspaceFolders: [], + onDidChangeConfiguration: vi.fn().mockReturnValue({ dispose: vi.fn() }), + onDidChangeWorkspaceFolders: vi.fn().mockReturnValue({ dispose: vi.fn() }), + onDidCreateFiles: vi.fn().mockReturnValue({ dispose: vi.fn() }), + onDidSaveTextDocument: vi.fn().mockReturnValue({ dispose: vi.fn() }), + fs: { stat: vi.fn(), readFile: vi.fn(), readDirectory: vi.fn() }, + }, + window: { + createOutputChannel: vi.fn().mockImplementation(() => ({ + appendLine: vi.fn(), append: vi.fn(), clear: vi.fn(), show: vi.fn(), + hide: vi.fn(), dispose: vi.fn(), info: vi.fn(), warn: vi.fn(), + error: vi.fn(), debug: vi.fn(), trace: vi.fn(), logLevel: 3, + name: 'CodeQL MCP', onDidChangeLogLevel: vi.fn(), + })), + showInformationMessage: vi.fn(), showWarningMessage: vi.fn(), showErrorMessage: vi.fn(), + createStatusBarItem: vi.fn().mockReturnValue({ show: vi.fn(), hide: vi.fn(), dispose: vi.fn(), text: '', tooltip: '', command: undefined }), + onDidChangeActiveTextEditor: vi.fn().mockReturnValue({ dispose: vi.fn() }), + }, + commands: { registerCommand: vi.fn().mockReturnValue({ dispose: vi.fn() }), executeCommand: vi.fn() }, + extensions: { getExtension: vi.fn(), all: [], onDidChange: vi.fn().mockReturnValue({ dispose: vi.fn() }) }, + tasks: { onDidEndTask: vi.fn().mockReturnValue({ dispose: vi.fn() }), onDidEndTaskProcess: vi.fn().mockReturnValue({ dispose: vi.fn() }) }, + languages: { onDidChangeDiagnostics: vi.fn().mockReturnValue({ dispose: vi.fn() }) }, + lm: { registerMcpServerDefinitionProvider: vi.fn().mockReturnValue({ dispose: vi.fn() }) }, + Disposable: { from: vi.fn() }, + StatusBarAlignment: { Left: 1, Right: 2 }, + ConfigurationTarget: { Global: 1, Workspace: 2, WorkspaceFolder: 3 }, + McpStdioServerDefinition: vi.fn().mockImplementation( + (label: string, command: string, args?: string[], env?: Record, version?: string) => ({ + label, command, args: args ?? [], env: env ?? {}, version, + }) + ), + }; +} diff --git a/extensions/vscode/test/server/mcp-provider.test.ts b/extensions/vscode/test/server/mcp-provider.test.ts new file mode 100644 index 00000000..b3bdae45 --- /dev/null +++ b/extensions/vscode/test/server/mcp-provider.test.ts @@ -0,0 +1,128 @@ +import { describe, it, expect, vi, beforeEach } from 'vitest'; + + +import { McpProvider } from '../../src/server/mcp-provider'; + +function createMockServerManager() { + return { + getCommand: vi.fn().mockReturnValue('npx'), + getArgs: vi.fn().mockReturnValue(['-y', 'codeql-development-mcp-server']), + getVersion: vi.fn().mockReturnValue(undefined), + getDescription: vi.fn().mockReturnValue('npx -y codeql-development-mcp-server'), + getInstallDir: vi.fn().mockReturnValue('/mock/install'), + getPackageRoot: vi.fn().mockReturnValue('/mock/install/node_modules/codeql-development-mcp-server'), + isInstalled: vi.fn().mockResolvedValue(true), + getInstalledVersion: vi.fn().mockResolvedValue('2.24.1'), + ensureInstalled: vi.fn().mockResolvedValue(false), + install: vi.fn().mockResolvedValue(undefined), + dispose: vi.fn(), + push: vi.fn(), + } as any; +} + +function createMockEnvBuilder() { + return { + build: vi.fn().mockResolvedValue({ + CODEQL_PATH: '/usr/local/bin/codeql', + CODEQL_MCP_WORKSPACE: '/mock/workspace', + }), + invalidate: vi.fn(), + dispose: vi.fn(), + push: vi.fn(), + } as any; +} + +function createMockLogger() { + return { + info: vi.fn(), + warn: vi.fn(), + error: vi.fn(), + debug: vi.fn(), + show: vi.fn(), + dispose: vi.fn(), + } as any; +} + +describe('McpProvider', () => { + let provider: McpProvider; + let serverManager: any; + let envBuilder: any; + let logger: any; + + beforeEach(() => { + vi.resetAllMocks(); + serverManager = createMockServerManager(); + envBuilder = createMockEnvBuilder(); + logger = createMockLogger(); + provider = new McpProvider(serverManager, envBuilder, logger); + }); + + it('should be instantiable', () => { + expect(provider).toBeDefined(); + }); + + it('should provide server definitions with npx command', async () => { + const token = { isCancellationRequested: false, onCancellationRequested: vi.fn() }; + const definitions = await provider.provideMcpServerDefinitions(token as any); + + expect(definitions).toBeDefined(); + expect(definitions).toHaveLength(1); + expect(definitions![0]).toMatchObject({ + label: 'ql-mcp', + command: 'npx', + args: ['-y', 'codeql-development-mcp-server'], + }); + }); + + it('should include environment from envBuilder in the definition', async () => { + const token = { isCancellationRequested: false, onCancellationRequested: vi.fn() }; + const definitions = await provider.provideMcpServerDefinitions(token as any); + + expect(definitions![0].env).toEqual({ + CODEQL_PATH: '/usr/local/bin/codeql', + CODEQL_MCP_WORKSPACE: '/mock/workspace', + }); + }); + + it('should always provide a definition (npx handles download)', async () => { + serverManager.isInstalled.mockResolvedValue(false); + + const token = { isCancellationRequested: false, onCancellationRequested: vi.fn() }; + const definitions = await provider.provideMcpServerDefinitions(token as any); + + expect(definitions).toHaveLength(1); + }); + + it('should pass version from serverManager when pinned', async () => { + serverManager.getVersion.mockReturnValue('2.20.0'); + + const token = { isCancellationRequested: false, onCancellationRequested: vi.fn() }; + const definitions = await provider.provideMcpServerDefinitions(token as any); + + expect(definitions![0].version).toBe('2.20.0'); + }); + + it('should resolve definition by refreshing environment', async () => { + const updatedEnv = { CODEQL_PATH: '/new/path', TRANSPORT_MODE: 'stdio' }; + envBuilder.build.mockResolvedValue(updatedEnv); + + const serverDef = { label: 'ql-mcp', command: 'npx', args: [], env: {} } as any; + const token = { isCancellationRequested: false, onCancellationRequested: vi.fn() }; + const resolved = await provider.resolveMcpServerDefinition(serverDef, token as any); + + expect(resolved).toBeDefined(); + expect(resolved!.env).toEqual(updatedEnv); + }); + + it('should expose onDidChangeMcpServerDefinitions event', () => { + expect(provider.onDidChangeMcpServerDefinitions).toBeDefined(); + }); + + it('should fire change event when fireDidChange is called', () => { + expect(() => provider.fireDidChange()).not.toThrow(); + }); + + it('should be disposable', () => { + expect(() => provider.dispose()).not.toThrow(); + }); +}); diff --git a/extensions/vscode/test/server/pack-installer.test.ts b/extensions/vscode/test/server/pack-installer.test.ts new file mode 100644 index 00000000..ef803d10 --- /dev/null +++ b/extensions/vscode/test/server/pack-installer.test.ts @@ -0,0 +1,189 @@ +import { describe, it, expect, vi, beforeEach } from 'vitest'; +import { PackInstaller } from '../../src/server/pack-installer'; + +vi.mock('child_process', () => ({ + execFile: vi.fn(), +})); + +vi.mock('fs/promises', () => ({ + access: vi.fn(), + readdir: vi.fn(), +})); + +import { execFile } from 'child_process'; +import { access } from 'fs/promises'; + +function createMockCliResolver() { + return { + resolve: vi.fn().mockResolvedValue('/usr/local/bin/codeql'), + invalidateCache: vi.fn(), + dispose: vi.fn(), + push: vi.fn(), + } as any; +} + +function createMockServerManager() { + return { + getPackageRoot: vi.fn().mockReturnValue('/mock/global-storage/mcp-server/node_modules/codeql-development-mcp-server'), + getInstallDir: vi.fn().mockReturnValue('/mock/global-storage/mcp-server'), + getCommand: vi.fn().mockReturnValue('npx'), + getArgs: vi.fn().mockReturnValue(['-y', 'codeql-development-mcp-server']), + dispose: vi.fn(), + push: vi.fn(), + } as any; +} + +function createMockLogger() { + return { + info: vi.fn(), + warn: vi.fn(), + error: vi.fn(), + debug: vi.fn(), + show: vi.fn(), + dispose: vi.fn(), + } as any; +} + +describe('PackInstaller', () => { + let installer: PackInstaller; + let cliResolver: any; + let serverManager: any; + let logger: any; + + beforeEach(() => { + vi.resetAllMocks(); + cliResolver = createMockCliResolver(); + serverManager = createMockServerManager(); + logger = createMockLogger(); + installer = new PackInstaller(cliResolver, serverManager, logger); + }); + + it('should be instantiable', () => { + expect(installer).toBeDefined(); + }); + + it('should list all supported languages', () => { + const languages = PackInstaller.SUPPORTED_LANGUAGES; + expect(languages).toContain('javascript'); + expect(languages).toContain('python'); + expect(languages).toContain('java'); + expect(languages).toHaveLength(9); + }); + + it('should resolve qlpack paths under the package root', () => { + const paths = installer.getQlpackPaths(); + expect(paths).toHaveLength(9); + for (const p of paths) { + expect(p).toContain('codeql-development-mcp-server/ql/'); + expect(p).toContain('/tools/src'); + } + }); + + it('should skip installation when CLI is not found', async () => { + cliResolver.resolve.mockResolvedValue(undefined); + + await installer.installAll(); + + expect(execFile).not.toHaveBeenCalled(); + expect(logger.warn).toHaveBeenCalled(); + }); + + it('should run codeql pack install for each language', async () => { + vi.mocked(access).mockResolvedValue(undefined); + + vi.mocked(execFile).mockImplementation( + (_cmd: any, _args: any, _opts: any, callback: any) => { + const cb = typeof _opts === 'function' ? _opts : callback; + cb(null, '', ''); + return {} as any; + }, + ); + + await installer.installAll({ force: true }); + + // Should have called execFile once per supported language + expect(execFile).toHaveBeenCalledTimes(PackInstaller.SUPPORTED_LANGUAGES.length); + }); + + it('should pass correct args to codeql CLI', async () => { + vi.mocked(access).mockResolvedValue(undefined); + vi.mocked(execFile).mockImplementation( + (_cmd: any, _args: any, _opts: any, callback: any) => { + const cb = typeof _opts === 'function' ? _opts : callback; + cb(null, '', ''); + return {} as any; + }, + ); + + await installer.installAll({ languages: ['javascript'] }); + + const [cmd, args] = vi.mocked(execFile).mock.calls[0]; + expect(cmd).toBe('/usr/local/bin/codeql'); + expect(args).toContain('pack'); + expect(args).toContain('install'); + expect(args).toContain('--no-strict-mode'); + }); + + it('should skip languages whose pack directory does not exist', async () => { + // Only javascript exists, others don't + vi.mocked(access).mockImplementation((path: any) => { + if (String(path).includes('/javascript/')) return Promise.resolve(undefined as any); + return Promise.reject(new Error('ENOENT')); + }); + + vi.mocked(execFile).mockImplementation( + (_cmd: any, _args: any, _opts: any, callback: any) => { + const cb = typeof _opts === 'function' ? _opts : callback; + cb(null, '', ''); + return {} as any; + }, + ); + + await installer.installAll(); + + // Only one call — for javascript + expect(execFile).toHaveBeenCalledTimes(1); + }); + + it('should continue installing other languages when one fails', async () => { + vi.mocked(access).mockResolvedValue(undefined); + let callCount = 0; + vi.mocked(execFile).mockImplementation( + (_cmd: any, _args: any, _opts: any, callback: any) => { + const cb = typeof _opts === 'function' ? _opts : callback; + callCount++; + if (callCount === 3) { + cb(new Error('pack install failed'), '', 'error'); + } else { + cb(null, '', ''); + } + return {} as any; + }, + ); + + // Should not throw — errors are logged per-language + await installer.installAll(); + + expect(execFile).toHaveBeenCalledTimes(PackInstaller.SUPPORTED_LANGUAGES.length); + expect(logger.error).toHaveBeenCalledTimes(1); + }); + + it('should install only specified languages', async () => { + vi.mocked(access).mockResolvedValue(undefined); + vi.mocked(execFile).mockImplementation( + (_cmd: any, _args: any, _opts: any, callback: any) => { + const cb = typeof _opts === 'function' ? _opts : callback; + cb(null, '', ''); + return {} as any; + }, + ); + + await installer.installAll({ languages: ['javascript', 'python'] }); + + expect(execFile).toHaveBeenCalledTimes(2); + }); + + it('should be disposable', () => { + expect(() => installer.dispose()).not.toThrow(); + }); +}); diff --git a/extensions/vscode/test/server/server-manager.test.ts b/extensions/vscode/test/server/server-manager.test.ts new file mode 100644 index 00000000..118cae3a --- /dev/null +++ b/extensions/vscode/test/server/server-manager.test.ts @@ -0,0 +1,163 @@ +import { describe, it, expect, vi, beforeEach } from 'vitest'; +import { ServerManager } from '../../src/server/server-manager'; + +vi.mock('child_process', () => ({ + execFile: vi.fn(), +})); + +vi.mock('fs/promises', () => ({ + access: vi.fn(), + readFile: vi.fn(), + mkdir: vi.fn(), +})); + +import { execFile } from 'child_process'; +import { access, readFile } from 'fs/promises'; + +function createMockContext() { + return { + globalStorageUri: { fsPath: '/mock/global-storage' }, + globalState: { + get: vi.fn(), + update: vi.fn().mockResolvedValue(undefined), + keys: vi.fn().mockReturnValue([]), + setKeysForSync: vi.fn(), + }, + subscriptions: [], + } as any; +} + +function createMockLogger() { + return { + info: vi.fn(), + warn: vi.fn(), + error: vi.fn(), + debug: vi.fn(), + show: vi.fn(), + dispose: vi.fn(), + } as any; +} + +describe('ServerManager', () => { + let manager: ServerManager; + let ctx: any; + let logger: any; + + beforeEach(() => { + vi.resetAllMocks(); + ctx = createMockContext(); + logger = createMockLogger(); + manager = new ServerManager(ctx, logger); + }); + + it('should be instantiable', () => { + expect(manager).toBeDefined(); + }); + + it('should compute install directory under globalStorageUri', () => { + const dir = manager.getInstallDir(); + expect(dir).toBe('/mock/global-storage/mcp-server'); + }); + + it('should compute package root under install dir', () => { + const root = manager.getPackageRoot(); + expect(root).toBe( + '/mock/global-storage/mcp-server/node_modules/codeql-development-mcp-server', + ); + }); + + it('should detect when package is not installed', async () => { + vi.mocked(access).mockRejectedValue(new Error('ENOENT')); + const installed = await manager.isInstalled(); + expect(installed).toBe(false); + }); + + it('should detect when package is installed', async () => { + vi.mocked(access).mockResolvedValue(undefined); + vi.mocked(readFile).mockResolvedValue(JSON.stringify({ version: '2.24.1' })); + const installed = await manager.isInstalled(); + expect(installed).toBe(true); + }); + + it('should default command to npx', () => { + expect(manager.getCommand()).toBe('npx'); + }); + + it('should default args to npx -y codeql-development-mcp-server', () => { + const args = manager.getArgs(); + expect(args).toEqual(['-y', 'codeql-development-mcp-server']); + }); + + it('should provide a human-readable description', () => { + const desc = manager.getDescription(); + expect(desc).toBe('npx -y codeql-development-mcp-server'); + }); + + it('should run npm install when installing', async () => { + vi.mocked(execFile).mockImplementation( + (_cmd: any, _args: any, _opts: any, callback: any) => { + if (typeof _opts === 'function') { + _opts(null, '', ''); + } else if (callback) { + callback(null, '', ''); + } + return {} as any; + }, + ); + vi.mocked(access).mockRejectedValue(new Error('ENOENT')); + + await manager.install(); + expect(execFile).toHaveBeenCalled(); + + // Should call npm with install --prefix + const [cmd, args] = vi.mocked(execFile).mock.calls[0]; + expect(cmd).toMatch(/npm/); + expect(args).toContain('install'); + expect(args).toContain('--prefix'); + }); + + it('should reject when npm install fails', async () => { + vi.mocked(execFile).mockImplementation( + (_cmd: any, _args: any, _opts: any, callback: any) => { + const cb = typeof _opts === 'function' ? _opts : callback; + cb(new Error('npm ERR! network'), '', 'npm ERR! network'); + return {} as any; + }, + ); + + await expect(manager.install()).rejects.toThrow(/npm install failed/); + expect(logger.error).toHaveBeenCalled(); + }); + + it('should read installed version from package.json', async () => { + vi.mocked(readFile).mockResolvedValue(JSON.stringify({ version: '2.24.1' })); + + const version = await manager.getInstalledVersion(); + expect(version).toBe('2.24.1'); + }); + + it('should return undefined for version when not installed', async () => { + vi.mocked(readFile).mockRejectedValue(new Error('ENOENT')); + + const version = await manager.getInstalledVersion(); + expect(version).toBeUndefined(); + }); + + it('should skip install in ensureInstalled when already current', async () => { + vi.mocked(access).mockResolvedValue(undefined); + vi.mocked(readFile).mockResolvedValue(JSON.stringify({ version: '2.24.1' })); + + const installed = await manager.ensureInstalled(); + + expect(installed).toBe(false); // No fresh install + expect(execFile).not.toHaveBeenCalled(); + }); + + it('should return undefined version when using latest', () => { + expect(manager.getVersion()).toBeUndefined(); + }); + + it('should be disposable', () => { + expect(() => manager.dispose()).not.toThrow(); + }); +}); diff --git a/extensions/vscode/test/setup.ts b/extensions/vscode/test/setup.ts new file mode 100644 index 00000000..ee6554e2 --- /dev/null +++ b/extensions/vscode/test/setup.ts @@ -0,0 +1,7 @@ +/** + * Global test setup for Vitest. + * + * Each test file that imports vscode-dependent code must call + * vi.mock('vscode', ...) with its own factory. See test/helpers/vscode-mock.ts. + */ + diff --git a/extensions/vscode/test/suite/extension.integration.test.ts b/extensions/vscode/test/suite/extension.integration.test.ts new file mode 100644 index 00000000..e0cdd844 --- /dev/null +++ b/extensions/vscode/test/suite/extension.integration.test.ts @@ -0,0 +1,61 @@ +/** + * Integration tests for the CodeQL MCP Server extension. + * + * These run inside the Extension Development Host with the REAL VS Code API. + * They verify the extension activates correctly and registers the expected + * contributions (commands, MCP server provider, etc.). + */ + +import * as assert from 'assert'; +import * as vscode from 'vscode'; + +const EXTENSION_ID = 'advanced-security.codeql-development-mcp-server-vscode'; + +suite('Extension Integration Tests', () => { + test('Extension should be present', () => { + const ext = vscode.extensions.getExtension(EXTENSION_ID); + assert.ok(ext, `Extension ${EXTENSION_ID} not found`); + }); + + test('Extension should activate', async () => { + const ext = vscode.extensions.getExtension(EXTENSION_ID); + assert.ok(ext, `Extension ${EXTENSION_ID} not found`); + + if (!ext.isActive) { + await ext.activate(); + } + assert.ok(ext.isActive, 'Extension did not activate'); + }); + + test('Extension should return API with mcpProvider', async () => { + const ext = vscode.extensions.getExtension(EXTENSION_ID); + assert.ok(ext); + + const api = ext.isActive ? ext.exports : await ext.activate(); + assert.ok(api, 'Extension did not return an API'); + assert.ok(api.mcpProvider, 'API missing mcpProvider'); + }); + + test('Commands should be registered', async () => { + const commands = await vscode.commands.getCommands(true); + const expected = [ + 'codeql-mcp.reinstallServer', + 'codeql-mcp.reinstallPacks', + 'codeql-mcp.showStatus', + 'codeql-mcp.showLogs', + ]; + for (const cmd of expected) { + assert.ok( + commands.includes(cmd), + `Command ${cmd} not registered`, + ); + } + }); + + test('CodeQL MCP output channel should exist', async () => { + // The extension creates a LogOutputChannel named "CodeQL MCP". + // We can verify this indirectly by running the showLogs command. + await vscode.commands.executeCommand('codeql-mcp.showLogs'); + // If the command doesn't throw, the channel exists. + }); +}); diff --git a/extensions/vscode/test/suite/index.ts b/extensions/vscode/test/suite/index.ts new file mode 100644 index 00000000..1c648c17 --- /dev/null +++ b/extensions/vscode/test/suite/index.ts @@ -0,0 +1,49 @@ +/** + * Extension Host test runner entry point. + * + * VS Code's `--extensionTestsPath` expects a module that exports a `run()` + * function. This file runs integration tests with Mocha inside the Extension + * Development Host — where the real VS Code API is available. + * + * Each test file is compiled to a separate .cjs file by esbuild (via outdir), + * so the runner discovers them via glob at runtime. + * + * These are INTEGRATION tests (real vscode API, real extension activation). + * Unit tests stay in test/ and run via vitest (no Extension Host needed). + */ + +import * as path from 'path'; +import Mocha from 'mocha'; +import { glob } from 'glob'; + +export async function run(): Promise { + const mocha = new Mocha({ + ui: 'tdd', + color: true, + timeout: 30_000, + }); + + const testsRoot = path.resolve(__dirname); + + // Find all compiled test files (*.test.cjs) in this directory + const files = await glob('**/*.test.cjs', { cwd: testsRoot }); + + for (const f of files) { + mocha.addFile(path.resolve(testsRoot, f)); + } + + return new Promise((resolve, reject) => { + try { + mocha.run((failures) => { + if (failures > 0) { + reject(new Error(`${failures} test(s) failed.`)); + } else { + resolve(); + } + }); + } catch (err) { + console.error('Test runner error:', err); + reject(err); + } + }); +} diff --git a/extensions/vscode/test/tsconfig.json b/extensions/vscode/test/tsconfig.json new file mode 100644 index 00000000..72e3dde3 --- /dev/null +++ b/extensions/vscode/test/tsconfig.json @@ -0,0 +1,16 @@ +{ + "extends": "../tsconfig.json", + "compilerOptions": { + "rootDir": "..", + "types": ["vitest/globals", "node"], + "noEmit": true + }, + "include": [ + "**/*.ts", + "**/*.test.ts", + "../src/**/*.ts" + ], + "exclude": [ + "node_modules" + ] +} diff --git a/extensions/vscode/tsconfig.json b/extensions/vscode/tsconfig.json new file mode 100644 index 00000000..bec27d2f --- /dev/null +++ b/extensions/vscode/tsconfig.json @@ -0,0 +1,25 @@ +{ + "compilerOptions": { + "target": "ES2022", + "module": "ESNext", + "moduleResolution": "bundler", + "allowSyntheticDefaultImports": true, + "esModuleInterop": true, + "strict": true, + "skipLibCheck": true, + "forceConsistentCasingInFileNames": true, + "declaration": true, + "outDir": "./dist", + "rootDir": "./src", + "resolveJsonModule": true, + "composite": true + }, + "include": [ + "src/**/*" + ], + "exclude": [ + "node_modules", + "dist", + "test" + ] +} diff --git a/extensions/vscode/vitest.config.ts b/extensions/vscode/vitest.config.ts new file mode 100644 index 00000000..4f860ca3 --- /dev/null +++ b/extensions/vscode/vitest.config.ts @@ -0,0 +1,20 @@ +import { defineConfig } from 'vitest/config'; +import { fileURLToPath, URL } from 'url'; + +export default defineConfig({ + test: { + globals: true, + environment: 'node', + include: ['test/**/*.{test,spec}.{js,ts}'], + exclude: ['test/suite/**'], + watch: false, + testTimeout: 10000, + alias: { + vscode: fileURLToPath(new URL('./__mocks__/vscode.ts', import.meta.url)), + }, + coverage: { + include: ['src/**/*.ts'], + exclude: ['src/**/*.d.ts'], + }, + }, +}); diff --git a/package-lock.json b/package-lock.json index 02a59b8c..2e44f624 100644 --- a/package-lock.json +++ b/package-lock.json @@ -10,7 +10,8 @@ "license": "SEE LICENSE IN LICENSE", "workspaces": [ "client", - "server" + "server", + "extensions/vscode" ], "devDependencies": { "eslint": "^9.39.2", @@ -258,6 +259,49 @@ "url": "https://github.com/sponsors/isaacs" } }, + "extensions/vscode": { + "name": "codeql-development-mcp-server-vscode", + "version": "2.24.1", + "license": "SEE LICENSE IN LICENSE", + "devDependencies": { + "@eslint/js": "^9.39.2", + "@types/mocha": "^10.0.10", + "@types/node": "^22.15.0", + "@types/vscode": "^1.99.0", + "@vitest/coverage-v8": "^4.0.18", + "esbuild": "^0.27.3", + "eslint": "^9.39.2", + "eslint-config-prettier": "^10.1.8", + "eslint-plugin-prettier": "^5.5.5", + "glob": "^11.0.2", + "mocha": "^11.2.2", + "prettier": "^3.8.1", + "typescript": "^5.9.3", + "typescript-eslint": "^8.54.0", + "vitest": "^4.0.18" + }, + "engines": { + "node": ">=24.13.0", + "vscode": "^1.99.0" + } + }, + "extensions/vscode/node_modules/@types/node": { + "version": "22.19.11", + "resolved": "https://registry.npmjs.org/@types/node/-/node-22.19.11.tgz", + "integrity": "sha512-BH7YwL6rA93ReqeQS1c4bsPpcfOmJasG+Fkr6Y59q83f9M1WcBRHR2vM+P9eOisYRcN3ujQoiZY8uk5W+1WL8w==", + "dev": true, + "license": "MIT", + "dependencies": { + "undici-types": "~6.21.0" + } + }, + "extensions/vscode/node_modules/undici-types": { + "version": "6.21.0", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.21.0.tgz", + "integrity": "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==", + "dev": true, + "license": "MIT" + }, "node_modules/@babel/helper-string-parser": { "version": "7.27.1", "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.27.1.tgz", @@ -991,6 +1035,16 @@ "node": "20 || >=22" } }, + "node_modules/@isaacs/cliui": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-9.0.0.tgz", + "integrity": "sha512-AokJm4tuBHillT+FpMtxQ60n8ObyXBatq7jD2/JA9dxbDDokKQm8KMht5ibGzLVU9IJDIKK4TPKgMHEYMn3lMg==", + "dev": true, + "license": "BlueOak-1.0.0", + "engines": { + "node": ">=18" + } + }, "node_modules/@jridgewell/resolve-uri": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", @@ -1081,6 +1135,17 @@ "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", "license": "MIT" }, + "node_modules/@pkgjs/parseargs": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz", + "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==", + "dev": true, + "license": "MIT", + "optional": true, + "engines": { + "node": ">=14" + } + }, "node_modules/@pkgr/core": { "version": "0.2.9", "resolved": "https://registry.npmjs.org/@pkgr/core/-/core-0.2.9.tgz", @@ -1560,6 +1625,13 @@ "dev": true, "license": "MIT" }, + "node_modules/@types/mocha": { + "version": "10.0.10", + "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-10.0.10.tgz", + "integrity": "sha512-xPyYSz1cMPnJQhl0CLMH68j3gprKZaTjG3s5Vi+fDgx+uhG9NOXwbVt52eFS8ECyXhyKcjDLCBEqBExKuiZb7Q==", + "dev": true, + "license": "MIT" + }, "node_modules/@types/node": { "version": "25.2.2", "resolved": "https://registry.npmjs.org/@types/node/-/node-25.2.2.tgz", @@ -1605,6 +1677,13 @@ "@types/node": "*" } }, + "node_modules/@types/vscode": { + "version": "1.109.0", + "resolved": "https://registry.npmjs.org/@types/vscode/-/vscode-1.109.0.tgz", + "integrity": "sha512-0Pf95rnwEIwDbmXGC08r0B4TQhAbsHQ5UyTIgVgoieDe4cOnf92usuR5dEczb6bTKEp7ziZH4TV1TRGPPCExtw==", + "dev": true, + "license": "MIT" + }, "node_modules/@typescript-eslint/eslint-plugin": { "version": "8.55.0", "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.55.0.tgz", @@ -2097,6 +2176,16 @@ "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", "license": "MIT" }, + "node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, "node_modules/ansi-styles": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", @@ -2183,6 +2272,13 @@ "concat-map": "0.0.1" } }, + "node_modules/browser-stdout": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz", + "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==", + "dev": true, + "license": "ISC" + }, "node_modules/bytes": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", @@ -2231,6 +2327,19 @@ "node": ">=6" } }, + "node_modules/camelcase": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", + "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/chai": { "version": "6.2.2", "resolved": "https://registry.npmjs.org/chai/-/chai-6.2.2.tgz", @@ -2258,6 +2367,37 @@ "url": "https://github.com/chalk/chalk?sponsor=1" } }, + "node_modules/chokidar": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-4.0.3.tgz", + "integrity": "sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==", + "dev": true, + "license": "MIT", + "dependencies": { + "readdirp": "^4.0.1" + }, + "engines": { + "node": ">= 14.16.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/cliui": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", + "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.1", + "wrap-ansi": "^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, "node_modules/codeql-development-mcp-server": { "resolved": "server", "link": true @@ -2266,6 +2406,10 @@ "resolved": "client", "link": true }, + "node_modules/codeql-development-mcp-server-vscode": { + "resolved": "extensions/vscode", + "link": true + }, "node_modules/color-convert": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", @@ -2381,6 +2525,19 @@ } } }, + "node_modules/decamelize": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-4.0.0.tgz", + "integrity": "sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/deep-is": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", @@ -2397,6 +2554,16 @@ "node": ">= 0.8" } }, + "node_modules/diff": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/diff/-/diff-7.0.0.tgz", + "integrity": "sha512-PJWHUb1RFevKCwaFA9RlG5tCd+FO5iRh9A8HEtkmBH2Li03iJriB6m6JIN4rGz3K3JLawI7/veA1xzRKP6ISBw==", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.3.1" + } + }, "node_modules/dotenv": { "version": "17.2.4", "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-17.2.4.tgz", @@ -2423,12 +2590,26 @@ "node": ">= 0.4" } }, + "node_modules/eastasianwidth": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", + "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==", + "dev": true, + "license": "MIT" + }, "node_modules/ee-first": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==", "license": "MIT" }, + "node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true, + "license": "MIT" + }, "node_modules/encodeurl": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-2.0.0.tgz", @@ -2517,6 +2698,16 @@ "@esbuild/win32-x64": "0.27.3" } }, + "node_modules/escalade": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", + "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, "node_modules/escape-html": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", @@ -2961,6 +3152,16 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/flat": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz", + "integrity": "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==", + "dev": true, + "license": "BSD-3-Clause", + "bin": { + "flat": "cli.js" + } + }, "node_modules/flat-cache": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-4.0.1.tgz", @@ -2982,6 +3183,23 @@ "dev": true, "license": "ISC" }, + "node_modules/foreground-child": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.3.1.tgz", + "integrity": "sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw==", + "dev": true, + "license": "ISC", + "dependencies": { + "cross-spawn": "^7.0.6", + "signal-exit": "^4.0.1" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "node_modules/forwarded": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", @@ -3024,6 +3242,16 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "dev": true, + "license": "ISC", + "engines": { + "node": "6.* || 8.* || >= 10.*" + } + }, "node_modules/get-intrinsic": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz", @@ -3061,6 +3289,31 @@ "node": ">= 0.4" } }, + "node_modules/glob": { + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-11.1.0.tgz", + "integrity": "sha512-vuNwKSaKiqm7g0THUBu2x7ckSs3XJLXE+2ssL7/MfTGPLLcrJQ/4Uq1CjPTtO5cCIiRxqvN6Twy1qOwhL0Xjcw==", + "deprecated": "Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "foreground-child": "^3.3.1", + "jackspeak": "^4.1.1", + "minimatch": "^10.1.1", + "minipass": "^7.1.2", + "package-json-from-dist": "^1.0.0", + "path-scurry": "^2.0.0" + }, + "bin": { + "glob": "dist/esm/bin.mjs" + }, + "engines": { + "node": "20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "node_modules/glob-parent": { "version": "6.0.2", "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", @@ -3074,6 +3327,48 @@ "node": ">=10.13.0" } }, + "node_modules/glob/node_modules/balanced-match": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-4.0.2.tgz", + "integrity": "sha512-x0K50QvKQ97fdEz2kPehIerj+YTeptKF9hyYkKf6egnwmMWAkADiO0QCzSp0R5xN8FTZgYaBfSaue46Ej62nMg==", + "dev": true, + "license": "MIT", + "dependencies": { + "jackspeak": "^4.2.3" + }, + "engines": { + "node": "20 || >=22" + } + }, + "node_modules/glob/node_modules/brace-expansion": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.2.tgz", + "integrity": "sha512-Pdk8c9poy+YhOgVWw1JNN22/HcivgKWwpxKq04M/jTmHyCZn12WPJebZxdjSa5TmBqISrUSgNYU3eRORljfCCw==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^4.0.2" + }, + "engines": { + "node": "20 || >=22" + } + }, + "node_modules/glob/node_modules/minimatch": { + "version": "10.2.0", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.0.tgz", + "integrity": "sha512-ugkC31VaVg9cF0DFVoADH12k6061zNZkZON+aX8AWsR9GhPcErkcMBceb6znR8wLERM2AkkOxy2nWRLpT9Jq5w==", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "brace-expansion": "^5.0.2" + }, + "engines": { + "node": "20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "node_modules/globals": { "version": "14.0.0", "resolved": "https://registry.npmjs.org/globals/-/globals-14.0.0.tgz", @@ -3133,6 +3428,16 @@ "node": ">= 0.4" } }, + "node_modules/he": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", + "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", + "dev": true, + "license": "MIT", + "bin": { + "he": "bin/he" + } + }, "node_modules/hono": { "version": "4.11.9", "resolved": "https://registry.npmjs.org/hono/-/hono-4.11.9.tgz", @@ -3257,6 +3562,16 @@ "node": ">=0.10.0" } }, + "node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, "node_modules/is-glob": { "version": "4.0.3", "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", @@ -3270,12 +3585,45 @@ "node": ">=0.10.0" } }, + "node_modules/is-path-inside": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", + "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/is-plain-obj": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-2.1.0.tgz", + "integrity": "sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, "node_modules/is-promise": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-4.0.0.tgz", "integrity": "sha512-hvpoI6korhJMnej285dSg6nu1+e6uxs7zG3BYAm5byqDsgJNWwxzM6z6iZiAgQR4TJ30JmBTOwqZUw3WlyH3AQ==", "license": "MIT" }, + "node_modules/is-unicode-supported": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz", + "integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/isexe": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", @@ -3321,6 +3669,22 @@ "node": ">=8" } }, + "node_modules/jackspeak": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-4.2.3.tgz", + "integrity": "sha512-ykkVRwrYvFm1nb2AJfKKYPr0emF6IiXDYUaFx4Zn9ZuIH7MrzEZ3sD5RlqGXNRpHtvUHJyOnCEFxOlNDtGo7wg==", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "@isaacs/cliui": "^9.0.0" + }, + "engines": { + "node": "20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "node_modules/jose": { "version": "6.1.3", "resolved": "https://registry.npmjs.org/jose/-/jose-6.1.3.tgz", @@ -3423,6 +3787,23 @@ "dev": true, "license": "MIT" }, + "node_modules/log-symbols": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz", + "integrity": "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==", + "dev": true, + "license": "MIT", + "dependencies": { + "chalk": "^4.1.0", + "is-unicode-supported": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/lowdb": { "version": "7.0.1", "resolved": "https://registry.npmjs.org/lowdb/-/lowdb-7.0.1.tgz", @@ -3438,6 +3819,16 @@ "url": "https://github.com/sponsors/typicode" } }, + "node_modules/lru-cache": { + "version": "11.2.6", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.2.6.tgz", + "integrity": "sha512-ESL2CrkS/2wTPfuend7Zhkzo2u0daGJ/A2VucJOgQ/C48S/zB8MMeMHSGKYpXhIjbPxfuezITkaBH1wqv00DDQ==", + "dev": true, + "license": "BlueOak-1.0.0", + "engines": { + "node": "20 || >=22" + } + }, "node_modules/magic-string": { "version": "0.30.21", "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.21.tgz", @@ -3544,16 +3935,270 @@ "node": "*" } }, - "node_modules/ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", - "license": "MIT" - }, - "node_modules/nanoid": { - "version": "3.3.11", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.11.tgz", - "integrity": "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==", + "node_modules/minipass": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz", + "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, + "node_modules/mocha": { + "version": "11.7.5", + "resolved": "https://registry.npmjs.org/mocha/-/mocha-11.7.5.tgz", + "integrity": "sha512-mTT6RgopEYABzXWFx+GcJ+ZQ32kp4fMf0xvpZIIfSq9Z8lC/++MtcCnQ9t5FP2veYEP95FIYSvW+U9fV4xrlig==", + "dev": true, + "license": "MIT", + "dependencies": { + "browser-stdout": "^1.3.1", + "chokidar": "^4.0.1", + "debug": "^4.3.5", + "diff": "^7.0.0", + "escape-string-regexp": "^4.0.0", + "find-up": "^5.0.0", + "glob": "^10.4.5", + "he": "^1.2.0", + "is-path-inside": "^3.0.3", + "js-yaml": "^4.1.0", + "log-symbols": "^4.1.0", + "minimatch": "^9.0.5", + "ms": "^2.1.3", + "picocolors": "^1.1.1", + "serialize-javascript": "^6.0.2", + "strip-json-comments": "^3.1.1", + "supports-color": "^8.1.1", + "workerpool": "^9.2.0", + "yargs": "^17.7.2", + "yargs-parser": "^21.1.1", + "yargs-unparser": "^2.0.0" + }, + "bin": { + "_mocha": "bin/_mocha", + "mocha": "bin/mocha.js" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/mocha/node_modules/@isaacs/cliui": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", + "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==", + "dev": true, + "license": "ISC", + "dependencies": { + "string-width": "^5.1.2", + "string-width-cjs": "npm:string-width@^4.2.0", + "strip-ansi": "^7.0.1", + "strip-ansi-cjs": "npm:strip-ansi@^6.0.1", + "wrap-ansi": "^8.1.0", + "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/mocha/node_modules/ansi-regex": { + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.2.2.tgz", + "integrity": "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/mocha/node_modules/ansi-styles": { + "version": "6.2.3", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.3.tgz", + "integrity": "sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/mocha/node_modules/brace-expansion": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz", + "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/mocha/node_modules/emoji-regex": { + "version": "9.2.2", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", + "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", + "dev": true, + "license": "MIT" + }, + "node_modules/mocha/node_modules/glob": { + "version": "10.5.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-10.5.0.tgz", + "integrity": "sha512-DfXN8DfhJ7NH3Oe7cFmu3NCu1wKbkReJ8TorzSAFbSKrlNaQSKfIzqYqVY8zlbs2NLBbWpRiU52GX2PbaBVNkg==", + "deprecated": "Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me", + "dev": true, + "license": "ISC", + "dependencies": { + "foreground-child": "^3.1.0", + "jackspeak": "^3.1.2", + "minimatch": "^9.0.4", + "minipass": "^7.1.2", + "package-json-from-dist": "^1.0.0", + "path-scurry": "^1.11.1" + }, + "bin": { + "glob": "dist/esm/bin.mjs" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/mocha/node_modules/jackspeak": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-3.4.3.tgz", + "integrity": "sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "@isaacs/cliui": "^8.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + }, + "optionalDependencies": { + "@pkgjs/parseargs": "^0.11.0" + } + }, + "node_modules/mocha/node_modules/lru-cache": { + "version": "10.4.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", + "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/mocha/node_modules/minimatch": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/mocha/node_modules/path-scurry": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.11.1.tgz", + "integrity": "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "lru-cache": "^10.2.0", + "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" + }, + "engines": { + "node": ">=16 || 14 >=14.18" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/mocha/node_modules/string-width": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", + "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", + "dev": true, + "license": "MIT", + "dependencies": { + "eastasianwidth": "^0.2.0", + "emoji-regex": "^9.2.2", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/mocha/node_modules/strip-ansi": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.2.tgz", + "integrity": "sha512-gmBGslpoQJtgnMAvOVqGZpEz9dyoKTCzy2nfz/n8aIFhN/jCE/rCmcxabB6jOOHV+0WNnylOxaxBQPSvcWklhA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, + "node_modules/mocha/node_modules/supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/supports-color?sponsor=1" + } + }, + "node_modules/mocha/node_modules/wrap-ansi": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", + "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^6.1.0", + "string-width": "^5.0.1", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "license": "MIT" + }, + "node_modules/nanoid": { + "version": "3.3.11", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.11.tgz", + "integrity": "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==", "dev": true, "funding": [ { @@ -3688,6 +4333,13 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/package-json-from-dist": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/package-json-from-dist/-/package-json-from-dist-1.0.1.tgz", + "integrity": "sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==", + "dev": true, + "license": "BlueOak-1.0.0" + }, "node_modules/parent-module": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", @@ -3729,6 +4381,23 @@ "node": ">=8" } }, + "node_modules/path-scurry": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-2.0.1.tgz", + "integrity": "sha512-oWyT4gICAu+kaA7QWk/jvCHWarMKNs6pXOGWKDTr7cw4IGcUbW+PeTfbaQiLGheFRpjo6O9J0PmyMfQPjH71oA==", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "lru-cache": "^11.0.0", + "minipass": "^7.1.2" + }, + "engines": { + "node": "20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "node_modules/path-to-regexp": { "version": "8.3.0", "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-8.3.0.tgz", @@ -3882,6 +4551,16 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/randombytes": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", + "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "safe-buffer": "^5.1.0" + } + }, "node_modules/range-parser": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", @@ -3906,6 +4585,30 @@ "node": ">= 0.10" } }, + "node_modules/readdirp": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-4.1.2.tgz", + "integrity": "sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 14.18.0" + }, + "funding": { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/require-from-string": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", @@ -3986,6 +4689,27 @@ "node": ">= 18" } }, + "node_modules/safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, "node_modules/safer-buffer": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", @@ -4031,6 +4755,16 @@ "url": "https://opencollective.com/express" } }, + "node_modules/serialize-javascript": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.2.tgz", + "integrity": "sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "randombytes": "^2.1.0" + } + }, "node_modules/serve-static": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-2.2.1.tgz", @@ -4156,6 +4890,19 @@ "dev": true, "license": "ISC" }, + "node_modules/signal-exit": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", + "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "node_modules/source-map-js": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", @@ -4201,6 +4948,64 @@ "url": "https://github.com/sponsors/typicode" } }, + "node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/string-width-cjs": { + "name": "string-width", + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-ansi-cjs": { + "name": "strip-ansi", + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/strip-json-comments": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", @@ -4607,12 +5412,111 @@ "node": ">=0.10.0" } }, + "node_modules/workerpool": { + "version": "9.3.4", + "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-9.3.4.tgz", + "integrity": "sha512-TmPRQYYSAnnDiEB0P/Ytip7bFGvqnSU6I2BcuSw7Hx+JSg/DsUi5ebYfc8GYaSdpuvOcEs6dXxPurOYpe9QFwg==", + "dev": true, + "license": "Apache-2.0" + }, + "node_modules/wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/wrap-ansi-cjs": { + "name": "wrap-ansi", + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, "node_modules/wrappy": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", "license": "ISC" }, + "node_modules/y18n": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", + "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=10" + } + }, + "node_modules/yargs": { + "version": "17.7.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", + "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", + "dev": true, + "license": "MIT", + "dependencies": { + "cliui": "^8.0.1", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.3", + "y18n": "^5.0.5", + "yargs-parser": "^21.1.1" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/yargs-parser": { + "version": "21.1.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", + "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=12" + } + }, + "node_modules/yargs-unparser": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-2.0.0.tgz", + "integrity": "sha512-7pRTIA9Qc1caZ0bZ6RYRGbHJthJWuakf+WmHK0rVeLkNrrGhfoabBNdue6kdINI6r4if7ocq9aD/n7xwKOdzOA==", + "dev": true, + "license": "MIT", + "dependencies": { + "camelcase": "^6.0.0", + "decamelize": "^4.0.0", + "flat": "^5.0.2", + "is-plain-obj": "^2.1.0" + }, + "engines": { + "node": ">=10" + } + }, "node_modules/yocto-queue": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", diff --git a/package.json b/package.json index 2e2b36ac..1727761e 100644 --- a/package.json +++ b/package.json @@ -31,21 +31,22 @@ "typescript-eslint": "^8.55.0" }, "scripts": { - "build": "npm run build -w server", + "build": "npm run build -w server && npm run build -w extensions/vscode", "build-and-test": "npm run build:all && npm run test:all", - "build:all": "npm run tidy && npm run build -w server && npm run build -w client", - "clean": "npm run clean -w client -w server", + "build:all": "npm run tidy && npm run build -w server && npm run build -w client && npm run build -w extensions/vscode", + "clean": "npm run clean -w client -w server -w extensions/vscode", "dev:stdio": "npm run dev:stdio -w server", "dev:http": "npm run dev:http -w server", "format": "prettier --write '**/*.{yml,yaml,md}'", "format:check": "prettier --check '**/*.{yml,yaml,md}'", - "lint": "npm run lint -w client -w server", - "lint:fix": "npm run lint:fix -w client -w server", + "lint": "npm run lint -w client -w server -w extensions/vscode", + "lint:fix": "npm run lint:fix -w client -w server -w extensions/vscode", "start": "npm run start -w server", - "test": "npm run test:server && npm run test:client", - "test:all": "npm run test:server && npm run test:client", + "test": "npm run test:server && npm run test:client && npm run test:vscode", + "test:all": "npm run test:server && npm run test:client && npm run test:vscode", "test:client": "npm run test:integration:default -w client", "test:server": "npm run test -w server", + "test:vscode": "npm run test -w extensions/vscode", "tidy": "npm run lint:fix && npm run format", "tidy:check": "npm run lint && npm run format:check", "upgrade": "npm run upgrade:node", @@ -53,6 +54,7 @@ }, "workspaces": [ "client", - "server" + "server", + "extensions/vscode" ] } diff --git a/server/dist/codeql-development-mcp-server.js b/server/dist/codeql-development-mcp-server.js index 8062b998..07b3b689 100755 --- a/server/dist/codeql-development-mcp-server.js +++ b/server/dist/codeql-development-mcp-server.js @@ -1621,7 +1621,8 @@ async function executeCodeQLCommand(subcommand, options, additionalArgs = [], cw return executeCLICommand({ command: "codeql", args, - cwd + cwd, + timeout: 0 }); } async function executeQLTCommand(subcommand, options, additionalArgs = []) { @@ -5817,17 +5818,293 @@ var codeqlGenerateQueryHelpTool = { resultProcessor: defaultCLIResultProcessor }; -// src/tools/codeql/pack-install.ts +// src/tools/codeql/list-databases.ts +import { existsSync as existsSync6, readdirSync as readdirSync2, readFileSync as readFileSync4, statSync as statSync2 } from "fs"; +import { join as join7 } from "path"; import { z as z12 } from "zod"; + +// src/lib/discovery-config.ts +function parsePathList(envValue) { + if (!envValue) { + return []; + } + return envValue.split(":").map((p) => p.trim()).filter((p) => p.length > 0); +} +function getDatabaseBaseDirs() { + return parsePathList(process.env.CODEQL_DATABASES_BASE_DIRS); +} +function getQueryRunResultsDirs() { + return parsePathList(process.env.CODEQL_QUERY_RUN_RESULTS_DIRS); +} + +// src/tools/codeql/list-databases.ts +init_logger(); +function parseDatabaseYml(ymlPath) { + try { + const content = readFileSync4(ymlPath, "utf-8"); + const info = {}; + for (const line of content.split("\n")) { + const trimmed = line.trim(); + const colonIdx = trimmed.indexOf(":"); + if (colonIdx === -1) continue; + const key = trimmed.substring(0, colonIdx).trim(); + const value = trimmed.substring(colonIdx + 1).trim().replace(/^["']|["']$/g, ""); + switch (key) { + case "primaryLanguage": + info.language = value; + break; + case "cliVersion": + info.cliVersion = value; + break; + case "creationTime": + info.creationTime = value; + break; + } + } + return info; + } catch { + return {}; + } +} +async function discoverDatabases(baseDirs, language) { + const databases = []; + for (const baseDir of baseDirs) { + if (!existsSync6(baseDir)) { + continue; + } + let entries; + try { + entries = readdirSync2(baseDir); + } catch { + continue; + } + for (const entry of entries) { + const entryPath = join7(baseDir, entry); + try { + if (!statSync2(entryPath).isDirectory()) { + continue; + } + } catch { + continue; + } + const ymlPath = join7(entryPath, "codeql-database.yml"); + if (!existsSync6(ymlPath)) { + continue; + } + const metadata = parseDatabaseYml(ymlPath); + if (language && metadata.language !== language) { + continue; + } + databases.push({ + cliVersion: metadata.cliVersion, + creationTime: metadata.creationTime, + language: metadata.language, + name: entry, + path: entryPath + }); + } + } + return databases; +} +function registerListDatabasesTool(server) { + server.tool( + "list_codeql_databases", + "List CodeQL databases discovered in configured base directories (set via CODEQL_DATABASES_BASE_DIRS env var). Returns path, language, CLI version, and creation time for each database.", + { + language: z12.string().optional().describe('Filter databases by language (e.g., "javascript", "python")') + }, + async ({ language }) => { + try { + const baseDirs = getDatabaseBaseDirs(); + if (baseDirs.length === 0) { + return { + content: [ + { + type: "text", + text: "No database base directories configured. Set the CODEQL_DATABASES_BASE_DIRS environment variable to a colon-separated list of directories to search." + } + ] + }; + } + const databases = await discoverDatabases(baseDirs, language); + if (databases.length === 0) { + const filterMsg = language ? ` for language "${language}"` : ""; + return { + content: [ + { + type: "text", + text: `No CodeQL databases found${filterMsg} in: ${baseDirs.join(", ")}` + } + ] + }; + } + const lines = [ + `Found ${databases.length} CodeQL database(s):`, + "", + ...databases.map((db) => { + const parts = [` ${db.name}`]; + parts.push(` Path: ${db.path}`); + if (db.language) parts.push(` Language: ${db.language}`); + if (db.cliVersion) parts.push(` CLI Version: ${db.cliVersion}`); + if (db.creationTime) parts.push(` Created: ${db.creationTime}`); + return parts.join("\n"); + }) + ]; + return { + content: [{ type: "text", text: lines.join("\n") }] + }; + } catch (error) { + logger.error("Error listing databases:", error); + return { + content: [ + { + type: "text", + text: `Error: ${error instanceof Error ? error.message : "Unknown error"}` + } + ], + isError: true + }; + } + } + ); +} + +// src/tools/codeql/list-query-run-results.ts +import { existsSync as existsSync7, readdirSync as readdirSync3, readFileSync as readFileSync5, statSync as statSync3 } from "fs"; +import { join as join8 } from "path"; +import { z as z13 } from "zod"; +init_logger(); +var QUERY_RUN_DIR_PATTERN = /^(.+\.ql)-(.+)$/; +async function discoverQueryRunResults(resultsDirs, queryName) { + const results = []; + for (const dir of resultsDirs) { + if (!existsSync7(dir)) { + continue; + } + let entries; + try { + entries = readdirSync3(dir); + } catch { + continue; + } + for (const entry of entries) { + const entryPath = join8(dir, entry); + try { + if (!statSync3(entryPath).isDirectory()) { + continue; + } + } catch { + continue; + } + const match = QUERY_RUN_DIR_PATTERN.exec(entry); + if (!match) { + continue; + } + const [, name, runId] = match; + if (queryName && name !== queryName) { + continue; + } + const hasEvaluatorLog = existsSync7(join8(entryPath, "evaluator-log.jsonl")); + const hasBqrs = existsSync7(join8(entryPath, "results.bqrs")); + const hasSarif = existsSync7(join8(entryPath, "results-interpreted.sarif")); + let timestamp2; + const timestampPath = join8(entryPath, "timestamp"); + if (existsSync7(timestampPath)) { + try { + timestamp2 = readFileSync5(timestampPath, "utf-8").trim(); + } catch { + } + } + results.push({ + hasBqrs, + hasEvaluatorLog, + hasSarif, + path: entryPath, + queryName: name, + runId, + timestamp: timestamp2 + }); + } + } + return results; +} +function registerListQueryRunResultsTool(server) { + server.tool( + "list_query_run_results", + "List discovered query run result directories (set via CODEQL_QUERY_RUN_RESULTS_DIRS env var). Returns path, query name, timestamp, and available artifacts for each run.", + { + queryName: z13.string().optional().describe('Filter results by query name (e.g., "UI5Xss.ql")') + }, + async ({ queryName }) => { + try { + const resultsDirs = getQueryRunResultsDirs(); + if (resultsDirs.length === 0) { + return { + content: [ + { + type: "text", + text: "No query run results directories configured. Set the CODEQL_QUERY_RUN_RESULTS_DIRS environment variable to a colon-separated list of directories to search." + } + ] + }; + } + const runs = await discoverQueryRunResults(resultsDirs, queryName); + if (runs.length === 0) { + const filterMsg = queryName ? ` for query "${queryName}"` : ""; + return { + content: [ + { + type: "text", + text: `No query run results found${filterMsg} in: ${resultsDirs.join(", ")}` + } + ] + }; + } + const lines = [ + `Found ${runs.length} query run result(s):`, + "", + ...runs.map((run) => { + const artifacts = []; + if (run.hasEvaluatorLog) artifacts.push("evaluator-log"); + if (run.hasBqrs) artifacts.push("bqrs"); + if (run.hasSarif) artifacts.push("sarif"); + const parts = [` ${run.queryName} (${run.runId})`]; + parts.push(` Path: ${run.path}`); + if (run.timestamp) parts.push(` Timestamp: ${run.timestamp}`); + parts.push(` Artifacts: ${artifacts.length > 0 ? artifacts.join(", ") : "none"}`); + return parts.join("\n"); + }) + ]; + return { + content: [{ type: "text", text: lines.join("\n") }] + }; + } catch (error) { + logger.error("Error listing query run results:", error); + return { + content: [ + { + type: "text", + text: `Error: ${error instanceof Error ? error.message : "Unknown error"}` + } + ], + isError: true + }; + } + } + ); +} + +// src/tools/codeql/pack-install.ts +import { z as z14 } from "zod"; var codeqlPackInstallTool = { name: "codeql_pack_install", description: "Install CodeQL pack dependencies", command: "codeql", subcommand: "pack install", inputSchema: { - packDir: z12.string().optional().describe("Directory containing qlpack.yml (default: current)"), - force: z12.boolean().optional().describe("Force reinstall of dependencies"), - "no-strict-mode": z12.boolean().optional().describe("Allow non-strict dependency resolution"), + packDir: z14.string().optional().describe("Directory containing qlpack.yml (default: current)"), + force: z14.boolean().optional().describe("Force reinstall of dependencies"), + "no-strict-mode": z14.boolean().optional().describe("Allow non-strict dependency resolution"), verbose: createCodeQLSchemas.verbose(), additionalArgs: createCodeQLSchemas.additionalArgs() }, @@ -5839,16 +6116,16 @@ var codeqlPackInstallTool = { }; // src/tools/codeql/pack-ls.ts -import { z as z13 } from "zod"; +import { z as z15 } from "zod"; var codeqlPackLsTool = { name: "codeql_pack_ls", description: "List CodeQL packs under some local directory path", command: "codeql", subcommand: "pack ls", inputSchema: { - dir: z13.string().optional().describe("The root directory of the package or workspace, defaults to the current working directory"), - format: z13.enum(["text", "json"]).optional().describe("Output format: text (default) or json"), - groups: z13.string().optional().describe("List of CodeQL pack groups to include or exclude"), + dir: z15.string().optional().describe("The root directory of the package or workspace, defaults to the current working directory"), + format: z15.enum(["text", "json"]).optional().describe("Output format: text (default) or json"), + groups: z15.string().optional().describe("List of CodeQL pack groups to include or exclude"), verbose: createCodeQLSchemas.verbose(), additionalArgs: createCodeQLSchemas.additionalArgs() }, @@ -5863,12 +6140,12 @@ var codeqlPackLsTool = { // src/tools/codeql/profile-codeql-query.ts init_cli_executor(); init_logger(); -import { z as z14 } from "zod"; -import { writeFileSync as writeFileSync3, readFileSync as readFileSync4, existsSync as existsSync6 } from "fs"; -import { join as join7, dirname as dirname6, basename as basename4 } from "path"; +import { z as z16 } from "zod"; +import { writeFileSync as writeFileSync3, readFileSync as readFileSync6, existsSync as existsSync8 } from "fs"; +import { join as join9, dirname as dirname6, basename as basename4 } from "path"; import { mkdirSync as mkdirSync6 } from "fs"; function parseEvaluatorLog(logPath) { - const logContent = readFileSync4(logPath, "utf-8"); + const logContent = readFileSync6(logPath, "utf-8"); const jsonObjects = logContent.split("\n\n").filter((s) => s.trim()); const events = jsonObjects.map((obj) => { try { @@ -5987,12 +6264,12 @@ function registerProfileCodeQLQueryTool(server) { "profile_codeql_query", "Profile the performance of a CodeQL query run against a specific database by analyzing the evaluator log JSON file", { - query: z14.string().describe("Path to the .ql query file"), - database: z14.string().describe("Path to the CodeQL database directory"), - evaluatorLog: z14.string().optional().describe( + query: z16.string().describe("Path to the .ql query file"), + database: z16.string().describe("Path to the CodeQL database directory"), + evaluatorLog: z16.string().optional().describe( "Path to an existing structured JSON log (e.g., evaluator-log.jsonl) file. If not provided, the tool will run the query to generate one." ), - outputDir: z14.string().optional().describe("Directory to write profiling data files (defaults to same directory as evaluator log)") + outputDir: z16.string().optional().describe("Directory to write profiling data files (defaults to same directory as evaluator log)") }, async (params) => { try { @@ -6002,11 +6279,11 @@ function registerProfileCodeQLQueryTool(server) { let sarifPath; if (!logPath) { logger.info("No evaluator log provided, running query to generate one"); - const defaultOutputDir = outputDir || join7(dirname6(query), "profile-output"); + const defaultOutputDir = outputDir || join9(dirname6(query), "profile-output"); mkdirSync6(defaultOutputDir, { recursive: true }); - logPath = join7(defaultOutputDir, "evaluator-log.jsonl"); - bqrsPath = join7(defaultOutputDir, "query-results.bqrs"); - sarifPath = join7(defaultOutputDir, "query-results.sarif"); + logPath = join9(defaultOutputDir, "evaluator-log.jsonl"); + bqrsPath = join9(defaultOutputDir, "query-results.bqrs"); + sarifPath = join9(defaultOutputDir, "query-results.sarif"); const queryResult = await executeCodeQLCommand( "query run", { @@ -6029,7 +6306,7 @@ function registerProfileCodeQLQueryTool(server) { isError: true }; } - if (existsSync6(bqrsPath)) { + if (existsSync8(bqrsPath)) { try { const sarifResult = await executeCodeQLCommand( "bqrs interpret", @@ -6044,7 +6321,7 @@ function registerProfileCodeQLQueryTool(server) { } } } - if (!existsSync6(logPath)) { + if (!existsSync8(logPath)) { return { content: [ { @@ -6059,11 +6336,11 @@ function registerProfileCodeQLQueryTool(server) { const profile = parseEvaluatorLog(logPath); const profileOutputDir = outputDir || dirname6(logPath); mkdirSync6(profileOutputDir, { recursive: true }); - const jsonPath = join7(profileOutputDir, "query-evaluation-profile.json"); + const jsonPath = join9(profileOutputDir, "query-evaluation-profile.json"); const jsonContent = formatAsJson(profile); writeFileSync3(jsonPath, jsonContent); logger.info(`Profile JSON written to: ${jsonPath}`); - const mdPath = join7(profileOutputDir, "query-evaluation-profile.md"); + const mdPath = join9(profileOutputDir, "query-evaluation-profile.md"); const mdContent = formatAsMermaid(profile); writeFileSync3(mdPath, mdContent); logger.info(`Profile Mermaid diagram written to: ${mdPath}`); @@ -6075,7 +6352,7 @@ function registerProfileCodeQLQueryTool(server) { if (bqrsPath) { outputFiles.push(`Query Results (BQRS): ${bqrsPath}`); } - if (sarifPath && existsSync6(sarifPath)) { + if (sarifPath && existsSync8(sarifPath)) { outputFiles.push(`Query Results (SARIF): ${sarifPath}`); } const responseText = [ @@ -6120,20 +6397,20 @@ function registerProfileCodeQLQueryTool(server) { } // src/tools/codeql/query-compile.ts -import { z as z15 } from "zod"; +import { z as z17 } from "zod"; var codeqlQueryCompileTool = { name: "codeql_query_compile", description: "Compile and validate CodeQL queries", command: "codeql", subcommand: "query compile", inputSchema: { - query: z15.string().describe("Path to the CodeQL query file (.ql)"), - database: z15.string().optional().describe("Path to the CodeQL database"), - library: z15.string().optional().describe("Path to query library"), - output: z15.string().optional().describe("Output file path"), - warnings: z15.enum(["hide", "show", "error"]).optional().describe("How to handle compilation warnings"), - verbose: z15.boolean().optional().describe("Enable verbose output"), - additionalArgs: z15.array(z15.string()).optional().describe("Additional command-line arguments") + query: z17.string().describe("Path to the CodeQL query file (.ql)"), + database: z17.string().optional().describe("Path to the CodeQL database"), + library: z17.string().optional().describe("Path to query library"), + output: z17.string().optional().describe("Output file path"), + warnings: z17.enum(["hide", "show", "error"]).optional().describe("How to handle compilation warnings"), + verbose: z17.boolean().optional().describe("Enable verbose output"), + additionalArgs: z17.array(z17.string()).optional().describe("Additional command-line arguments") }, examples: [ "codeql query compile --database=/path/to/db MyQuery.ql", @@ -6142,7 +6419,7 @@ var codeqlQueryCompileTool = { }; // src/tools/codeql/query-format.ts -import { z as z16 } from "zod"; +import { z as z18 } from "zod"; function formatResultProcessor(result, params) { const isCheckOnly = params["check-only"]; const hasFormatChanges = result.exitCode === 1; @@ -6158,12 +6435,12 @@ var codeqlQueryFormatTool = { command: "codeql", subcommand: "query format", inputSchema: { - files: z16.array(z16.string()).describe("One or more .ql or .qll source files to format"), - output: z16.string().optional().describe("Write formatted code to this file instead of stdout"), - "in-place": z16.boolean().optional().describe("Overwrite each input file with formatted version"), - "check-only": z16.boolean().optional().describe("Check formatting without writing output"), - backup: z16.string().optional().describe("Backup extension when overwriting existing files"), - "no-syntax-errors": z16.boolean().optional().describe("Ignore syntax errors and pretend file is formatted"), + files: z18.array(z18.string()).describe("One or more .ql or .qll source files to format"), + output: z18.string().optional().describe("Write formatted code to this file instead of stdout"), + "in-place": z18.boolean().optional().describe("Overwrite each input file with formatted version"), + "check-only": z18.boolean().optional().describe("Check formatting without writing output"), + backup: z18.string().optional().describe("Backup extension when overwriting existing files"), + "no-syntax-errors": z18.boolean().optional().describe("Ignore syntax errors and pretend file is formatted"), verbose: createCodeQLSchemas.verbose(), additionalArgs: createCodeQLSchemas.additionalArgs() }, @@ -6176,33 +6453,33 @@ var codeqlQueryFormatTool = { }; // src/tools/codeql/query-run.ts -import { z as z17 } from "zod"; +import { z as z19 } from "zod"; var codeqlQueryRunTool = { name: "codeql_query_run", description: 'Execute a CodeQL query against a database. Use either "query" parameter for direct file path OR "queryName" + "queryLanguage" for pre-defined tool queries.', command: "codeql", subcommand: "query run", inputSchema: { - query: z17.string().optional().describe("Path to the CodeQL query file (.ql) - cannot be used with queryName"), - queryName: z17.string().optional().describe('Name of pre-defined query to run (e.g., "PrintAST", "CallGraphFrom", "CallGraphTo") - requires queryLanguage'), - queryLanguage: z17.string().optional().describe('Programming language for tools queries (e.g., "javascript", "java", "python") - required when using queryName'), - queryPack: z17.string().optional().describe("Query pack path (defaults to server/ql//tools/src/ for tool queries)"), - sourceFiles: z17.string().optional().describe('Comma-separated list of source file paths for PrintAST queries (e.g., "src/main.js,src/utils.js" or just "main.js")'), - sourceFunction: z17.string().optional().describe('Comma-separated list of source function names for CallGraphFrom queries (e.g., "main,processData")'), - targetFunction: z17.string().optional().describe('Comma-separated list of target function names for CallGraphTo queries (e.g., "helper,validateInput")'), + query: z19.string().optional().describe("Path to the CodeQL query file (.ql) - cannot be used with queryName"), + queryName: z19.string().optional().describe('Name of pre-defined query to run (e.g., "PrintAST", "CallGraphFrom", "CallGraphTo") - requires queryLanguage'), + queryLanguage: z19.string().optional().describe('Programming language for tools queries (e.g., "javascript", "java", "python") - required when using queryName'), + queryPack: z19.string().optional().describe("Query pack path (defaults to server/ql//tools/src/ for tool queries)"), + sourceFiles: z19.string().optional().describe('Comma-separated list of source file paths for PrintAST queries (e.g., "src/main.js,src/utils.js" or just "main.js")'), + sourceFunction: z19.string().optional().describe('Comma-separated list of source function names for CallGraphFrom queries (e.g., "main,processData")'), + targetFunction: z19.string().optional().describe('Comma-separated list of target function names for CallGraphTo queries (e.g., "helper,validateInput")'), database: createCodeQLSchemas.database(), output: createCodeQLSchemas.output(), - external: z17.array(z17.string()).optional().describe("External predicate data: predicate=file.csv"), + external: z19.array(z19.string()).optional().describe("External predicate data: predicate=file.csv"), timeout: createCodeQLSchemas.timeout(), - logDir: z17.string().optional().describe("Custom directory for query execution logs (overrides CODEQL_QUERY_LOG_DIR environment variable). If not provided, uses CODEQL_QUERY_LOG_DIR or defaults to .tmp/query-logs/"), - "evaluator-log": z17.string().optional().describe("Path to save evaluator log (deprecated: use logDir instead)"), - "evaluator-log-minify": z17.boolean().optional().describe("Minimize evaluator log for smaller size"), - "evaluator-log-level": z17.number().min(1).max(5).optional().describe("Evaluator log verbosity level (1-5, default 5)"), - "tuple-counting": z17.boolean().optional().describe("Display tuple counts for each evaluation step in evaluator logs"), - format: z17.enum(["sarif-latest", "sarifv2.1.0", "csv", "graphtext", "dgml", "dot"]).optional().describe("Output format for query results via codeql bqrs interpret. Defaults to sarif-latest for @kind problem/path-problem queries, graphtext for @kind graph queries. Graph formats (graphtext, dgml, dot) only work with @kind graph queries."), - interpretedOutput: z17.string().optional().describe("Output file for interpreted results (e.g., results.sarif, results.txt). If not provided, defaults based on format: .sarif for SARIF, .txt for graphtext/csv, .dgml for dgml, .dot for dot"), - evaluationFunction: z17.string().optional().describe('[DEPRECATED - use format parameter instead] Built-in function for query results evaluation (e.g., "mermaid-graph", "json-decode", "csv-decode") or path to custom evaluation script'), - evaluationOutput: z17.string().optional().describe("[DEPRECATED - use interpretedOutput parameter instead] Output file for evaluation results"), + logDir: z19.string().optional().describe("Custom directory for query execution logs (overrides CODEQL_QUERY_LOG_DIR environment variable). If not provided, uses CODEQL_QUERY_LOG_DIR or defaults to .tmp/query-logs/"), + "evaluator-log": z19.string().optional().describe("Path to save evaluator log (deprecated: use logDir instead)"), + "evaluator-log-minify": z19.boolean().optional().describe("Minimize evaluator log for smaller size"), + "evaluator-log-level": z19.number().min(1).max(5).optional().describe("Evaluator log verbosity level (1-5, default 5)"), + "tuple-counting": z19.boolean().optional().describe("Display tuple counts for each evaluation step in evaluator logs"), + format: z19.enum(["sarif-latest", "sarifv2.1.0", "csv", "graphtext", "dgml", "dot"]).optional().describe("Output format for query results via codeql bqrs interpret. Defaults to sarif-latest for @kind problem/path-problem queries, graphtext for @kind graph queries. Graph formats (graphtext, dgml, dot) only work with @kind graph queries."), + interpretedOutput: z19.string().optional().describe("Output file for interpreted results (e.g., results.sarif, results.txt). If not provided, defaults based on format: .sarif for SARIF, .txt for graphtext/csv, .dgml for dgml, .dot for dot"), + evaluationFunction: z19.string().optional().describe('[DEPRECATED - use format parameter instead] Built-in function for query results evaluation (e.g., "mermaid-graph", "json-decode", "csv-decode") or path to custom evaluation script'), + evaluationOutput: z19.string().optional().describe("[DEPRECATED - use interpretedOutput parameter instead] Output file for evaluation results"), verbose: createCodeQLSchemas.verbose(), additionalArgs: createCodeQLSchemas.additionalArgs() }, @@ -6217,8 +6494,8 @@ var codeqlQueryRunTool = { }; // src/tools/codeql/quick-evaluate.ts -import { z as z18 } from "zod"; -import { join as join8, resolve as resolve6 } from "path"; +import { z as z20 } from "zod"; +import { join as join10, resolve as resolve6 } from "path"; init_logger(); init_temp_dir(); async function quickEvaluate({ @@ -6237,7 +6514,7 @@ async function quickEvaluate({ throw new Error(`Symbol '${symbol}' not found as class or predicate in file: ${file}`); } } - const resolvedOutput = resolve6(output_path || join8(getProjectTmpDir("quickeval"), "quickeval.bqrs")); + const resolvedOutput = resolve6(output_path || join10(getProjectTmpDir("quickeval"), "quickeval.bqrs")); return resolvedOutput; } catch (error) { throw new Error(`CodeQL evaluation failed: ${error instanceof Error ? error.message : "Unknown error"}`); @@ -6248,10 +6525,10 @@ function registerQuickEvaluateTool(server) { "quick_evaluate", "Quick evaluate either a class or a predicate in a CodeQL query for debugging", { - file: z18.string().describe("Path to the .ql file containing the symbol"), - db: z18.string().describe("Path to the CodeQL database"), - symbol: z18.string().describe("Name of the class or predicate to evaluate"), - output_path: z18.string().optional().describe("Output path for results (defaults to project-local .tmp/quickeval/)") + file: z20.string().describe("Path to the .ql file containing the symbol"), + db: z20.string().describe("Path to the CodeQL database"), + symbol: z20.string().describe("Name of the class or predicate to evaluate"), + output_path: z20.string().optional().describe("Output path for results (defaults to project-local .tmp/quickeval/)") }, async ({ file, db, symbol, output_path }) => { try { @@ -6277,7 +6554,7 @@ function registerQuickEvaluateTool(server) { // src/tools/codeql/register-database.ts init_logger(); -import { z as z19 } from "zod"; +import { z as z21 } from "zod"; import { access, constants } from "fs/promises"; import { resolve as resolve7 } from "path"; async function registerDatabase(dbPath) { @@ -6328,7 +6605,7 @@ function registerRegisterDatabaseTool(server) { "register_database", "Register a CodeQL database given a local path to the database directory", { - db_path: z19.string().describe("Path to the CodeQL database directory") + db_path: z21.string().describe("Path to the CodeQL database directory") }, async ({ db_path }) => { try { @@ -6353,15 +6630,15 @@ function registerRegisterDatabaseTool(server) { } // src/tools/codeql/resolve-database.ts -import { z as z20 } from "zod"; +import { z as z22 } from "zod"; var codeqlResolveDatabaseTool = { name: "codeql_resolve_database", description: "Resolve database path and validate database structure", command: "codeql", subcommand: "resolve database", inputSchema: { - database: z20.string().describe("Database path to resolve"), - format: z20.enum(["text", "json", "betterjson"]).optional().describe("Output format for database information"), + database: z22.string().describe("Database path to resolve"), + format: z22.enum(["text", "json", "betterjson"]).optional().describe("Output format for database information"), verbose: createCodeQLSchemas.verbose(), additionalArgs: createCodeQLSchemas.additionalArgs() }, @@ -6374,16 +6651,16 @@ var codeqlResolveDatabaseTool = { }; // src/tools/codeql/resolve-languages.ts -import { z as z21 } from "zod"; +import { z as z23 } from "zod"; var codeqlResolveLanguagesTool = { name: "codeql_resolve_languages", description: "List installed CodeQL extractor packs", command: "codeql", subcommand: "resolve languages", inputSchema: { - format: z21.enum(["text", "json", "betterjson"]).optional().describe("Output format for language information"), - verbose: z21.boolean().optional().describe("Enable verbose output"), - additionalArgs: z21.array(z21.string()).optional().describe("Additional command-line arguments") + format: z23.enum(["text", "json", "betterjson"]).optional().describe("Output format for language information"), + verbose: z23.boolean().optional().describe("Enable verbose output"), + additionalArgs: z23.array(z23.string()).optional().describe("Additional command-line arguments") }, examples: [ "codeql resolve languages --format=text", @@ -6394,17 +6671,17 @@ var codeqlResolveLanguagesTool = { }; // src/tools/codeql/resolve-library-path.ts -import { z as z22 } from "zod"; +import { z as z24 } from "zod"; var codeqlResolveLibraryPathTool = { name: "codeql_resolve_library-path", description: "Resolve library path for CodeQL queries and libraries", command: "codeql", subcommand: "resolve library-path", inputSchema: { - language: z22.string().optional().describe("Programming language to resolve library path for"), - format: z22.enum(["text", "json", "betterjson"]).optional().describe("Output format for library path information"), - verbose: z22.boolean().optional().describe("Enable verbose output"), - additionalArgs: z22.array(z22.string()).optional().describe("Additional command-line arguments") + language: z24.string().optional().describe("Programming language to resolve library path for"), + format: z24.enum(["text", "json", "betterjson"]).optional().describe("Output format for library path information"), + verbose: z24.boolean().optional().describe("Enable verbose output"), + additionalArgs: z24.array(z24.string()).optional().describe("Additional command-line arguments") }, examples: [ "codeql resolve library-path --language=java", @@ -6415,17 +6692,17 @@ var codeqlResolveLibraryPathTool = { }; // src/tools/codeql/resolve-metadata.ts -import { z as z23 } from "zod"; +import { z as z25 } from "zod"; var codeqlResolveMetadataTool = { name: "codeql_resolve_metadata", description: "Resolve and return the key-value metadata pairs from a CodeQL query source file.", command: "codeql", subcommand: "resolve metadata", inputSchema: { - query: z23.string().describe("Query file to resolve metadata for"), - format: z23.enum(["json"]).optional().describe("Output format for metadata information (always JSON, optional for future compatibility)"), - verbose: z23.boolean().optional().describe("Enable verbose output"), - additionalArgs: z23.array(z23.string()).optional().describe("Additional command-line arguments") + query: z25.string().describe("Query file to resolve metadata for"), + format: z25.enum(["json"]).optional().describe("Output format for metadata information (always JSON, optional for future compatibility)"), + verbose: z25.boolean().optional().describe("Enable verbose output"), + additionalArgs: z25.array(z25.string()).optional().describe("Additional command-line arguments") }, examples: [ "codeql resolve metadata -- relative-path/2/MyQuery.ql", @@ -6435,15 +6712,15 @@ var codeqlResolveMetadataTool = { }; // src/tools/codeql/resolve-qlref.ts -import { z as z24 } from "zod"; +import { z as z26 } from "zod"; var codeqlResolveQlrefTool = { name: "codeql_resolve_qlref", description: "Resolve qlref files to their corresponding query files", command: "codeql", subcommand: "resolve qlref", inputSchema: { - qlref: z24.string().describe("Path to the .qlref file to resolve"), - format: z24.enum(["text", "json", "betterjson"]).optional().describe("Output format for qlref resolution"), + qlref: z26.string().describe("Path to the .qlref file to resolve"), + format: z26.enum(["text", "json", "betterjson"]).optional().describe("Output format for qlref resolution"), verbose: createCodeQLSchemas.verbose(), additionalArgs: createCodeQLSchemas.additionalArgs() }, @@ -6456,7 +6733,7 @@ var codeqlResolveQlrefTool = { }; // src/tools/codeql/resolve-queries.ts -import { z as z25 } from "zod"; +import { z as z27 } from "zod"; var jsonOnlyResultProcessor = (result, params) => { if (!result.success) { return `Command failed (exit code ${result.exitCode || "unknown"}): @@ -6486,10 +6763,10 @@ var codeqlResolveQueriesTool = { command: "codeql", subcommand: "resolve queries", inputSchema: { - directory: z25.string().optional().describe("Directory to search for queries"), - language: z25.string().optional().describe("Filter queries by programming language"), - format: z25.enum(["text", "json", "betterjson", "bylanguage"]).optional().describe("Output format for query list"), - "additional-packs": z25.union([z25.string(), z25.array(z25.string())]).optional().describe("Additional pack directories to search for CodeQL packs"), + directory: z27.string().optional().describe("Directory to search for queries"), + language: z27.string().optional().describe("Filter queries by programming language"), + format: z27.enum(["text", "json", "betterjson", "bylanguage"]).optional().describe("Output format for query list"), + "additional-packs": z27.union([z27.string(), z27.array(z27.string())]).optional().describe("Additional pack directories to search for CodeQL packs"), verbose: createCodeQLSchemas.verbose(), additionalArgs: createCodeQLSchemas.additionalArgs() }, @@ -6503,15 +6780,15 @@ var codeqlResolveQueriesTool = { }; // src/tools/codeql/resolve-tests.ts -import { z as z26 } from "zod"; +import { z as z28 } from "zod"; var codeqlResolveTestsTool = { name: "codeql_resolve_tests", description: "Resolve the local filesystem paths of unit tests and/or queries under some base directory", command: "codeql", subcommand: "resolve tests", inputSchema: { - tests: z26.array(z26.string()).optional().describe("One or more tests (.ql, .qlref files, or test directories)"), - format: z26.enum(["text", "json"]).optional().describe("Output format for test list"), + tests: z28.array(z28.string()).optional().describe("One or more tests (.ql, .qlref files, or test directories)"), + format: z28.enum(["text", "json"]).optional().describe("Output format for test list"), verbose: createCodeQLSchemas.verbose(), additionalArgs: createCodeQLSchemas.additionalArgs() }, @@ -6524,14 +6801,14 @@ var codeqlResolveTestsTool = { }; // src/tools/codeql/test-accept.ts -import { z as z27 } from "zod"; +import { z as z29 } from "zod"; var codeqlTestAcceptTool = { name: "codeql_test_accept", description: "Accept new test results as the expected baseline", command: "codeql", subcommand: "test accept", inputSchema: { - tests: z27.array(z27.string()).describe("One or more tests (.ql, .qlref files, or test directories)"), + tests: z29.array(z29.string()).describe("One or more tests (.ql, .qlref files, or test directories)"), verbose: createCodeQLSchemas.verbose(), additionalArgs: createCodeQLSchemas.additionalArgs() }, @@ -6544,15 +6821,15 @@ var codeqlTestAcceptTool = { }; // src/tools/codeql/test-extract.ts -import { z as z28 } from "zod"; +import { z as z30 } from "zod"; var codeqlTestExtractTool = { name: "codeql_test_extract", description: "Extract test databases for CodeQL query tests", command: "codeql", subcommand: "test extract", inputSchema: { - tests: z28.array(z28.string()).describe("One or more test directories or files"), - language: z28.string().optional().describe("Programming language for extraction"), + tests: z30.array(z30.string()).describe("One or more test directories or files"), + language: z30.string().optional().describe("Programming language for extraction"), threads: createCodeQLSchemas.threads(), ram: createCodeQLSchemas.ram(), verbose: createCodeQLSchemas.verbose(), @@ -6567,18 +6844,18 @@ var codeqlTestExtractTool = { }; // src/tools/codeql/test-run.ts -import { z as z29 } from "zod"; +import { z as z31 } from "zod"; var codeqlTestRunTool = { name: "codeql_test_run", description: "Run CodeQL query tests", command: "codeql", subcommand: "test run", inputSchema: { - tests: z29.array(z29.string()).describe("One or more tests (.ql, .qlref files, or test directories)"), - "show-extractor-output": z29.boolean().optional().describe("Show output from extractors during test execution"), - "keep-databases": z29.boolean().optional().describe("Keep test databases after running tests"), - "learn": z29.boolean().optional().describe("Accept current output as expected for failing tests"), - logDir: z29.string().optional().describe("Custom directory for test execution logs (overrides CODEQL_QUERY_LOG_DIR environment variable). If not provided, uses CODEQL_QUERY_LOG_DIR or defaults to .tmp/query-logs/"), + tests: z31.array(z31.string()).describe("One or more tests (.ql, .qlref files, or test directories)"), + "show-extractor-output": z31.boolean().optional().describe("Show output from extractors during test execution"), + "keep-databases": z31.boolean().optional().describe("Keep test databases after running tests"), + "learn": z31.boolean().optional().describe("Accept current output as expected for failing tests"), + logDir: z31.string().optional().describe("Custom directory for test execution logs (overrides CODEQL_QUERY_LOG_DIR environment variable). If not provided, uses CODEQL_QUERY_LOG_DIR or defaults to .tmp/query-logs/"), threads: createCodeQLSchemas.threads(), ram: createCodeQLSchemas.ram(), verbose: createCodeQLSchemas.verbose(), @@ -6593,7 +6870,7 @@ var codeqlTestRunTool = { }; // src/tools/codeql-tools.ts -import { z as z30 } from "zod"; +import { z as z32 } from "zod"; // src/lib/validation.ts function validateCodeQLSyntax(query, _language) { @@ -6712,8 +6989,8 @@ function registerCodeQLTools(server) { "validate_codeql_query", "Quick heuristic validation for CodeQL query structure - checks for common patterns like from/where/select clauses and metadata presence. Does NOT compile the query. For authoritative validation with actual compilation, use codeql_lsp_diagnostics instead.", { - query: z30.string().describe("The CodeQL query to validate"), - language: z30.string().optional().describe("Target programming language") + query: z32.string().describe("The CodeQL query to validate"), + language: z32.string().optional().describe("Target programming language") }, async ({ query, language }) => { try { @@ -6739,11 +7016,11 @@ function registerCodeQLTools(server) { "create_codeql_query", "Create directory structure and files for a new CodeQL query with tests", { - basePath: z30.string().describe("Base path where src/ and test/ directories will be created"), - queryName: z30.string().describe("Name of the query (e.g., MySecurityQuery)"), - language: z30.string().describe("Target programming language (e.g., javascript, python, java)"), - description: z30.string().optional().describe("Description of what the query does"), - queryId: z30.string().optional().describe("Custom query ID (defaults to language/example/queryname)") + basePath: z32.string().describe("Base path where src/ and test/ directories will be created"), + queryName: z32.string().describe("Name of the query (e.g., MySecurityQuery)"), + language: z32.string().describe("Target programming language (e.g., javascript, python, java)"), + description: z32.string().optional().describe("Description of what the query does"), + queryId: z32.string().optional().describe("Custom query ID (defaults to language/example/queryname)") }, async ({ basePath, queryName, language, description, queryId }) => { try { @@ -6811,41 +7088,43 @@ function registerCodeQLTools(server) { registerFindClassPositionTool(server); registerFindCodeQLQueryFilesTool(server); registerFindPredicatePositionTool(server); + registerListDatabasesTool(server); + registerListQueryRunResultsTool(server); registerProfileCodeQLQueryTool(server); registerQuickEvaluateTool(server); registerRegisterDatabaseTool(server); } // src/lib/resources.ts -import { readFileSync as readFileSync5 } from "fs"; -import { join as join10, dirname as dirname7 } from "path"; +import { readFileSync as readFileSync7 } from "fs"; +import { join as join12, dirname as dirname7 } from "path"; import { fileURLToPath as fileURLToPath2 } from "url"; var __filename2 = fileURLToPath2(import.meta.url); var __dirname2 = dirname7(__filename2); function getGettingStartedGuide() { try { - return readFileSync5(join10(__dirname2, "../resources/getting-started.md"), "utf-8"); + return readFileSync7(join12(__dirname2, "../resources/getting-started.md"), "utf-8"); } catch { return "Getting started guide not available"; } } function getQueryBasicsGuide() { try { - return readFileSync5(join10(__dirname2, "../resources/query-basics.md"), "utf-8"); + return readFileSync7(join12(__dirname2, "../resources/query-basics.md"), "utf-8"); } catch { return "Query basics guide not available"; } } function getSecurityTemplates() { try { - return readFileSync5(join10(__dirname2, "../resources/security-templates.md"), "utf-8"); + return readFileSync7(join12(__dirname2, "../resources/security-templates.md"), "utf-8"); } catch { return "Security templates not available"; } } function getPerformancePatterns() { try { - return readFileSync5(join10(__dirname2, "../resources/performance-patterns.md"), "utf-8"); + return readFileSync7(join12(__dirname2, "../resources/performance-patterns.md"), "utf-8"); } catch { return "Performance patterns not available"; } @@ -6934,8 +7213,8 @@ function registerCodeQLResources(server) { // src/tools/lsp/lsp-diagnostics.ts init_logger(); init_temp_dir(); -import { z as z31 } from "zod"; -import { join as join11 } from "path"; +import { z as z33 } from "zod"; +import { join as join13 } from "path"; import { pathToFileURL as pathToFileURL3 } from "url"; // src/tools/lsp/lsp-server-helper.ts @@ -7033,7 +7312,7 @@ async function lspDiagnostics({ serverOptions, workspaceUri }); - const evalUri = pathToFileURL3(join11(getProjectTmpDir("lsp-eval"), `eval_${Date.now()}.ql`)).href; + const evalUri = pathToFileURL3(join13(getProjectTmpDir("lsp-eval"), `eval_${Date.now()}.ql`)).href; const diagnostics = await languageServer.evaluateQL(qlCode, evalUri); const summary = { errorCount: diagnostics.filter((d) => d.severity === 1).length, @@ -7060,10 +7339,10 @@ function registerLspDiagnosticsTool(server) { "codeql_lsp_diagnostics", "Authoritative syntax and semantic validation of CodeQL (QL) code via the CodeQL Language Server. Compiles the query and provides real-time diagnostics with precise error locations. Use this for accurate validation; for quick heuristic checks without compilation, use validate_codeql_query instead. Note: inline ql_code is evaluated as a virtual document and cannot resolve pack imports (e.g. `import javascript`). For validating queries with imports, use codeql_query_compile on the actual file instead.", { - log_level: z31.enum(["OFF", "ERROR", "WARN", "INFO", "DEBUG", "TRACE", "ALL"]).optional().describe("Language server log level"), - ql_code: z31.string().describe("The CodeQL (QL) code to evaluate for syntax and semantic errors"), - search_path: z31.string().optional().describe("Optional search path for CodeQL libraries"), - workspace_uri: z31.string().optional().describe("Optional workspace URI for context (defaults to ./ql directory)") + log_level: z33.enum(["OFF", "ERROR", "WARN", "INFO", "DEBUG", "TRACE", "ALL"]).optional().describe("Language server log level"), + ql_code: z33.string().describe("The CodeQL (QL) code to evaluate for syntax and semantic errors"), + search_path: z33.string().optional().describe("Optional search path for CodeQL libraries"), + workspace_uri: z33.string().optional().describe("Optional workspace URI for context (defaults to ./ql directory)") }, async ({ ql_code, workspace_uri, search_path, log_level }) => { try { @@ -7190,15 +7469,15 @@ async function lspReferences(params) { } // src/tools/lsp/lsp-tools.ts -import { z as z32 } from "zod"; +import { z as z34 } from "zod"; init_logger(); var lspParamsSchema = { - character: z32.number().int().min(0).describe("0-based character offset within the line"), - file_content: z32.string().optional().describe("Optional file content override (reads from disk if omitted)"), - file_path: z32.string().describe("Path to the CodeQL (.ql/.qll) file. Relative paths are resolved against the user workspace directory (see CODEQL_MCP_WORKSPACE)."), - line: z32.number().int().min(0).describe("0-based line number in the document"), - search_path: z32.string().optional().describe("Optional search path for CodeQL libraries"), - workspace_uri: z32.string().optional().describe("Optional workspace URI for context (defaults to ./ql directory)") + character: z34.number().int().min(0).describe("0-based character offset within the line"), + file_content: z34.string().optional().describe("Optional file content override (reads from disk if omitted)"), + file_path: z34.string().describe("Path to the CodeQL (.ql/.qll) file. Relative paths are resolved against the user workspace directory (see CODEQL_MCP_WORKSPACE)."), + line: z34.number().int().min(0).describe("0-based line number in the document"), + search_path: z34.string().optional().describe("Optional search path for CodeQL libraries"), + workspace_uri: z34.string().optional().describe("Optional workspace URI for context (defaults to ./ql directory)") }; function toHandlerParams(input) { return { @@ -7308,8 +7587,8 @@ function registerLSPTools(server) { } // src/resources/language-resources.ts -import { readFileSync as readFileSync6, existsSync as existsSync7 } from "fs"; -import { join as join12 } from "path"; +import { readFileSync as readFileSync8, existsSync as existsSync9 } from "fs"; +import { join as join14 } from "path"; // src/types/language-types.ts var LANGUAGE_RESOURCES = [ @@ -7369,12 +7648,12 @@ function getQLBasePath() { } function loadResourceContent(relativePath) { try { - const fullPath = join12(getQLBasePath(), relativePath); - if (!existsSync7(fullPath)) { + const fullPath = join14(getQLBasePath(), relativePath); + if (!existsSync9(fullPath)) { logger.warn(`Resource file not found: ${fullPath}`); return null; } - return readFileSync6(fullPath, "utf-8"); + return readFileSync8(fullPath, "utf-8"); } catch (error) { logger.error(`Error loading resource file ${relativePath}:`, error); return null; @@ -7496,19 +7775,19 @@ function registerLanguageResources(server) { } // src/prompts/workflow-prompts.ts -import { z as z33 } from "zod"; +import { z as z35 } from "zod"; import { basename as basename5 } from "path"; // src/prompts/prompt-loader.ts -import { readFileSync as readFileSync7 } from "fs"; -import { join as join13, dirname as dirname8 } from "path"; +import { readFileSync as readFileSync9 } from "fs"; +import { join as join15, dirname as dirname8 } from "path"; import { fileURLToPath as fileURLToPath3 } from "url"; var __filename3 = fileURLToPath3(import.meta.url); var __dirname3 = dirname8(__filename3); function loadPromptTemplate(promptFileName) { try { - const promptPath = join13(__dirname3, promptFileName); - return readFileSync7(promptPath, "utf-8"); + const promptPath = join15(__dirname3, promptFileName); + return readFileSync9(promptPath, "utf-8"); } catch (error) { return `Prompt template '${promptFileName}' not available: ${error instanceof Error ? error.message : "Unknown error"}`; } @@ -7540,49 +7819,49 @@ var SUPPORTED_LANGUAGES = [ "ruby", "swift" ]; -var testDrivenDevelopmentSchema = z33.object({ - language: z33.enum(SUPPORTED_LANGUAGES).describe("Programming language for the query"), - queryName: z33.string().optional().describe("Name of the query to develop") +var testDrivenDevelopmentSchema = z35.object({ + language: z35.enum(SUPPORTED_LANGUAGES).describe("Programming language for the query"), + queryName: z35.string().optional().describe("Name of the query to develop") }); -var toolsQueryWorkflowSchema = z33.object({ - database: z33.string().describe("Path to the CodeQL database"), - language: z33.enum(SUPPORTED_LANGUAGES).describe("Programming language for the tools queries"), - sourceFiles: z33.string().optional().describe('Comma-separated source file names for PrintAST (e.g., "main.js,utils.js")'), - sourceFunction: z33.string().optional().describe('Function name for PrintCFG or CallGraphFrom (e.g., "processData")'), - targetFunction: z33.string().optional().describe('Function name for CallGraphTo (e.g., "validate")') +var toolsQueryWorkflowSchema = z35.object({ + database: z35.string().describe("Path to the CodeQL database"), + language: z35.enum(SUPPORTED_LANGUAGES).describe("Programming language for the tools queries"), + sourceFiles: z35.string().optional().describe('Comma-separated source file names for PrintAST (e.g., "main.js,utils.js")'), + sourceFunction: z35.string().optional().describe('Function name for PrintCFG or CallGraphFrom (e.g., "processData")'), + targetFunction: z35.string().optional().describe('Function name for CallGraphTo (e.g., "validate")') }); -var workshopCreationWorkflowSchema = z33.object({ - queryPath: z33.string().describe("Path to the production-grade CodeQL query (.ql or .qlref)"), - language: z33.enum(SUPPORTED_LANGUAGES).describe("Programming language of the query"), - workshopName: z33.string().optional().describe("Name for the workshop directory"), - numStages: z33.coerce.number().optional().describe("Number of incremental stages (default: 4-8)") +var workshopCreationWorkflowSchema = z35.object({ + queryPath: z35.string().describe("Path to the production-grade CodeQL query (.ql or .qlref)"), + language: z35.enum(SUPPORTED_LANGUAGES).describe("Programming language of the query"), + workshopName: z35.string().optional().describe("Name for the workshop directory"), + numStages: z35.coerce.number().optional().describe("Number of incremental stages (default: 4-8)") }); -var qlTddBasicSchema = z33.object({ - language: z33.enum(SUPPORTED_LANGUAGES).optional().describe("Programming language for the query (optional)"), - queryName: z33.string().optional().describe("Name of the query to develop") +var qlTddBasicSchema = z35.object({ + language: z35.enum(SUPPORTED_LANGUAGES).optional().describe("Programming language for the query (optional)"), + queryName: z35.string().optional().describe("Name of the query to develop") }); -var qlTddAdvancedSchema = z33.object({ - database: z33.string().optional().describe("Path to the CodeQL database for analysis"), - language: z33.enum(SUPPORTED_LANGUAGES).optional().describe("Programming language for the query (optional)"), - queryName: z33.string().optional().describe("Name of the query to develop") +var qlTddAdvancedSchema = z35.object({ + database: z35.string().optional().describe("Path to the CodeQL database for analysis"), + language: z35.enum(SUPPORTED_LANGUAGES).optional().describe("Programming language for the query (optional)"), + queryName: z35.string().optional().describe("Name of the query to develop") }); -var sarifRankSchema = z33.object({ - queryId: z33.string().optional().describe("CodeQL query/rule identifier"), - sarifPath: z33.string().optional().describe("Path to the SARIF file to analyze") +var sarifRankSchema = z35.object({ + queryId: z35.string().optional().describe("CodeQL query/rule identifier"), + sarifPath: z35.string().optional().describe("Path to the SARIF file to analyze") }); -var explainCodeqlQuerySchema = z33.object({ - databasePath: z33.string().optional().describe("Optional path to a real CodeQL database for profiling"), - language: z33.enum(SUPPORTED_LANGUAGES).describe("Programming language of the query"), - queryPath: z33.string().describe("Path to the CodeQL query file (.ql or .qlref)") +var explainCodeqlQuerySchema = z35.object({ + databasePath: z35.string().optional().describe("Optional path to a real CodeQL database for profiling"), + language: z35.enum(SUPPORTED_LANGUAGES).describe("Programming language of the query"), + queryPath: z35.string().describe("Path to the CodeQL query file (.ql or .qlref)") }); -var documentCodeqlQuerySchema = z33.object({ - language: z33.enum(SUPPORTED_LANGUAGES).describe("Programming language of the query"), - queryPath: z33.string().describe("Path to the CodeQL query file (.ql or .qlref)") +var documentCodeqlQuerySchema = z35.object({ + language: z35.enum(SUPPORTED_LANGUAGES).describe("Programming language of the query"), + queryPath: z35.string().describe("Path to the CodeQL query file (.ql or .qlref)") }); -var qlLspIterativeDevelopmentSchema = z33.object({ - language: z33.enum(SUPPORTED_LANGUAGES).optional().describe("Programming language for the query"), - queryPath: z33.string().optional().describe("Path to the query file being developed"), - workspaceUri: z33.string().optional().describe("Workspace URI for LSP dependency resolution") +var qlLspIterativeDevelopmentSchema = z35.object({ + language: z35.enum(SUPPORTED_LANGUAGES).optional().describe("Programming language for the query"), + queryPath: z35.string().optional().describe("Path to the query file being developed"), + workspaceUri: z35.string().optional().describe("Workspace URI for LSP dependency resolution") }); var WORKFLOW_PROMPT_NAMES = [ "document_codeql_query", @@ -7969,7 +8248,7 @@ function buildWorkshopContext(queryPath, language, workshopName, numStages) { } // src/tools/monitoring-tools.ts -import { z as z35 } from "zod"; +import { z as z37 } from "zod"; import { randomUUID as randomUUID3 } from "crypto"; // ../node_modules/lowdb/lib/core/Low.js @@ -8003,7 +8282,7 @@ var Low = class { }; // ../node_modules/lowdb/lib/adapters/node/TextFile.js -import { readFileSync as readFileSync8, renameSync, writeFileSync as writeFileSync5 } from "node:fs"; +import { readFileSync as readFileSync10, renameSync, writeFileSync as writeFileSync5 } from "node:fs"; import path3 from "node:path"; var TextFileSync = class { #tempFilename; @@ -8016,7 +8295,7 @@ var TextFileSync = class { read() { let data; try { - data = readFileSync8(this.#filename, "utf-8"); + data = readFileSync10(this.#filename, "utf-8"); } catch (e) { if (e.code === "ENOENT") { return null; @@ -8067,135 +8346,135 @@ var JSONFileSync = class extends DataFileSync { // src/lib/session-data-manager.ts init_temp_dir(); import { mkdirSync as mkdirSync8, writeFileSync as writeFileSync6 } from "fs"; -import { join as join14 } from "path"; +import { join as join16 } from "path"; import { randomUUID as randomUUID2 } from "crypto"; // src/types/monitoring.ts -import { z as z34 } from "zod"; -var MCPCallRecordSchema = z34.object({ - callId: z34.string(), - timestamp: z34.string(), +import { z as z36 } from "zod"; +var MCPCallRecordSchema = z36.object({ + callId: z36.string(), + timestamp: z36.string(), // ISO timestamp - toolName: z34.string(), - parameters: z34.record(z34.any()), - result: z34.any(), - success: z34.boolean(), - duration: z34.number(), + toolName: z36.string(), + parameters: z36.record(z36.any()), + result: z36.any(), + success: z36.boolean(), + duration: z36.number(), // milliseconds - nextSuggestedTool: z34.string().optional() + nextSuggestedTool: z36.string().optional() }); -var TestExecutionRecordSchema = z34.object({ - executionId: z34.string(), - timestamp: z34.string(), - type: z34.enum(["compilation", "test_run", "database_build"]), - success: z34.boolean(), - details: z34.record(z34.any()), - metrics: z34.object({ - passRate: z34.number().optional(), - coverage: z34.number().optional(), - performance: z34.number().optional() +var TestExecutionRecordSchema = z36.object({ + executionId: z36.string(), + timestamp: z36.string(), + type: z36.enum(["compilation", "test_run", "database_build"]), + success: z36.boolean(), + details: z36.record(z36.any()), + metrics: z36.object({ + passRate: z36.number().optional(), + coverage: z36.number().optional(), + performance: z36.number().optional() }).optional() }); -var QualityScoreRecordSchema = z34.object({ - scoreId: z34.string(), - timestamp: z34.string(), - overallScore: z34.number().min(0).max(100), +var QualityScoreRecordSchema = z36.object({ + scoreId: z36.string(), + timestamp: z36.string(), + overallScore: z36.number().min(0).max(100), // 0-100 - dimensions: z34.object({ - syntacticCorrectness: z34.number().min(0).max(100), - testCoverageResults: z34.number().min(0).max(100), - documentationQuality: z34.number().min(0).max(100), - functionalCorrectness: z34.number().min(0).max(100) + dimensions: z36.object({ + syntacticCorrectness: z36.number().min(0).max(100), + testCoverageResults: z36.number().min(0).max(100), + documentationQuality: z36.number().min(0).max(100), + functionalCorrectness: z36.number().min(0).max(100) }), - grade: z34.enum(["A", "B", "C", "D", "F"]), - recommendations: z34.array(z34.string()) + grade: z36.enum(["A", "B", "C", "D", "F"]), + recommendations: z36.array(z36.string()) }); -var QueryStateSchema = z34.object({ - filesPresent: z34.array(z34.string()), - compilationStatus: z34.enum(["unknown", "success", "failed"]), - testStatus: z34.enum(["unknown", "passing", "failing", "no_tests"]), - documentationStatus: z34.enum(["unknown", "present", "missing", "incomplete"]), - lastActivity: z34.string() +var QueryStateSchema = z36.object({ + filesPresent: z36.array(z36.string()), + compilationStatus: z36.enum(["unknown", "success", "failed"]), + testStatus: z36.enum(["unknown", "passing", "failing", "no_tests"]), + documentationStatus: z36.enum(["unknown", "present", "missing", "incomplete"]), + lastActivity: z36.string() // ISO timestamp }); -var QueryDevelopmentSessionSchema = z34.object({ +var QueryDevelopmentSessionSchema = z36.object({ // Session Metadata - sessionId: z34.string(), - queryPath: z34.string(), - language: z34.string(), - queryType: z34.string().optional(), - description: z34.string().optional(), - startTime: z34.string(), + sessionId: z36.string(), + queryPath: z36.string(), + language: z36.string(), + queryType: z36.string().optional(), + description: z36.string().optional(), + startTime: z36.string(), // ISO timestamp - endTime: z34.string().optional(), + endTime: z36.string().optional(), // ISO timestamp - status: z34.enum(["active", "completed", "failed", "abandoned"]), + status: z36.enum(["active", "completed", "failed", "abandoned"]), // MCP Call History - mcpCalls: z34.array(MCPCallRecordSchema), + mcpCalls: z36.array(MCPCallRecordSchema), // Test Execution Records - testExecutions: z34.array(TestExecutionRecordSchema), + testExecutions: z36.array(TestExecutionRecordSchema), // Quality Metrics - qualityScores: z34.array(QualityScoreRecordSchema), + qualityScores: z36.array(QualityScoreRecordSchema), // Development State currentState: QueryStateSchema, - recommendations: z34.array(z34.string()), - nextSuggestedTool: z34.string().optional() + recommendations: z36.array(z36.string()), + nextSuggestedTool: z36.string().optional() }); -var SessionFilterSchema = z34.object({ - queryPath: z34.string().optional(), - status: z34.string().optional(), - dateRange: z34.tuple([z34.string(), z34.string()]).optional(), - language: z34.string().optional(), - queryType: z34.string().optional() +var SessionFilterSchema = z36.object({ + queryPath: z36.string().optional(), + status: z36.string().optional(), + dateRange: z36.tuple([z36.string(), z36.string()]).optional(), + language: z36.string().optional(), + queryType: z36.string().optional() }); -var ComparisonReportSchema = z34.object({ - sessionIds: z34.array(z34.string()), - dimensions: z34.array(z34.string()), - timestamp: z34.string(), - results: z34.record(z34.any()) +var ComparisonReportSchema = z36.object({ + sessionIds: z36.array(z36.string()), + dimensions: z36.array(z36.string()), + timestamp: z36.string(), + results: z36.record(z36.any()) }); -var AggregateReportSchema = z34.object({ +var AggregateReportSchema = z36.object({ filters: SessionFilterSchema, - timestamp: z34.string(), - totalSessions: z34.number(), - successRate: z34.number(), - averageQualityScore: z34.number(), - commonPatterns: z34.array(z34.string()), - recommendations: z34.array(z34.string()) + timestamp: z36.string(), + totalSessions: z36.number(), + successRate: z36.number(), + averageQualityScore: z36.number(), + commonPatterns: z36.array(z36.string()), + recommendations: z36.array(z36.string()) }); -var ExportResultSchema = z34.object({ - format: z34.enum(["json", "html", "markdown"]), - filename: z34.string(), - content: z34.string(), - timestamp: z34.string() +var ExportResultSchema = z36.object({ + format: z36.enum(["json", "html", "markdown"]), + filename: z36.string(), + content: z36.string(), + timestamp: z36.string() }); -var FunctionalTestResultSchema = z34.object({ - sessionId: z34.string(), - queryPath: z34.string(), - passed: z34.boolean(), - criteria: z34.record(z34.any()), - details: z34.record(z34.any()), - timestamp: z34.string() +var FunctionalTestResultSchema = z36.object({ + sessionId: z36.string(), + queryPath: z36.string(), + passed: z36.boolean(), + criteria: z36.record(z36.any()), + details: z36.record(z36.any()), + timestamp: z36.string() }); -var TestReportSchema = z34.object({ - sessionIds: z34.array(z34.string()), - criteria: z34.record(z34.any()), - timestamp: z34.string(), - overallPassRate: z34.number(), - results: z34.array(FunctionalTestResultSchema), - summary: z34.record(z34.any()) +var TestReportSchema = z36.object({ + sessionIds: z36.array(z36.string()), + criteria: z36.record(z36.any()), + timestamp: z36.string(), + overallPassRate: z36.number(), + results: z36.array(FunctionalTestResultSchema), + summary: z36.record(z36.any()) }); -var MonitoringConfigSchema = z34.object({ - storageLocation: z34.string().default(".ql-mcp-tracking/"), - autoTrackSessions: z34.boolean().default(true), - retentionDays: z34.number().default(90), - includeCallParameters: z34.boolean().default(true), - includeCallResults: z34.boolean().default(true), - maxActiveSessionsPerQuery: z34.number().default(3), - scoringFrequency: z34.enum(["per_call", "periodic", "manual"]).default("per_call"), - archiveCompletedSessions: z34.boolean().default(true), - enableRecommendations: z34.boolean().default(true), - enableMonitoringTools: z34.boolean().default(false) +var MonitoringConfigSchema = z36.object({ + storageLocation: z36.string().default(".ql-mcp-tracking/"), + autoTrackSessions: z36.boolean().default(true), + retentionDays: z36.number().default(90), + includeCallParameters: z36.boolean().default(true), + includeCallResults: z36.boolean().default(true), + maxActiveSessionsPerQuery: z36.number().default(3), + scoringFrequency: z36.enum(["per_call", "periodic", "manual"]).default("per_call"), + archiveCompletedSessions: z36.boolean().default(true), + enableRecommendations: z36.boolean().default(true), + enableMonitoringTools: z36.boolean().default(false) // Opt-in: session_* tools disabled by default for end-users }); @@ -8212,7 +8491,7 @@ var SessionDataManager = class { }); this.storageDir = this.config.storageLocation; this.ensureStorageDirectory(); - const adapter = new JSONFileSync(join14(this.storageDir, "sessions.json")); + const adapter = new JSONFileSync(join16(this.storageDir, "sessions.json")); this.db = new Low(adapter, { sessions: [] }); @@ -8244,9 +8523,9 @@ var SessionDataManager = class { mkdirSync8(this.storageDir, { recursive: true }); const subdirs = ["sessions-archive", "exports"]; for (const subdir of subdirs) { - mkdirSync8(join14(this.storageDir, subdir), { recursive: true }); + mkdirSync8(join16(this.storageDir, subdir), { recursive: true }); } - const configPath = join14(this.storageDir, "config.json"); + const configPath = join16(this.storageDir, "config.json"); try { writeFileSync6(configPath, JSON.stringify(this.config, null, 2), { flag: "wx" }); } catch (e) { @@ -8425,9 +8704,9 @@ var SessionDataManager = class { if (!session) return; const date = new Date(session.endTime || session.startTime); const monthDir = `${date.getFullYear()}-${String(date.getMonth() + 1).padStart(2, "0")}`; - const archiveDir = join14(this.storageDir, "sessions-archive", monthDir); + const archiveDir = join16(this.storageDir, "sessions-archive", monthDir); mkdirSync8(archiveDir, { recursive: true }); - const archiveFile = join14(archiveDir, `${sessionId}.json`); + const archiveFile = join16(archiveDir, `${sessionId}.json`); writeFileSync6(archiveFile, JSON.stringify(session, null, 2)); await this.db.read(); this.db.data.sessions = this.db.data.sessions.filter((s) => s.sessionId !== sessionId); @@ -8479,7 +8758,7 @@ var SessionDataManager = class { ...this.config, ...configUpdate }); - const configPath = join14(this.storageDir, "config.json"); + const configPath = join16(this.storageDir, "config.json"); writeFileSync6(configPath, JSON.stringify(this.config, null, 2)); logger.info("Updated monitoring configuration"); } @@ -8489,7 +8768,7 @@ function parseBoolEnv(envVar, defaultValue) { return envVar.toLowerCase() === "true" || envVar === "1"; } var sessionDataManager = new SessionDataManager({ - storageLocation: process.env.MONITORING_STORAGE_LOCATION || join14(getProjectTmpBase(), ".ql-mcp-tracking"), + storageLocation: process.env.MONITORING_STORAGE_LOCATION || join16(getProjectTmpBase(), ".ql-mcp-tracking"), enableMonitoringTools: parseBoolEnv(process.env.ENABLE_MONITORING_TOOLS, false) }); @@ -8519,8 +8798,8 @@ function registerSessionEndTool(server) { "session_end", "End a query development session with final status", { - sessionId: z35.string().describe("ID of the session to end"), - status: z35.enum(["completed", "failed", "abandoned"]).describe("Final status of the session") + sessionId: z37.string().describe("ID of the session to end"), + status: z37.enum(["completed", "failed", "abandoned"]).describe("Final status of the session") }, async ({ sessionId, status }) => { try { @@ -8564,7 +8843,7 @@ function registerSessionGetTool(server) { "session_get", "Get complete details of a specific query development session", { - sessionId: z35.string().describe("ID of the session to retrieve") + sessionId: z37.string().describe("ID of the session to retrieve") }, async ({ sessionId }) => { try { @@ -8608,11 +8887,11 @@ function registerSessionListTool(server) { "session_list", "List query development sessions with optional filtering", { - queryPath: z35.string().optional().describe("Filter by query path (partial match)"), - status: z35.string().optional().describe("Filter by session status"), - dateRange: z35.array(z35.string()).length(2).optional().describe("Filter by date range [start, end] (ISO timestamps)"), - language: z35.string().optional().describe("Filter by programming language"), - queryType: z35.string().optional().describe("Filter by query type") + queryPath: z37.string().optional().describe("Filter by query path (partial match)"), + status: z37.string().optional().describe("Filter by session status"), + dateRange: z37.array(z37.string()).length(2).optional().describe("Filter by date range [start, end] (ISO timestamps)"), + language: z37.string().optional().describe("Filter by programming language"), + queryType: z37.string().optional().describe("Filter by query type") }, async ({ queryPath, status, dateRange, language, queryType }) => { try { @@ -8668,11 +8947,11 @@ function registerSessionUpdateStateTool(server) { "session_update_state", "Update the current state of a query development session", { - sessionId: z35.string().describe("ID of the session to update"), - filesPresent: z35.array(z35.string()).optional().describe("List of files present in the query development"), - compilationStatus: z35.enum(["unknown", "success", "failed"]).optional().describe("Current compilation status"), - testStatus: z35.enum(["unknown", "passing", "failing", "no_tests"]).optional().describe("Current test status"), - documentationStatus: z35.enum(["unknown", "present", "missing", "incomplete"]).optional().describe("Documentation status") + sessionId: z37.string().describe("ID of the session to update"), + filesPresent: z37.array(z37.string()).optional().describe("List of files present in the query development"), + compilationStatus: z37.enum(["unknown", "success", "failed"]).optional().describe("Current compilation status"), + testStatus: z37.enum(["unknown", "passing", "failing", "no_tests"]).optional().describe("Current test status"), + documentationStatus: z37.enum(["unknown", "present", "missing", "incomplete"]).optional().describe("Documentation status") }, async ({ sessionId, filesPresent, compilationStatus, testStatus, documentationStatus }) => { try { @@ -8722,8 +9001,8 @@ function registerSessionGetCallHistoryTool(server) { "session_get_call_history", "Get MCP call history for a specific session", { - sessionId: z35.string().describe("ID of the session"), - limit: z35.number().optional().describe("Maximum number of calls to return (most recent first)") + sessionId: z37.string().describe("ID of the session"), + limit: z37.number().optional().describe("Maximum number of calls to return (most recent first)") }, async ({ sessionId, limit }) => { try { @@ -8775,8 +9054,8 @@ function registerSessionGetTestHistoryTool(server) { "session_get_test_history", "Get test execution history for a specific session", { - sessionId: z35.string().describe("ID of the session"), - limit: z35.number().optional().describe("Maximum number of test executions to return (most recent first)") + sessionId: z37.string().describe("ID of the session"), + limit: z37.number().optional().describe("Maximum number of test executions to return (most recent first)") }, async ({ sessionId, limit }) => { try { @@ -8828,8 +9107,8 @@ function registerSessionGetScoreHistoryTool(server) { "session_get_score_history", "Get quality score history for a specific session", { - sessionId: z35.string().describe("ID of the session"), - limit: z35.number().optional().describe("Maximum number of scores to return (most recent first)") + sessionId: z37.string().describe("ID of the session"), + limit: z37.number().optional().describe("Maximum number of scores to return (most recent first)") }, async ({ sessionId, limit }) => { try { @@ -8881,7 +9160,7 @@ function registerSessionCalculateCurrentScoreTool(server) { "session_calculate_current_score", "Calculate current quality score for a session based on its state", { - sessionId: z35.string().describe("ID of the session") + sessionId: z37.string().describe("ID of the session") }, async ({ sessionId }) => { try { @@ -8929,8 +9208,8 @@ function registerSessionsCompareTool(server) { "sessions_compare", "Compare multiple query development sessions across specified dimensions", { - sessionIds: z35.array(z35.string()).describe("Array of session IDs to compare"), - dimensions: z35.array(z35.string()).optional().describe("Specific dimensions to compare (default: all)") + sessionIds: z37.array(z37.string()).describe("Array of session IDs to compare"), + dimensions: z37.array(z37.string()).optional().describe("Specific dimensions to compare (default: all)") }, async ({ sessionIds, dimensions }) => { try { @@ -8978,11 +9257,11 @@ function registerSessionsAggregateTool(server) { "sessions_aggregate", "Generate aggregate insights from multiple sessions based on filters", { - queryPath: z35.string().optional().describe("Filter by query path (partial match)"), - status: z35.string().optional().describe("Filter by session status"), - dateRange: z35.array(z35.string()).length(2).optional().describe("Filter by date range [start, end] (ISO timestamps)"), - language: z35.string().optional().describe("Filter by programming language"), - queryType: z35.string().optional().describe("Filter by query type") + queryPath: z37.string().optional().describe("Filter by query path (partial match)"), + status: z37.string().optional().describe("Filter by session status"), + dateRange: z37.array(z37.string()).length(2).optional().describe("Filter by date range [start, end] (ISO timestamps)"), + language: z37.string().optional().describe("Filter by programming language"), + queryType: z37.string().optional().describe("Filter by query type") }, async ({ queryPath, status, dateRange, language, queryType }) => { try { @@ -9024,8 +9303,8 @@ function registerSessionsExportTool(server) { "sessions_export", "Export session data in specified format for external analysis", { - sessionIds: z35.array(z35.string()).describe("Array of session IDs to export"), - format: z35.enum(["json", "html", "markdown"]).optional().default("json").describe("Export format") + sessionIds: z37.array(z37.string()).describe("Array of session IDs to export"), + format: z37.enum(["json", "html", "markdown"]).optional().default("json").describe("Export format") }, async ({ sessionIds, format = "json" }) => { try { diff --git a/server/dist/codeql-development-mcp-server.js.map b/server/dist/codeql-development-mcp-server.js.map index c89954e2..1d9467e0 100644 --- a/server/dist/codeql-development-mcp-server.js.map +++ b/server/dist/codeql-development-mcp-server.js.map @@ -1,7 +1,7 @@ { "version": 3, - "sources": ["../src/utils/logger.ts", "../src/lib/server-config.ts", "../src/utils/package-paths.ts", "../src/utils/temp-dir.ts", "../src/utils/process-ready.ts", "../src/lib/language-server.ts", "../src/lib/query-server.ts", "../src/lib/cli-server.ts", "../src/lib/server-manager.ts", "../src/lib/cli-executor.ts", "../src/codeql-development-mcp-server.ts", "../src/tools/codeql/bqrs-decode.ts", "../src/lib/cli-tool-registry.ts", "../src/lib/query-results-evaluator.ts", "../src/lib/log-directory-manager.ts", "../src/tools/codeql/bqrs-info.ts", "../src/tools/codeql/bqrs-interpret.ts", "../src/tools/codeql/database-analyze.ts", "../src/tools/codeql/database-create.ts", "../src/tools/codeql/find-class-position.ts", "../src/tools/codeql/find-predicate-position.ts", "../src/tools/codeql/find-query-files.ts", "../src/lib/query-file-finder.ts", "../../node_modules/js-yaml/dist/js-yaml.mjs", "../src/lib/metadata-resolver.ts", "../src/tools/codeql/generate-log-summary.ts", "../src/tools/codeql/generate-query-help.ts", "../src/tools/codeql/pack-install.ts", "../src/tools/codeql/pack-ls.ts", "../src/tools/codeql/profile-codeql-query.ts", "../src/tools/codeql/query-compile.ts", "../src/tools/codeql/query-format.ts", "../src/tools/codeql/query-run.ts", "../src/tools/codeql/quick-evaluate.ts", "../src/tools/codeql/register-database.ts", "../src/tools/codeql/resolve-database.ts", "../src/tools/codeql/resolve-languages.ts", "../src/tools/codeql/resolve-library-path.ts", "../src/tools/codeql/resolve-metadata.ts", "../src/tools/codeql/resolve-qlref.ts", "../src/tools/codeql/resolve-queries.ts", "../src/tools/codeql/resolve-tests.ts", "../src/tools/codeql/test-accept.ts", "../src/tools/codeql/test-extract.ts", "../src/tools/codeql/test-run.ts", "../src/tools/codeql-tools.ts", "../src/lib/validation.ts", "../src/lib/query-scaffolding.ts", "../src/lib/resources.ts", "../src/tools/codeql-resources.ts", "../src/tools/lsp/lsp-diagnostics.ts", "../src/tools/lsp/lsp-server-helper.ts", "../src/tools/lsp/lsp-handlers.ts", "../src/tools/lsp/lsp-tools.ts", "../src/resources/language-resources.ts", "../src/types/language-types.ts", "../src/prompts/workflow-prompts.ts", "../src/prompts/prompt-loader.ts", "../src/tools/monitoring-tools.ts", "../../node_modules/lowdb/lib/core/Low.js", "../../node_modules/lowdb/lib/adapters/node/TextFile.js", "../../node_modules/lowdb/lib/adapters/node/DataFile.js", "../../node_modules/lowdb/lib/adapters/node/JSONFile.js", "../src/lib/session-data-manager.ts", "../src/types/monitoring.ts"], - "sourcesContent": ["/**\n * Simple logger utility.\n *\n * All log output is written to stderr. In stdio transport mode, stdout is\n * reserved exclusively for the MCP JSON-RPC protocol \u2014 any non-protocol\n * bytes on stdout would corrupt the message stream.\n */\nexport const logger = {\n info: (message: string, ...args: unknown[]) => {\n console.error(`[INFO] ${new Date().toISOString()} ${message}`, ...args);\n },\n error: (message: string, ...args: unknown[]) => {\n console.error(`[ERROR] ${new Date().toISOString()} ${message}`, ...args);\n },\n warn: (message: string, ...args: unknown[]) => {\n console.error(`[WARN] ${new Date().toISOString()} ${message}`, ...args);\n },\n debug: (message: string, ...args: unknown[]) => {\n if (process.env.DEBUG) {\n console.error(`[DEBUG] ${new Date().toISOString()} ${message}`, ...args);\n }\n },\n};\n", "/**\n * Configuration types for CodeQL background server processes.\n *\n * CodeQL provides three background server types:\n * 1. language-server \u2013 LSP-based QL validation (JSON-RPC over stdio)\n * 2. query-server2 \u2013 Query evaluation (custom protocol over stdio)\n * 3. cli-server \u2013 JVM reuse for CLI commands (custom protocol over stdio)\n *\n * Each server type has its own configuration options, but they share common\n * settings like searchPath and commonCaches.\n */\n\nimport { createHash } from 'crypto';\n\n/**\n * Server types supported by CodeQL.\n */\nexport type CodeQLServerType = 'cli' | 'language' | 'query';\n\n/**\n * Common configuration shared across all server types.\n */\nexport interface BaseServerConfig {\n /** Path to QL packs (like `codeql query compile --search-path`). */\n searchPath?: string;\n /** Location for cached data (compilation plans, downloaded packs). */\n commonCaches?: string;\n /** Directory for detailed logs. */\n logdir?: string;\n}\n\n/**\n * Configuration for the CodeQL Language Server.\n */\nexport interface LanguageServerConfig extends BaseServerConfig {\n /** Error checking mode. Default: ON_CHANGE */\n checkErrors?: 'EXPLICIT' | 'ON_CHANGE';\n /** Log level for the language server. */\n loglevel?: 'ALL' | 'DEBUG' | 'ERROR' | 'INFO' | 'OFF' | 'TRACE' | 'WARN';\n /** Single-threaded execution. */\n synchronous?: boolean;\n /** Verbosity level for progress. */\n verbosity?: 'errors' | 'progress' | 'progress+' | 'progress++' | 'progress+++' | 'warnings';\n}\n\n/**\n * Configuration for the CodeQL Query Server (query-server2).\n */\nexport interface QueryServerConfig extends BaseServerConfig {\n /** Thread count. 0 = one per core, -N = leave N cores free. */\n threads?: number;\n /** Query evaluation timeout in seconds. */\n timeout?: number;\n /** Maximum disk cache size in MB for intermediate results. */\n maxDiskCache?: number;\n /** Path for structured evaluator performance logs. */\n evaluatorLog?: string;\n /** Include tuple counts in evaluation logs. */\n tupleCounting?: boolean;\n /** Enable debug mode. */\n debug?: boolean;\n}\n\n/**\n * Configuration for the CodeQL CLI Server.\n */\nexport interface CLIServerConfig extends BaseServerConfig {\n // cli-server has fewer options \u2014 just commonCaches and logdir.\n}\n\n/**\n * Union of all server configurations (discriminated by usage context).\n */\nexport type ServerConfig = CLIServerConfig | LanguageServerConfig | QueryServerConfig;\n\n/**\n * Compute a deterministic hash for a server configuration.\n * Used to detect configuration changes that require a server restart.\n *\n * @param type - The server type.\n * @param config - The server configuration.\n * @returns A hex-encoded SHA-256 hash of the canonical JSON representation.\n */\nexport function computeConfigHash(type: CodeQLServerType, config: ServerConfig): string {\n // Deep-sort all keys to ensure deterministic serialization regardless of\n // property insertion order.\n const sortKeys = (_key: string, value: unknown): unknown => {\n if (value && typeof value === 'object' && !Array.isArray(value)) {\n const sorted: Record = {};\n for (const k of Object.keys(value as Record).sort()) {\n sorted[k] = (value as Record)[k];\n }\n return sorted;\n }\n return value;\n };\n const canonical = JSON.stringify({ config, type }, sortKeys);\n return createHash('sha256').update(canonical).digest('hex');\n}\n\n/**\n * Build command-line arguments for a language server from its configuration.\n */\nexport function buildLanguageServerArgs(config: LanguageServerConfig): string[] {\n const args: string[] = [\n 'execute', 'language-server',\n `--check-errors=${config.checkErrors ?? 'ON_CHANGE'}`,\n ];\n\n if (config.searchPath) {\n args.push(`--search-path=${config.searchPath}`);\n }\n if (config.commonCaches) {\n args.push(`--common-caches=${config.commonCaches}`);\n }\n if (config.logdir) {\n args.push(`--logdir=${config.logdir}`);\n }\n if (config.loglevel) {\n args.push(`--loglevel=${config.loglevel}`);\n }\n if (config.synchronous) {\n args.push('--synchronous');\n }\n if (config.verbosity) {\n args.push(`--verbosity=${config.verbosity}`);\n }\n\n return args;\n}\n\n/**\n * Build command-line arguments for a query server from its configuration.\n */\nexport function buildQueryServerArgs(config: QueryServerConfig): string[] {\n const args: string[] = [\n 'execute', 'query-server2',\n ];\n\n if (config.searchPath) {\n args.push(`--search-path=${config.searchPath}`);\n }\n if (config.commonCaches) {\n args.push(`--common-caches=${config.commonCaches}`);\n }\n if (config.logdir) {\n args.push(`--logdir=${config.logdir}`);\n }\n if (config.threads !== undefined) {\n args.push(`--threads=${config.threads}`);\n }\n if (config.timeout !== undefined) {\n args.push(`--timeout=${config.timeout}`);\n }\n if (config.maxDiskCache !== undefined) {\n args.push(`--max-disk-cache=${config.maxDiskCache}`);\n }\n if (config.evaluatorLog) {\n args.push(`--evaluator-log=${config.evaluatorLog}`);\n }\n if (config.debug) {\n args.push('--debug');\n args.push('--tuple-counting');\n } else if (config.tupleCounting) {\n args.push('--tuple-counting');\n }\n\n return args;\n}\n\n/**\n * Build command-line arguments for a CLI server from its configuration.\n */\nexport function buildCLIServerArgs(config: CLIServerConfig): string[] {\n const args: string[] = [\n 'execute', 'cli-server',\n ];\n\n if (config.commonCaches) {\n args.push(`--common-caches=${config.commonCaches}`);\n }\n if (config.logdir) {\n args.push(`--logdir=${config.logdir}`);\n }\n\n return args;\n}\n", "/**\n * Utilities for resolving filesystem paths relative to the server package root.\n *\n * The server can run from three different directory layouts:\n *\n * 1. **Source** (dev): `server/src/lib/` \u2192 packageRoot = `server/`\n * 2. **Bundle in monorepo** (dev/CI): `server/dist/` \u2192 packageRoot = `server/`\n * 3. **Bundle via npm** (production): `/dist/` \u2192 packageRoot = `/`\n *\n * In all three cases, the bundled QL tool query packs live at\n * `/ql//tools/src/`.\n *\n * The \"workspace root\" (monorepo root) is one level above packageRoot when\n * running from the monorepo checkout, and the packageRoot itself when running\n * from an npm install (no parent monorepo).\n */\n\nimport { dirname, resolve } from 'path';\nimport { existsSync, readFileSync } from 'fs';\nimport { fileURLToPath } from 'url';\n\nconst __filename = fileURLToPath(import.meta.url);\nconst __dirname = dirname(__filename);\n\n/**\n * Detect whether the current __dirname looks like source code (`src/lib` or\n * `src/utils`) vs a bundled flat output directory (`dist/`).\n *\n * Uses a tail-of-path check so that unrelated `/src/` segments earlier in the\n * install path (e.g. `~/src/project/node_modules/.../dist`) don't cause a\n * false positive.\n */\nfunction isRunningFromSource(dir: string): boolean {\n const normalized = dir.replace(/\\\\/g, '/');\n return /\\/src(\\/[^/]+)?$/.test(normalized);\n}\n\n/**\n * Get the server package root directory.\n *\n * - From source (`server/src/utils/`): up 2 levels \u2192 `server/`\n * - From bundle (`server/dist/` or `/dist/`): up 1 level \u2192 package root\n */\nexport function getPackageRootDir(currentDir: string = __dirname): string {\n return isRunningFromSource(currentDir)\n ? resolve(currentDir, '..', '..') // src/utils \u2192 server/\n : resolve(currentDir, '..'); // dist/ \u2192 package root\n}\n\n/**\n * Get the workspace root directory (monorepo root when applicable).\n *\n * If a `package.json` with `workspaces` exists one level above the package\n * root, we're in a monorepo and that parent is the workspace root. Otherwise,\n * the packageRoot itself is the workspace root (npm install scenario).\n */\nexport function getWorkspaceRootDir(packageRoot?: string): string {\n const pkgRoot = packageRoot ?? getPackageRootDir();\n const parentDir = resolve(pkgRoot, '..');\n\n // In the monorepo, the parent directory contains a package.json with workspaces\n try {\n const parentPkgPath = resolve(parentDir, 'package.json');\n if (existsSync(parentPkgPath)) {\n const parentPkg = JSON.parse(readFileSync(parentPkgPath, 'utf8'));\n if (parentPkg.workspaces) {\n return parentDir;\n }\n }\n } catch {\n // Not in a monorepo \u2014 fall through\n }\n\n return pkgRoot;\n}\n\n/**\n * Resolve the path to a tool query pack's source directory.\n *\n * @param language - CodeQL language identifier (e.g., \"javascript\", \"cpp\")\n * @param packageRoot - Override the package root (for testing)\n * @returns Absolute path to `ql//tools/src/`\n */\nexport function resolveToolQueryPackPath(language: string, packageRoot?: string): string {\n const pkgRoot = packageRoot ?? getPackageRootDir();\n return resolve(pkgRoot, 'ql', language, 'tools', 'src');\n}\n\n/**\n * Read the package version from the nearest package.json.\n *\n * Cached at first call so the file is read at most once per process.\n */\nlet _cachedVersion: string | undefined;\nexport function getPackageVersion(): string {\n if (_cachedVersion !== undefined) return _cachedVersion;\n try {\n const pkgPath = resolve(getPackageRootDir(), 'package.json');\n const pkg = JSON.parse(readFileSync(pkgPath, 'utf8'));\n _cachedVersion = pkg.version ?? '0.0.0';\n } catch {\n _cachedVersion = '0.0.0';\n }\n return _cachedVersion as string;\n}\n\n/**\n * Get the effective workspace directory for resolving user-supplied relative\n * paths (test directories, database paths, pack dirs, etc.).\n *\n * In a monorepo checkout the workspace root is the monorepo parent. In an\n * npm-installed layout, `workspaceRootDir` falls back to `packageRootDir`\n * which may be read-only and is not the user's project. In that case we\n * fall back to `process.cwd()` so that relative paths resolve against the\n * directory the user actually invoked the server from.\n *\n * Override with `CODEQL_MCP_WORKSPACE` for deterministic behavior.\n */\nexport function getUserWorkspaceDir(): string {\n if (process.env.CODEQL_MCP_WORKSPACE) {\n return process.env.CODEQL_MCP_WORKSPACE;\n }\n // When workspaceRootDir === packageRootDir we are NOT in a monorepo\n // (npm-installed), so fall back to process.cwd().\n if (workspaceRootDir === packageRootDir) {\n return process.cwd();\n }\n return workspaceRootDir;\n}\n\n// Pre-computed values for use throughout the server\nexport const packageRootDir = getPackageRootDir();\nexport const workspaceRootDir = getWorkspaceRootDir(packageRootDir);\n", "/**\n * Secure project-local temporary directory utilities.\n *\n * All temporary files are created under `/.tmp/` which is\n * `.gitignore`d. This avoids writing to the OS temp directory\n * (`os.tmpdir()` / `/tmp`), which is world-readable and triggers\n * CWE-377 / CWE-378 (js/insecure-temporary-file).\n */\n\nimport { mkdirSync, mkdtempSync } from 'fs';\nimport { isAbsolute, join, resolve } from 'path';\nimport { getPackageRootDir } from './package-paths';\n\n/**\n * Base directory for all project-local temporary data.\n *\n * Resolution order:\n * 1. `CODEQL_MCP_TMP_DIR` environment variable \u2014 for read-only package root\n * scenarios (e.g., npm global installs where the package directory is not\n * writable). Relative paths are resolved against process.cwd().\n * 2. `/.tmp` \u2014 default; excluded from version control.\n */\nconst PROJECT_TMP_BASE = process.env.CODEQL_MCP_TMP_DIR\n ? (isAbsolute(process.env.CODEQL_MCP_TMP_DIR) \n ? process.env.CODEQL_MCP_TMP_DIR \n : resolve(process.cwd(), process.env.CODEQL_MCP_TMP_DIR))\n : join(getPackageRootDir(), '.tmp');\n\n/**\n * Return the project-local `.tmp` base directory, creating it if needed.\n */\nexport function getProjectTmpBase(): string {\n mkdirSync(PROJECT_TMP_BASE, { recursive: true });\n return PROJECT_TMP_BASE;\n}\n\n/**\n * Create a unique temporary directory under the project `.tmp` root.\n *\n * Works identically to `fs.mkdtempSync(os.tmpdir(), prefix)` but is\n * scoped to the repository.\n *\n * @param prefix - Directory name prefix (e.g. `'codeql-external-'`).\n * @returns Absolute path to the newly created directory.\n */\nexport function createProjectTempDir(prefix: string): string {\n const base = getProjectTmpBase();\n return mkdtempSync(join(base, prefix));\n}\n\n/**\n * Return a deterministic subdirectory under `.tmp/`, creating it\n * if it does not already exist.\n *\n * Useful for well-known scratch areas such as `query-logs` or `quickeval`.\n *\n * @param name - Subdirectory name (e.g. `'query-logs'`).\n * @returns Absolute path to the subdirectory.\n */\nexport function getProjectTmpDir(name: string): string {\n const dir = join(getProjectTmpBase(), name);\n mkdirSync(dir, { recursive: true });\n return dir;\n}\n", "/**\n * Utility for waiting until a spawned child process is ready.\n *\n * CodeQL background servers (cli-server, query-server2, language-server) run\n * on the JVM and emit stderr log output once the JVM has initialised. Rather\n * than sleeping for a hard-coded duration \u2014 which is fragile on both fast and\n * slow machines \u2014 this helper resolves as soon as the first stderr output\n * arrives (indicating the JVM is alive), or when the maximum timeout expires.\n * It also rejects immediately if the process exits or errors before becoming\n * ready, giving callers a clear error instead of a silent hang.\n */\n\nimport { ChildProcess } from 'child_process';\nimport { clearTimeout, setTimeout } from 'timers';\nimport { logger } from './logger';\n\n/** Default maximum wait for a CodeQL server to become ready (30 s). */\nconst DEFAULT_READY_TIMEOUT_MS = 30_000;\n\n/**\n * Options for {@link waitForProcessReady}.\n */\nexport interface ProcessReadyOptions {\n /**\n * Maximum time in milliseconds to wait for the process to emit its first\n * stderr output. If the timeout is reached without a signal the promise\n * still resolves (best-effort) so the caller can attempt communication.\n *\n * Default: 30 000 ms.\n */\n timeoutMs?: number;\n}\n\n/**\n * Wait until a child process signals readiness.\n *\n * \"Ready\" is defined as any of:\n * 1. The process emits data on **stderr** (JVM startup log line).\n * 2. The process emits data on **stdout** (initial protocol message).\n * 3. The maximum timeout elapses (best-effort resolve).\n *\n * The promise **rejects** if the process emits an `error` event or exits\n * before any of the above conditions are met.\n *\n * @param child - The spawned child process.\n * @param name - A human-readable label for log messages.\n * @param opts - Optional configuration.\n */\nexport function waitForProcessReady(\n child: ChildProcess,\n name: string,\n opts?: ProcessReadyOptions,\n): Promise {\n const timeoutMs = opts?.timeoutMs ?? DEFAULT_READY_TIMEOUT_MS;\n\n return new Promise((resolve, reject) => {\n let settled = false;\n\n const cleanup = () => {\n settled = true;\n child.stderr?.removeListener('data', onStderr);\n child.stdout?.removeListener('data', onStdout);\n child.removeListener('error', onError);\n child.removeListener('exit', onExit);\n clearTimeout(timer);\n };\n\n const onStderr = () => {\n if (settled) return;\n logger.debug(`${name}: ready (stderr output detected)`);\n cleanup();\n resolve();\n };\n\n const onStdout = () => {\n if (settled) return;\n logger.debug(`${name}: ready (stdout output detected)`);\n cleanup();\n resolve();\n };\n\n const onError = (error: Error) => {\n if (settled) return;\n cleanup();\n reject(new Error(`${name} failed to start: ${error.message}`));\n };\n\n const onExit = (code: number | null) => {\n if (settled) return;\n cleanup();\n reject(new Error(`${name} exited before becoming ready (code: ${code})`));\n };\n\n const timer = setTimeout(() => {\n if (settled) return;\n logger.warn(`${name}: readiness timeout (${timeoutMs} ms) \u2014 proceeding anyway`);\n cleanup();\n resolve(); // best-effort: let the caller attempt communication\n }, timeoutMs);\n\n child.stderr?.on('data', onStderr);\n child.stdout?.on('data', onStdout);\n child.on('error', onError);\n child.on('exit', onExit);\n\n // If the process was dead before we even attached listeners, reject now\n if (child.killed || child.exitCode !== null) {\n cleanup();\n reject(new Error(`${name} is not running (exitCode: ${child.exitCode})`));\n }\n });\n}\n", "/**\n * CodeQL Language Server manager for LSP communication\n * Manages the lifecycle and communication with the CodeQL language server process\n */\n\nimport { spawn, ChildProcess } from 'child_process';\nimport { EventEmitter } from 'events';\nimport { setTimeout, clearTimeout } from 'timers';\nimport { pathToFileURL } from 'url';\nimport { delimiter, join } from 'path';\nimport { logger } from '../utils/logger';\nimport { getPackageVersion } from '../utils/package-paths';\nimport { getProjectTmpDir } from '../utils/temp-dir';\nimport { getResolvedCodeQLDir } from './cli-executor';\nimport { waitForProcessReady } from '../utils/process-ready';\n\nexport interface LSPMessage {\n jsonrpc: '2.0';\n id?: number | string;\n method: string;\n params?: unknown;\n result?: unknown;\n error?: {\n code: number;\n message: string;\n data?: unknown;\n };\n}\n\nexport interface Diagnostic {\n range: {\n start: { line: number; character: number };\n end: { line: number; character: number };\n };\n severity: number; // 1=Error, 2=Warning, 3=Information, 4=Hint\n source?: string;\n message: string;\n code?: string | number;\n}\n\nexport interface PublishDiagnosticsParams {\n uri: string;\n diagnostics: Diagnostic[];\n}\n\nexport interface LanguageServerOptions {\n searchPath?: string;\n logdir?: string;\n loglevel?: 'ALL' | 'DEBUG' | 'ERROR' | 'INFO' | 'OFF' | 'TRACE' | 'WARN';\n synchronous?: boolean;\n verbosity?: 'errors' | 'progress' | 'progress+' | 'progress++' | 'progress+++' | 'warnings';\n}\n\n/**\n * Position in a text document (0-based line and character).\n */\nexport interface LSPPosition {\n character: number;\n line: number;\n}\n\n/**\n * A range in a text document.\n */\nexport interface LSPRange {\n end: LSPPosition;\n start: LSPPosition;\n}\n\n/**\n * A location in a resource (file URI + range).\n */\nexport interface LSPLocation {\n range: LSPRange;\n uri: string;\n}\n\n/**\n * Identifies a text document by its URI.\n */\nexport interface TextDocumentIdentifier {\n uri: string;\n}\n\n/**\n * A text document position (document + position within it).\n */\nexport interface TextDocumentPositionParams {\n position: LSPPosition;\n textDocument: TextDocumentIdentifier;\n}\n\n/**\n * A completion item returned by the language server.\n */\nexport interface CompletionItem {\n detail?: string;\n documentation?: string | { kind: string; value: string };\n insertText?: string;\n kind?: number;\n label: string;\n sortText?: string;\n}\n\nexport class CodeQLLanguageServer extends EventEmitter {\n private server: ChildProcess | null = null;\n private messageId = 1;\n private pendingResponses = new Map void; reject: (_error: Error) => void }>();\n private isInitialized = false;\n private currentWorkspaceUri: string | undefined;\n private messageBuffer = '';\n\n constructor(private _options: LanguageServerOptions = {}) {\n super();\n }\n\n async start(): Promise {\n if (this.server) {\n throw new Error('Language server is already running');\n }\n\n logger.info('Starting CodeQL Language Server...');\n\n const args = [\n 'execute', 'language-server',\n '--check-errors=ON_CHANGE'\n ];\n\n // Add optional arguments\n if (this._options.searchPath) {\n args.push(`--search-path=${this._options.searchPath}`);\n }\n if (this._options.logdir) {\n args.push(`--logdir=${this._options.logdir}`);\n }\n if (this._options.loglevel) {\n args.push(`--loglevel=${this._options.loglevel}`);\n }\n if (this._options.synchronous) {\n args.push('--synchronous');\n }\n if (this._options.verbosity) {\n args.push(`--verbosity=${this._options.verbosity}`);\n }\n\n // Build environment with CODEQL_PATH directory prepended to PATH\n // (mirrors the approach in cli-executor.ts getSafeEnvironment).\n const spawnEnv = { ...process.env };\n const codeqlDir = getResolvedCodeQLDir();\n if (codeqlDir && spawnEnv.PATH) {\n spawnEnv.PATH = `${codeqlDir}${delimiter}${spawnEnv.PATH}`;\n } else if (codeqlDir) {\n spawnEnv.PATH = codeqlDir;\n }\n\n this.server = spawn('codeql', args, {\n stdio: ['pipe', 'pipe', 'pipe'],\n env: spawnEnv\n });\n\n this.server.stderr?.on('data', (data) => {\n logger.debug('CodeQL LS stderr:', data.toString());\n });\n\n this.server.stdout?.on('data', (data) => {\n this.handleStdout(data);\n });\n\n this.server.on('error', (error) => {\n logger.error('CodeQL Language Server error:', error);\n this.emit('error', error);\n });\n\n this.server.on('exit', (code) => {\n logger.info('CodeQL Language Server exited with code:', code);\n this.server = null;\n this.isInitialized = false;\n this.emit('exit', code);\n });\n\n // Wait for the JVM to initialise (resolves on first stderr/stdout output)\n await waitForProcessReady(this.server, 'CodeQL Language Server');\n }\n\n private handleStdout(data: Buffer): void {\n this.messageBuffer += data.toString();\n \n let headerEnd = this.messageBuffer.indexOf('\\r\\n\\r\\n');\n while (headerEnd !== -1) {\n const header = this.messageBuffer.substring(0, headerEnd);\n const contentLengthMatch = header.match(/Content-Length: (\\d+)/);\n \n if (contentLengthMatch) {\n const contentLength = parseInt(contentLengthMatch[1]);\n const messageStart = headerEnd + 4;\n const messageEnd = messageStart + contentLength;\n \n if (this.messageBuffer.length >= messageEnd) {\n const messageContent = this.messageBuffer.substring(messageStart, messageEnd);\n this.messageBuffer = this.messageBuffer.substring(messageEnd);\n \n try {\n const message: LSPMessage = JSON.parse(messageContent);\n this.handleMessage(message);\n } catch (error) {\n logger.error('Failed to parse LSP message:', error, messageContent);\n }\n \n headerEnd = this.messageBuffer.indexOf('\\r\\n\\r\\n');\n } else {\n break;\n }\n } else {\n logger.error('Invalid LSP header:', header);\n this.messageBuffer = '';\n break;\n }\n }\n }\n\n private handleMessage(message: LSPMessage): void {\n logger.debug('Received LSP message:', message);\n\n // Handle responses to our requests\n if (message.id !== undefined && this.pendingResponses.has(Number(message.id))) {\n const pending = this.pendingResponses.get(Number(message.id))!;\n this.pendingResponses.delete(Number(message.id));\n \n if (message.error) {\n pending.reject(new Error(`LSP Error: ${message.error.message}`));\n } else {\n pending.resolve(message.result);\n }\n return;\n }\n\n // Handle notifications from server\n if (message.method === 'textDocument/publishDiagnostics') {\n this.emit('diagnostics', message.params as PublishDiagnosticsParams);\n }\n }\n\n private sendMessage(message: LSPMessage): void {\n if (!this.server?.stdin) {\n throw new Error('Language server is not running');\n }\n\n const messageStr = JSON.stringify(message);\n const contentLength = Buffer.byteLength(messageStr, 'utf8');\n const header = `Content-Length: ${contentLength}\\r\\n\\r\\n`;\n const fullMessage = header + messageStr;\n\n logger.debug('Sending LSP message:', fullMessage);\n this.server.stdin.write(fullMessage);\n }\n\n private sendRequest(method: string, params?: unknown): Promise {\n const id = this.messageId++;\n const message: LSPMessage = {\n jsonrpc: '2.0',\n id,\n method,\n params\n };\n\n return new Promise((resolve, reject) => {\n // Wrap resolve/reject to clear the timer when the promise settles.\n const timer = setTimeout(() => {\n if (this.pendingResponses.has(id)) {\n this.pendingResponses.delete(id);\n reject(new Error(`LSP request timeout for method: ${method}`));\n }\n }, 60_000); // 60 second timeout (Windows CI cold JVM can exceed 30s)\n\n this.pendingResponses.set(id, {\n reject: (err: Error) => { clearTimeout(timer); reject(err); },\n resolve: (val: unknown) => { clearTimeout(timer); resolve(val); },\n });\n this.sendMessage(message);\n });\n }\n\n private sendNotification(method: string, params?: unknown): void {\n const message: LSPMessage = {\n jsonrpc: '2.0',\n method,\n params\n };\n this.sendMessage(message);\n }\n\n /**\n * Initialize the language server with an optional workspace URI.\n *\n * If the server is already initialized with a different workspace, a\n * `workspace/didChangeWorkspaceFolders` notification is sent to update\n * the workspace context instead of requiring a full restart.\n */\n async initialize(workspaceUri?: string): Promise {\n if (this.isInitialized) {\n // If workspace changed, notify the server\n if (workspaceUri && workspaceUri !== this.currentWorkspaceUri) {\n await this.updateWorkspace(workspaceUri);\n }\n return;\n }\n\n logger.info('Initializing CodeQL Language Server...');\n\n const initParams = {\n processId: process.pid,\n clientInfo: {\n name: 'codeql-development-mcp-server',\n version: getPackageVersion()\n },\n capabilities: {\n textDocument: {\n completion: { completionItem: { snippetSupport: false } },\n definition: {},\n publishDiagnostics: {},\n references: {},\n synchronization: {\n didClose: true,\n didChange: true,\n didOpen: true,\n },\n },\n workspace: {\n workspaceFolders: true,\n },\n }\n };\n\n if (workspaceUri) {\n (initParams as unknown as { workspaceFolders: unknown[] }).workspaceFolders = [{\n uri: workspaceUri,\n name: 'codeql-workspace'\n }];\n }\n\n await this.sendRequest('initialize', initParams);\n this.sendNotification('initialized', {});\n\n this.currentWorkspaceUri = workspaceUri;\n this.isInitialized = true;\n logger.info('CodeQL Language Server initialized successfully');\n }\n\n /**\n * Update the workspace folders on a running, initialized server.\n */\n private async updateWorkspace(newUri: string): Promise {\n logger.info(`Updating workspace from ${this.currentWorkspaceUri} to ${newUri}`);\n\n const removed = this.currentWorkspaceUri\n ? [{ uri: this.currentWorkspaceUri, name: 'codeql-workspace' }]\n : [];\n\n this.sendNotification('workspace/didChangeWorkspaceFolders', {\n event: {\n added: [{ uri: newUri, name: 'codeql-workspace' }],\n removed,\n },\n });\n\n this.currentWorkspaceUri = newUri;\n }\n\n /**\n * Get the current workspace URI.\n */\n getWorkspaceUri(): string | undefined {\n return this.currentWorkspaceUri;\n }\n\n async evaluateQL(qlCode: string, uri?: string): Promise {\n if (!this.isInitialized) {\n throw new Error('Language server is not initialized');\n }\n\n // Default to a project-local virtual URI rather than /tmp\n const documentUri = uri || pathToFileURL(join(getProjectTmpDir('lsp-eval'), 'eval.ql')).href;\n\n return new Promise((resolve, reject) => {\n let diagnosticsReceived = false;\n const timeout = setTimeout(() => {\n if (!diagnosticsReceived) {\n this.removeListener('diagnostics', diagnosticsHandler);\n reject(new Error('Timeout waiting for diagnostics'));\n }\n }, 90_000); // 90s \u2014 first call triggers JVM start + compilation; Windows CI is slow\n\n // Listen for diagnostics\n const diagnosticsHandler = (params: PublishDiagnosticsParams) => {\n if (params.uri === documentUri) {\n diagnosticsReceived = true;\n clearTimeout(timeout);\n this.removeListener('diagnostics', diagnosticsHandler);\n\n // Close the document\n this.sendNotification('textDocument/didClose', {\n textDocument: { uri: documentUri }\n });\n\n resolve(params.diagnostics);\n }\n };\n\n this.on('diagnostics', diagnosticsHandler);\n\n // Open the document with the QL code\n this.sendNotification('textDocument/didOpen', {\n textDocument: {\n uri: documentUri,\n languageId: 'ql',\n version: 1,\n text: qlCode\n }\n });\n });\n }\n\n // ---- LSP feature methods (issue #1) ----\n\n /**\n * Get code completions at a position in a document.\n */\n async getCompletions(params: TextDocumentPositionParams): Promise {\n if (!this.isInitialized) {\n throw new Error('Language server is not initialized');\n }\n if (!this.isRunning()) {\n throw new Error('Language server process is not running');\n }\n const result = await this.sendRequest('textDocument/completion', params);\n // The result may be a CompletionList or CompletionItem[]\n if (result && typeof result === 'object' && 'items' in (result as object)) {\n return (result as { items: CompletionItem[] }).items;\n }\n return (result as CompletionItem[]) || [];\n }\n\n /**\n * Find the definition(s) of a symbol at a position.\n */\n async getDefinition(params: TextDocumentPositionParams): Promise {\n if (!this.isInitialized) {\n throw new Error('Language server is not initialized');\n }\n if (!this.isRunning()) {\n throw new Error('Language server process is not running');\n }\n const result = await this.sendRequest('textDocument/definition', params);\n return this.normalizeLocations(result);\n }\n\n /**\n * Find all references to a symbol at a position.\n */\n async getReferences(params: TextDocumentPositionParams & { context?: { includeDeclaration: boolean } }): Promise {\n if (!this.isInitialized) {\n throw new Error('Language server is not initialized');\n }\n if (!this.isRunning()) {\n throw new Error('Language server process is not running');\n }\n const result = await this.sendRequest('textDocument/references', {\n ...params,\n context: params.context ?? { includeDeclaration: true },\n });\n return this.normalizeLocations(result);\n }\n\n /**\n * Open a text document in the language server.\n * The document must be opened before requesting completions, definitions, etc.\n */\n openDocument(uri: string, text: string, languageId = 'ql', version = 1): void {\n if (!this.isInitialized) {\n throw new Error('Language server is not initialized');\n }\n this.sendNotification('textDocument/didOpen', {\n textDocument: { uri, languageId, version, text },\n });\n }\n\n /**\n * Close a text document in the language server.\n */\n closeDocument(uri: string): void {\n if (!this.isInitialized) {\n throw new Error('Language server is not initialized');\n }\n this.sendNotification('textDocument/didClose', {\n textDocument: { uri },\n });\n }\n\n /**\n * Normalize a definition/references/implementation result to Location[].\n * The LSP spec allows Location | Location[] | LocationLink[].\n */\n private normalizeLocations(result: unknown): LSPLocation[] {\n if (!result) return [];\n if (Array.isArray(result)) {\n return result.map((item) => {\n // LocationLink has targetUri/targetRange\n if ('targetUri' in item) {\n return { uri: item.targetUri, range: item.targetRange } as LSPLocation;\n }\n return item as LSPLocation;\n });\n }\n // Single Location\n if (typeof result === 'object' && 'uri' in (result as object)) {\n return [result as LSPLocation];\n }\n return [];\n }\n\n async shutdown(): Promise {\n if (!this.server) {\n return;\n }\n\n logger.info('Shutting down CodeQL Language Server...');\n\n try {\n await this.sendRequest('shutdown', {});\n if (this.server) {\n this.sendNotification('exit', {});\n }\n } catch (error) {\n logger.warn('Error during graceful shutdown:', error);\n }\n\n // Force kill if needed\n await new Promise((resolve) => {\n const timer = setTimeout(() => {\n if (this.server) {\n this.server.kill('SIGTERM');\n }\n resolve();\n }, 1000);\n\n if (this.server) {\n this.server.once('exit', () => {\n clearTimeout(timer);\n this.server = null;\n resolve();\n });\n } else {\n clearTimeout(timer);\n resolve();\n }\n });\n\n this.isInitialized = false;\n }\n\n isRunning(): boolean {\n return this.server !== null && !this.server.killed;\n }\n}", "/**\n * CodeQL Query Server (query-server2) client.\n *\n * Manages a long-lived `codeql execute query-server2` process that evaluates\n * queries using a custom JSON-RPC protocol over stdio. Reusing the server\n * avoids repeated JVM startup for each query evaluation.\n *\n * Protocol: The query-server2 uses JSON-RPC with Content-Length headers\n * (same framing as LSP) over stdin/stdout.\n */\n\nimport { ChildProcess, spawn } from 'child_process';\nimport { delimiter } from 'path';\nimport { EventEmitter } from 'events';\nimport { clearTimeout, setTimeout } from 'timers';\nimport { buildQueryServerArgs, QueryServerConfig } from './server-config';\nimport { getResolvedCodeQLDir } from './cli-executor';\nimport { logger } from '../utils/logger';\nimport { waitForProcessReady } from '../utils/process-ready';\n\n/**\n * A pending request awaiting a response from the query server.\n */\ninterface PendingRequest {\n reject: (_error: Error) => void;\n resolve: (_value: unknown) => void;\n}\n\n/**\n * Client for the CodeQL query-server2 process.\n *\n * Spawns `codeql execute query-server2` and communicates over stdin/stdout\n * using JSON-RPC with Content-Length framing.\n */\nexport class CodeQLQueryServer extends EventEmitter {\n private messageBuffer = '';\n private messageId = 1;\n private pendingRequests = new Map();\n private process: ChildProcess | null = null;\n private readonly config: QueryServerConfig;\n\n constructor(config: QueryServerConfig) {\n super();\n this.config = config;\n }\n\n /**\n * Start the query-server2 process.\n */\n async start(): Promise {\n if (this.process) {\n throw new Error('Query server is already running');\n }\n\n logger.info('Starting CodeQL Query Server (query-server2)...');\n\n const args = buildQueryServerArgs(this.config);\n\n // Build environment with CODEQL_PATH directory prepended to PATH\n const spawnEnv = { ...process.env };\n const codeqlDir = getResolvedCodeQLDir();\n if (codeqlDir && spawnEnv.PATH) {\n spawnEnv.PATH = `${codeqlDir}${delimiter}${spawnEnv.PATH}`;\n } else if (codeqlDir) {\n spawnEnv.PATH = codeqlDir;\n }\n\n this.process = spawn('codeql', args, {\n stdio: ['pipe', 'pipe', 'pipe'],\n env: spawnEnv,\n });\n\n this.process.stderr?.on('data', (data: Buffer) => {\n logger.debug('QueryServer2 stderr:', data.toString());\n });\n\n this.process.stdout?.on('data', (data: Buffer) => {\n this.handleStdout(data);\n });\n\n this.process.on('error', (error: Error) => {\n logger.error('Query server process error:', error);\n this.emit('error', error);\n });\n\n this.process.on('exit', (code: number | null) => {\n logger.info(`Query server exited with code: ${code}`);\n this.rejectAllPending(new Error(`Query server exited with code: ${code}`));\n this.process = null;\n this.emit('exit', code);\n });\n\n // Wait for the JVM to initialise (resolves on first stderr/stdout output)\n await waitForProcessReady(this.process, 'CodeQL Query Server');\n logger.info('CodeQL Query Server started');\n }\n\n /**\n * Send a request to the query server and await the response.\n *\n * @param method - The JSON-RPC method name.\n * @param params - The method parameters.\n * @param timeoutMs - Request timeout in milliseconds (default: 300000 = 5 min).\n * @returns The result from the server.\n */\n sendRequest(method: string, params?: unknown, timeoutMs = 300_000): Promise {\n const id = this.messageId++;\n const message = {\n id,\n jsonrpc: '2.0' as const,\n method,\n params,\n };\n\n return new Promise((resolve, reject) => {\n this.pendingRequests.set(id, { reject, resolve });\n\n try {\n this.sendRaw(message);\n } catch (error) {\n // Clean up immediately \u2014 sendRaw() failed so no response will arrive.\n this.pendingRequests.delete(id);\n reject(error instanceof Error ? error : new Error(String(error)));\n return;\n }\n\n const timer = setTimeout(() => {\n if (this.pendingRequests.has(id)) {\n this.pendingRequests.delete(id);\n reject(new Error(`Query server request timeout for method: ${method}`));\n }\n }, timeoutMs);\n\n // Clear the timeout when the promise settles\n const originalResolve = resolve;\n const originalReject = reject;\n const wrapped = {\n reject: (err: Error) => { clearTimeout(timer); originalReject(err); },\n resolve: (val: unknown) => { clearTimeout(timer); originalResolve(val); },\n };\n this.pendingRequests.set(id, wrapped);\n });\n }\n\n /**\n * Gracefully shut down the query server.\n */\n async shutdown(): Promise {\n if (!this.process) {\n return;\n }\n\n logger.info('Shutting down CodeQL Query Server...');\n\n try {\n await this.sendRequest('shutdown', {}, 5000);\n } catch (error) {\n logger.warn('Error during query server graceful shutdown:', error);\n }\n\n // Force kill if process lingers\n await new Promise((resolve) => {\n const timer = setTimeout(() => {\n if (this.process) {\n this.process.kill('SIGTERM');\n this.process = null;\n }\n resolve();\n }, 2000);\n\n if (this.process) {\n this.process.once('exit', () => {\n clearTimeout(timer);\n this.process = null;\n resolve();\n });\n } else {\n clearTimeout(timer);\n resolve();\n }\n });\n }\n\n /**\n * Whether the query server process is running.\n */\n isRunning(): boolean {\n return this.process !== null && !this.process.killed;\n }\n\n // ---- private helpers ----\n\n private handleStdout(data: Buffer): void {\n this.messageBuffer += data.toString();\n\n let headerEnd = this.messageBuffer.indexOf('\\r\\n\\r\\n');\n while (headerEnd !== -1) {\n const header = this.messageBuffer.substring(0, headerEnd);\n const contentLengthMatch = header.match(/Content-Length: (\\d+)/);\n\n if (contentLengthMatch) {\n const contentLength = parseInt(contentLengthMatch[1]);\n const messageStart = headerEnd + 4;\n const messageEnd = messageStart + contentLength;\n\n if (this.messageBuffer.length >= messageEnd) {\n const messageContent = this.messageBuffer.substring(messageStart, messageEnd);\n this.messageBuffer = this.messageBuffer.substring(messageEnd);\n\n try {\n const message = JSON.parse(messageContent);\n this.handleMessage(message);\n } catch (error) {\n logger.error('Failed to parse query server message:', error);\n }\n\n headerEnd = this.messageBuffer.indexOf('\\r\\n\\r\\n');\n } else {\n break;\n }\n } else {\n logger.error('Invalid query server header:', header);\n this.messageBuffer = '';\n break;\n }\n }\n }\n\n private handleMessage(message: { error?: { message: string }; id?: number; method?: string; params?: unknown; result?: unknown }): void {\n logger.debug('QueryServer2 message:', message);\n\n // Handle responses\n if (message.id !== undefined && this.pendingRequests.has(Number(message.id))) {\n const pending = this.pendingRequests.get(Number(message.id))!;\n this.pendingRequests.delete(Number(message.id));\n\n if (message.error) {\n pending.reject(new Error(`Query server error: ${message.error.message}`));\n } else {\n pending.resolve(message.result);\n }\n return;\n }\n\n // Handle notifications (progress, etc.)\n if (message.method) {\n this.emit('notification', { method: message.method, params: message.params });\n }\n }\n\n private rejectAllPending(error: Error): void {\n for (const [id, pending] of this.pendingRequests) {\n pending.reject(error);\n this.pendingRequests.delete(id);\n }\n }\n\n private sendRaw(message: object): void {\n if (!this.process?.stdin) {\n throw new Error('Query server is not running');\n }\n\n const body = JSON.stringify(message);\n const contentLength = Buffer.byteLength(body, 'utf8');\n const frame = `Content-Length: ${contentLength}\\r\\n\\r\\n${body}`;\n this.process.stdin.write(frame);\n }\n}\n", "/**\n * CodeQL CLI Server client.\n *\n * Manages a long-lived `codeql execute cli-server` process that executes CLI\n * commands without repeated JVM startup overhead. Commands are serialized as\n * JSON arrays followed by a NUL byte, and responses are NUL-terminated JSON.\n *\n * Inspired by the `CodeQLCliServer` class in github/vscode-codeql.\n */\n\nimport { ChildProcess, spawn } from 'child_process';\nimport { delimiter } from 'path';\nimport { EventEmitter } from 'events';\nimport { clearTimeout, setTimeout } from 'timers';\nimport { buildCLIServerArgs, CLIServerConfig } from './server-config';\nimport { getResolvedCodeQLDir } from './cli-executor';\nimport { logger } from '../utils/logger';\nimport { waitForProcessReady } from '../utils/process-ready';\n\n/**\n * A queued command waiting to be sent to the CLI server.\n */\ninterface QueuedCommand {\n args: string[];\n reject: (_error: Error) => void;\n resolve: (_value: string) => void;\n}\n\n/**\n * Client for the CodeQL CLI Server process.\n *\n * The cli-server uses a simple NUL-delimited protocol:\n * - **Request**: JSON array of command arguments, followed by a NUL byte.\n * - **Response**: command stdout, terminated by a NUL byte on stdout.\n * stderr is forwarded as-is.\n */\nexport class CodeQLCLIServer extends EventEmitter {\n private commandInProgress = false;\n private commandQueue: Array<() => void> = [];\n private readonly config: CLIServerConfig;\n private currentReject: ((_error: Error) => void) | null = null;\n private currentResolve: ((_value: string) => void) | null = null;\n private nullBuffer = Buffer.alloc(1);\n private process: ChildProcess | null = null;\n private stdoutBuffer = '';\n\n constructor(config: CLIServerConfig) {\n super();\n this.config = config;\n }\n\n /**\n * Start the cli-server process.\n */\n async start(): Promise {\n if (this.process) {\n throw new Error('CLI server is already running');\n }\n\n logger.info('Starting CodeQL CLI Server...');\n\n const args = buildCLIServerArgs(this.config);\n\n const spawnEnv = { ...process.env };\n const codeqlDir = getResolvedCodeQLDir();\n if (codeqlDir && spawnEnv.PATH) {\n spawnEnv.PATH = `${codeqlDir}${delimiter}${spawnEnv.PATH}`;\n } else if (codeqlDir) {\n spawnEnv.PATH = codeqlDir;\n }\n\n this.process = spawn('codeql', args, {\n stdio: ['pipe', 'pipe', 'pipe'],\n env: spawnEnv,\n });\n\n this.process.stdout?.on('data', (data: Buffer) => {\n this.handleStdout(data);\n });\n\n this.process.stderr?.on('data', (data: Buffer) => {\n logger.debug('CLIServer stderr:', data.toString());\n });\n\n this.process.on('error', (error: Error) => {\n logger.error('CLI server process error:', error);\n if (this.currentReject) {\n this.currentReject(error);\n this.currentReject = null;\n this.currentResolve = null;\n }\n this.emit('error', error);\n });\n\n this.process.on('exit', (code: number | null) => {\n logger.info(`CLI server exited with code: ${code}`);\n if (this.currentReject) {\n this.currentReject(new Error(`CLI server exited unexpectedly with code: ${code}`));\n this.currentReject = null;\n this.currentResolve = null;\n }\n this.process = null;\n this.emit('exit', code);\n });\n\n // Wait for the JVM to initialise (resolves on first stderr/stdout output)\n await waitForProcessReady(this.process, 'CodeQL CLI Server');\n logger.info('CodeQL CLI Server started');\n }\n\n /**\n * Run a CodeQL CLI command through the persistent server.\n *\n * Commands are serialized and queued; only one command runs at a time.\n *\n * @param args - The full command arguments (e.g. `['resolve', 'qlpacks']`).\n * @returns The stdout output from the command.\n */\n runCommand(args: string[]): Promise {\n return new Promise((resolve, reject) => {\n const execute = () => {\n this.executeCommand({ args, reject, resolve });\n };\n\n if (this.commandInProgress) {\n this.commandQueue.push(execute);\n } else {\n execute();\n }\n });\n }\n\n /**\n * Gracefully shut down the CLI server.\n */\n async shutdown(): Promise {\n if (!this.process) {\n return;\n }\n\n logger.info('Shutting down CodeQL CLI Server...');\n\n try {\n // Send shutdown command\n this.process.stdin?.write(JSON.stringify(['shutdown']), 'utf8');\n this.process.stdin?.write(this.nullBuffer);\n } catch (error) {\n logger.warn('Error during CLI server shutdown request:', error);\n }\n\n // Give it a moment, then force kill\n await new Promise((resolve) => {\n const timer = setTimeout(() => {\n if (this.process) {\n this.process.kill('SIGTERM');\n this.process = null;\n }\n resolve();\n }, 2000);\n\n if (this.process) {\n this.process.once('exit', () => {\n clearTimeout(timer);\n this.process = null;\n resolve();\n });\n } else {\n clearTimeout(timer);\n resolve();\n }\n });\n\n this.commandInProgress = false;\n this.commandQueue = [];\n logger.info('CodeQL CLI Server stopped');\n }\n\n /**\n * Whether the CLI server process is running.\n */\n isRunning(): boolean {\n return this.process !== null && !this.process.killed;\n }\n\n // ---- private helpers ----\n\n private executeCommand(cmd: QueuedCommand): void {\n if (!this.process?.stdin) {\n cmd.reject(new Error('CLI server is not running'));\n return;\n }\n\n this.commandInProgress = true;\n this.currentResolve = cmd.resolve;\n this.currentReject = cmd.reject;\n\n try {\n this.process.stdin.write(JSON.stringify(cmd.args), 'utf8');\n this.process.stdin.write(this.nullBuffer);\n } catch (error) {\n this.commandInProgress = false;\n this.currentResolve = null;\n this.currentReject = null;\n cmd.reject(error instanceof Error ? error : new Error(String(error)));\n this.runNext();\n }\n }\n\n private handleStdout(data: Buffer): void {\n this.stdoutBuffer += data.toString();\n\n // Process all NUL-delimited responses in the buffer\n let nulIndex = this.stdoutBuffer.indexOf('\\0');\n while (nulIndex !== -1) {\n const result = this.stdoutBuffer.substring(0, nulIndex);\n this.stdoutBuffer = this.stdoutBuffer.substring(nulIndex + 1);\n\n if (this.currentResolve) {\n this.currentResolve(result);\n this.currentResolve = null;\n this.currentReject = null;\n }\n\n this.commandInProgress = false;\n this.runNext();\n\n nulIndex = this.stdoutBuffer.indexOf('\\0');\n }\n }\n\n private runNext(): void {\n const next = this.commandQueue.shift();\n if (next) {\n next();\n }\n }\n}\n", "/**\n * CodeQL Server Manager\n *\n * Manages the lifecycle of CodeQL background server processes:\n * - language-server (LSP-based QL validation)\n * - query-server2 (query evaluation)\n * - cli-server (JVM reuse for CLI commands)\n *\n * Servers are keyed by a hash of their configuration. When a caller requests\n * a server with a different configuration, the old server is shut down and a\n * new one is started. Session-specific cache directories provide isolation.\n */\n\nimport { mkdirSync } from 'fs';\nimport { join } from 'path';\nimport { randomUUID } from 'crypto';\nimport {\n CLIServerConfig,\n CodeQLServerType,\n computeConfigHash,\n LanguageServerConfig,\n QueryServerConfig,\n ServerConfig,\n} from './server-config';\nimport { CodeQLLanguageServer } from './language-server';\nimport { CodeQLQueryServer } from './query-server';\nimport { CodeQLCLIServer } from './cli-server';\nimport { getProjectTmpDir } from '../utils/temp-dir';\nimport { logger } from '../utils/logger';\n\n/**\n * Entry in the managed servers map.\n */\ninterface ManagedServer {\n configHash: string;\n server: CodeQLCLIServer | CodeQLLanguageServer | CodeQLQueryServer;\n sessionId: string;\n type: CodeQLServerType;\n}\n\n/**\n * Options for creating a session-specific cache layout.\n */\nexport interface SessionCacheOptions {\n /** Override the session ID (defaults to a random UUID). */\n sessionId?: string;\n}\n\n/**\n * Manages CodeQL background server processes with config-aware caching.\n *\n * Callers should use `getLanguageServer()`, `getQueryServer()`, or\n * `getCLIServer()` to obtain a running server. If the requested\n * configuration differs from the currently running server of that type, the\n * old server is stopped and replaced.\n */\nexport class CodeQLServerManager {\n /** Keyed by `CodeQLServerType` \u2014 at most one per type at a time. */\n private servers = new Map();\n\n /** In-flight `getOrRestart` promises, keyed by server type, to serialize concurrent calls. */\n private pendingStarts = new Map>();\n\n /** The session ID used for cache isolation. */\n private sessionId: string;\n\n /** Root directory for session-specific caches. */\n private sessionCacheDir: string;\n\n constructor(options?: SessionCacheOptions) {\n this.sessionId = options?.sessionId ?? randomUUID();\n this.sessionCacheDir = join(\n getProjectTmpDir('codeql-cache'),\n this.sessionId,\n );\n // Pre-create the cache directory tree\n for (const subdir of ['compilation-cache', 'logs', 'query-cache']) {\n mkdirSync(join(this.sessionCacheDir, subdir), { recursive: true });\n }\n logger.info(`CodeQLServerManager initialized (session: ${this.sessionId})`);\n }\n\n // ---- Public API ----\n\n /**\n * Get the current session ID.\n */\n getSessionId(): string {\n return this.sessionId;\n }\n\n /**\n * Get the session-specific cache directory.\n */\n getCacheDir(): string {\n return this.sessionCacheDir;\n }\n\n /**\n * Return the session-specific log directory.\n */\n getLogDir(): string {\n return join(this.sessionCacheDir, 'logs');\n }\n\n /**\n * Get or create a Language Server with the given configuration.\n *\n * If a language server is already running with the same config it is reused.\n * If the config has changed the old server is shut down first.\n */\n async getLanguageServer(config: LanguageServerConfig): Promise {\n const enriched = this.enrichConfig(config) as LanguageServerConfig;\n return this.getOrRestart('language', enriched, () => {\n // Convert LanguageServerConfig to the LanguageServerOptions the existing class expects\n return new CodeQLLanguageServer({\n loglevel: enriched.loglevel,\n logdir: enriched.logdir,\n searchPath: enriched.searchPath,\n synchronous: enriched.synchronous,\n verbosity: enriched.verbosity,\n });\n }) as Promise;\n }\n\n /**\n * Get or create a Query Server with the given configuration.\n */\n async getQueryServer(config: QueryServerConfig): Promise {\n const enriched = this.enrichConfig(config) as QueryServerConfig;\n return this.getOrRestart('query', enriched, () => {\n return new CodeQLQueryServer(enriched);\n }) as Promise;\n }\n\n /**\n * Get or create a CLI Server with the given configuration.\n */\n async getCLIServer(config: CLIServerConfig): Promise {\n const enriched = this.enrichConfig(config) as CLIServerConfig;\n return this.getOrRestart('cli', enriched, () => {\n return new CodeQLCLIServer(enriched);\n }) as Promise;\n }\n\n /**\n * Shut down a specific server type.\n */\n async shutdownServer(type: CodeQLServerType): Promise {\n const managed = this.servers.get(type);\n if (!managed) return;\n\n logger.info(`Shutting down ${type} server (session: ${managed.sessionId})`);\n await this.stopServer(managed);\n this.servers.delete(type);\n }\n\n /**\n * Shut down all managed servers.\n */\n async shutdownAll(): Promise {\n logger.info(`Shutting down all servers for session: ${this.sessionId}`);\n const shutdownPromises = Array.from(this.servers.entries()).map(\n async ([type, managed]) => {\n try {\n await this.stopServer(managed);\n } catch (error) {\n logger.error(`Error shutting down ${type} server:`, error);\n }\n },\n );\n await Promise.all(shutdownPromises);\n this.servers.clear();\n logger.info('All servers shut down');\n }\n\n /**\n * Check whether a server of the given type is currently running.\n */\n isRunning(type: CodeQLServerType): boolean {\n const managed = this.servers.get(type);\n if (!managed) return false;\n return managed.server.isRunning();\n }\n\n /**\n * Get status information for all managed servers.\n */\n getStatus(): Record {\n const status: Record = {\n cli: null,\n language: null,\n query: null,\n };\n for (const [type, managed] of this.servers) {\n status[type] = {\n configHash: managed.configHash,\n running: managed.server.isRunning(),\n sessionId: managed.sessionId,\n };\n }\n return status as Record;\n }\n\n // ---- Private helpers ----\n\n /**\n * Eagerly start the language server so the JVM is warm when the first\n * LSP tool call arrives. Uses the default configuration that\n * `lsp-handlers.ts` / `lsp-diagnostics.ts` would create on the first\n * `getLanguageServer()` call. The server is stored in the managed-servers\n * map and reused by subsequent tool invocations.\n *\n * This is fire-and-forget: errors are logged but do not prevent the MCP\n * server from starting.\n */\n async warmUpLanguageServer(): Promise {\n try {\n // Lazy-import to avoid circular dependency at module level\n const { packageRootDir } = await import('../utils/package-paths');\n const { resolve } = await import('path');\n\n const config: LanguageServerConfig = {\n checkErrors: 'ON_CHANGE',\n loglevel: 'WARN',\n searchPath: resolve(packageRootDir, 'ql'),\n };\n logger.info('Warming up language server (background JVM start)...');\n await this.getLanguageServer(config);\n logger.info('Language server warm-up complete');\n } catch (error) {\n logger.warn('Language server warm-up failed (will retry on first tool call):', error);\n }\n }\n\n /**\n * Eagerly start the CLI server so the JVM is warm when the first\n * `executeCodeQLCommand()` call routes through it.\n *\n * The CLI server uses only session-scoped `commonCaches` and `logdir`,\n * both injected by `enrichConfig()`. Passing an empty config is\n * intentional \u2014 it matches what `executeCodeQLCommand()` will request.\n *\n * Fire-and-forget: errors are logged but do not block startup.\n */\n async warmUpCLIServer(): Promise {\n try {\n logger.info('Warming up CLI server (background JVM start)...');\n await this.getCLIServer({});\n logger.info('CLI server warm-up complete');\n } catch (error) {\n logger.warn('CLI server warm-up failed (will retry on first tool call):', error);\n }\n }\n\n /**\n * Enrich a config with session-specific defaults for commonCaches and logdir.\n */\n private enrichConfig(config: T): T {\n return {\n ...config,\n commonCaches: config.commonCaches ?? this.sessionCacheDir,\n logdir: config.logdir ?? this.getLogDir(),\n };\n }\n\n /**\n * Get an existing server if its config matches, otherwise stop the old\n * one and start a new server.\n *\n * Concurrent calls for the same server type are serialized via\n * `pendingStarts` to avoid spawning duplicate server processes.\n */\n private async getOrRestart(\n type: CodeQLServerType,\n config: ServerConfig,\n factory: () => CodeQLCLIServer | CodeQLLanguageServer | CodeQLQueryServer,\n ): Promise {\n // If another call is already starting a server of this type, wait for it\n // to settle (success or failure) and then re-check whether the result is\n // still usable.\n const inflight = this.pendingStarts.get(type);\n if (inflight) {\n try { await inflight; } catch { /* swallow \u2014 original caller handles the rejection */ }\n }\n\n const work = this.doGetOrRestart(type, config, factory);\n this.pendingStarts.set(type, work);\n try {\n return await work;\n } finally {\n // Ensure `work` has settled before removing the pendingStarts entry so\n // that concurrent callers waiting on the same promise see a consistent\n // map state. The try/catch avoids re-throwing a rejection that the\n // outer `try` block already handles.\n try { await work; } catch { /* already handled */ }\n if (this.pendingStarts.get(type) === work) {\n this.pendingStarts.delete(type);\n }\n }\n }\n\n /**\n * Core logic for getOrRestart, separated to allow serialization.\n */\n private async doGetOrRestart(\n type: CodeQLServerType,\n config: ServerConfig,\n factory: () => CodeQLCLIServer | CodeQLLanguageServer | CodeQLQueryServer,\n ): Promise {\n const hash = computeConfigHash(type, config);\n const existing = this.servers.get(type);\n\n // Reuse if config matches and server is still running\n if (existing && existing.configHash === hash && existing.server.isRunning()) {\n logger.debug(`Reusing existing ${type} server (hash: ${hash.substring(0, 8)})`);\n return existing.server;\n }\n\n // Config changed or server died \u2014 stop the old one\n if (existing) {\n logger.info(`${type} server config changed or dead, restarting...`);\n await this.stopServer(existing);\n this.servers.delete(type);\n }\n\n // Start a new server\n const server = factory();\n await server.start();\n\n this.servers.set(type, {\n configHash: hash,\n server,\n sessionId: this.sessionId,\n type,\n });\n\n logger.info(`${type} server started (hash: ${hash.substring(0, 8)})`);\n return server;\n }\n\n /**\n * Stop a managed server, ignoring errors.\n */\n private async stopServer(managed: ManagedServer): Promise {\n try {\n await managed.server.shutdown();\n } catch (error) {\n logger.warn(`Error stopping ${managed.type} server:`, error);\n // Best-effort \u2014 don't propagate\n }\n }\n}\n\n/**\n * Global server manager singleton.\n *\n * Initialized lazily by `getServerManager()`. The MCP server entry point\n * should call `initServerManager()` at startup and `shutdownServerManager()`\n * at graceful shutdown.\n */\nlet globalServerManager: CodeQLServerManager | null = null;\n\n/**\n * Initialize the global server manager (idempotent).\n */\nexport function initServerManager(options?: SessionCacheOptions): CodeQLServerManager {\n if (!globalServerManager) {\n globalServerManager = new CodeQLServerManager(options);\n }\n return globalServerManager;\n}\n\n/**\n * Get the global server manager, creating it if needed.\n */\nexport function getServerManager(): CodeQLServerManager {\n if (!globalServerManager) {\n globalServerManager = new CodeQLServerManager();\n }\n return globalServerManager;\n}\n\n/**\n * Shut down the global server manager and all its servers.\n */\nexport async function shutdownServerManager(): Promise {\n if (globalServerManager) {\n await globalServerManager.shutdownAll();\n globalServerManager = null;\n }\n}\n\n/**\n * Reset the global server manager (for testing only).\n */\nexport function resetServerManager(): void {\n globalServerManager = null;\n}\n", "/**\n * Generic CLI command execution utilities for CodeQL and QLT commands\n */\n\nimport { execFile } from 'child_process';\nimport { existsSync } from 'fs';\nimport { basename, delimiter, dirname, isAbsolute } from 'path';\nimport { promisify } from 'util';\nimport { logger } from '../utils/logger';\n\nconst execFileAsync = promisify(execFile);\n\nexport interface CLIExecutionResult {\n stdout: string;\n stderr: string;\n success: boolean;\n error?: string;\n exitCode?: number;\n}\n\nexport interface CLIExecutionOptions {\n command: string;\n args: string[];\n cwd?: string;\n timeout?: number;\n env?: Record;\n}\n\n// Whitelist of allowed commands to prevent arbitrary command execution\nconst ALLOWED_COMMANDS = new Set([\n 'codeql',\n 'git',\n 'node',\n 'npm',\n 'qlt',\n 'which'\n]);\n\n// Additional commands allowed in test environments\nlet testCommands: Set | null = null;\n\n// Whitelist of safe environment variables to pass to child processes\n// This prevents potentially malicious environment variables from being passed through\nconst SAFE_ENV_VARS = [\n 'HOME', // User home directory\n 'LANG', // Locale setting\n 'LC_ALL', // Locale setting\n 'LC_CTYPE', // Locale setting\n 'PATH', // Required to find executables\n 'SHELL', // User's shell (Unix)\n 'TEMP', // Temporary directory (Windows)\n 'TERM', // Terminal type (Unix)\n 'TMP', // Temporary directory (Windows)\n 'TMPDIR', // Temporary directory (Unix)\n 'USER', // Current user (Unix)\n 'USERNAME', // Current user (Windows)\n] as const;\n\n// Whitelist of safe environment variable prefixes\n// These are needed for CodeQL and Node.js functionality\nconst SAFE_ENV_PREFIXES = [\n 'CODEQL_', // CodeQL-specific variables\n 'NODE_', // Node.js-specific variables (for npm, etc.)\n] as const;\n\n// Pattern for dangerous control characters in CLI arguments\n// Rejected characters:\n// \\x01-\\x08: SOH through BS (start of heading, text, null control chars, backspace)\n// \\x0B: Vertical tab - rarely used legitimately, can cause display issues\n// \\x0C: Form feed - can cause unexpected page breaks in output\n// \\x0E-\\x1F: SO through US (shift out/in, device controls, separators)\n// Allowed characters:\n// \\x00: Null byte - handled separately for clearer error messaging\n// \\x09: Horizontal tab - commonly used in file paths and arguments\n// \\x0A: Newline (LF) - may appear in multi-line arguments\n// \\x0D: Carriage return (CR) - may appear with newlines on Windows\n// eslint-disable-next-line no-control-regex\nconst DANGEROUS_CONTROL_CHARS = /[\\x01-\\x08\\x0B\\x0C\\x0E-\\x1F]/;\n\n/**\n * Enable test-specific commands for testing purposes\n * This should only be called in test environments\n */\nexport function enableTestCommands(): void {\n testCommands = new Set([\n 'cat',\n 'echo',\n 'ls',\n 'sh',\n 'sleep'\n ]);\n}\n\n/**\n * Disable test-specific commands\n */\nexport function disableTestCommands(): void {\n testCommands = null;\n}\n\n/**\n * Check if a command is allowed\n */\nfunction isCommandAllowed(command: string): boolean {\n return ALLOWED_COMMANDS.has(command) || (testCommands !== null && testCommands.has(command));\n}\n\n// Resolved CodeQL binary directory from CODEQL_PATH.\n// When set, this directory is prepended to PATH for all child processes\n// so that `execFile('codeql', ...)` finds the correct binary via execvp().\n// Using PATH lookup (rather than an absolute path) is essential because\n// execvp() handles shell-script shebangs correctly, whereas passing an\n// absolute path to execFile() can fail with ENOENT for shell scripts.\nlet resolvedCodeQLDir: string | null = null;\n\n// Cached result from resolveCodeQLBinary(). `undefined` means not yet resolved.\nlet resolvedBinaryResult: string | undefined;\n\n/**\n * Resolve the CodeQL CLI binary path.\n *\n * Resolution order:\n * 1. `CODEQL_PATH` environment variable \u2014 must point to an existing file whose\n * basename is `codeql` (or `codeql.exe` / `codeql.cmd` on Windows).\n * The parent directory is prepended to PATH for child processes.\n * 2. Falls back to the bare `codeql` command (resolved via PATH at exec time).\n *\n * The resolved value is cached for the lifetime of the process. Call this once\n * at startup; subsequent calls are a no-op and return the cached value.\n */\nexport function resolveCodeQLBinary(): string {\n // Short-circuit if already resolved\n if (resolvedBinaryResult !== undefined) {\n return resolvedBinaryResult;\n }\n\n const envPath = process.env.CODEQL_PATH;\n\n if (!envPath) {\n resolvedCodeQLDir = null;\n resolvedBinaryResult = 'codeql';\n return resolvedBinaryResult;\n }\n\n // Validate the path points to a plausible CodeQL binary\n const base = basename(envPath).toLowerCase();\n const validBaseNames = ['codeql', 'codeql.exe', 'codeql.cmd'];\n if (!validBaseNames.includes(base)) {\n throw new Error(\n `CODEQL_PATH must point to a CodeQL CLI binary (expected basename: codeql), got: ${base}`\n );\n }\n\n // Require an absolute path to avoid ambiguity\n if (!isAbsolute(envPath)) {\n throw new Error(\n `CODEQL_PATH must be an absolute path, got: ${envPath}`\n );\n }\n\n // Verify the file exists\n if (!existsSync(envPath)) {\n throw new Error(\n `CODEQL_PATH points to a file that does not exist: ${envPath}`\n );\n }\n\n resolvedCodeQLDir = dirname(envPath);\n resolvedBinaryResult = 'codeql';\n logger.info(`CodeQL CLI resolved via CODEQL_PATH: ${envPath} (dir: ${resolvedCodeQLDir})`);\n return resolvedBinaryResult;\n}\n\n/**\n * Get the currently resolved CodeQL binary directory, or null if using PATH.\n */\nexport function getResolvedCodeQLDir(): string | null {\n return resolvedCodeQLDir;\n}\n\n/**\n * Reset the resolved CodeQL binary to the default (for testing only).\n */\nexport function resetResolvedCodeQLBinary(): void {\n resolvedCodeQLDir = null;\n resolvedBinaryResult = undefined;\n}\n\n/**\n * Validate that the resolved CodeQL binary is actually callable.\n *\n * Runs `codeql version --format=terse` and verifies the process exits\n * successfully. This catches the case where `CODEQL_PATH` is unset and\n * `codeql` is not on PATH \u2014 the server would otherwise start normally\n * but every tool invocation would fail.\n *\n * @returns The version string reported by the CodeQL CLI.\n * @throws Error if the binary is not reachable or returns a non-zero exit code.\n */\nexport async function validateCodeQLBinaryReachable(): Promise {\n const binary = resolvedBinaryResult ?? 'codeql';\n const env = { ...process.env };\n if (resolvedCodeQLDir) {\n env.PATH = resolvedCodeQLDir + delimiter + (env.PATH || '');\n }\n\n try {\n const { stdout } = await execFileAsync(binary, ['version', '--format=terse'], {\n env,\n timeout: 15_000,\n });\n return stdout.trim();\n } catch (err: unknown) {\n const message = err instanceof Error ? err.message : String(err);\n throw new Error(\n `CodeQL CLI is not reachable (binary: ${binary}). ` +\n `Ensure codeql is on PATH or set the CODEQL_PATH environment variable ` +\n `to the absolute path of the CodeQL CLI binary. Details: ${message}`\n );\n }\n}\n\n/**\n * Sanitize a CLI argument to prevent potential issues with special characters.\n * \n * While execFile() does not spawn a shell (preventing shell injection), we still\n * validate arguments to:\n * 1. Reject null bytes that could truncate strings in C-based commands\n * 2. Reject control characters that could cause unexpected behavior\n * 3. Provide defense-in-depth against potential issues\n * \n * @param arg - The argument to sanitize\n * @returns The sanitized argument\n * @throws Error if the argument contains dangerous characters\n */\nexport function sanitizeCLIArgument(arg: string): string {\n // Reject null bytes - these can truncate strings in C-based commands\n // Error message intentionally excludes argument content to avoid logging potentially sensitive data\n if (arg.includes('\\0')) {\n throw new Error(`CLI argument contains null byte: argument rejected for security`);\n }\n \n // Reject control characters using the module-level constant pattern\n if (DANGEROUS_CONTROL_CHARS.test(arg)) {\n // Error message intentionally excludes argument content to avoid logging potentially sensitive data\n throw new Error(`CLI argument contains control characters: argument rejected for security`);\n }\n \n return arg;\n}\n\n/**\n * Sanitize an array of CLI arguments\n * @param args - The arguments to sanitize\n * @returns The sanitized arguments\n * @throws Error if any argument contains dangerous characters\n */\nexport function sanitizeCLIArguments(args: string[]): string[] {\n return args.map(sanitizeCLIArgument);\n}\n\n/**\n * Filter environment variables to only include safe ones\n * This prevents potentially malicious environment variables from being passed to child processes\n */\nfunction getSafeEnvironment(additionalEnv?: Record): Record {\n const safeEnv: Record = {};\n \n // Copy whitelisted environment variables from process.env\n for (const key of SAFE_ENV_VARS) {\n if (process.env[key] !== undefined) {\n safeEnv[key] = process.env[key]!;\n }\n }\n \n // Copy environment variables with whitelisted prefixes\n for (const [key, value] of Object.entries(process.env)) {\n if (value !== undefined && SAFE_ENV_PREFIXES.some(prefix => key.startsWith(prefix))) {\n safeEnv[key] = value;\n }\n }\n \n // When CODEQL_PATH was set, prepend the resolved directory to PATH so that\n // `execFile('codeql', ...)` finds the user-specified binary via execvp().\n // This approach (PATH manipulation + bare command name) is essential because\n // execvp() handles shell-script shebangs correctly, whereas passing an\n // absolute path to execFile() fails with ENOENT for shell-script launchers.\n if (resolvedCodeQLDir && safeEnv.PATH) {\n safeEnv.PATH = `${resolvedCodeQLDir}${delimiter}${safeEnv.PATH}`;\n } else if (resolvedCodeQLDir) {\n safeEnv.PATH = resolvedCodeQLDir;\n }\n \n // Merge with explicitly provided environment variables\n // These are trusted as they come from the application code, not external sources\n if (additionalEnv) {\n Object.assign(safeEnv, additionalEnv);\n }\n \n return safeEnv;\n}\n\n/**\n * Execute a CLI command and return the result.\n * \n * Security: This function uses execFile() instead of exec() to avoid shell interpretation.\n * Arguments are passed directly to the executable as an array, preventing shell injection.\n * Additional security measures include:\n * - Command whitelist validation\n * - Shell metacharacter detection in command names\n * - CLI argument sanitization (null bytes, control characters)\n * - Environment variable filtering\n */\nexport async function executeCLICommand(options: CLIExecutionOptions): Promise {\n try {\n const { command, args, cwd, timeout = 300000, env } = options; // 5 minute default timeout\n \n // Validate command is in the whitelist to prevent arbitrary command execution\n if (!isCommandAllowed(command)) {\n throw new Error(`Command not allowed: ${command}. Only whitelisted commands can be executed.`);\n }\n \n // Validate command to ensure it doesn't contain shell metacharacters\n if (command.includes(';') || command.includes('|') || command.includes('&') || \n command.includes('$') || command.includes('`') || command.includes('\\n') ||\n command.includes('\\r')) {\n throw new Error(`Invalid command: contains shell metacharacters: ${command}`);\n }\n \n // Sanitize CLI arguments to prevent issues with special characters\n // This provides defense-in-depth even though execFile() doesn't use a shell\n const sanitizedArgs = sanitizeCLIArguments(args);\n \n logger.info(`Executing CLI command: ${command}`, { args: sanitizedArgs, cwd, timeout });\n \n const execOptions = {\n cwd,\n timeout,\n env: getSafeEnvironment(env),\n };\n \n // execFile() is used instead of exec() to avoid shell interpretation\n // Arguments are passed as an array, not interpolated into a command string\n const { stdout, stderr } = await execFileAsync(command, sanitizedArgs, execOptions);\n\n return {\n stdout,\n stderr,\n success: true,\n exitCode: 0\n };\n\n } catch (error: unknown) {\n logger.error('CLI command execution failed:', error);\n \n const err = error as Error & { code?: number; stdout?: string; stderr?: string };\n const errorMessage = err instanceof Error ? err.message : String(error);\n const exitCode = err.code || 1;\n \n return {\n stdout: err.stdout || '',\n stderr: err.stderr || errorMessage,\n success: false,\n error: errorMessage,\n exitCode\n };\n }\n}\n\n/**\n * Build CodeQL command arguments with proper escaping\n */\nexport function buildCodeQLArgs(subcommand: string, options: Record): string[] {\n const args = [subcommand];\n \n // Single-letter parameters that should use -key=value format (with equals sign)\n // Note: CodeQL CLI uses -t=key=value format for metadata, not -t key=value\n const singleLetterParams = new Set(['t', 'o', 'v', 'q', 'h', 'J']);\n \n for (const [key, value] of Object.entries(options)) {\n if (value === undefined || value === null) {\n continue;\n }\n \n const isSingleLetter = key.length === 1 && singleLetterParams.has(key);\n \n if (typeof value === 'boolean') {\n if (value) {\n args.push(isSingleLetter ? `-${key}` : `--${key}`);\n }\n } else if (Array.isArray(value)) {\n // Handle array values (e.g., multiple -t flags for metadata)\n for (const item of value) {\n if (isSingleLetter) {\n // For single-letter params like -t, use -key=value format\n args.push(`-${key}=${String(item)}`);\n } else {\n // For long params, use --key=value format\n args.push(`--${key}=${String(item)}`);\n }\n }\n } else {\n // Handle string, number, and other values\n if (isSingleLetter) {\n // For single-letter params, use -key=value format\n args.push(`-${key}=${String(value)}`);\n } else {\n args.push(`--${key}=${String(value)}`);\n }\n }\n }\n \n return args;\n}\n\n/**\n * Build QLT command arguments with proper escaping\n */\nexport function buildQLTArgs(subcommand: string, options: Record): string[] {\n const args = [subcommand];\n \n for (const [key, value] of Object.entries(options)) {\n if (value === undefined || value === null) {\n continue;\n }\n \n if (typeof value === 'boolean') {\n if (value) {\n args.push(`--${key}`);\n }\n } else if (Array.isArray(value)) {\n // Handle array values\n for (const item of value) {\n args.push(`--${key}`, String(item));\n }\n } else {\n // Handle string, number, and other values\n args.push(`--${key}`, String(value));\n }\n }\n \n return args;\n}\n\n/**\n * CodeQL subcommands that MUST run as fresh processes.\n *\n * These cannot use the cli-server because they:\n * - Spawn extractors or other long-running child processes (database create, test extract)\n * - Produce multi-event NUL-delimited streams (test run)\n * - Are compound orchestration commands (database analyze)\n *\n * Everything else is routed through the persistent cli-server JVM for\n * sub-second execution instead of 2-5 s JVM cold-start per invocation.\n */\nconst FRESH_PROCESS_SUBCOMMANDS = new Set([\n 'database analyze',\n 'database create',\n 'test extract',\n 'test run',\n]);\n\n/**\n * Execute a CodeQL command.\n *\n * By default, commands are routed through the persistent `codeql execute\n * cli-server` process managed by {@link CodeQLServerManager}, eliminating\n * repeated JVM startup overhead (~2-5 s savings per call).\n *\n * Commands listed in {@link FRESH_PROCESS_SUBCOMMANDS} (e.g. `database create`,\n * `test run`) are always executed as fresh processes because they either spawn\n * child extractors, produce streaming output, or require a dedicated working\n * directory.\n *\n * If the cli-server is not available (e.g. during early startup before\n * `initServerManager()` is called), the function falls back transparently to\n * a fresh process.\n */\nexport async function executeCodeQLCommand(\n subcommand: string,\n options: Record,\n additionalArgs: string[] = [],\n cwd?: string\n): Promise {\n const args = buildCodeQLArgs(subcommand, options);\n args.push(...additionalArgs);\n\n // Determine whether this subcommand can use the persistent cli-server.\n // Commands that need a specific CWD also must use a fresh process because\n // the cli-server's CWD is fixed at startup.\n const canUseCLIServer = !FRESH_PROCESS_SUBCOMMANDS.has(subcommand) && !cwd;\n\n if (canUseCLIServer) {\n try {\n // Lazy-import to avoid circular dependency at module level.\n // Use getServerManager() (not initServerManager()) \u2014 if the manager\n // hasn't been initialized yet (e.g. during tests or early startup),\n // this creates one, but we only attempt to *use* the cli-server if\n // it is already running (warmed up at MCP server startup). We never\n // block on starting a new cli-server here \u2014 that would add JVM\n // startup latency to the first fresh-process-fallback call.\n const { getServerManager } = await import('./server-manager');\n const manager = getServerManager();\n\n if (manager.isRunning('cli')) {\n const cliServer = await manager.getCLIServer({});\n const sanitizedArgs = sanitizeCLIArguments(args);\n\n logger.info(`Executing CodeQL command via cli-server: ${subcommand}`, { args: sanitizedArgs });\n\n const stdout = await cliServer.runCommand(sanitizedArgs);\n\n return {\n stdout,\n stderr: '',\n success: true,\n exitCode: 0,\n };\n } else {\n logger.debug(`cli-server not yet running for \"${subcommand}\", using fresh process`);\n }\n } catch (error) {\n // If the cli-server call fails, check whether it's a command-level\n // error (the CLI returned non-zero) or a transport/startup error.\n // For transport errors we fall back to a fresh process; for command\n // errors we return the failure directly.\n const message = error instanceof Error ? error.message : String(error);\n\n // Transport-level errors that warrant a fallback:\n if (message.includes('CLI server is not running') ||\n message.includes('CLI server exited') ||\n message.includes('failed to start')) {\n logger.warn(`cli-server unavailable for \"${subcommand}\", falling back to fresh process: ${message}`);\n // Fall through to fresh-process execution below\n } else {\n // Command-level error \u2014 return it as a failed result\n logger.error(`cli-server command failed for \"${subcommand}\": ${message}`);\n return {\n stdout: '',\n stderr: message,\n success: false,\n error: message,\n exitCode: 1,\n };\n }\n }\n }\n\n // Fresh-process execution (for FRESH_PROCESS_SUBCOMMANDS, CWD-specific\n // calls, or as a fallback when the cli-server is unavailable).\n return executeCLICommand({\n command: 'codeql',\n args,\n cwd\n });\n}\n\n/**\n * Execute a QLT command\n */\nexport async function executeQLTCommand(\n subcommand: string, \n options: Record, \n additionalArgs: string[] = []\n): Promise {\n const args = buildQLTArgs(subcommand, options);\n args.push(...additionalArgs);\n \n return executeCLICommand({\n command: 'qlt',\n args\n });\n}\n\n/**\n * Get help text for a CLI command\n */\nexport async function getCommandHelp(command: string, subcommand?: string): Promise {\n const args = subcommand ? [subcommand, '--help'] : ['--help'];\n \n const result = await executeCLICommand({\n command,\n args\n });\n \n return result.stdout || result.stderr || 'No help available';\n}\n\n/**\n * Validate that a command exists on the system.\n */\nexport async function validateCommandExists(command: string): Promise {\n try {\n const result = await executeCLICommand({\n command: 'which',\n args: [command]\n });\n return result.success;\n } catch {\n return false;\n }\n}", "/**\n * CodeQL Development MCP McpServer\n * Main entry point for the server\n */\n\nimport { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';\nimport { StreamableHTTPServerTransport } from '@modelcontextprotocol/sdk/server/streamableHttp.js';\nimport express from 'express';\nimport cors from 'cors';\nimport dotenv from 'dotenv';\nimport { realpathSync } from 'fs';\nimport { resolve } from 'path';\nimport { pathToFileURL } from 'url';\nimport { registerCodeQLTools, registerCodeQLResources } from './tools';\nimport { registerLSPTools } from './tools/lsp';\nimport { registerLanguageResources } from './resources/language-resources';\nimport { registerWorkflowPrompts } from './prompts/workflow-prompts';\nimport { registerMonitoringTools } from './tools/monitoring-tools';\nimport { sessionDataManager } from './lib/session-data-manager';\nimport { resolveCodeQLBinary, validateCodeQLBinaryReachable } from './lib/cli-executor';\nimport { initServerManager, shutdownServerManager } from './lib/server-manager';\nimport { packageRootDir } from './utils/package-paths';\nimport { logger } from './utils/logger';\n\n// Load environment variables from a .env file co-located with the package root.\n// Uses the package directory (not CWD) so that npm-installed users don't\n// accidentally inherit a .env from their project.\n// Set DOTENV_CONFIG_QUIET to suppress the dotenv banner that would otherwise\n// leak to stdout and corrupt the MCP stdio JSON-RPC channel.\ndotenv.config({ path: resolve(packageRootDir, '.env'), quiet: true });\n\nconst PACKAGE_NAME = 'codeql-development-mcp-server';\nconst VERSION = '2.24.1';\n\n/**\n * Start the MCP server\n */\nexport async function startServer(mode: 'stdio' | 'http' = 'stdio'): Promise {\n logger.info(`Starting CodeQL Development MCP McpServer v${VERSION} in ${mode} mode`);\n\n // Resolve the CodeQL CLI binary path (honors CODEQL_PATH env var).\n // This must happen before any tool registration so that all CodeQL commands\n // use the user-specified binary.\n const codeqlBinary = resolveCodeQLBinary();\n logger.info(`CodeQL CLI binary: ${codeqlBinary}`);\n\n // Validate that the resolved binary is actually callable. This catches\n // misconfigurations early (e.g. codeql not on PATH and CODEQL_PATH unset)\n // instead of failing silently and producing confusing tool-level errors.\n const codeqlVersion = await validateCodeQLBinaryReachable();\n logger.info(`CodeQL CLI version: ${codeqlVersion}`);\n\n const server = new McpServer({\n name: PACKAGE_NAME,\n version: VERSION,\n });\n\n // Register CodeQL tools (legacy high-level helpers)\n registerCodeQLTools(server);\n\n // Register LSP-based tools (diagnostics, completion, definition, references)\n registerLSPTools(server);\n\n // Register CodeQL resources (static guides)\n registerCodeQLResources(server);\n\n // Register language-specific resources (AST references, security patterns)\n registerLanguageResources(server);\n\n // Register high-level workflow prompts (complete development workflows)\n registerWorkflowPrompts(server);\n\n // Register monitoring and reporting tools\n registerMonitoringTools(server);\n\n // Initialize session data manager\n await sessionDataManager.initialize();\n\n // Initialize the CodeQL background server manager and eagerly start the\n // language server and CLI server JVMs so they are warm when the first tool\n // calls arrive. This avoids 2-60 s cold-start penalties per JVM.\n const manager = initServerManager();\n Promise.all([\n manager.warmUpLanguageServer(),\n manager.warmUpCLIServer(),\n ]).catch(() => { /* individual errors logged inside each warm-up method */ });\n\n if (mode === 'stdio') {\n const transport = new StdioServerTransport();\n await server.connect(transport);\n logger.info('McpServer started successfully on STDIO transport');\n } else {\n // HTTP mode\n const app = express();\n app.use(cors());\n app.use(express.json());\n\n const transport = new StreamableHTTPServerTransport({\n sessionIdGenerator: () => Math.random().toString(36).substring(7),\n });\n await server.connect(transport);\n\n app.all('/mcp', (req, res) => {\n transport.handleRequest(req, res, req.body).catch((err) => {\n logger.error('Error handling MCP request:', err);\n if (!res.headersSent) {\n res.status(500).json({ error: 'Internal McpServer Error' });\n }\n });\n });\n\n app.get('/', (_req, res) => {\n res.json({\n name: PACKAGE_NAME,\n version: VERSION,\n description: 'CodeQL Development MCP McpServer',\n status: 'running',\n });\n });\n\n const host = process.env.HTTP_HOST || 'localhost';\n const port = Number(process.env.HTTP_PORT || process.env.PORT) || 3000;\n \n // Return a promise that keeps the process alive\n return new Promise((resolve, reject) => {\n const httpServer = app.listen(port, host, () => {\n logger.info(`HTTP server listening on http://${host}:${port}/mcp`);\n resolve();\n });\n \n httpServer.on('error', (error) => {\n logger.error('HTTP server error:', error);\n reject(error);\n });\n });\n }\n\n setupGracefulShutdown(server);\n return server;\n}\n\n/**\n * Set up graceful shutdown handling\n */\nfunction setupGracefulShutdown(server: McpServer): void {\n const shutdown = async () => {\n logger.info('Shutting down server...');\n try {\n // Shut down all CodeQL background servers first\n await shutdownServerManager();\n await server.close();\n logger.info('McpServer closed gracefully');\n process.exit(0);\n } catch (error) {\n logger.error('Error during shutdown:', error);\n process.exit(1);\n }\n };\n\n process.on('SIGINT', shutdown);\n process.on('SIGTERM', shutdown);\n}\n\n/**\n * Main function to start the server\n */\nasync function main(): Promise {\n try {\n const transportMode = (process.env.TRANSPORT_MODE || 'stdio').toLowerCase();\n const mode: 'stdio' | 'http' = transportMode === 'http' ? 'http' : 'stdio';\n await startServer(mode);\n } catch (error) {\n logger.error('Failed to start server:', error);\n process.exit(1);\n }\n}\n\n// Start the server if this file is run directly.\n// Use realpathSync to resolve npm/npx symlinks so the guard works for both\n// direct invocation and globally-installed npm bin entries.\nconst scriptPath = process.argv[1] ? realpathSync(resolve(process.argv[1])) : undefined;\nif (scriptPath && import.meta.url === pathToFileURL(scriptPath).href) {\n main();\n}\n", "/**\n * CodeQL BQRS decode tool\n */\n\nimport { z } from 'zod';\nimport { CLIToolDefinition, createCodeQLSchemas, createBQRSResultProcessor } from '../../lib/cli-tool-registry';\n\nexport const codeqlBqrsDecodeTool: CLIToolDefinition = {\n name: 'codeql_bqrs_decode',\n description: 'Decode BQRS result files to human-readable formats',\n command: 'codeql',\n subcommand: 'bqrs decode',\n inputSchema: {\n files: z.array(z.string()).describe('BQRS file(s) to decode'),\n output: createCodeQLSchemas.output(),\n format: z.enum(['csv', 'json']).optional().describe('Output format'),\n 'max-paths': z.number().optional().describe('Maximum number of paths to output'),\n 'start-at': z.number().optional().describe('Start output at result number'),\n 'max-results': z.number().optional().describe('Maximum number of results'),\n verbose: createCodeQLSchemas.verbose(),\n additionalArgs: createCodeQLSchemas.additionalArgs()\n },\n examples: [\n 'codeql bqrs decode --format=csv --output=results.csv results.bqrs',\n 'codeql bqrs decode --format=json --max-results=100 results.bqrs'\n ],\n resultProcessor: createBQRSResultProcessor()\n};", "/**\n * Generic tool registry for creating MCP tools from CLI command definitions\n */\n\nimport { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport { z } from 'zod';\nimport { executeCodeQLCommand, executeQLTCommand, CLIExecutionResult } from './cli-executor';\nimport { logger } from '../utils/logger';\nimport { evaluateQueryResults, QueryEvaluationResult, extractQueryMetadata } from './query-results-evaluator';\nimport { getOrCreateLogDirectory } from './log-directory-manager';\nimport { getUserWorkspaceDir, packageRootDir, resolveToolQueryPackPath } from '../utils/package-paths';\nimport { writeFileSync, rmSync, existsSync, mkdirSync } from 'fs';\nimport { basename, dirname, isAbsolute, join, resolve } from 'path';\nimport { createProjectTempDir } from '../utils/temp-dir';\n\nexport type { CLIExecutionResult } from './cli-executor';\n\nexport interface CLIToolDefinition {\n name: string;\n description: string;\n command: 'codeql' | 'qlt';\n subcommand: string;\n inputSchema: Record;\n examples?: string[];\n resultProcessor?: (_result: CLIExecutionResult, _params: Record) => string;\n}\n\n/**\n * Default result processor that formats CLI output appropriately\n */\nexport const defaultCLIResultProcessor = (\n result: CLIExecutionResult, \n _params: Record\n): string => {\n if (!result.success) {\n return `Command failed (exit code ${result.exitCode || 'unknown'}):\\n${result.error || result.stderr}`;\n }\n \n let output = '';\n \n if (result.stdout) {\n output += result.stdout;\n }\n \n if (result.stderr) {\n if (output) {\n output += '\\n\\nWarnings/Info:\\n';\n }\n output += result.stderr;\n }\n \n if (!output) {\n output = 'Command executed successfully (no output)';\n }\n \n return output;\n};\n\n/**\n * Register a CLI tool with the MCP server\n */\nexport function registerCLITool(server: McpServer, definition: CLIToolDefinition): void {\n const {\n name,\n description,\n command,\n subcommand,\n inputSchema,\n resultProcessor = defaultCLIResultProcessor\n } = definition;\n\n server.tool(\n name,\n description,\n inputSchema,\n async (params: Record) => {\n // Track temporary directories for cleanup\n const tempDirsToCleanup: string[] = [];\n \n try {\n logger.info(`Executing CLI tool: ${name}`, { command, subcommand, params });\n\n // Separate positional arguments from named options\n // Extract tool-specific parameters that should not be passed to CLI\n // Note: format is extracted for tools that use it internally but not on CLI\n // For codeql_bqrs_interpret, codeql_bqrs_decode, codeql_generate_query-help, and codeql_database_analyze, format should be passed to CLI\n const formatShouldBePassedToCLI = name === 'codeql_bqrs_interpret' || name === 'codeql_bqrs_decode' || name === 'codeql_generate_query-help' || name === 'codeql_database_analyze';\n \n const extractedParams = formatShouldBePassedToCLI\n ? {\n _positional: params._positional || [],\n files: params.files,\n file: params.file,\n dir: params.dir,\n packDir: params.packDir,\n tests: params.tests,\n query: params.query,\n queryName: params.queryName,\n queryLanguage: params.queryLanguage,\n queryPack: params.queryPack,\n sourceFiles: params.sourceFiles,\n sourceFunction: params.sourceFunction,\n targetFunction: params.targetFunction,\n interpretedOutput: params.interpretedOutput,\n evaluationFunction: params.evaluationFunction,\n evaluationOutput: params.evaluationOutput,\n directory: params.directory,\n logDir: params.logDir,\n qlref: params.qlref\n }\n : {\n _positional: params._positional || [],\n files: params.files,\n file: params.file,\n dir: params.dir,\n packDir: params.packDir,\n tests: params.tests,\n query: params.query,\n queryName: params.queryName,\n queryLanguage: params.queryLanguage,\n queryPack: params.queryPack, \n sourceFiles: params.sourceFiles,\n sourceFunction: params.sourceFunction,\n targetFunction: params.targetFunction,\n format: params.format,\n interpretedOutput: params.interpretedOutput,\n evaluationFunction: params.evaluationFunction,\n evaluationOutput: params.evaluationOutput,\n directory: params.directory,\n logDir: params.logDir,\n qlref: params.qlref\n };\n\n const {\n _positional = [],\n files,\n file,\n dir,\n packDir,\n tests,\n query,\n queryName,\n queryLanguage: _queryLanguage,\n queryPack: _queryPack,\n sourceFiles,\n sourceFunction,\n targetFunction,\n format: _format,\n interpretedOutput: _interpretedOutput,\n evaluationFunction: _evaluationFunction,\n evaluationOutput: _evaluationOutput,\n directory,\n logDir: customLogDir,\n qlref,\n } = extractedParams;\n\n // Get remaining options (everything not extracted above)\n const options = {...params};\n Object.keys(extractedParams).forEach(key => delete options[key]);\n let positionalArgs = Array.isArray(_positional) ? _positional as string[] : [_positional as string];\n\n // Handle files parameter as positional arguments for certain tools\n if (files && Array.isArray(files)) {\n positionalArgs = [...positionalArgs, ...files as string[]];\n }\n\n // Handle file parameter as positional argument for BQRS tools\n if (file && name.startsWith('codeql_bqrs_')) {\n positionalArgs = [...positionalArgs, file as string];\n }\n\n // Handle qlref parameter as positional argument for resolve qlref tool\n if (qlref && name === 'codeql_resolve_qlref') {\n positionalArgs = [...positionalArgs, qlref as string];\n }\n\n // Handle database parameter as positional argument for resolve database tool\n if (options.database && name === 'codeql_resolve_database') {\n positionalArgs = [...positionalArgs, options.database as string];\n delete options.database;\n }\n\n // Handle database parameter as positional argument for database create tool\n if (options.database && name === 'codeql_database_create') {\n positionalArgs = [...positionalArgs, options.database as string];\n delete options.database;\n }\n\n // Handle database and queries parameters as positional arguments for database analyze tool\n if (name === 'codeql_database_analyze') {\n if (options.database) {\n positionalArgs = [...positionalArgs, options.database as string];\n delete options.database;\n }\n if (options.queries) {\n positionalArgs = [...positionalArgs, options.queries as string];\n delete options.queries;\n }\n }\n\n // Handle query parameter as positional argument for generate query-help tool\n if (query && name === 'codeql_generate_query-help') {\n positionalArgs = [...positionalArgs, query as string];\n }\n\n // Handle dir parameter as positional argument for pack tools\n if (dir && (name === 'codeql_pack_ls')) {\n positionalArgs = [...positionalArgs, dir as string];\n }\n \n // Handle tool-specific parameters using switch pattern for better maintainability\n switch (name) {\n case 'codeql_test_accept':\n case 'codeql_test_extract':\n case 'codeql_test_run':\n case 'codeql_resolve_tests':\n // Handle tests parameter as positional arguments for test tools.\n // Resolve relative paths against the user's effective workspace\n // directory. In monorepo layouts this is the repo root; in npm-\n // installed layouts it falls back to process.cwd().\n if (tests && Array.isArray(tests)) {\n const userDir = getUserWorkspaceDir();\n positionalArgs = [...positionalArgs, ...(tests as string[]).map(\n t => isAbsolute(t) ? t : resolve(userDir, t)\n )];\n }\n break;\n \n case 'codeql_query_run': {\n // Resolve database path to absolute path if it's relative\n if (options.database && typeof options.database === 'string' && !isAbsolute(options.database)) {\n options.database = resolve(getUserWorkspaceDir(), options.database);\n logger.info(`Resolved database path to: ${options.database}`);\n }\n \n // Implement query resolution logic with enhanced results processing\n const resolvedQuery = await resolveQueryPath(params, logger);\n if (resolvedQuery) {\n positionalArgs = [...positionalArgs, resolvedQuery];\n } else if (query) {\n positionalArgs = [...positionalArgs, query as string];\n }\n \n // Handle external predicates for tool queries\n if (queryName === 'PrintAST' && sourceFiles) {\n // Create a CSV file with the source file paths for the external predicate\n // The external predicate expects a CSV file with one column containing file paths\n const filePaths = (sourceFiles as string).split(',').map((f: string) => f.trim());\n let tempDir: string;\n let csvPath: string;\n try {\n tempDir = createProjectTempDir('codeql-external-');\n tempDirsToCleanup.push(tempDir); // Track for cleanup\n csvPath = join(tempDir, 'selectedSourceFiles.csv');\n\n // Create CSV content\n const csvContent = filePaths.join('\\n') + '\\n';\n\n writeFileSync(csvPath, csvContent, 'utf8');\n } catch (err) {\n logger.error(`Failed to create external predicate CSV for PrintAST query at path ${csvPath || '[unknown]'}: ${err instanceof Error ? err.message : String(err)}`);\n throw err;\n }\n \n // Add the external predicate with the CSV file path\n const currentExternal = options.external || [];\n const externalArray = Array.isArray(currentExternal) ? currentExternal : [currentExternal];\n externalArray.push(`selectedSourceFiles=${csvPath}`);\n options.external = externalArray;\n \n logger.info(`Created external predicate CSV at ${csvPath} for files: ${filePaths.join(', ')}`);\n }\n \n // Handle external predicates for CallGraphFrom queries\n if (queryName === 'CallGraphFrom' && sourceFunction) {\n const functionNames = (sourceFunction as string).split(',').map((f: string) => f.trim());\n let tempDir: string;\n let csvPath: string;\n try {\n tempDir = createProjectTempDir('codeql-external-');\n tempDirsToCleanup.push(tempDir);\n csvPath = join(tempDir, 'sourceFunction.csv');\n\n // Create CSV content\n const csvContent = functionNames.join('\\n') + '\\n';\n\n writeFileSync(csvPath, csvContent, 'utf8');\n } catch (err) {\n logger.error(`Failed to create external predicate CSV for CallGraphFrom query at path ${csvPath || '[unknown]'}: ${err instanceof Error ? err.message : String(err)}`);\n throw err;\n }\n \n // Add the external predicate with the CSV file path\n const currentExternal = options.external || [];\n const externalArray = Array.isArray(currentExternal) ? currentExternal : [currentExternal];\n externalArray.push(`sourceFunction=${csvPath}`);\n options.external = externalArray;\n \n logger.info(`Created external predicate CSV at ${csvPath} for functions: ${functionNames.join(', ')}`);\n }\n \n // Handle external predicates for CallGraphTo queries\n if (queryName === 'CallGraphTo' && targetFunction) {\n const functionNames = (targetFunction as string).split(',').map((f: string) => f.trim());\n let tempDir: string;\n let csvPath: string;\n try {\n tempDir = createProjectTempDir('codeql-external-');\n tempDirsToCleanup.push(tempDir);\n csvPath = join(tempDir, 'targetFunction.csv');\n\n // Create CSV content\n const csvContent = functionNames.join('\\n') + '\\n';\n\n writeFileSync(csvPath, csvContent, 'utf8');\n } catch (err) {\n logger.error(`Failed to create external predicate CSV for CallGraphTo query at path ${csvPath || '[unknown]'}: ${err instanceof Error ? err.message : String(err)}`);\n throw err;\n }\n \n // Add the external predicate with the CSV file path\n const currentExternal = options.external || [];\n const externalArray = Array.isArray(currentExternal) ? currentExternal : [currentExternal];\n externalArray.push(`targetFunction=${csvPath}`);\n options.external = externalArray;\n \n logger.info(`Created external predicate CSV at ${csvPath} for functions: ${functionNames.join(', ')}`);\n }\n break;\n }\n \n case 'codeql_query_compile':\n case 'codeql_resolve_metadata':\n // Handle query parameter as positional argument for query compilation and metadata tools\n if (query) {\n positionalArgs = [...positionalArgs, query as string];\n }\n break;\n \n case 'codeql_resolve_queries':\n // Handle directory parameter as positional argument\n if (directory) {\n positionalArgs = [...positionalArgs, directory as string];\n }\n break;\n \n default:\n // No special parameter handling needed for other tools\n break;\n }\n\n // Set up logging directory for query/test runs\n let queryLogDir: string | undefined;\n if (name === 'codeql_query_run' || name === 'codeql_test_run') {\n queryLogDir = getOrCreateLogDirectory(customLogDir as string | undefined);\n logger.info(`Using log directory for ${name}: ${queryLogDir}`);\n \n // Create timestamp file to track when query/test run started\n const timestampPath = join(queryLogDir, 'timestamp');\n writeFileSync(timestampPath, Date.now().toString(), 'utf8');\n \n // Set the --logdir option for CodeQL CLI\n options.logdir = queryLogDir;\n \n // Set verbosity to progress+ to generate detailed query.log/test.log\n if (!options.verbosity) {\n options.verbosity = 'progress+';\n }\n \n // For query run, also handle the deprecated evaluator-log parameter and default output\n if (name === 'codeql_query_run') {\n // If evaluator-log was explicitly provided (deprecated), use it\n // Otherwise, set it to the log directory\n if (!options['evaluator-log']) {\n options['evaluator-log'] = join(queryLogDir, 'evaluator-log.jsonl');\n }\n \n // If output was not explicitly provided, set it to the log directory\n if (!options.output) {\n options.output = join(queryLogDir, 'results.bqrs');\n }\n }\n }\n\n let result: CLIExecutionResult;\n \n if (command === 'codeql') {\n // For pack commands, set the working directory to where qlpack.yml is located.\n // Resolve to absolute path since the MCP server's cwd may differ from\n // the workspace root (especially when launched by VS Code).\n let cwd: string | undefined;\n if ((name === 'codeql_pack_install' || name === 'codeql_pack_ls') && (dir || packDir)) {\n const rawCwd = (dir || packDir) as string;\n // Resolve relative paths against the user's effective workspace\n // directory rather than a potentially read-only package root.\n cwd = isAbsolute(rawCwd) ? rawCwd : resolve(getUserWorkspaceDir(), rawCwd);\n }\n \n // Add --additional-packs for commands that need to access local test packs.\n // Only set the default examples path when it actually exists on disk\n // (it may be absent in npm-installed layouts where ql/javascript/examples/\n // is not included in the published package).\n const defaultExamplesPath = resolve(packageRootDir, 'ql', 'javascript', 'examples');\n const additionalPacksPath = process.env.CODEQL_ADDITIONAL_PACKS\n || (existsSync(defaultExamplesPath) ? defaultExamplesPath : undefined);\n if (additionalPacksPath && (name === 'codeql_test_run' || name === 'codeql_query_run' || name === 'codeql_query_compile')) {\n options['additional-packs'] = additionalPacksPath;\n }\n \n // Keep test databases for codeql_test_run to allow subsequent query runs\n if (name === 'codeql_test_run') {\n options['keep-databases'] = true;\n }\n \n result = await executeCodeQLCommand(subcommand, options, positionalArgs, cwd);\n } else if (command === 'qlt') {\n result = await executeQLTCommand(subcommand, options, positionalArgs);\n } else {\n throw new Error(`Unsupported command: ${command}`);\n }\n\n // Post-execution processing for codeql_query_run\n if (name === 'codeql_query_run' && result.success && queryLogDir) {\n // Generate SARIF interpretation if results.bqrs exists\n const bqrsPath = options.output as string;\n const sarifPath = join(queryLogDir, 'results.sarif');\n \n if (existsSync(bqrsPath)) {\n try {\n const sarifResult = await executeCodeQLCommand(\n 'bqrs interpret',\n { format: 'sarif-latest', output: sarifPath },\n [bqrsPath]\n );\n \n if (sarifResult.success) {\n logger.info(`Generated SARIF interpretation at ${sarifPath}`);\n }\n } catch (error) {\n logger.warn(`Failed to generate SARIF interpretation: ${error}`);\n }\n }\n \n // Process evaluation results\n result = await processQueryRunResults(result, params, logger);\n }\n\n // Process the result\n const processedResult = resultProcessor(result, params);\n\n return {\n content: [{\n type: 'text' as const,\n text: processedResult\n }],\n isError: !result.success\n };\n\n } catch (error) {\n logger.error(`Error in CLI tool ${name}:`, error);\n \n return {\n content: [{\n type: 'text' as const,\n text: `Failed to execute CLI tool: ${error instanceof Error ? error.message : String(error)}`\n }],\n isError: true\n };\n } finally {\n // Clean up temporary directories\n for (const tempDir of tempDirsToCleanup) {\n try {\n rmSync(tempDir, { recursive: true, force: true });\n logger.info(`Cleaned up temporary directory: ${tempDir}`);\n } catch (cleanupError) {\n logger.error(`Failed to clean up temporary directory ${tempDir}:`, cleanupError);\n }\n }\n }\n }\n );\n}\n\n/**\n * Helper function to create common CodeQL input schemas\n */\nexport const createCodeQLSchemas = {\n database: () => z.string().describe('Path to the CodeQL database'),\n \n query: () => z.string().describe('Path to the CodeQL query file (.ql)'),\n \n output: () => z.string().optional().describe('Output file path'),\n \n outputFormat: () => z.enum(['csv', 'json', 'bqrs', 'sarif-latest', 'sarifv2.1.0']).optional()\n .describe('Output format for results'),\n \n language: () => z.string().optional().describe('Programming language'),\n \n threads: () => z.number().optional().describe('Number of threads to use'),\n \n ram: () => z.number().optional().describe('Amount of RAM to use (MB)'),\n \n timeout: () => z.number().optional().describe('Timeout in seconds'),\n \n verbose: () => z.boolean().optional().describe('Enable verbose output'),\n \n additionalArgs: () => z.array(z.string()).optional().describe('Additional command-line arguments'),\n \n positionalArgs: () => z.array(z.string()).optional().describe('Positional arguments')\n .transform((val) => ({ _positional: val }))\n};\n\n/**\n * Helper function to create common QLT input schemas\n */\nexport const createQLTSchemas = {\n language: () => z.string().describe('Programming language'),\n \n output: () => z.string().optional().describe('Output directory or file path'),\n \n template: () => z.string().optional().describe('Template to use'),\n \n name: () => z.string().optional().describe('Name for generated query'),\n \n description: () => z.string().optional().describe('Description for generated query'),\n \n verbose: () => z.boolean().optional().describe('Enable verbose output'),\n \n force: () => z.boolean().optional().describe('Force overwrite existing files'),\n \n additionalArgs: () => z.array(z.string()).optional().describe('Additional command-line arguments')\n};\n\n/**\n * Create a result processor that formats BQRS output specially\n */\nexport const createBQRSResultProcessor = () => (\n result: CLIExecutionResult, \n params: Record\n): string => {\n if (!result.success) {\n return defaultCLIResultProcessor(result, params);\n }\n \n // For BQRS commands, provide more context about the output\n let output = result.stdout;\n \n if (params.output) {\n output += `\\n\\nResults saved to: ${params.output}`;\n }\n \n if (result.stderr) {\n output += `\\n\\nAdditional information:\\n${result.stderr}`;\n }\n \n return output;\n};\n\n/**\n * Create a result processor that formats database creation output\n */\nexport const createDatabaseResultProcessor = () => (\n result: CLIExecutionResult, \n params: Record\n): string => {\n if (!result.success) {\n return defaultCLIResultProcessor(result, params);\n }\n \n let output = 'Database creation completed successfully';\n \n if (params.database || params._positional) {\n const dbPath = params.database || (Array.isArray(params._positional) ? params._positional[0] : params._positional);\n output += `\\n\\nDatabase location: ${dbPath}`;\n }\n \n if (result.stdout) {\n output += `\\n\\nOutput:\\n${result.stdout}`;\n }\n \n if (result.stderr) {\n output += `\\n\\nAdditional information:\\n${result.stderr}`;\n }\n \n return output;\n};\n\n/**\n * Resolve query path for codeql_query_run tool\n * If queryName and queryLanguage are provided, resolve using codeql resolve queries\n */\nasync function resolveQueryPath(\n params: Record, \n logger: { info: (_message: string, ..._args: unknown[]) => void; error: (_message: string, ..._args: unknown[]) => void }\n): Promise {\n const { queryName, queryLanguage, queryPack, query } = params;\n \n // Validate parameter usage - queryName and query are mutually exclusive\n if (queryName && query) {\n logger.error('Cannot use both \"query\" and \"queryName\" parameters simultaneously. Use either \"query\" for direct file path OR \"queryName\" + \"queryLanguage\" for tool queries.');\n throw new Error('Cannot use both \"query\" and \"queryName\" parameters simultaneously. Use either \"query\" for direct file path OR \"queryName\" + \"queryLanguage\" for tool queries.');\n }\n \n // If no queryName provided, fall back to direct query parameter\n if (!queryName) {\n return query as string || null;\n }\n \n // If queryName provided but no language, we can't resolve\n if (!queryLanguage) {\n logger.error('queryLanguage is required when using queryName parameter. Supported languages: actions, cpp, csharp, go, java, javascript, python, ruby, swift');\n throw new Error('queryLanguage is required when using queryName parameter. Supported languages: actions, cpp, csharp, go, java, javascript, python, ruby, swift');\n }\n \n try {\n // Determine the query pack path - use absolute path to ensure it works regardless of cwd\n const defaultPackPath = resolveToolQueryPackPath(queryLanguage as string);\n const packPath = queryPack as string || defaultPackPath;\n \n logger.info(`Resolving query: ${queryName} for language: ${queryLanguage} in pack: ${packPath}`);\n \n // Execute codeql resolve queries to get available queries\n const { executeCodeQLCommand } = await import('./cli-executor');\n const resolveResult = await executeCodeQLCommand(\n 'resolve queries',\n { format: 'json' },\n [packPath]\n );\n \n if (!resolveResult.success) {\n logger.error('Failed to resolve queries:', resolveResult.stderr || resolveResult.error);\n throw new Error(`Failed to resolve queries: ${resolveResult.stderr || resolveResult.error}`);\n }\n \n // Parse the JSON output to find matching queries\n let resolvedQueries: string[];\n try {\n resolvedQueries = JSON.parse(resolveResult.stdout);\n } catch (parseError) {\n logger.error('Failed to parse resolve queries output:', parseError);\n throw new Error('Failed to parse resolve queries output');\n }\n \n // Find the query that matches the requested name exactly\n const matchingQuery = resolvedQueries.find(queryPath => {\n const fileName = basename(queryPath);\n // Match exact query name: \"PrintAST\" should match \"PrintAST.ql\" only\n return fileName === `${queryName}.ql`;\n });\n\n if (!matchingQuery) {\n logger.error(`Query \"${queryName}.ql\" not found in pack \"${packPath}\". Available queries:`, resolvedQueries.map(q => basename(q)));\n throw new Error(`Query \"${queryName}.ql\" not found in pack \"${packPath}\"`);\n }\n \n logger.info(`Resolved query \"${queryName}\" to: ${matchingQuery}`);\n return matchingQuery;\n \n } catch (error) {\n logger.error('Error resolving query path:', error);\n throw error;\n }\n}\n\n/**\n * Interpret BQRS file using codeql bqrs interpret\n */\nasync function interpretBQRSFile(\n bqrsPath: string,\n queryPath: string,\n format: string,\n outputPath: string,\n logger: { info: (_message: string, ..._args: unknown[]) => void; error: (_message: string, ..._args: unknown[]) => void }\n): Promise {\n try {\n // Extract query metadata to get id and kind\n const metadata = await extractQueryMetadata(queryPath);\n \n // Validate required metadata fields\n const missingFields = [];\n if (!metadata.id) missingFields.push('id');\n if (!metadata.kind) missingFields.push('kind');\n \n if (missingFields.length > 0) {\n return {\n success: false,\n exitCode: 1,\n stdout: '',\n stderr: '',\n error: `Query metadata is incomplete. Missing required field(s): ${missingFields.join(', ')}. Ensure the query file contains @id and @kind metadata.`\n };\n }\n \n // Sanitize metadata values to prevent command injection\n const sanitizedKind = (metadata.kind || '').replace(/[^a-zA-Z0-9_-]/g, '');\n const sanitizedId = (metadata.id || '').replace(/[^a-zA-Z0-9_/:-]/g, '');\n \n // Validate format for query kind\n const graphFormats = ['graphtext', 'dgml', 'dot'];\n if (graphFormats.includes(format) && metadata.kind !== 'graph') {\n return {\n success: false,\n exitCode: 1,\n stdout: '',\n stderr: '',\n error: `Format '${format}' is only compatible with @kind graph queries, but this query has @kind ${metadata.kind}`\n };\n }\n \n // Ensure output directory exists\n mkdirSync(dirname(outputPath), { recursive: true });\n \n // Build the codeql bqrs interpret command\n const params: Record = {\n format: format,\n output: outputPath,\n t: [`kind=${sanitizedKind}`, `id=${sanitizedId}`]\n };\n \n logger.info(`Interpreting BQRS file ${bqrsPath} with format ${format} to ${outputPath}`);\n \n // Execute codeql bqrs interpret\n const result = await executeCodeQLCommand(\n 'bqrs interpret',\n params,\n [bqrsPath]\n );\n \n return result;\n } catch (error) {\n return {\n success: false,\n exitCode: 1,\n stdout: '',\n stderr: '',\n error: `Failed to interpret BQRS file: ${error}`\n };\n }\n}\n\n/**\n * Get default output extension based on format\n */\nfunction getDefaultExtension(format: string): string {\n switch (format) {\n case 'sarif-latest':\n case 'sarifv2.1.0':\n return '.sarif';\n case 'csv':\n return '.csv';\n case 'graphtext':\n return '.txt';\n case 'dgml':\n return '.dgml';\n case 'dot':\n return '.dot';\n default:\n return '.txt';\n }\n}\n\n/**\n * Process query run results with optional interpretation or evaluation\n */\nasync function processQueryRunResults(\n result: CLIExecutionResult,\n params: Record,\n logger: { info: (_message: string, ..._args: unknown[]) => void; error: (_message: string, ..._args: unknown[]) => void }\n): Promise {\n try {\n const { format, interpretedOutput, evaluationFunction, evaluationOutput, output, query, queryName, queryLanguage } = params;\n \n // If no format or evaluationFunction specified, return as-is\n if (!format && !evaluationFunction) {\n return result;\n }\n \n // Ensure output (bqrs file) was generated\n if (!output) {\n return result;\n }\n \n const bqrsPath = output as string;\n \n // Determine the query path for metadata extraction\n let queryPath: string | null = null;\n \n if (query) {\n queryPath = query as string;\n } else if (queryName && queryLanguage) {\n // Try to resolve the query path again for evaluation\n queryPath = await resolveQueryPath(params, logger);\n }\n \n if (!queryPath) {\n logger.error('Cannot determine query path for interpretation/evaluation');\n return {\n ...result,\n stdout: result.stdout + '\\n\\nWarning: Query interpretation skipped - could not determine query path'\n };\n }\n \n // Handle new format parameter (preferred approach)\n if (format) {\n const outputFormat = format as string;\n \n // Determine output path\n let outputFilePath = interpretedOutput as string | undefined;\n if (!outputFilePath) {\n const ext = getDefaultExtension(outputFormat);\n outputFilePath = bqrsPath.replace('.bqrs', ext);\n }\n \n logger.info(`Interpreting query results from ${bqrsPath} with format: ${outputFormat}`);\n \n // Interpret the BQRS file\n const interpretResult = await interpretBQRSFile(\n bqrsPath,\n queryPath,\n outputFormat,\n outputFilePath,\n logger\n );\n \n if (interpretResult.success) {\n let enhancedOutput = result.stdout;\n enhancedOutput += `\\n\\nQuery results interpreted successfully with format: ${outputFormat}`;\n enhancedOutput += `\\nInterpreted output saved to: ${outputFilePath}`;\n \n return {\n ...result,\n stdout: enhancedOutput\n };\n } else {\n logger.error('Query interpretation failed:', interpretResult.error);\n return {\n ...result,\n stdout: result.stdout + `\\n\\nWarning: Query interpretation failed - ${interpretResult.error || interpretResult.stderr}`\n };\n }\n }\n \n // Handle legacy evaluationFunction parameter (deprecated)\n if (evaluationFunction) {\n logger.info(`Using deprecated evaluationFunction parameter. Consider using format parameter instead.`);\n logger.info(`Evaluating query results from ${bqrsPath} using function: ${evaluationFunction}`);\n \n // Perform the evaluation\n const evaluationResult: QueryEvaluationResult = await evaluateQueryResults(\n bqrsPath,\n queryPath,\n evaluationFunction as string,\n evaluationOutput as string | undefined\n );\n \n if (evaluationResult.success) {\n // Append evaluation results to the command output\n let enhancedOutput = result.stdout;\n \n if (evaluationResult.outputPath) {\n enhancedOutput += `\\n\\nQuery evaluation completed successfully.`;\n enhancedOutput += `\\nEvaluation output saved to: ${evaluationResult.outputPath}`;\n }\n \n if (evaluationResult.content) {\n enhancedOutput += `\\n\\n=== Query Results Evaluation ===\\n`;\n enhancedOutput += evaluationResult.content;\n }\n \n return {\n ...result,\n stdout: enhancedOutput\n };\n } else {\n // Evaluation failed, but don't fail the whole operation\n logger.error('Query evaluation failed:', evaluationResult.error);\n return {\n ...result,\n stdout: result.stdout + `\\n\\nWarning: Query evaluation failed - ${evaluationResult.error}`\n };\n }\n }\n \n return result;\n } catch (error) {\n logger.error('Error in query results processing:', error);\n return {\n ...result,\n stdout: result.stdout + `\\n\\nWarning: Query processing error - ${error}`\n };\n }\n}", "/**\n * Query results evaluation functions for processing .bqrs files\n */\n\nimport { executeCodeQLCommand } from './cli-executor';\nimport { logger } from '../utils/logger';\nimport { writeFileSync, readFileSync } from 'fs';\nimport { dirname, isAbsolute } from 'path';\nimport { mkdirSync } from 'fs';\n\nexport interface QueryEvaluationResult {\n success: boolean;\n outputPath?: string;\n content?: string;\n error?: string;\n}\n\nexport interface QueryMetadata {\n kind?: string;\n name?: string;\n description?: string;\n id?: string;\n tags?: string[];\n}\n\n/**\n * Built-in evaluation functions\n */\nexport const BUILT_IN_EVALUATORS = {\n 'json-decode': 'JSON format decoder for query results',\n 'csv-decode': 'CSV format decoder for query results', \n 'mermaid-graph': 'Mermaid diagram generator for @kind graph queries (like PrintAST)',\n} as const;\n\nexport type BuiltInEvaluator = keyof typeof BUILT_IN_EVALUATORS;\n\n/**\n * Extract metadata from a CodeQL query file\n */\nexport async function extractQueryMetadata(queryPath: string): Promise {\n try {\n const queryContent = readFileSync(queryPath, 'utf-8');\n const metadata: QueryMetadata = {};\n \n // Extract metadata from comments using regex patterns\n const kindMatch = queryContent.match(/@kind\\s+([^\\s]+)/);\n if (kindMatch) metadata.kind = kindMatch[1];\n \n const nameMatch = queryContent.match(/@name\\s+(.+)/);\n if (nameMatch) metadata.name = nameMatch[1].trim();\n \n const descMatch = queryContent.match(/@description\\s+(.+)/);\n if (descMatch) metadata.description = descMatch[1].trim();\n \n const idMatch = queryContent.match(/@id\\s+(.+)/);\n if (idMatch) metadata.id = idMatch[1].trim();\n \n const tagsMatch = queryContent.match(/@tags\\s+(.+)/);\n if (tagsMatch) {\n metadata.tags = tagsMatch[1].split(/\\s+/).filter(t => t.length > 0);\n }\n \n return metadata;\n } catch (error) {\n logger.error('Failed to extract query metadata:', error);\n return {};\n }\n}\n\n/**\n * JSON decoder - converts .bqrs to JSON format\n */\nexport async function evaluateWithJsonDecoder(\n bqrsPath: string, \n outputPath?: string\n): Promise {\n try {\n const result = await executeCodeQLCommand(\n 'bqrs decode',\n { format: 'json' },\n [bqrsPath]\n );\n \n if (!result.success) {\n return {\n success: false,\n error: `Failed to decode BQRS file: ${result.stderr || result.error}`\n };\n }\n \n const defaultOutputPath = outputPath || bqrsPath.replace('.bqrs', '.json');\n \n // Ensure output directory exists\n mkdirSync(dirname(defaultOutputPath), { recursive: true });\n \n // Write JSON results\n writeFileSync(defaultOutputPath, result.stdout);\n \n return {\n success: true,\n outputPath: defaultOutputPath,\n content: result.stdout\n };\n } catch (error) {\n return {\n success: false,\n error: `JSON evaluation failed: ${error}`\n };\n }\n}\n\n/**\n * CSV decoder - converts .bqrs to CSV format\n */\nexport async function evaluateWithCsvDecoder(\n bqrsPath: string,\n outputPath?: string\n): Promise {\n try {\n const result = await executeCodeQLCommand(\n 'bqrs decode',\n { format: 'csv' },\n [bqrsPath]\n );\n \n if (!result.success) {\n return {\n success: false,\n error: `Failed to decode BQRS file: ${result.stderr || result.error}`\n };\n }\n \n const defaultOutputPath = outputPath || bqrsPath.replace('.bqrs', '.csv');\n \n // Ensure output directory exists\n mkdirSync(dirname(defaultOutputPath), { recursive: true });\n \n // Write CSV results\n writeFileSync(defaultOutputPath, result.stdout);\n \n return {\n success: true,\n outputPath: defaultOutputPath,\n content: result.stdout\n };\n } catch (error) {\n return {\n success: false,\n error: `CSV evaluation failed: ${error}`\n };\n }\n}\n\n/**\n * Mermaid graph generator - converts @kind graph query results to mermaid diagrams\n */\nexport async function evaluateWithMermaidGraph(\n bqrsPath: string,\n queryPath: string,\n outputPath?: string\n): Promise {\n try {\n // First extract query metadata to confirm this is a graph query\n const metadata = await extractQueryMetadata(queryPath);\n \n if (metadata.kind !== 'graph') {\n logger.error(`Query is not a graph query (kind: ${metadata.kind}), mermaid-graph evaluation is only for @kind graph queries`);\n return {\n success: false,\n error: `Query is not a graph query (kind: ${metadata.kind}), mermaid-graph evaluation is only for @kind graph queries`\n };\n }\n \n // Decode the BQRS file to JSON first\n const jsonResult = await executeCodeQLCommand(\n 'bqrs decode',\n { format: 'json' },\n [bqrsPath]\n );\n \n if (!jsonResult.success) {\n return {\n success: false,\n error: `Failed to decode BQRS file: ${jsonResult.stderr || jsonResult.error}`\n };\n }\n \n // Parse the JSON results\n let queryResults;\n try {\n queryResults = JSON.parse(jsonResult.stdout);\n } catch (parseError) {\n return {\n success: false,\n error: `Failed to parse query results JSON: ${parseError}`\n };\n }\n \n // Generate mermaid diagram from graph results\n const mermaidContent = generateMermaidFromGraphResults(queryResults, metadata);\n \n const defaultOutputPath = outputPath || bqrsPath.replace('.bqrs', '.md');\n \n // Ensure output directory exists\n mkdirSync(dirname(defaultOutputPath), { recursive: true });\n \n // Write markdown file with mermaid diagram\n writeFileSync(defaultOutputPath, mermaidContent);\n \n return {\n success: true,\n outputPath: defaultOutputPath,\n content: mermaidContent\n };\n } catch (error) {\n return {\n success: false,\n error: `Mermaid graph evaluation failed: ${error}`\n };\n }\n}\n\n/**\n * Generate mermaid diagram from CodeQL graph query results\n */\nfunction generateMermaidFromGraphResults(queryResults: unknown, metadata: QueryMetadata): string {\n const queryName = sanitizeMarkdown(metadata.name || 'CodeQL Query Results');\n const queryDesc = sanitizeMarkdown(metadata.description || 'Graph visualization of CodeQL query results');\n \n let mermaidContent = `# ${queryName}\\n\\n${queryDesc}\\n\\n`;\n \n // Handle different result structures that CodeQL graph queries can produce\n if (!queryResults || typeof queryResults !== 'object') {\n mermaidContent += '```mermaid\\ngraph TD\\n A[No Results]\\n```\\n';\n return mermaidContent;\n }\n \n // Check if results have the expected structure for graph queries\n const tuples = queryResults.tuples || queryResults;\n \n if (!Array.isArray(tuples) || tuples.length === 0) {\n mermaidContent += '```mermaid\\ngraph TD\\n A[No Graph Data]\\n```\\n';\n return mermaidContent;\n }\n \n mermaidContent += '```mermaid\\ngraph TD\\n';\n \n // Track nodes and edges to avoid duplicates\n const nodes = new Set();\n const edges = new Set();\n \n // Process each tuple in the results\n tuples.forEach((tuple: unknown, index: number) => {\n if (Array.isArray(tuple) && tuple.length >= 2) {\n // Extract source and target from tuple\n const source = sanitizeNodeId(tuple[0]?.toString() || `node_${index}_0`);\n const target = sanitizeNodeId(tuple[1]?.toString() || `node_${index}_1`);\n const label = tuple[2]?.toString() || '';\n \n // Add nodes\n nodes.add(source);\n nodes.add(target);\n \n // Add edge\n const edgeId = `${source}_${target}`;\n if (!edges.has(edgeId)) {\n if (label) {\n mermaidContent += ` ${source} -->|${sanitizeLabel(label)}| ${target}\\n`;\n } else {\n mermaidContent += ` ${source} --> ${target}\\n`;\n }\n edges.add(edgeId);\n }\n } else if (typeof tuple === 'object' && tuple !== null) {\n // Handle object-based results\n const source = sanitizeNodeId(tuple.source?.toString() || tuple.from?.toString() || `node_${index}_src`);\n const target = sanitizeNodeId(tuple.target?.toString() || tuple.to?.toString() || `node_${index}_tgt`);\n const label = tuple.label?.toString() || tuple.relation?.toString() || '';\n \n nodes.add(source);\n nodes.add(target);\n \n const edgeId = `${source}_${target}`;\n if (!edges.has(edgeId)) {\n if (label) {\n mermaidContent += ` ${source} -->|${sanitizeLabel(label)}| ${target}\\n`;\n } else {\n mermaidContent += ` ${source} --> ${target}\\n`;\n }\n edges.add(edgeId);\n }\n }\n });\n \n // If no edges were created, create a simple diagram showing the first few nodes\n if (edges.size === 0 && nodes.size > 0) {\n const nodeArray = Array.from(nodes).slice(0, 10); // Limit to avoid clutter\n nodeArray.forEach((node, index) => {\n if (index === 0) {\n mermaidContent += ` ${node}[${sanitizeLabel(node)}]\\n`;\n } else {\n mermaidContent += ` ${nodeArray[0]} --> ${node}\\n`;\n }\n });\n }\n \n mermaidContent += '```\\n\\n';\n \n // Add statistics\n mermaidContent += `## Query Statistics\\n\\n`;\n mermaidContent += `- Total nodes: ${nodes.size}\\n`;\n mermaidContent += `- Total edges: ${edges.size}\\n`;\n mermaidContent += `- Total tuples processed: ${tuples.length}\\n`;\n \n return mermaidContent;\n}\n\n/**\n * Sanitize node IDs for mermaid compatibility\n */\nfunction sanitizeNodeId(id: string): string {\n return id\n .replace(/[^a-zA-Z0-9_]/g, '_')\n .replace(/^(\\d)/, 'n$1') // Prefix with 'n' if starts with number\n .substring(0, 50); // Limit length\n}\n\n/**\n * Sanitize labels for mermaid compatibility\n */\nfunction sanitizeLabel(label: string): string {\n return label\n .replace(/[|\"`<>\\n\\r\\t]/g, '') // Remove problematic characters including backticks, newlines, angle brackets\n .replace(/\\s+/g, ' ') // Normalize whitespace\n .trim()\n .substring(0, 30); // Limit length for readability\n}\n\n/**\n * Sanitize markdown content to prevent injection\n */\nfunction sanitizeMarkdown(content: string): string {\n return content\n .replace(/[<>\"`]/g, '') // Remove potentially dangerous characters\n .replace(/\\n/g, ' ') // Convert newlines to spaces\n .replace(/\\s+/g, ' ') // Normalize whitespace\n .trim()\n .substring(0, 100); // Limit length\n}\n\n/**\n * Main evaluation function that determines which evaluator to use\n */\nexport async function evaluateQueryResults(\n bqrsPath: string,\n queryPath: string,\n evaluationFunction?: string,\n outputPath?: string\n): Promise {\n try {\n // If no evaluation function specified, default to json-decode\n const evalFunc = evaluationFunction || 'json-decode';\n \n logger.info(`Evaluating query results with function: ${evalFunc}`);\n \n // Handle built-in evaluation functions\n switch (evalFunc) {\n case 'json-decode':\n return await evaluateWithJsonDecoder(bqrsPath, outputPath);\n \n case 'csv-decode':\n return await evaluateWithCsvDecoder(bqrsPath, outputPath);\n \n case 'mermaid-graph':\n return await evaluateWithMermaidGraph(bqrsPath, queryPath, outputPath);\n \n default:\n // Check if it's a path to a custom evaluation script\n if (isAbsolute(evalFunc)) {\n return await evaluateWithCustomScript(bqrsPath, queryPath, evalFunc, outputPath);\n } else {\n return {\n success: false,\n error: `Unknown evaluation function: ${evalFunc}. Available built-in functions: ${Object.keys(BUILT_IN_EVALUATORS).join(', ')}`\n };\n }\n }\n } catch (error) {\n return {\n success: false,\n error: `Query evaluation failed: ${error}`\n };\n }\n}\n\n/**\n * Execute custom evaluation script\n */\nasync function evaluateWithCustomScript(\n _bqrsPath: string,\n _queryPath: string,\n _scriptPath: string,\n _outputPath?: string\n): Promise {\n // TODO: Implement custom script execution\n // This would need to execute the script with bqrsPath and queryPath as arguments\n // and capture the output\n return {\n success: false,\n error: 'Custom evaluation scripts are not yet implemented'\n };\n}", "/**\n * Log directory management utilities for CodeQL query and test runs\n */\n\nimport { mkdirSync, existsSync } from 'fs';\nimport { join, resolve } from 'path';\nimport { randomBytes } from 'crypto';\nimport { getProjectTmpDir } from '../utils/temp-dir';\n\n/**\n * Ensure that a given path is within a base directory.\n * Throws an error if the path is outside the base directory.\n */\nfunction ensurePathWithinBase(baseDir: string, targetPath: string): string {\n const absBase = resolve(baseDir);\n const absTarget = resolve(targetPath);\n if (!absTarget.startsWith(absBase + '/') && absTarget !== absBase) {\n throw new Error(`Provided log directory is outside the allowed base directory: ${absBase}`);\n }\n return absTarget;\n}\n\n/**\n * Get or create a unique log directory for query/test runs\n * \n * @param logDir - Optional custom log directory from parameters\n * @returns Absolute path to the log directory\n */\nexport function getOrCreateLogDirectory(logDir?: string): string {\n // Use CODEQL_QUERY_LOG_DIR env var or default base\n const baseLogDir = process.env.CODEQL_QUERY_LOG_DIR || getProjectTmpDir('query-logs');\n\n // If logDir is explicitly provided, validate it is within baseLogDir\n if (logDir) {\n const absLogDir = ensurePathWithinBase(baseLogDir, logDir);\n if (!existsSync(absLogDir)) {\n mkdirSync(absLogDir, { recursive: true });\n }\n return absLogDir;\n }\n \n // Otherwise, use baseLogDir and create a unique subdirectory\n \n // Create base directory if it doesn't exist\n if (!existsSync(baseLogDir)) {\n mkdirSync(baseLogDir, { recursive: true });\n }\n \n // Generate unique subdirectory with timestamp and random ID\n const timestamp = new Date().toISOString().replace(/[:.]/g, '-');\n const uniqueId = randomBytes(4).toString('hex');\n const uniqueLogDir = join(baseLogDir, `query-run-${timestamp}-${uniqueId}`);\n \n mkdirSync(uniqueLogDir, { recursive: true });\n \n return uniqueLogDir;\n}\n", "/**\n * CodeQL BQRS info tool\n */\n\nimport { z } from 'zod';\nimport { CLIToolDefinition, createCodeQLSchemas, createBQRSResultProcessor } from '../../lib/cli-tool-registry';\n\nexport const codeqlBqrsInfoTool: CLIToolDefinition = {\n name: 'codeql_bqrs_info',\n description: 'Get metadata and information about BQRS result files',\n command: 'codeql',\n subcommand: 'bqrs info',\n inputSchema: {\n files: z.array(z.string()).describe('BQRS file(s) to examine'),\n verbose: createCodeQLSchemas.verbose(),\n additionalArgs: createCodeQLSchemas.additionalArgs()\n },\n examples: [\n 'codeql bqrs info results.bqrs',\n 'codeql bqrs info --verbose results.bqrs'\n ],\n resultProcessor: createBQRSResultProcessor()\n};", "/**\n * CodeQL BQRS interpret tool\n */\n\nimport { z } from 'zod';\nimport { CLIToolDefinition, createCodeQLSchemas, createBQRSResultProcessor } from '../../lib/cli-tool-registry';\n\nexport const codeqlBqrsInterpretTool: CLIToolDefinition = {\n name: 'codeql_bqrs_interpret',\n description: 'Interpret BQRS result files according to query metadata and generate output in specified formats (CSV, SARIF, graph formats)',\n command: 'codeql',\n subcommand: 'bqrs interpret',\n inputSchema: {\n file: z.string().describe('The BQRS file to interpret'),\n format: z.enum(['csv', 'sarif-latest', 'sarifv2.1.0', 'graphtext', 'dgml', 'dot'])\n .describe('Output format: csv (comma-separated), sarif-latest/sarifv2.1.0 (SARIF), graphtext/dgml/dot (graph formats, only for @kind graph queries)'),\n output: createCodeQLSchemas.output(),\n t: z.array(z.string())\n .describe('Query metadata key=value pairs. At least \"kind\" and \"id\" must be specified (e.g., [\"kind=graph\", \"id=js/print-ast\"])'),\n 'max-paths': z.number().optional()\n .describe('Maximum number of paths to produce for each alert with paths (default: 4)'),\n 'sarif-add-file-contents': z.boolean().optional()\n .describe('[SARIF only] Include full file contents for all files referenced in results'),\n 'sarif-add-snippets': z.boolean().optional()\n .describe('[SARIF only] Include code snippets for each location with context'),\n 'sarif-group-rules-by-pack': z.boolean().optional()\n .describe('[SARIF only] Place rule objects under their QL pack in tool.extensions property'),\n 'sarif-multicause-markdown': z.boolean().optional()\n .describe('[SARIF only] Include multi-cause alerts as Markdown-formatted lists'),\n 'sarif-category': z.string().optional()\n .describe('[SARIF only] Category for this analysis (distinguishes multiple analyses on same code)'),\n 'csv-location-format': z.enum(['uri', 'line-column', 'offset-length']).optional()\n .describe('[CSV only] Format for locations in CSV output (default: line-column)'),\n 'dot-location-url-format': z.string().optional()\n .describe('[DOT only] Format string for file location URLs (placeholders: {path}, {start:line}, {start:column}, {end:line}, {end:column}, {offset}, {length})'),\n threads: z.number().optional()\n .describe('Number of threads for computing paths (0 = one per core, -N = leave N cores unused)'),\n 'column-kind': z.enum(['utf8', 'utf16', 'utf32', 'bytes']).optional()\n .describe('[SARIF only] Column kind for interpreting location columns'),\n 'unicode-new-lines': z.boolean().optional()\n .describe('[SARIF only] Whether unicode newlines (U+2028, U+2029) are considered as newlines'),\n verbose: createCodeQLSchemas.verbose(),\n additionalArgs: createCodeQLSchemas.additionalArgs()\n },\n examples: [\n 'codeql bqrs interpret --format=sarif-latest --output=results.sarif -t kind=problem -t id=js/sql-injection results.bqrs',\n 'codeql bqrs interpret --format=graphtext --output=ast.txt -t kind=graph -t id=js/print-ast results.bqrs',\n 'codeql bqrs interpret --format=csv --csv-location-format=line-column --output=results.csv -t kind=problem -t id=js/xss results.bqrs',\n 'codeql bqrs interpret --format=dot --output=graph.dot -t kind=graph -t id=java/call-graph results.bqrs',\n 'codeql bqrs interpret --format=sarif-latest --sarif-add-snippets --sarif-category=security --output=results.sarif -t kind=path-problem -t id=go/path-injection results.bqrs'\n ],\n resultProcessor: createBQRSResultProcessor()\n};\n", "/**\n * CodeQL database analyze tool\n */\n\nimport { z } from 'zod';\nimport { CLIToolDefinition } from '../../lib/cli-tool-registry';\n\nexport const codeqlDatabaseAnalyzeTool: CLIToolDefinition = {\n name: 'codeql_database_analyze',\n description: 'Run queries or query suites against CodeQL databases',\n command: 'codeql',\n subcommand: 'database analyze',\n inputSchema: {\n database: z.string().describe('Path to the CodeQL database'),\n queries: z.string().describe('Queries or query suite to run'),\n output: z.string().optional().describe('Output file path'),\n format: z.enum(['csv', 'json', 'sarif-latest', 'sarifv2.1.0']).optional()\n .describe('Output format for results'),\n 'download-location': z.string().optional()\n .describe('Location to download missing dependencies'),\n threads: z.number().optional().describe('Number of threads to use'),\n ram: z.number().optional().describe('Amount of RAM to use (MB)'),\n timeout: z.number().optional().describe('Timeout in seconds'),\n verbose: z.boolean().optional().describe('Enable verbose output'),\n additionalArgs: z.array(z.string()).optional().describe('Additional command-line arguments')\n },\n examples: [\n 'codeql database analyze mydb queries.qls --format=sarif-latest --output=results.sarif',\n 'codeql database analyze mydb codeql/java-queries --format=csv'\n ]\n};", "/**\n * CodeQL database create tool\n */\n\nimport { z } from 'zod';\nimport { CLIToolDefinition, createDatabaseResultProcessor } from '../../lib/cli-tool-registry';\n\nexport const codeqlDatabaseCreateTool: CLIToolDefinition = {\n name: 'codeql_database_create',\n description: 'Create a CodeQL database from source code',\n command: 'codeql',\n subcommand: 'database create',\n inputSchema: {\n database: z.string().describe('Database path/name to create'),\n language: z.string().optional().describe('Programming language(s) to extract'),\n 'source-root': z.string().optional().describe('Root directory of source code'),\n command: z.string().optional().describe('Build command for compiled languages'),\n 'build-mode': z.enum(['none', 'autobuild', 'manual']).optional()\n .describe('Build mode: none (interpreted langs), autobuild, or manual'),\n threads: z.number().optional().describe('Number of threads to use'),\n ram: z.number().optional().describe('Amount of RAM to use (MB)'),\n verbose: z.boolean().optional().describe('Enable verbose output'),\n overwrite: z.boolean().optional().describe('Overwrite existing database if it exists'),\n 'no-cleanup': z.boolean().optional().describe('Skip database cleanup after finalization'),\n additionalArgs: z.array(z.string()).optional().describe('Additional command-line arguments')\n },\n examples: [\n 'codeql database create --language=java --source-root=/path/to/project mydb',\n 'codeql database create --language=cpp --command=\"make all\" mydb',\n 'codeql database create --language=python,javascript mydb'\n ],\n resultProcessor: createDatabaseResultProcessor()\n};", "/**\n * CodeQL find class position tool\n * \n * Inspired by JordyZomer/codeql-mcp repository:\n * - https://github.com/JordyZomer/codeql-mcp/blob/main/server.py\n * - https://github.com/JordyZomer/codeql-mcp/blob/main/codeqlclient.py\n */\n\nimport { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport { z } from 'zod';\nimport { readFile } from 'fs/promises';\nimport { logger } from '../../utils/logger';\n\nexport interface ClassPosition {\n start_line: number;\n start_col: number;\n end_line: number;\n end_col: number;\n}\n\n/**\n * Find the 1-based position of a class name identifier in a QL file.\n * Returns: { start_line, start_col, end_line, end_col }\n */\nexport async function findClassPosition(filepath: string, className: string): Promise {\n try {\n const content = await readFile(filepath, 'utf-8');\n const lines = content.split('\\n');\n\n for (let i = 0; i < lines.length; i++) {\n const line = lines[i];\n // Match class definition with the specific class name\n const classNameRegex = new RegExp(`\\\\bclass\\\\s+(${className.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&')})\\\\b`);\n const match = classNameRegex.exec(line);\n \n if (match) {\n const start_line = i + 1; // 1-based line numbering\n // The class name is in capture group 1\n const classNameStart = match.index + match[0].indexOf(match[1]);\n const start_col = classNameStart + 1; // 1-based column numbering\n const end_col = start_col + className.length - 1; // end_col is inclusive\n \n return {\n start_line,\n start_col,\n end_line: start_line,\n end_col\n };\n }\n }\n\n throw new Error(`Class name '${className}' not found in file: ${filepath}`);\n } catch (error) {\n if (error instanceof Error && error.message.includes('not found in file')) {\n throw error;\n }\n throw new Error(`Failed to read or parse file ${filepath}: ${error instanceof Error ? error.message : 'Unknown error'}`);\n }\n}\n\n/**\n * Register the find class position tool with the MCP server\n */\nexport function registerFindClassPositionTool(server: McpServer): void {\n server.tool(\n 'find_class_position',\n 'Finds startline, startcol, endline endcol of a class for quickeval',\n {\n file: z.string().describe('Path to the .ql file to search'),\n name: z.string().describe('Name of the class to find'),\n },\n async ({ file, name }) => {\n try {\n const position = await findClassPosition(file, name);\n return {\n content: [{ type: 'text', text: JSON.stringify(position, null, 2) }],\n };\n } catch (error) {\n logger.error('Error finding class position:', error);\n return {\n content: [\n {\n type: 'text',\n text: `Error: ${error instanceof Error ? error.message : 'Unknown error'}`,\n },\n ],\n isError: true,\n };\n }\n }\n );\n}", "/**\n * CodeQL find predicate position tool\n * \n * Inspired by JordyZomer/codeql-mcp repository:\n * - https://github.com/JordyZomer/codeql-mcp/blob/main/server.py\n * - https://github.com/JordyZomer/codeql-mcp/blob/main/codeqlclient.py\n */\n\nimport { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport { z } from 'zod';\nimport { readFile } from 'fs/promises';\nimport { logger } from '../../utils/logger';\n\nexport interface PredicatePosition {\n start_line: number;\n start_col: number;\n end_line: number;\n end_col: number;\n}\n\n/**\n * Find the 1-based position of a predicate name in a QL file.\n * Supports: \n * - predicate name(...) - predicates with no return type\n * - Type name(...) - predicates with return type (e.g., string foo())\n * - name(...) (inside class) - member predicates\n * Returns: { start_line, start_col, end_line, end_col }\n */\nexport async function findPredicatePosition(filepath: string, predicateName: string): Promise {\n try {\n const content = await readFile(filepath, 'utf-8');\n const lines = content.split('\\n');\n const escapedName = predicateName.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&');\n\n for (let i = 0; i < lines.length; i++) {\n const line = lines[i];\n \n // Match predicate definition with the specific predicate name\n // Pattern 1: predicate name(...)\n const predicateKeywordRegex = new RegExp(`\\\\bpredicate\\\\s+(${escapedName})\\\\s*\\\\(`);\n let match = predicateKeywordRegex.exec(line);\n \n // Pattern 2: Type name(...) - predicates with return type\n // Matches: string foo(), int bar(), MyClass baz(), etc.\n // Must start at beginning of line (with optional whitespace) or after certain keywords\n if (!match) {\n const returnTypeRegex = new RegExp(`(?:^|\\\\s)(?:abstract\\\\s+)?(?:cached\\\\s+)?(?:private\\\\s+)?(?:deprecated\\\\s+)?(?:\\\\w+)\\\\s+(${escapedName})\\\\s*\\\\(`);\n match = returnTypeRegex.exec(line);\n }\n \n if (match) {\n const start_line = i + 1; // 1-based line numbering\n // The predicate name is in capture group 1\n const predicateNameStart = match.index + match[0].indexOf(match[1]);\n const start_col = predicateNameStart + 1; // 1-based column numbering\n const end_col = start_col + predicateName.length - 1; // end_col is inclusive\n \n return {\n start_line,\n start_col,\n end_line: start_line,\n end_col\n };\n }\n }\n\n throw new Error(`Predicate name '${predicateName}' not found in file: ${filepath}`);\n } catch (error) {\n if (error instanceof Error && error.message.includes('not found in file')) {\n throw error;\n }\n throw new Error(`Failed to read or parse file ${filepath}: ${error instanceof Error ? error.message : 'Unknown error'}`);\n }\n}\n\n/**\n * Register the find predicate position tool with the MCP server\n */\nexport function registerFindPredicatePositionTool(server: McpServer): void {\n server.tool(\n 'find_predicate_position',\n 'Finds startline, startcol, endline endcol of a predicate for quickeval',\n {\n file: z.string().describe('Path to the .ql file to search'),\n name: z.string().describe('Name of the predicate to find'),\n },\n async ({ file, name }) => {\n try {\n const position = await findPredicatePosition(file, name);\n return {\n content: [{ type: 'text', text: JSON.stringify(position, null, 2) }],\n };\n } catch (error) {\n logger.error('Error finding predicate position:', error);\n return {\n content: [\n {\n type: 'text',\n text: `Error: ${error instanceof Error ? error.message : 'Unknown error'}`,\n },\n ],\n isError: true,\n };\n }\n }\n );\n}", "/**\n * CodeQL find query files tool\n * Discovers and tracks all files related to a CodeQL query\n */\n\nimport { z } from 'zod';\nimport { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport { findCodeQLQueryFiles } from '../../lib/query-file-finder';\nimport { logger } from '../../utils/logger';\n\n/**\n * Register the find_codeql_query_files tool\n */\nexport function registerFindCodeQLQueryFilesTool(server: McpServer): void {\n server.tool(\n 'find_codeql_query_files',\n 'Find and track all files and directories related to a CodeQL query, including resolved metadata',\n {\n queryPath: z.string().describe('Path to the CodeQL query file (.ql)'),\n language: z.string().optional().describe('Programming language (optional, will be inferred if not provided)'),\n resolveMetadata: z.boolean().optional().describe('Whether to resolve query metadata (default: true)')\n },\n async ({ queryPath, language, resolveMetadata }) => {\n try {\n const result = await findCodeQLQueryFiles(\n queryPath,\n language,\n resolveMetadata !== false // Default to true if not specified\n );\n\n return {\n content: [{ type: 'text', text: JSON.stringify(result, null, 2) }]\n };\n } catch (error) {\n logger.error('Error finding CodeQL query files:', error);\n return {\n content: [\n {\n type: 'text',\n text: `Error: ${error instanceof Error ? error.message : 'Unknown error'}`\n }\n ],\n isError: true\n };\n }\n }\n );\n}\n", "/**\n * CodeQL query file finder utilities\n * Handles discovery and tracking of query-related files and directories\n */\n\nimport * as fs from 'fs';\nimport * as path from 'path';\nimport * as yaml from 'js-yaml';\nimport { QueryFileInfo, QueryFilesResult } from '../types/codeql';\nimport { resolveQueryMetadata } from './metadata-resolver';\n\n// Supported CodeQL languages and their file extensions (alphabetically ordered)\nconst LANGUAGE_EXTENSIONS: Record = {\n actions: 'yml',\n cpp: 'cpp',\n csharp: 'cs',\n go: 'go',\n java: 'java',\n javascript: 'js',\n python: 'py',\n ruby: 'rb',\n swift: 'swift',\n typescript: 'ts'\n};\n\nconst KNOWN_LANGUAGES = Object.keys(LANGUAGE_EXTENSIONS);\n\n/**\n * Get the file extension for test code based on language\n */\nfunction getLanguageExtension(language: string): string {\n return LANGUAGE_EXTENSIONS[language.toLowerCase()] || 'txt';\n}\n\n/**\n * Infer the language from the query file's directory structure\n */\nfunction inferLanguageFromPath(queryPath: string): string {\n const parts = queryPath.split(path.sep);\n\n for (const part of parts) {\n if (KNOWN_LANGUAGES.includes(part.toLowerCase())) {\n return part.toLowerCase();\n }\n }\n\n // Default fallback\n return 'unknown';\n}\n\n/**\n * Find the nearest qlpack.yml or codeql-pack.yml file by walking up the directory tree\n */\nfunction findNearestQlpack(startPath: string): string | null {\n let currentPath = startPath;\n const root = path.parse(currentPath).root;\n\n while (currentPath !== root) {\n // Check for codeql-pack.yml first (newer format), then qlpack.yml\n for (const packFile of ['codeql-pack.yml', 'qlpack.yml']) {\n const packPath = path.join(currentPath, packFile);\n if (fs.existsSync(packPath) && fs.statSync(packPath).isFile()) {\n return packPath;\n }\n }\n currentPath = path.dirname(currentPath);\n }\n\n return null;\n}\n\n/**\n * Read and parse qlpack.yml file\n */\nfunction readQlpackMetadata(qlpackPath: string): Record | null {\n try {\n const content = fs.readFileSync(qlpackPath, 'utf-8');\n const parsed = yaml.load(content) as Record;\n return parsed;\n } catch (_error) {\n // If we can't parse it, return null rather than failing\n return null;\n }\n}\n\n/**\n * Check if a file exists and return QueryFileInfo\n */\nfunction checkFile(filePath: string): QueryFileInfo {\n try {\n const exists = fs.existsSync(filePath) && fs.statSync(filePath).isFile();\n return {\n exists,\n path: filePath // Always return path, whether it exists or not\n };\n } catch {\n return {\n exists: false,\n path: filePath // Return the path even on error\n };\n }\n}\n\n/**\n * Check if a directory exists and return QueryFileInfo\n */\nfunction checkDirectory(dirPath: string): QueryFileInfo {\n try {\n const exists = fs.existsSync(dirPath) && fs.statSync(dirPath).isDirectory();\n return {\n exists,\n path: dirPath // Always return path, whether it exists or not\n };\n } catch {\n return {\n exists: false,\n path: dirPath // Return the path even on error\n };\n }\n}\n\n/**\n * Find all test code files in the test directory\n */\nfunction findTestCodeFiles(testDir: string, queryName: string, language: string): string[] {\n if (!fs.existsSync(testDir)) {\n return [];\n }\n\n try {\n const files = fs.readdirSync(testDir);\n const languageExt = getLanguageExtension(language);\n const testFiles: string[] = [];\n\n // Look for files matching the query name or other test code files\n const allValidExtensions = [...new Set([...Object.values(LANGUAGE_EXTENSIONS), 'yaml'])]; // Include yaml as alias for yml\n\n for (const file of files) {\n const filePath = path.join(testDir, file);\n const stat = fs.statSync(filePath);\n\n if (stat.isFile()) {\n // Include the primary test file matching query name\n if (file === `${queryName}.${languageExt}`) {\n testFiles.push(filePath);\n }\n // Include other code files (but not .qlref, .expected, .actual files)\n else if (!file.endsWith('.qlref') && !file.endsWith('.expected') && !file.endsWith('.actual')) {\n const ext = path.extname(file).slice(1);\n if (ext === languageExt || allValidExtensions.includes(ext)) {\n testFiles.push(filePath);\n }\n }\n }\n }\n\n return testFiles;\n } catch {\n return [];\n }\n}\n\n/**\n * Find CodeQL query files and directories based on a query file path\n * Optionally resolves metadata if the query file exists\n */\nexport async function findCodeQLQueryFiles(\n queryFilePath: string,\n language?: string,\n resolveMetadata: boolean = true\n): Promise {\n // Resolve absolute path\n const absoluteQueryPath = path.resolve(queryFilePath);\n\n // Extract query name and directory\n const queryName = path.basename(absoluteQueryPath, '.ql');\n const queryDir = path.dirname(absoluteQueryPath);\n\n // Infer language if not provided\n const detectedLanguage = language || inferLanguageFromPath(absoluteQueryPath);\n\n // Check query file itself\n const queryPath = checkFile(absoluteQueryPath);\n const queryDirectory = checkDirectory(queryDir);\n\n // Check for documentation files\n const mdPath = path.join(queryDir, `${queryName}.md`);\n const qhelpPath = path.join(queryDir, `${queryName}.qhelp`);\n const mdInfo = checkFile(mdPath);\n const qhelpInfo = checkFile(qhelpPath);\n\n const documentationPath: QueryFileInfo = mdInfo.exists ? mdInfo : (qhelpInfo.exists ? qhelpInfo : {\n exists: false,\n path: mdPath // Suggest .md as the default\n });\n\n // Check for specification file\n const qspecPath = path.join(queryDir, `${queryName}.qspec`);\n const specificationPath = checkFile(qspecPath);\n\n // Determine test directory\n // Pattern: if query is in .../src/QueryName/, test should be in .../test/QueryName/\n let testDir: string;\n if (queryDir.includes(`${path.sep}src${path.sep}`)) {\n // Find the last occurrence of /src/ and replace it with /test/\n const parts = queryDir.split(path.sep);\n const srcIndex = parts.lastIndexOf('src');\n if (srcIndex !== -1) {\n parts[srcIndex] = 'test';\n testDir = parts.join(path.sep);\n } else {\n // Fallback in case split didn't find it\n testDir = path.join(path.dirname(queryDir), 'test', queryName);\n }\n } else {\n // Fallback: if not in src directory, construct test dir based on parent\n testDir = path.join(path.dirname(queryDir), 'test', queryName);\n }\n const testDirectory = checkDirectory(testDir);\n\n // Check for .qlref file\n const qlrefPath = path.join(testDir, `${queryName}.qlref`);\n const qlrefInfo = checkFile(qlrefPath);\n\n // Find test code files\n const testCodePaths = findTestCodeFiles(testDir, queryName, detectedLanguage);\n\n // Check for expected results\n const expectedPath = path.join(testDir, `${queryName}.expected`);\n const expectedResultsPath = checkFile(expectedPath);\n\n // Check for actual results\n const actualPath = path.join(testDir, `${queryName}.actual`);\n const actualResultsPath = checkFile(actualPath);\n\n // Check for test database\n const testprojPath = path.join(testDir, `${queryName}.testproj`);\n const testDatabasePath = checkDirectory(testprojPath);\n\n // Determine missing files\n const missingFiles: string[] = [];\n if (!queryPath.exists) missingFiles.push(queryPath.path);\n if (!documentationPath.exists) missingFiles.push(documentationPath.path);\n if (!specificationPath.exists) missingFiles.push(specificationPath.path);\n if (!testDirectory.exists) missingFiles.push(testDirectory.path);\n if (!qlrefInfo.exists) missingFiles.push(qlrefInfo.path);\n if (testCodePaths.length === 0) missingFiles.push(path.join(testDir, `${queryName}.${getLanguageExtension(detectedLanguage)}`));\n if (!expectedResultsPath.exists) missingFiles.push(expectedResultsPath.path);\n\n const allFilesExist = missingFiles.length === 0;\n\n // Resolve metadata if requested and query file exists\n let metadata: { [key: string]: string | string[] } | undefined;\n if (resolveMetadata && queryPath.exists) {\n const resolvedMetadata = await resolveQueryMetadata(absoluteQueryPath);\n if (resolvedMetadata) {\n metadata = resolvedMetadata;\n }\n }\n\n // Resolve pack metadata and directories by finding the nearest qlpack.yml files\n let packMetadata: Record | undefined;\n const queryPackPath = findNearestQlpack(queryDir);\n const queryPackDir = queryPackPath ? path.dirname(queryPackPath) : queryDir;\n if (queryPackPath) {\n const parsed = readQlpackMetadata(queryPackPath);\n if (parsed) {\n packMetadata = parsed;\n }\n }\n\n // Find pack directory for test files\n const testPackPath = findNearestQlpack(testDir);\n const testPackDir = testPackPath ? path.dirname(testPackPath) : testDir;\n\n return {\n queryName,\n language: detectedLanguage,\n\n allFilesExist,\n\n files: {\n query: {\n dir: queryDirectory.path,\n doc: path.basename(documentationPath.path),\n packDir: queryPackDir,\n query: path.basename(queryPath.path),\n spec: path.basename(specificationPath.path)\n },\n test: {\n actual: path.basename(actualResultsPath.path),\n dir: testDirectory.path,\n expected: path.basename(expectedResultsPath.path),\n packDir: testPackDir,\n qlref: path.basename(qlrefInfo.path),\n testCode: testCodePaths,\n testDatabaseDir: testDatabasePath.path\n }\n },\n\n metadata,\n\n missingFiles,\n\n packMetadata,\n\n status: {\n actualResultsExist: actualResultsPath.exists,\n documentationExists: documentationPath.exists,\n expectedResultsExist: expectedResultsPath.exists,\n hasTestCode: testCodePaths.length > 0,\n qlrefExists: qlrefInfo.exists,\n queryExists: queryPath.exists,\n specificationExists: specificationPath.exists,\n testDatabaseDirExists: testDatabasePath.exists,\n testDirectoryExists: testDirectory.exists\n }\n };\n}\n", "\n/*! js-yaml 4.1.1 https://github.com/nodeca/js-yaml @license MIT */\nfunction isNothing(subject) {\n return (typeof subject === 'undefined') || (subject === null);\n}\n\n\nfunction isObject(subject) {\n return (typeof subject === 'object') && (subject !== null);\n}\n\n\nfunction toArray(sequence) {\n if (Array.isArray(sequence)) return sequence;\n else if (isNothing(sequence)) return [];\n\n return [ sequence ];\n}\n\n\nfunction extend(target, source) {\n var index, length, key, sourceKeys;\n\n if (source) {\n sourceKeys = Object.keys(source);\n\n for (index = 0, length = sourceKeys.length; index < length; index += 1) {\n key = sourceKeys[index];\n target[key] = source[key];\n }\n }\n\n return target;\n}\n\n\nfunction repeat(string, count) {\n var result = '', cycle;\n\n for (cycle = 0; cycle < count; cycle += 1) {\n result += string;\n }\n\n return result;\n}\n\n\nfunction isNegativeZero(number) {\n return (number === 0) && (Number.NEGATIVE_INFINITY === 1 / number);\n}\n\n\nvar isNothing_1 = isNothing;\nvar isObject_1 = isObject;\nvar toArray_1 = toArray;\nvar repeat_1 = repeat;\nvar isNegativeZero_1 = isNegativeZero;\nvar extend_1 = extend;\n\nvar common = {\n\tisNothing: isNothing_1,\n\tisObject: isObject_1,\n\ttoArray: toArray_1,\n\trepeat: repeat_1,\n\tisNegativeZero: isNegativeZero_1,\n\textend: extend_1\n};\n\n// YAML error class. http://stackoverflow.com/questions/8458984\n\n\nfunction formatError(exception, compact) {\n var where = '', message = exception.reason || '(unknown reason)';\n\n if (!exception.mark) return message;\n\n if (exception.mark.name) {\n where += 'in \"' + exception.mark.name + '\" ';\n }\n\n where += '(' + (exception.mark.line + 1) + ':' + (exception.mark.column + 1) + ')';\n\n if (!compact && exception.mark.snippet) {\n where += '\\n\\n' + exception.mark.snippet;\n }\n\n return message + ' ' + where;\n}\n\n\nfunction YAMLException$1(reason, mark) {\n // Super constructor\n Error.call(this);\n\n this.name = 'YAMLException';\n this.reason = reason;\n this.mark = mark;\n this.message = formatError(this, false);\n\n // Include stack trace in error object\n if (Error.captureStackTrace) {\n // Chrome and NodeJS\n Error.captureStackTrace(this, this.constructor);\n } else {\n // FF, IE 10+ and Safari 6+. Fallback for others\n this.stack = (new Error()).stack || '';\n }\n}\n\n\n// Inherit from Error\nYAMLException$1.prototype = Object.create(Error.prototype);\nYAMLException$1.prototype.constructor = YAMLException$1;\n\n\nYAMLException$1.prototype.toString = function toString(compact) {\n return this.name + ': ' + formatError(this, compact);\n};\n\n\nvar exception = YAMLException$1;\n\n// get snippet for a single line, respecting maxLength\nfunction getLine(buffer, lineStart, lineEnd, position, maxLineLength) {\n var head = '';\n var tail = '';\n var maxHalfLength = Math.floor(maxLineLength / 2) - 1;\n\n if (position - lineStart > maxHalfLength) {\n head = ' ... ';\n lineStart = position - maxHalfLength + head.length;\n }\n\n if (lineEnd - position > maxHalfLength) {\n tail = ' ...';\n lineEnd = position + maxHalfLength - tail.length;\n }\n\n return {\n str: head + buffer.slice(lineStart, lineEnd).replace(/\\t/g, '\u2192') + tail,\n pos: position - lineStart + head.length // relative position\n };\n}\n\n\nfunction padStart(string, max) {\n return common.repeat(' ', max - string.length) + string;\n}\n\n\nfunction makeSnippet(mark, options) {\n options = Object.create(options || null);\n\n if (!mark.buffer) return null;\n\n if (!options.maxLength) options.maxLength = 79;\n if (typeof options.indent !== 'number') options.indent = 1;\n if (typeof options.linesBefore !== 'number') options.linesBefore = 3;\n if (typeof options.linesAfter !== 'number') options.linesAfter = 2;\n\n var re = /\\r?\\n|\\r|\\0/g;\n var lineStarts = [ 0 ];\n var lineEnds = [];\n var match;\n var foundLineNo = -1;\n\n while ((match = re.exec(mark.buffer))) {\n lineEnds.push(match.index);\n lineStarts.push(match.index + match[0].length);\n\n if (mark.position <= match.index && foundLineNo < 0) {\n foundLineNo = lineStarts.length - 2;\n }\n }\n\n if (foundLineNo < 0) foundLineNo = lineStarts.length - 1;\n\n var result = '', i, line;\n var lineNoLength = Math.min(mark.line + options.linesAfter, lineEnds.length).toString().length;\n var maxLineLength = options.maxLength - (options.indent + lineNoLength + 3);\n\n for (i = 1; i <= options.linesBefore; i++) {\n if (foundLineNo - i < 0) break;\n line = getLine(\n mark.buffer,\n lineStarts[foundLineNo - i],\n lineEnds[foundLineNo - i],\n mark.position - (lineStarts[foundLineNo] - lineStarts[foundLineNo - i]),\n maxLineLength\n );\n result = common.repeat(' ', options.indent) + padStart((mark.line - i + 1).toString(), lineNoLength) +\n ' | ' + line.str + '\\n' + result;\n }\n\n line = getLine(mark.buffer, lineStarts[foundLineNo], lineEnds[foundLineNo], mark.position, maxLineLength);\n result += common.repeat(' ', options.indent) + padStart((mark.line + 1).toString(), lineNoLength) +\n ' | ' + line.str + '\\n';\n result += common.repeat('-', options.indent + lineNoLength + 3 + line.pos) + '^' + '\\n';\n\n for (i = 1; i <= options.linesAfter; i++) {\n if (foundLineNo + i >= lineEnds.length) break;\n line = getLine(\n mark.buffer,\n lineStarts[foundLineNo + i],\n lineEnds[foundLineNo + i],\n mark.position - (lineStarts[foundLineNo] - lineStarts[foundLineNo + i]),\n maxLineLength\n );\n result += common.repeat(' ', options.indent) + padStart((mark.line + i + 1).toString(), lineNoLength) +\n ' | ' + line.str + '\\n';\n }\n\n return result.replace(/\\n$/, '');\n}\n\n\nvar snippet = makeSnippet;\n\nvar TYPE_CONSTRUCTOR_OPTIONS = [\n 'kind',\n 'multi',\n 'resolve',\n 'construct',\n 'instanceOf',\n 'predicate',\n 'represent',\n 'representName',\n 'defaultStyle',\n 'styleAliases'\n];\n\nvar YAML_NODE_KINDS = [\n 'scalar',\n 'sequence',\n 'mapping'\n];\n\nfunction compileStyleAliases(map) {\n var result = {};\n\n if (map !== null) {\n Object.keys(map).forEach(function (style) {\n map[style].forEach(function (alias) {\n result[String(alias)] = style;\n });\n });\n }\n\n return result;\n}\n\nfunction Type$1(tag, options) {\n options = options || {};\n\n Object.keys(options).forEach(function (name) {\n if (TYPE_CONSTRUCTOR_OPTIONS.indexOf(name) === -1) {\n throw new exception('Unknown option \"' + name + '\" is met in definition of \"' + tag + '\" YAML type.');\n }\n });\n\n // TODO: Add tag format check.\n this.options = options; // keep original options in case user wants to extend this type later\n this.tag = tag;\n this.kind = options['kind'] || null;\n this.resolve = options['resolve'] || function () { return true; };\n this.construct = options['construct'] || function (data) { return data; };\n this.instanceOf = options['instanceOf'] || null;\n this.predicate = options['predicate'] || null;\n this.represent = options['represent'] || null;\n this.representName = options['representName'] || null;\n this.defaultStyle = options['defaultStyle'] || null;\n this.multi = options['multi'] || false;\n this.styleAliases = compileStyleAliases(options['styleAliases'] || null);\n\n if (YAML_NODE_KINDS.indexOf(this.kind) === -1) {\n throw new exception('Unknown kind \"' + this.kind + '\" is specified for \"' + tag + '\" YAML type.');\n }\n}\n\nvar type = Type$1;\n\n/*eslint-disable max-len*/\n\n\n\n\n\nfunction compileList(schema, name) {\n var result = [];\n\n schema[name].forEach(function (currentType) {\n var newIndex = result.length;\n\n result.forEach(function (previousType, previousIndex) {\n if (previousType.tag === currentType.tag &&\n previousType.kind === currentType.kind &&\n previousType.multi === currentType.multi) {\n\n newIndex = previousIndex;\n }\n });\n\n result[newIndex] = currentType;\n });\n\n return result;\n}\n\n\nfunction compileMap(/* lists... */) {\n var result = {\n scalar: {},\n sequence: {},\n mapping: {},\n fallback: {},\n multi: {\n scalar: [],\n sequence: [],\n mapping: [],\n fallback: []\n }\n }, index, length;\n\n function collectType(type) {\n if (type.multi) {\n result.multi[type.kind].push(type);\n result.multi['fallback'].push(type);\n } else {\n result[type.kind][type.tag] = result['fallback'][type.tag] = type;\n }\n }\n\n for (index = 0, length = arguments.length; index < length; index += 1) {\n arguments[index].forEach(collectType);\n }\n return result;\n}\n\n\nfunction Schema$1(definition) {\n return this.extend(definition);\n}\n\n\nSchema$1.prototype.extend = function extend(definition) {\n var implicit = [];\n var explicit = [];\n\n if (definition instanceof type) {\n // Schema.extend(type)\n explicit.push(definition);\n\n } else if (Array.isArray(definition)) {\n // Schema.extend([ type1, type2, ... ])\n explicit = explicit.concat(definition);\n\n } else if (definition && (Array.isArray(definition.implicit) || Array.isArray(definition.explicit))) {\n // Schema.extend({ explicit: [ type1, type2, ... ], implicit: [ type1, type2, ... ] })\n if (definition.implicit) implicit = implicit.concat(definition.implicit);\n if (definition.explicit) explicit = explicit.concat(definition.explicit);\n\n } else {\n throw new exception('Schema.extend argument should be a Type, [ Type ], ' +\n 'or a schema definition ({ implicit: [...], explicit: [...] })');\n }\n\n implicit.forEach(function (type$1) {\n if (!(type$1 instanceof type)) {\n throw new exception('Specified list of YAML types (or a single Type object) contains a non-Type object.');\n }\n\n if (type$1.loadKind && type$1.loadKind !== 'scalar') {\n throw new exception('There is a non-scalar type in the implicit list of a schema. Implicit resolving of such types is not supported.');\n }\n\n if (type$1.multi) {\n throw new exception('There is a multi type in the implicit list of a schema. Multi tags can only be listed as explicit.');\n }\n });\n\n explicit.forEach(function (type$1) {\n if (!(type$1 instanceof type)) {\n throw new exception('Specified list of YAML types (or a single Type object) contains a non-Type object.');\n }\n });\n\n var result = Object.create(Schema$1.prototype);\n\n result.implicit = (this.implicit || []).concat(implicit);\n result.explicit = (this.explicit || []).concat(explicit);\n\n result.compiledImplicit = compileList(result, 'implicit');\n result.compiledExplicit = compileList(result, 'explicit');\n result.compiledTypeMap = compileMap(result.compiledImplicit, result.compiledExplicit);\n\n return result;\n};\n\n\nvar schema = Schema$1;\n\nvar str = new type('tag:yaml.org,2002:str', {\n kind: 'scalar',\n construct: function (data) { return data !== null ? data : ''; }\n});\n\nvar seq = new type('tag:yaml.org,2002:seq', {\n kind: 'sequence',\n construct: function (data) { return data !== null ? data : []; }\n});\n\nvar map = new type('tag:yaml.org,2002:map', {\n kind: 'mapping',\n construct: function (data) { return data !== null ? data : {}; }\n});\n\nvar failsafe = new schema({\n explicit: [\n str,\n seq,\n map\n ]\n});\n\nfunction resolveYamlNull(data) {\n if (data === null) return true;\n\n var max = data.length;\n\n return (max === 1 && data === '~') ||\n (max === 4 && (data === 'null' || data === 'Null' || data === 'NULL'));\n}\n\nfunction constructYamlNull() {\n return null;\n}\n\nfunction isNull(object) {\n return object === null;\n}\n\nvar _null = new type('tag:yaml.org,2002:null', {\n kind: 'scalar',\n resolve: resolveYamlNull,\n construct: constructYamlNull,\n predicate: isNull,\n represent: {\n canonical: function () { return '~'; },\n lowercase: function () { return 'null'; },\n uppercase: function () { return 'NULL'; },\n camelcase: function () { return 'Null'; },\n empty: function () { return ''; }\n },\n defaultStyle: 'lowercase'\n});\n\nfunction resolveYamlBoolean(data) {\n if (data === null) return false;\n\n var max = data.length;\n\n return (max === 4 && (data === 'true' || data === 'True' || data === 'TRUE')) ||\n (max === 5 && (data === 'false' || data === 'False' || data === 'FALSE'));\n}\n\nfunction constructYamlBoolean(data) {\n return data === 'true' ||\n data === 'True' ||\n data === 'TRUE';\n}\n\nfunction isBoolean(object) {\n return Object.prototype.toString.call(object) === '[object Boolean]';\n}\n\nvar bool = new type('tag:yaml.org,2002:bool', {\n kind: 'scalar',\n resolve: resolveYamlBoolean,\n construct: constructYamlBoolean,\n predicate: isBoolean,\n represent: {\n lowercase: function (object) { return object ? 'true' : 'false'; },\n uppercase: function (object) { return object ? 'TRUE' : 'FALSE'; },\n camelcase: function (object) { return object ? 'True' : 'False'; }\n },\n defaultStyle: 'lowercase'\n});\n\nfunction isHexCode(c) {\n return ((0x30/* 0 */ <= c) && (c <= 0x39/* 9 */)) ||\n ((0x41/* A */ <= c) && (c <= 0x46/* F */)) ||\n ((0x61/* a */ <= c) && (c <= 0x66/* f */));\n}\n\nfunction isOctCode(c) {\n return ((0x30/* 0 */ <= c) && (c <= 0x37/* 7 */));\n}\n\nfunction isDecCode(c) {\n return ((0x30/* 0 */ <= c) && (c <= 0x39/* 9 */));\n}\n\nfunction resolveYamlInteger(data) {\n if (data === null) return false;\n\n var max = data.length,\n index = 0,\n hasDigits = false,\n ch;\n\n if (!max) return false;\n\n ch = data[index];\n\n // sign\n if (ch === '-' || ch === '+') {\n ch = data[++index];\n }\n\n if (ch === '0') {\n // 0\n if (index + 1 === max) return true;\n ch = data[++index];\n\n // base 2, base 8, base 16\n\n if (ch === 'b') {\n // base 2\n index++;\n\n for (; index < max; index++) {\n ch = data[index];\n if (ch === '_') continue;\n if (ch !== '0' && ch !== '1') return false;\n hasDigits = true;\n }\n return hasDigits && ch !== '_';\n }\n\n\n if (ch === 'x') {\n // base 16\n index++;\n\n for (; index < max; index++) {\n ch = data[index];\n if (ch === '_') continue;\n if (!isHexCode(data.charCodeAt(index))) return false;\n hasDigits = true;\n }\n return hasDigits && ch !== '_';\n }\n\n\n if (ch === 'o') {\n // base 8\n index++;\n\n for (; index < max; index++) {\n ch = data[index];\n if (ch === '_') continue;\n if (!isOctCode(data.charCodeAt(index))) return false;\n hasDigits = true;\n }\n return hasDigits && ch !== '_';\n }\n }\n\n // base 10 (except 0)\n\n // value should not start with `_`;\n if (ch === '_') return false;\n\n for (; index < max; index++) {\n ch = data[index];\n if (ch === '_') continue;\n if (!isDecCode(data.charCodeAt(index))) {\n return false;\n }\n hasDigits = true;\n }\n\n // Should have digits and should not end with `_`\n if (!hasDigits || ch === '_') return false;\n\n return true;\n}\n\nfunction constructYamlInteger(data) {\n var value = data, sign = 1, ch;\n\n if (value.indexOf('_') !== -1) {\n value = value.replace(/_/g, '');\n }\n\n ch = value[0];\n\n if (ch === '-' || ch === '+') {\n if (ch === '-') sign = -1;\n value = value.slice(1);\n ch = value[0];\n }\n\n if (value === '0') return 0;\n\n if (ch === '0') {\n if (value[1] === 'b') return sign * parseInt(value.slice(2), 2);\n if (value[1] === 'x') return sign * parseInt(value.slice(2), 16);\n if (value[1] === 'o') return sign * parseInt(value.slice(2), 8);\n }\n\n return sign * parseInt(value, 10);\n}\n\nfunction isInteger(object) {\n return (Object.prototype.toString.call(object)) === '[object Number]' &&\n (object % 1 === 0 && !common.isNegativeZero(object));\n}\n\nvar int = new type('tag:yaml.org,2002:int', {\n kind: 'scalar',\n resolve: resolveYamlInteger,\n construct: constructYamlInteger,\n predicate: isInteger,\n represent: {\n binary: function (obj) { return obj >= 0 ? '0b' + obj.toString(2) : '-0b' + obj.toString(2).slice(1); },\n octal: function (obj) { return obj >= 0 ? '0o' + obj.toString(8) : '-0o' + obj.toString(8).slice(1); },\n decimal: function (obj) { return obj.toString(10); },\n /* eslint-disable max-len */\n hexadecimal: function (obj) { return obj >= 0 ? '0x' + obj.toString(16).toUpperCase() : '-0x' + obj.toString(16).toUpperCase().slice(1); }\n },\n defaultStyle: 'decimal',\n styleAliases: {\n binary: [ 2, 'bin' ],\n octal: [ 8, 'oct' ],\n decimal: [ 10, 'dec' ],\n hexadecimal: [ 16, 'hex' ]\n }\n});\n\nvar YAML_FLOAT_PATTERN = new RegExp(\n // 2.5e4, 2.5 and integers\n '^(?:[-+]?(?:[0-9][0-9_]*)(?:\\\\.[0-9_]*)?(?:[eE][-+]?[0-9]+)?' +\n // .2e4, .2\n // special case, seems not from spec\n '|\\\\.[0-9_]+(?:[eE][-+]?[0-9]+)?' +\n // .inf\n '|[-+]?\\\\.(?:inf|Inf|INF)' +\n // .nan\n '|\\\\.(?:nan|NaN|NAN))$');\n\nfunction resolveYamlFloat(data) {\n if (data === null) return false;\n\n if (!YAML_FLOAT_PATTERN.test(data) ||\n // Quick hack to not allow integers end with `_`\n // Probably should update regexp & check speed\n data[data.length - 1] === '_') {\n return false;\n }\n\n return true;\n}\n\nfunction constructYamlFloat(data) {\n var value, sign;\n\n value = data.replace(/_/g, '').toLowerCase();\n sign = value[0] === '-' ? -1 : 1;\n\n if ('+-'.indexOf(value[0]) >= 0) {\n value = value.slice(1);\n }\n\n if (value === '.inf') {\n return (sign === 1) ? Number.POSITIVE_INFINITY : Number.NEGATIVE_INFINITY;\n\n } else if (value === '.nan') {\n return NaN;\n }\n return sign * parseFloat(value, 10);\n}\n\n\nvar SCIENTIFIC_WITHOUT_DOT = /^[-+]?[0-9]+e/;\n\nfunction representYamlFloat(object, style) {\n var res;\n\n if (isNaN(object)) {\n switch (style) {\n case 'lowercase': return '.nan';\n case 'uppercase': return '.NAN';\n case 'camelcase': return '.NaN';\n }\n } else if (Number.POSITIVE_INFINITY === object) {\n switch (style) {\n case 'lowercase': return '.inf';\n case 'uppercase': return '.INF';\n case 'camelcase': return '.Inf';\n }\n } else if (Number.NEGATIVE_INFINITY === object) {\n switch (style) {\n case 'lowercase': return '-.inf';\n case 'uppercase': return '-.INF';\n case 'camelcase': return '-.Inf';\n }\n } else if (common.isNegativeZero(object)) {\n return '-0.0';\n }\n\n res = object.toString(10);\n\n // JS stringifier can build scientific format without dots: 5e-100,\n // while YAML requres dot: 5.e-100. Fix it with simple hack\n\n return SCIENTIFIC_WITHOUT_DOT.test(res) ? res.replace('e', '.e') : res;\n}\n\nfunction isFloat(object) {\n return (Object.prototype.toString.call(object) === '[object Number]') &&\n (object % 1 !== 0 || common.isNegativeZero(object));\n}\n\nvar float = new type('tag:yaml.org,2002:float', {\n kind: 'scalar',\n resolve: resolveYamlFloat,\n construct: constructYamlFloat,\n predicate: isFloat,\n represent: representYamlFloat,\n defaultStyle: 'lowercase'\n});\n\nvar json = failsafe.extend({\n implicit: [\n _null,\n bool,\n int,\n float\n ]\n});\n\nvar core = json;\n\nvar YAML_DATE_REGEXP = new RegExp(\n '^([0-9][0-9][0-9][0-9])' + // [1] year\n '-([0-9][0-9])' + // [2] month\n '-([0-9][0-9])$'); // [3] day\n\nvar YAML_TIMESTAMP_REGEXP = new RegExp(\n '^([0-9][0-9][0-9][0-9])' + // [1] year\n '-([0-9][0-9]?)' + // [2] month\n '-([0-9][0-9]?)' + // [3] day\n '(?:[Tt]|[ \\\\t]+)' + // ...\n '([0-9][0-9]?)' + // [4] hour\n ':([0-9][0-9])' + // [5] minute\n ':([0-9][0-9])' + // [6] second\n '(?:\\\\.([0-9]*))?' + // [7] fraction\n '(?:[ \\\\t]*(Z|([-+])([0-9][0-9]?)' + // [8] tz [9] tz_sign [10] tz_hour\n '(?::([0-9][0-9]))?))?$'); // [11] tz_minute\n\nfunction resolveYamlTimestamp(data) {\n if (data === null) return false;\n if (YAML_DATE_REGEXP.exec(data) !== null) return true;\n if (YAML_TIMESTAMP_REGEXP.exec(data) !== null) return true;\n return false;\n}\n\nfunction constructYamlTimestamp(data) {\n var match, year, month, day, hour, minute, second, fraction = 0,\n delta = null, tz_hour, tz_minute, date;\n\n match = YAML_DATE_REGEXP.exec(data);\n if (match === null) match = YAML_TIMESTAMP_REGEXP.exec(data);\n\n if (match === null) throw new Error('Date resolve error');\n\n // match: [1] year [2] month [3] day\n\n year = +(match[1]);\n month = +(match[2]) - 1; // JS month starts with 0\n day = +(match[3]);\n\n if (!match[4]) { // no hour\n return new Date(Date.UTC(year, month, day));\n }\n\n // match: [4] hour [5] minute [6] second [7] fraction\n\n hour = +(match[4]);\n minute = +(match[5]);\n second = +(match[6]);\n\n if (match[7]) {\n fraction = match[7].slice(0, 3);\n while (fraction.length < 3) { // milli-seconds\n fraction += '0';\n }\n fraction = +fraction;\n }\n\n // match: [8] tz [9] tz_sign [10] tz_hour [11] tz_minute\n\n if (match[9]) {\n tz_hour = +(match[10]);\n tz_minute = +(match[11] || 0);\n delta = (tz_hour * 60 + tz_minute) * 60000; // delta in mili-seconds\n if (match[9] === '-') delta = -delta;\n }\n\n date = new Date(Date.UTC(year, month, day, hour, minute, second, fraction));\n\n if (delta) date.setTime(date.getTime() - delta);\n\n return date;\n}\n\nfunction representYamlTimestamp(object /*, style*/) {\n return object.toISOString();\n}\n\nvar timestamp = new type('tag:yaml.org,2002:timestamp', {\n kind: 'scalar',\n resolve: resolveYamlTimestamp,\n construct: constructYamlTimestamp,\n instanceOf: Date,\n represent: representYamlTimestamp\n});\n\nfunction resolveYamlMerge(data) {\n return data === '<<' || data === null;\n}\n\nvar merge = new type('tag:yaml.org,2002:merge', {\n kind: 'scalar',\n resolve: resolveYamlMerge\n});\n\n/*eslint-disable no-bitwise*/\n\n\n\n\n\n// [ 64, 65, 66 ] -> [ padding, CR, LF ]\nvar BASE64_MAP = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=\\n\\r';\n\n\nfunction resolveYamlBinary(data) {\n if (data === null) return false;\n\n var code, idx, bitlen = 0, max = data.length, map = BASE64_MAP;\n\n // Convert one by one.\n for (idx = 0; idx < max; idx++) {\n code = map.indexOf(data.charAt(idx));\n\n // Skip CR/LF\n if (code > 64) continue;\n\n // Fail on illegal characters\n if (code < 0) return false;\n\n bitlen += 6;\n }\n\n // If there are any bits left, source was corrupted\n return (bitlen % 8) === 0;\n}\n\nfunction constructYamlBinary(data) {\n var idx, tailbits,\n input = data.replace(/[\\r\\n=]/g, ''), // remove CR/LF & padding to simplify scan\n max = input.length,\n map = BASE64_MAP,\n bits = 0,\n result = [];\n\n // Collect by 6*4 bits (3 bytes)\n\n for (idx = 0; idx < max; idx++) {\n if ((idx % 4 === 0) && idx) {\n result.push((bits >> 16) & 0xFF);\n result.push((bits >> 8) & 0xFF);\n result.push(bits & 0xFF);\n }\n\n bits = (bits << 6) | map.indexOf(input.charAt(idx));\n }\n\n // Dump tail\n\n tailbits = (max % 4) * 6;\n\n if (tailbits === 0) {\n result.push((bits >> 16) & 0xFF);\n result.push((bits >> 8) & 0xFF);\n result.push(bits & 0xFF);\n } else if (tailbits === 18) {\n result.push((bits >> 10) & 0xFF);\n result.push((bits >> 2) & 0xFF);\n } else if (tailbits === 12) {\n result.push((bits >> 4) & 0xFF);\n }\n\n return new Uint8Array(result);\n}\n\nfunction representYamlBinary(object /*, style*/) {\n var result = '', bits = 0, idx, tail,\n max = object.length,\n map = BASE64_MAP;\n\n // Convert every three bytes to 4 ASCII characters.\n\n for (idx = 0; idx < max; idx++) {\n if ((idx % 3 === 0) && idx) {\n result += map[(bits >> 18) & 0x3F];\n result += map[(bits >> 12) & 0x3F];\n result += map[(bits >> 6) & 0x3F];\n result += map[bits & 0x3F];\n }\n\n bits = (bits << 8) + object[idx];\n }\n\n // Dump tail\n\n tail = max % 3;\n\n if (tail === 0) {\n result += map[(bits >> 18) & 0x3F];\n result += map[(bits >> 12) & 0x3F];\n result += map[(bits >> 6) & 0x3F];\n result += map[bits & 0x3F];\n } else if (tail === 2) {\n result += map[(bits >> 10) & 0x3F];\n result += map[(bits >> 4) & 0x3F];\n result += map[(bits << 2) & 0x3F];\n result += map[64];\n } else if (tail === 1) {\n result += map[(bits >> 2) & 0x3F];\n result += map[(bits << 4) & 0x3F];\n result += map[64];\n result += map[64];\n }\n\n return result;\n}\n\nfunction isBinary(obj) {\n return Object.prototype.toString.call(obj) === '[object Uint8Array]';\n}\n\nvar binary = new type('tag:yaml.org,2002:binary', {\n kind: 'scalar',\n resolve: resolveYamlBinary,\n construct: constructYamlBinary,\n predicate: isBinary,\n represent: representYamlBinary\n});\n\nvar _hasOwnProperty$3 = Object.prototype.hasOwnProperty;\nvar _toString$2 = Object.prototype.toString;\n\nfunction resolveYamlOmap(data) {\n if (data === null) return true;\n\n var objectKeys = [], index, length, pair, pairKey, pairHasKey,\n object = data;\n\n for (index = 0, length = object.length; index < length; index += 1) {\n pair = object[index];\n pairHasKey = false;\n\n if (_toString$2.call(pair) !== '[object Object]') return false;\n\n for (pairKey in pair) {\n if (_hasOwnProperty$3.call(pair, pairKey)) {\n if (!pairHasKey) pairHasKey = true;\n else return false;\n }\n }\n\n if (!pairHasKey) return false;\n\n if (objectKeys.indexOf(pairKey) === -1) objectKeys.push(pairKey);\n else return false;\n }\n\n return true;\n}\n\nfunction constructYamlOmap(data) {\n return data !== null ? data : [];\n}\n\nvar omap = new type('tag:yaml.org,2002:omap', {\n kind: 'sequence',\n resolve: resolveYamlOmap,\n construct: constructYamlOmap\n});\n\nvar _toString$1 = Object.prototype.toString;\n\nfunction resolveYamlPairs(data) {\n if (data === null) return true;\n\n var index, length, pair, keys, result,\n object = data;\n\n result = new Array(object.length);\n\n for (index = 0, length = object.length; index < length; index += 1) {\n pair = object[index];\n\n if (_toString$1.call(pair) !== '[object Object]') return false;\n\n keys = Object.keys(pair);\n\n if (keys.length !== 1) return false;\n\n result[index] = [ keys[0], pair[keys[0]] ];\n }\n\n return true;\n}\n\nfunction constructYamlPairs(data) {\n if (data === null) return [];\n\n var index, length, pair, keys, result,\n object = data;\n\n result = new Array(object.length);\n\n for (index = 0, length = object.length; index < length; index += 1) {\n pair = object[index];\n\n keys = Object.keys(pair);\n\n result[index] = [ keys[0], pair[keys[0]] ];\n }\n\n return result;\n}\n\nvar pairs = new type('tag:yaml.org,2002:pairs', {\n kind: 'sequence',\n resolve: resolveYamlPairs,\n construct: constructYamlPairs\n});\n\nvar _hasOwnProperty$2 = Object.prototype.hasOwnProperty;\n\nfunction resolveYamlSet(data) {\n if (data === null) return true;\n\n var key, object = data;\n\n for (key in object) {\n if (_hasOwnProperty$2.call(object, key)) {\n if (object[key] !== null) return false;\n }\n }\n\n return true;\n}\n\nfunction constructYamlSet(data) {\n return data !== null ? data : {};\n}\n\nvar set = new type('tag:yaml.org,2002:set', {\n kind: 'mapping',\n resolve: resolveYamlSet,\n construct: constructYamlSet\n});\n\nvar _default = core.extend({\n implicit: [\n timestamp,\n merge\n ],\n explicit: [\n binary,\n omap,\n pairs,\n set\n ]\n});\n\n/*eslint-disable max-len,no-use-before-define*/\n\n\n\n\n\n\n\nvar _hasOwnProperty$1 = Object.prototype.hasOwnProperty;\n\n\nvar CONTEXT_FLOW_IN = 1;\nvar CONTEXT_FLOW_OUT = 2;\nvar CONTEXT_BLOCK_IN = 3;\nvar CONTEXT_BLOCK_OUT = 4;\n\n\nvar CHOMPING_CLIP = 1;\nvar CHOMPING_STRIP = 2;\nvar CHOMPING_KEEP = 3;\n\n\nvar PATTERN_NON_PRINTABLE = /[\\x00-\\x08\\x0B\\x0C\\x0E-\\x1F\\x7F-\\x84\\x86-\\x9F\\uFFFE\\uFFFF]|[\\uD800-\\uDBFF](?![\\uDC00-\\uDFFF])|(?:[^\\uD800-\\uDBFF]|^)[\\uDC00-\\uDFFF]/;\nvar PATTERN_NON_ASCII_LINE_BREAKS = /[\\x85\\u2028\\u2029]/;\nvar PATTERN_FLOW_INDICATORS = /[,\\[\\]\\{\\}]/;\nvar PATTERN_TAG_HANDLE = /^(?:!|!!|![a-z\\-]+!)$/i;\nvar PATTERN_TAG_URI = /^(?:!|[^,\\[\\]\\{\\}])(?:%[0-9a-f]{2}|[0-9a-z\\-#;\\/\\?:@&=\\+\\$,_\\.!~\\*'\\(\\)\\[\\]])*$/i;\n\n\nfunction _class(obj) { return Object.prototype.toString.call(obj); }\n\nfunction is_EOL(c) {\n return (c === 0x0A/* LF */) || (c === 0x0D/* CR */);\n}\n\nfunction is_WHITE_SPACE(c) {\n return (c === 0x09/* Tab */) || (c === 0x20/* Space */);\n}\n\nfunction is_WS_OR_EOL(c) {\n return (c === 0x09/* Tab */) ||\n (c === 0x20/* Space */) ||\n (c === 0x0A/* LF */) ||\n (c === 0x0D/* CR */);\n}\n\nfunction is_FLOW_INDICATOR(c) {\n return c === 0x2C/* , */ ||\n c === 0x5B/* [ */ ||\n c === 0x5D/* ] */ ||\n c === 0x7B/* { */ ||\n c === 0x7D/* } */;\n}\n\nfunction fromHexCode(c) {\n var lc;\n\n if ((0x30/* 0 */ <= c) && (c <= 0x39/* 9 */)) {\n return c - 0x30;\n }\n\n /*eslint-disable no-bitwise*/\n lc = c | 0x20;\n\n if ((0x61/* a */ <= lc) && (lc <= 0x66/* f */)) {\n return lc - 0x61 + 10;\n }\n\n return -1;\n}\n\nfunction escapedHexLen(c) {\n if (c === 0x78/* x */) { return 2; }\n if (c === 0x75/* u */) { return 4; }\n if (c === 0x55/* U */) { return 8; }\n return 0;\n}\n\nfunction fromDecimalCode(c) {\n if ((0x30/* 0 */ <= c) && (c <= 0x39/* 9 */)) {\n return c - 0x30;\n }\n\n return -1;\n}\n\nfunction simpleEscapeSequence(c) {\n /* eslint-disable indent */\n return (c === 0x30/* 0 */) ? '\\x00' :\n (c === 0x61/* a */) ? '\\x07' :\n (c === 0x62/* b */) ? '\\x08' :\n (c === 0x74/* t */) ? '\\x09' :\n (c === 0x09/* Tab */) ? '\\x09' :\n (c === 0x6E/* n */) ? '\\x0A' :\n (c === 0x76/* v */) ? '\\x0B' :\n (c === 0x66/* f */) ? '\\x0C' :\n (c === 0x72/* r */) ? '\\x0D' :\n (c === 0x65/* e */) ? '\\x1B' :\n (c === 0x20/* Space */) ? ' ' :\n (c === 0x22/* \" */) ? '\\x22' :\n (c === 0x2F/* / */) ? '/' :\n (c === 0x5C/* \\ */) ? '\\x5C' :\n (c === 0x4E/* N */) ? '\\x85' :\n (c === 0x5F/* _ */) ? '\\xA0' :\n (c === 0x4C/* L */) ? '\\u2028' :\n (c === 0x50/* P */) ? '\\u2029' : '';\n}\n\nfunction charFromCodepoint(c) {\n if (c <= 0xFFFF) {\n return String.fromCharCode(c);\n }\n // Encode UTF-16 surrogate pair\n // https://en.wikipedia.org/wiki/UTF-16#Code_points_U.2B010000_to_U.2B10FFFF\n return String.fromCharCode(\n ((c - 0x010000) >> 10) + 0xD800,\n ((c - 0x010000) & 0x03FF) + 0xDC00\n );\n}\n\n// set a property of a literal object, while protecting against prototype pollution,\n// see https://github.com/nodeca/js-yaml/issues/164 for more details\nfunction setProperty(object, key, value) {\n // used for this specific key only because Object.defineProperty is slow\n if (key === '__proto__') {\n Object.defineProperty(object, key, {\n configurable: true,\n enumerable: true,\n writable: true,\n value: value\n });\n } else {\n object[key] = value;\n }\n}\n\nvar simpleEscapeCheck = new Array(256); // integer, for fast access\nvar simpleEscapeMap = new Array(256);\nfor (var i = 0; i < 256; i++) {\n simpleEscapeCheck[i] = simpleEscapeSequence(i) ? 1 : 0;\n simpleEscapeMap[i] = simpleEscapeSequence(i);\n}\n\n\nfunction State$1(input, options) {\n this.input = input;\n\n this.filename = options['filename'] || null;\n this.schema = options['schema'] || _default;\n this.onWarning = options['onWarning'] || null;\n // (Hidden) Remove? makes the loader to expect YAML 1.1 documents\n // if such documents have no explicit %YAML directive\n this.legacy = options['legacy'] || false;\n\n this.json = options['json'] || false;\n this.listener = options['listener'] || null;\n\n this.implicitTypes = this.schema.compiledImplicit;\n this.typeMap = this.schema.compiledTypeMap;\n\n this.length = input.length;\n this.position = 0;\n this.line = 0;\n this.lineStart = 0;\n this.lineIndent = 0;\n\n // position of first leading tab in the current line,\n // used to make sure there are no tabs in the indentation\n this.firstTabInLine = -1;\n\n this.documents = [];\n\n /*\n this.version;\n this.checkLineBreaks;\n this.tagMap;\n this.anchorMap;\n this.tag;\n this.anchor;\n this.kind;\n this.result;*/\n\n}\n\n\nfunction generateError(state, message) {\n var mark = {\n name: state.filename,\n buffer: state.input.slice(0, -1), // omit trailing \\0\n position: state.position,\n line: state.line,\n column: state.position - state.lineStart\n };\n\n mark.snippet = snippet(mark);\n\n return new exception(message, mark);\n}\n\nfunction throwError(state, message) {\n throw generateError(state, message);\n}\n\nfunction throwWarning(state, message) {\n if (state.onWarning) {\n state.onWarning.call(null, generateError(state, message));\n }\n}\n\n\nvar directiveHandlers = {\n\n YAML: function handleYamlDirective(state, name, args) {\n\n var match, major, minor;\n\n if (state.version !== null) {\n throwError(state, 'duplication of %YAML directive');\n }\n\n if (args.length !== 1) {\n throwError(state, 'YAML directive accepts exactly one argument');\n }\n\n match = /^([0-9]+)\\.([0-9]+)$/.exec(args[0]);\n\n if (match === null) {\n throwError(state, 'ill-formed argument of the YAML directive');\n }\n\n major = parseInt(match[1], 10);\n minor = parseInt(match[2], 10);\n\n if (major !== 1) {\n throwError(state, 'unacceptable YAML version of the document');\n }\n\n state.version = args[0];\n state.checkLineBreaks = (minor < 2);\n\n if (minor !== 1 && minor !== 2) {\n throwWarning(state, 'unsupported YAML version of the document');\n }\n },\n\n TAG: function handleTagDirective(state, name, args) {\n\n var handle, prefix;\n\n if (args.length !== 2) {\n throwError(state, 'TAG directive accepts exactly two arguments');\n }\n\n handle = args[0];\n prefix = args[1];\n\n if (!PATTERN_TAG_HANDLE.test(handle)) {\n throwError(state, 'ill-formed tag handle (first argument) of the TAG directive');\n }\n\n if (_hasOwnProperty$1.call(state.tagMap, handle)) {\n throwError(state, 'there is a previously declared suffix for \"' + handle + '\" tag handle');\n }\n\n if (!PATTERN_TAG_URI.test(prefix)) {\n throwError(state, 'ill-formed tag prefix (second argument) of the TAG directive');\n }\n\n try {\n prefix = decodeURIComponent(prefix);\n } catch (err) {\n throwError(state, 'tag prefix is malformed: ' + prefix);\n }\n\n state.tagMap[handle] = prefix;\n }\n};\n\n\nfunction captureSegment(state, start, end, checkJson) {\n var _position, _length, _character, _result;\n\n if (start < end) {\n _result = state.input.slice(start, end);\n\n if (checkJson) {\n for (_position = 0, _length = _result.length; _position < _length; _position += 1) {\n _character = _result.charCodeAt(_position);\n if (!(_character === 0x09 ||\n (0x20 <= _character && _character <= 0x10FFFF))) {\n throwError(state, 'expected valid JSON character');\n }\n }\n } else if (PATTERN_NON_PRINTABLE.test(_result)) {\n throwError(state, 'the stream contains non-printable characters');\n }\n\n state.result += _result;\n }\n}\n\nfunction mergeMappings(state, destination, source, overridableKeys) {\n var sourceKeys, key, index, quantity;\n\n if (!common.isObject(source)) {\n throwError(state, 'cannot merge mappings; the provided source object is unacceptable');\n }\n\n sourceKeys = Object.keys(source);\n\n for (index = 0, quantity = sourceKeys.length; index < quantity; index += 1) {\n key = sourceKeys[index];\n\n if (!_hasOwnProperty$1.call(destination, key)) {\n setProperty(destination, key, source[key]);\n overridableKeys[key] = true;\n }\n }\n}\n\nfunction storeMappingPair(state, _result, overridableKeys, keyTag, keyNode, valueNode,\n startLine, startLineStart, startPos) {\n\n var index, quantity;\n\n // The output is a plain object here, so keys can only be strings.\n // We need to convert keyNode to a string, but doing so can hang the process\n // (deeply nested arrays that explode exponentially using aliases).\n if (Array.isArray(keyNode)) {\n keyNode = Array.prototype.slice.call(keyNode);\n\n for (index = 0, quantity = keyNode.length; index < quantity; index += 1) {\n if (Array.isArray(keyNode[index])) {\n throwError(state, 'nested arrays are not supported inside keys');\n }\n\n if (typeof keyNode === 'object' && _class(keyNode[index]) === '[object Object]') {\n keyNode[index] = '[object Object]';\n }\n }\n }\n\n // Avoid code execution in load() via toString property\n // (still use its own toString for arrays, timestamps,\n // and whatever user schema extensions happen to have @@toStringTag)\n if (typeof keyNode === 'object' && _class(keyNode) === '[object Object]') {\n keyNode = '[object Object]';\n }\n\n\n keyNode = String(keyNode);\n\n if (_result === null) {\n _result = {};\n }\n\n if (keyTag === 'tag:yaml.org,2002:merge') {\n if (Array.isArray(valueNode)) {\n for (index = 0, quantity = valueNode.length; index < quantity; index += 1) {\n mergeMappings(state, _result, valueNode[index], overridableKeys);\n }\n } else {\n mergeMappings(state, _result, valueNode, overridableKeys);\n }\n } else {\n if (!state.json &&\n !_hasOwnProperty$1.call(overridableKeys, keyNode) &&\n _hasOwnProperty$1.call(_result, keyNode)) {\n state.line = startLine || state.line;\n state.lineStart = startLineStart || state.lineStart;\n state.position = startPos || state.position;\n throwError(state, 'duplicated mapping key');\n }\n\n setProperty(_result, keyNode, valueNode);\n delete overridableKeys[keyNode];\n }\n\n return _result;\n}\n\nfunction readLineBreak(state) {\n var ch;\n\n ch = state.input.charCodeAt(state.position);\n\n if (ch === 0x0A/* LF */) {\n state.position++;\n } else if (ch === 0x0D/* CR */) {\n state.position++;\n if (state.input.charCodeAt(state.position) === 0x0A/* LF */) {\n state.position++;\n }\n } else {\n throwError(state, 'a line break is expected');\n }\n\n state.line += 1;\n state.lineStart = state.position;\n state.firstTabInLine = -1;\n}\n\nfunction skipSeparationSpace(state, allowComments, checkIndent) {\n var lineBreaks = 0,\n ch = state.input.charCodeAt(state.position);\n\n while (ch !== 0) {\n while (is_WHITE_SPACE(ch)) {\n if (ch === 0x09/* Tab */ && state.firstTabInLine === -1) {\n state.firstTabInLine = state.position;\n }\n ch = state.input.charCodeAt(++state.position);\n }\n\n if (allowComments && ch === 0x23/* # */) {\n do {\n ch = state.input.charCodeAt(++state.position);\n } while (ch !== 0x0A/* LF */ && ch !== 0x0D/* CR */ && ch !== 0);\n }\n\n if (is_EOL(ch)) {\n readLineBreak(state);\n\n ch = state.input.charCodeAt(state.position);\n lineBreaks++;\n state.lineIndent = 0;\n\n while (ch === 0x20/* Space */) {\n state.lineIndent++;\n ch = state.input.charCodeAt(++state.position);\n }\n } else {\n break;\n }\n }\n\n if (checkIndent !== -1 && lineBreaks !== 0 && state.lineIndent < checkIndent) {\n throwWarning(state, 'deficient indentation');\n }\n\n return lineBreaks;\n}\n\nfunction testDocumentSeparator(state) {\n var _position = state.position,\n ch;\n\n ch = state.input.charCodeAt(_position);\n\n // Condition state.position === state.lineStart is tested\n // in parent on each call, for efficiency. No needs to test here again.\n if ((ch === 0x2D/* - */ || ch === 0x2E/* . */) &&\n ch === state.input.charCodeAt(_position + 1) &&\n ch === state.input.charCodeAt(_position + 2)) {\n\n _position += 3;\n\n ch = state.input.charCodeAt(_position);\n\n if (ch === 0 || is_WS_OR_EOL(ch)) {\n return true;\n }\n }\n\n return false;\n}\n\nfunction writeFoldedLines(state, count) {\n if (count === 1) {\n state.result += ' ';\n } else if (count > 1) {\n state.result += common.repeat('\\n', count - 1);\n }\n}\n\n\nfunction readPlainScalar(state, nodeIndent, withinFlowCollection) {\n var preceding,\n following,\n captureStart,\n captureEnd,\n hasPendingContent,\n _line,\n _lineStart,\n _lineIndent,\n _kind = state.kind,\n _result = state.result,\n ch;\n\n ch = state.input.charCodeAt(state.position);\n\n if (is_WS_OR_EOL(ch) ||\n is_FLOW_INDICATOR(ch) ||\n ch === 0x23/* # */ ||\n ch === 0x26/* & */ ||\n ch === 0x2A/* * */ ||\n ch === 0x21/* ! */ ||\n ch === 0x7C/* | */ ||\n ch === 0x3E/* > */ ||\n ch === 0x27/* ' */ ||\n ch === 0x22/* \" */ ||\n ch === 0x25/* % */ ||\n ch === 0x40/* @ */ ||\n ch === 0x60/* ` */) {\n return false;\n }\n\n if (ch === 0x3F/* ? */ || ch === 0x2D/* - */) {\n following = state.input.charCodeAt(state.position + 1);\n\n if (is_WS_OR_EOL(following) ||\n withinFlowCollection && is_FLOW_INDICATOR(following)) {\n return false;\n }\n }\n\n state.kind = 'scalar';\n state.result = '';\n captureStart = captureEnd = state.position;\n hasPendingContent = false;\n\n while (ch !== 0) {\n if (ch === 0x3A/* : */) {\n following = state.input.charCodeAt(state.position + 1);\n\n if (is_WS_OR_EOL(following) ||\n withinFlowCollection && is_FLOW_INDICATOR(following)) {\n break;\n }\n\n } else if (ch === 0x23/* # */) {\n preceding = state.input.charCodeAt(state.position - 1);\n\n if (is_WS_OR_EOL(preceding)) {\n break;\n }\n\n } else if ((state.position === state.lineStart && testDocumentSeparator(state)) ||\n withinFlowCollection && is_FLOW_INDICATOR(ch)) {\n break;\n\n } else if (is_EOL(ch)) {\n _line = state.line;\n _lineStart = state.lineStart;\n _lineIndent = state.lineIndent;\n skipSeparationSpace(state, false, -1);\n\n if (state.lineIndent >= nodeIndent) {\n hasPendingContent = true;\n ch = state.input.charCodeAt(state.position);\n continue;\n } else {\n state.position = captureEnd;\n state.line = _line;\n state.lineStart = _lineStart;\n state.lineIndent = _lineIndent;\n break;\n }\n }\n\n if (hasPendingContent) {\n captureSegment(state, captureStart, captureEnd, false);\n writeFoldedLines(state, state.line - _line);\n captureStart = captureEnd = state.position;\n hasPendingContent = false;\n }\n\n if (!is_WHITE_SPACE(ch)) {\n captureEnd = state.position + 1;\n }\n\n ch = state.input.charCodeAt(++state.position);\n }\n\n captureSegment(state, captureStart, captureEnd, false);\n\n if (state.result) {\n return true;\n }\n\n state.kind = _kind;\n state.result = _result;\n return false;\n}\n\nfunction readSingleQuotedScalar(state, nodeIndent) {\n var ch,\n captureStart, captureEnd;\n\n ch = state.input.charCodeAt(state.position);\n\n if (ch !== 0x27/* ' */) {\n return false;\n }\n\n state.kind = 'scalar';\n state.result = '';\n state.position++;\n captureStart = captureEnd = state.position;\n\n while ((ch = state.input.charCodeAt(state.position)) !== 0) {\n if (ch === 0x27/* ' */) {\n captureSegment(state, captureStart, state.position, true);\n ch = state.input.charCodeAt(++state.position);\n\n if (ch === 0x27/* ' */) {\n captureStart = state.position;\n state.position++;\n captureEnd = state.position;\n } else {\n return true;\n }\n\n } else if (is_EOL(ch)) {\n captureSegment(state, captureStart, captureEnd, true);\n writeFoldedLines(state, skipSeparationSpace(state, false, nodeIndent));\n captureStart = captureEnd = state.position;\n\n } else if (state.position === state.lineStart && testDocumentSeparator(state)) {\n throwError(state, 'unexpected end of the document within a single quoted scalar');\n\n } else {\n state.position++;\n captureEnd = state.position;\n }\n }\n\n throwError(state, 'unexpected end of the stream within a single quoted scalar');\n}\n\nfunction readDoubleQuotedScalar(state, nodeIndent) {\n var captureStart,\n captureEnd,\n hexLength,\n hexResult,\n tmp,\n ch;\n\n ch = state.input.charCodeAt(state.position);\n\n if (ch !== 0x22/* \" */) {\n return false;\n }\n\n state.kind = 'scalar';\n state.result = '';\n state.position++;\n captureStart = captureEnd = state.position;\n\n while ((ch = state.input.charCodeAt(state.position)) !== 0) {\n if (ch === 0x22/* \" */) {\n captureSegment(state, captureStart, state.position, true);\n state.position++;\n return true;\n\n } else if (ch === 0x5C/* \\ */) {\n captureSegment(state, captureStart, state.position, true);\n ch = state.input.charCodeAt(++state.position);\n\n if (is_EOL(ch)) {\n skipSeparationSpace(state, false, nodeIndent);\n\n // TODO: rework to inline fn with no type cast?\n } else if (ch < 256 && simpleEscapeCheck[ch]) {\n state.result += simpleEscapeMap[ch];\n state.position++;\n\n } else if ((tmp = escapedHexLen(ch)) > 0) {\n hexLength = tmp;\n hexResult = 0;\n\n for (; hexLength > 0; hexLength--) {\n ch = state.input.charCodeAt(++state.position);\n\n if ((tmp = fromHexCode(ch)) >= 0) {\n hexResult = (hexResult << 4) + tmp;\n\n } else {\n throwError(state, 'expected hexadecimal character');\n }\n }\n\n state.result += charFromCodepoint(hexResult);\n\n state.position++;\n\n } else {\n throwError(state, 'unknown escape sequence');\n }\n\n captureStart = captureEnd = state.position;\n\n } else if (is_EOL(ch)) {\n captureSegment(state, captureStart, captureEnd, true);\n writeFoldedLines(state, skipSeparationSpace(state, false, nodeIndent));\n captureStart = captureEnd = state.position;\n\n } else if (state.position === state.lineStart && testDocumentSeparator(state)) {\n throwError(state, 'unexpected end of the document within a double quoted scalar');\n\n } else {\n state.position++;\n captureEnd = state.position;\n }\n }\n\n throwError(state, 'unexpected end of the stream within a double quoted scalar');\n}\n\nfunction readFlowCollection(state, nodeIndent) {\n var readNext = true,\n _line,\n _lineStart,\n _pos,\n _tag = state.tag,\n _result,\n _anchor = state.anchor,\n following,\n terminator,\n isPair,\n isExplicitPair,\n isMapping,\n overridableKeys = Object.create(null),\n keyNode,\n keyTag,\n valueNode,\n ch;\n\n ch = state.input.charCodeAt(state.position);\n\n if (ch === 0x5B/* [ */) {\n terminator = 0x5D;/* ] */\n isMapping = false;\n _result = [];\n } else if (ch === 0x7B/* { */) {\n terminator = 0x7D;/* } */\n isMapping = true;\n _result = {};\n } else {\n return false;\n }\n\n if (state.anchor !== null) {\n state.anchorMap[state.anchor] = _result;\n }\n\n ch = state.input.charCodeAt(++state.position);\n\n while (ch !== 0) {\n skipSeparationSpace(state, true, nodeIndent);\n\n ch = state.input.charCodeAt(state.position);\n\n if (ch === terminator) {\n state.position++;\n state.tag = _tag;\n state.anchor = _anchor;\n state.kind = isMapping ? 'mapping' : 'sequence';\n state.result = _result;\n return true;\n } else if (!readNext) {\n throwError(state, 'missed comma between flow collection entries');\n } else if (ch === 0x2C/* , */) {\n // \"flow collection entries can never be completely empty\", as per YAML 1.2, section 7.4\n throwError(state, \"expected the node content, but found ','\");\n }\n\n keyTag = keyNode = valueNode = null;\n isPair = isExplicitPair = false;\n\n if (ch === 0x3F/* ? */) {\n following = state.input.charCodeAt(state.position + 1);\n\n if (is_WS_OR_EOL(following)) {\n isPair = isExplicitPair = true;\n state.position++;\n skipSeparationSpace(state, true, nodeIndent);\n }\n }\n\n _line = state.line; // Save the current line.\n _lineStart = state.lineStart;\n _pos = state.position;\n composeNode(state, nodeIndent, CONTEXT_FLOW_IN, false, true);\n keyTag = state.tag;\n keyNode = state.result;\n skipSeparationSpace(state, true, nodeIndent);\n\n ch = state.input.charCodeAt(state.position);\n\n if ((isExplicitPair || state.line === _line) && ch === 0x3A/* : */) {\n isPair = true;\n ch = state.input.charCodeAt(++state.position);\n skipSeparationSpace(state, true, nodeIndent);\n composeNode(state, nodeIndent, CONTEXT_FLOW_IN, false, true);\n valueNode = state.result;\n }\n\n if (isMapping) {\n storeMappingPair(state, _result, overridableKeys, keyTag, keyNode, valueNode, _line, _lineStart, _pos);\n } else if (isPair) {\n _result.push(storeMappingPair(state, null, overridableKeys, keyTag, keyNode, valueNode, _line, _lineStart, _pos));\n } else {\n _result.push(keyNode);\n }\n\n skipSeparationSpace(state, true, nodeIndent);\n\n ch = state.input.charCodeAt(state.position);\n\n if (ch === 0x2C/* , */) {\n readNext = true;\n ch = state.input.charCodeAt(++state.position);\n } else {\n readNext = false;\n }\n }\n\n throwError(state, 'unexpected end of the stream within a flow collection');\n}\n\nfunction readBlockScalar(state, nodeIndent) {\n var captureStart,\n folding,\n chomping = CHOMPING_CLIP,\n didReadContent = false,\n detectedIndent = false,\n textIndent = nodeIndent,\n emptyLines = 0,\n atMoreIndented = false,\n tmp,\n ch;\n\n ch = state.input.charCodeAt(state.position);\n\n if (ch === 0x7C/* | */) {\n folding = false;\n } else if (ch === 0x3E/* > */) {\n folding = true;\n } else {\n return false;\n }\n\n state.kind = 'scalar';\n state.result = '';\n\n while (ch !== 0) {\n ch = state.input.charCodeAt(++state.position);\n\n if (ch === 0x2B/* + */ || ch === 0x2D/* - */) {\n if (CHOMPING_CLIP === chomping) {\n chomping = (ch === 0x2B/* + */) ? CHOMPING_KEEP : CHOMPING_STRIP;\n } else {\n throwError(state, 'repeat of a chomping mode identifier');\n }\n\n } else if ((tmp = fromDecimalCode(ch)) >= 0) {\n if (tmp === 0) {\n throwError(state, 'bad explicit indentation width of a block scalar; it cannot be less than one');\n } else if (!detectedIndent) {\n textIndent = nodeIndent + tmp - 1;\n detectedIndent = true;\n } else {\n throwError(state, 'repeat of an indentation width identifier');\n }\n\n } else {\n break;\n }\n }\n\n if (is_WHITE_SPACE(ch)) {\n do { ch = state.input.charCodeAt(++state.position); }\n while (is_WHITE_SPACE(ch));\n\n if (ch === 0x23/* # */) {\n do { ch = state.input.charCodeAt(++state.position); }\n while (!is_EOL(ch) && (ch !== 0));\n }\n }\n\n while (ch !== 0) {\n readLineBreak(state);\n state.lineIndent = 0;\n\n ch = state.input.charCodeAt(state.position);\n\n while ((!detectedIndent || state.lineIndent < textIndent) &&\n (ch === 0x20/* Space */)) {\n state.lineIndent++;\n ch = state.input.charCodeAt(++state.position);\n }\n\n if (!detectedIndent && state.lineIndent > textIndent) {\n textIndent = state.lineIndent;\n }\n\n if (is_EOL(ch)) {\n emptyLines++;\n continue;\n }\n\n // End of the scalar.\n if (state.lineIndent < textIndent) {\n\n // Perform the chomping.\n if (chomping === CHOMPING_KEEP) {\n state.result += common.repeat('\\n', didReadContent ? 1 + emptyLines : emptyLines);\n } else if (chomping === CHOMPING_CLIP) {\n if (didReadContent) { // i.e. only if the scalar is not empty.\n state.result += '\\n';\n }\n }\n\n // Break this `while` cycle and go to the funciton's epilogue.\n break;\n }\n\n // Folded style: use fancy rules to handle line breaks.\n if (folding) {\n\n // Lines starting with white space characters (more-indented lines) are not folded.\n if (is_WHITE_SPACE(ch)) {\n atMoreIndented = true;\n // except for the first content line (cf. Example 8.1)\n state.result += common.repeat('\\n', didReadContent ? 1 + emptyLines : emptyLines);\n\n // End of more-indented block.\n } else if (atMoreIndented) {\n atMoreIndented = false;\n state.result += common.repeat('\\n', emptyLines + 1);\n\n // Just one line break - perceive as the same line.\n } else if (emptyLines === 0) {\n if (didReadContent) { // i.e. only if we have already read some scalar content.\n state.result += ' ';\n }\n\n // Several line breaks - perceive as different lines.\n } else {\n state.result += common.repeat('\\n', emptyLines);\n }\n\n // Literal style: just add exact number of line breaks between content lines.\n } else {\n // Keep all line breaks except the header line break.\n state.result += common.repeat('\\n', didReadContent ? 1 + emptyLines : emptyLines);\n }\n\n didReadContent = true;\n detectedIndent = true;\n emptyLines = 0;\n captureStart = state.position;\n\n while (!is_EOL(ch) && (ch !== 0)) {\n ch = state.input.charCodeAt(++state.position);\n }\n\n captureSegment(state, captureStart, state.position, false);\n }\n\n return true;\n}\n\nfunction readBlockSequence(state, nodeIndent) {\n var _line,\n _tag = state.tag,\n _anchor = state.anchor,\n _result = [],\n following,\n detected = false,\n ch;\n\n // there is a leading tab before this token, so it can't be a block sequence/mapping;\n // it can still be flow sequence/mapping or a scalar\n if (state.firstTabInLine !== -1) return false;\n\n if (state.anchor !== null) {\n state.anchorMap[state.anchor] = _result;\n }\n\n ch = state.input.charCodeAt(state.position);\n\n while (ch !== 0) {\n if (state.firstTabInLine !== -1) {\n state.position = state.firstTabInLine;\n throwError(state, 'tab characters must not be used in indentation');\n }\n\n if (ch !== 0x2D/* - */) {\n break;\n }\n\n following = state.input.charCodeAt(state.position + 1);\n\n if (!is_WS_OR_EOL(following)) {\n break;\n }\n\n detected = true;\n state.position++;\n\n if (skipSeparationSpace(state, true, -1)) {\n if (state.lineIndent <= nodeIndent) {\n _result.push(null);\n ch = state.input.charCodeAt(state.position);\n continue;\n }\n }\n\n _line = state.line;\n composeNode(state, nodeIndent, CONTEXT_BLOCK_IN, false, true);\n _result.push(state.result);\n skipSeparationSpace(state, true, -1);\n\n ch = state.input.charCodeAt(state.position);\n\n if ((state.line === _line || state.lineIndent > nodeIndent) && (ch !== 0)) {\n throwError(state, 'bad indentation of a sequence entry');\n } else if (state.lineIndent < nodeIndent) {\n break;\n }\n }\n\n if (detected) {\n state.tag = _tag;\n state.anchor = _anchor;\n state.kind = 'sequence';\n state.result = _result;\n return true;\n }\n return false;\n}\n\nfunction readBlockMapping(state, nodeIndent, flowIndent) {\n var following,\n allowCompact,\n _line,\n _keyLine,\n _keyLineStart,\n _keyPos,\n _tag = state.tag,\n _anchor = state.anchor,\n _result = {},\n overridableKeys = Object.create(null),\n keyTag = null,\n keyNode = null,\n valueNode = null,\n atExplicitKey = false,\n detected = false,\n ch;\n\n // there is a leading tab before this token, so it can't be a block sequence/mapping;\n // it can still be flow sequence/mapping or a scalar\n if (state.firstTabInLine !== -1) return false;\n\n if (state.anchor !== null) {\n state.anchorMap[state.anchor] = _result;\n }\n\n ch = state.input.charCodeAt(state.position);\n\n while (ch !== 0) {\n if (!atExplicitKey && state.firstTabInLine !== -1) {\n state.position = state.firstTabInLine;\n throwError(state, 'tab characters must not be used in indentation');\n }\n\n following = state.input.charCodeAt(state.position + 1);\n _line = state.line; // Save the current line.\n\n //\n // Explicit notation case. There are two separate blocks:\n // first for the key (denoted by \"?\") and second for the value (denoted by \":\")\n //\n if ((ch === 0x3F/* ? */ || ch === 0x3A/* : */) && is_WS_OR_EOL(following)) {\n\n if (ch === 0x3F/* ? */) {\n if (atExplicitKey) {\n storeMappingPair(state, _result, overridableKeys, keyTag, keyNode, null, _keyLine, _keyLineStart, _keyPos);\n keyTag = keyNode = valueNode = null;\n }\n\n detected = true;\n atExplicitKey = true;\n allowCompact = true;\n\n } else if (atExplicitKey) {\n // i.e. 0x3A/* : */ === character after the explicit key.\n atExplicitKey = false;\n allowCompact = true;\n\n } else {\n throwError(state, 'incomplete explicit mapping pair; a key node is missed; or followed by a non-tabulated empty line');\n }\n\n state.position += 1;\n ch = following;\n\n //\n // Implicit notation case. Flow-style node as the key first, then \":\", and the value.\n //\n } else {\n _keyLine = state.line;\n _keyLineStart = state.lineStart;\n _keyPos = state.position;\n\n if (!composeNode(state, flowIndent, CONTEXT_FLOW_OUT, false, true)) {\n // Neither implicit nor explicit notation.\n // Reading is done. Go to the epilogue.\n break;\n }\n\n if (state.line === _line) {\n ch = state.input.charCodeAt(state.position);\n\n while (is_WHITE_SPACE(ch)) {\n ch = state.input.charCodeAt(++state.position);\n }\n\n if (ch === 0x3A/* : */) {\n ch = state.input.charCodeAt(++state.position);\n\n if (!is_WS_OR_EOL(ch)) {\n throwError(state, 'a whitespace character is expected after the key-value separator within a block mapping');\n }\n\n if (atExplicitKey) {\n storeMappingPair(state, _result, overridableKeys, keyTag, keyNode, null, _keyLine, _keyLineStart, _keyPos);\n keyTag = keyNode = valueNode = null;\n }\n\n detected = true;\n atExplicitKey = false;\n allowCompact = false;\n keyTag = state.tag;\n keyNode = state.result;\n\n } else if (detected) {\n throwError(state, 'can not read an implicit mapping pair; a colon is missed');\n\n } else {\n state.tag = _tag;\n state.anchor = _anchor;\n return true; // Keep the result of `composeNode`.\n }\n\n } else if (detected) {\n throwError(state, 'can not read a block mapping entry; a multiline key may not be an implicit key');\n\n } else {\n state.tag = _tag;\n state.anchor = _anchor;\n return true; // Keep the result of `composeNode`.\n }\n }\n\n //\n // Common reading code for both explicit and implicit notations.\n //\n if (state.line === _line || state.lineIndent > nodeIndent) {\n if (atExplicitKey) {\n _keyLine = state.line;\n _keyLineStart = state.lineStart;\n _keyPos = state.position;\n }\n\n if (composeNode(state, nodeIndent, CONTEXT_BLOCK_OUT, true, allowCompact)) {\n if (atExplicitKey) {\n keyNode = state.result;\n } else {\n valueNode = state.result;\n }\n }\n\n if (!atExplicitKey) {\n storeMappingPair(state, _result, overridableKeys, keyTag, keyNode, valueNode, _keyLine, _keyLineStart, _keyPos);\n keyTag = keyNode = valueNode = null;\n }\n\n skipSeparationSpace(state, true, -1);\n ch = state.input.charCodeAt(state.position);\n }\n\n if ((state.line === _line || state.lineIndent > nodeIndent) && (ch !== 0)) {\n throwError(state, 'bad indentation of a mapping entry');\n } else if (state.lineIndent < nodeIndent) {\n break;\n }\n }\n\n //\n // Epilogue.\n //\n\n // Special case: last mapping's node contains only the key in explicit notation.\n if (atExplicitKey) {\n storeMappingPair(state, _result, overridableKeys, keyTag, keyNode, null, _keyLine, _keyLineStart, _keyPos);\n }\n\n // Expose the resulting mapping.\n if (detected) {\n state.tag = _tag;\n state.anchor = _anchor;\n state.kind = 'mapping';\n state.result = _result;\n }\n\n return detected;\n}\n\nfunction readTagProperty(state) {\n var _position,\n isVerbatim = false,\n isNamed = false,\n tagHandle,\n tagName,\n ch;\n\n ch = state.input.charCodeAt(state.position);\n\n if (ch !== 0x21/* ! */) return false;\n\n if (state.tag !== null) {\n throwError(state, 'duplication of a tag property');\n }\n\n ch = state.input.charCodeAt(++state.position);\n\n if (ch === 0x3C/* < */) {\n isVerbatim = true;\n ch = state.input.charCodeAt(++state.position);\n\n } else if (ch === 0x21/* ! */) {\n isNamed = true;\n tagHandle = '!!';\n ch = state.input.charCodeAt(++state.position);\n\n } else {\n tagHandle = '!';\n }\n\n _position = state.position;\n\n if (isVerbatim) {\n do { ch = state.input.charCodeAt(++state.position); }\n while (ch !== 0 && ch !== 0x3E/* > */);\n\n if (state.position < state.length) {\n tagName = state.input.slice(_position, state.position);\n ch = state.input.charCodeAt(++state.position);\n } else {\n throwError(state, 'unexpected end of the stream within a verbatim tag');\n }\n } else {\n while (ch !== 0 && !is_WS_OR_EOL(ch)) {\n\n if (ch === 0x21/* ! */) {\n if (!isNamed) {\n tagHandle = state.input.slice(_position - 1, state.position + 1);\n\n if (!PATTERN_TAG_HANDLE.test(tagHandle)) {\n throwError(state, 'named tag handle cannot contain such characters');\n }\n\n isNamed = true;\n _position = state.position + 1;\n } else {\n throwError(state, 'tag suffix cannot contain exclamation marks');\n }\n }\n\n ch = state.input.charCodeAt(++state.position);\n }\n\n tagName = state.input.slice(_position, state.position);\n\n if (PATTERN_FLOW_INDICATORS.test(tagName)) {\n throwError(state, 'tag suffix cannot contain flow indicator characters');\n }\n }\n\n if (tagName && !PATTERN_TAG_URI.test(tagName)) {\n throwError(state, 'tag name cannot contain such characters: ' + tagName);\n }\n\n try {\n tagName = decodeURIComponent(tagName);\n } catch (err) {\n throwError(state, 'tag name is malformed: ' + tagName);\n }\n\n if (isVerbatim) {\n state.tag = tagName;\n\n } else if (_hasOwnProperty$1.call(state.tagMap, tagHandle)) {\n state.tag = state.tagMap[tagHandle] + tagName;\n\n } else if (tagHandle === '!') {\n state.tag = '!' + tagName;\n\n } else if (tagHandle === '!!') {\n state.tag = 'tag:yaml.org,2002:' + tagName;\n\n } else {\n throwError(state, 'undeclared tag handle \"' + tagHandle + '\"');\n }\n\n return true;\n}\n\nfunction readAnchorProperty(state) {\n var _position,\n ch;\n\n ch = state.input.charCodeAt(state.position);\n\n if (ch !== 0x26/* & */) return false;\n\n if (state.anchor !== null) {\n throwError(state, 'duplication of an anchor property');\n }\n\n ch = state.input.charCodeAt(++state.position);\n _position = state.position;\n\n while (ch !== 0 && !is_WS_OR_EOL(ch) && !is_FLOW_INDICATOR(ch)) {\n ch = state.input.charCodeAt(++state.position);\n }\n\n if (state.position === _position) {\n throwError(state, 'name of an anchor node must contain at least one character');\n }\n\n state.anchor = state.input.slice(_position, state.position);\n return true;\n}\n\nfunction readAlias(state) {\n var _position, alias,\n ch;\n\n ch = state.input.charCodeAt(state.position);\n\n if (ch !== 0x2A/* * */) return false;\n\n ch = state.input.charCodeAt(++state.position);\n _position = state.position;\n\n while (ch !== 0 && !is_WS_OR_EOL(ch) && !is_FLOW_INDICATOR(ch)) {\n ch = state.input.charCodeAt(++state.position);\n }\n\n if (state.position === _position) {\n throwError(state, 'name of an alias node must contain at least one character');\n }\n\n alias = state.input.slice(_position, state.position);\n\n if (!_hasOwnProperty$1.call(state.anchorMap, alias)) {\n throwError(state, 'unidentified alias \"' + alias + '\"');\n }\n\n state.result = state.anchorMap[alias];\n skipSeparationSpace(state, true, -1);\n return true;\n}\n\nfunction composeNode(state, parentIndent, nodeContext, allowToSeek, allowCompact) {\n var allowBlockStyles,\n allowBlockScalars,\n allowBlockCollections,\n indentStatus = 1, // 1: this>parent, 0: this=parent, -1: this parentIndent) {\n indentStatus = 1;\n } else if (state.lineIndent === parentIndent) {\n indentStatus = 0;\n } else if (state.lineIndent < parentIndent) {\n indentStatus = -1;\n }\n }\n }\n\n if (indentStatus === 1) {\n while (readTagProperty(state) || readAnchorProperty(state)) {\n if (skipSeparationSpace(state, true, -1)) {\n atNewLine = true;\n allowBlockCollections = allowBlockStyles;\n\n if (state.lineIndent > parentIndent) {\n indentStatus = 1;\n } else if (state.lineIndent === parentIndent) {\n indentStatus = 0;\n } else if (state.lineIndent < parentIndent) {\n indentStatus = -1;\n }\n } else {\n allowBlockCollections = false;\n }\n }\n }\n\n if (allowBlockCollections) {\n allowBlockCollections = atNewLine || allowCompact;\n }\n\n if (indentStatus === 1 || CONTEXT_BLOCK_OUT === nodeContext) {\n if (CONTEXT_FLOW_IN === nodeContext || CONTEXT_FLOW_OUT === nodeContext) {\n flowIndent = parentIndent;\n } else {\n flowIndent = parentIndent + 1;\n }\n\n blockIndent = state.position - state.lineStart;\n\n if (indentStatus === 1) {\n if (allowBlockCollections &&\n (readBlockSequence(state, blockIndent) ||\n readBlockMapping(state, blockIndent, flowIndent)) ||\n readFlowCollection(state, flowIndent)) {\n hasContent = true;\n } else {\n if ((allowBlockScalars && readBlockScalar(state, flowIndent)) ||\n readSingleQuotedScalar(state, flowIndent) ||\n readDoubleQuotedScalar(state, flowIndent)) {\n hasContent = true;\n\n } else if (readAlias(state)) {\n hasContent = true;\n\n if (state.tag !== null || state.anchor !== null) {\n throwError(state, 'alias node should not have any properties');\n }\n\n } else if (readPlainScalar(state, flowIndent, CONTEXT_FLOW_IN === nodeContext)) {\n hasContent = true;\n\n if (state.tag === null) {\n state.tag = '?';\n }\n }\n\n if (state.anchor !== null) {\n state.anchorMap[state.anchor] = state.result;\n }\n }\n } else if (indentStatus === 0) {\n // Special case: block sequences are allowed to have same indentation level as the parent.\n // http://www.yaml.org/spec/1.2/spec.html#id2799784\n hasContent = allowBlockCollections && readBlockSequence(state, blockIndent);\n }\n }\n\n if (state.tag === null) {\n if (state.anchor !== null) {\n state.anchorMap[state.anchor] = state.result;\n }\n\n } else if (state.tag === '?') {\n // Implicit resolving is not allowed for non-scalar types, and '?'\n // non-specific tag is only automatically assigned to plain scalars.\n //\n // We only need to check kind conformity in case user explicitly assigns '?'\n // tag, for example like this: \"! [0]\"\n //\n if (state.result !== null && state.kind !== 'scalar') {\n throwError(state, 'unacceptable node kind for ! tag; it should be \"scalar\", not \"' + state.kind + '\"');\n }\n\n for (typeIndex = 0, typeQuantity = state.implicitTypes.length; typeIndex < typeQuantity; typeIndex += 1) {\n type = state.implicitTypes[typeIndex];\n\n if (type.resolve(state.result)) { // `state.result` updated in resolver if matched\n state.result = type.construct(state.result);\n state.tag = type.tag;\n if (state.anchor !== null) {\n state.anchorMap[state.anchor] = state.result;\n }\n break;\n }\n }\n } else if (state.tag !== '!') {\n if (_hasOwnProperty$1.call(state.typeMap[state.kind || 'fallback'], state.tag)) {\n type = state.typeMap[state.kind || 'fallback'][state.tag];\n } else {\n // looking for multi type\n type = null;\n typeList = state.typeMap.multi[state.kind || 'fallback'];\n\n for (typeIndex = 0, typeQuantity = typeList.length; typeIndex < typeQuantity; typeIndex += 1) {\n if (state.tag.slice(0, typeList[typeIndex].tag.length) === typeList[typeIndex].tag) {\n type = typeList[typeIndex];\n break;\n }\n }\n }\n\n if (!type) {\n throwError(state, 'unknown tag !<' + state.tag + '>');\n }\n\n if (state.result !== null && type.kind !== state.kind) {\n throwError(state, 'unacceptable node kind for !<' + state.tag + '> tag; it should be \"' + type.kind + '\", not \"' + state.kind + '\"');\n }\n\n if (!type.resolve(state.result, state.tag)) { // `state.result` updated in resolver if matched\n throwError(state, 'cannot resolve a node with !<' + state.tag + '> explicit tag');\n } else {\n state.result = type.construct(state.result, state.tag);\n if (state.anchor !== null) {\n state.anchorMap[state.anchor] = state.result;\n }\n }\n }\n\n if (state.listener !== null) {\n state.listener('close', state);\n }\n return state.tag !== null || state.anchor !== null || hasContent;\n}\n\nfunction readDocument(state) {\n var documentStart = state.position,\n _position,\n directiveName,\n directiveArgs,\n hasDirectives = false,\n ch;\n\n state.version = null;\n state.checkLineBreaks = state.legacy;\n state.tagMap = Object.create(null);\n state.anchorMap = Object.create(null);\n\n while ((ch = state.input.charCodeAt(state.position)) !== 0) {\n skipSeparationSpace(state, true, -1);\n\n ch = state.input.charCodeAt(state.position);\n\n if (state.lineIndent > 0 || ch !== 0x25/* % */) {\n break;\n }\n\n hasDirectives = true;\n ch = state.input.charCodeAt(++state.position);\n _position = state.position;\n\n while (ch !== 0 && !is_WS_OR_EOL(ch)) {\n ch = state.input.charCodeAt(++state.position);\n }\n\n directiveName = state.input.slice(_position, state.position);\n directiveArgs = [];\n\n if (directiveName.length < 1) {\n throwError(state, 'directive name must not be less than one character in length');\n }\n\n while (ch !== 0) {\n while (is_WHITE_SPACE(ch)) {\n ch = state.input.charCodeAt(++state.position);\n }\n\n if (ch === 0x23/* # */) {\n do { ch = state.input.charCodeAt(++state.position); }\n while (ch !== 0 && !is_EOL(ch));\n break;\n }\n\n if (is_EOL(ch)) break;\n\n _position = state.position;\n\n while (ch !== 0 && !is_WS_OR_EOL(ch)) {\n ch = state.input.charCodeAt(++state.position);\n }\n\n directiveArgs.push(state.input.slice(_position, state.position));\n }\n\n if (ch !== 0) readLineBreak(state);\n\n if (_hasOwnProperty$1.call(directiveHandlers, directiveName)) {\n directiveHandlers[directiveName](state, directiveName, directiveArgs);\n } else {\n throwWarning(state, 'unknown document directive \"' + directiveName + '\"');\n }\n }\n\n skipSeparationSpace(state, true, -1);\n\n if (state.lineIndent === 0 &&\n state.input.charCodeAt(state.position) === 0x2D/* - */ &&\n state.input.charCodeAt(state.position + 1) === 0x2D/* - */ &&\n state.input.charCodeAt(state.position + 2) === 0x2D/* - */) {\n state.position += 3;\n skipSeparationSpace(state, true, -1);\n\n } else if (hasDirectives) {\n throwError(state, 'directives end mark is expected');\n }\n\n composeNode(state, state.lineIndent - 1, CONTEXT_BLOCK_OUT, false, true);\n skipSeparationSpace(state, true, -1);\n\n if (state.checkLineBreaks &&\n PATTERN_NON_ASCII_LINE_BREAKS.test(state.input.slice(documentStart, state.position))) {\n throwWarning(state, 'non-ASCII line breaks are interpreted as content');\n }\n\n state.documents.push(state.result);\n\n if (state.position === state.lineStart && testDocumentSeparator(state)) {\n\n if (state.input.charCodeAt(state.position) === 0x2E/* . */) {\n state.position += 3;\n skipSeparationSpace(state, true, -1);\n }\n return;\n }\n\n if (state.position < (state.length - 1)) {\n throwError(state, 'end of the stream or a document separator is expected');\n } else {\n return;\n }\n}\n\n\nfunction loadDocuments(input, options) {\n input = String(input);\n options = options || {};\n\n if (input.length !== 0) {\n\n // Add tailing `\\n` if not exists\n if (input.charCodeAt(input.length - 1) !== 0x0A/* LF */ &&\n input.charCodeAt(input.length - 1) !== 0x0D/* CR */) {\n input += '\\n';\n }\n\n // Strip BOM\n if (input.charCodeAt(0) === 0xFEFF) {\n input = input.slice(1);\n }\n }\n\n var state = new State$1(input, options);\n\n var nullpos = input.indexOf('\\0');\n\n if (nullpos !== -1) {\n state.position = nullpos;\n throwError(state, 'null byte is not allowed in input');\n }\n\n // Use 0 as string terminator. That significantly simplifies bounds check.\n state.input += '\\0';\n\n while (state.input.charCodeAt(state.position) === 0x20/* Space */) {\n state.lineIndent += 1;\n state.position += 1;\n }\n\n while (state.position < (state.length - 1)) {\n readDocument(state);\n }\n\n return state.documents;\n}\n\n\nfunction loadAll$1(input, iterator, options) {\n if (iterator !== null && typeof iterator === 'object' && typeof options === 'undefined') {\n options = iterator;\n iterator = null;\n }\n\n var documents = loadDocuments(input, options);\n\n if (typeof iterator !== 'function') {\n return documents;\n }\n\n for (var index = 0, length = documents.length; index < length; index += 1) {\n iterator(documents[index]);\n }\n}\n\n\nfunction load$1(input, options) {\n var documents = loadDocuments(input, options);\n\n if (documents.length === 0) {\n /*eslint-disable no-undefined*/\n return undefined;\n } else if (documents.length === 1) {\n return documents[0];\n }\n throw new exception('expected a single document in the stream, but found more');\n}\n\n\nvar loadAll_1 = loadAll$1;\nvar load_1 = load$1;\n\nvar loader = {\n\tloadAll: loadAll_1,\n\tload: load_1\n};\n\n/*eslint-disable no-use-before-define*/\n\n\n\n\n\nvar _toString = Object.prototype.toString;\nvar _hasOwnProperty = Object.prototype.hasOwnProperty;\n\nvar CHAR_BOM = 0xFEFF;\nvar CHAR_TAB = 0x09; /* Tab */\nvar CHAR_LINE_FEED = 0x0A; /* LF */\nvar CHAR_CARRIAGE_RETURN = 0x0D; /* CR */\nvar CHAR_SPACE = 0x20; /* Space */\nvar CHAR_EXCLAMATION = 0x21; /* ! */\nvar CHAR_DOUBLE_QUOTE = 0x22; /* \" */\nvar CHAR_SHARP = 0x23; /* # */\nvar CHAR_PERCENT = 0x25; /* % */\nvar CHAR_AMPERSAND = 0x26; /* & */\nvar CHAR_SINGLE_QUOTE = 0x27; /* ' */\nvar CHAR_ASTERISK = 0x2A; /* * */\nvar CHAR_COMMA = 0x2C; /* , */\nvar CHAR_MINUS = 0x2D; /* - */\nvar CHAR_COLON = 0x3A; /* : */\nvar CHAR_EQUALS = 0x3D; /* = */\nvar CHAR_GREATER_THAN = 0x3E; /* > */\nvar CHAR_QUESTION = 0x3F; /* ? */\nvar CHAR_COMMERCIAL_AT = 0x40; /* @ */\nvar CHAR_LEFT_SQUARE_BRACKET = 0x5B; /* [ */\nvar CHAR_RIGHT_SQUARE_BRACKET = 0x5D; /* ] */\nvar CHAR_GRAVE_ACCENT = 0x60; /* ` */\nvar CHAR_LEFT_CURLY_BRACKET = 0x7B; /* { */\nvar CHAR_VERTICAL_LINE = 0x7C; /* | */\nvar CHAR_RIGHT_CURLY_BRACKET = 0x7D; /* } */\n\nvar ESCAPE_SEQUENCES = {};\n\nESCAPE_SEQUENCES[0x00] = '\\\\0';\nESCAPE_SEQUENCES[0x07] = '\\\\a';\nESCAPE_SEQUENCES[0x08] = '\\\\b';\nESCAPE_SEQUENCES[0x09] = '\\\\t';\nESCAPE_SEQUENCES[0x0A] = '\\\\n';\nESCAPE_SEQUENCES[0x0B] = '\\\\v';\nESCAPE_SEQUENCES[0x0C] = '\\\\f';\nESCAPE_SEQUENCES[0x0D] = '\\\\r';\nESCAPE_SEQUENCES[0x1B] = '\\\\e';\nESCAPE_SEQUENCES[0x22] = '\\\\\"';\nESCAPE_SEQUENCES[0x5C] = '\\\\\\\\';\nESCAPE_SEQUENCES[0x85] = '\\\\N';\nESCAPE_SEQUENCES[0xA0] = '\\\\_';\nESCAPE_SEQUENCES[0x2028] = '\\\\L';\nESCAPE_SEQUENCES[0x2029] = '\\\\P';\n\nvar DEPRECATED_BOOLEANS_SYNTAX = [\n 'y', 'Y', 'yes', 'Yes', 'YES', 'on', 'On', 'ON',\n 'n', 'N', 'no', 'No', 'NO', 'off', 'Off', 'OFF'\n];\n\nvar DEPRECATED_BASE60_SYNTAX = /^[-+]?[0-9_]+(?::[0-9_]+)+(?:\\.[0-9_]*)?$/;\n\nfunction compileStyleMap(schema, map) {\n var result, keys, index, length, tag, style, type;\n\n if (map === null) return {};\n\n result = {};\n keys = Object.keys(map);\n\n for (index = 0, length = keys.length; index < length; index += 1) {\n tag = keys[index];\n style = String(map[tag]);\n\n if (tag.slice(0, 2) === '!!') {\n tag = 'tag:yaml.org,2002:' + tag.slice(2);\n }\n type = schema.compiledTypeMap['fallback'][tag];\n\n if (type && _hasOwnProperty.call(type.styleAliases, style)) {\n style = type.styleAliases[style];\n }\n\n result[tag] = style;\n }\n\n return result;\n}\n\nfunction encodeHex(character) {\n var string, handle, length;\n\n string = character.toString(16).toUpperCase();\n\n if (character <= 0xFF) {\n handle = 'x';\n length = 2;\n } else if (character <= 0xFFFF) {\n handle = 'u';\n length = 4;\n } else if (character <= 0xFFFFFFFF) {\n handle = 'U';\n length = 8;\n } else {\n throw new exception('code point within a string may not be greater than 0xFFFFFFFF');\n }\n\n return '\\\\' + handle + common.repeat('0', length - string.length) + string;\n}\n\n\nvar QUOTING_TYPE_SINGLE = 1,\n QUOTING_TYPE_DOUBLE = 2;\n\nfunction State(options) {\n this.schema = options['schema'] || _default;\n this.indent = Math.max(1, (options['indent'] || 2));\n this.noArrayIndent = options['noArrayIndent'] || false;\n this.skipInvalid = options['skipInvalid'] || false;\n this.flowLevel = (common.isNothing(options['flowLevel']) ? -1 : options['flowLevel']);\n this.styleMap = compileStyleMap(this.schema, options['styles'] || null);\n this.sortKeys = options['sortKeys'] || false;\n this.lineWidth = options['lineWidth'] || 80;\n this.noRefs = options['noRefs'] || false;\n this.noCompatMode = options['noCompatMode'] || false;\n this.condenseFlow = options['condenseFlow'] || false;\n this.quotingType = options['quotingType'] === '\"' ? QUOTING_TYPE_DOUBLE : QUOTING_TYPE_SINGLE;\n this.forceQuotes = options['forceQuotes'] || false;\n this.replacer = typeof options['replacer'] === 'function' ? options['replacer'] : null;\n\n this.implicitTypes = this.schema.compiledImplicit;\n this.explicitTypes = this.schema.compiledExplicit;\n\n this.tag = null;\n this.result = '';\n\n this.duplicates = [];\n this.usedDuplicates = null;\n}\n\n// Indents every line in a string. Empty lines (\\n only) are not indented.\nfunction indentString(string, spaces) {\n var ind = common.repeat(' ', spaces),\n position = 0,\n next = -1,\n result = '',\n line,\n length = string.length;\n\n while (position < length) {\n next = string.indexOf('\\n', position);\n if (next === -1) {\n line = string.slice(position);\n position = length;\n } else {\n line = string.slice(position, next + 1);\n position = next + 1;\n }\n\n if (line.length && line !== '\\n') result += ind;\n\n result += line;\n }\n\n return result;\n}\n\nfunction generateNextLine(state, level) {\n return '\\n' + common.repeat(' ', state.indent * level);\n}\n\nfunction testImplicitResolving(state, str) {\n var index, length, type;\n\n for (index = 0, length = state.implicitTypes.length; index < length; index += 1) {\n type = state.implicitTypes[index];\n\n if (type.resolve(str)) {\n return true;\n }\n }\n\n return false;\n}\n\n// [33] s-white ::= s-space | s-tab\nfunction isWhitespace(c) {\n return c === CHAR_SPACE || c === CHAR_TAB;\n}\n\n// Returns true if the character can be printed without escaping.\n// From YAML 1.2: \"any allowed characters known to be non-printable\n// should also be escaped. [However,] This isn\u2019t mandatory\"\n// Derived from nb-char - \\t - #x85 - #xA0 - #x2028 - #x2029.\nfunction isPrintable(c) {\n return (0x00020 <= c && c <= 0x00007E)\n || ((0x000A1 <= c && c <= 0x00D7FF) && c !== 0x2028 && c !== 0x2029)\n || ((0x0E000 <= c && c <= 0x00FFFD) && c !== CHAR_BOM)\n || (0x10000 <= c && c <= 0x10FFFF);\n}\n\n// [34] ns-char ::= nb-char - s-white\n// [27] nb-char ::= c-printable - b-char - c-byte-order-mark\n// [26] b-char ::= b-line-feed | b-carriage-return\n// Including s-white (for some reason, examples doesn't match specs in this aspect)\n// ns-char ::= c-printable - b-line-feed - b-carriage-return - c-byte-order-mark\nfunction isNsCharOrWhitespace(c) {\n return isPrintable(c)\n && c !== CHAR_BOM\n // - b-char\n && c !== CHAR_CARRIAGE_RETURN\n && c !== CHAR_LINE_FEED;\n}\n\n// [127] ns-plain-safe(c) ::= c = flow-out \u21D2 ns-plain-safe-out\n// c = flow-in \u21D2 ns-plain-safe-in\n// c = block-key \u21D2 ns-plain-safe-out\n// c = flow-key \u21D2 ns-plain-safe-in\n// [128] ns-plain-safe-out ::= ns-char\n// [129] ns-plain-safe-in ::= ns-char - c-flow-indicator\n// [130] ns-plain-char(c) ::= ( ns-plain-safe(c) - \u201C:\u201D - \u201C#\u201D )\n// | ( /* An ns-char preceding */ \u201C#\u201D )\n// | ( \u201C:\u201D /* Followed by an ns-plain-safe(c) */ )\nfunction isPlainSafe(c, prev, inblock) {\n var cIsNsCharOrWhitespace = isNsCharOrWhitespace(c);\n var cIsNsChar = cIsNsCharOrWhitespace && !isWhitespace(c);\n return (\n // ns-plain-safe\n inblock ? // c = flow-in\n cIsNsCharOrWhitespace\n : cIsNsCharOrWhitespace\n // - c-flow-indicator\n && c !== CHAR_COMMA\n && c !== CHAR_LEFT_SQUARE_BRACKET\n && c !== CHAR_RIGHT_SQUARE_BRACKET\n && c !== CHAR_LEFT_CURLY_BRACKET\n && c !== CHAR_RIGHT_CURLY_BRACKET\n )\n // ns-plain-char\n && c !== CHAR_SHARP // false on '#'\n && !(prev === CHAR_COLON && !cIsNsChar) // false on ': '\n || (isNsCharOrWhitespace(prev) && !isWhitespace(prev) && c === CHAR_SHARP) // change to true on '[^ ]#'\n || (prev === CHAR_COLON && cIsNsChar); // change to true on ':[^ ]'\n}\n\n// Simplified test for values allowed as the first character in plain style.\nfunction isPlainSafeFirst(c) {\n // Uses a subset of ns-char - c-indicator\n // where ns-char = nb-char - s-white.\n // No support of ( ( \u201C?\u201D | \u201C:\u201D | \u201C-\u201D ) /* Followed by an ns-plain-safe(c)) */ ) part\n return isPrintable(c) && c !== CHAR_BOM\n && !isWhitespace(c) // - s-white\n // - (c-indicator ::=\n // \u201C-\u201D | \u201C?\u201D | \u201C:\u201D | \u201C,\u201D | \u201C[\u201D | \u201C]\u201D | \u201C{\u201D | \u201C}\u201D\n && c !== CHAR_MINUS\n && c !== CHAR_QUESTION\n && c !== CHAR_COLON\n && c !== CHAR_COMMA\n && c !== CHAR_LEFT_SQUARE_BRACKET\n && c !== CHAR_RIGHT_SQUARE_BRACKET\n && c !== CHAR_LEFT_CURLY_BRACKET\n && c !== CHAR_RIGHT_CURLY_BRACKET\n // | \u201C#\u201D | \u201C&\u201D | \u201C*\u201D | \u201C!\u201D | \u201C|\u201D | \u201C=\u201D | \u201C>\u201D | \u201C'\u201D | \u201C\"\u201D\n && c !== CHAR_SHARP\n && c !== CHAR_AMPERSAND\n && c !== CHAR_ASTERISK\n && c !== CHAR_EXCLAMATION\n && c !== CHAR_VERTICAL_LINE\n && c !== CHAR_EQUALS\n && c !== CHAR_GREATER_THAN\n && c !== CHAR_SINGLE_QUOTE\n && c !== CHAR_DOUBLE_QUOTE\n // | \u201C%\u201D | \u201C@\u201D | \u201C`\u201D)\n && c !== CHAR_PERCENT\n && c !== CHAR_COMMERCIAL_AT\n && c !== CHAR_GRAVE_ACCENT;\n}\n\n// Simplified test for values allowed as the last character in plain style.\nfunction isPlainSafeLast(c) {\n // just not whitespace or colon, it will be checked to be plain character later\n return !isWhitespace(c) && c !== CHAR_COLON;\n}\n\n// Same as 'string'.codePointAt(pos), but works in older browsers.\nfunction codePointAt(string, pos) {\n var first = string.charCodeAt(pos), second;\n if (first >= 0xD800 && first <= 0xDBFF && pos + 1 < string.length) {\n second = string.charCodeAt(pos + 1);\n if (second >= 0xDC00 && second <= 0xDFFF) {\n // https://mathiasbynens.be/notes/javascript-encoding#surrogate-formulae\n return (first - 0xD800) * 0x400 + second - 0xDC00 + 0x10000;\n }\n }\n return first;\n}\n\n// Determines whether block indentation indicator is required.\nfunction needIndentIndicator(string) {\n var leadingSpaceRe = /^\\n* /;\n return leadingSpaceRe.test(string);\n}\n\nvar STYLE_PLAIN = 1,\n STYLE_SINGLE = 2,\n STYLE_LITERAL = 3,\n STYLE_FOLDED = 4,\n STYLE_DOUBLE = 5;\n\n// Determines which scalar styles are possible and returns the preferred style.\n// lineWidth = -1 => no limit.\n// Pre-conditions: str.length > 0.\n// Post-conditions:\n// STYLE_PLAIN or STYLE_SINGLE => no \\n are in the string.\n// STYLE_LITERAL => no lines are suitable for folding (or lineWidth is -1).\n// STYLE_FOLDED => a line > lineWidth and can be folded (and lineWidth != -1).\nfunction chooseScalarStyle(string, singleLineOnly, indentPerLevel, lineWidth,\n testAmbiguousType, quotingType, forceQuotes, inblock) {\n\n var i;\n var char = 0;\n var prevChar = null;\n var hasLineBreak = false;\n var hasFoldableLine = false; // only checked if shouldTrackWidth\n var shouldTrackWidth = lineWidth !== -1;\n var previousLineBreak = -1; // count the first line correctly\n var plain = isPlainSafeFirst(codePointAt(string, 0))\n && isPlainSafeLast(codePointAt(string, string.length - 1));\n\n if (singleLineOnly || forceQuotes) {\n // Case: no block styles.\n // Check for disallowed characters to rule out plain and single.\n for (i = 0; i < string.length; char >= 0x10000 ? i += 2 : i++) {\n char = codePointAt(string, i);\n if (!isPrintable(char)) {\n return STYLE_DOUBLE;\n }\n plain = plain && isPlainSafe(char, prevChar, inblock);\n prevChar = char;\n }\n } else {\n // Case: block styles permitted.\n for (i = 0; i < string.length; char >= 0x10000 ? i += 2 : i++) {\n char = codePointAt(string, i);\n if (char === CHAR_LINE_FEED) {\n hasLineBreak = true;\n // Check if any line can be folded.\n if (shouldTrackWidth) {\n hasFoldableLine = hasFoldableLine ||\n // Foldable line = too long, and not more-indented.\n (i - previousLineBreak - 1 > lineWidth &&\n string[previousLineBreak + 1] !== ' ');\n previousLineBreak = i;\n }\n } else if (!isPrintable(char)) {\n return STYLE_DOUBLE;\n }\n plain = plain && isPlainSafe(char, prevChar, inblock);\n prevChar = char;\n }\n // in case the end is missing a \\n\n hasFoldableLine = hasFoldableLine || (shouldTrackWidth &&\n (i - previousLineBreak - 1 > lineWidth &&\n string[previousLineBreak + 1] !== ' '));\n }\n // Although every style can represent \\n without escaping, prefer block styles\n // for multiline, since they're more readable and they don't add empty lines.\n // Also prefer folding a super-long line.\n if (!hasLineBreak && !hasFoldableLine) {\n // Strings interpretable as another type have to be quoted;\n // e.g. the string 'true' vs. the boolean true.\n if (plain && !forceQuotes && !testAmbiguousType(string)) {\n return STYLE_PLAIN;\n }\n return quotingType === QUOTING_TYPE_DOUBLE ? STYLE_DOUBLE : STYLE_SINGLE;\n }\n // Edge case: block indentation indicator can only have one digit.\n if (indentPerLevel > 9 && needIndentIndicator(string)) {\n return STYLE_DOUBLE;\n }\n // At this point we know block styles are valid.\n // Prefer literal style unless we want to fold.\n if (!forceQuotes) {\n return hasFoldableLine ? STYLE_FOLDED : STYLE_LITERAL;\n }\n return quotingType === QUOTING_TYPE_DOUBLE ? STYLE_DOUBLE : STYLE_SINGLE;\n}\n\n// Note: line breaking/folding is implemented for only the folded style.\n// NB. We drop the last trailing newline (if any) of a returned block scalar\n// since the dumper adds its own newline. This always works:\n// \u2022 No ending newline => unaffected; already using strip \"-\" chomping.\n// \u2022 Ending newline => removed then restored.\n// Importantly, this keeps the \"+\" chomp indicator from gaining an extra line.\nfunction writeScalar(state, string, level, iskey, inblock) {\n state.dump = (function () {\n if (string.length === 0) {\n return state.quotingType === QUOTING_TYPE_DOUBLE ? '\"\"' : \"''\";\n }\n if (!state.noCompatMode) {\n if (DEPRECATED_BOOLEANS_SYNTAX.indexOf(string) !== -1 || DEPRECATED_BASE60_SYNTAX.test(string)) {\n return state.quotingType === QUOTING_TYPE_DOUBLE ? ('\"' + string + '\"') : (\"'\" + string + \"'\");\n }\n }\n\n var indent = state.indent * Math.max(1, level); // no 0-indent scalars\n // As indentation gets deeper, let the width decrease monotonically\n // to the lower bound min(state.lineWidth, 40).\n // Note that this implies\n // state.lineWidth \u2264 40 + state.indent: width is fixed at the lower bound.\n // state.lineWidth > 40 + state.indent: width decreases until the lower bound.\n // This behaves better than a constant minimum width which disallows narrower options,\n // or an indent threshold which causes the width to suddenly increase.\n var lineWidth = state.lineWidth === -1\n ? -1 : Math.max(Math.min(state.lineWidth, 40), state.lineWidth - indent);\n\n // Without knowing if keys are implicit/explicit, assume implicit for safety.\n var singleLineOnly = iskey\n // No block styles in flow mode.\n || (state.flowLevel > -1 && level >= state.flowLevel);\n function testAmbiguity(string) {\n return testImplicitResolving(state, string);\n }\n\n switch (chooseScalarStyle(string, singleLineOnly, state.indent, lineWidth,\n testAmbiguity, state.quotingType, state.forceQuotes && !iskey, inblock)) {\n\n case STYLE_PLAIN:\n return string;\n case STYLE_SINGLE:\n return \"'\" + string.replace(/'/g, \"''\") + \"'\";\n case STYLE_LITERAL:\n return '|' + blockHeader(string, state.indent)\n + dropEndingNewline(indentString(string, indent));\n case STYLE_FOLDED:\n return '>' + blockHeader(string, state.indent)\n + dropEndingNewline(indentString(foldString(string, lineWidth), indent));\n case STYLE_DOUBLE:\n return '\"' + escapeString(string) + '\"';\n default:\n throw new exception('impossible error: invalid scalar style');\n }\n }());\n}\n\n// Pre-conditions: string is valid for a block scalar, 1 <= indentPerLevel <= 9.\nfunction blockHeader(string, indentPerLevel) {\n var indentIndicator = needIndentIndicator(string) ? String(indentPerLevel) : '';\n\n // note the special case: the string '\\n' counts as a \"trailing\" empty line.\n var clip = string[string.length - 1] === '\\n';\n var keep = clip && (string[string.length - 2] === '\\n' || string === '\\n');\n var chomp = keep ? '+' : (clip ? '' : '-');\n\n return indentIndicator + chomp + '\\n';\n}\n\n// (See the note for writeScalar.)\nfunction dropEndingNewline(string) {\n return string[string.length - 1] === '\\n' ? string.slice(0, -1) : string;\n}\n\n// Note: a long line without a suitable break point will exceed the width limit.\n// Pre-conditions: every char in str isPrintable, str.length > 0, width > 0.\nfunction foldString(string, width) {\n // In folded style, $k$ consecutive newlines output as $k+1$ newlines\u2014\n // unless they're before or after a more-indented line, or at the very\n // beginning or end, in which case $k$ maps to $k$.\n // Therefore, parse each chunk as newline(s) followed by a content line.\n var lineRe = /(\\n+)([^\\n]*)/g;\n\n // first line (possibly an empty line)\n var result = (function () {\n var nextLF = string.indexOf('\\n');\n nextLF = nextLF !== -1 ? nextLF : string.length;\n lineRe.lastIndex = nextLF;\n return foldLine(string.slice(0, nextLF), width);\n }());\n // If we haven't reached the first content line yet, don't add an extra \\n.\n var prevMoreIndented = string[0] === '\\n' || string[0] === ' ';\n var moreIndented;\n\n // rest of the lines\n var match;\n while ((match = lineRe.exec(string))) {\n var prefix = match[1], line = match[2];\n moreIndented = (line[0] === ' ');\n result += prefix\n + (!prevMoreIndented && !moreIndented && line !== ''\n ? '\\n' : '')\n + foldLine(line, width);\n prevMoreIndented = moreIndented;\n }\n\n return result;\n}\n\n// Greedy line breaking.\n// Picks the longest line under the limit each time,\n// otherwise settles for the shortest line over the limit.\n// NB. More-indented lines *cannot* be folded, as that would add an extra \\n.\nfunction foldLine(line, width) {\n if (line === '' || line[0] === ' ') return line;\n\n // Since a more-indented line adds a \\n, breaks can't be followed by a space.\n var breakRe = / [^ ]/g; // note: the match index will always be <= length-2.\n var match;\n // start is an inclusive index. end, curr, and next are exclusive.\n var start = 0, end, curr = 0, next = 0;\n var result = '';\n\n // Invariants: 0 <= start <= length-1.\n // 0 <= curr <= next <= max(0, length-2). curr - start <= width.\n // Inside the loop:\n // A match implies length >= 2, so curr and next are <= length-2.\n while ((match = breakRe.exec(line))) {\n next = match.index;\n // maintain invariant: curr - start <= width\n if (next - start > width) {\n end = (curr > start) ? curr : next; // derive end <= length-2\n result += '\\n' + line.slice(start, end);\n // skip the space that was output as \\n\n start = end + 1; // derive start <= length-1\n }\n curr = next;\n }\n\n // By the invariants, start <= length-1, so there is something left over.\n // It is either the whole string or a part starting from non-whitespace.\n result += '\\n';\n // Insert a break if the remainder is too long and there is a break available.\n if (line.length - start > width && curr > start) {\n result += line.slice(start, curr) + '\\n' + line.slice(curr + 1);\n } else {\n result += line.slice(start);\n }\n\n return result.slice(1); // drop extra \\n joiner\n}\n\n// Escapes a double-quoted string.\nfunction escapeString(string) {\n var result = '';\n var char = 0;\n var escapeSeq;\n\n for (var i = 0; i < string.length; char >= 0x10000 ? i += 2 : i++) {\n char = codePointAt(string, i);\n escapeSeq = ESCAPE_SEQUENCES[char];\n\n if (!escapeSeq && isPrintable(char)) {\n result += string[i];\n if (char >= 0x10000) result += string[i + 1];\n } else {\n result += escapeSeq || encodeHex(char);\n }\n }\n\n return result;\n}\n\nfunction writeFlowSequence(state, level, object) {\n var _result = '',\n _tag = state.tag,\n index,\n length,\n value;\n\n for (index = 0, length = object.length; index < length; index += 1) {\n value = object[index];\n\n if (state.replacer) {\n value = state.replacer.call(object, String(index), value);\n }\n\n // Write only valid elements, put null instead of invalid elements.\n if (writeNode(state, level, value, false, false) ||\n (typeof value === 'undefined' &&\n writeNode(state, level, null, false, false))) {\n\n if (_result !== '') _result += ',' + (!state.condenseFlow ? ' ' : '');\n _result += state.dump;\n }\n }\n\n state.tag = _tag;\n state.dump = '[' + _result + ']';\n}\n\nfunction writeBlockSequence(state, level, object, compact) {\n var _result = '',\n _tag = state.tag,\n index,\n length,\n value;\n\n for (index = 0, length = object.length; index < length; index += 1) {\n value = object[index];\n\n if (state.replacer) {\n value = state.replacer.call(object, String(index), value);\n }\n\n // Write only valid elements, put null instead of invalid elements.\n if (writeNode(state, level + 1, value, true, true, false, true) ||\n (typeof value === 'undefined' &&\n writeNode(state, level + 1, null, true, true, false, true))) {\n\n if (!compact || _result !== '') {\n _result += generateNextLine(state, level);\n }\n\n if (state.dump && CHAR_LINE_FEED === state.dump.charCodeAt(0)) {\n _result += '-';\n } else {\n _result += '- ';\n }\n\n _result += state.dump;\n }\n }\n\n state.tag = _tag;\n state.dump = _result || '[]'; // Empty sequence if no valid values.\n}\n\nfunction writeFlowMapping(state, level, object) {\n var _result = '',\n _tag = state.tag,\n objectKeyList = Object.keys(object),\n index,\n length,\n objectKey,\n objectValue,\n pairBuffer;\n\n for (index = 0, length = objectKeyList.length; index < length; index += 1) {\n\n pairBuffer = '';\n if (_result !== '') pairBuffer += ', ';\n\n if (state.condenseFlow) pairBuffer += '\"';\n\n objectKey = objectKeyList[index];\n objectValue = object[objectKey];\n\n if (state.replacer) {\n objectValue = state.replacer.call(object, objectKey, objectValue);\n }\n\n if (!writeNode(state, level, objectKey, false, false)) {\n continue; // Skip this pair because of invalid key;\n }\n\n if (state.dump.length > 1024) pairBuffer += '? ';\n\n pairBuffer += state.dump + (state.condenseFlow ? '\"' : '') + ':' + (state.condenseFlow ? '' : ' ');\n\n if (!writeNode(state, level, objectValue, false, false)) {\n continue; // Skip this pair because of invalid value.\n }\n\n pairBuffer += state.dump;\n\n // Both key and value are valid.\n _result += pairBuffer;\n }\n\n state.tag = _tag;\n state.dump = '{' + _result + '}';\n}\n\nfunction writeBlockMapping(state, level, object, compact) {\n var _result = '',\n _tag = state.tag,\n objectKeyList = Object.keys(object),\n index,\n length,\n objectKey,\n objectValue,\n explicitPair,\n pairBuffer;\n\n // Allow sorting keys so that the output file is deterministic\n if (state.sortKeys === true) {\n // Default sorting\n objectKeyList.sort();\n } else if (typeof state.sortKeys === 'function') {\n // Custom sort function\n objectKeyList.sort(state.sortKeys);\n } else if (state.sortKeys) {\n // Something is wrong\n throw new exception('sortKeys must be a boolean or a function');\n }\n\n for (index = 0, length = objectKeyList.length; index < length; index += 1) {\n pairBuffer = '';\n\n if (!compact || _result !== '') {\n pairBuffer += generateNextLine(state, level);\n }\n\n objectKey = objectKeyList[index];\n objectValue = object[objectKey];\n\n if (state.replacer) {\n objectValue = state.replacer.call(object, objectKey, objectValue);\n }\n\n if (!writeNode(state, level + 1, objectKey, true, true, true)) {\n continue; // Skip this pair because of invalid key.\n }\n\n explicitPair = (state.tag !== null && state.tag !== '?') ||\n (state.dump && state.dump.length > 1024);\n\n if (explicitPair) {\n if (state.dump && CHAR_LINE_FEED === state.dump.charCodeAt(0)) {\n pairBuffer += '?';\n } else {\n pairBuffer += '? ';\n }\n }\n\n pairBuffer += state.dump;\n\n if (explicitPair) {\n pairBuffer += generateNextLine(state, level);\n }\n\n if (!writeNode(state, level + 1, objectValue, true, explicitPair)) {\n continue; // Skip this pair because of invalid value.\n }\n\n if (state.dump && CHAR_LINE_FEED === state.dump.charCodeAt(0)) {\n pairBuffer += ':';\n } else {\n pairBuffer += ': ';\n }\n\n pairBuffer += state.dump;\n\n // Both key and value are valid.\n _result += pairBuffer;\n }\n\n state.tag = _tag;\n state.dump = _result || '{}'; // Empty mapping if no valid pairs.\n}\n\nfunction detectType(state, object, explicit) {\n var _result, typeList, index, length, type, style;\n\n typeList = explicit ? state.explicitTypes : state.implicitTypes;\n\n for (index = 0, length = typeList.length; index < length; index += 1) {\n type = typeList[index];\n\n if ((type.instanceOf || type.predicate) &&\n (!type.instanceOf || ((typeof object === 'object') && (object instanceof type.instanceOf))) &&\n (!type.predicate || type.predicate(object))) {\n\n if (explicit) {\n if (type.multi && type.representName) {\n state.tag = type.representName(object);\n } else {\n state.tag = type.tag;\n }\n } else {\n state.tag = '?';\n }\n\n if (type.represent) {\n style = state.styleMap[type.tag] || type.defaultStyle;\n\n if (_toString.call(type.represent) === '[object Function]') {\n _result = type.represent(object, style);\n } else if (_hasOwnProperty.call(type.represent, style)) {\n _result = type.represent[style](object, style);\n } else {\n throw new exception('!<' + type.tag + '> tag resolver accepts not \"' + style + '\" style');\n }\n\n state.dump = _result;\n }\n\n return true;\n }\n }\n\n return false;\n}\n\n// Serializes `object` and writes it to global `result`.\n// Returns true on success, or false on invalid object.\n//\nfunction writeNode(state, level, object, block, compact, iskey, isblockseq) {\n state.tag = null;\n state.dump = object;\n\n if (!detectType(state, object, false)) {\n detectType(state, object, true);\n }\n\n var type = _toString.call(state.dump);\n var inblock = block;\n var tagStr;\n\n if (block) {\n block = (state.flowLevel < 0 || state.flowLevel > level);\n }\n\n var objectOrArray = type === '[object Object]' || type === '[object Array]',\n duplicateIndex,\n duplicate;\n\n if (objectOrArray) {\n duplicateIndex = state.duplicates.indexOf(object);\n duplicate = duplicateIndex !== -1;\n }\n\n if ((state.tag !== null && state.tag !== '?') || duplicate || (state.indent !== 2 && level > 0)) {\n compact = false;\n }\n\n if (duplicate && state.usedDuplicates[duplicateIndex]) {\n state.dump = '*ref_' + duplicateIndex;\n } else {\n if (objectOrArray && duplicate && !state.usedDuplicates[duplicateIndex]) {\n state.usedDuplicates[duplicateIndex] = true;\n }\n if (type === '[object Object]') {\n if (block && (Object.keys(state.dump).length !== 0)) {\n writeBlockMapping(state, level, state.dump, compact);\n if (duplicate) {\n state.dump = '&ref_' + duplicateIndex + state.dump;\n }\n } else {\n writeFlowMapping(state, level, state.dump);\n if (duplicate) {\n state.dump = '&ref_' + duplicateIndex + ' ' + state.dump;\n }\n }\n } else if (type === '[object Array]') {\n if (block && (state.dump.length !== 0)) {\n if (state.noArrayIndent && !isblockseq && level > 0) {\n writeBlockSequence(state, level - 1, state.dump, compact);\n } else {\n writeBlockSequence(state, level, state.dump, compact);\n }\n if (duplicate) {\n state.dump = '&ref_' + duplicateIndex + state.dump;\n }\n } else {\n writeFlowSequence(state, level, state.dump);\n if (duplicate) {\n state.dump = '&ref_' + duplicateIndex + ' ' + state.dump;\n }\n }\n } else if (type === '[object String]') {\n if (state.tag !== '?') {\n writeScalar(state, state.dump, level, iskey, inblock);\n }\n } else if (type === '[object Undefined]') {\n return false;\n } else {\n if (state.skipInvalid) return false;\n throw new exception('unacceptable kind of an object to dump ' + type);\n }\n\n if (state.tag !== null && state.tag !== '?') {\n // Need to encode all characters except those allowed by the spec:\n //\n // [35] ns-dec-digit ::= [#x30-#x39] /* 0-9 */\n // [36] ns-hex-digit ::= ns-dec-digit\n // | [#x41-#x46] /* A-F */ | [#x61-#x66] /* a-f */\n // [37] ns-ascii-letter ::= [#x41-#x5A] /* A-Z */ | [#x61-#x7A] /* a-z */\n // [38] ns-word-char ::= ns-dec-digit | ns-ascii-letter | \u201C-\u201D\n // [39] ns-uri-char ::= \u201C%\u201D ns-hex-digit ns-hex-digit | ns-word-char | \u201C#\u201D\n // | \u201C;\u201D | \u201C/\u201D | \u201C?\u201D | \u201C:\u201D | \u201C@\u201D | \u201C&\u201D | \u201C=\u201D | \u201C+\u201D | \u201C$\u201D | \u201C,\u201D\n // | \u201C_\u201D | \u201C.\u201D | \u201C!\u201D | \u201C~\u201D | \u201C*\u201D | \u201C'\u201D | \u201C(\u201D | \u201C)\u201D | \u201C[\u201D | \u201C]\u201D\n //\n // Also need to encode '!' because it has special meaning (end of tag prefix).\n //\n tagStr = encodeURI(\n state.tag[0] === '!' ? state.tag.slice(1) : state.tag\n ).replace(/!/g, '%21');\n\n if (state.tag[0] === '!') {\n tagStr = '!' + tagStr;\n } else if (tagStr.slice(0, 18) === 'tag:yaml.org,2002:') {\n tagStr = '!!' + tagStr.slice(18);\n } else {\n tagStr = '!<' + tagStr + '>';\n }\n\n state.dump = tagStr + ' ' + state.dump;\n }\n }\n\n return true;\n}\n\nfunction getDuplicateReferences(object, state) {\n var objects = [],\n duplicatesIndexes = [],\n index,\n length;\n\n inspectNode(object, objects, duplicatesIndexes);\n\n for (index = 0, length = duplicatesIndexes.length; index < length; index += 1) {\n state.duplicates.push(objects[duplicatesIndexes[index]]);\n }\n state.usedDuplicates = new Array(length);\n}\n\nfunction inspectNode(object, objects, duplicatesIndexes) {\n var objectKeyList,\n index,\n length;\n\n if (object !== null && typeof object === 'object') {\n index = objects.indexOf(object);\n if (index !== -1) {\n if (duplicatesIndexes.indexOf(index) === -1) {\n duplicatesIndexes.push(index);\n }\n } else {\n objects.push(object);\n\n if (Array.isArray(object)) {\n for (index = 0, length = object.length; index < length; index += 1) {\n inspectNode(object[index], objects, duplicatesIndexes);\n }\n } else {\n objectKeyList = Object.keys(object);\n\n for (index = 0, length = objectKeyList.length; index < length; index += 1) {\n inspectNode(object[objectKeyList[index]], objects, duplicatesIndexes);\n }\n }\n }\n }\n}\n\nfunction dump$1(input, options) {\n options = options || {};\n\n var state = new State(options);\n\n if (!state.noRefs) getDuplicateReferences(input, state);\n\n var value = input;\n\n if (state.replacer) {\n value = state.replacer.call({ '': value }, '', value);\n }\n\n if (writeNode(state, 0, value, true, true)) return state.dump + '\\n';\n\n return '';\n}\n\nvar dump_1 = dump$1;\n\nvar dumper = {\n\tdump: dump_1\n};\n\nfunction renamed(from, to) {\n return function () {\n throw new Error('Function yaml.' + from + ' is removed in js-yaml 4. ' +\n 'Use yaml.' + to + ' instead, which is now safe by default.');\n };\n}\n\n\nvar Type = type;\nvar Schema = schema;\nvar FAILSAFE_SCHEMA = failsafe;\nvar JSON_SCHEMA = json;\nvar CORE_SCHEMA = core;\nvar DEFAULT_SCHEMA = _default;\nvar load = loader.load;\nvar loadAll = loader.loadAll;\nvar dump = dumper.dump;\nvar YAMLException = exception;\n\n// Re-export all types in case user wants to create custom schema\nvar types = {\n binary: binary,\n float: float,\n map: map,\n null: _null,\n pairs: pairs,\n set: set,\n timestamp: timestamp,\n bool: bool,\n int: int,\n merge: merge,\n omap: omap,\n seq: seq,\n str: str\n};\n\n// Removed functions from JS-YAML 3.0.x\nvar safeLoad = renamed('safeLoad', 'load');\nvar safeLoadAll = renamed('safeLoadAll', 'loadAll');\nvar safeDump = renamed('safeDump', 'dump');\n\nvar jsYaml = {\n\tType: Type,\n\tSchema: Schema,\n\tFAILSAFE_SCHEMA: FAILSAFE_SCHEMA,\n\tJSON_SCHEMA: JSON_SCHEMA,\n\tCORE_SCHEMA: CORE_SCHEMA,\n\tDEFAULT_SCHEMA: DEFAULT_SCHEMA,\n\tload: load,\n\tloadAll: loadAll,\n\tdump: dump,\n\tYAMLException: YAMLException,\n\ttypes: types,\n\tsafeLoad: safeLoad,\n\tsafeLoadAll: safeLoadAll,\n\tsafeDump: safeDump\n};\n\nexport { CORE_SCHEMA, DEFAULT_SCHEMA, FAILSAFE_SCHEMA, JSON_SCHEMA, Schema, Type, YAMLException, jsYaml as default, dump, load, loadAll, safeDump, safeLoad, safeLoadAll, types };\n", "/**\n * CodeQL metadata resolver utilities\n * Handles resolution of query metadata using the CodeQL CLI\n */\n\nimport { executeCodeQLCommand } from './cli-executor';\nimport { logger } from '../utils/logger';\n\n/**\n * Query metadata structure returned by codeql resolve metadata\n */\nexport interface QueryMetadata {\n [key: string]: string | string[];\n}\n\n/**\n * Resolve metadata for a CodeQL query file\n * @param queryPath - Absolute or relative path to the .ql query file\n * @returns Parsed metadata object or null if resolution fails\n */\nexport async function resolveQueryMetadata(queryPath: string): Promise {\n try {\n logger.info(`Resolving metadata for query: ${queryPath}`);\n\n const result = await executeCodeQLCommand(\n 'resolve metadata',\n { format: 'json' },\n [queryPath]\n );\n\n if (!result.success) {\n logger.error(`Failed to resolve metadata for ${queryPath}:`, result.stderr || result.error);\n return null;\n }\n\n // Parse the JSON output\n try {\n const metadata = JSON.parse(result.stdout);\n return metadata;\n } catch (parseError) {\n logger.error(`Failed to parse metadata JSON for ${queryPath}:`, parseError);\n return null;\n }\n } catch (error) {\n logger.error(`Error resolving metadata for ${queryPath}:`, error);\n return null;\n }\n}\n", "/**\n * CodeQL generate log-summary tool\n */\n\nimport { z } from 'zod';\nimport { CLIToolDefinition, createCodeQLSchemas, defaultCLIResultProcessor } from '../../lib/cli-tool-registry';\n\nexport const codeqlGenerateLogSummaryTool: CLIToolDefinition = {\n name: 'codeql_generate_log-summary',\n description: 'Create a summary of a structured JSON evaluator event log file',\n command: 'codeql',\n subcommand: 'generate log-summary',\n inputSchema: {\n inputLog: z.string().describe('Path to the evaluator log file to summarize'),\n outputFile: z.string().optional().describe('Path to write the summary (optional, defaults to stdout)'),\n format: z.enum(['text', 'predicates', 'overall']).optional()\n .describe('Output format: text (human-readable), predicates (JSON), or overall (stats)'),\n 'minify-output': z.boolean().optional().describe('Minify JSON output'),\n utc: z.boolean().optional().describe('Force UTC timestamps'),\n 'deduplicate-stage-summaries': z.boolean().optional().describe('Deduplicate stage summaries'),\n verbose: createCodeQLSchemas.verbose(),\n additionalArgs: createCodeQLSchemas.additionalArgs()\n },\n examples: [\n 'codeql generate log-summary --format=text -- evaluator-log.json.txt summary.txt',\n 'codeql generate log-summary --format=predicates --minify-output -- evaluator-log.json.txt',\n 'codeql generate log-summary --format=overall -- evaluator-log.json.txt overall-stats.json'\n ],\n resultProcessor: defaultCLIResultProcessor\n};", "/**\n * CodeQL generate query-help tool\n */\n\nimport { z } from 'zod';\nimport { CLIToolDefinition, createCodeQLSchemas, defaultCLIResultProcessor } from '../../lib/cli-tool-registry';\n\nexport const codeqlGenerateQueryHelpTool: CLIToolDefinition = {\n name: 'codeql_generate_query-help',\n description: 'Generate query help documentation from QLDoc comments',\n command: 'codeql',\n subcommand: 'generate query-help',\n inputSchema: {\n query: z.string().describe('Path to the query file to generate help for'),\n outputFile: z.string().optional().describe('Path to write the help documentation'),\n format: z.enum(['markdown', 'text', 'html']).optional()\n .describe('Output format for the help documentation'),\n verbose: createCodeQLSchemas.verbose(),\n additionalArgs: createCodeQLSchemas.additionalArgs()\n },\n examples: [\n 'codeql generate query-help -- MyQuery.ql',\n 'codeql generate query-help --format=markdown -- MyQuery.ql help.md',\n 'codeql generate query-help --format=html -- MyQuery.ql help.html'\n ],\n resultProcessor: defaultCLIResultProcessor\n};", "/**\n * CodeQL pack install tool\n */\n\nimport { z } from 'zod';\nimport { CLIToolDefinition, createCodeQLSchemas } from '../../lib/cli-tool-registry';\n\nexport const codeqlPackInstallTool: CLIToolDefinition = {\n name: 'codeql_pack_install',\n description: 'Install CodeQL pack dependencies',\n command: 'codeql',\n subcommand: 'pack install',\n inputSchema: {\n packDir: z.string().optional().describe('Directory containing qlpack.yml (default: current)'),\n force: z.boolean().optional().describe('Force reinstall of dependencies'),\n 'no-strict-mode': z.boolean().optional()\n .describe('Allow non-strict dependency resolution'),\n verbose: createCodeQLSchemas.verbose(),\n additionalArgs: createCodeQLSchemas.additionalArgs()\n },\n examples: [\n 'codeql pack install',\n 'codeql pack install --force /path/to/pack',\n 'codeql pack install --no-strict-mode'\n ]\n};", "/**\n * CodeQL pack ls tool\n */\n\nimport { z } from 'zod';\nimport { CLIToolDefinition, createCodeQLSchemas, defaultCLIResultProcessor } from '../../lib/cli-tool-registry';\n\nexport const codeqlPackLsTool: CLIToolDefinition = {\n name: 'codeql_pack_ls',\n description: 'List CodeQL packs under some local directory path',\n command: 'codeql',\n subcommand: 'pack ls',\n inputSchema: {\n dir: z.string().optional().describe('The root directory of the package or workspace, defaults to the current working directory'),\n format: z.enum(['text', 'json']).optional()\n .describe('Output format: text (default) or json'),\n groups: z.string().optional()\n .describe('List of CodeQL pack groups to include or exclude'),\n verbose: createCodeQLSchemas.verbose(),\n additionalArgs: createCodeQLSchemas.additionalArgs()\n },\n examples: [\n 'codeql pack ls -- .',\n 'codeql pack ls --format=json -- /path/to/pack-directory',\n 'codeql pack ls --format=json --groups=queries,tests -- .'\n ],\n resultProcessor: defaultCLIResultProcessor\n};", "/**\n * CodeQL query profiling tool\n */\n\nimport { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport { z } from 'zod';\nimport { executeCodeQLCommand } from '../../lib/cli-executor';\nimport { logger } from '../../utils/logger';\nimport { writeFileSync, readFileSync, existsSync } from 'fs';\nimport { join, dirname, basename } from 'path';\nimport { mkdirSync } from 'fs';\n\ninterface EvaluatorLogEvent {\n time: string;\n type: string;\n eventId: number;\n nanoTime: number;\n [key: string]: unknown;\n}\n\ninterface PipelineNode {\n eventId: number;\n name: string;\n position?: string;\n type?: string;\n startTime: number;\n endTime: number;\n duration: number;\n resultSize?: number;\n tupleCount?: number;\n dependencies: string[];\n dependencyEventIds: number[];\n}\n\ninterface ProfileData {\n queryName: string;\n totalDuration: number;\n totalEvents: number;\n pipelines: PipelineNode[];\n}\n\n/**\n * Parse evaluator log and create profile data\n */\nfunction parseEvaluatorLog(logPath: string): ProfileData {\n const logContent = readFileSync(logPath, 'utf-8');\n \n // Split by empty lines to get each JSON object (handles both JSONL and pretty-printed JSON)\n const jsonObjects = logContent.split('\\n\\n').filter((s) => s.trim());\n const events: EvaluatorLogEvent[] = jsonObjects\n .map((obj) => {\n try {\n return JSON.parse(obj);\n } catch (_error) {\n logger.warn(`Failed to parse evaluator log object: ${obj.substring(0, 100)}...`);\n return null;\n }\n })\n .filter((event): event is EvaluatorLogEvent => event !== null);\n\n // Map to track pipeline nodes by their start event ID\n const pipelineMap = new Map>();\n // Map to track dependency event IDs by predicate name\n const predicateNameToEventId = new Map();\n \n let queryName = '';\n let queryStartTime = 0;\n let queryEndTime = 0;\n\n for (const event of events) {\n switch (event.type) {\n case 'QUERY_STARTED':\n queryName = (event.queryName as string) || '';\n queryStartTime = event.nanoTime;\n break;\n\n case 'QUERY_COMPLETED':\n queryEndTime = event.nanoTime;\n break;\n\n case 'PREDICATE_STARTED': {\n const predicateName = event.predicateName as string;\n const position = event.position as string | undefined;\n const predicateType = event.predicateType as string | undefined;\n const dependencies = event.dependencies as Record | undefined;\n \n // Track this predicate's event ID by name for dependency resolution\n predicateNameToEventId.set(predicateName, event.eventId);\n \n // Get dependency event IDs\n const dependencyEventIds: number[] = [];\n const dependencyNames: string[] = [];\n if (dependencies) {\n for (const depName of Object.keys(dependencies)) {\n dependencyNames.push(depName);\n const depEventId = predicateNameToEventId.get(depName);\n if (depEventId !== undefined) {\n dependencyEventIds.push(depEventId);\n }\n }\n }\n\n pipelineMap.set(event.eventId, {\n eventId: event.eventId,\n name: predicateName,\n position,\n type: predicateType,\n startTime: event.nanoTime,\n dependencies: dependencyNames,\n dependencyEventIds,\n });\n break;\n }\n\n case 'PREDICATE_COMPLETED': {\n const startEventId = event.startEvent as number;\n const pipelineInfo = pipelineMap.get(startEventId);\n if (pipelineInfo) {\n const startEvent = events.find((e) => e.eventId === startEventId);\n if (startEvent) {\n const duration = (event.nanoTime - startEvent.nanoTime) / 1_000_000; // Convert to ms\n pipelineInfo.endTime = event.nanoTime;\n pipelineInfo.duration = duration;\n pipelineInfo.resultSize = event.resultSize as number | undefined;\n pipelineInfo.tupleCount = event.tupleCount as number | undefined;\n }\n }\n break;\n }\n }\n }\n\n // Convert to array and maintain original evaluation order (by eventId)\n const pipelines: PipelineNode[] = Array.from(pipelineMap.values())\n .filter((p): p is PipelineNode => p.duration !== undefined)\n .sort((a, b) => a.eventId - b.eventId);\n\n const totalDuration = queryEndTime > 0 ? (queryEndTime - queryStartTime) / 1_000_000 : 0;\n\n return {\n queryName,\n totalDuration,\n totalEvents: events.length,\n pipelines,\n };\n}\n\n/**\n * Format profile data as JSON\n */\nfunction formatAsJson(profile: ProfileData): string {\n return JSON.stringify(profile, null, 2);\n}\n\n/**\n * Format profile data as Mermaid diagram\n * Creates a graph showing the query evaluation pipelines in order of execution\n * with dependencies as edges, annotated with duration and result sizes\n */\nfunction formatAsMermaid(profile: ProfileData): string {\n const lines: string[] = [];\n\n lines.push('```mermaid');\n lines.push('graph TD');\n lines.push('');\n \n // Add query root node\n lines.push(` QUERY[\"${basename(profile.queryName)}
Total: ${profile.totalDuration.toFixed(2)}ms\"]`);\n lines.push('');\n \n // Create nodes for each pipeline in evaluation order (already sorted by eventId)\n profile.pipelines.forEach((pipeline) => {\n const nodeId = `P${pipeline.eventId}`;\n const duration = pipeline.duration.toFixed(2);\n const resultSize = pipeline.resultSize !== undefined ? pipeline.resultSize : '?';\n // Sanitize predicate name for Mermaid\n const name = pipeline.name.replace(/[<>]/g, '').substring(0, 40);\n lines.push(` ${nodeId}[\"${name}
${duration}ms | ${resultSize} results\"]`);\n });\n \n lines.push('');\n \n // Add edges from QUERY to root pipelines (those with no dependencies)\n const rootPipelines = profile.pipelines.filter((p) => p.dependencies.length === 0);\n \n rootPipelines.forEach((pipeline) => {\n lines.push(` QUERY --> P${pipeline.eventId}`);\n });\n \n lines.push('');\n \n // Add edges between pipelines based on dependencies (using eventIds to preserve links)\n profile.pipelines.forEach((pipeline) => {\n pipeline.dependencyEventIds.forEach((depEventId) => {\n const duration = pipeline.duration.toFixed(2);\n lines.push(` P${depEventId} -->|\"${duration}ms\"| P${pipeline.eventId}`);\n });\n });\n \n lines.push('');\n lines.push(' classDef default fill:#e1f5ff,stroke:#333,stroke-width:2px');\n lines.push(' classDef query fill:#ffe1e1,stroke:#333,stroke-width:3px');\n lines.push(' class QUERY query');\n lines.push('```');\n\n return lines.join('\\n');\n}\n\n/**\n * Register the profile_codeql_query tool\n */\nexport function registerProfileCodeQLQueryTool(server: McpServer): void {\n server.tool(\n 'profile_codeql_query',\n 'Profile the performance of a CodeQL query run against a specific database by analyzing the evaluator log JSON file',\n {\n query: z.string().describe('Path to the .ql query file'),\n database: z.string().describe('Path to the CodeQL database directory'),\n evaluatorLog: z\n .string()\n .optional()\n .describe(\n 'Path to an existing structured JSON log (e.g., evaluator-log.jsonl) file. If not provided, the tool will run the query to generate one.'\n ),\n outputDir: z\n .string()\n .optional()\n .describe('Directory to write profiling data files (defaults to same directory as evaluator log)'),\n },\n async (params) => {\n try {\n const { query, database, evaluatorLog, outputDir } = params;\n let logPath = evaluatorLog;\n let bqrsPath: string | undefined;\n let sarifPath: string | undefined;\n\n // If evaluator log not provided, run the query to generate one\n if (!logPath) {\n logger.info('No evaluator log provided, running query to generate one');\n\n // Determine output directory\n const defaultOutputDir = outputDir || join(dirname(query as string), 'profile-output');\n mkdirSync(defaultOutputDir, { recursive: true });\n\n logPath = join(defaultOutputDir, 'evaluator-log.jsonl');\n bqrsPath = join(defaultOutputDir, 'query-results.bqrs');\n sarifPath = join(defaultOutputDir, 'query-results.sarif');\n\n // Run query with evaluator logging and tuple counting\n const queryResult = await executeCodeQLCommand(\n 'query run',\n {\n database: database as string,\n output: bqrsPath,\n 'evaluator-log': logPath,\n 'tuple-counting': true,\n 'evaluator-log-level': 5,\n },\n [query as string]\n );\n\n if (!queryResult.success) {\n return {\n content: [\n {\n type: 'text' as const,\n text: `Failed to run query: ${queryResult.stderr || queryResult.error}`,\n },\n ],\n isError: true,\n };\n }\n\n // Generate SARIF interpretation\n if (existsSync(bqrsPath)) {\n try {\n const sarifResult = await executeCodeQLCommand(\n 'bqrs interpret',\n { format: 'sarif-latest', output: sarifPath },\n [bqrsPath]\n );\n\n if (sarifResult.success) {\n logger.info(`Generated SARIF interpretation at ${sarifPath}`);\n }\n } catch (error) {\n logger.warn(`Failed to generate SARIF interpretation: ${error}`);\n }\n }\n }\n\n // Verify evaluator log exists\n if (!existsSync(logPath)) {\n return {\n content: [\n {\n type: 'text' as const,\n text: `Evaluator log not found at: ${logPath}`,\n },\n ],\n isError: true,\n };\n }\n\n // Parse the evaluator log\n logger.info(`Parsing evaluator log from: ${logPath}`);\n const profile = parseEvaluatorLog(logPath);\n\n // Determine output directory for profile\n const profileOutputDir = outputDir || dirname(logPath);\n mkdirSync(profileOutputDir, { recursive: true });\n\n // Write profile JSON file\n const jsonPath = join(profileOutputDir, 'query-evaluation-profile.json');\n const jsonContent = formatAsJson(profile);\n writeFileSync(jsonPath, jsonContent);\n logger.info(`Profile JSON written to: ${jsonPath}`);\n\n // Write profile Mermaid diagram file\n const mdPath = join(profileOutputDir, 'query-evaluation-profile.md');\n const mdContent = formatAsMermaid(profile);\n writeFileSync(mdPath, mdContent);\n logger.info(`Profile Mermaid diagram written to: ${mdPath}`);\n\n // Build response message\n const outputFiles: string[] = [\n `Profile JSON: ${jsonPath}`,\n `Profile Mermaid: ${mdPath}`,\n `Evaluator Log: ${logPath}`,\n ];\n\n if (bqrsPath) {\n outputFiles.push(`Query Results (BQRS): ${bqrsPath}`);\n }\n\n if (sarifPath && existsSync(sarifPath)) {\n outputFiles.push(`Query Results (SARIF): ${sarifPath}`);\n }\n\n const responseText = [\n 'Query profiling completed successfully!',\n '',\n 'Output Files:',\n ...outputFiles.map((f) => ` - ${f}`),\n '',\n 'Profile Summary:',\n ` - Query: ${basename(profile.queryName)}`,\n ` - Total Duration: ${profile.totalDuration.toFixed(2)} ms`,\n ` - Total Pipelines: ${profile.pipelines.length}`,\n ` - Total Events: ${profile.totalEvents}`,\n '',\n 'First 5 Pipeline Nodes (in evaluation order):',\n ...profile.pipelines.slice(0, 5).map((p, idx) => {\n return ` ${idx + 1}. ${p.name} (${p.duration.toFixed(2)} ms, ${p.resultSize || '?'} results)`;\n }),\n ].join('\\n');\n\n return {\n content: [\n {\n type: 'text' as const,\n text: responseText,\n },\n ],\n };\n } catch (error) {\n logger.error('Error profiling CodeQL query:', error);\n\n return {\n content: [\n {\n type: 'text' as const,\n text: `Failed to profile query: ${error instanceof Error ? error.message : String(error)}`,\n },\n ],\n isError: true,\n };\n }\n }\n );\n}\n", "/**\n * CodeQL query compile tool\n */\n\nimport { z } from 'zod';\nimport { CLIToolDefinition } from '../../lib/cli-tool-registry';\n\nexport const codeqlQueryCompileTool: CLIToolDefinition = {\n name: 'codeql_query_compile',\n description: 'Compile and validate CodeQL queries',\n command: 'codeql',\n subcommand: 'query compile',\n inputSchema: {\n query: z.string().describe('Path to the CodeQL query file (.ql)'),\n database: z.string().optional().describe('Path to the CodeQL database'),\n library: z.string().optional().describe('Path to query library'),\n output: z.string().optional().describe('Output file path'),\n warnings: z.enum(['hide', 'show', 'error']).optional()\n .describe('How to handle compilation warnings'),\n verbose: z.boolean().optional().describe('Enable verbose output'),\n additionalArgs: z.array(z.string()).optional().describe('Additional command-line arguments')\n },\n examples: [\n 'codeql query compile --database=/path/to/db MyQuery.ql',\n 'codeql query compile --library=/path/to/lib --output=compiled.qlo MyQuery.ql'\n ]\n};", "/**\n * CodeQL query format tool\n */\n\nimport { z } from 'zod';\nimport { CLIToolDefinition, createCodeQLSchemas, defaultCLIResultProcessor, CLIExecutionResult } from '../../lib/cli-tool-registry';\n\n/**\n * Custom result processor for codeql query format tool\n * Exit code 1 with --check-only means \"file would change\" - this is success for format checking\n */\nfunction formatResultProcessor(result: CLIExecutionResult, params: Record): string {\n const isCheckOnly = params['check-only'];\n const hasFormatChanges = result.exitCode === 1;\n \n if (isCheckOnly && hasFormatChanges) {\n // Mark as success for the CLI tool registry since detecting format changes is the intended behavior\n result.success = true;\n return result.stdout || result.stderr || 'File would change by autoformatting.';\n }\n \n return defaultCLIResultProcessor(result, params);\n}\n\nexport const codeqlQueryFormatTool: CLIToolDefinition = {\n name: 'codeql_query_format',\n description: 'Automatically format CodeQL source code files',\n command: 'codeql',\n subcommand: 'query format',\n inputSchema: {\n files: z.array(z.string()).describe('One or more .ql or .qll source files to format'),\n output: z.string().optional().describe('Write formatted code to this file instead of stdout'),\n 'in-place': z.boolean().optional().describe('Overwrite each input file with formatted version'),\n 'check-only': z.boolean().optional().describe('Check formatting without writing output'),\n backup: z.string().optional().describe('Backup extension when overwriting existing files'),\n 'no-syntax-errors': z.boolean().optional().describe('Ignore syntax errors and pretend file is formatted'),\n verbose: createCodeQLSchemas.verbose(),\n additionalArgs: createCodeQLSchemas.additionalArgs()\n },\n examples: [\n 'codeql query format -i -- ExampleQuery.ql',\n 'codeql query format --in-place -- queries/*.ql',\n 'codeql query format --check-only -- queries/*.ql'\n ],\n resultProcessor: formatResultProcessor\n};", "/**\n * CodeQL query run tool\n */\n\nimport { z } from 'zod';\nimport { CLIToolDefinition, createCodeQLSchemas } from '../../lib/cli-tool-registry';\n\nexport const codeqlQueryRunTool: CLIToolDefinition = {\n name: 'codeql_query_run',\n description: 'Execute a CodeQL query against a database. Use either \"query\" parameter for direct file path OR \"queryName\" + \"queryLanguage\" for pre-defined tool queries.',\n command: 'codeql',\n subcommand: 'query run',\n inputSchema: {\n query: z.string().optional().describe('Path to the CodeQL query file (.ql) - cannot be used with queryName'),\n queryName: z.string().optional().describe('Name of pre-defined query to run (e.g., \"PrintAST\", \"CallGraphFrom\", \"CallGraphTo\") - requires queryLanguage'),\n queryLanguage: z.string().optional().describe('Programming language for tools queries (e.g., \"javascript\", \"java\", \"python\") - required when using queryName'),\n queryPack: z.string().optional().describe('Query pack path (defaults to server/ql//tools/src/ for tool queries)'),\n sourceFiles: z.string().optional().describe('Comma-separated list of source file paths for PrintAST queries (e.g., \"src/main.js,src/utils.js\" or just \"main.js\")'),\n sourceFunction: z.string().optional().describe('Comma-separated list of source function names for CallGraphFrom queries (e.g., \"main,processData\")'),\n targetFunction: z.string().optional().describe('Comma-separated list of target function names for CallGraphTo queries (e.g., \"helper,validateInput\")'),\n database: createCodeQLSchemas.database(),\n output: createCodeQLSchemas.output(),\n external: z.array(z.string()).optional()\n .describe('External predicate data: predicate=file.csv'),\n timeout: createCodeQLSchemas.timeout(),\n logDir: z.string().optional()\n .describe('Custom directory for query execution logs (overrides CODEQL_QUERY_LOG_DIR environment variable). If not provided, uses CODEQL_QUERY_LOG_DIR or defaults to .tmp/query-logs/'),\n 'evaluator-log': z.string().optional().describe('Path to save evaluator log (deprecated: use logDir instead)'),\n 'evaluator-log-minify': z.boolean().optional()\n .describe('Minimize evaluator log for smaller size'),\n 'evaluator-log-level': z.number().min(1).max(5).optional()\n .describe('Evaluator log verbosity level (1-5, default 5)'),\n 'tuple-counting': z.boolean().optional()\n .describe('Display tuple counts for each evaluation step in evaluator logs'),\n format: z.enum(['sarif-latest', 'sarifv2.1.0', 'csv', 'graphtext', 'dgml', 'dot']).optional()\n .describe('Output format for query results via codeql bqrs interpret. Defaults to sarif-latest for @kind problem/path-problem queries, graphtext for @kind graph queries. Graph formats (graphtext, dgml, dot) only work with @kind graph queries.'),\n interpretedOutput: z.string().optional()\n .describe('Output file for interpreted results (e.g., results.sarif, results.txt). If not provided, defaults based on format: .sarif for SARIF, .txt for graphtext/csv, .dgml for dgml, .dot for dot'),\n evaluationFunction: z.string().optional()\n .describe('[DEPRECATED - use format parameter instead] Built-in function for query results evaluation (e.g., \"mermaid-graph\", \"json-decode\", \"csv-decode\") or path to custom evaluation script'),\n evaluationOutput: z.string().optional()\n .describe('[DEPRECATED - use interpretedOutput parameter instead] Output file for evaluation results'),\n verbose: createCodeQLSchemas.verbose(),\n additionalArgs: createCodeQLSchemas.additionalArgs()\n },\n examples: [\n 'codeql query run --database=mydb --output=results.bqrs MyQuery.ql',\n 'codeql query run --database=mydb --query-name=PrintAST --query-language=javascript --source-files=src/index.js --output=results.bqrs --format=graphtext --interpreted-output=results.txt',\n 'codeql query run --database=mydb --external=data=input.csv --output=results.bqrs MyQuery.ql --format=sarif-latest --interpreted-output=results.sarif',\n 'codeql query run --database=mydb --evaluator-log=eval.log --tuple-counting --evaluator-log-level=5 --output=results.bqrs MyQuery.ql',\n 'codeql query run --database=mydb --query-name=PrintAST --query-language=javascript --source-files=\"main.js,utils.js\" --format=graphtext',\n 'codeql query run --database=mydb --log-dir=/custom/log/path --tuple-counting --output=results.bqrs MyQuery.ql'\n ]\n};", "/**\n * CodeQL quick evaluate tool\n * \n * Inspired by JordyZomer/codeql-mcp repository:\n * - https://github.com/JordyZomer/codeql-mcp/blob/main/server.py\n * - https://github.com/JordyZomer/codeql-mcp/blob/main/codeqlclient.py\n */\n\nimport { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport { z } from 'zod';\nimport { join, resolve } from 'path';\nimport { findClassPosition } from './find-class-position';\nimport { findPredicatePosition } from './find-predicate-position';\nimport { logger } from '../../utils/logger';\nimport { getProjectTmpDir } from '../../utils/temp-dir';\n\nexport interface QuickEvaluateParams {\n file: string;\n db: string;\n symbol: string;\n output_path?: string;\n}\n\n/**\n * Quick evaluate either a class or a predicate in a CodeQL query.\n * This allows debugging a select portion of QL code without running the whole query.\n */\nexport async function quickEvaluate({\n file,\n db: _db,\n symbol,\n output_path\n}: QuickEvaluateParams): Promise {\n try {\n // Try to find as a class first, then as a predicate\n try {\n await findClassPosition(file, symbol);\n } catch {\n try {\n await findPredicatePosition(file, symbol);\n } catch {\n throw new Error(`Symbol '${symbol}' not found as class or predicate in file: ${file}`);\n }\n }\n \n const resolvedOutput = resolve(output_path || join(getProjectTmpDir('quickeval'), 'quickeval.bqrs'));\n \n // For now, return the resolved output path\n // In a full implementation, this would use the CodeQL CLI or query server\n // to perform the actual quick evaluation with the position parameters\n return resolvedOutput;\n } catch (error) {\n throw new Error(`CodeQL evaluation failed: ${error instanceof Error ? error.message : 'Unknown error'}`);\n }\n}\n\n/**\n * Register the quick evaluate tool with the MCP server\n */\nexport function registerQuickEvaluateTool(server: McpServer): void {\n server.tool(\n 'quick_evaluate',\n 'Quick evaluate either a class or a predicate in a CodeQL query for debugging',\n {\n file: z.string().describe('Path to the .ql file containing the symbol'),\n db: z.string().describe('Path to the CodeQL database'),\n symbol: z.string().describe('Name of the class or predicate to evaluate'),\n output_path: z.string().optional().describe('Output path for results (defaults to project-local .tmp/quickeval/)'),\n },\n async ({ file, db, symbol, output_path }) => {\n try {\n const result = await quickEvaluate({ file, db, symbol, output_path });\n return {\n content: [{ type: 'text', text: result }],\n };\n } catch (error) {\n logger.error('Error in quick evaluate:', error);\n return {\n content: [\n {\n type: 'text',\n text: `Error: ${error instanceof Error ? error.message : 'Unknown error'}`,\n },\n ],\n isError: true,\n };\n }\n }\n );\n}", "/**\n * CodeQL register database tool\n * \n * Inspired by JordyZomer/codeql-mcp repository:\n * - https://github.com/JordyZomer/codeql-mcp/blob/main/server.py\n * - https://github.com/JordyZomer/codeql-mcp/blob/main/codeqlclient.py\n */\n\nimport { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport { z } from 'zod';\nimport { access, constants } from 'fs/promises';\nimport { resolve } from 'path';\nimport { logger } from '../../utils/logger';\n\nexport interface DatabaseRegistration {\n uri: string;\n content: {\n sourceArchiveZip: string;\n dbDir: string;\n };\n}\n\n/**\n * Register a CodeQL database given a local path to the database directory.\n * Validates that the database exists and has required structure.\n * Supports both full databases (with src.zip) and test databases (with src/ folder).\n */\nexport async function registerDatabase(dbPath: string): Promise {\n try {\n const resolvedPath = resolve(dbPath);\n \n // Check if database directory exists\n await access(resolvedPath, constants.F_OK);\n \n // Check for codeql-database.yml (required for all CodeQL databases)\n const dbYmlPath = resolve(resolvedPath, 'codeql-database.yml');\n await access(dbYmlPath, constants.F_OK);\n \n // Check if src.zip exists (for full databases) OR src/ directory exists (for test databases)\n const srcZipPath = resolve(resolvedPath, 'src.zip');\n const srcDirPath = resolve(resolvedPath, 'src');\n \n let hasSrcZip = false;\n let hasSrcDir = false;\n \n try {\n await access(srcZipPath, constants.F_OK);\n hasSrcZip = true;\n } catch {\n // src.zip not found, check for src/ directory\n }\n \n if (!hasSrcZip) {\n try {\n await access(srcDirPath, constants.F_OK);\n hasSrcDir = true;\n } catch {\n // src directory not found either\n }\n }\n \n if (!hasSrcZip && !hasSrcDir) {\n throw new Error(`Missing required source archive (src.zip) or source directory (src/) in: ${dbPath}`);\n }\n \n // For now, we just validate and return success message\n // In a full implementation, this would register with a query server\n const sourceType = hasSrcZip ? 'src.zip' : 'src/';\n return `Database registered: ${dbPath} (source: ${sourceType})`;\n } catch (error) {\n if (error instanceof Error) {\n const errorCode = (error as { code?: string }).code;\n if (errorCode === 'ENOENT') {\n if (error.message.includes('codeql-database.yml')) {\n throw new Error(`Missing required codeql-database.yml in: ${dbPath}`);\n }\n throw new Error(`Database path does not exist: ${dbPath}`);\n }\n if (errorCode === 'EACCES') {\n throw new Error(`Database path does not exist: ${dbPath}`);\n }\n }\n throw new Error(`Failed to register database: ${error instanceof Error ? error.message : 'Unknown error'}`);\n }\n}\n\n/**\n * Register the register database tool with the MCP server\n */\nexport function registerRegisterDatabaseTool(server: McpServer): void {\n server.tool(\n 'register_database',\n 'Register a CodeQL database given a local path to the database directory',\n {\n db_path: z.string().describe('Path to the CodeQL database directory'),\n },\n async ({ db_path }) => {\n try {\n const result = await registerDatabase(db_path);\n return {\n content: [{ type: 'text', text: result }],\n };\n } catch (error) {\n logger.error('Error registering database:', error);\n return {\n content: [\n {\n type: 'text',\n text: `Error: ${error instanceof Error ? error.message : 'Unknown error'}`,\n },\n ],\n isError: true,\n };\n }\n }\n );\n}", "/**\n * CodeQL resolve database tool\n */\n\nimport { z } from 'zod';\nimport { CLIToolDefinition, createCodeQLSchemas, defaultCLIResultProcessor } from '../../lib/cli-tool-registry';\n\nexport const codeqlResolveDatabaseTool: CLIToolDefinition = {\n name: 'codeql_resolve_database',\n description: 'Resolve database path and validate database structure',\n command: 'codeql',\n subcommand: 'resolve database',\n inputSchema: {\n database: z.string().describe('Database path to resolve'),\n format: z.enum(['text', 'json', 'betterjson']).optional()\n .describe('Output format for database information'),\n verbose: createCodeQLSchemas.verbose(),\n additionalArgs: createCodeQLSchemas.additionalArgs()\n },\n examples: [\n 'codeql resolve database -- /path/to/database',\n 'codeql resolve database --format=json -- my-database',\n 'codeql resolve database --format=betterjson -- database-dir'\n ],\n resultProcessor: defaultCLIResultProcessor\n};", "/**\n * CodeQL resolve languages tool\n */\n\nimport { z } from 'zod';\nimport { CLIToolDefinition, defaultCLIResultProcessor } from '../../lib/cli-tool-registry';\n\nexport const codeqlResolveLanguagesTool: CLIToolDefinition = {\n name: 'codeql_resolve_languages',\n description: 'List installed CodeQL extractor packs',\n command: 'codeql',\n subcommand: 'resolve languages',\n inputSchema: {\n format: z.enum(['text', 'json', 'betterjson']).optional()\n .describe('Output format for language information'),\n verbose: z.boolean().optional().describe('Enable verbose output'),\n additionalArgs: z.array(z.string()).optional().describe('Additional command-line arguments')\n },\n examples: [\n 'codeql resolve languages --format=text',\n 'codeql resolve languages --format=json',\n 'codeql resolve languages --format=betterjson'\n ],\n resultProcessor: defaultCLIResultProcessor\n};", "/**\n * CodeQL resolve library-path tool\n */\n\nimport { z } from 'zod';\nimport { CLIToolDefinition, defaultCLIResultProcessor } from '../../lib/cli-tool-registry';\n\nexport const codeqlResolveLibraryPathTool: CLIToolDefinition = {\n name: 'codeql_resolve_library-path',\n description: 'Resolve library path for CodeQL queries and libraries',\n command: 'codeql',\n subcommand: 'resolve library-path',\n inputSchema: {\n language: z.string().optional().describe('Programming language to resolve library path for'),\n format: z.enum(['text', 'json', 'betterjson']).optional()\n .describe('Output format for library path information'),\n verbose: z.boolean().optional().describe('Enable verbose output'),\n additionalArgs: z.array(z.string()).optional().describe('Additional command-line arguments')\n },\n examples: [\n 'codeql resolve library-path --language=java',\n 'codeql resolve library-path --format=json --language=python',\n 'codeql resolve library-path --format=betterjson'\n ],\n resultProcessor: defaultCLIResultProcessor\n};", "/**\n * CodeQL resolve metadata tool\n */\n\nimport { z } from 'zod';\nimport { CLIToolDefinition, defaultCLIResultProcessor } from '../../lib/cli-tool-registry';\n\nexport const codeqlResolveMetadataTool: CLIToolDefinition = {\n name: 'codeql_resolve_metadata',\n description: 'Resolve and return the key-value metadata pairs from a CodeQL query source file.',\n command: 'codeql',\n subcommand: 'resolve metadata',\n inputSchema: {\n query: z.string().describe('Query file to resolve metadata for'),\n format: z.enum(['json']).optional()\n .describe('Output format for metadata information (always JSON, optional for future compatibility)'),\n verbose: z.boolean().optional().describe('Enable verbose output'),\n additionalArgs: z.array(z.string()).optional().describe('Additional command-line arguments')\n },\n examples: [\n 'codeql resolve metadata -- relative-path/2/MyQuery.ql',\n 'codeql resolve metadata --format=json -- /absolute-plus/relative-path/2/MyQuery.ql'\n ],\n resultProcessor: defaultCLIResultProcessor\n};", "/**\n * CodeQL resolve qlref tool\n */\n\nimport { z } from 'zod';\nimport { CLIToolDefinition, createCodeQLSchemas, defaultCLIResultProcessor } from '../../lib/cli-tool-registry';\n\nexport const codeqlResolveQlrefTool: CLIToolDefinition = {\n name: 'codeql_resolve_qlref',\n description: 'Resolve qlref files to their corresponding query files',\n command: 'codeql',\n subcommand: 'resolve qlref',\n inputSchema: {\n qlref: z.string().describe('Path to the .qlref file to resolve'),\n format: z.enum(['text', 'json', 'betterjson']).optional()\n .describe('Output format for qlref resolution'),\n verbose: createCodeQLSchemas.verbose(),\n additionalArgs: createCodeQLSchemas.additionalArgs()\n },\n examples: [\n 'codeql resolve qlref -- test/MyQuery.qlref',\n 'codeql resolve qlref --format=json -- test/MyQuery.qlref',\n 'codeql resolve qlref --format=betterjson -- test/MyQuery.qlref'\n ],\n resultProcessor: defaultCLIResultProcessor\n};", "/**\n * CodeQL resolve queries tool\n */\n\nimport { z } from 'zod';\nimport { CLIToolDefinition, createCodeQLSchemas, CLIExecutionResult } from '../../lib/cli-tool-registry';\n\n/**\n * Result processor that only returns stdout for JSON formats\n * This prevents warnings/info from stderr from corrupting JSON output\n */\nconst jsonOnlyResultProcessor = (\n result: CLIExecutionResult,\n params: Record\n): string => {\n if (!result.success) {\n return `Command failed (exit code ${result.exitCode || 'unknown'}):\\n${result.error || result.stderr}`;\n }\n\n // For JSON formats (including bylanguage), only return stdout to avoid mixing warnings with JSON\n if (params.format === 'json' || params.format === 'betterjson' || params.format === 'bylanguage') {\n return result.stdout || '[]';\n }\n\n // For text format, include warnings\n let output = '';\n\n if (result.stdout) {\n output += result.stdout;\n }\n\n if (result.stderr) {\n if (output) {\n output += '\\n\\nWarnings/Info:\\n';\n }\n output += result.stderr;\n }\n\n if (!output) {\n output = 'Command executed successfully (no output)';\n }\n\n return output;\n};\n\nexport const codeqlResolveQueriesTool: CLIToolDefinition = {\n name: 'codeql_resolve_queries',\n description: 'List available CodeQL queries found on the local filesystem',\n command: 'codeql',\n subcommand: 'resolve queries',\n inputSchema: {\n directory: z.string().optional().describe('Directory to search for queries'),\n language: z.string().optional().describe('Filter queries by programming language'),\n format: z.enum(['text', 'json', 'betterjson', 'bylanguage']).optional()\n .describe('Output format for query list'),\n 'additional-packs': z.union([z.string(), z.array(z.string())]).optional()\n .describe('Additional pack directories to search for CodeQL packs'),\n verbose: createCodeQLSchemas.verbose(),\n additionalArgs: createCodeQLSchemas.additionalArgs()\n },\n examples: [\n 'codeql resolve queries',\n 'codeql resolve queries --language=java --format=json',\n 'codeql resolve queries --format=betterjson -- /path/to/queries',\n 'codeql resolve queries --additional-packs=/path/to/packs codeql/java-queries'\n ],\n resultProcessor: jsonOnlyResultProcessor\n};", "/**\n * CodeQL resolve tests tool\n */\n\nimport { z } from 'zod';\nimport { CLIToolDefinition, createCodeQLSchemas, defaultCLIResultProcessor } from '../../lib/cli-tool-registry';\n\nexport const codeqlResolveTestsTool: CLIToolDefinition = {\n name: 'codeql_resolve_tests',\n description: 'Resolve the local filesystem paths of unit tests and/or queries under some base directory',\n command: 'codeql',\n subcommand: 'resolve tests',\n inputSchema: {\n tests: z.array(z.string()).optional().describe('One or more tests (.ql, .qlref files, or test directories)'),\n format: z.enum(['text', 'json']).optional()\n .describe('Output format for test list'),\n verbose: createCodeQLSchemas.verbose(),\n additionalArgs: createCodeQLSchemas.additionalArgs()\n },\n examples: [\n 'codeql resolve tests',\n 'codeql resolve tests --format=json -- test-directory',\n 'codeql resolve tests --format=json -- test1.ql test2.ql'\n ],\n resultProcessor: defaultCLIResultProcessor\n};", "/**\n * CodeQL test accept tool\n */\n\nimport { z } from 'zod';\nimport { CLIToolDefinition, createCodeQLSchemas, defaultCLIResultProcessor } from '../../lib/cli-tool-registry';\n\nexport const codeqlTestAcceptTool: CLIToolDefinition = {\n name: 'codeql_test_accept',\n description: 'Accept new test results as the expected baseline',\n command: 'codeql',\n subcommand: 'test accept',\n inputSchema: {\n tests: z.array(z.string()).describe('One or more tests (.ql, .qlref files, or test directories)'),\n verbose: createCodeQLSchemas.verbose(),\n additionalArgs: createCodeQLSchemas.additionalArgs()\n },\n examples: [\n 'codeql test accept -- languages/java/test/MyQuery/MyQuery.qlref',\n 'codeql test accept -- languages/java/test/MyQuery/',\n 'codeql test accept -- languages/java/src/MyQuery/MyQuery.ql'\n ],\n resultProcessor: defaultCLIResultProcessor\n};", "/**\n * CodeQL test extract tool\n */\n\nimport { z } from 'zod';\nimport { CLIToolDefinition, createCodeQLSchemas, defaultCLIResultProcessor } from '../../lib/cli-tool-registry';\n\nexport const codeqlTestExtractTool: CLIToolDefinition = {\n name: 'codeql_test_extract',\n description: 'Extract test databases for CodeQL query tests',\n command: 'codeql',\n subcommand: 'test extract',\n inputSchema: {\n tests: z.array(z.string()).describe('One or more test directories or files'),\n language: z.string().optional().describe('Programming language for extraction'),\n threads: createCodeQLSchemas.threads(),\n ram: createCodeQLSchemas.ram(),\n verbose: createCodeQLSchemas.verbose(),\n additionalArgs: createCodeQLSchemas.additionalArgs()\n },\n examples: [\n 'codeql test extract -- languages/java/test/MyQuery/',\n 'codeql test extract --language=java --threads=4 -- test-directory',\n 'codeql test extract --threads=2 --ram=2048 -- multiple/test/directories'\n ],\n resultProcessor: defaultCLIResultProcessor\n};", "/**\n * CodeQL test run tool\n */\n\nimport { CLIToolDefinition, createCodeQLSchemas } from '../../lib/cli-tool-registry';\nimport { z } from 'zod';\n\nexport const codeqlTestRunTool: CLIToolDefinition = {\n name: 'codeql_test_run',\n description: 'Run CodeQL query tests',\n command: 'codeql',\n subcommand: 'test run',\n inputSchema: {\n tests: z.array(z.string()).describe('One or more tests (.ql, .qlref files, or test directories)'),\n 'show-extractor-output': z.boolean().optional()\n .describe('Show output from extractors during test execution'),\n 'keep-databases': z.boolean().optional()\n .describe('Keep test databases after running tests'),\n 'learn': z.boolean().optional()\n .describe('Accept current output as expected for failing tests'),\n logDir: z.string().optional()\n .describe('Custom directory for test execution logs (overrides CODEQL_QUERY_LOG_DIR environment variable). If not provided, uses CODEQL_QUERY_LOG_DIR or defaults to .tmp/query-logs/'),\n threads: createCodeQLSchemas.threads(),\n ram: createCodeQLSchemas.ram(),\n verbose: createCodeQLSchemas.verbose(),\n additionalArgs: createCodeQLSchemas.additionalArgs()\n },\n examples: [\n 'codeql test run /path/to/tests',\n 'codeql test run --learn /path/to/failing/tests',\n 'codeql test run --threads=4 --keep-databases /path/to/tests',\n 'codeql test run --log-dir=/custom/log/path /path/to/tests'\n ]\n};", "/**\n * CodeQL tools registration for MCP server\n * Includes both high-level helpers and CLI command wrappers\n */\n\nimport { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport { z } from 'zod';\nimport { validateCodeQLSyntax } from '../lib/validation';\nimport { createCodeQLQuery } from '../lib/query-scaffolding';\nimport { registerCLITool } from '../lib/cli-tool-registry';\nimport {\n codeqlBqrsDecodeTool,\n codeqlBqrsInfoTool,\n codeqlBqrsInterpretTool,\n codeqlDatabaseAnalyzeTool,\n codeqlDatabaseCreateTool,\n codeqlGenerateLogSummaryTool,\n codeqlGenerateQueryHelpTool,\n codeqlPackInstallTool,\n codeqlPackLsTool,\n codeqlQueryCompileTool,\n codeqlQueryFormatTool,\n codeqlQueryRunTool,\n codeqlResolveDatabaseTool,\n codeqlResolveLanguagesTool,\n codeqlResolveLibraryPathTool,\n codeqlResolveMetadataTool,\n codeqlResolveQlrefTool,\n codeqlResolveQueriesTool,\n codeqlResolveTestsTool,\n codeqlTestAcceptTool,\n codeqlTestExtractTool,\n codeqlTestRunTool,\n registerFindClassPositionTool,\n registerFindCodeQLQueryFilesTool,\n registerFindPredicatePositionTool,\n registerProfileCodeQLQueryTool,\n registerQuickEvaluateTool,\n registerRegisterDatabaseTool\n} from './codeql';\nimport { logger } from '../utils/logger';\n\n/**\n * Register all CodeQL tools with the MCP server\n */\nexport function registerCodeQLTools(server: McpServer): void {\n // Register high-level helper tools\n \n // Tool: Validate CodeQL Query (heuristic-based)\n server.tool(\n 'validate_codeql_query',\n 'Quick heuristic validation for CodeQL query structure - checks for common patterns like from/where/select clauses and metadata presence. Does NOT compile the query. For authoritative validation with actual compilation, use codeql_lsp_diagnostics instead.',\n {\n query: z.string().describe('The CodeQL query to validate'),\n language: z.string().optional().describe('Target programming language'),\n },\n async ({ query, language }) => {\n try {\n const validation = validateCodeQLSyntax(query, language);\n return {\n content: [{ type: 'text', text: JSON.stringify(validation, null, 2) }],\n };\n } catch (error) {\n logger.error('Error validating CodeQL query:', error);\n return {\n content: [\n {\n type: 'text',\n text: `Error: ${error instanceof Error ? error.message : 'Unknown error'}`,\n },\n ],\n isError: true,\n };\n }\n }\n );\n\n // Tool: Create CodeQL Query\n server.tool(\n 'create_codeql_query',\n 'Create directory structure and files for a new CodeQL query with tests',\n {\n basePath: z.string().describe('Base path where src/ and test/ directories will be created'),\n queryName: z.string().describe('Name of the query (e.g., MySecurityQuery)'),\n language: z.string().describe('Target programming language (e.g., javascript, python, java)'),\n description: z.string().optional().describe('Description of what the query does'),\n queryId: z.string().optional().describe('Custom query ID (defaults to language/example/queryname)'),\n },\n async ({ basePath, queryName, language, description, queryId }) => {\n try {\n const result = createCodeQLQuery({\n basePath,\n queryName,\n language,\n description,\n queryId\n });\n \n const summary = {\n success: true,\n queryPath: result.queryPath,\n testPath: result.testPath,\n qlrefPath: result.qlrefPath,\n testCodePath: result.testCodePath,\n filesCreated: result.filesCreated,\n nextSteps: [\n 'Review and customize the generated query in: ' + result.queryPath,\n 'Add test cases to: ' + result.testCodePath,\n 'Run codeql_pack_install to install dependencies',\n 'Run codeql_test_extract to create test database',\n 'Run codeql_test_run to execute tests'\n ]\n };\n \n return {\n content: [{ type: 'text', text: JSON.stringify(summary, null, 2) }],\n };\n } catch (error) {\n logger.error('Error creating CodeQL query:', error);\n return {\n content: [\n {\n type: 'text',\n text: `Error: ${error instanceof Error ? error.message : 'Unknown error'}`,\n },\n ],\n isError: true,\n };\n }\n }\n );\n\n // Register CLI tools (alphabetically by tool name)\n registerCLITool(server, codeqlBqrsDecodeTool);\n registerCLITool(server, codeqlBqrsInfoTool);\n registerCLITool(server, codeqlBqrsInterpretTool);\n registerCLITool(server, codeqlDatabaseAnalyzeTool);\n registerCLITool(server, codeqlDatabaseCreateTool);\n registerCLITool(server, codeqlGenerateLogSummaryTool);\n registerCLITool(server, codeqlGenerateQueryHelpTool);\n registerCLITool(server, codeqlPackInstallTool);\n registerCLITool(server, codeqlPackLsTool);\n registerCLITool(server, codeqlQueryCompileTool);\n registerCLITool(server, codeqlQueryFormatTool);\n registerCLITool(server, codeqlQueryRunTool);\n registerCLITool(server, codeqlResolveDatabaseTool);\n registerCLITool(server, codeqlResolveLanguagesTool);\n registerCLITool(server, codeqlResolveLibraryPathTool);\n registerCLITool(server, codeqlResolveMetadataTool);\n registerCLITool(server, codeqlResolveQlrefTool);\n registerCLITool(server, codeqlResolveQueriesTool);\n registerCLITool(server, codeqlResolveTestsTool);\n registerCLITool(server, codeqlTestAcceptTool);\n registerCLITool(server, codeqlTestExtractTool);\n registerCLITool(server, codeqlTestRunTool);\n\n // Register new MCP tools (inspired by JordyZomer/codeql-mcp repository)\n registerFindClassPositionTool(server);\n registerFindCodeQLQueryFilesTool(server);\n registerFindPredicatePositionTool(server);\n registerProfileCodeQLQueryTool(server);\n registerQuickEvaluateTool(server);\n registerRegisterDatabaseTool(server);\n}\n", "/**\n * CodeQL query validation utilities\n */\n\nimport { resolve, normalize, isAbsolute, relative } from 'path';\n\nexport interface CodeQLValidationResult {\n isValid: boolean;\n errors: string[];\n warnings: string[];\n suggestions: string[];\n}\n\n/**\n * Validates CodeQL query syntax and structure\n */\nexport function validateCodeQLSyntax(query: string, _language?: string): CodeQLValidationResult {\n const validation: CodeQLValidationResult = {\n isValid: true,\n errors: [],\n warnings: [],\n suggestions: [],\n };\n\n if (!query.trim()) {\n validation.isValid = false;\n validation.errors.push('Query cannot be empty');\n return validation;\n }\n\n if (!query.includes('from') && !query.includes('select')) {\n validation.warnings.push('Query should typically include \"from\" and \"select\" clauses');\n }\n\n if (!query.includes('@name') && !query.includes('@description')) {\n validation.suggestions.push('Consider adding @name and @description metadata');\n }\n\n return validation;\n}\n\n/**\n * Validates a file path to prevent path traversal attacks\n * @param filePath - The file path to validate\n * @param workspaceRoot - Optional workspace root directory. If not provided, allows any absolute path but still blocks traversal attempts\n * @returns The validated absolute path\n * @throws Error if the path contains path traversal sequences\n */\nexport function validateFilePath(filePath: string, workspaceRoot?: string): string {\n // Normalize the path to resolve any . or .. segments\n const normalizedPath = normalize(filePath);\n \n // Check for path traversal attempts in the normalized path\n // This blocks paths like \"../../../etc/passwd\" even after normalization\n if (normalizedPath.includes('..')) {\n throw new Error(`Invalid file path: path traversal detected in \"${filePath}\"`);\n }\n \n // Resolve to absolute path\n const absolutePath = isAbsolute(normalizedPath) \n ? normalizedPath \n : resolve(workspaceRoot || process.cwd(), normalizedPath);\n \n // If workspace root is specified, ensure the resolved path is within it\n if (workspaceRoot) {\n const relativePath = relative(workspaceRoot, absolutePath);\n \n // If relative path starts with .. or is absolute, it's outside workspace\n if (relativePath.startsWith('..') || isAbsolute(relativePath)) {\n throw new Error(`Invalid file path: \"${filePath}\" is outside the workspace root`);\n }\n }\n \n return absolutePath;\n}", "/**\n * CodeQL query scaffolding utilities\n * Handles creation of query directory structure and files\n */\n\nimport * as fs from 'fs';\nimport * as path from 'path';\n\nexport interface QueryScaffoldingOptions {\n basePath: string;\n queryName: string;\n language: string;\n description?: string;\n queryId?: string;\n}\n\nexport interface QueryScaffoldingResult {\n queryPath: string;\n testPath: string;\n qlrefPath: string;\n testCodePath: string;\n filesCreated: string[];\n}\n\n/**\n * Get the file extension for test code based on language\n */\nfunction getLanguageExtension(language: string): string {\n const extensions: Record = {\n javascript: 'js',\n typescript: 'ts',\n python: 'py',\n java: 'java',\n csharp: 'cs',\n cpp: 'cpp',\n go: 'go',\n ruby: 'rb',\n actions: 'yml'\n };\n return extensions[language.toLowerCase()] || 'txt';\n}\n\n/**\n * Generate query template content\n */\nfunction generateQueryTemplate(\n queryName: string,\n language: string,\n description?: string,\n queryId?: string\n): string {\n const desc = description || `${queryName} query`;\n const id = queryId || `${language}/example/${queryName.toLowerCase()}`;\n \n return `/**\n * @id ${id}\n * @name ${queryName}\n * @description ${desc}\n * @kind problem\n * @precision medium\n * @problem.severity warning\n */\n\nimport ${language}\n\n// TODO: Implement query logic\nfrom File f\nwhere f.getBaseName() = \"${queryName}.${getLanguageExtension(language)}\"\nselect f, \"TODO: Add query logic\"\n`;\n}\n\n/**\n * Create the directory structure and files for a new CodeQL query\n */\nexport function createCodeQLQuery(options: QueryScaffoldingOptions): QueryScaffoldingResult {\n const { basePath, queryName, language, description, queryId } = options;\n \n // Resolve absolute paths\n const absoluteBasePath = path.resolve(basePath);\n \n // Define paths with intermediate directory\n const srcDir = path.join(absoluteBasePath, 'src', queryName);\n const testDir = path.join(absoluteBasePath, 'test', queryName);\n \n const queryPath = path.join(srcDir, `${queryName}.ql`);\n const qlrefPath = path.join(testDir, `${queryName}.qlref`);\n const testCodePath = path.join(testDir, `${queryName}.${getLanguageExtension(language)}`);\n \n const filesCreated: string[] = [];\n \n try {\n // Create directories (recursive: true is a no-op if they already exist)\n fs.mkdirSync(srcDir, { recursive: true });\n fs.mkdirSync(testDir, { recursive: true });\n \n // Create files atomically using 'wx' flag (exclusive create) to avoid\n // TOCTOU race between existsSync check and writeFileSync (CWE-367).\n // The 'wx' flag fails with EEXIST if the file already exists.\n try {\n const queryContent = generateQueryTemplate(queryName, language, description, queryId);\n fs.writeFileSync(queryPath, queryContent, { encoding: 'utf8', flag: 'wx' });\n filesCreated.push(queryPath);\n } catch (e: unknown) {\n const err = e as { code?: string };\n if (err.code !== 'EEXIST') throw e;\n }\n \n try {\n const qlrefContent = `${queryName}/${queryName}.ql\\n`;\n fs.writeFileSync(qlrefPath, qlrefContent, { encoding: 'utf8', flag: 'wx' });\n filesCreated.push(qlrefPath);\n } catch (e: unknown) {\n const err = e as { code?: string };\n if (err.code !== 'EEXIST') throw e;\n }\n \n try {\n const testCodeContent = `// Test code for ${queryName}\\n// TODO: Add test cases\\n`;\n fs.writeFileSync(testCodePath, testCodeContent, { encoding: 'utf8', flag: 'wx' });\n filesCreated.push(testCodePath);\n } catch (e: unknown) {\n const err = e as { code?: string };\n if (err.code !== 'EEXIST') throw e;\n }\n \n return {\n queryPath,\n testPath: testDir,\n qlrefPath,\n testCodePath,\n filesCreated\n };\n } catch (error) {\n throw new Error(`Failed to create query scaffolding: ${error instanceof Error ? error.message : 'Unknown error'}`);\n }\n}\n", "/**\n * CodeQL learning resources utilities\n */\n\nimport { readFileSync } from 'fs';\nimport { join, dirname } from 'path';\nimport { fileURLToPath } from 'url';\n\nconst __filename = fileURLToPath(import.meta.url);\nconst __dirname = dirname(__filename);\n\n/**\n * Get the getting started guide content\n */\nexport function getGettingStartedGuide(): string {\n try {\n return readFileSync(join(__dirname, '../resources/getting-started.md'), 'utf-8');\n } catch {\n return 'Getting started guide not available';\n }\n}\n\n/**\n * Get the query basics guide content\n */\nexport function getQueryBasicsGuide(): string {\n try {\n return readFileSync(join(__dirname, '../resources/query-basics.md'), 'utf-8');\n } catch {\n return 'Query basics guide not available';\n }\n}\n\n/**\n * Get the security templates content\n */\nexport function getSecurityTemplates(): string {\n try {\n return readFileSync(join(__dirname, '../resources/security-templates.md'), 'utf-8');\n } catch {\n return 'Security templates not available';\n }\n}\n\n/**\n * Get the performance patterns content\n */\nexport function getPerformancePatterns(): string {\n try {\n return readFileSync(join(__dirname, '../resources/performance-patterns.md'), 'utf-8');\n } catch {\n return 'Performance patterns not available';\n }\n}", "/**\n * CodeQL resources registration for MCP server\n */\n\nimport { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport {\n getGettingStartedGuide,\n getQueryBasicsGuide,\n getSecurityTemplates,\n getPerformancePatterns,\n} from '../lib/resources';\n\n/**\n * Register all CodeQL resources with the MCP server\n */\nexport function registerCodeQLResources(server: McpServer): void {\n // Getting Started Guide\n server.resource(\n 'CodeQL Getting Started',\n 'codeql://learning/getting-started',\n {\n description: 'Comprehensive introduction to CodeQL for beginners',\n mimeType: 'text/markdown',\n },\n async () => {\n return {\n contents: [\n {\n uri: 'codeql://learning/getting-started',\n mimeType: 'text/markdown',\n text: getGettingStartedGuide(),\n },\n ],\n };\n }\n );\n\n // Query Basics Guide\n server.resource(\n 'CodeQL Query Basics',\n 'codeql://learning/query-basics',\n {\n description: 'Learn the fundamentals of writing CodeQL queries',\n mimeType: 'text/markdown',\n },\n async () => {\n return {\n contents: [\n {\n uri: 'codeql://learning/query-basics',\n mimeType: 'text/markdown',\n text: getQueryBasicsGuide(),\n },\n ],\n };\n }\n );\n\n // Security Templates\n server.resource(\n 'CodeQL Security Templates',\n 'codeql://templates/security',\n {\n description: 'Ready-to-use security query templates',\n mimeType: 'text/markdown',\n },\n async () => {\n return {\n contents: [\n {\n uri: 'codeql://templates/security',\n mimeType: 'text/markdown',\n text: getSecurityTemplates(),\n },\n ],\n };\n }\n );\n\n // Performance Patterns\n server.resource(\n 'CodeQL Performance Patterns',\n 'codeql://patterns/performance',\n {\n description: 'Best practices for writing efficient CodeQL queries',\n mimeType: 'text/markdown',\n },\n async () => {\n return {\n contents: [\n {\n uri: 'codeql://patterns/performance',\n mimeType: 'text/markdown',\n text: getPerformancePatterns(),\n },\n ],\n };\n }\n );\n}\n", "/**\n * CodeQL LSP Diagnostics tool for MCP server.\n *\n * Provides real-time QL code validation through LSP communication.\n * Renamed from `codeql_language_server_eval` to `codeql_lsp_diagnostics`\n * for consistency with the `codeql_lsp_*` tool naming convention.\n */\n\nimport { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport { z } from 'zod';\nimport { Diagnostic, LanguageServerOptions } from '../../lib/language-server';\nimport { logger } from '../../utils/logger';\nimport { getProjectTmpDir } from '../../utils/temp-dir';\nimport { join } from 'path';\nimport { pathToFileURL } from 'url';\nimport { getInitializedLanguageServer } from './lsp-server-helper';\n\nexport interface LspDiagnosticsParams {\n qlCode: string;\n serverOptions?: LanguageServerOptions;\n workspaceUri?: string;\n}\n\nexport interface LspDiagnosticsResult {\n diagnostics: Diagnostic[];\n formattedOutput: string;\n isValid: boolean;\n summary: {\n errorCount: number;\n hintCount: number;\n infoCount: number;\n warningCount: number;\n };\n}\n\n/**\n * Format diagnostics for human-readable output.\n */\nfunction formatDiagnostics(diagnostics: Diagnostic[]): string {\n if (diagnostics.length === 0) {\n return '\u2705 No issues found in QL code';\n }\n\n const lines: string[] = [];\n lines.push(`Found ${diagnostics.length} issue(s):\\n`);\n\n diagnostics.forEach((diagnostic, index) => {\n const severityIcon = getSeverityIcon(diagnostic.severity);\n const severityName = getSeverityName(diagnostic.severity);\n const location = `Line ${diagnostic.range.start.line + 1}, Column ${diagnostic.range.start.character + 1}`;\n\n lines.push(`${index + 1}. ${severityIcon} ${severityName} at ${location}`);\n lines.push(` ${diagnostic.message}`);\n if (diagnostic.source) {\n lines.push(` Source: ${diagnostic.source}`);\n }\n if (diagnostic.code) {\n lines.push(` Code: ${diagnostic.code}`);\n }\n lines.push('');\n });\n\n return lines.join('\\n');\n}\n\nfunction getSeverityIcon(severity: number): string {\n switch (severity) {\n case 1: return '\u274C'; // Error\n case 2: return '\u26A0\uFE0F'; // Warning\n case 3: return '\u2139\uFE0F'; // Information\n case 4: return '\uD83D\uDCA1'; // Hint\n default: return '\u2753';\n }\n}\n\nfunction getSeverityName(severity: number): string {\n switch (severity) {\n case 1: return 'Error';\n case 2: return 'Warning';\n case 3: return 'Information';\n case 4: return 'Hint';\n default: return 'Unknown';\n }\n}\n\n/**\n * Evaluate QL code using the CodeQL Language Server and return diagnostics.\n */\nexport async function lspDiagnostics({\n qlCode,\n workspaceUri,\n serverOptions = {}\n}: LspDiagnosticsParams): Promise {\n try {\n logger.info('Evaluating QL code via Language Server...');\n\n const languageServer = await getInitializedLanguageServer({\n serverOptions,\n workspaceUri,\n });\n\n // Generate unique URI for this evaluation\n const evalUri = pathToFileURL(join(getProjectTmpDir('lsp-eval'), `eval_${Date.now()}.ql`)).href;\n\n const diagnostics = await languageServer.evaluateQL(qlCode, evalUri);\n\n // Count diagnostics by severity\n const summary = {\n errorCount: diagnostics.filter(d => d.severity === 1).length,\n hintCount: diagnostics.filter(d => d.severity === 4).length,\n infoCount: diagnostics.filter(d => d.severity === 3).length,\n warningCount: diagnostics.filter(d => d.severity === 2).length,\n };\n\n const isValid = summary.errorCount === 0;\n const formattedOutput = formatDiagnostics(diagnostics);\n\n logger.info(`QL evaluation complete. Valid: ${isValid}, Issues: ${diagnostics.length}`);\n\n return {\n diagnostics,\n formattedOutput,\n isValid,\n summary,\n };\n\n } catch (error) {\n logger.error('Error evaluating QL code:', error);\n throw new Error(`QL evaluation failed: ${error instanceof Error ? error.message : 'Unknown error'}`);\n }\n}\n\n/**\n * Shutdown the language server via the server manager.\n */\nexport async function shutdownDiagnosticsServer(): Promise {\n const { getServerManager } = await import('../../lib/server-manager');\n const manager = getServerManager();\n await manager.shutdownServer('language');\n}\n\n/**\n * Register the codeql_lsp_diagnostics tool with the MCP server.\n */\nexport function registerLspDiagnosticsTool(server: McpServer): void {\n server.tool(\n 'codeql_lsp_diagnostics',\n 'Authoritative syntax and semantic validation of CodeQL (QL) code via the CodeQL Language Server. Compiles the query and provides real-time diagnostics with precise error locations. Use this for accurate validation; for quick heuristic checks without compilation, use validate_codeql_query instead. Note: inline ql_code is evaluated as a virtual document and cannot resolve pack imports (e.g. `import javascript`). For validating queries with imports, use codeql_query_compile on the actual file instead.',\n {\n log_level: z.enum(['OFF', 'ERROR', 'WARN', 'INFO', 'DEBUG', 'TRACE', 'ALL']).optional().describe('Language server log level'),\n ql_code: z.string().describe('The CodeQL (QL) code to evaluate for syntax and semantic errors'),\n search_path: z.string().optional().describe('Optional search path for CodeQL libraries'),\n workspace_uri: z.string().optional().describe('Optional workspace URI for context (defaults to ./ql directory)'),\n },\n async ({ ql_code, workspace_uri, search_path, log_level }) => {\n try {\n const serverOptions: LanguageServerOptions = {};\n\n if (search_path) {\n serverOptions.searchPath = search_path;\n }\n if (log_level) {\n serverOptions.loglevel = log_level;\n }\n\n const result = await lspDiagnostics({\n qlCode: ql_code,\n serverOptions,\n workspaceUri: workspace_uri,\n });\n\n // Return structured result\n const responseContent = {\n diagnostics: result.diagnostics.map(d => ({\n code: d.code,\n column: d.range.start.character + 1, // Convert to 1-based column numbers\n line: d.range.start.line + 1, // Convert to 1-based line numbers\n message: d.message,\n severity: getSeverityName(d.severity),\n source: d.source,\n })),\n formattedOutput: result.formattedOutput,\n isValid: result.isValid,\n summary: result.summary,\n };\n\n return {\n content: [\n {\n text: JSON.stringify(responseContent, null, 2),\n type: 'text',\n }\n ],\n };\n\n } catch (error) {\n logger.error('Error in codeql_lsp_diagnostics tool:', error);\n return {\n content: [\n {\n text: `Error: ${error instanceof Error ? error.message : 'Unknown error'}`,\n type: 'text',\n },\n ],\n isError: true,\n };\n }\n }\n );\n\n // NOTE: Cleanup is handled centrally by shutdownServerManager() in\n // codeql-development-mcp-server.ts (setupGracefulShutdown). Registering\n // additional process.on('SIGINT'/'SIGTERM') handlers here would\n // accumulate on repeated calls and is unnecessary.\n}\n", "/**\n * Shared helper for obtaining a running, initialized CodeQL Language Server.\n *\n * Both `lsp-diagnostics.ts` and `lsp-handlers.ts` need to:\n * 1. Build a `LanguageServerConfig` with sensible defaults\n * 2. Obtain a server instance from the `CodeQLServerManager`\n * 3. Resolve a workspace URI (relative \u2192 absolute \u2192 `file://`)\n * 4. Initialize the server with the resolved workspace\n *\n * Centralizing this logic avoids duplication and ensures consistent\n * default behaviour across all LSP tools.\n */\n\nimport { isAbsolute, resolve } from 'path';\nimport { pathToFileURL } from 'url';\n\nimport { CodeQLLanguageServer, LanguageServerOptions } from '../../lib/language-server';\nimport { LanguageServerConfig } from '../../lib/server-config';\nimport { getServerManager } from '../../lib/server-manager';\nimport { logger } from '../../utils/logger';\n\n/**\n * Options accepted by {@link getInitializedLanguageServer}.\n */\nexport interface InitializedServerOptions {\n /** Language-server-level options (loglevel, searchPath, etc.). */\n serverOptions?: LanguageServerOptions;\n /** Workspace URI \u2014 may be a `file://` URI, absolute path, or relative path. */\n workspaceUri?: string;\n}\n\n/**\n * Return a running, initialized `CodeQLLanguageServer`.\n *\n * - Resolves `searchPath` to the bundled `ql` directory when not provided.\n * - Converts relative / bare-directory `workspaceUri` paths to `file://` URIs\n * resolved against `getUserWorkspaceDir()` (respects `CODEQL_MCP_WORKSPACE`).\n * - Falls back to the bundled `ql` directory when no workspace is given.\n * - Delegates lifecycle management to the global `CodeQLServerManager`.\n */\nexport async function getInitializedLanguageServer(\n opts: InitializedServerOptions = {},\n): Promise {\n const { packageRootDir: pkgRoot, getUserWorkspaceDir } = await import('../../utils/package-paths');\n const options = opts.serverOptions ?? {};\n\n const config: LanguageServerConfig = {\n checkErrors: 'ON_CHANGE',\n loglevel: options.loglevel ?? 'WARN',\n searchPath: options.searchPath ?? resolve(pkgRoot, 'ql'),\n synchronous: options.synchronous,\n verbosity: options.verbosity,\n };\n\n const manager = getServerManager();\n const server = await manager.getLanguageServer(config);\n\n // Normalize workspace URI: convert relative / bare directory paths to\n // file:// URIs against getUserWorkspaceDir() (respects CODEQL_MCP_WORKSPACE).\n let effectiveUri = opts.workspaceUri;\n if (effectiveUri && !effectiveUri.startsWith('file://')) {\n const absWorkspace = isAbsolute(effectiveUri)\n ? effectiveUri\n : resolve(getUserWorkspaceDir(), effectiveUri);\n effectiveUri = pathToFileURL(absWorkspace).href;\n }\n effectiveUri = effectiveUri ?? pathToFileURL(resolve(pkgRoot, 'ql')).href;\n\n await server.initialize(effectiveUri);\n logger.debug(`Language server initialized with workspace: ${effectiveUri}`);\n\n return server;\n}\n", "/**\n * CodeQL LSP tool handlers.\n *\n * Bridges MCP tool invocations to LSP requests on the CodeQL Language Server.\n * Each handler acquires a language server via the CodeQLServerManager,\n * opens the requested document, sends the LSP request, and returns the result.\n */\n\nimport { readFile } from 'fs/promises';\nimport { isAbsolute, resolve } from 'path';\nimport { pathToFileURL } from 'url';\n\nimport {\n CompletionItem,\n LSPLocation,\n TextDocumentPositionParams,\n} from '../../lib/language-server';\nimport { logger } from '../../utils/logger';\nimport { getUserWorkspaceDir } from '../../utils/package-paths';\nimport { getInitializedLanguageServer } from './lsp-server-helper';\n\n/**\n * Common parameters for LSP tool invocations.\n */\nexport interface LSPToolParams {\n /** 0-based character offset within the line. */\n character: number;\n /** Optional override for the file content (if not reading from disk). */\n fileContent?: string;\n /**\n * Path to the QL file. May be absolute or relative.\n * Relative paths are resolved against `getUserWorkspaceDir()`\n * (respects the `CODEQL_MCP_WORKSPACE` environment variable).\n */\n filePath: string;\n /** 0-based line number in the document. */\n line: number;\n /** Optional search path for CodeQL libraries. */\n searchPath?: string;\n /** Optional workspace URI for context. */\n workspaceUri?: string;\n}\n\n/**\n * Get a running, initialized language server for the given parameters.\n */\nasync function getInitializedServer(params: LSPToolParams) {\n return getInitializedLanguageServer({\n serverOptions: { searchPath: params.searchPath },\n workspaceUri: params.workspaceUri,\n });\n}\n\n/**\n * Resolve the file path to an absolute path and file:// URI.\n */\nfunction prepareDocumentPosition(\n params: LSPToolParams,\n): { absPath: string; docUri: string } {\n // Resolve relative paths against getUserWorkspaceDir() so that\n // CODEQL_MCP_WORKSPACE is respected and behaviour is consistent across tools.\n const absPath = isAbsolute(params.filePath)\n ? params.filePath\n : resolve(getUserWorkspaceDir(), params.filePath);\n const docUri = pathToFileURL(absPath).href;\n\n return { absPath, docUri };\n}\n\n/**\n * Read file content and open the document in the language server.\n */\nasync function openDocumentForPosition(\n server: Awaited>,\n params: LSPToolParams,\n absPath: string,\n docUri: string,\n): Promise {\n // Read file content from disk or use provided content\n let text: string;\n if (params.fileContent) {\n text = params.fileContent;\n } else {\n try {\n text = await readFile(absPath, 'utf-8');\n } catch (error) {\n throw new Error(`Cannot read file: ${absPath}: ${error instanceof Error ? error.message : error}`);\n }\n }\n\n // Open the document so the language server knows about it\n server.openDocument(docUri, text);\n\n return {\n position: { character: params.character, line: params.line },\n textDocument: { uri: docUri },\n };\n}\n\n/**\n * Get code completions at a position.\n */\nexport async function lspCompletion(params: LSPToolParams): Promise {\n logger.info(`LSP completion at ${params.filePath}:${params.line}:${params.character}`);\n const server = await getInitializedServer(params);\n const { absPath, docUri } = prepareDocumentPosition(params);\n const positionParams = await openDocumentForPosition(server, params, absPath, docUri);\n\n try {\n return await server.getCompletions(positionParams);\n } finally {\n server.closeDocument(docUri);\n }\n}\n\n/**\n * Go to definition of a symbol at a position.\n */\nexport async function lspDefinition(params: LSPToolParams): Promise {\n logger.info(`LSP definition at ${params.filePath}:${params.line}:${params.character}`);\n const server = await getInitializedServer(params);\n const { absPath, docUri } = prepareDocumentPosition(params);\n const positionParams = await openDocumentForPosition(server, params, absPath, docUri);\n\n try {\n return await server.getDefinition(positionParams);\n } finally {\n server.closeDocument(docUri);\n }\n}\n\n/**\n * Find all references to a symbol at a position.\n */\nexport async function lspReferences(params: LSPToolParams): Promise {\n logger.info(`LSP references at ${params.filePath}:${params.line}:${params.character}`);\n const server = await getInitializedServer(params);\n const { absPath, docUri } = prepareDocumentPosition(params);\n const positionParams = await openDocumentForPosition(server, params, absPath, docUri);\n\n try {\n return await server.getReferences({\n ...positionParams,\n context: { includeDeclaration: true },\n });\n } finally {\n server.closeDocument(docUri);\n }\n}\n", "/**\n * CodeQL LSP MCP tool definitions.\n *\n * Registers four LSP-based tools:\n * - codeql_lsp_completion \u2013 code completions at cursor position\n * - codeql_lsp_definition \u2013 go to definition\n * - codeql_lsp_diagnostics \u2013 QL code validation via LSP diagnostics\n * - codeql_lsp_references \u2013 find all references\n */\n\nimport { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport { z } from 'zod';\nimport { registerLspDiagnosticsTool } from './lsp-diagnostics';\nimport {\n lspCompletion,\n lspDefinition,\n lspReferences,\n} from './lsp-handlers';\nimport { logger } from '../../utils/logger';\n\n/**\n * Shared Zod schema for the common LSP tool parameters.\n */\nconst lspParamsSchema = {\n character: z.number().int().min(0).describe('0-based character offset within the line'),\n file_content: z.string().optional().describe('Optional file content override (reads from disk if omitted)'),\n file_path: z.string().describe('Path to the CodeQL (.ql/.qll) file. Relative paths are resolved against the user workspace directory (see CODEQL_MCP_WORKSPACE).'),\n line: z.number().int().min(0).describe('0-based line number in the document'),\n search_path: z.string().optional().describe('Optional search path for CodeQL libraries'),\n workspace_uri: z.string().optional().describe('Optional workspace URI for context (defaults to ./ql directory)'),\n};\n\n/**\n * Helper to build the handler params from the raw MCP tool input.\n */\nfunction toHandlerParams(input: {\n character: number;\n file_content?: string;\n file_path: string;\n line: number;\n search_path?: string;\n workspace_uri?: string;\n}) {\n return {\n character: input.character,\n fileContent: input.file_content,\n filePath: input.file_path,\n line: input.line,\n searchPath: input.search_path,\n workspaceUri: input.workspace_uri,\n };\n}\n\n/**\n * Register all LSP-based tools with the MCP server.\n */\nexport function registerLSPTools(server: McpServer): void {\n // --- codeql_lsp_diagnostics (relocated from codeql_language_server_eval) ---\n registerLspDiagnosticsTool(server);\n\n // --- codeql_lsp_completion ---\n server.tool(\n 'codeql_lsp_completion',\n 'Get code completions at a cursor position in a CodeQL file. Returns completion items with labels, documentation, and insert text. The file must be a .ql or .qll file. IMPORTANT: Set workspace_uri to the pack or workspace root directory for dependency resolution; without it, completions for imported libraries will be empty.',\n lspParamsSchema,\n async (input) => {\n try {\n const items = await lspCompletion(toHandlerParams(input));\n return {\n content: [{\n text: JSON.stringify({\n completionCount: items.length,\n items: items.map((item) => ({\n detail: item.detail,\n documentation: item.documentation,\n insertText: item.insertText,\n kind: item.kind,\n label: item.label,\n })),\n }, null, 2),\n type: 'text' as const,\n }],\n };\n } catch (error) {\n logger.error('codeql_lsp_completion error:', error);\n return {\n content: [{ text: `Error: ${error instanceof Error ? error.message : 'Unknown error'}`, type: 'text' as const }],\n isError: true,\n };\n }\n },\n );\n\n // --- codeql_lsp_definition ---\n server.tool(\n 'codeql_lsp_definition',\n 'Go to the definition of a CodeQL symbol at a given position. Returns one or more file locations where the symbol is defined. Set workspace_uri to the pack root for dependency resolution.',\n lspParamsSchema,\n async (input) => {\n try {\n const locations = await lspDefinition(toHandlerParams(input));\n return {\n content: [{\n text: JSON.stringify({\n definitionCount: locations.length,\n locations: locations.map((loc) => ({\n endCharacter: loc.range.end.character,\n endLine: loc.range.end.line + 1,\n startCharacter: loc.range.start.character,\n startLine: loc.range.start.line + 1,\n uri: loc.uri,\n })),\n }, null, 2),\n type: 'text' as const,\n }],\n };\n } catch (error) {\n logger.error('codeql_lsp_definition error:', error);\n return {\n content: [{ text: `Error: ${error instanceof Error ? error.message : 'Unknown error'}`, type: 'text' as const }],\n isError: true,\n };\n }\n },\n );\n\n // --- codeql_lsp_references ---\n server.tool(\n 'codeql_lsp_references',\n 'Find all references to a CodeQL symbol at a given position. Returns file locations of all usages, including the declaration. Set workspace_uri to the pack root for dependency resolution.',\n lspParamsSchema,\n async (input) => {\n try {\n const locations = await lspReferences(toHandlerParams(input));\n return {\n content: [{\n text: JSON.stringify({\n locations: locations.map((loc) => ({\n endCharacter: loc.range.end.character,\n endLine: loc.range.end.line + 1,\n startCharacter: loc.range.start.character,\n startLine: loc.range.start.line + 1,\n uri: loc.uri,\n })),\n referenceCount: locations.length,\n }, null, 2),\n type: 'text' as const,\n }],\n };\n } catch (error) {\n logger.error('codeql_lsp_references error:', error);\n return {\n content: [{ text: `Error: ${error instanceof Error ? error.message : 'Unknown error'}`, type: 'text' as const }],\n isError: true,\n };\n }\n },\n );\n}\n", "/**\n * Language-specific resources implementation\n * Dynamically loads and serves language-specific AST references and security patterns\n */\n\nimport { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport { readFileSync, existsSync } from 'fs';\nimport { join } from 'path';\nimport { LANGUAGE_RESOURCES } from '../types/language-types';\nimport { workspaceRootDir } from '../utils/package-paths';\nimport { logger } from '../utils/logger';\n\n/**\n * Get the base path for ql resources.\n * Uses the workspace root (monorepo root or package root) so that\n * resource files are found regardless of the server's process.cwd().\n */\nfunction getQLBasePath(): string {\n return workspaceRootDir;\n}\n\n/**\n * Load content from a resource file\n */\nfunction loadResourceContent(relativePath: string): string | null {\n try {\n const fullPath = join(getQLBasePath(), relativePath);\n \n if (!existsSync(fullPath)) {\n logger.warn(`Resource file not found: ${fullPath}`);\n return null;\n }\n \n return readFileSync(fullPath, 'utf-8');\n } catch (error) {\n logger.error(`Error loading resource file ${relativePath}:`, error);\n return null;\n }\n}\n\n/**\n * Register language-specific AST resources\n */\nexport function registerLanguageASTResources(server: McpServer): void {\n for (const langResource of LANGUAGE_RESOURCES) {\n if (!langResource.astFile) continue;\n \n const resourceUri = `codeql://languages/${langResource.language}/ast`;\n \n server.resource(\n `${langResource.language.toUpperCase()} AST Reference`,\n resourceUri,\n {\n description: `CodeQL AST class reference for ${langResource.language} programs`,\n mimeType: 'text/markdown'\n },\n async () => {\n const content = loadResourceContent(langResource.astFile!);\n \n if (!content) {\n return {\n contents: [{\n uri: resourceUri,\n mimeType: 'text/markdown',\n text: `# ${langResource.language.toUpperCase()} AST Reference\\n\\nResource file not found or could not be loaded.`\n }]\n };\n }\n \n return {\n contents: [{\n uri: resourceUri,\n mimeType: 'text/markdown',\n text: content\n }]\n };\n }\n );\n }\n}\n\n/**\n * Register language-specific security pattern resources\n */\nexport function registerLanguageSecurityResources(server: McpServer): void {\n for (const langResource of LANGUAGE_RESOURCES) {\n if (!langResource.securityFile) continue;\n \n const resourceUri = `codeql://languages/${langResource.language}/security`;\n \n server.resource(\n `${langResource.language.toUpperCase()} Security Patterns`,\n resourceUri,\n {\n description: `CodeQL security query patterns and framework modeling for ${langResource.language}`,\n mimeType: 'text/markdown'\n },\n async () => {\n const content = loadResourceContent(langResource.securityFile!);\n \n if (!content) {\n return {\n contents: [{\n uri: resourceUri,\n mimeType: 'text/markdown',\n text: `# ${langResource.language.toUpperCase()} Security Patterns\\n\\nResource file not found or could not be loaded.`\n }]\n };\n }\n \n return {\n contents: [{\n uri: resourceUri,\n mimeType: 'text/markdown',\n text: content\n }]\n };\n }\n );\n }\n}\n\n/**\n * Register additional language-specific resources (like Go's dataflow patterns)\n */\nexport function registerLanguageAdditionalResources(server: McpServer): void {\n for (const langResource of LANGUAGE_RESOURCES) {\n if (!langResource.additionalFiles) continue;\n \n for (const [resourceType, filePath] of Object.entries(langResource.additionalFiles)) {\n const resourceUri = `codeql://languages/${langResource.language}/${resourceType}`;\n \n server.resource(\n `${langResource.language.toUpperCase()} ${resourceType.replace('-', ' ').replace(/\\b\\w/g, l => l.toUpperCase())}`,\n resourceUri,\n {\n description: `CodeQL ${resourceType.replace('-', ' ')} guide for ${langResource.language}`,\n mimeType: 'text/markdown'\n },\n async () => {\n const content = loadResourceContent(filePath);\n \n if (!content) {\n return {\n contents: [{\n uri: resourceUri,\n mimeType: 'text/markdown',\n text: `# ${langResource.language.toUpperCase()} ${resourceType.replace('-', ' ').replace(/\\b\\w/g, l => l.toUpperCase())}\\n\\nResource file not found or could not be loaded.`\n }]\n };\n }\n \n return {\n contents: [{\n uri: resourceUri,\n mimeType: 'text/markdown',\n text: content\n }]\n };\n }\n );\n }\n }\n}\n\n/**\n * Register all language-specific resources\n */\nexport function registerLanguageResources(server: McpServer): void {\n logger.info('Registering language-specific resources...');\n \n // Register AST references for all languages\n registerLanguageASTResources(server);\n \n // Register security patterns for languages that have them\n registerLanguageSecurityResources(server);\n \n // Register additional resources (like Go's dataflow patterns)\n registerLanguageAdditionalResources(server);\n \n logger.info(`Registered resources for ${LANGUAGE_RESOURCES.length} languages`);\n}", "/**\n * Type definitions and constants for language-specific resources\n */\n\n// Language mappings to resource files\nexport interface LanguageResource {\n language: string;\n astFile?: string;\n securityFile?: string;\n additionalFiles?: Record;\n}\n\nexport const LANGUAGE_RESOURCES: LanguageResource[] = [\n {\n language: 'actions',\n astFile: 'ql/languages/actions/tools/dev/actions_ast.prompt.md'\n },\n {\n language: 'cpp',\n astFile: 'ql/languages/cpp/tools/dev/cpp_ast.prompt.md',\n securityFile: 'ql/languages/cpp/tools/dev/cpp_security_query_guide.prompt.md'\n },\n {\n language: 'csharp',\n astFile: 'ql/languages/csharp/tools/dev/csharp_ast.prompt.md',\n securityFile: 'ql/languages/csharp/tools/dev/csharp_security_query_guide.prompt.md'\n },\n {\n language: 'go',\n astFile: 'ql/languages/go/tools/dev/go_ast.prompt.md',\n securityFile: 'ql/languages/go/tools/dev/go_security_query_guide.prompt.md',\n additionalFiles: {\n 'dataflow': 'ql/languages/go/tools/dev/go_dataflow.prompt.md',\n 'library-modeling': 'ql/languages/go/tools/dev/go_library_modeling.prompt.md',\n 'basic-queries': 'ql/languages/go/tools/dev/go_basic_queries.prompt.md'\n }\n },\n {\n language: 'java',\n astFile: 'ql/languages/java/tools/dev/java_ast.prompt.md'\n },\n {\n language: 'javascript',\n astFile: 'ql/languages/javascript/tools/dev/javascript_ast.prompt.md',\n securityFile: 'ql/languages/javascript/tools/dev/javascript_security_query_guide.prompt.md'\n },\n {\n language: 'python',\n astFile: 'ql/languages/python/tools/dev/python_ast.prompt.md',\n securityFile: 'ql/languages/python/tools/dev/python_security_query_guide.prompt.md'\n },\n {\n language: 'ql',\n astFile: 'ql/languages/ql/tools/dev/ql_ast.prompt.md'\n },\n {\n language: 'ruby',\n astFile: 'ql/languages/ruby/tools/dev/ruby_ast.prompt.md'\n }\n];", "/**\n * MCP Server workflow prompts for CodeQL development\n *\n * All prompt content is loaded from .prompt.md files in this directory.\n * This file only handles prompt registration and parameter processing.\n */\n\nimport { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport { z } from 'zod';\nimport { basename } from 'path';\nimport { loadPromptTemplate, processPromptTemplate } from './prompt-loader';\nimport { logger } from '../utils/logger';\n\n/** Supported CodeQL languages for tools queries */\nexport const SUPPORTED_LANGUAGES = [\n 'actions',\n 'cpp',\n 'csharp',\n 'go',\n 'java',\n 'javascript',\n 'python',\n 'ruby',\n 'swift'\n] as const;\n\n// \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n// Exported parameter schemas for each workflow prompt.\n//\n// Extracting the schemas makes it easy to unit-test required vs optional\n// validation independently of the MCP server registration.\n//\n// **Convention for VS Code UX consistency**:\n// Every prompt MUST expose at least one parameter \u2013 even if all parameters\n// are optional \u2013 so that VS Code always displays the parameter input dialog\n// and allows the user to customize the prompt before Copilot Chat processes\n// it. The `description` field on each Zod schema member doubles as the\n// placeholder text shown in the VS Code input box.\n// \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n/**\n * Schema for test_driven_development prompt parameters.\n *\n * - `language` is **required** \u2013 the TDD workflow is language-specific.\n * - `queryName` is optional \u2013 defaults to '[QueryName]' if omitted.\n */\nexport const testDrivenDevelopmentSchema = z.object({\n language: z\n .enum(SUPPORTED_LANGUAGES)\n .describe('Programming language for the query'),\n queryName: z\n .string()\n .optional()\n .describe('Name of the query to develop'),\n});\n\n/**\n * Schema for tools_query_workflow prompt parameters.\n *\n * - `language` and `database` are **required**.\n * - `sourceFiles`, `sourceFunction`, `targetFunction` are optional context.\n */\nexport const toolsQueryWorkflowSchema = z.object({\n database: z\n .string()\n .describe('Path to the CodeQL database'),\n language: z\n .enum(SUPPORTED_LANGUAGES)\n .describe('Programming language for the tools queries'),\n sourceFiles: z\n .string()\n .optional()\n .describe('Comma-separated source file names for PrintAST (e.g., \"main.js,utils.js\")'),\n sourceFunction: z\n .string()\n .optional()\n .describe('Function name for PrintCFG or CallGraphFrom (e.g., \"processData\")'),\n targetFunction: z\n .string()\n .optional()\n .describe('Function name for CallGraphTo (e.g., \"validate\")'),\n});\n\n/**\n * Schema for workshop_creation_workflow prompt parameters.\n * Uses z.coerce.number() for numStages to handle string inputs from VSCode slash commands.\n *\n * - `queryPath` and `language` are **required**.\n * - `workshopName` and `numStages` are optional.\n */\nexport const workshopCreationWorkflowSchema = z.object({\n queryPath: z\n .string()\n .describe('Path to the production-grade CodeQL query (.ql or .qlref)'),\n language: z\n .enum(SUPPORTED_LANGUAGES)\n .describe('Programming language of the query'),\n workshopName: z\n .string()\n .optional()\n .describe('Name for the workshop directory'),\n numStages: z\n .coerce.number()\n .optional()\n .describe('Number of incremental stages (default: 4-8)'),\n});\n\n/**\n * Schema for ql_tdd_basic prompt parameters.\n *\n * All parameters are optional \u2013 but at least one should be present so the\n * VS Code quick-pick dialog appears.\n */\nexport const qlTddBasicSchema = z.object({\n language: z\n .enum(SUPPORTED_LANGUAGES)\n .optional()\n .describe('Programming language for the query (optional)'),\n queryName: z\n .string()\n .optional()\n .describe('Name of the query to develop'),\n});\n\n/**\n * Schema for ql_tdd_advanced prompt parameters.\n *\n * All parameters are optional.\n */\nexport const qlTddAdvancedSchema = z.object({\n database: z\n .string()\n .optional()\n .describe('Path to the CodeQL database for analysis'),\n language: z\n .enum(SUPPORTED_LANGUAGES)\n .optional()\n .describe('Programming language for the query (optional)'),\n queryName: z\n .string()\n .optional()\n .describe('Name of the query to develop'),\n});\n\n/**\n * Schema for sarif_rank_false_positives / sarif_rank_true_positives.\n *\n * Both parameters are optional.\n */\nexport const sarifRankSchema = z.object({\n queryId: z\n .string()\n .optional()\n .describe('CodeQL query/rule identifier'),\n sarifPath: z\n .string()\n .optional()\n .describe('Path to the SARIF file to analyze'),\n});\n\n/**\n * Schema for explain_codeql_query prompt parameters.\n *\n * - `queryPath` and `language` are **required**.\n * - `databasePath` is optional.\n */\nexport const explainCodeqlQuerySchema = z.object({\n databasePath: z\n .string()\n .optional()\n .describe('Optional path to a real CodeQL database for profiling'),\n language: z\n .enum(SUPPORTED_LANGUAGES)\n .describe('Programming language of the query'),\n queryPath: z\n .string()\n .describe('Path to the CodeQL query file (.ql or .qlref)'),\n});\n\n/**\n * Schema for document_codeql_query prompt parameters.\n *\n * - `queryPath` and `language` are **required**.\n */\nexport const documentCodeqlQuerySchema = z.object({\n language: z\n .enum(SUPPORTED_LANGUAGES)\n .describe('Programming language of the query'),\n queryPath: z\n .string()\n .describe('Path to the CodeQL query file (.ql or .qlref)'),\n});\n\n/**\n * Schema for ql_lsp_iterative_development prompt parameters.\n *\n * All parameters are optional.\n */\nexport const qlLspIterativeDevelopmentSchema = z.object({\n language: z\n .enum(SUPPORTED_LANGUAGES)\n .optional()\n .describe('Programming language for the query'),\n queryPath: z\n .string()\n .optional()\n .describe('Path to the query file being developed'),\n workspaceUri: z\n .string()\n .optional()\n .describe('Workspace URI for LSP dependency resolution'),\n});\n\n// \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n// Prompt names (exported for testing)\n// \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n/** Names of every workflow prompt registered with the MCP server. */\nexport const WORKFLOW_PROMPT_NAMES = [\n 'document_codeql_query',\n 'explain_codeql_query',\n 'ql_lsp_iterative_development',\n 'ql_tdd_advanced',\n 'ql_tdd_basic',\n 'sarif_rank_false_positives',\n 'sarif_rank_true_positives',\n 'test_driven_development',\n 'tools_query_workflow',\n 'workshop_creation_workflow',\n] as const;\n\n/**\n * Register MCP workflow prompts\n *\n * Each prompt loads its content from a corresponding .prompt.md file\n * and processes any parameter substitutions.\n *\n * **UX note**: Every prompt schema is passed to `server.prompt()` so that\n * VS Code always displays the parameter-input quick-pick before the prompt\n * is sent to Copilot Chat. This lets users review and customise the values.\n */\nexport function registerWorkflowPrompts(server: McpServer): void {\n // Test-Driven Development Prompt\n server.prompt(\n 'test_driven_development',\n 'Test-driven development workflow for CodeQL queries using MCP tools',\n testDrivenDevelopmentSchema.shape,\n async ({ language, queryName }) => {\n const template = loadPromptTemplate('ql-tdd-basic.prompt.md');\n const content = processPromptTemplate(template, {\n language,\n queryName: queryName || '[QueryName]'\n });\n\n return {\n messages: [\n {\n role: 'user',\n content: {\n type: 'text',\n text: `## Context\\n\\n- **Language**: ${language}\\n${queryName ? `- **Query Name**: ${queryName}\\n` : ''}\\n${content}`\n }\n }\n ]\n };\n }\n );\n\n // Tools Query Workflow Prompt\n server.prompt(\n 'tools_query_workflow',\n 'Guide for using built-in tools queries (PrintAST, PrintCFG, CallGraphFrom, CallGraphTo) to understand code structure',\n toolsQueryWorkflowSchema.shape,\n async ({\n language,\n database,\n sourceFiles,\n sourceFunction,\n targetFunction\n }) => {\n const template = loadPromptTemplate('tools-query-workflow.prompt.md');\n const content = processPromptTemplate(template, {\n language,\n database\n });\n\n const contextSection = buildToolsQueryContext(\n language,\n database,\n sourceFiles,\n sourceFunction,\n targetFunction\n );\n\n return {\n messages: [\n {\n role: 'user',\n content: {\n type: 'text',\n text: contextSection + content\n }\n }\n ]\n };\n }\n );\n\n // Workshop Creation Workflow Prompt\n server.prompt(\n 'workshop_creation_workflow',\n 'Guide for creating CodeQL query development workshops from production-grade queries',\n workshopCreationWorkflowSchema.shape,\n async ({ queryPath, language, workshopName, numStages }) => {\n const template = loadPromptTemplate('workshop-creation-workflow.prompt.md');\n\n // Derive workshop name from query path if not provided\n const derivedName =\n workshopName ||\n basename(queryPath)\n .replace(/\\.(ql|qlref)$/, '')\n .toLowerCase()\n .replace(/[^a-z0-9]+/g, '-') ||\n 'codeql-workshop';\n\n const contextSection = buildWorkshopContext(\n queryPath,\n language,\n derivedName,\n numStages\n );\n\n return {\n messages: [\n {\n role: 'user',\n content: {\n type: 'text',\n text: contextSection + template\n }\n }\n ]\n };\n }\n );\n\n // TDD Basic Prompt - Test-Driven Development Checklist\n server.prompt(\n 'ql_tdd_basic',\n 'Test-driven CodeQL query development checklist - write tests first, implement query, iterate until tests pass',\n qlTddBasicSchema.shape,\n async ({ language, queryName }) => {\n const template = loadPromptTemplate('ql-tdd-basic.prompt.md');\n\n let contextSection = '## Your Development Context\\n\\n';\n if (language) {\n contextSection += `- **Language**: ${language}\\n`;\n }\n if (queryName) {\n contextSection += `- **Query Name**: ${queryName}\\n`;\n }\n if (language || queryName) {\n contextSection += '\\n';\n }\n\n return {\n messages: [\n {\n role: 'user',\n content: {\n type: 'text',\n text: contextSection + template\n }\n }\n ]\n };\n }\n );\n\n // TDD Advanced Prompt - Advanced Techniques with AST/CFG/CallGraph\n server.prompt(\n 'ql_tdd_advanced',\n 'Advanced test-driven CodeQL development with AST visualization, control flow, and call graph analysis',\n qlTddAdvancedSchema.shape,\n async ({ language, queryName, database }) => {\n const template = loadPromptTemplate('ql-tdd-advanced.prompt.md');\n\n let contextSection = '## Your Development Context\\n\\n';\n if (language) {\n contextSection += `- **Language**: ${language}\\n`;\n }\n if (queryName) {\n contextSection += `- **Query Name**: ${queryName}\\n`;\n }\n if (database) {\n contextSection += `- **Database**: ${database}\\n`;\n }\n if (language || queryName || database) {\n contextSection += '\\n';\n }\n\n return {\n messages: [\n {\n role: 'user',\n content: {\n type: 'text',\n text: contextSection + template\n }\n }\n ]\n };\n }\n );\n\n // SARIF Rank False Positives Prompt\n server.prompt(\n 'sarif_rank_false_positives',\n 'Analyze SARIF results to identify likely false positives in CodeQL query results',\n sarifRankSchema.shape,\n async ({ queryId, sarifPath }) => {\n const template = loadPromptTemplate('sarif-rank-false-positives.prompt.md');\n\n let contextSection = '## Analysis Context\\n\\n';\n if (queryId) {\n contextSection += `- **Query ID**: ${queryId}\\n`;\n }\n if (sarifPath) {\n contextSection += `- **SARIF File**: ${sarifPath}\\n`;\n }\n if (queryId || sarifPath) {\n contextSection += '\\n';\n }\n\n return {\n messages: [\n {\n role: 'user',\n content: {\n type: 'text',\n text: contextSection + template\n }\n }\n ]\n };\n }\n );\n\n // SARIF Rank True Positives Prompt\n server.prompt(\n 'sarif_rank_true_positives',\n 'Analyze SARIF results to identify likely true positives in CodeQL query results',\n sarifRankSchema.shape,\n async ({ queryId, sarifPath }) => {\n const template = loadPromptTemplate('sarif-rank-true-positives.prompt.md');\n\n let contextSection = '## Analysis Context\\n\\n';\n if (queryId) {\n contextSection += `- **Query ID**: ${queryId}\\n`;\n }\n if (sarifPath) {\n contextSection += `- **SARIF File**: ${sarifPath}\\n`;\n }\n if (queryId || sarifPath) {\n contextSection += '\\n';\n }\n\n return {\n messages: [\n {\n role: 'user',\n content: {\n type: 'text',\n text: contextSection + template\n }\n }\n ]\n };\n }\n );\n\n // Explain CodeQL Query Prompt (for workshop learning content)\n server.prompt(\n 'explain_codeql_query',\n 'Generate detailed explanation of a CodeQL query for workshop learning content - uses MCP tools to gather context and produces both verbal explanations and mermaid evaluation diagrams',\n explainCodeqlQuerySchema.shape,\n async ({ queryPath, language, databasePath }) => {\n const template = loadPromptTemplate('explain-codeql-query.prompt.md');\n\n let contextSection = '## Query to Explain\\n\\n';\n contextSection += `- **Query Path**: ${queryPath}\\n`;\n contextSection += `- **Language**: ${language}\\n`;\n if (databasePath) {\n contextSection += `- **Database Path**: ${databasePath}\\n`;\n }\n contextSection += '\\n';\n\n return {\n messages: [\n {\n role: 'user',\n content: {\n type: 'text',\n text: contextSection + template\n }\n }\n ]\n };\n }\n );\n\n // Document CodeQL Query Prompt\n server.prompt(\n 'document_codeql_query',\n 'Create or update documentation for a CodeQL query - generates standardized markdown documentation as a sibling file to the query',\n documentCodeqlQuerySchema.shape,\n async ({ queryPath, language }) => {\n const template = loadPromptTemplate('document-codeql-query.prompt.md');\n\n const contextSection = `## Query to Document\n\n- **Query Path**: ${queryPath}\n- **Language**: ${language}\n\n`;\n\n return {\n messages: [\n {\n role: 'user',\n content: {\n type: 'text',\n text: contextSection + template\n }\n }\n ]\n };\n }\n );\n\n // LSP-powered Iterative Development Prompt\n server.prompt(\n 'ql_lsp_iterative_development',\n 'Iterative CodeQL query development using LSP tools for completion, navigation, and validation',\n qlLspIterativeDevelopmentSchema.shape,\n async ({ language, queryPath, workspaceUri }) => {\n const template = loadPromptTemplate('ql-lsp-iterative-development.prompt.md');\n\n let contextSection = '## Your Development Context\\n\\n';\n if (language) {\n contextSection += `- **Language**: ${language}\\n`;\n }\n if (queryPath) {\n contextSection += `- **Query Path**: ${queryPath}\\n`;\n }\n if (workspaceUri) {\n contextSection += `- **Workspace URI**: ${workspaceUri}\\n`;\n }\n if (language || queryPath || workspaceUri) {\n contextSection += '\\n';\n }\n\n return {\n messages: [\n {\n role: 'user',\n content: {\n type: 'text',\n text: contextSection + template,\n },\n },\n ],\n };\n }\n );\n\n logger.info(`Registered ${WORKFLOW_PROMPT_NAMES.length} workflow prompts`);\n}\n\n/**\n * Build context section for tools query workflow\n */\nexport function buildToolsQueryContext(\n language: string,\n database: string,\n sourceFiles?: string,\n sourceFunction?: string,\n targetFunction?: string\n): string {\n const lines = [\n '## Your Context',\n '',\n `- **Language**: ${language}`,\n `- **Database**: ${database}`\n ];\n\n if (sourceFiles) {\n lines.push(`- **Source Files**: ${sourceFiles}`);\n }\n if (sourceFunction) {\n lines.push(`- **Source Function**: ${sourceFunction}`);\n }\n if (targetFunction) {\n lines.push(`- **Target Function**: ${targetFunction}`);\n }\n\n lines.push('', '## Recommended Next Steps', '');\n\n if (sourceFiles) {\n lines.push(\n `1. Run \\`codeql_query_run\\` with queryName=\"PrintAST\", sourceFiles=\"${sourceFiles}\"`\n );\n } else {\n lines.push('1. Identify source files to analyze with PrintAST');\n }\n\n if (sourceFunction) {\n lines.push(\n `2. Run \\`codeql_query_run\\` with queryName=\"PrintCFG\" or \"CallGraphFrom\", sourceFunction=\"${sourceFunction}\"`\n );\n } else {\n lines.push(\n '2. Identify key functions for CFG or call graph analysis'\n );\n }\n\n if (targetFunction) {\n lines.push(\n `3. Run \\`codeql_query_run\\` with queryName=\"CallGraphTo\", targetFunction=\"${targetFunction}\"`\n );\n } else {\n lines.push('3. Identify target functions to find callers');\n }\n\n lines.push('', '');\n return lines.join('\\n');\n}\n\n/**\n * Build context section for workshop creation workflow\n */\nexport function buildWorkshopContext(\n queryPath: string,\n language: string,\n workshopName: string,\n numStages?: number\n): string {\n return `## Your Workshop Context\n\n- **Target Query**: ${queryPath}\n- **Language**: ${language}\n- **Workshop Name**: ${workshopName}\n- **Suggested Stages**: ${numStages || '4-8 (auto-detect based on query complexity)'}\n\n## Immediate Actions\n\n1. **Locate query files**: Use \\`find_codeql_query_files\\` with queryPath=\"${queryPath}\"\n2. **Understand query for learning content**: Use the \\`explain_codeql_query\\` prompt with queryPath=\"${queryPath}\" and language=\"${language}\"\n3. **Document each workshop stage**: Use the \\`document_codeql_query\\` prompt to create/update documentation for each solution query\n4. **Verify tests pass**: Use \\`codeql_test_run\\` on existing tests\n5. **Run tools queries**: Generate AST/CFG understanding for workshop materials\n\n`;\n}\n", "/**\n * Utility functions for loading prompt template files\n */\n\nimport { readFileSync } from 'fs';\nimport { join, dirname } from 'path';\nimport { fileURLToPath } from 'url';\n\nconst __filename = fileURLToPath(import.meta.url);\nconst __dirname = dirname(__filename);\n\n/**\n * Load a prompt template from a .prompt.md file\n */\nexport function loadPromptTemplate(promptFileName: string): string {\n try {\n const promptPath = join(__dirname, promptFileName);\n return readFileSync(promptPath, 'utf-8');\n } catch (error) {\n return `Prompt template '${promptFileName}' not available: ${error instanceof Error ? error.message : 'Unknown error'}`;\n }\n}\n\n/**\n * Process prompt template by replacing placeholders with actual values\n */\nexport function processPromptTemplate(template: string, variables: Record): string {\n let processed = template;\n \n // Replace variables in the format {{variable}} or {variable}\n for (const [key, value] of Object.entries(variables)) {\n const patterns = [\n new RegExp(`\\\\{\\\\{${key}\\\\}\\\\}`, 'g'),\n new RegExp(`\\\\{${key}\\\\}`, 'g')\n ];\n \n for (const pattern of patterns) {\n processed = processed.replace(pattern, value);\n }\n }\n \n return processed;\n}", "/**\n * Monitoring Tools - MCP tool implementations for session management and reporting\n * Provides the MCP Tool APIs specified in the monitoring specification\n */\n\nimport { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport { z } from 'zod';\nimport { randomUUID } from 'crypto';\nimport { sessionDataManager } from '../lib/session-data-manager';\nimport {\n QueryDevelopmentSession,\n SessionFilter,\n QualityScoreRecord,\n ComparisonReport,\n AggregateReport,\n ExportResult,\n FunctionalTestResult,\n} from '../types/monitoring';\nimport { logger } from '../utils/logger';\n\n/**\n * Register all monitoring and reporting tools with the MCP server\n * Note: These tools are opt-in and disabled by default for end-users.\n * Set enableMonitoringTools: true in monitoring config to enable them.\n */\nexport function registerMonitoringTools(server: McpServer): void {\n const config = sessionDataManager.getConfig();\n \n // Check if monitoring tools are enabled (opt-in, disabled by default)\n if (!config.enableMonitoringTools) {\n logger.info('Monitoring tools are disabled (opt-in). Set enableMonitoringTools: true to enable session_* tools.');\n return;\n }\n\n // Session Management Tools - session_start removed per feedback (auto-creation instead)\n registerSessionEndTool(server);\n registerSessionGetTool(server);\n registerSessionListTool(server);\n registerSessionUpdateStateTool(server);\n\n // Session Analytics Tools\n registerSessionGetCallHistoryTool(server);\n registerSessionGetTestHistoryTool(server);\n registerSessionGetScoreHistoryTool(server);\n registerSessionCalculateCurrentScoreTool(server);\n\n // Batch Operations Tools\n registerSessionsCompareTool(server);\n registerSessionsAggregateTool(server);\n registerSessionsExportTool(server);\n\n // Note: Functional Testing Support Tools are internal only, not exposed as MCP tools\n\n logger.info('Registered monitoring and reporting tools');\n}\n\n/**\n * Session Management Tools\n */\n\n// session_start tool removed - sessions are now auto-created when needed\n// Sessions are automatically created when MCP tools are called with queryPath\n// If explicit session creation is needed, provide sessionId=null and it will auto-create\n\nfunction registerSessionEndTool(server: McpServer): void {\n server.tool(\n 'session_end',\n 'End a query development session with final status',\n {\n sessionId: z.string().describe('ID of the session to end'),\n status: z.enum(['completed', 'failed', 'abandoned']).describe('Final status of the session'),\n },\n async ({ sessionId, status }) => {\n try {\n const session = await sessionDataManager.endSession(sessionId, status);\n \n if (!session) {\n return {\n content: [\n {\n type: 'text',\n text: `Session not found: ${sessionId}`,\n },\n ],\n isError: true,\n };\n }\n\n return {\n content: [\n {\n type: 'text',\n text: JSON.stringify(session, null, 2),\n },\n ],\n };\n } catch (error) {\n logger.error('Error ending session:', error);\n return {\n content: [\n {\n type: 'text',\n text: `Error ending session: ${error instanceof Error ? error.message : 'Unknown error'}`,\n },\n ],\n isError: true,\n };\n }\n }\n );\n}\n\nfunction registerSessionGetTool(server: McpServer): void {\n server.tool(\n 'session_get',\n 'Get complete details of a specific query development session',\n {\n sessionId: z.string().describe('ID of the session to retrieve'),\n },\n async ({ sessionId }) => {\n try {\n const session = await sessionDataManager.getSession(sessionId);\n \n if (!session) {\n return {\n content: [\n {\n type: 'text',\n text: `Session not found: ${sessionId}`,\n },\n ],\n isError: true,\n };\n }\n\n return {\n content: [\n {\n type: 'text',\n text: JSON.stringify(session, null, 2),\n },\n ],\n };\n } catch (error) {\n logger.error('Error getting session:', error);\n return {\n content: [\n {\n type: 'text',\n text: `Error getting session: ${error instanceof Error ? error.message : 'Unknown error'}`,\n },\n ],\n isError: true,\n };\n }\n }\n );\n}\n\nfunction registerSessionListTool(server: McpServer): void {\n server.tool(\n 'session_list',\n 'List query development sessions with optional filtering',\n {\n queryPath: z.string().optional().describe('Filter by query path (partial match)'),\n status: z.string().optional().describe('Filter by session status'),\n dateRange: z.array(z.string()).length(2).optional().describe('Filter by date range [start, end] (ISO timestamps)'),\n language: z.string().optional().describe('Filter by programming language'),\n queryType: z.string().optional().describe('Filter by query type'),\n },\n async ({ queryPath, status, dateRange, language, queryType }) => {\n try {\n const filters: SessionFilter = {};\n if (queryPath) filters.queryPath = queryPath;\n if (status) filters.status = status;\n if (dateRange) filters.dateRange = [dateRange[0], dateRange[1]];\n if (language) filters.language = language;\n if (queryType) filters.queryType = queryType;\n\n const sessions = await sessionDataManager.listSessions(\n Object.keys(filters).length > 0 ? filters : undefined\n );\n\n const sessionList = {\n totalSessions: sessions.length,\n sessions: sessions.map(s => ({\n sessionId: s.sessionId,\n queryPath: s.queryPath,\n language: s.language,\n status: s.status,\n startTime: s.startTime,\n endTime: s.endTime,\n mcpCallsCount: s.mcpCalls.length,\n testExecutionsCount: s.testExecutions.length,\n currentScore: s.qualityScores.length > 0 \n ? s.qualityScores[s.qualityScores.length - 1].overallScore \n : null,\n })),\n };\n\n return {\n content: [\n {\n type: 'text',\n text: JSON.stringify(sessionList, null, 2),\n },\n ],\n recommendations: generateListRecommendations(sessions),\n };\n } catch (error) {\n logger.error('Error listing sessions:', error);\n return {\n content: [\n {\n type: 'text',\n text: `Error listing sessions: ${error instanceof Error ? error.message : 'Unknown error'}`,\n },\n ],\n isError: true,\n };\n }\n }\n );\n}\n\nfunction registerSessionUpdateStateTool(server: McpServer): void {\n server.tool(\n 'session_update_state',\n 'Update the current state of a query development session',\n {\n sessionId: z.string().describe('ID of the session to update'),\n filesPresent: z.array(z.string()).optional().describe('List of files present in the query development'),\n compilationStatus: z.enum(['unknown', 'success', 'failed']).optional().describe('Current compilation status'),\n testStatus: z.enum(['unknown', 'passing', 'failing', 'no_tests']).optional().describe('Current test status'),\n documentationStatus: z.enum(['unknown', 'present', 'missing', 'incomplete']).optional().describe('Documentation status'),\n },\n async ({ sessionId, filesPresent, compilationStatus, testStatus, documentationStatus }) => {\n try {\n const stateUpdate: Record = {};\n if (filesPresent !== undefined) stateUpdate.filesPresent = filesPresent;\n if (compilationStatus !== undefined) stateUpdate.compilationStatus = compilationStatus;\n if (testStatus !== undefined) stateUpdate.testStatus = testStatus;\n if (documentationStatus !== undefined) stateUpdate.documentationStatus = documentationStatus;\n\n const session = await sessionDataManager.updateSessionState(sessionId, stateUpdate);\n \n if (!session) {\n return {\n content: [\n {\n type: 'text',\n text: `Session not found: ${sessionId}`,\n },\n ],\n isError: true,\n };\n }\n\n return {\n content: [\n {\n type: 'text',\n text: JSON.stringify(session, null, 2),\n },\n ],\n recommendations: generateRecommendations(session, 'session_update_state'),\n };\n } catch (error) {\n logger.error('Error updating session state:', error);\n return {\n content: [\n {\n type: 'text',\n text: `Error updating session state: ${error instanceof Error ? error.message : 'Unknown error'}`,\n },\n ],\n isError: true,\n };\n }\n }\n );\n}\n\n/**\n * Session Analytics Tools\n */\n\nfunction registerSessionGetCallHistoryTool(server: McpServer): void {\n server.tool(\n 'session_get_call_history',\n 'Get MCP call history for a specific session',\n {\n sessionId: z.string().describe('ID of the session'),\n limit: z.number().optional().describe('Maximum number of calls to return (most recent first)'),\n },\n async ({ sessionId, limit }) => {\n try {\n const session = await sessionDataManager.getSession(sessionId);\n \n if (!session) {\n return {\n content: [\n {\n type: 'text',\n text: `Session not found: ${sessionId}`,\n },\n ],\n isError: true,\n };\n }\n\n let calls = [...session.mcpCalls].reverse(); // Most recent first\n if (limit && limit > 0) {\n calls = calls.slice(0, limit);\n }\n\n return {\n content: [\n {\n type: 'text',\n text: JSON.stringify({\n sessionId,\n totalCalls: session.mcpCalls.length,\n callHistory: calls,\n }, null, 2),\n },\n ],\n };\n } catch (error) {\n logger.error('Error getting call history:', error);\n return {\n content: [\n {\n type: 'text',\n text: `Error getting call history: ${error instanceof Error ? error.message : 'Unknown error'}`,\n },\n ],\n isError: true,\n };\n }\n }\n );\n}\n\nfunction registerSessionGetTestHistoryTool(server: McpServer): void {\n server.tool(\n 'session_get_test_history',\n 'Get test execution history for a specific session',\n {\n sessionId: z.string().describe('ID of the session'),\n limit: z.number().optional().describe('Maximum number of test executions to return (most recent first)'),\n },\n async ({ sessionId, limit }) => {\n try {\n const session = await sessionDataManager.getSession(sessionId);\n \n if (!session) {\n return {\n content: [\n {\n type: 'text',\n text: `Session not found: ${sessionId}`,\n },\n ],\n isError: true,\n };\n }\n\n let tests = [...session.testExecutions].reverse(); // Most recent first\n if (limit && limit > 0) {\n tests = tests.slice(0, limit);\n }\n\n return {\n content: [\n {\n type: 'text',\n text: JSON.stringify({\n sessionId,\n totalTests: session.testExecutions.length,\n testHistory: tests,\n }, null, 2),\n },\n ],\n };\n } catch (error) {\n logger.error('Error getting test history:', error);\n return {\n content: [\n {\n type: 'text',\n text: `Error getting test history: ${error instanceof Error ? error.message : 'Unknown error'}`,\n },\n ],\n isError: true,\n };\n }\n }\n );\n}\n\nfunction registerSessionGetScoreHistoryTool(server: McpServer): void {\n server.tool(\n 'session_get_score_history',\n 'Get quality score history for a specific session',\n {\n sessionId: z.string().describe('ID of the session'),\n limit: z.number().optional().describe('Maximum number of scores to return (most recent first)'),\n },\n async ({ sessionId, limit }) => {\n try {\n const session = await sessionDataManager.getSession(sessionId);\n \n if (!session) {\n return {\n content: [\n {\n type: 'text',\n text: `Session not found: ${sessionId}`,\n },\n ],\n isError: true,\n };\n }\n\n let scores = [...session.qualityScores].reverse(); // Most recent first\n if (limit && limit > 0) {\n scores = scores.slice(0, limit);\n }\n\n return {\n content: [\n {\n type: 'text',\n text: JSON.stringify({\n sessionId,\n totalScores: session.qualityScores.length,\n scoreHistory: scores,\n }, null, 2),\n },\n ],\n };\n } catch (error) {\n logger.error('Error getting score history:', error);\n return {\n content: [\n {\n type: 'text',\n text: `Error getting score history: ${error instanceof Error ? error.message : 'Unknown error'}`,\n },\n ],\n isError: true,\n };\n }\n }\n );\n}\n\nfunction registerSessionCalculateCurrentScoreTool(server: McpServer): void {\n server.tool(\n 'session_calculate_current_score',\n 'Calculate current quality score for a session based on its state',\n {\n sessionId: z.string().describe('ID of the session'),\n },\n async ({ sessionId }) => {\n try {\n const session = await sessionDataManager.getSession(sessionId);\n \n if (!session) {\n return {\n content: [\n {\n type: 'text',\n text: `Session not found: ${sessionId}`,\n },\n ],\n isError: true,\n };\n }\n\n // Calculate quality score based on current state\n const scoreRecord = calculateQualityScore(session);\n \n // Add the score to the session\n await sessionDataManager.addQualityScore(sessionId, scoreRecord);\n \n // Get updated session with new score\n const updatedSession = await sessionDataManager.getSession(sessionId);\n\n return {\n content: [\n {\n type: 'text',\n text: JSON.stringify(scoreRecord, null, 2),\n },\n ],\n recommendations: generateRecommendations(updatedSession, 'session_calculate_current_score'),\n };\n } catch (error) {\n logger.error('Error calculating current score:', error);\n return {\n content: [\n {\n type: 'text',\n text: `Error calculating current score: ${error instanceof Error ? error.message : 'Unknown error'}`,\n },\n ],\n isError: true,\n };\n }\n }\n );\n}\n\n/**\n * Batch Operations Tools\n */\n\nfunction registerSessionsCompareTool(server: McpServer): void {\n server.tool(\n 'sessions_compare',\n 'Compare multiple query development sessions across specified dimensions',\n {\n sessionIds: z.array(z.string()).describe('Array of session IDs to compare'),\n dimensions: z.array(z.string()).optional().describe('Specific dimensions to compare (default: all)'),\n },\n async ({ sessionIds, dimensions }) => {\n try {\n const sessions = await Promise.all(\n sessionIds.map(id => sessionDataManager.getSession(id))\n );\n\n const validSessions = sessions.filter(s => s !== null) as QueryDevelopmentSession[];\n \n if (validSessions.length === 0) {\n return {\n content: [\n {\n type: 'text',\n text: 'No valid sessions found for comparison',\n },\n ],\n isError: true,\n };\n }\n\n const comparison = await compareSessions(validSessions, dimensions);\n\n return {\n content: [\n {\n type: 'text',\n text: JSON.stringify(comparison, null, 2),\n },\n ],\n };\n } catch (error) {\n logger.error('Error comparing sessions:', error);\n return {\n content: [\n {\n type: 'text',\n text: `Error comparing sessions: ${error instanceof Error ? error.message : 'Unknown error'}`,\n },\n ],\n isError: true,\n };\n }\n }\n );\n}\n\nfunction registerSessionsAggregateTool(server: McpServer): void {\n server.tool(\n 'sessions_aggregate',\n 'Generate aggregate insights from multiple sessions based on filters',\n {\n queryPath: z.string().optional().describe('Filter by query path (partial match)'),\n status: z.string().optional().describe('Filter by session status'),\n dateRange: z.array(z.string()).length(2).optional().describe('Filter by date range [start, end] (ISO timestamps)'),\n language: z.string().optional().describe('Filter by programming language'),\n queryType: z.string().optional().describe('Filter by query type'),\n },\n async ({ queryPath, status, dateRange, language, queryType }) => {\n try {\n const filters: SessionFilter = {};\n if (queryPath) filters.queryPath = queryPath;\n if (status) filters.status = status;\n if (dateRange) filters.dateRange = [dateRange[0], dateRange[1]];\n if (language) filters.language = language;\n if (queryType) filters.queryType = queryType;\n\n const sessions = await sessionDataManager.listSessions(\n Object.keys(filters).length > 0 ? filters : undefined\n );\n\n const aggregate = await aggregateSessions(sessions, filters);\n\n return {\n content: [\n {\n type: 'text',\n text: JSON.stringify(aggregate, null, 2),\n },\n ],\n };\n } catch (error) {\n logger.error('Error aggregating sessions:', error);\n return {\n content: [\n {\n type: 'text',\n text: `Error aggregating sessions: ${error instanceof Error ? error.message : 'Unknown error'}`,\n },\n ],\n isError: true,\n };\n }\n }\n );\n}\n\nfunction registerSessionsExportTool(server: McpServer): void {\n server.tool(\n 'sessions_export',\n 'Export session data in specified format for external analysis',\n {\n sessionIds: z.array(z.string()).describe('Array of session IDs to export'),\n format: z.enum(['json', 'html', 'markdown']).optional().default('json').describe('Export format'),\n },\n async ({ sessionIds, format = 'json' }) => {\n try {\n const sessions = await Promise.all(\n sessionIds.map(id => sessionDataManager.getSession(id))\n );\n\n const validSessions = sessions.filter(s => s !== null) as QueryDevelopmentSession[];\n \n if (validSessions.length === 0) {\n return {\n content: [\n {\n type: 'text',\n text: 'No valid sessions found for export',\n },\n ],\n isError: true,\n };\n }\n\n const exportResult = await exportSessions(validSessions, format);\n\n return {\n content: [\n {\n type: 'text',\n text: JSON.stringify(exportResult, null, 2),\n },\n ],\n };\n } catch (error) {\n logger.error('Error exporting sessions:', error);\n return {\n content: [\n {\n type: 'text',\n text: `Error exporting sessions: ${error instanceof Error ? error.message : 'Unknown error'}`,\n },\n ],\n isError: true,\n };\n }\n }\n );\n}\n\n/**\n * Helper Functions\n */\n\n/**\n * Calculate quality score for a session based on current state and history\n */\nfunction calculateQualityScore(session: QueryDevelopmentSession): QualityScoreRecord {\n const timestamp = new Date().toISOString();\n \n // Calculate syntactic correctness (25%)\n const syntacticCorrectness = session.currentState.compilationStatus === 'success' ? 100 :\n session.currentState.compilationStatus === 'failed' ? 0 : 50;\n\n // Calculate test coverage and results (30%)\n const testCoverageResults = session.currentState.testStatus === 'passing' ? 100 :\n session.currentState.testStatus === 'failing' ? 25 :\n session.currentState.testStatus === 'no_tests' ? 0 : 50;\n\n // Calculate documentation quality (20%)\n const documentationQuality = session.currentState.documentationStatus === 'present' ? 100 :\n session.currentState.documentationStatus === 'incomplete' ? 60 :\n session.currentState.documentationStatus === 'missing' ? 0 : 50;\n\n // Calculate functional correctness (25%) - based on successful test runs\n const successfulTests = session.testExecutions.filter(t => t.success && t.type === 'test_run').length;\n const totalTests = session.testExecutions.filter(t => t.type === 'test_run').length;\n const functionalCorrectness = totalTests > 0 ? (successfulTests / totalTests) * 100 : 50;\n\n // Calculate overall score\n const overallScore = Math.round(\n (syntacticCorrectness * 0.25) +\n (testCoverageResults * 0.30) +\n (documentationQuality * 0.20) +\n (functionalCorrectness * 0.25)\n );\n\n // Determine grade\n const grade = overallScore >= 90 ? 'A' :\n overallScore >= 80 ? 'B' :\n overallScore >= 70 ? 'C' :\n overallScore >= 60 ? 'D' : 'F';\n\n // Generate recommendations\n const recommendations: string[] = [];\n if (syntacticCorrectness < 100) {\n recommendations.push('Fix compilation errors to improve syntactic correctness');\n }\n if (testCoverageResults < 70) {\n recommendations.push('Add comprehensive tests and ensure they pass');\n }\n if (documentationQuality < 80) {\n recommendations.push('Add or improve query documentation with examples');\n }\n if (functionalCorrectness < 80) {\n recommendations.push('Improve test pass rate and verify query logic');\n }\n\n return {\n scoreId: randomUUID(),\n timestamp,\n overallScore,\n dimensions: {\n syntacticCorrectness,\n testCoverageResults,\n documentationQuality,\n functionalCorrectness,\n },\n grade,\n recommendations,\n };\n}\n\n/**\n * Compare multiple sessions\n */\nasync function compareSessions(\n sessions: QueryDevelopmentSession[],\n dimensions?: string[]\n): Promise {\n const timestamp = new Date().toISOString();\n const sessionIds = sessions.map(s => s.sessionId);\n \n const results: Record = {\n sessionCount: sessions.length,\n sessionOverview: sessions.map(s => ({\n sessionId: s.sessionId,\n queryPath: s.queryPath,\n status: s.status,\n mcpCallsCount: s.mcpCalls.length,\n duration: s.endTime ? \n new Date(s.endTime).getTime() - new Date(s.startTime).getTime() : \n new Date().getTime() - new Date(s.startTime).getTime(),\n currentScore: s.qualityScores.length > 0 ? \n s.qualityScores[s.qualityScores.length - 1].overallScore : null,\n })),\n };\n\n if (!dimensions || dimensions.includes('quality')) {\n const qualityScores = sessions.map(s => \n s.qualityScores.length > 0 ? s.qualityScores[s.qualityScores.length - 1] : null\n );\n results.qualityComparison = {\n averageScore: qualityScores\n .filter(q => q !== null)\n .reduce((sum, q) => sum + q!.overallScore, 0) / qualityScores.filter(q => q !== null).length,\n scoreRange: {\n min: Math.min(...qualityScores.filter(q => q !== null).map(q => q!.overallScore)),\n max: Math.max(...qualityScores.filter(q => q !== null).map(q => q!.overallScore)),\n },\n };\n }\n\n if (!dimensions || dimensions.includes('activity')) {\n results.activityComparison = {\n totalMCPCalls: sessions.reduce((sum, s) => sum + s.mcpCalls.length, 0),\n averageCallsPerSession: sessions.reduce((sum, s) => sum + s.mcpCalls.length, 0) / sessions.length,\n mostActiveTool: getMostUsedTool(sessions),\n };\n }\n\n return {\n sessionIds,\n dimensions: dimensions || ['all'],\n timestamp,\n results,\n };\n}\n\n/**\n * Aggregate insights from multiple sessions\n */\nasync function aggregateSessions(\n sessions: QueryDevelopmentSession[],\n filters: SessionFilter\n): Promise {\n const timestamp = new Date().toISOString();\n \n const completedSessions = sessions.filter(s => s.status === 'completed');\n const successRate = sessions.length > 0 ? completedSessions.length / sessions.length : 0;\n \n const qualityScores = sessions\n .map(s => s.qualityScores.length > 0 ? s.qualityScores[s.qualityScores.length - 1].overallScore : null)\n .filter(score => score !== null) as number[];\n \n const averageQualityScore = qualityScores.length > 0 ? \n qualityScores.reduce((sum, score) => sum + score, 0) / qualityScores.length : 0;\n\n const commonPatterns = identifyCommonPatterns(sessions);\n const recommendations = generateAggregateRecommendations(sessions);\n\n return {\n filters,\n timestamp,\n totalSessions: sessions.length,\n successRate,\n averageQualityScore,\n commonPatterns,\n recommendations,\n };\n}\n\n/**\n * Export sessions in specified format\n */\nasync function exportSessions(\n sessions: QueryDevelopmentSession[],\n format: 'json' | 'html' | 'markdown'\n): Promise {\n const timestamp = new Date().toISOString();\n const filename = `session-export-${timestamp.replace(/[:.]/g, '-')}.${format}`;\n \n let content: string;\n \n switch (format) {\n case 'json':\n content = JSON.stringify(sessions, null, 2);\n break;\n case 'html':\n content = generateHTMLReport(sessions);\n break;\n case 'markdown':\n content = generateMarkdownReport(sessions);\n break;\n }\n\n return {\n format,\n filename,\n content,\n timestamp,\n };\n}\n\n/**\n * Utility functions\n */\n\nfunction getMostUsedTool(sessions: QueryDevelopmentSession[]): string {\n const toolCounts: Record = {};\n \n sessions.forEach(session => {\n session.mcpCalls.forEach(call => {\n toolCounts[call.toolName] = (toolCounts[call.toolName] || 0) + 1;\n });\n });\n\n return Object.entries(toolCounts)\n .sort(([, a], [, b]) => b - a)[0]?.[0] || 'none';\n}\n\nfunction identifyCommonPatterns(sessions: QueryDevelopmentSession[]): string[] {\n const patterns: string[] = [];\n \n const commonTools = getMostUsedTool(sessions);\n if (commonTools && commonTools !== 'none') {\n patterns.push(`Most commonly used tool: ${commonTools}`);\n }\n\n const completionRate = sessions.filter(s => s.status === 'completed').length / sessions.length;\n if (completionRate > 0.8) {\n patterns.push('High completion rate indicates effective workflow');\n } else if (completionRate < 0.5) {\n patterns.push('Low completion rate suggests workflow issues');\n }\n\n return patterns;\n}\n\nfunction generateAggregateRecommendations(sessions: QueryDevelopmentSession[]): string[] {\n const recommendations: string[] = [];\n \n const failedSessions = sessions.filter(s => s.status === 'failed');\n if (failedSessions.length > sessions.length * 0.3) {\n recommendations.push('High failure rate - consider improving error handling and guidance');\n }\n\n const averageCallsPerSession = sessions.reduce((sum, s) => sum + s.mcpCalls.length, 0) / sessions.length;\n if (averageCallsPerSession > 20) {\n recommendations.push('High number of MCP calls per session - consider workflow optimization');\n }\n\n return recommendations;\n}\n\nfunction generateHTMLReport(sessions: QueryDevelopmentSession[]): string {\n const html = `\n\n\n\n Session Export Report\n \n\n\n

Query Development Sessions Report

\n

Generated: ${new Date().toISOString()}

\n

Total Sessions: ${sessions.length}

\n \n ${sessions.map(session => `\n
\n

Session: ${session.sessionId}

\n

Query Path: ${session.queryPath}

\n

Status: ${session.status}

\n

Language: ${session.language}

\n

Start Time: ${session.startTime}

\n

MCP Calls: ${session.mcpCalls.length}

\n

Test Executions: ${session.testExecutions.length}

\n

Quality Scores: ${session.qualityScores.length}

\n
\n `).join('')}\n\n`;\n \n return html;\n}\n\nfunction generateMarkdownReport(sessions: QueryDevelopmentSession[]): string {\n const md = `# Query Development Sessions Report\n\nGenerated: ${new Date().toISOString()}\nTotal Sessions: ${sessions.length}\n\n## Session Summary\n\n| Session ID | Query Path | Status | Language | MCP Calls | Test Executions |\n|------------|-----------|--------|----------|-----------|-----------------|\n${sessions.map(session => \n `| ${session.sessionId} | ${session.queryPath} | ${session.status} | ${session.language} | ${session.mcpCalls.length} | ${session.testExecutions.length} |`\n).join('\\n')}\n\n## Detailed Sessions\n\n${sessions.map(session => `\n### Session: ${session.sessionId}\n\n- **Query Path:** ${session.queryPath}\n- **Status:** ${session.status}\n- **Language:** ${session.language}\n- **Start Time:** ${session.startTime}\n- **End Time:** ${session.endTime || 'N/A'}\n- **MCP Calls:** ${session.mcpCalls.length}\n- **Test Executions:** ${session.testExecutions.length}\n- **Quality Scores:** ${session.qualityScores.length}\n\n${session.recommendations.length > 0 ? `\n**Current Recommendations:**\n${session.recommendations.map(rec => `- ${rec}`).join('\\n')}\n` : ''}\n`).join('\\n')}`;\n\n return md;\n}\n\nfunction _calculateAverageDuration(sessions: QueryDevelopmentSession[]): number {\n const completedSessions = sessions.filter(s => s.endTime);\n if (completedSessions.length === 0) return 0;\n\n const totalDuration = completedSessions.reduce((sum, session) => {\n return sum + (new Date(session.endTime!).getTime() - new Date(session.startTime).getTime());\n }, 0);\n\n return totalDuration / completedSessions.length;\n}\n\nfunction _identifyFailureReasons(results: FunctionalTestResult[]): string[] {\n const failedResults = results.filter(r => !r.passed);\n const reasons: Record = {};\n\n failedResults.forEach(result => {\n Object.entries(result.criteria).forEach(([criterion, passed]) => {\n if (!passed) {\n reasons[criterion] = (reasons[criterion] || 0) + 1;\n }\n });\n });\n\n return Object.entries(reasons)\n .sort(([, a], [, b]) => b - a)\n .map(([reason, count]) => `${reason}: ${count} sessions`);\n}\n\n/**\n * Generate recommendations for MCP tool responses\n * Returns a map of MCP primitive paths to recommendation reasons\n */\nfunction generateRecommendations(\n session: QueryDevelopmentSession | null,\n currentTool: string\n): Record {\n if (!session) {\n return {};\n }\n\n const recommendations: Record = {};\n\n // Session state-based recommendations\n if (session.currentState.compilationStatus === 'failed') {\n recommendations['codeql_query_format'] = 'Format query to fix potential syntax issues';\n recommendations['codeql_query_compile'] = 'Recompile after fixing syntax errors';\n } else if (session.currentState.compilationStatus === 'success') {\n if (session.currentState.testStatus === 'unknown' || session.currentState.testStatus === 'no_tests') {\n recommendations['codeql_test_run'] = 'Run tests to validate query functionality';\n } else if (session.currentState.testStatus === 'failing') {\n recommendations['session_get_test_history'] = 'Review test failures to identify issues';\n recommendations['codeql_query_compile'] = 'Verify query logic matches test expectations';\n } else if (session.currentState.testStatus === 'passing') {\n recommendations['session_calculate_current_score'] = 'Calculate quality score for completed query';\n }\n }\n\n // Tool-specific follow-up recommendations\n switch (currentTool) {\n case 'session_get':\n if (session.mcpCalls.length === 0) {\n recommendations['codeql_query_compile'] = 'Start development by compiling the query';\n }\n break;\n case 'session_end':\n if (session.status === 'completed') {\n recommendations['sessions_export'] = 'Export session data for analysis';\n }\n break;\n case 'session_calculate_current_score': {\n const latestScore = session.qualityScores[session.qualityScores.length - 1];\n if (latestScore && latestScore.overallScore < 80) {\n if (latestScore.dimensions.syntacticCorrectness < 100) {\n recommendations['codeql_query_format'] = 'Improve syntax and formatting';\n }\n if (latestScore.dimensions.testCoverageResults < 70) {\n recommendations['codeql_test_run'] = 'Improve test coverage and results';\n }\n }\n break;\n }\n case 'session_update_state':\n // Recommend next logical step based on updated state\n if (session.currentState.compilationStatus === 'success' && session.currentState.testStatus === 'unknown') {\n recommendations['codeql_test_run'] = 'Run tests now that compilation is successful';\n }\n break;\n }\n\n return recommendations;\n}\n\n/**\n * Generate recommendations for session list results\n */\nfunction generateListRecommendations(sessions: QueryDevelopmentSession[]): Record {\n const recommendations: Record = {};\n\n const activeSessions = sessions.filter(s => s.status === 'active');\n const completedSessions = sessions.filter(s => s.status === 'completed');\n\n if (activeSessions.length > 0) {\n recommendations['session_get'] = `Review details of ${activeSessions.length} active session(s)`;\n }\n\n if (completedSessions.length > 1) {\n recommendations['sessions_compare'] = 'Compare completed sessions to identify patterns';\n recommendations['sessions_aggregate'] = 'Generate aggregate insights from multiple sessions';\n }\n\n if (sessions.length > 5) {\n recommendations['sessions_export'] = 'Export session data for comprehensive analysis';\n }\n\n return recommendations;\n}", "function checkArgs(adapter, defaultData) {\n if (adapter === undefined)\n throw new Error('lowdb: missing adapter');\n if (defaultData === undefined)\n throw new Error('lowdb: missing default data');\n}\nexport class Low {\n adapter;\n data;\n constructor(adapter, defaultData) {\n checkArgs(adapter, defaultData);\n this.adapter = adapter;\n this.data = defaultData;\n }\n async read() {\n const data = await this.adapter.read();\n if (data)\n this.data = data;\n }\n async write() {\n if (this.data)\n await this.adapter.write(this.data);\n }\n async update(fn) {\n fn(this.data);\n await this.write();\n }\n}\nexport class LowSync {\n adapter;\n data;\n constructor(adapter, defaultData) {\n checkArgs(adapter, defaultData);\n this.adapter = adapter;\n this.data = defaultData;\n }\n read() {\n const data = this.adapter.read();\n if (data)\n this.data = data;\n }\n write() {\n if (this.data)\n this.adapter.write(this.data);\n }\n update(fn) {\n fn(this.data);\n this.write();\n }\n}\n", "import { readFileSync, renameSync, writeFileSync } from 'node:fs';\nimport { readFile } from 'node:fs/promises';\nimport path from 'node:path';\nimport { Writer } from 'steno';\nexport class TextFile {\n #filename;\n #writer;\n constructor(filename) {\n this.#filename = filename;\n this.#writer = new Writer(filename);\n }\n async read() {\n let data;\n try {\n data = await readFile(this.#filename, 'utf-8');\n }\n catch (e) {\n if (e.code === 'ENOENT') {\n return null;\n }\n throw e;\n }\n return data;\n }\n write(str) {\n return this.#writer.write(str);\n }\n}\nexport class TextFileSync {\n #tempFilename;\n #filename;\n constructor(filename) {\n this.#filename = filename;\n const f = filename.toString();\n this.#tempFilename = path.join(path.dirname(f), `.${path.basename(f)}.tmp`);\n }\n read() {\n let data;\n try {\n data = readFileSync(this.#filename, 'utf-8');\n }\n catch (e) {\n if (e.code === 'ENOENT') {\n return null;\n }\n throw e;\n }\n return data;\n }\n write(str) {\n writeFileSync(this.#tempFilename, str);\n renameSync(this.#tempFilename, this.#filename);\n }\n}\n", "import { TextFile, TextFileSync } from './TextFile.js';\nexport class DataFile {\n #adapter;\n #parse;\n #stringify;\n constructor(filename, { parse, stringify, }) {\n this.#adapter = new TextFile(filename);\n this.#parse = parse;\n this.#stringify = stringify;\n }\n async read() {\n const data = await this.#adapter.read();\n if (data === null) {\n return null;\n }\n else {\n return this.#parse(data);\n }\n }\n write(obj) {\n return this.#adapter.write(this.#stringify(obj));\n }\n}\nexport class DataFileSync {\n #adapter;\n #parse;\n #stringify;\n constructor(filename, { parse, stringify, }) {\n this.#adapter = new TextFileSync(filename);\n this.#parse = parse;\n this.#stringify = stringify;\n }\n read() {\n const data = this.#adapter.read();\n if (data === null) {\n return null;\n }\n else {\n return this.#parse(data);\n }\n }\n write(obj) {\n this.#adapter.write(this.#stringify(obj));\n }\n}\n", "import { DataFile, DataFileSync } from './DataFile.js';\nexport class JSONFile extends DataFile {\n constructor(filename) {\n super(filename, {\n parse: JSON.parse,\n stringify: (data) => JSON.stringify(data, null, 2),\n });\n }\n}\nexport class JSONFileSync extends DataFileSync {\n constructor(filename) {\n super(filename, {\n parse: JSON.parse,\n stringify: (data) => JSON.stringify(data, null, 2),\n });\n }\n}\n", "/**\n * Session Data Management\n * Provides unified JSON storage and session lifecycle management using lowdb\n */\n\nimport { Low } from 'lowdb';\nimport { JSONFileSync } from 'lowdb/node';\nimport { mkdirSync, writeFileSync } from 'fs';\nimport { join } from 'path';\nimport { randomUUID } from 'crypto';\nimport { getProjectTmpBase } from '../utils/temp-dir';\nimport {\n QueryDevelopmentSession,\n QueryState,\n MCPCallRecord,\n TestExecutionRecord,\n QualityScoreRecord,\n SessionFilter,\n MonitoringConfig,\n MonitoringConfigSchema,\n} from '../types/monitoring';\nimport { logger } from '../utils/logger';\n\n/**\n * Database schema for lowdb - sessions only\n */\ninterface SessionDatabase {\n sessions: QueryDevelopmentSession[];\n}\n\n/**\n * Session Data Manager - handles all session persistence and lifecycle\n */\nexport class SessionDataManager {\n private db: Low;\n private config: MonitoringConfig;\n private storageDir: string;\n\n constructor(configOverrides: Partial = {}) {\n this.config = MonitoringConfigSchema.parse({\n ...MonitoringConfigSchema.parse({}),\n ...configOverrides,\n });\n\n this.storageDir = this.config.storageLocation;\n this.ensureStorageDirectory();\n\n const adapter = new JSONFileSync(join(this.storageDir, 'sessions.json'));\n this.db = new Low(adapter, {\n sessions: [],\n });\n\n this.initializeDatabase();\n }\n\n /**\n * Initialize the database and ensure it's properly set up\n */\n async initialize(): Promise {\n await this.initializeDatabase();\n }\n\n /**\n * Initialize the database and ensure it's properly set up\n */\n private async initializeDatabase(): Promise {\n try {\n await this.db.read();\n \n logger.info(`Session data manager initialized with ${this.db.data.sessions.length} sessions`);\n } catch (error) {\n logger.error('Failed to initialize session database:', error);\n throw error;\n }\n }\n\n /**\n * Ensure storage directory structure exists\n */\n private ensureStorageDirectory(): void {\n try {\n // mkdirSync with recursive: true is a no-op if directories already exist\n mkdirSync(this.storageDir, { recursive: true });\n\n // Create subdirectories\n const subdirs = ['sessions-archive', 'exports'];\n for (const subdir of subdirs) {\n mkdirSync(join(this.storageDir, subdir), { recursive: true });\n }\n\n // Use 'wx' flag (exclusive create) to atomically create config only\n // if it doesn't exist, avoiding TOCTOU race (CWE-367).\n const configPath = join(this.storageDir, 'config.json');\n try {\n writeFileSync(configPath, JSON.stringify(this.config, null, 2), { flag: 'wx' });\n } catch (e: unknown) {\n const err = e as { code?: string };\n if (err.code !== 'EEXIST') throw e;\n }\n\n logger.debug(`Storage directory initialized: ${this.storageDir}`);\n } catch (error) {\n logger.error('Failed to create storage directory:', error);\n throw error;\n }\n }\n\n /**\n * Start a new query development session\n */\n async startSession(\n queryPath: string,\n language?: string,\n queryType?: string,\n description?: string\n ): Promise {\n const sessionId = randomUUID();\n const startTime = new Date().toISOString();\n\n const session: QueryDevelopmentSession = {\n sessionId,\n queryPath,\n language: language || 'unknown',\n queryType,\n description,\n startTime,\n status: 'active',\n mcpCalls: [],\n testExecutions: [],\n qualityScores: [],\n currentState: {\n filesPresent: [],\n compilationStatus: 'unknown',\n testStatus: 'unknown',\n documentationStatus: 'unknown',\n lastActivity: startTime,\n },\n recommendations: [],\n };\n\n await this.db.read();\n this.db.data.sessions.push(session);\n await this.db.write();\n\n logger.info(`Started new session: ${sessionId} for query: ${queryPath}`);\n return sessionId;\n }\n\n /**\n * End a session with final status\n */\n async endSession(\n sessionId: string,\n status: 'completed' | 'failed' | 'abandoned'\n ): Promise {\n await this.db.read();\n \n const session = this.db.data.sessions.find(s => s.sessionId === sessionId);\n if (!session) {\n logger.warn(`Session not found: ${sessionId}`);\n return null;\n }\n\n session.status = status;\n session.endTime = new Date().toISOString();\n session.currentState.lastActivity = session.endTime;\n\n await this.db.write();\n\n // Archive completed session if enabled\n if (this.config.archiveCompletedSessions && status === 'completed') {\n await this.archiveSession(sessionId);\n }\n\n logger.info(`Ended session: ${sessionId} with status: ${status}`);\n return session;\n }\n\n /**\n * Get a specific session by ID\n */\n async getSession(sessionId: string): Promise {\n await this.db.read();\n const session = this.db.data.sessions.find(s => s.sessionId === sessionId);\n return session || null;\n }\n\n /**\n * List sessions with optional filtering\n */\n async listSessions(filters?: SessionFilter): Promise {\n await this.db.read();\n let sessions = [...this.db.data.sessions];\n\n if (filters) {\n if (filters.queryPath) {\n sessions = sessions.filter(s => s.queryPath.includes(filters.queryPath!));\n }\n if (filters.status) {\n sessions = sessions.filter(s => s.status === filters.status);\n }\n if (filters.language) {\n sessions = sessions.filter(s => s.language === filters.language);\n }\n if (filters.queryType) {\n sessions = sessions.filter(s => s.queryType === filters.queryType);\n }\n if (filters.dateRange) {\n const [start, end] = filters.dateRange;\n sessions = sessions.filter(s => \n s.startTime >= start && s.startTime <= end\n );\n }\n }\n\n return sessions;\n }\n\n /**\n * Update session state\n */\n async updateSessionState(\n sessionId: string,\n stateUpdate: Partial\n ): Promise {\n await this.db.read();\n \n const session = this.db.data.sessions.find(s => s.sessionId === sessionId);\n if (!session) {\n logger.warn(`Session not found: ${sessionId}`);\n return null;\n }\n\n session.currentState = {\n ...session.currentState,\n ...stateUpdate,\n lastActivity: new Date().toISOString(),\n };\n\n await this.db.write();\n return session;\n }\n\n /**\n * Add MCP call record to session\n */\n async addMCPCall(sessionId: string, callRecord: MCPCallRecord): Promise {\n await this.db.read();\n \n const session = this.db.data.sessions.find(s => s.sessionId === sessionId);\n if (!session) {\n logger.warn(`Session not found for MCP call: ${sessionId}`);\n return;\n }\n\n session.mcpCalls.push(callRecord);\n session.currentState.lastActivity = callRecord.timestamp;\n\n // Update next suggested tool if provided\n if (callRecord.nextSuggestedTool) {\n session.nextSuggestedTool = callRecord.nextSuggestedTool;\n }\n\n await this.db.write();\n }\n\n /**\n * Add test execution record to session\n */\n async addTestExecution(sessionId: string, testRecord: TestExecutionRecord): Promise {\n await this.db.read();\n \n const session = this.db.data.sessions.find(s => s.sessionId === sessionId);\n if (!session) {\n logger.warn(`Session not found for test execution: ${sessionId}`);\n return;\n }\n\n session.testExecutions.push(testRecord);\n session.currentState.lastActivity = testRecord.timestamp;\n\n // Update compilation/test status based on execution\n if (testRecord.type === 'compilation') {\n session.currentState.compilationStatus = testRecord.success ? 'success' : 'failed';\n } else if (testRecord.type === 'test_run') {\n session.currentState.testStatus = testRecord.success ? 'passing' : 'failing';\n }\n\n await this.db.write();\n }\n\n /**\n * Add quality score record to session\n */\n async addQualityScore(sessionId: string, scoreRecord: QualityScoreRecord): Promise {\n await this.db.read();\n \n const session = this.db.data.sessions.find(s => s.sessionId === sessionId);\n if (!session) {\n logger.warn(`Session not found for quality score: ${sessionId}`);\n return;\n }\n\n session.qualityScores.push(scoreRecord);\n session.currentState.lastActivity = scoreRecord.timestamp;\n session.recommendations = scoreRecord.recommendations;\n\n await this.db.write();\n }\n\n /**\n * Archive a completed session to monthly file\n */\n private async archiveSession(sessionId: string): Promise {\n try {\n const session = await this.getSession(sessionId);\n if (!session) return;\n\n const date = new Date(session.endTime || session.startTime);\n const monthDir = `${date.getFullYear()}-${String(date.getMonth() + 1).padStart(2, '0')}`;\n const archiveDir = join(this.storageDir, 'sessions-archive', monthDir);\n\n mkdirSync(archiveDir, { recursive: true });\n\n const archiveFile = join(archiveDir, `${sessionId}.json`);\n writeFileSync(archiveFile, JSON.stringify(session, null, 2));\n\n // Remove from active sessions\n await this.db.read();\n this.db.data.sessions = this.db.data.sessions.filter(s => s.sessionId !== sessionId);\n await this.db.write();\n\n logger.info(`Archived session: ${sessionId} to ${archiveFile}`);\n } catch (error) {\n logger.error(`Failed to archive session ${sessionId}:`, error);\n }\n }\n\n /**\n * Get active sessions for a specific query path\n */\n async getActiveSessionsForQuery(queryPath: string): Promise {\n await this.db.read();\n return this.db.data.sessions.filter(s => \n s.queryPath === queryPath && s.status === 'active'\n );\n }\n\n /**\n * Clean up old sessions based on retention policy\n */\n async cleanupOldSessions(): Promise {\n const cutoffDate = new Date();\n cutoffDate.setDate(cutoffDate.getDate() - this.config.retentionDays);\n const cutoffTimestamp = cutoffDate.toISOString();\n\n await this.db.read();\n const sessionsToRemove = this.db.data.sessions.filter(s => \n s.endTime && s.endTime < cutoffTimestamp\n );\n\n if (sessionsToRemove.length > 0) {\n this.db.data.sessions = this.db.data.sessions.filter(s => \n !s.endTime || s.endTime >= cutoffTimestamp\n );\n await this.db.write();\n\n logger.info(`Cleaned up ${sessionsToRemove.length} old sessions`);\n }\n }\n\n /**\n * Get configuration\n */\n getConfig(): MonitoringConfig {\n return this.config;\n }\n\n /**\n * Update configuration\n */\n async updateConfig(configUpdate: Partial): Promise {\n this.config = MonitoringConfigSchema.parse({\n ...this.config,\n ...configUpdate,\n });\n\n // Update config.json file only\n const configPath = join(this.storageDir, 'config.json');\n writeFileSync(configPath, JSON.stringify(this.config, null, 2));\n\n logger.info('Updated monitoring configuration');\n }\n}\n\n/**\n * Parse boolean environment variable\n */\nfunction parseBoolEnv(envVar: string | undefined, defaultValue: boolean): boolean {\n if (envVar === undefined) return defaultValue;\n return envVar.toLowerCase() === 'true' || envVar === '1';\n}\n\n// Export singleton instance with environment variable support\nexport const sessionDataManager = new SessionDataManager({\n storageLocation: process.env.MONITORING_STORAGE_LOCATION || join(getProjectTmpBase(), '.ql-mcp-tracking'),\n enableMonitoringTools: parseBoolEnv(process.env.ENABLE_MONITORING_TOOLS, false),\n});", "import { z } from 'zod';\n\n/**\n * Monitoring and Reporting types for CodeQL Development MCP Server\n * Based on the specification in docs/mcp-server-monitoring-and-reporting.md\n */\n\n/**\n * MCP Call Record - captures individual MCP tool calls\n */\nexport const MCPCallRecordSchema = z.object({\n callId: z.string(),\n timestamp: z.string(), // ISO timestamp\n toolName: z.string(),\n parameters: z.record(z.any()),\n result: z.any(),\n success: z.boolean(),\n duration: z.number(), // milliseconds\n nextSuggestedTool: z.string().optional(),\n});\n\nexport type MCPCallRecord = z.infer;\n\n/**\n * Test Execution Record - captures query compilation and test runs\n */\nexport const TestExecutionRecordSchema = z.object({\n executionId: z.string(),\n timestamp: z.string(),\n type: z.enum(['compilation', 'test_run', 'database_build']),\n success: z.boolean(),\n details: z.record(z.any()),\n metrics: z.object({\n passRate: z.number().optional(),\n coverage: z.number().optional(),\n performance: z.number().optional(),\n }).optional(),\n});\n\nexport type TestExecutionRecord = z.infer;\n\n/**\n * Quality Score Record - multi-dimensional quality assessment\n */\nexport const QualityScoreRecordSchema = z.object({\n scoreId: z.string(),\n timestamp: z.string(),\n overallScore: z.number().min(0).max(100), // 0-100\n dimensions: z.object({\n syntacticCorrectness: z.number().min(0).max(100),\n testCoverageResults: z.number().min(0).max(100),\n documentationQuality: z.number().min(0).max(100),\n functionalCorrectness: z.number().min(0).max(100),\n }),\n grade: z.enum(['A', 'B', 'C', 'D', 'F']),\n recommendations: z.array(z.string()),\n});\n\nexport type QualityScoreRecord = z.infer;\n\n/**\n * Query State - current state of the query development\n */\nexport const QueryStateSchema = z.object({\n filesPresent: z.array(z.string()),\n compilationStatus: z.enum(['unknown', 'success', 'failed']),\n testStatus: z.enum(['unknown', 'passing', 'failing', 'no_tests']),\n documentationStatus: z.enum(['unknown', 'present', 'missing', 'incomplete']),\n lastActivity: z.string(), // ISO timestamp\n});\n\nexport type QueryState = z.infer;\n\n/**\n * Query Development Session - main data structure for tracking\n */\nexport const QueryDevelopmentSessionSchema = z.object({\n // Session Metadata\n sessionId: z.string(),\n queryPath: z.string(),\n language: z.string(),\n queryType: z.string().optional(),\n description: z.string().optional(),\n startTime: z.string(), // ISO timestamp\n endTime: z.string().optional(), // ISO timestamp\n status: z.enum(['active', 'completed', 'failed', 'abandoned']),\n\n // MCP Call History\n mcpCalls: z.array(MCPCallRecordSchema),\n\n // Test Execution Records\n testExecutions: z.array(TestExecutionRecordSchema),\n\n // Quality Metrics\n qualityScores: z.array(QualityScoreRecordSchema),\n\n // Development State\n currentState: QueryStateSchema,\n recommendations: z.array(z.string()),\n nextSuggestedTool: z.string().optional(),\n});\n\nexport type QueryDevelopmentSession = z.infer;\n\n/**\n * Session Filter for listing and searching\n */\nexport const SessionFilterSchema = z.object({\n queryPath: z.string().optional(),\n status: z.string().optional(),\n dateRange: z.tuple([z.string(), z.string()]).optional(),\n language: z.string().optional(),\n queryType: z.string().optional(),\n});\n\nexport type SessionFilter = z.infer;\n\n/**\n * Comparison Report for analyzing multiple sessions\n */\nexport const ComparisonReportSchema = z.object({\n sessionIds: z.array(z.string()),\n dimensions: z.array(z.string()),\n timestamp: z.string(),\n results: z.record(z.any()),\n});\n\nexport type ComparisonReport = z.infer;\n\n/**\n * Aggregate Report for batch analysis\n */\nexport const AggregateReportSchema = z.object({\n filters: SessionFilterSchema,\n timestamp: z.string(),\n totalSessions: z.number(),\n successRate: z.number(),\n averageQualityScore: z.number(),\n commonPatterns: z.array(z.string()),\n recommendations: z.array(z.string()),\n});\n\nexport type AggregateReport = z.infer;\n\n/**\n * Export Result for data export operations\n */\nexport const ExportResultSchema = z.object({\n format: z.enum(['json', 'html', 'markdown']),\n filename: z.string(),\n content: z.string(),\n timestamp: z.string(),\n});\n\nexport type ExportResult = z.infer;\n\n/**\n * Functional Test Result for automated testing\n */\nexport const FunctionalTestResultSchema = z.object({\n sessionId: z.string(),\n queryPath: z.string(),\n passed: z.boolean(),\n criteria: z.record(z.any()),\n details: z.record(z.any()),\n timestamp: z.string(),\n});\n\nexport type FunctionalTestResult = z.infer;\n\n/**\n * Test Report for comprehensive test analysis\n */\nexport const TestReportSchema = z.object({\n sessionIds: z.array(z.string()),\n criteria: z.record(z.any()),\n timestamp: z.string(),\n overallPassRate: z.number(),\n results: z.array(FunctionalTestResultSchema),\n summary: z.record(z.any()),\n});\n\nexport type TestReport = z.infer;\n\n/**\n * Monitoring Configuration\n */\nexport const MonitoringConfigSchema = z.object({\n storageLocation: z.string().default('.ql-mcp-tracking/'),\n autoTrackSessions: z.boolean().default(true),\n retentionDays: z.number().default(90),\n includeCallParameters: z.boolean().default(true),\n includeCallResults: z.boolean().default(true),\n maxActiveSessionsPerQuery: z.number().default(3),\n scoringFrequency: z.enum(['per_call', 'periodic', 'manual']).default('per_call'),\n archiveCompletedSessions: z.boolean().default(true),\n enableRecommendations: z.boolean().default(true),\n enableMonitoringTools: z.boolean().default(false), // Opt-in: session_* tools disabled by default for end-users\n});\n\nexport type MonitoringConfig = z.infer;"], - "mappings": "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", - "names": ["type", "resolve", "setTimeout", "resolve", "setTimeout", "clearTimeout", "join", "resolve", "spawn", "delimiter", "EventEmitter", "clearTimeout", "setTimeout", "resolve", "spawn", "delimiter", "EventEmitter", "clearTimeout", "setTimeout", "resolve", "mkdirSync", "join", "type", "packageRootDir", "resolve", "existsSync", "delimiter", "dirname", "isAbsolute", "binary", "getServerManager", "resolve", "pathToFileURL", "z", "readFileSync", "dirname", "isAbsolute", "mkdirSync", "mkdirSync", "existsSync", "join", "resolve", "timestamp", "writeFileSync", "existsSync", "mkdirSync", "basename", "dirname", "isAbsolute", "join", "resolve", "logger", "executeCodeQLCommand", "basename", "mkdirSync", "dirname", "z", "z", "z", "z", "z", "z", "z", "z", "z", "z", "readFile", "z", "exception", "map", "schema", "type", "extend", "str", "string", "z", "z", "z", "z", "z", "z", "z", "z", "z", "z", "writeFileSync", "readFileSync", "existsSync", "join", "dirname", "basename", "mkdirSync", "z", "z", "z", "z", "z", "z", "join", "resolve", "resolve", "join", "z", "z", "resolve", "z", "z", "z", "z", "z", "z", "z", "z", "z", "z", "z", "z", "z", "z", "z", "z", "z", "z", "z", "z", "fs", "path", "getLanguageExtension", "z", "readFileSync", "join", "dirname", "fileURLToPath", "__filename", "__dirname", "z", "join", "pathToFileURL", "isAbsolute", "resolve", "pathToFileURL", "getUserWorkspaceDir", "pathToFileURL", "join", "z", "readFile", "isAbsolute", "resolve", "pathToFileURL", "isAbsolute", "resolve", "pathToFileURL", "readFile", "z", "z", "readFileSync", "existsSync", "join", "join", "existsSync", "readFileSync", "z", "basename", "readFileSync", "join", "dirname", "fileURLToPath", "__filename", "__dirname", "z", "basename", "z", "randomUUID", "readFileSync", "writeFileSync", "path", "path", "readFileSync", "str", "writeFileSync", "parse", "mkdirSync", "writeFileSync", "join", "randomUUID", "z", "join", "mkdirSync", "writeFileSync", "randomUUID", "z", "timestamp", "randomUUID", "resolve", "pathToFileURL"] + "sources": ["../src/utils/logger.ts", "../src/lib/server-config.ts", "../src/utils/package-paths.ts", "../src/utils/temp-dir.ts", "../src/utils/process-ready.ts", "../src/lib/language-server.ts", "../src/lib/query-server.ts", "../src/lib/cli-server.ts", "../src/lib/server-manager.ts", "../src/lib/cli-executor.ts", "../src/codeql-development-mcp-server.ts", "../src/tools/codeql/bqrs-decode.ts", "../src/lib/cli-tool-registry.ts", "../src/lib/query-results-evaluator.ts", "../src/lib/log-directory-manager.ts", "../src/tools/codeql/bqrs-info.ts", "../src/tools/codeql/bqrs-interpret.ts", "../src/tools/codeql/database-analyze.ts", "../src/tools/codeql/database-create.ts", "../src/tools/codeql/find-class-position.ts", "../src/tools/codeql/find-predicate-position.ts", "../src/tools/codeql/find-query-files.ts", "../src/lib/query-file-finder.ts", "../../node_modules/js-yaml/dist/js-yaml.mjs", "../src/lib/metadata-resolver.ts", "../src/tools/codeql/generate-log-summary.ts", "../src/tools/codeql/generate-query-help.ts", "../src/tools/codeql/list-databases.ts", "../src/lib/discovery-config.ts", "../src/tools/codeql/list-query-run-results.ts", "../src/tools/codeql/pack-install.ts", "../src/tools/codeql/pack-ls.ts", "../src/tools/codeql/profile-codeql-query.ts", "../src/tools/codeql/query-compile.ts", "../src/tools/codeql/query-format.ts", "../src/tools/codeql/query-run.ts", "../src/tools/codeql/quick-evaluate.ts", "../src/tools/codeql/register-database.ts", "../src/tools/codeql/resolve-database.ts", "../src/tools/codeql/resolve-languages.ts", "../src/tools/codeql/resolve-library-path.ts", "../src/tools/codeql/resolve-metadata.ts", "../src/tools/codeql/resolve-qlref.ts", "../src/tools/codeql/resolve-queries.ts", "../src/tools/codeql/resolve-tests.ts", "../src/tools/codeql/test-accept.ts", "../src/tools/codeql/test-extract.ts", "../src/tools/codeql/test-run.ts", "../src/tools/codeql-tools.ts", "../src/lib/validation.ts", "../src/lib/query-scaffolding.ts", "../src/lib/resources.ts", "../src/tools/codeql-resources.ts", "../src/tools/lsp/lsp-diagnostics.ts", "../src/tools/lsp/lsp-server-helper.ts", "../src/tools/lsp/lsp-handlers.ts", "../src/tools/lsp/lsp-tools.ts", "../src/resources/language-resources.ts", "../src/types/language-types.ts", "../src/prompts/workflow-prompts.ts", "../src/prompts/prompt-loader.ts", "../src/tools/monitoring-tools.ts", "../../node_modules/lowdb/lib/core/Low.js", "../../node_modules/lowdb/lib/adapters/node/TextFile.js", "../../node_modules/lowdb/lib/adapters/node/DataFile.js", "../../node_modules/lowdb/lib/adapters/node/JSONFile.js", "../src/lib/session-data-manager.ts", "../src/types/monitoring.ts"], + "sourcesContent": ["/**\n * Simple logger utility.\n *\n * All log output is written to stderr. In stdio transport mode, stdout is\n * reserved exclusively for the MCP JSON-RPC protocol \u2014 any non-protocol\n * bytes on stdout would corrupt the message stream.\n */\nexport const logger = {\n info: (message: string, ...args: unknown[]) => {\n console.error(`[INFO] ${new Date().toISOString()} ${message}`, ...args);\n },\n error: (message: string, ...args: unknown[]) => {\n console.error(`[ERROR] ${new Date().toISOString()} ${message}`, ...args);\n },\n warn: (message: string, ...args: unknown[]) => {\n console.error(`[WARN] ${new Date().toISOString()} ${message}`, ...args);\n },\n debug: (message: string, ...args: unknown[]) => {\n if (process.env.DEBUG) {\n console.error(`[DEBUG] ${new Date().toISOString()} ${message}`, ...args);\n }\n },\n};\n", "/**\n * Configuration types for CodeQL background server processes.\n *\n * CodeQL provides three background server types:\n * 1. language-server \u2013 LSP-based QL validation (JSON-RPC over stdio)\n * 2. query-server2 \u2013 Query evaluation (custom protocol over stdio)\n * 3. cli-server \u2013 JVM reuse for CLI commands (custom protocol over stdio)\n *\n * Each server type has its own configuration options, but they share common\n * settings like searchPath and commonCaches.\n */\n\nimport { createHash } from 'crypto';\n\n/**\n * Server types supported by CodeQL.\n */\nexport type CodeQLServerType = 'cli' | 'language' | 'query';\n\n/**\n * Common configuration shared across all server types.\n */\nexport interface BaseServerConfig {\n /** Path to QL packs (like `codeql query compile --search-path`). */\n searchPath?: string;\n /** Location for cached data (compilation plans, downloaded packs). */\n commonCaches?: string;\n /** Directory for detailed logs. */\n logdir?: string;\n}\n\n/**\n * Configuration for the CodeQL Language Server.\n */\nexport interface LanguageServerConfig extends BaseServerConfig {\n /** Error checking mode. Default: ON_CHANGE */\n checkErrors?: 'EXPLICIT' | 'ON_CHANGE';\n /** Log level for the language server. */\n loglevel?: 'ALL' | 'DEBUG' | 'ERROR' | 'INFO' | 'OFF' | 'TRACE' | 'WARN';\n /** Single-threaded execution. */\n synchronous?: boolean;\n /** Verbosity level for progress. */\n verbosity?: 'errors' | 'progress' | 'progress+' | 'progress++' | 'progress+++' | 'warnings';\n}\n\n/**\n * Configuration for the CodeQL Query Server (query-server2).\n */\nexport interface QueryServerConfig extends BaseServerConfig {\n /** Thread count. 0 = one per core, -N = leave N cores free. */\n threads?: number;\n /** Query evaluation timeout in seconds. */\n timeout?: number;\n /** Maximum disk cache size in MB for intermediate results. */\n maxDiskCache?: number;\n /** Path for structured evaluator performance logs. */\n evaluatorLog?: string;\n /** Include tuple counts in evaluation logs. */\n tupleCounting?: boolean;\n /** Enable debug mode. */\n debug?: boolean;\n}\n\n/**\n * Configuration for the CodeQL CLI Server.\n */\nexport interface CLIServerConfig extends BaseServerConfig {\n // cli-server has fewer options \u2014 just commonCaches and logdir.\n}\n\n/**\n * Union of all server configurations (discriminated by usage context).\n */\nexport type ServerConfig = CLIServerConfig | LanguageServerConfig | QueryServerConfig;\n\n/**\n * Compute a deterministic hash for a server configuration.\n * Used to detect configuration changes that require a server restart.\n *\n * @param type - The server type.\n * @param config - The server configuration.\n * @returns A hex-encoded SHA-256 hash of the canonical JSON representation.\n */\nexport function computeConfigHash(type: CodeQLServerType, config: ServerConfig): string {\n // Deep-sort all keys to ensure deterministic serialization regardless of\n // property insertion order.\n const sortKeys = (_key: string, value: unknown): unknown => {\n if (value && typeof value === 'object' && !Array.isArray(value)) {\n const sorted: Record = {};\n for (const k of Object.keys(value as Record).sort()) {\n sorted[k] = (value as Record)[k];\n }\n return sorted;\n }\n return value;\n };\n const canonical = JSON.stringify({ config, type }, sortKeys);\n return createHash('sha256').update(canonical).digest('hex');\n}\n\n/**\n * Build command-line arguments for a language server from its configuration.\n */\nexport function buildLanguageServerArgs(config: LanguageServerConfig): string[] {\n const args: string[] = [\n 'execute', 'language-server',\n `--check-errors=${config.checkErrors ?? 'ON_CHANGE'}`,\n ];\n\n if (config.searchPath) {\n args.push(`--search-path=${config.searchPath}`);\n }\n if (config.commonCaches) {\n args.push(`--common-caches=${config.commonCaches}`);\n }\n if (config.logdir) {\n args.push(`--logdir=${config.logdir}`);\n }\n if (config.loglevel) {\n args.push(`--loglevel=${config.loglevel}`);\n }\n if (config.synchronous) {\n args.push('--synchronous');\n }\n if (config.verbosity) {\n args.push(`--verbosity=${config.verbosity}`);\n }\n\n return args;\n}\n\n/**\n * Build command-line arguments for a query server from its configuration.\n */\nexport function buildQueryServerArgs(config: QueryServerConfig): string[] {\n const args: string[] = [\n 'execute', 'query-server2',\n ];\n\n if (config.searchPath) {\n args.push(`--search-path=${config.searchPath}`);\n }\n if (config.commonCaches) {\n args.push(`--common-caches=${config.commonCaches}`);\n }\n if (config.logdir) {\n args.push(`--logdir=${config.logdir}`);\n }\n if (config.threads !== undefined) {\n args.push(`--threads=${config.threads}`);\n }\n if (config.timeout !== undefined) {\n args.push(`--timeout=${config.timeout}`);\n }\n if (config.maxDiskCache !== undefined) {\n args.push(`--max-disk-cache=${config.maxDiskCache}`);\n }\n if (config.evaluatorLog) {\n args.push(`--evaluator-log=${config.evaluatorLog}`);\n }\n if (config.debug) {\n args.push('--debug');\n args.push('--tuple-counting');\n } else if (config.tupleCounting) {\n args.push('--tuple-counting');\n }\n\n return args;\n}\n\n/**\n * Build command-line arguments for a CLI server from its configuration.\n */\nexport function buildCLIServerArgs(config: CLIServerConfig): string[] {\n const args: string[] = [\n 'execute', 'cli-server',\n ];\n\n if (config.commonCaches) {\n args.push(`--common-caches=${config.commonCaches}`);\n }\n if (config.logdir) {\n args.push(`--logdir=${config.logdir}`);\n }\n\n return args;\n}\n", "/**\n * Utilities for resolving filesystem paths relative to the server package root.\n *\n * The server can run from three different directory layouts:\n *\n * 1. **Source** (dev): `server/src/lib/` \u2192 packageRoot = `server/`\n * 2. **Bundle in monorepo** (dev/CI): `server/dist/` \u2192 packageRoot = `server/`\n * 3. **Bundle via npm** (production): `/dist/` \u2192 packageRoot = `/`\n *\n * In all three cases, the bundled QL tool query packs live at\n * `/ql//tools/src/`.\n *\n * The \"workspace root\" (monorepo root) is one level above packageRoot when\n * running from the monorepo checkout, and the packageRoot itself when running\n * from an npm install (no parent monorepo).\n */\n\nimport { dirname, resolve } from 'path';\nimport { existsSync, readFileSync } from 'fs';\nimport { fileURLToPath } from 'url';\n\nconst __filename = fileURLToPath(import.meta.url);\nconst __dirname = dirname(__filename);\n\n/**\n * Detect whether the current __dirname looks like source code (`src/lib` or\n * `src/utils`) vs a bundled flat output directory (`dist/`).\n *\n * Uses a tail-of-path check so that unrelated `/src/` segments earlier in the\n * install path (e.g. `~/src/project/node_modules/.../dist`) don't cause a\n * false positive.\n */\nfunction isRunningFromSource(dir: string): boolean {\n const normalized = dir.replace(/\\\\/g, '/');\n return /\\/src(\\/[^/]+)?$/.test(normalized);\n}\n\n/**\n * Get the server package root directory.\n *\n * - From source (`server/src/utils/`): up 2 levels \u2192 `server/`\n * - From bundle (`server/dist/` or `/dist/`): up 1 level \u2192 package root\n */\nexport function getPackageRootDir(currentDir: string = __dirname): string {\n return isRunningFromSource(currentDir)\n ? resolve(currentDir, '..', '..') // src/utils \u2192 server/\n : resolve(currentDir, '..'); // dist/ \u2192 package root\n}\n\n/**\n * Get the workspace root directory (monorepo root when applicable).\n *\n * If a `package.json` with `workspaces` exists one level above the package\n * root, we're in a monorepo and that parent is the workspace root. Otherwise,\n * the packageRoot itself is the workspace root (npm install scenario).\n */\nexport function getWorkspaceRootDir(packageRoot?: string): string {\n const pkgRoot = packageRoot ?? getPackageRootDir();\n const parentDir = resolve(pkgRoot, '..');\n\n // In the monorepo, the parent directory contains a package.json with workspaces\n try {\n const parentPkgPath = resolve(parentDir, 'package.json');\n if (existsSync(parentPkgPath)) {\n const parentPkg = JSON.parse(readFileSync(parentPkgPath, 'utf8'));\n if (parentPkg.workspaces) {\n return parentDir;\n }\n }\n } catch {\n // Not in a monorepo \u2014 fall through\n }\n\n return pkgRoot;\n}\n\n/**\n * Resolve the path to a tool query pack's source directory.\n *\n * @param language - CodeQL language identifier (e.g., \"javascript\", \"cpp\")\n * @param packageRoot - Override the package root (for testing)\n * @returns Absolute path to `ql//tools/src/`\n */\nexport function resolveToolQueryPackPath(language: string, packageRoot?: string): string {\n const pkgRoot = packageRoot ?? getPackageRootDir();\n return resolve(pkgRoot, 'ql', language, 'tools', 'src');\n}\n\n/**\n * Read the package version from the nearest package.json.\n *\n * Cached at first call so the file is read at most once per process.\n */\nlet _cachedVersion: string | undefined;\nexport function getPackageVersion(): string {\n if (_cachedVersion !== undefined) return _cachedVersion;\n try {\n const pkgPath = resolve(getPackageRootDir(), 'package.json');\n const pkg = JSON.parse(readFileSync(pkgPath, 'utf8'));\n _cachedVersion = pkg.version ?? '0.0.0';\n } catch {\n _cachedVersion = '0.0.0';\n }\n return _cachedVersion as string;\n}\n\n/**\n * Get the effective workspace directory for resolving user-supplied relative\n * paths (test directories, database paths, pack dirs, etc.).\n *\n * In a monorepo checkout the workspace root is the monorepo parent. In an\n * npm-installed layout, `workspaceRootDir` falls back to `packageRootDir`\n * which may be read-only and is not the user's project. In that case we\n * fall back to `process.cwd()` so that relative paths resolve against the\n * directory the user actually invoked the server from.\n *\n * Override with `CODEQL_MCP_WORKSPACE` for deterministic behavior.\n */\nexport function getUserWorkspaceDir(): string {\n if (process.env.CODEQL_MCP_WORKSPACE) {\n return process.env.CODEQL_MCP_WORKSPACE;\n }\n // When workspaceRootDir === packageRootDir we are NOT in a monorepo\n // (npm-installed), so fall back to process.cwd().\n if (workspaceRootDir === packageRootDir) {\n return process.cwd();\n }\n return workspaceRootDir;\n}\n\n// Pre-computed values for use throughout the server\nexport const packageRootDir = getPackageRootDir();\nexport const workspaceRootDir = getWorkspaceRootDir(packageRootDir);\n", "/**\n * Secure project-local temporary directory utilities.\n *\n * All temporary files are created under `/.tmp/` which is\n * `.gitignore`d. This avoids writing to the OS temp directory\n * (`os.tmpdir()` / `/tmp`), which is world-readable and triggers\n * CWE-377 / CWE-378 (js/insecure-temporary-file).\n */\n\nimport { mkdirSync, mkdtempSync } from 'fs';\nimport { isAbsolute, join, resolve } from 'path';\nimport { getPackageRootDir } from './package-paths';\n\n/**\n * Base directory for all project-local temporary data.\n *\n * Resolution order:\n * 1. `CODEQL_MCP_TMP_DIR` environment variable \u2014 for read-only package root\n * scenarios (e.g., npm global installs where the package directory is not\n * writable). Relative paths are resolved against process.cwd().\n * 2. `/.tmp` \u2014 default; excluded from version control.\n */\nconst PROJECT_TMP_BASE = process.env.CODEQL_MCP_TMP_DIR\n ? (isAbsolute(process.env.CODEQL_MCP_TMP_DIR) \n ? process.env.CODEQL_MCP_TMP_DIR \n : resolve(process.cwd(), process.env.CODEQL_MCP_TMP_DIR))\n : join(getPackageRootDir(), '.tmp');\n\n/**\n * Return the project-local `.tmp` base directory, creating it if needed.\n */\nexport function getProjectTmpBase(): string {\n mkdirSync(PROJECT_TMP_BASE, { recursive: true });\n return PROJECT_TMP_BASE;\n}\n\n/**\n * Create a unique temporary directory under the project `.tmp` root.\n *\n * Works identically to `fs.mkdtempSync(os.tmpdir(), prefix)` but is\n * scoped to the repository.\n *\n * @param prefix - Directory name prefix (e.g. `'codeql-external-'`).\n * @returns Absolute path to the newly created directory.\n */\nexport function createProjectTempDir(prefix: string): string {\n const base = getProjectTmpBase();\n return mkdtempSync(join(base, prefix));\n}\n\n/**\n * Return a deterministic subdirectory under `.tmp/`, creating it\n * if it does not already exist.\n *\n * Useful for well-known scratch areas such as `query-logs` or `quickeval`.\n *\n * @param name - Subdirectory name (e.g. `'query-logs'`).\n * @returns Absolute path to the subdirectory.\n */\nexport function getProjectTmpDir(name: string): string {\n const dir = join(getProjectTmpBase(), name);\n mkdirSync(dir, { recursive: true });\n return dir;\n}\n", "/**\n * Utility for waiting until a spawned child process is ready.\n *\n * CodeQL background servers (cli-server, query-server2, language-server) run\n * on the JVM and emit stderr log output once the JVM has initialised. Rather\n * than sleeping for a hard-coded duration \u2014 which is fragile on both fast and\n * slow machines \u2014 this helper resolves as soon as the first stderr output\n * arrives (indicating the JVM is alive), or when the maximum timeout expires.\n * It also rejects immediately if the process exits or errors before becoming\n * ready, giving callers a clear error instead of a silent hang.\n */\n\nimport { ChildProcess } from 'child_process';\nimport { clearTimeout, setTimeout } from 'timers';\nimport { logger } from './logger';\n\n/** Default maximum wait for a CodeQL server to become ready (30 s). */\nconst DEFAULT_READY_TIMEOUT_MS = 30_000;\n\n/**\n * Options for {@link waitForProcessReady}.\n */\nexport interface ProcessReadyOptions {\n /**\n * Maximum time in milliseconds to wait for the process to emit its first\n * stderr output. If the timeout is reached without a signal the promise\n * still resolves (best-effort) so the caller can attempt communication.\n *\n * Default: 30 000 ms.\n */\n timeoutMs?: number;\n}\n\n/**\n * Wait until a child process signals readiness.\n *\n * \"Ready\" is defined as any of:\n * 1. The process emits data on **stderr** (JVM startup log line).\n * 2. The process emits data on **stdout** (initial protocol message).\n * 3. The maximum timeout elapses (best-effort resolve).\n *\n * The promise **rejects** if the process emits an `error` event or exits\n * before any of the above conditions are met.\n *\n * @param child - The spawned child process.\n * @param name - A human-readable label for log messages.\n * @param opts - Optional configuration.\n */\nexport function waitForProcessReady(\n child: ChildProcess,\n name: string,\n opts?: ProcessReadyOptions,\n): Promise {\n const timeoutMs = opts?.timeoutMs ?? DEFAULT_READY_TIMEOUT_MS;\n\n return new Promise((resolve, reject) => {\n let settled = false;\n\n const cleanup = () => {\n settled = true;\n child.stderr?.removeListener('data', onStderr);\n child.stdout?.removeListener('data', onStdout);\n child.removeListener('error', onError);\n child.removeListener('exit', onExit);\n clearTimeout(timer);\n };\n\n const onStderr = () => {\n if (settled) return;\n logger.debug(`${name}: ready (stderr output detected)`);\n cleanup();\n resolve();\n };\n\n const onStdout = () => {\n if (settled) return;\n logger.debug(`${name}: ready (stdout output detected)`);\n cleanup();\n resolve();\n };\n\n const onError = (error: Error) => {\n if (settled) return;\n cleanup();\n reject(new Error(`${name} failed to start: ${error.message}`));\n };\n\n const onExit = (code: number | null) => {\n if (settled) return;\n cleanup();\n reject(new Error(`${name} exited before becoming ready (code: ${code})`));\n };\n\n const timer = setTimeout(() => {\n if (settled) return;\n logger.warn(`${name}: readiness timeout (${timeoutMs} ms) \u2014 proceeding anyway`);\n cleanup();\n resolve(); // best-effort: let the caller attempt communication\n }, timeoutMs);\n\n child.stderr?.on('data', onStderr);\n child.stdout?.on('data', onStdout);\n child.on('error', onError);\n child.on('exit', onExit);\n\n // If the process was dead before we even attached listeners, reject now\n if (child.killed || child.exitCode !== null) {\n cleanup();\n reject(new Error(`${name} is not running (exitCode: ${child.exitCode})`));\n }\n });\n}\n", "/**\n * CodeQL Language Server manager for LSP communication\n * Manages the lifecycle and communication with the CodeQL language server process\n */\n\nimport { spawn, ChildProcess } from 'child_process';\nimport { EventEmitter } from 'events';\nimport { setTimeout, clearTimeout } from 'timers';\nimport { pathToFileURL } from 'url';\nimport { delimiter, join } from 'path';\nimport { logger } from '../utils/logger';\nimport { getPackageVersion } from '../utils/package-paths';\nimport { getProjectTmpDir } from '../utils/temp-dir';\nimport { getResolvedCodeQLDir } from './cli-executor';\nimport { waitForProcessReady } from '../utils/process-ready';\n\nexport interface LSPMessage {\n jsonrpc: '2.0';\n id?: number | string;\n method: string;\n params?: unknown;\n result?: unknown;\n error?: {\n code: number;\n message: string;\n data?: unknown;\n };\n}\n\nexport interface Diagnostic {\n range: {\n start: { line: number; character: number };\n end: { line: number; character: number };\n };\n severity: number; // 1=Error, 2=Warning, 3=Information, 4=Hint\n source?: string;\n message: string;\n code?: string | number;\n}\n\nexport interface PublishDiagnosticsParams {\n uri: string;\n diagnostics: Diagnostic[];\n}\n\nexport interface LanguageServerOptions {\n searchPath?: string;\n logdir?: string;\n loglevel?: 'ALL' | 'DEBUG' | 'ERROR' | 'INFO' | 'OFF' | 'TRACE' | 'WARN';\n synchronous?: boolean;\n verbosity?: 'errors' | 'progress' | 'progress+' | 'progress++' | 'progress+++' | 'warnings';\n}\n\n/**\n * Position in a text document (0-based line and character).\n */\nexport interface LSPPosition {\n character: number;\n line: number;\n}\n\n/**\n * A range in a text document.\n */\nexport interface LSPRange {\n end: LSPPosition;\n start: LSPPosition;\n}\n\n/**\n * A location in a resource (file URI + range).\n */\nexport interface LSPLocation {\n range: LSPRange;\n uri: string;\n}\n\n/**\n * Identifies a text document by its URI.\n */\nexport interface TextDocumentIdentifier {\n uri: string;\n}\n\n/**\n * A text document position (document + position within it).\n */\nexport interface TextDocumentPositionParams {\n position: LSPPosition;\n textDocument: TextDocumentIdentifier;\n}\n\n/**\n * A completion item returned by the language server.\n */\nexport interface CompletionItem {\n detail?: string;\n documentation?: string | { kind: string; value: string };\n insertText?: string;\n kind?: number;\n label: string;\n sortText?: string;\n}\n\nexport class CodeQLLanguageServer extends EventEmitter {\n private server: ChildProcess | null = null;\n private messageId = 1;\n private pendingResponses = new Map void; reject: (_error: Error) => void }>();\n private isInitialized = false;\n private currentWorkspaceUri: string | undefined;\n private messageBuffer = '';\n\n constructor(private _options: LanguageServerOptions = {}) {\n super();\n }\n\n async start(): Promise {\n if (this.server) {\n throw new Error('Language server is already running');\n }\n\n logger.info('Starting CodeQL Language Server...');\n\n const args = [\n 'execute', 'language-server',\n '--check-errors=ON_CHANGE'\n ];\n\n // Add optional arguments\n if (this._options.searchPath) {\n args.push(`--search-path=${this._options.searchPath}`);\n }\n if (this._options.logdir) {\n args.push(`--logdir=${this._options.logdir}`);\n }\n if (this._options.loglevel) {\n args.push(`--loglevel=${this._options.loglevel}`);\n }\n if (this._options.synchronous) {\n args.push('--synchronous');\n }\n if (this._options.verbosity) {\n args.push(`--verbosity=${this._options.verbosity}`);\n }\n\n // Build environment with CODEQL_PATH directory prepended to PATH\n // (mirrors the approach in cli-executor.ts getSafeEnvironment).\n const spawnEnv = { ...process.env };\n const codeqlDir = getResolvedCodeQLDir();\n if (codeqlDir && spawnEnv.PATH) {\n spawnEnv.PATH = `${codeqlDir}${delimiter}${spawnEnv.PATH}`;\n } else if (codeqlDir) {\n spawnEnv.PATH = codeqlDir;\n }\n\n this.server = spawn('codeql', args, {\n stdio: ['pipe', 'pipe', 'pipe'],\n env: spawnEnv\n });\n\n this.server.stderr?.on('data', (data) => {\n logger.debug('CodeQL LS stderr:', data.toString());\n });\n\n this.server.stdout?.on('data', (data) => {\n this.handleStdout(data);\n });\n\n this.server.on('error', (error) => {\n logger.error('CodeQL Language Server error:', error);\n this.emit('error', error);\n });\n\n this.server.on('exit', (code) => {\n logger.info('CodeQL Language Server exited with code:', code);\n this.server = null;\n this.isInitialized = false;\n this.emit('exit', code);\n });\n\n // Wait for the JVM to initialise (resolves on first stderr/stdout output)\n await waitForProcessReady(this.server, 'CodeQL Language Server');\n }\n\n private handleStdout(data: Buffer): void {\n this.messageBuffer += data.toString();\n \n let headerEnd = this.messageBuffer.indexOf('\\r\\n\\r\\n');\n while (headerEnd !== -1) {\n const header = this.messageBuffer.substring(0, headerEnd);\n const contentLengthMatch = header.match(/Content-Length: (\\d+)/);\n \n if (contentLengthMatch) {\n const contentLength = parseInt(contentLengthMatch[1]);\n const messageStart = headerEnd + 4;\n const messageEnd = messageStart + contentLength;\n \n if (this.messageBuffer.length >= messageEnd) {\n const messageContent = this.messageBuffer.substring(messageStart, messageEnd);\n this.messageBuffer = this.messageBuffer.substring(messageEnd);\n \n try {\n const message: LSPMessage = JSON.parse(messageContent);\n this.handleMessage(message);\n } catch (error) {\n logger.error('Failed to parse LSP message:', error, messageContent);\n }\n \n headerEnd = this.messageBuffer.indexOf('\\r\\n\\r\\n');\n } else {\n break;\n }\n } else {\n logger.error('Invalid LSP header:', header);\n this.messageBuffer = '';\n break;\n }\n }\n }\n\n private handleMessage(message: LSPMessage): void {\n logger.debug('Received LSP message:', message);\n\n // Handle responses to our requests\n if (message.id !== undefined && this.pendingResponses.has(Number(message.id))) {\n const pending = this.pendingResponses.get(Number(message.id))!;\n this.pendingResponses.delete(Number(message.id));\n \n if (message.error) {\n pending.reject(new Error(`LSP Error: ${message.error.message}`));\n } else {\n pending.resolve(message.result);\n }\n return;\n }\n\n // Handle notifications from server\n if (message.method === 'textDocument/publishDiagnostics') {\n this.emit('diagnostics', message.params as PublishDiagnosticsParams);\n }\n }\n\n private sendMessage(message: LSPMessage): void {\n if (!this.server?.stdin) {\n throw new Error('Language server is not running');\n }\n\n const messageStr = JSON.stringify(message);\n const contentLength = Buffer.byteLength(messageStr, 'utf8');\n const header = `Content-Length: ${contentLength}\\r\\n\\r\\n`;\n const fullMessage = header + messageStr;\n\n logger.debug('Sending LSP message:', fullMessage);\n this.server.stdin.write(fullMessage);\n }\n\n private sendRequest(method: string, params?: unknown): Promise {\n const id = this.messageId++;\n const message: LSPMessage = {\n jsonrpc: '2.0',\n id,\n method,\n params\n };\n\n return new Promise((resolve, reject) => {\n // Wrap resolve/reject to clear the timer when the promise settles.\n const timer = setTimeout(() => {\n if (this.pendingResponses.has(id)) {\n this.pendingResponses.delete(id);\n reject(new Error(`LSP request timeout for method: ${method}`));\n }\n }, 60_000); // 60 second timeout (Windows CI cold JVM can exceed 30s)\n\n this.pendingResponses.set(id, {\n reject: (err: Error) => { clearTimeout(timer); reject(err); },\n resolve: (val: unknown) => { clearTimeout(timer); resolve(val); },\n });\n this.sendMessage(message);\n });\n }\n\n private sendNotification(method: string, params?: unknown): void {\n const message: LSPMessage = {\n jsonrpc: '2.0',\n method,\n params\n };\n this.sendMessage(message);\n }\n\n /**\n * Initialize the language server with an optional workspace URI.\n *\n * If the server is already initialized with a different workspace, a\n * `workspace/didChangeWorkspaceFolders` notification is sent to update\n * the workspace context instead of requiring a full restart.\n */\n async initialize(workspaceUri?: string): Promise {\n if (this.isInitialized) {\n // If workspace changed, notify the server\n if (workspaceUri && workspaceUri !== this.currentWorkspaceUri) {\n await this.updateWorkspace(workspaceUri);\n }\n return;\n }\n\n logger.info('Initializing CodeQL Language Server...');\n\n const initParams = {\n processId: process.pid,\n clientInfo: {\n name: 'codeql-development-mcp-server',\n version: getPackageVersion()\n },\n capabilities: {\n textDocument: {\n completion: { completionItem: { snippetSupport: false } },\n definition: {},\n publishDiagnostics: {},\n references: {},\n synchronization: {\n didClose: true,\n didChange: true,\n didOpen: true,\n },\n },\n workspace: {\n workspaceFolders: true,\n },\n }\n };\n\n if (workspaceUri) {\n (initParams as unknown as { workspaceFolders: unknown[] }).workspaceFolders = [{\n uri: workspaceUri,\n name: 'codeql-workspace'\n }];\n }\n\n await this.sendRequest('initialize', initParams);\n this.sendNotification('initialized', {});\n\n this.currentWorkspaceUri = workspaceUri;\n this.isInitialized = true;\n logger.info('CodeQL Language Server initialized successfully');\n }\n\n /**\n * Update the workspace folders on a running, initialized server.\n */\n private async updateWorkspace(newUri: string): Promise {\n logger.info(`Updating workspace from ${this.currentWorkspaceUri} to ${newUri}`);\n\n const removed = this.currentWorkspaceUri\n ? [{ uri: this.currentWorkspaceUri, name: 'codeql-workspace' }]\n : [];\n\n this.sendNotification('workspace/didChangeWorkspaceFolders', {\n event: {\n added: [{ uri: newUri, name: 'codeql-workspace' }],\n removed,\n },\n });\n\n this.currentWorkspaceUri = newUri;\n }\n\n /**\n * Get the current workspace URI.\n */\n getWorkspaceUri(): string | undefined {\n return this.currentWorkspaceUri;\n }\n\n async evaluateQL(qlCode: string, uri?: string): Promise {\n if (!this.isInitialized) {\n throw new Error('Language server is not initialized');\n }\n\n // Default to a project-local virtual URI rather than /tmp\n const documentUri = uri || pathToFileURL(join(getProjectTmpDir('lsp-eval'), 'eval.ql')).href;\n\n return new Promise((resolve, reject) => {\n let diagnosticsReceived = false;\n const timeout = setTimeout(() => {\n if (!diagnosticsReceived) {\n this.removeListener('diagnostics', diagnosticsHandler);\n reject(new Error('Timeout waiting for diagnostics'));\n }\n }, 90_000); // 90s \u2014 first call triggers JVM start + compilation; Windows CI is slow\n\n // Listen for diagnostics\n const diagnosticsHandler = (params: PublishDiagnosticsParams) => {\n if (params.uri === documentUri) {\n diagnosticsReceived = true;\n clearTimeout(timeout);\n this.removeListener('diagnostics', diagnosticsHandler);\n\n // Close the document\n this.sendNotification('textDocument/didClose', {\n textDocument: { uri: documentUri }\n });\n\n resolve(params.diagnostics);\n }\n };\n\n this.on('diagnostics', diagnosticsHandler);\n\n // Open the document with the QL code\n this.sendNotification('textDocument/didOpen', {\n textDocument: {\n uri: documentUri,\n languageId: 'ql',\n version: 1,\n text: qlCode\n }\n });\n });\n }\n\n // ---- LSP feature methods (issue #1) ----\n\n /**\n * Get code completions at a position in a document.\n */\n async getCompletions(params: TextDocumentPositionParams): Promise {\n if (!this.isInitialized) {\n throw new Error('Language server is not initialized');\n }\n if (!this.isRunning()) {\n throw new Error('Language server process is not running');\n }\n const result = await this.sendRequest('textDocument/completion', params);\n // The result may be a CompletionList or CompletionItem[]\n if (result && typeof result === 'object' && 'items' in (result as object)) {\n return (result as { items: CompletionItem[] }).items;\n }\n return (result as CompletionItem[]) || [];\n }\n\n /**\n * Find the definition(s) of a symbol at a position.\n */\n async getDefinition(params: TextDocumentPositionParams): Promise {\n if (!this.isInitialized) {\n throw new Error('Language server is not initialized');\n }\n if (!this.isRunning()) {\n throw new Error('Language server process is not running');\n }\n const result = await this.sendRequest('textDocument/definition', params);\n return this.normalizeLocations(result);\n }\n\n /**\n * Find all references to a symbol at a position.\n */\n async getReferences(params: TextDocumentPositionParams & { context?: { includeDeclaration: boolean } }): Promise {\n if (!this.isInitialized) {\n throw new Error('Language server is not initialized');\n }\n if (!this.isRunning()) {\n throw new Error('Language server process is not running');\n }\n const result = await this.sendRequest('textDocument/references', {\n ...params,\n context: params.context ?? { includeDeclaration: true },\n });\n return this.normalizeLocations(result);\n }\n\n /**\n * Open a text document in the language server.\n * The document must be opened before requesting completions, definitions, etc.\n */\n openDocument(uri: string, text: string, languageId = 'ql', version = 1): void {\n if (!this.isInitialized) {\n throw new Error('Language server is not initialized');\n }\n this.sendNotification('textDocument/didOpen', {\n textDocument: { uri, languageId, version, text },\n });\n }\n\n /**\n * Close a text document in the language server.\n */\n closeDocument(uri: string): void {\n if (!this.isInitialized) {\n throw new Error('Language server is not initialized');\n }\n this.sendNotification('textDocument/didClose', {\n textDocument: { uri },\n });\n }\n\n /**\n * Normalize a definition/references/implementation result to Location[].\n * The LSP spec allows Location | Location[] | LocationLink[].\n */\n private normalizeLocations(result: unknown): LSPLocation[] {\n if (!result) return [];\n if (Array.isArray(result)) {\n return result.map((item) => {\n // LocationLink has targetUri/targetRange\n if ('targetUri' in item) {\n return { uri: item.targetUri, range: item.targetRange } as LSPLocation;\n }\n return item as LSPLocation;\n });\n }\n // Single Location\n if (typeof result === 'object' && 'uri' in (result as object)) {\n return [result as LSPLocation];\n }\n return [];\n }\n\n async shutdown(): Promise {\n if (!this.server) {\n return;\n }\n\n logger.info('Shutting down CodeQL Language Server...');\n\n try {\n await this.sendRequest('shutdown', {});\n if (this.server) {\n this.sendNotification('exit', {});\n }\n } catch (error) {\n logger.warn('Error during graceful shutdown:', error);\n }\n\n // Force kill if needed\n await new Promise((resolve) => {\n const timer = setTimeout(() => {\n if (this.server) {\n this.server.kill('SIGTERM');\n }\n resolve();\n }, 1000);\n\n if (this.server) {\n this.server.once('exit', () => {\n clearTimeout(timer);\n this.server = null;\n resolve();\n });\n } else {\n clearTimeout(timer);\n resolve();\n }\n });\n\n this.isInitialized = false;\n }\n\n isRunning(): boolean {\n return this.server !== null && !this.server.killed;\n }\n}", "/**\n * CodeQL Query Server (query-server2) client.\n *\n * Manages a long-lived `codeql execute query-server2` process that evaluates\n * queries using a custom JSON-RPC protocol over stdio. Reusing the server\n * avoids repeated JVM startup for each query evaluation.\n *\n * Protocol: The query-server2 uses JSON-RPC with Content-Length headers\n * (same framing as LSP) over stdin/stdout.\n */\n\nimport { ChildProcess, spawn } from 'child_process';\nimport { delimiter } from 'path';\nimport { EventEmitter } from 'events';\nimport { clearTimeout, setTimeout } from 'timers';\nimport { buildQueryServerArgs, QueryServerConfig } from './server-config';\nimport { getResolvedCodeQLDir } from './cli-executor';\nimport { logger } from '../utils/logger';\nimport { waitForProcessReady } from '../utils/process-ready';\n\n/**\n * A pending request awaiting a response from the query server.\n */\ninterface PendingRequest {\n reject: (_error: Error) => void;\n resolve: (_value: unknown) => void;\n}\n\n/**\n * Client for the CodeQL query-server2 process.\n *\n * Spawns `codeql execute query-server2` and communicates over stdin/stdout\n * using JSON-RPC with Content-Length framing.\n */\nexport class CodeQLQueryServer extends EventEmitter {\n private messageBuffer = '';\n private messageId = 1;\n private pendingRequests = new Map();\n private process: ChildProcess | null = null;\n private readonly config: QueryServerConfig;\n\n constructor(config: QueryServerConfig) {\n super();\n this.config = config;\n }\n\n /**\n * Start the query-server2 process.\n */\n async start(): Promise {\n if (this.process) {\n throw new Error('Query server is already running');\n }\n\n logger.info('Starting CodeQL Query Server (query-server2)...');\n\n const args = buildQueryServerArgs(this.config);\n\n // Build environment with CODEQL_PATH directory prepended to PATH\n const spawnEnv = { ...process.env };\n const codeqlDir = getResolvedCodeQLDir();\n if (codeqlDir && spawnEnv.PATH) {\n spawnEnv.PATH = `${codeqlDir}${delimiter}${spawnEnv.PATH}`;\n } else if (codeqlDir) {\n spawnEnv.PATH = codeqlDir;\n }\n\n this.process = spawn('codeql', args, {\n stdio: ['pipe', 'pipe', 'pipe'],\n env: spawnEnv,\n });\n\n this.process.stderr?.on('data', (data: Buffer) => {\n logger.debug('QueryServer2 stderr:', data.toString());\n });\n\n this.process.stdout?.on('data', (data: Buffer) => {\n this.handleStdout(data);\n });\n\n this.process.on('error', (error: Error) => {\n logger.error('Query server process error:', error);\n this.emit('error', error);\n });\n\n this.process.on('exit', (code: number | null) => {\n logger.info(`Query server exited with code: ${code}`);\n this.rejectAllPending(new Error(`Query server exited with code: ${code}`));\n this.process = null;\n this.emit('exit', code);\n });\n\n // Wait for the JVM to initialise (resolves on first stderr/stdout output)\n await waitForProcessReady(this.process, 'CodeQL Query Server');\n logger.info('CodeQL Query Server started');\n }\n\n /**\n * Send a request to the query server and await the response.\n *\n * @param method - The JSON-RPC method name.\n * @param params - The method parameters.\n * @param timeoutMs - Request timeout in milliseconds (default: 300000 = 5 min).\n * @returns The result from the server.\n */\n sendRequest(method: string, params?: unknown, timeoutMs = 300_000): Promise {\n const id = this.messageId++;\n const message = {\n id,\n jsonrpc: '2.0' as const,\n method,\n params,\n };\n\n return new Promise((resolve, reject) => {\n this.pendingRequests.set(id, { reject, resolve });\n\n try {\n this.sendRaw(message);\n } catch (error) {\n // Clean up immediately \u2014 sendRaw() failed so no response will arrive.\n this.pendingRequests.delete(id);\n reject(error instanceof Error ? error : new Error(String(error)));\n return;\n }\n\n const timer = setTimeout(() => {\n if (this.pendingRequests.has(id)) {\n this.pendingRequests.delete(id);\n reject(new Error(`Query server request timeout for method: ${method}`));\n }\n }, timeoutMs);\n\n // Clear the timeout when the promise settles\n const originalResolve = resolve;\n const originalReject = reject;\n const wrapped = {\n reject: (err: Error) => { clearTimeout(timer); originalReject(err); },\n resolve: (val: unknown) => { clearTimeout(timer); originalResolve(val); },\n };\n this.pendingRequests.set(id, wrapped);\n });\n }\n\n /**\n * Gracefully shut down the query server.\n */\n async shutdown(): Promise {\n if (!this.process) {\n return;\n }\n\n logger.info('Shutting down CodeQL Query Server...');\n\n try {\n await this.sendRequest('shutdown', {}, 5000);\n } catch (error) {\n logger.warn('Error during query server graceful shutdown:', error);\n }\n\n // Force kill if process lingers\n await new Promise((resolve) => {\n const timer = setTimeout(() => {\n if (this.process) {\n this.process.kill('SIGTERM');\n this.process = null;\n }\n resolve();\n }, 2000);\n\n if (this.process) {\n this.process.once('exit', () => {\n clearTimeout(timer);\n this.process = null;\n resolve();\n });\n } else {\n clearTimeout(timer);\n resolve();\n }\n });\n }\n\n /**\n * Whether the query server process is running.\n */\n isRunning(): boolean {\n return this.process !== null && !this.process.killed;\n }\n\n // ---- private helpers ----\n\n private handleStdout(data: Buffer): void {\n this.messageBuffer += data.toString();\n\n let headerEnd = this.messageBuffer.indexOf('\\r\\n\\r\\n');\n while (headerEnd !== -1) {\n const header = this.messageBuffer.substring(0, headerEnd);\n const contentLengthMatch = header.match(/Content-Length: (\\d+)/);\n\n if (contentLengthMatch) {\n const contentLength = parseInt(contentLengthMatch[1]);\n const messageStart = headerEnd + 4;\n const messageEnd = messageStart + contentLength;\n\n if (this.messageBuffer.length >= messageEnd) {\n const messageContent = this.messageBuffer.substring(messageStart, messageEnd);\n this.messageBuffer = this.messageBuffer.substring(messageEnd);\n\n try {\n const message = JSON.parse(messageContent);\n this.handleMessage(message);\n } catch (error) {\n logger.error('Failed to parse query server message:', error);\n }\n\n headerEnd = this.messageBuffer.indexOf('\\r\\n\\r\\n');\n } else {\n break;\n }\n } else {\n logger.error('Invalid query server header:', header);\n this.messageBuffer = '';\n break;\n }\n }\n }\n\n private handleMessage(message: { error?: { message: string }; id?: number; method?: string; params?: unknown; result?: unknown }): void {\n logger.debug('QueryServer2 message:', message);\n\n // Handle responses\n if (message.id !== undefined && this.pendingRequests.has(Number(message.id))) {\n const pending = this.pendingRequests.get(Number(message.id))!;\n this.pendingRequests.delete(Number(message.id));\n\n if (message.error) {\n pending.reject(new Error(`Query server error: ${message.error.message}`));\n } else {\n pending.resolve(message.result);\n }\n return;\n }\n\n // Handle notifications (progress, etc.)\n if (message.method) {\n this.emit('notification', { method: message.method, params: message.params });\n }\n }\n\n private rejectAllPending(error: Error): void {\n for (const [id, pending] of this.pendingRequests) {\n pending.reject(error);\n this.pendingRequests.delete(id);\n }\n }\n\n private sendRaw(message: object): void {\n if (!this.process?.stdin) {\n throw new Error('Query server is not running');\n }\n\n const body = JSON.stringify(message);\n const contentLength = Buffer.byteLength(body, 'utf8');\n const frame = `Content-Length: ${contentLength}\\r\\n\\r\\n${body}`;\n this.process.stdin.write(frame);\n }\n}\n", "/**\n * CodeQL CLI Server client.\n *\n * Manages a long-lived `codeql execute cli-server` process that executes CLI\n * commands without repeated JVM startup overhead. Commands are serialized as\n * JSON arrays followed by a NUL byte, and responses are NUL-terminated JSON.\n *\n * Inspired by the `CodeQLCliServer` class in github/vscode-codeql.\n */\n\nimport { ChildProcess, spawn } from 'child_process';\nimport { delimiter } from 'path';\nimport { EventEmitter } from 'events';\nimport { clearTimeout, setTimeout } from 'timers';\nimport { buildCLIServerArgs, CLIServerConfig } from './server-config';\nimport { getResolvedCodeQLDir } from './cli-executor';\nimport { logger } from '../utils/logger';\nimport { waitForProcessReady } from '../utils/process-ready';\n\n/**\n * A queued command waiting to be sent to the CLI server.\n */\ninterface QueuedCommand {\n args: string[];\n reject: (_error: Error) => void;\n resolve: (_value: string) => void;\n}\n\n/**\n * Client for the CodeQL CLI Server process.\n *\n * The cli-server uses a simple NUL-delimited protocol:\n * - **Request**: JSON array of command arguments, followed by a NUL byte.\n * - **Response**: command stdout, terminated by a NUL byte on stdout.\n * stderr is forwarded as-is.\n */\nexport class CodeQLCLIServer extends EventEmitter {\n private commandInProgress = false;\n private commandQueue: Array<() => void> = [];\n private readonly config: CLIServerConfig;\n private currentReject: ((_error: Error) => void) | null = null;\n private currentResolve: ((_value: string) => void) | null = null;\n private nullBuffer = Buffer.alloc(1);\n private process: ChildProcess | null = null;\n private stdoutBuffer = '';\n\n constructor(config: CLIServerConfig) {\n super();\n this.config = config;\n }\n\n /**\n * Start the cli-server process.\n */\n async start(): Promise {\n if (this.process) {\n throw new Error('CLI server is already running');\n }\n\n logger.info('Starting CodeQL CLI Server...');\n\n const args = buildCLIServerArgs(this.config);\n\n const spawnEnv = { ...process.env };\n const codeqlDir = getResolvedCodeQLDir();\n if (codeqlDir && spawnEnv.PATH) {\n spawnEnv.PATH = `${codeqlDir}${delimiter}${spawnEnv.PATH}`;\n } else if (codeqlDir) {\n spawnEnv.PATH = codeqlDir;\n }\n\n this.process = spawn('codeql', args, {\n stdio: ['pipe', 'pipe', 'pipe'],\n env: spawnEnv,\n });\n\n this.process.stdout?.on('data', (data: Buffer) => {\n this.handleStdout(data);\n });\n\n this.process.stderr?.on('data', (data: Buffer) => {\n logger.debug('CLIServer stderr:', data.toString());\n });\n\n this.process.on('error', (error: Error) => {\n logger.error('CLI server process error:', error);\n if (this.currentReject) {\n this.currentReject(error);\n this.currentReject = null;\n this.currentResolve = null;\n }\n this.emit('error', error);\n });\n\n this.process.on('exit', (code: number | null) => {\n logger.info(`CLI server exited with code: ${code}`);\n if (this.currentReject) {\n this.currentReject(new Error(`CLI server exited unexpectedly with code: ${code}`));\n this.currentReject = null;\n this.currentResolve = null;\n }\n this.process = null;\n this.emit('exit', code);\n });\n\n // Wait for the JVM to initialise (resolves on first stderr/stdout output)\n await waitForProcessReady(this.process, 'CodeQL CLI Server');\n logger.info('CodeQL CLI Server started');\n }\n\n /**\n * Run a CodeQL CLI command through the persistent server.\n *\n * Commands are serialized and queued; only one command runs at a time.\n *\n * @param args - The full command arguments (e.g. `['resolve', 'qlpacks']`).\n * @returns The stdout output from the command.\n */\n runCommand(args: string[]): Promise {\n return new Promise((resolve, reject) => {\n const execute = () => {\n this.executeCommand({ args, reject, resolve });\n };\n\n if (this.commandInProgress) {\n this.commandQueue.push(execute);\n } else {\n execute();\n }\n });\n }\n\n /**\n * Gracefully shut down the CLI server.\n */\n async shutdown(): Promise {\n if (!this.process) {\n return;\n }\n\n logger.info('Shutting down CodeQL CLI Server...');\n\n try {\n // Send shutdown command\n this.process.stdin?.write(JSON.stringify(['shutdown']), 'utf8');\n this.process.stdin?.write(this.nullBuffer);\n } catch (error) {\n logger.warn('Error during CLI server shutdown request:', error);\n }\n\n // Give it a moment, then force kill\n await new Promise((resolve) => {\n const timer = setTimeout(() => {\n if (this.process) {\n this.process.kill('SIGTERM');\n this.process = null;\n }\n resolve();\n }, 2000);\n\n if (this.process) {\n this.process.once('exit', () => {\n clearTimeout(timer);\n this.process = null;\n resolve();\n });\n } else {\n clearTimeout(timer);\n resolve();\n }\n });\n\n this.commandInProgress = false;\n this.commandQueue = [];\n logger.info('CodeQL CLI Server stopped');\n }\n\n /**\n * Whether the CLI server process is running.\n */\n isRunning(): boolean {\n return this.process !== null && !this.process.killed;\n }\n\n // ---- private helpers ----\n\n private executeCommand(cmd: QueuedCommand): void {\n if (!this.process?.stdin) {\n cmd.reject(new Error('CLI server is not running'));\n return;\n }\n\n this.commandInProgress = true;\n this.currentResolve = cmd.resolve;\n this.currentReject = cmd.reject;\n\n try {\n this.process.stdin.write(JSON.stringify(cmd.args), 'utf8');\n this.process.stdin.write(this.nullBuffer);\n } catch (error) {\n this.commandInProgress = false;\n this.currentResolve = null;\n this.currentReject = null;\n cmd.reject(error instanceof Error ? error : new Error(String(error)));\n this.runNext();\n }\n }\n\n private handleStdout(data: Buffer): void {\n this.stdoutBuffer += data.toString();\n\n // Process all NUL-delimited responses in the buffer\n let nulIndex = this.stdoutBuffer.indexOf('\\0');\n while (nulIndex !== -1) {\n const result = this.stdoutBuffer.substring(0, nulIndex);\n this.stdoutBuffer = this.stdoutBuffer.substring(nulIndex + 1);\n\n if (this.currentResolve) {\n this.currentResolve(result);\n this.currentResolve = null;\n this.currentReject = null;\n }\n\n this.commandInProgress = false;\n this.runNext();\n\n nulIndex = this.stdoutBuffer.indexOf('\\0');\n }\n }\n\n private runNext(): void {\n const next = this.commandQueue.shift();\n if (next) {\n next();\n }\n }\n}\n", "/**\n * CodeQL Server Manager\n *\n * Manages the lifecycle of CodeQL background server processes:\n * - language-server (LSP-based QL validation)\n * - query-server2 (query evaluation)\n * - cli-server (JVM reuse for CLI commands)\n *\n * Servers are keyed by a hash of their configuration. When a caller requests\n * a server with a different configuration, the old server is shut down and a\n * new one is started. Session-specific cache directories provide isolation.\n */\n\nimport { mkdirSync } from 'fs';\nimport { join } from 'path';\nimport { randomUUID } from 'crypto';\nimport {\n CLIServerConfig,\n CodeQLServerType,\n computeConfigHash,\n LanguageServerConfig,\n QueryServerConfig,\n ServerConfig,\n} from './server-config';\nimport { CodeQLLanguageServer } from './language-server';\nimport { CodeQLQueryServer } from './query-server';\nimport { CodeQLCLIServer } from './cli-server';\nimport { getProjectTmpDir } from '../utils/temp-dir';\nimport { logger } from '../utils/logger';\n\n/**\n * Entry in the managed servers map.\n */\ninterface ManagedServer {\n configHash: string;\n server: CodeQLCLIServer | CodeQLLanguageServer | CodeQLQueryServer;\n sessionId: string;\n type: CodeQLServerType;\n}\n\n/**\n * Options for creating a session-specific cache layout.\n */\nexport interface SessionCacheOptions {\n /** Override the session ID (defaults to a random UUID). */\n sessionId?: string;\n}\n\n/**\n * Manages CodeQL background server processes with config-aware caching.\n *\n * Callers should use `getLanguageServer()`, `getQueryServer()`, or\n * `getCLIServer()` to obtain a running server. If the requested\n * configuration differs from the currently running server of that type, the\n * old server is stopped and replaced.\n */\nexport class CodeQLServerManager {\n /** Keyed by `CodeQLServerType` \u2014 at most one per type at a time. */\n private servers = new Map();\n\n /** In-flight `getOrRestart` promises, keyed by server type, to serialize concurrent calls. */\n private pendingStarts = new Map>();\n\n /** The session ID used for cache isolation. */\n private sessionId: string;\n\n /** Root directory for session-specific caches. */\n private sessionCacheDir: string;\n\n constructor(options?: SessionCacheOptions) {\n this.sessionId = options?.sessionId ?? randomUUID();\n this.sessionCacheDir = join(\n getProjectTmpDir('codeql-cache'),\n this.sessionId,\n );\n // Pre-create the cache directory tree\n for (const subdir of ['compilation-cache', 'logs', 'query-cache']) {\n mkdirSync(join(this.sessionCacheDir, subdir), { recursive: true });\n }\n logger.info(`CodeQLServerManager initialized (session: ${this.sessionId})`);\n }\n\n // ---- Public API ----\n\n /**\n * Get the current session ID.\n */\n getSessionId(): string {\n return this.sessionId;\n }\n\n /**\n * Get the session-specific cache directory.\n */\n getCacheDir(): string {\n return this.sessionCacheDir;\n }\n\n /**\n * Return the session-specific log directory.\n */\n getLogDir(): string {\n return join(this.sessionCacheDir, 'logs');\n }\n\n /**\n * Get or create a Language Server with the given configuration.\n *\n * If a language server is already running with the same config it is reused.\n * If the config has changed the old server is shut down first.\n */\n async getLanguageServer(config: LanguageServerConfig): Promise {\n const enriched = this.enrichConfig(config) as LanguageServerConfig;\n return this.getOrRestart('language', enriched, () => {\n // Convert LanguageServerConfig to the LanguageServerOptions the existing class expects\n return new CodeQLLanguageServer({\n loglevel: enriched.loglevel,\n logdir: enriched.logdir,\n searchPath: enriched.searchPath,\n synchronous: enriched.synchronous,\n verbosity: enriched.verbosity,\n });\n }) as Promise;\n }\n\n /**\n * Get or create a Query Server with the given configuration.\n */\n async getQueryServer(config: QueryServerConfig): Promise {\n const enriched = this.enrichConfig(config) as QueryServerConfig;\n return this.getOrRestart('query', enriched, () => {\n return new CodeQLQueryServer(enriched);\n }) as Promise;\n }\n\n /**\n * Get or create a CLI Server with the given configuration.\n */\n async getCLIServer(config: CLIServerConfig): Promise {\n const enriched = this.enrichConfig(config) as CLIServerConfig;\n return this.getOrRestart('cli', enriched, () => {\n return new CodeQLCLIServer(enriched);\n }) as Promise;\n }\n\n /**\n * Shut down a specific server type.\n */\n async shutdownServer(type: CodeQLServerType): Promise {\n const managed = this.servers.get(type);\n if (!managed) return;\n\n logger.info(`Shutting down ${type} server (session: ${managed.sessionId})`);\n await this.stopServer(managed);\n this.servers.delete(type);\n }\n\n /**\n * Shut down all managed servers.\n */\n async shutdownAll(): Promise {\n logger.info(`Shutting down all servers for session: ${this.sessionId}`);\n const shutdownPromises = Array.from(this.servers.entries()).map(\n async ([type, managed]) => {\n try {\n await this.stopServer(managed);\n } catch (error) {\n logger.error(`Error shutting down ${type} server:`, error);\n }\n },\n );\n await Promise.all(shutdownPromises);\n this.servers.clear();\n logger.info('All servers shut down');\n }\n\n /**\n * Check whether a server of the given type is currently running.\n */\n isRunning(type: CodeQLServerType): boolean {\n const managed = this.servers.get(type);\n if (!managed) return false;\n return managed.server.isRunning();\n }\n\n /**\n * Get status information for all managed servers.\n */\n getStatus(): Record {\n const status: Record = {\n cli: null,\n language: null,\n query: null,\n };\n for (const [type, managed] of this.servers) {\n status[type] = {\n configHash: managed.configHash,\n running: managed.server.isRunning(),\n sessionId: managed.sessionId,\n };\n }\n return status as Record;\n }\n\n // ---- Private helpers ----\n\n /**\n * Eagerly start the language server so the JVM is warm when the first\n * LSP tool call arrives. Uses the default configuration that\n * `lsp-handlers.ts` / `lsp-diagnostics.ts` would create on the first\n * `getLanguageServer()` call. The server is stored in the managed-servers\n * map and reused by subsequent tool invocations.\n *\n * This is fire-and-forget: errors are logged but do not prevent the MCP\n * server from starting.\n */\n async warmUpLanguageServer(): Promise {\n try {\n // Lazy-import to avoid circular dependency at module level\n const { packageRootDir } = await import('../utils/package-paths');\n const { resolve } = await import('path');\n\n const config: LanguageServerConfig = {\n checkErrors: 'ON_CHANGE',\n loglevel: 'WARN',\n searchPath: resolve(packageRootDir, 'ql'),\n };\n logger.info('Warming up language server (background JVM start)...');\n await this.getLanguageServer(config);\n logger.info('Language server warm-up complete');\n } catch (error) {\n logger.warn('Language server warm-up failed (will retry on first tool call):', error);\n }\n }\n\n /**\n * Eagerly start the CLI server so the JVM is warm when the first\n * `executeCodeQLCommand()` call routes through it.\n *\n * The CLI server uses only session-scoped `commonCaches` and `logdir`,\n * both injected by `enrichConfig()`. Passing an empty config is\n * intentional \u2014 it matches what `executeCodeQLCommand()` will request.\n *\n * Fire-and-forget: errors are logged but do not block startup.\n */\n async warmUpCLIServer(): Promise {\n try {\n logger.info('Warming up CLI server (background JVM start)...');\n await this.getCLIServer({});\n logger.info('CLI server warm-up complete');\n } catch (error) {\n logger.warn('CLI server warm-up failed (will retry on first tool call):', error);\n }\n }\n\n /**\n * Enrich a config with session-specific defaults for commonCaches and logdir.\n */\n private enrichConfig(config: T): T {\n return {\n ...config,\n commonCaches: config.commonCaches ?? this.sessionCacheDir,\n logdir: config.logdir ?? this.getLogDir(),\n };\n }\n\n /**\n * Get an existing server if its config matches, otherwise stop the old\n * one and start a new server.\n *\n * Concurrent calls for the same server type are serialized via\n * `pendingStarts` to avoid spawning duplicate server processes.\n */\n private async getOrRestart(\n type: CodeQLServerType,\n config: ServerConfig,\n factory: () => CodeQLCLIServer | CodeQLLanguageServer | CodeQLQueryServer,\n ): Promise {\n // If another call is already starting a server of this type, wait for it\n // to settle (success or failure) and then re-check whether the result is\n // still usable.\n const inflight = this.pendingStarts.get(type);\n if (inflight) {\n try { await inflight; } catch { /* swallow \u2014 original caller handles the rejection */ }\n }\n\n const work = this.doGetOrRestart(type, config, factory);\n this.pendingStarts.set(type, work);\n try {\n return await work;\n } finally {\n // Ensure `work` has settled before removing the pendingStarts entry so\n // that concurrent callers waiting on the same promise see a consistent\n // map state. The try/catch avoids re-throwing a rejection that the\n // outer `try` block already handles.\n try { await work; } catch { /* already handled */ }\n if (this.pendingStarts.get(type) === work) {\n this.pendingStarts.delete(type);\n }\n }\n }\n\n /**\n * Core logic for getOrRestart, separated to allow serialization.\n */\n private async doGetOrRestart(\n type: CodeQLServerType,\n config: ServerConfig,\n factory: () => CodeQLCLIServer | CodeQLLanguageServer | CodeQLQueryServer,\n ): Promise {\n const hash = computeConfigHash(type, config);\n const existing = this.servers.get(type);\n\n // Reuse if config matches and server is still running\n if (existing && existing.configHash === hash && existing.server.isRunning()) {\n logger.debug(`Reusing existing ${type} server (hash: ${hash.substring(0, 8)})`);\n return existing.server;\n }\n\n // Config changed or server died \u2014 stop the old one\n if (existing) {\n logger.info(`${type} server config changed or dead, restarting...`);\n await this.stopServer(existing);\n this.servers.delete(type);\n }\n\n // Start a new server\n const server = factory();\n await server.start();\n\n this.servers.set(type, {\n configHash: hash,\n server,\n sessionId: this.sessionId,\n type,\n });\n\n logger.info(`${type} server started (hash: ${hash.substring(0, 8)})`);\n return server;\n }\n\n /**\n * Stop a managed server, ignoring errors.\n */\n private async stopServer(managed: ManagedServer): Promise {\n try {\n await managed.server.shutdown();\n } catch (error) {\n logger.warn(`Error stopping ${managed.type} server:`, error);\n // Best-effort \u2014 don't propagate\n }\n }\n}\n\n/**\n * Global server manager singleton.\n *\n * Initialized lazily by `getServerManager()`. The MCP server entry point\n * should call `initServerManager()` at startup and `shutdownServerManager()`\n * at graceful shutdown.\n */\nlet globalServerManager: CodeQLServerManager | null = null;\n\n/**\n * Initialize the global server manager (idempotent).\n */\nexport function initServerManager(options?: SessionCacheOptions): CodeQLServerManager {\n if (!globalServerManager) {\n globalServerManager = new CodeQLServerManager(options);\n }\n return globalServerManager;\n}\n\n/**\n * Get the global server manager, creating it if needed.\n */\nexport function getServerManager(): CodeQLServerManager {\n if (!globalServerManager) {\n globalServerManager = new CodeQLServerManager();\n }\n return globalServerManager;\n}\n\n/**\n * Shut down the global server manager and all its servers.\n */\nexport async function shutdownServerManager(): Promise {\n if (globalServerManager) {\n await globalServerManager.shutdownAll();\n globalServerManager = null;\n }\n}\n\n/**\n * Reset the global server manager (for testing only).\n */\nexport function resetServerManager(): void {\n globalServerManager = null;\n}\n", "/**\n * Generic CLI command execution utilities for CodeQL and QLT commands\n */\n\nimport { execFile } from 'child_process';\nimport { existsSync } from 'fs';\nimport { basename, delimiter, dirname, isAbsolute } from 'path';\nimport { promisify } from 'util';\nimport { logger } from '../utils/logger';\n\nconst execFileAsync = promisify(execFile);\n\nexport interface CLIExecutionResult {\n stdout: string;\n stderr: string;\n success: boolean;\n error?: string;\n exitCode?: number;\n}\n\nexport interface CLIExecutionOptions {\n command: string;\n args: string[];\n cwd?: string;\n timeout?: number;\n env?: Record;\n}\n\n// Whitelist of allowed commands to prevent arbitrary command execution\nconst ALLOWED_COMMANDS = new Set([\n 'codeql',\n 'git',\n 'node',\n 'npm',\n 'qlt',\n 'which'\n]);\n\n// Additional commands allowed in test environments\nlet testCommands: Set | null = null;\n\n// Whitelist of safe environment variables to pass to child processes\n// This prevents potentially malicious environment variables from being passed through\nconst SAFE_ENV_VARS = [\n 'HOME', // User home directory\n 'LANG', // Locale setting\n 'LC_ALL', // Locale setting\n 'LC_CTYPE', // Locale setting\n 'PATH', // Required to find executables\n 'SHELL', // User's shell (Unix)\n 'TEMP', // Temporary directory (Windows)\n 'TERM', // Terminal type (Unix)\n 'TMP', // Temporary directory (Windows)\n 'TMPDIR', // Temporary directory (Unix)\n 'USER', // Current user (Unix)\n 'USERNAME', // Current user (Windows)\n] as const;\n\n// Whitelist of safe environment variable prefixes\n// These are needed for CodeQL and Node.js functionality\nconst SAFE_ENV_PREFIXES = [\n 'CODEQL_', // CodeQL-specific variables\n 'NODE_', // Node.js-specific variables (for npm, etc.)\n] as const;\n\n// Pattern for dangerous control characters in CLI arguments\n// Rejected characters:\n// \\x01-\\x08: SOH through BS (start of heading, text, null control chars, backspace)\n// \\x0B: Vertical tab - rarely used legitimately, can cause display issues\n// \\x0C: Form feed - can cause unexpected page breaks in output\n// \\x0E-\\x1F: SO through US (shift out/in, device controls, separators)\n// Allowed characters:\n// \\x00: Null byte - handled separately for clearer error messaging\n// \\x09: Horizontal tab - commonly used in file paths and arguments\n// \\x0A: Newline (LF) - may appear in multi-line arguments\n// \\x0D: Carriage return (CR) - may appear with newlines on Windows\n// eslint-disable-next-line no-control-regex\nconst DANGEROUS_CONTROL_CHARS = /[\\x01-\\x08\\x0B\\x0C\\x0E-\\x1F]/;\n\n/**\n * Enable test-specific commands for testing purposes\n * This should only be called in test environments\n */\nexport function enableTestCommands(): void {\n testCommands = new Set([\n 'cat',\n 'echo',\n 'ls',\n 'sh',\n 'sleep'\n ]);\n}\n\n/**\n * Disable test-specific commands\n */\nexport function disableTestCommands(): void {\n testCommands = null;\n}\n\n/**\n * Check if a command is allowed\n */\nfunction isCommandAllowed(command: string): boolean {\n return ALLOWED_COMMANDS.has(command) || (testCommands !== null && testCommands.has(command));\n}\n\n// Resolved CodeQL binary directory from CODEQL_PATH.\n// When set, this directory is prepended to PATH for all child processes\n// so that `execFile('codeql', ...)` finds the correct binary via execvp().\n// Using PATH lookup (rather than an absolute path) is essential because\n// execvp() handles shell-script shebangs correctly, whereas passing an\n// absolute path to execFile() can fail with ENOENT for shell scripts.\nlet resolvedCodeQLDir: string | null = null;\n\n// Cached result from resolveCodeQLBinary(). `undefined` means not yet resolved.\nlet resolvedBinaryResult: string | undefined;\n\n/**\n * Resolve the CodeQL CLI binary path.\n *\n * Resolution order:\n * 1. `CODEQL_PATH` environment variable \u2014 must point to an existing file whose\n * basename is `codeql` (or `codeql.exe` / `codeql.cmd` on Windows).\n * The parent directory is prepended to PATH for child processes.\n * 2. Falls back to the bare `codeql` command (resolved via PATH at exec time).\n *\n * The resolved value is cached for the lifetime of the process. Call this once\n * at startup; subsequent calls are a no-op and return the cached value.\n */\nexport function resolveCodeQLBinary(): string {\n // Short-circuit if already resolved\n if (resolvedBinaryResult !== undefined) {\n return resolvedBinaryResult;\n }\n\n const envPath = process.env.CODEQL_PATH;\n\n if (!envPath) {\n resolvedCodeQLDir = null;\n resolvedBinaryResult = 'codeql';\n return resolvedBinaryResult;\n }\n\n // Validate the path points to a plausible CodeQL binary\n const base = basename(envPath).toLowerCase();\n const validBaseNames = ['codeql', 'codeql.exe', 'codeql.cmd'];\n if (!validBaseNames.includes(base)) {\n throw new Error(\n `CODEQL_PATH must point to a CodeQL CLI binary (expected basename: codeql), got: ${base}`\n );\n }\n\n // Require an absolute path to avoid ambiguity\n if (!isAbsolute(envPath)) {\n throw new Error(\n `CODEQL_PATH must be an absolute path, got: ${envPath}`\n );\n }\n\n // Verify the file exists\n if (!existsSync(envPath)) {\n throw new Error(\n `CODEQL_PATH points to a file that does not exist: ${envPath}`\n );\n }\n\n resolvedCodeQLDir = dirname(envPath);\n resolvedBinaryResult = 'codeql';\n logger.info(`CodeQL CLI resolved via CODEQL_PATH: ${envPath} (dir: ${resolvedCodeQLDir})`);\n return resolvedBinaryResult;\n}\n\n/**\n * Get the currently resolved CodeQL binary directory, or null if using PATH.\n */\nexport function getResolvedCodeQLDir(): string | null {\n return resolvedCodeQLDir;\n}\n\n/**\n * Reset the resolved CodeQL binary to the default (for testing only).\n */\nexport function resetResolvedCodeQLBinary(): void {\n resolvedCodeQLDir = null;\n resolvedBinaryResult = undefined;\n}\n\n/**\n * Validate that the resolved CodeQL binary is actually callable.\n *\n * Runs `codeql version --format=terse` and verifies the process exits\n * successfully. This catches the case where `CODEQL_PATH` is unset and\n * `codeql` is not on PATH \u2014 the server would otherwise start normally\n * but every tool invocation would fail.\n *\n * @returns The version string reported by the CodeQL CLI.\n * @throws Error if the binary is not reachable or returns a non-zero exit code.\n */\nexport async function validateCodeQLBinaryReachable(): Promise {\n const binary = resolvedBinaryResult ?? 'codeql';\n const env = { ...process.env };\n if (resolvedCodeQLDir) {\n env.PATH = resolvedCodeQLDir + delimiter + (env.PATH || '');\n }\n\n try {\n const { stdout } = await execFileAsync(binary, ['version', '--format=terse'], {\n env,\n timeout: 15_000,\n });\n return stdout.trim();\n } catch (err: unknown) {\n const message = err instanceof Error ? err.message : String(err);\n throw new Error(\n `CodeQL CLI is not reachable (binary: ${binary}). ` +\n `Ensure codeql is on PATH or set the CODEQL_PATH environment variable ` +\n `to the absolute path of the CodeQL CLI binary. Details: ${message}`\n );\n }\n}\n\n/**\n * Sanitize a CLI argument to prevent potential issues with special characters.\n * \n * While execFile() does not spawn a shell (preventing shell injection), we still\n * validate arguments to:\n * 1. Reject null bytes that could truncate strings in C-based commands\n * 2. Reject control characters that could cause unexpected behavior\n * 3. Provide defense-in-depth against potential issues\n * \n * @param arg - The argument to sanitize\n * @returns The sanitized argument\n * @throws Error if the argument contains dangerous characters\n */\nexport function sanitizeCLIArgument(arg: string): string {\n // Reject null bytes - these can truncate strings in C-based commands\n // Error message intentionally excludes argument content to avoid logging potentially sensitive data\n if (arg.includes('\\0')) {\n throw new Error(`CLI argument contains null byte: argument rejected for security`);\n }\n \n // Reject control characters using the module-level constant pattern\n if (DANGEROUS_CONTROL_CHARS.test(arg)) {\n // Error message intentionally excludes argument content to avoid logging potentially sensitive data\n throw new Error(`CLI argument contains control characters: argument rejected for security`);\n }\n \n return arg;\n}\n\n/**\n * Sanitize an array of CLI arguments\n * @param args - The arguments to sanitize\n * @returns The sanitized arguments\n * @throws Error if any argument contains dangerous characters\n */\nexport function sanitizeCLIArguments(args: string[]): string[] {\n return args.map(sanitizeCLIArgument);\n}\n\n/**\n * Filter environment variables to only include safe ones\n * This prevents potentially malicious environment variables from being passed to child processes\n */\nfunction getSafeEnvironment(additionalEnv?: Record): Record {\n const safeEnv: Record = {};\n \n // Copy whitelisted environment variables from process.env\n for (const key of SAFE_ENV_VARS) {\n if (process.env[key] !== undefined) {\n safeEnv[key] = process.env[key]!;\n }\n }\n \n // Copy environment variables with whitelisted prefixes\n for (const [key, value] of Object.entries(process.env)) {\n if (value !== undefined && SAFE_ENV_PREFIXES.some(prefix => key.startsWith(prefix))) {\n safeEnv[key] = value;\n }\n }\n \n // When CODEQL_PATH was set, prepend the resolved directory to PATH so that\n // `execFile('codeql', ...)` finds the user-specified binary via execvp().\n // This approach (PATH manipulation + bare command name) is essential because\n // execvp() handles shell-script shebangs correctly, whereas passing an\n // absolute path to execFile() fails with ENOENT for shell-script launchers.\n if (resolvedCodeQLDir && safeEnv.PATH) {\n safeEnv.PATH = `${resolvedCodeQLDir}${delimiter}${safeEnv.PATH}`;\n } else if (resolvedCodeQLDir) {\n safeEnv.PATH = resolvedCodeQLDir;\n }\n \n // Merge with explicitly provided environment variables\n // These are trusted as they come from the application code, not external sources\n if (additionalEnv) {\n Object.assign(safeEnv, additionalEnv);\n }\n \n return safeEnv;\n}\n\n/**\n * Execute a CLI command and return the result.\n * \n * Security: This function uses execFile() instead of exec() to avoid shell interpretation.\n * Arguments are passed directly to the executable as an array, preventing shell injection.\n * Additional security measures include:\n * - Command whitelist validation\n * - Shell metacharacter detection in command names\n * - CLI argument sanitization (null bytes, control characters)\n * - Environment variable filtering\n */\nexport async function executeCLICommand(options: CLIExecutionOptions): Promise {\n try {\n const { command, args, cwd, timeout = 300000, env } = options; // 5 minute default timeout\n \n // Validate command is in the whitelist to prevent arbitrary command execution\n if (!isCommandAllowed(command)) {\n throw new Error(`Command not allowed: ${command}. Only whitelisted commands can be executed.`);\n }\n \n // Validate command to ensure it doesn't contain shell metacharacters\n if (command.includes(';') || command.includes('|') || command.includes('&') || \n command.includes('$') || command.includes('`') || command.includes('\\n') ||\n command.includes('\\r')) {\n throw new Error(`Invalid command: contains shell metacharacters: ${command}`);\n }\n \n // Sanitize CLI arguments to prevent issues with special characters\n // This provides defense-in-depth even though execFile() doesn't use a shell\n const sanitizedArgs = sanitizeCLIArguments(args);\n \n logger.info(`Executing CLI command: ${command}`, { args: sanitizedArgs, cwd, timeout });\n \n const execOptions = {\n cwd,\n timeout,\n env: getSafeEnvironment(env),\n };\n \n // execFile() is used instead of exec() to avoid shell interpretation\n // Arguments are passed as an array, not interpolated into a command string\n const { stdout, stderr } = await execFileAsync(command, sanitizedArgs, execOptions);\n\n return {\n stdout,\n stderr,\n success: true,\n exitCode: 0\n };\n\n } catch (error: unknown) {\n logger.error('CLI command execution failed:', error);\n \n const err = error as Error & { code?: number; stdout?: string; stderr?: string };\n const errorMessage = err instanceof Error ? err.message : String(error);\n const exitCode = err.code || 1;\n \n return {\n stdout: err.stdout || '',\n stderr: err.stderr || errorMessage,\n success: false,\n error: errorMessage,\n exitCode\n };\n }\n}\n\n/**\n * Build CodeQL command arguments with proper escaping\n */\nexport function buildCodeQLArgs(subcommand: string, options: Record): string[] {\n const args = [subcommand];\n \n // Single-letter parameters that should use -key=value format (with equals sign)\n // Note: CodeQL CLI uses -t=key=value format for metadata, not -t key=value\n const singleLetterParams = new Set(['t', 'o', 'v', 'q', 'h', 'J']);\n \n for (const [key, value] of Object.entries(options)) {\n if (value === undefined || value === null) {\n continue;\n }\n \n const isSingleLetter = key.length === 1 && singleLetterParams.has(key);\n \n if (typeof value === 'boolean') {\n if (value) {\n args.push(isSingleLetter ? `-${key}` : `--${key}`);\n }\n } else if (Array.isArray(value)) {\n // Handle array values (e.g., multiple -t flags for metadata)\n for (const item of value) {\n if (isSingleLetter) {\n // For single-letter params like -t, use -key=value format\n args.push(`-${key}=${String(item)}`);\n } else {\n // For long params, use --key=value format\n args.push(`--${key}=${String(item)}`);\n }\n }\n } else {\n // Handle string, number, and other values\n if (isSingleLetter) {\n // For single-letter params, use -key=value format\n args.push(`-${key}=${String(value)}`);\n } else {\n args.push(`--${key}=${String(value)}`);\n }\n }\n }\n \n return args;\n}\n\n/**\n * Build QLT command arguments with proper escaping\n */\nexport function buildQLTArgs(subcommand: string, options: Record): string[] {\n const args = [subcommand];\n \n for (const [key, value] of Object.entries(options)) {\n if (value === undefined || value === null) {\n continue;\n }\n \n if (typeof value === 'boolean') {\n if (value) {\n args.push(`--${key}`);\n }\n } else if (Array.isArray(value)) {\n // Handle array values\n for (const item of value) {\n args.push(`--${key}`, String(item));\n }\n } else {\n // Handle string, number, and other values\n args.push(`--${key}`, String(value));\n }\n }\n \n return args;\n}\n\n/**\n * CodeQL subcommands that MUST run as fresh processes.\n *\n * These cannot use the cli-server because they:\n * - Spawn extractors or other long-running child processes (database create, test extract)\n * - Produce multi-event NUL-delimited streams (test run)\n * - Are compound orchestration commands (database analyze)\n *\n * Everything else is routed through the persistent cli-server JVM for\n * sub-second execution instead of 2-5 s JVM cold-start per invocation.\n */\nconst FRESH_PROCESS_SUBCOMMANDS = new Set([\n 'database analyze',\n 'database create',\n 'test extract',\n 'test run',\n]);\n\n/**\n * Execute a CodeQL command.\n *\n * By default, commands are routed through the persistent `codeql execute\n * cli-server` process managed by {@link CodeQLServerManager}, eliminating\n * repeated JVM startup overhead (~2-5 s savings per call).\n *\n * Commands listed in {@link FRESH_PROCESS_SUBCOMMANDS} (e.g. `database create`,\n * `test run`) are always executed as fresh processes because they either spawn\n * child extractors, produce streaming output, or require a dedicated working\n * directory.\n *\n * If the cli-server is not available (e.g. during early startup before\n * `initServerManager()` is called), the function falls back transparently to\n * a fresh process.\n */\nexport async function executeCodeQLCommand(\n subcommand: string,\n options: Record,\n additionalArgs: string[] = [],\n cwd?: string\n): Promise {\n const args = buildCodeQLArgs(subcommand, options);\n args.push(...additionalArgs);\n\n // Determine whether this subcommand can use the persistent cli-server.\n // Commands that need a specific CWD also must use a fresh process because\n // the cli-server's CWD is fixed at startup.\n const canUseCLIServer = !FRESH_PROCESS_SUBCOMMANDS.has(subcommand) && !cwd;\n\n if (canUseCLIServer) {\n try {\n // Lazy-import to avoid circular dependency at module level.\n // Use getServerManager() (not initServerManager()) \u2014 if the manager\n // hasn't been initialized yet (e.g. during tests or early startup),\n // this creates one, but we only attempt to *use* the cli-server if\n // it is already running (warmed up at MCP server startup). We never\n // block on starting a new cli-server here \u2014 that would add JVM\n // startup latency to the first fresh-process-fallback call.\n const { getServerManager } = await import('./server-manager');\n const manager = getServerManager();\n\n if (manager.isRunning('cli')) {\n const cliServer = await manager.getCLIServer({});\n const sanitizedArgs = sanitizeCLIArguments(args);\n\n logger.info(`Executing CodeQL command via cli-server: ${subcommand}`, { args: sanitizedArgs });\n\n const stdout = await cliServer.runCommand(sanitizedArgs);\n\n return {\n stdout,\n stderr: '',\n success: true,\n exitCode: 0,\n };\n } else {\n logger.debug(`cli-server not yet running for \"${subcommand}\", using fresh process`);\n }\n } catch (error) {\n // If the cli-server call fails, check whether it's a command-level\n // error (the CLI returned non-zero) or a transport/startup error.\n // For transport errors we fall back to a fresh process; for command\n // errors we return the failure directly.\n const message = error instanceof Error ? error.message : String(error);\n\n // Transport-level errors that warrant a fallback:\n if (message.includes('CLI server is not running') ||\n message.includes('CLI server exited') ||\n message.includes('failed to start')) {\n logger.warn(`cli-server unavailable for \"${subcommand}\", falling back to fresh process: ${message}`);\n // Fall through to fresh-process execution below\n } else {\n // Command-level error \u2014 return it as a failed result\n logger.error(`cli-server command failed for \"${subcommand}\": ${message}`);\n return {\n stdout: '',\n stderr: message,\n success: false,\n error: message,\n exitCode: 1,\n };\n }\n }\n }\n\n // Fresh-process execution (for FRESH_PROCESS_SUBCOMMANDS, CWD-specific\n // calls, or as a fallback when the cli-server is unavailable).\n // Use 0 (no timeout) because CodeQL operations such as query evaluation,\n // database analysis, profiling, and test runs are inherently long-running\n // and should not be killed by a process timeout.\n return executeCLICommand({\n command: 'codeql',\n args,\n cwd,\n timeout: 0\n });\n}\n\n/**\n * Execute a QLT command\n */\nexport async function executeQLTCommand(\n subcommand: string, \n options: Record, \n additionalArgs: string[] = []\n): Promise {\n const args = buildQLTArgs(subcommand, options);\n args.push(...additionalArgs);\n \n return executeCLICommand({\n command: 'qlt',\n args\n });\n}\n\n/**\n * Get help text for a CLI command\n */\nexport async function getCommandHelp(command: string, subcommand?: string): Promise {\n const args = subcommand ? [subcommand, '--help'] : ['--help'];\n \n const result = await executeCLICommand({\n command,\n args\n });\n \n return result.stdout || result.stderr || 'No help available';\n}\n\n/**\n * Validate that a command exists on the system.\n */\nexport async function validateCommandExists(command: string): Promise {\n try {\n const result = await executeCLICommand({\n command: 'which',\n args: [command]\n });\n return result.success;\n } catch {\n return false;\n }\n}", "/**\n * CodeQL Development MCP McpServer\n * Main entry point for the server\n */\n\nimport { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';\nimport { StreamableHTTPServerTransport } from '@modelcontextprotocol/sdk/server/streamableHttp.js';\nimport express from 'express';\nimport cors from 'cors';\nimport dotenv from 'dotenv';\nimport { realpathSync } from 'fs';\nimport { resolve } from 'path';\nimport { pathToFileURL } from 'url';\nimport { registerCodeQLTools, registerCodeQLResources } from './tools';\nimport { registerLSPTools } from './tools/lsp';\nimport { registerLanguageResources } from './resources/language-resources';\nimport { registerWorkflowPrompts } from './prompts/workflow-prompts';\nimport { registerMonitoringTools } from './tools/monitoring-tools';\nimport { sessionDataManager } from './lib/session-data-manager';\nimport { resolveCodeQLBinary, validateCodeQLBinaryReachable } from './lib/cli-executor';\nimport { initServerManager, shutdownServerManager } from './lib/server-manager';\nimport { packageRootDir } from './utils/package-paths';\nimport { logger } from './utils/logger';\n\n// Load environment variables from a .env file co-located with the package root.\n// Uses the package directory (not CWD) so that npm-installed users don't\n// accidentally inherit a .env from their project.\n// Set DOTENV_CONFIG_QUIET to suppress the dotenv banner that would otherwise\n// leak to stdout and corrupt the MCP stdio JSON-RPC channel.\ndotenv.config({ path: resolve(packageRootDir, '.env'), quiet: true });\n\nconst PACKAGE_NAME = 'codeql-development-mcp-server';\nconst VERSION = '2.24.1';\n\n/**\n * Start the MCP server\n */\nexport async function startServer(mode: 'stdio' | 'http' = 'stdio'): Promise {\n logger.info(`Starting CodeQL Development MCP McpServer v${VERSION} in ${mode} mode`);\n\n // Resolve the CodeQL CLI binary path (honors CODEQL_PATH env var).\n // This must happen before any tool registration so that all CodeQL commands\n // use the user-specified binary.\n const codeqlBinary = resolveCodeQLBinary();\n logger.info(`CodeQL CLI binary: ${codeqlBinary}`);\n\n // Validate that the resolved binary is actually callable. This catches\n // misconfigurations early (e.g. codeql not on PATH and CODEQL_PATH unset)\n // instead of failing silently and producing confusing tool-level errors.\n const codeqlVersion = await validateCodeQLBinaryReachable();\n logger.info(`CodeQL CLI version: ${codeqlVersion}`);\n\n const server = new McpServer({\n name: PACKAGE_NAME,\n version: VERSION,\n });\n\n // Register CodeQL tools (legacy high-level helpers)\n registerCodeQLTools(server);\n\n // Register LSP-based tools (diagnostics, completion, definition, references)\n registerLSPTools(server);\n\n // Register CodeQL resources (static guides)\n registerCodeQLResources(server);\n\n // Register language-specific resources (AST references, security patterns)\n registerLanguageResources(server);\n\n // Register high-level workflow prompts (complete development workflows)\n registerWorkflowPrompts(server);\n\n // Register monitoring and reporting tools\n registerMonitoringTools(server);\n\n // Initialize session data manager\n await sessionDataManager.initialize();\n\n // Initialize the CodeQL background server manager and eagerly start the\n // language server and CLI server JVMs so they are warm when the first tool\n // calls arrive. This avoids 2-60 s cold-start penalties per JVM.\n const manager = initServerManager();\n Promise.all([\n manager.warmUpLanguageServer(),\n manager.warmUpCLIServer(),\n ]).catch(() => { /* individual errors logged inside each warm-up method */ });\n\n if (mode === 'stdio') {\n const transport = new StdioServerTransport();\n await server.connect(transport);\n logger.info('McpServer started successfully on STDIO transport');\n } else {\n // HTTP mode\n const app = express();\n app.use(cors());\n app.use(express.json());\n\n const transport = new StreamableHTTPServerTransport({\n sessionIdGenerator: () => Math.random().toString(36).substring(7),\n });\n await server.connect(transport);\n\n app.all('/mcp', (req, res) => {\n transport.handleRequest(req, res, req.body).catch((err) => {\n logger.error('Error handling MCP request:', err);\n if (!res.headersSent) {\n res.status(500).json({ error: 'Internal McpServer Error' });\n }\n });\n });\n\n app.get('/', (_req, res) => {\n res.json({\n name: PACKAGE_NAME,\n version: VERSION,\n description: 'CodeQL Development MCP McpServer',\n status: 'running',\n });\n });\n\n const host = process.env.HTTP_HOST || 'localhost';\n const port = Number(process.env.HTTP_PORT || process.env.PORT) || 3000;\n \n // Return a promise that keeps the process alive\n return new Promise((resolve, reject) => {\n const httpServer = app.listen(port, host, () => {\n logger.info(`HTTP server listening on http://${host}:${port}/mcp`);\n resolve();\n });\n \n httpServer.on('error', (error) => {\n logger.error('HTTP server error:', error);\n reject(error);\n });\n });\n }\n\n setupGracefulShutdown(server);\n return server;\n}\n\n/**\n * Set up graceful shutdown handling\n */\nfunction setupGracefulShutdown(server: McpServer): void {\n const shutdown = async () => {\n logger.info('Shutting down server...');\n try {\n // Shut down all CodeQL background servers first\n await shutdownServerManager();\n await server.close();\n logger.info('McpServer closed gracefully');\n process.exit(0);\n } catch (error) {\n logger.error('Error during shutdown:', error);\n process.exit(1);\n }\n };\n\n process.on('SIGINT', shutdown);\n process.on('SIGTERM', shutdown);\n}\n\n/**\n * Main function to start the server\n */\nasync function main(): Promise {\n try {\n const transportMode = (process.env.TRANSPORT_MODE || 'stdio').toLowerCase();\n const mode: 'stdio' | 'http' = transportMode === 'http' ? 'http' : 'stdio';\n await startServer(mode);\n } catch (error) {\n logger.error('Failed to start server:', error);\n process.exit(1);\n }\n}\n\n// Start the server if this file is run directly.\n// Use realpathSync to resolve npm/npx symlinks so the guard works for both\n// direct invocation and globally-installed npm bin entries.\nconst scriptPath = process.argv[1] ? realpathSync(resolve(process.argv[1])) : undefined;\nif (scriptPath && import.meta.url === pathToFileURL(scriptPath).href) {\n main();\n}\n", "/**\n * CodeQL BQRS decode tool\n */\n\nimport { z } from 'zod';\nimport { CLIToolDefinition, createCodeQLSchemas, createBQRSResultProcessor } from '../../lib/cli-tool-registry';\n\nexport const codeqlBqrsDecodeTool: CLIToolDefinition = {\n name: 'codeql_bqrs_decode',\n description: 'Decode BQRS result files to human-readable formats',\n command: 'codeql',\n subcommand: 'bqrs decode',\n inputSchema: {\n files: z.array(z.string()).describe('BQRS file(s) to decode'),\n output: createCodeQLSchemas.output(),\n format: z.enum(['csv', 'json']).optional().describe('Output format'),\n 'max-paths': z.number().optional().describe('Maximum number of paths to output'),\n 'start-at': z.number().optional().describe('Start output at result number'),\n 'max-results': z.number().optional().describe('Maximum number of results'),\n verbose: createCodeQLSchemas.verbose(),\n additionalArgs: createCodeQLSchemas.additionalArgs()\n },\n examples: [\n 'codeql bqrs decode --format=csv --output=results.csv results.bqrs',\n 'codeql bqrs decode --format=json --max-results=100 results.bqrs'\n ],\n resultProcessor: createBQRSResultProcessor()\n};", "/**\n * Generic tool registry for creating MCP tools from CLI command definitions\n */\n\nimport { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport { z } from 'zod';\nimport { executeCodeQLCommand, executeQLTCommand, CLIExecutionResult } from './cli-executor';\nimport { logger } from '../utils/logger';\nimport { evaluateQueryResults, QueryEvaluationResult, extractQueryMetadata } from './query-results-evaluator';\nimport { getOrCreateLogDirectory } from './log-directory-manager';\nimport { getUserWorkspaceDir, packageRootDir, resolveToolQueryPackPath } from '../utils/package-paths';\nimport { writeFileSync, rmSync, existsSync, mkdirSync } from 'fs';\nimport { basename, dirname, isAbsolute, join, resolve } from 'path';\nimport { createProjectTempDir } from '../utils/temp-dir';\n\nexport type { CLIExecutionResult } from './cli-executor';\n\nexport interface CLIToolDefinition {\n name: string;\n description: string;\n command: 'codeql' | 'qlt';\n subcommand: string;\n inputSchema: Record;\n examples?: string[];\n resultProcessor?: (_result: CLIExecutionResult, _params: Record) => string;\n}\n\n/**\n * Default result processor that formats CLI output appropriately\n */\nexport const defaultCLIResultProcessor = (\n result: CLIExecutionResult, \n _params: Record\n): string => {\n if (!result.success) {\n return `Command failed (exit code ${result.exitCode || 'unknown'}):\\n${result.error || result.stderr}`;\n }\n \n let output = '';\n \n if (result.stdout) {\n output += result.stdout;\n }\n \n if (result.stderr) {\n if (output) {\n output += '\\n\\nWarnings/Info:\\n';\n }\n output += result.stderr;\n }\n \n if (!output) {\n output = 'Command executed successfully (no output)';\n }\n \n return output;\n};\n\n/**\n * Register a CLI tool with the MCP server\n */\nexport function registerCLITool(server: McpServer, definition: CLIToolDefinition): void {\n const {\n name,\n description,\n command,\n subcommand,\n inputSchema,\n resultProcessor = defaultCLIResultProcessor\n } = definition;\n\n server.tool(\n name,\n description,\n inputSchema,\n async (params: Record) => {\n // Track temporary directories for cleanup\n const tempDirsToCleanup: string[] = [];\n \n try {\n logger.info(`Executing CLI tool: ${name}`, { command, subcommand, params });\n\n // Separate positional arguments from named options\n // Extract tool-specific parameters that should not be passed to CLI\n // Note: format is extracted for tools that use it internally but not on CLI\n // For codeql_bqrs_interpret, codeql_bqrs_decode, codeql_generate_query-help, and codeql_database_analyze, format should be passed to CLI\n const formatShouldBePassedToCLI = name === 'codeql_bqrs_interpret' || name === 'codeql_bqrs_decode' || name === 'codeql_generate_query-help' || name === 'codeql_database_analyze';\n \n const extractedParams = formatShouldBePassedToCLI\n ? {\n _positional: params._positional || [],\n files: params.files,\n file: params.file,\n dir: params.dir,\n packDir: params.packDir,\n tests: params.tests,\n query: params.query,\n queryName: params.queryName,\n queryLanguage: params.queryLanguage,\n queryPack: params.queryPack,\n sourceFiles: params.sourceFiles,\n sourceFunction: params.sourceFunction,\n targetFunction: params.targetFunction,\n interpretedOutput: params.interpretedOutput,\n evaluationFunction: params.evaluationFunction,\n evaluationOutput: params.evaluationOutput,\n directory: params.directory,\n logDir: params.logDir,\n qlref: params.qlref\n }\n : {\n _positional: params._positional || [],\n files: params.files,\n file: params.file,\n dir: params.dir,\n packDir: params.packDir,\n tests: params.tests,\n query: params.query,\n queryName: params.queryName,\n queryLanguage: params.queryLanguage,\n queryPack: params.queryPack, \n sourceFiles: params.sourceFiles,\n sourceFunction: params.sourceFunction,\n targetFunction: params.targetFunction,\n format: params.format,\n interpretedOutput: params.interpretedOutput,\n evaluationFunction: params.evaluationFunction,\n evaluationOutput: params.evaluationOutput,\n directory: params.directory,\n logDir: params.logDir,\n qlref: params.qlref\n };\n\n const {\n _positional = [],\n files,\n file,\n dir,\n packDir,\n tests,\n query,\n queryName,\n queryLanguage: _queryLanguage,\n queryPack: _queryPack,\n sourceFiles,\n sourceFunction,\n targetFunction,\n format: _format,\n interpretedOutput: _interpretedOutput,\n evaluationFunction: _evaluationFunction,\n evaluationOutput: _evaluationOutput,\n directory,\n logDir: customLogDir,\n qlref,\n } = extractedParams;\n\n // Get remaining options (everything not extracted above)\n const options = {...params};\n Object.keys(extractedParams).forEach(key => delete options[key]);\n let positionalArgs = Array.isArray(_positional) ? _positional as string[] : [_positional as string];\n\n // Handle files parameter as positional arguments for certain tools\n if (files && Array.isArray(files)) {\n positionalArgs = [...positionalArgs, ...files as string[]];\n }\n\n // Handle file parameter as positional argument for BQRS tools\n if (file && name.startsWith('codeql_bqrs_')) {\n positionalArgs = [...positionalArgs, file as string];\n }\n\n // Handle qlref parameter as positional argument for resolve qlref tool\n if (qlref && name === 'codeql_resolve_qlref') {\n positionalArgs = [...positionalArgs, qlref as string];\n }\n\n // Handle database parameter as positional argument for resolve database tool\n if (options.database && name === 'codeql_resolve_database') {\n positionalArgs = [...positionalArgs, options.database as string];\n delete options.database;\n }\n\n // Handle database parameter as positional argument for database create tool\n if (options.database && name === 'codeql_database_create') {\n positionalArgs = [...positionalArgs, options.database as string];\n delete options.database;\n }\n\n // Handle database and queries parameters as positional arguments for database analyze tool\n if (name === 'codeql_database_analyze') {\n if (options.database) {\n positionalArgs = [...positionalArgs, options.database as string];\n delete options.database;\n }\n if (options.queries) {\n positionalArgs = [...positionalArgs, options.queries as string];\n delete options.queries;\n }\n }\n\n // Handle query parameter as positional argument for generate query-help tool\n if (query && name === 'codeql_generate_query-help') {\n positionalArgs = [...positionalArgs, query as string];\n }\n\n // Handle dir parameter as positional argument for pack tools\n if (dir && (name === 'codeql_pack_ls')) {\n positionalArgs = [...positionalArgs, dir as string];\n }\n \n // Handle tool-specific parameters using switch pattern for better maintainability\n switch (name) {\n case 'codeql_test_accept':\n case 'codeql_test_extract':\n case 'codeql_test_run':\n case 'codeql_resolve_tests':\n // Handle tests parameter as positional arguments for test tools.\n // Resolve relative paths against the user's effective workspace\n // directory. In monorepo layouts this is the repo root; in npm-\n // installed layouts it falls back to process.cwd().\n if (tests && Array.isArray(tests)) {\n const userDir = getUserWorkspaceDir();\n positionalArgs = [...positionalArgs, ...(tests as string[]).map(\n t => isAbsolute(t) ? t : resolve(userDir, t)\n )];\n }\n break;\n \n case 'codeql_query_run': {\n // Resolve database path to absolute path if it's relative\n if (options.database && typeof options.database === 'string' && !isAbsolute(options.database)) {\n options.database = resolve(getUserWorkspaceDir(), options.database);\n logger.info(`Resolved database path to: ${options.database}`);\n }\n \n // Implement query resolution logic with enhanced results processing\n const resolvedQuery = await resolveQueryPath(params, logger);\n if (resolvedQuery) {\n positionalArgs = [...positionalArgs, resolvedQuery];\n } else if (query) {\n positionalArgs = [...positionalArgs, query as string];\n }\n \n // Handle external predicates for tool queries\n if (queryName === 'PrintAST' && sourceFiles) {\n // Create a CSV file with the source file paths for the external predicate\n // The external predicate expects a CSV file with one column containing file paths\n const filePaths = (sourceFiles as string).split(',').map((f: string) => f.trim());\n let tempDir: string;\n let csvPath: string;\n try {\n tempDir = createProjectTempDir('codeql-external-');\n tempDirsToCleanup.push(tempDir); // Track for cleanup\n csvPath = join(tempDir, 'selectedSourceFiles.csv');\n\n // Create CSV content\n const csvContent = filePaths.join('\\n') + '\\n';\n\n writeFileSync(csvPath, csvContent, 'utf8');\n } catch (err) {\n logger.error(`Failed to create external predicate CSV for PrintAST query at path ${csvPath || '[unknown]'}: ${err instanceof Error ? err.message : String(err)}`);\n throw err;\n }\n \n // Add the external predicate with the CSV file path\n const currentExternal = options.external || [];\n const externalArray = Array.isArray(currentExternal) ? currentExternal : [currentExternal];\n externalArray.push(`selectedSourceFiles=${csvPath}`);\n options.external = externalArray;\n \n logger.info(`Created external predicate CSV at ${csvPath} for files: ${filePaths.join(', ')}`);\n }\n \n // Handle external predicates for CallGraphFrom queries\n if (queryName === 'CallGraphFrom' && sourceFunction) {\n const functionNames = (sourceFunction as string).split(',').map((f: string) => f.trim());\n let tempDir: string;\n let csvPath: string;\n try {\n tempDir = createProjectTempDir('codeql-external-');\n tempDirsToCleanup.push(tempDir);\n csvPath = join(tempDir, 'sourceFunction.csv');\n\n // Create CSV content\n const csvContent = functionNames.join('\\n') + '\\n';\n\n writeFileSync(csvPath, csvContent, 'utf8');\n } catch (err) {\n logger.error(`Failed to create external predicate CSV for CallGraphFrom query at path ${csvPath || '[unknown]'}: ${err instanceof Error ? err.message : String(err)}`);\n throw err;\n }\n \n // Add the external predicate with the CSV file path\n const currentExternal = options.external || [];\n const externalArray = Array.isArray(currentExternal) ? currentExternal : [currentExternal];\n externalArray.push(`sourceFunction=${csvPath}`);\n options.external = externalArray;\n \n logger.info(`Created external predicate CSV at ${csvPath} for functions: ${functionNames.join(', ')}`);\n }\n \n // Handle external predicates for CallGraphTo queries\n if (queryName === 'CallGraphTo' && targetFunction) {\n const functionNames = (targetFunction as string).split(',').map((f: string) => f.trim());\n let tempDir: string;\n let csvPath: string;\n try {\n tempDir = createProjectTempDir('codeql-external-');\n tempDirsToCleanup.push(tempDir);\n csvPath = join(tempDir, 'targetFunction.csv');\n\n // Create CSV content\n const csvContent = functionNames.join('\\n') + '\\n';\n\n writeFileSync(csvPath, csvContent, 'utf8');\n } catch (err) {\n logger.error(`Failed to create external predicate CSV for CallGraphTo query at path ${csvPath || '[unknown]'}: ${err instanceof Error ? err.message : String(err)}`);\n throw err;\n }\n \n // Add the external predicate with the CSV file path\n const currentExternal = options.external || [];\n const externalArray = Array.isArray(currentExternal) ? currentExternal : [currentExternal];\n externalArray.push(`targetFunction=${csvPath}`);\n options.external = externalArray;\n \n logger.info(`Created external predicate CSV at ${csvPath} for functions: ${functionNames.join(', ')}`);\n }\n break;\n }\n \n case 'codeql_query_compile':\n case 'codeql_resolve_metadata':\n // Handle query parameter as positional argument for query compilation and metadata tools\n if (query) {\n positionalArgs = [...positionalArgs, query as string];\n }\n break;\n \n case 'codeql_resolve_queries':\n // Handle directory parameter as positional argument\n if (directory) {\n positionalArgs = [...positionalArgs, directory as string];\n }\n break;\n \n default:\n // No special parameter handling needed for other tools\n break;\n }\n\n // Set up logging directory for query/test runs\n let queryLogDir: string | undefined;\n if (name === 'codeql_query_run' || name === 'codeql_test_run') {\n queryLogDir = getOrCreateLogDirectory(customLogDir as string | undefined);\n logger.info(`Using log directory for ${name}: ${queryLogDir}`);\n \n // Create timestamp file to track when query/test run started\n const timestampPath = join(queryLogDir, 'timestamp');\n writeFileSync(timestampPath, Date.now().toString(), 'utf8');\n \n // Set the --logdir option for CodeQL CLI\n options.logdir = queryLogDir;\n \n // Set verbosity to progress+ to generate detailed query.log/test.log\n if (!options.verbosity) {\n options.verbosity = 'progress+';\n }\n \n // For query run, also handle the deprecated evaluator-log parameter and default output\n if (name === 'codeql_query_run') {\n // If evaluator-log was explicitly provided (deprecated), use it\n // Otherwise, set it to the log directory\n if (!options['evaluator-log']) {\n options['evaluator-log'] = join(queryLogDir, 'evaluator-log.jsonl');\n }\n \n // If output was not explicitly provided, set it to the log directory\n if (!options.output) {\n options.output = join(queryLogDir, 'results.bqrs');\n }\n }\n }\n\n let result: CLIExecutionResult;\n \n if (command === 'codeql') {\n // For pack commands, set the working directory to where qlpack.yml is located.\n // Resolve to absolute path since the MCP server's cwd may differ from\n // the workspace root (especially when launched by VS Code).\n let cwd: string | undefined;\n if ((name === 'codeql_pack_install' || name === 'codeql_pack_ls') && (dir || packDir)) {\n const rawCwd = (dir || packDir) as string;\n // Resolve relative paths against the user's effective workspace\n // directory rather than a potentially read-only package root.\n cwd = isAbsolute(rawCwd) ? rawCwd : resolve(getUserWorkspaceDir(), rawCwd);\n }\n \n // Add --additional-packs for commands that need to access local test packs.\n // Only set the default examples path when it actually exists on disk\n // (it may be absent in npm-installed layouts where ql/javascript/examples/\n // is not included in the published package).\n const defaultExamplesPath = resolve(packageRootDir, 'ql', 'javascript', 'examples');\n const additionalPacksPath = process.env.CODEQL_ADDITIONAL_PACKS\n || (existsSync(defaultExamplesPath) ? defaultExamplesPath : undefined);\n if (additionalPacksPath && (name === 'codeql_test_run' || name === 'codeql_query_run' || name === 'codeql_query_compile')) {\n options['additional-packs'] = additionalPacksPath;\n }\n \n // Keep test databases for codeql_test_run to allow subsequent query runs\n if (name === 'codeql_test_run') {\n options['keep-databases'] = true;\n }\n \n result = await executeCodeQLCommand(subcommand, options, positionalArgs, cwd);\n } else if (command === 'qlt') {\n result = await executeQLTCommand(subcommand, options, positionalArgs);\n } else {\n throw new Error(`Unsupported command: ${command}`);\n }\n\n // Post-execution processing for codeql_query_run\n if (name === 'codeql_query_run' && result.success && queryLogDir) {\n // Generate SARIF interpretation if results.bqrs exists\n const bqrsPath = options.output as string;\n const sarifPath = join(queryLogDir, 'results.sarif');\n \n if (existsSync(bqrsPath)) {\n try {\n const sarifResult = await executeCodeQLCommand(\n 'bqrs interpret',\n { format: 'sarif-latest', output: sarifPath },\n [bqrsPath]\n );\n \n if (sarifResult.success) {\n logger.info(`Generated SARIF interpretation at ${sarifPath}`);\n }\n } catch (error) {\n logger.warn(`Failed to generate SARIF interpretation: ${error}`);\n }\n }\n \n // Process evaluation results\n result = await processQueryRunResults(result, params, logger);\n }\n\n // Process the result\n const processedResult = resultProcessor(result, params);\n\n return {\n content: [{\n type: 'text' as const,\n text: processedResult\n }],\n isError: !result.success\n };\n\n } catch (error) {\n logger.error(`Error in CLI tool ${name}:`, error);\n \n return {\n content: [{\n type: 'text' as const,\n text: `Failed to execute CLI tool: ${error instanceof Error ? error.message : String(error)}`\n }],\n isError: true\n };\n } finally {\n // Clean up temporary directories\n for (const tempDir of tempDirsToCleanup) {\n try {\n rmSync(tempDir, { recursive: true, force: true });\n logger.info(`Cleaned up temporary directory: ${tempDir}`);\n } catch (cleanupError) {\n logger.error(`Failed to clean up temporary directory ${tempDir}:`, cleanupError);\n }\n }\n }\n }\n );\n}\n\n/**\n * Helper function to create common CodeQL input schemas\n */\nexport const createCodeQLSchemas = {\n database: () => z.string().describe('Path to the CodeQL database'),\n \n query: () => z.string().describe('Path to the CodeQL query file (.ql)'),\n \n output: () => z.string().optional().describe('Output file path'),\n \n outputFormat: () => z.enum(['csv', 'json', 'bqrs', 'sarif-latest', 'sarifv2.1.0']).optional()\n .describe('Output format for results'),\n \n language: () => z.string().optional().describe('Programming language'),\n \n threads: () => z.number().optional().describe('Number of threads to use'),\n \n ram: () => z.number().optional().describe('Amount of RAM to use (MB)'),\n \n timeout: () => z.number().optional().describe('Timeout in seconds'),\n \n verbose: () => z.boolean().optional().describe('Enable verbose output'),\n \n additionalArgs: () => z.array(z.string()).optional().describe('Additional command-line arguments'),\n \n positionalArgs: () => z.array(z.string()).optional().describe('Positional arguments')\n .transform((val) => ({ _positional: val }))\n};\n\n/**\n * Helper function to create common QLT input schemas\n */\nexport const createQLTSchemas = {\n language: () => z.string().describe('Programming language'),\n \n output: () => z.string().optional().describe('Output directory or file path'),\n \n template: () => z.string().optional().describe('Template to use'),\n \n name: () => z.string().optional().describe('Name for generated query'),\n \n description: () => z.string().optional().describe('Description for generated query'),\n \n verbose: () => z.boolean().optional().describe('Enable verbose output'),\n \n force: () => z.boolean().optional().describe('Force overwrite existing files'),\n \n additionalArgs: () => z.array(z.string()).optional().describe('Additional command-line arguments')\n};\n\n/**\n * Create a result processor that formats BQRS output specially\n */\nexport const createBQRSResultProcessor = () => (\n result: CLIExecutionResult, \n params: Record\n): string => {\n if (!result.success) {\n return defaultCLIResultProcessor(result, params);\n }\n \n // For BQRS commands, provide more context about the output\n let output = result.stdout;\n \n if (params.output) {\n output += `\\n\\nResults saved to: ${params.output}`;\n }\n \n if (result.stderr) {\n output += `\\n\\nAdditional information:\\n${result.stderr}`;\n }\n \n return output;\n};\n\n/**\n * Create a result processor that formats database creation output\n */\nexport const createDatabaseResultProcessor = () => (\n result: CLIExecutionResult, \n params: Record\n): string => {\n if (!result.success) {\n return defaultCLIResultProcessor(result, params);\n }\n \n let output = 'Database creation completed successfully';\n \n if (params.database || params._positional) {\n const dbPath = params.database || (Array.isArray(params._positional) ? params._positional[0] : params._positional);\n output += `\\n\\nDatabase location: ${dbPath}`;\n }\n \n if (result.stdout) {\n output += `\\n\\nOutput:\\n${result.stdout}`;\n }\n \n if (result.stderr) {\n output += `\\n\\nAdditional information:\\n${result.stderr}`;\n }\n \n return output;\n};\n\n/**\n * Resolve query path for codeql_query_run tool\n * If queryName and queryLanguage are provided, resolve using codeql resolve queries\n */\nasync function resolveQueryPath(\n params: Record, \n logger: { info: (_message: string, ..._args: unknown[]) => void; error: (_message: string, ..._args: unknown[]) => void }\n): Promise {\n const { queryName, queryLanguage, queryPack, query } = params;\n \n // Validate parameter usage - queryName and query are mutually exclusive\n if (queryName && query) {\n logger.error('Cannot use both \"query\" and \"queryName\" parameters simultaneously. Use either \"query\" for direct file path OR \"queryName\" + \"queryLanguage\" for tool queries.');\n throw new Error('Cannot use both \"query\" and \"queryName\" parameters simultaneously. Use either \"query\" for direct file path OR \"queryName\" + \"queryLanguage\" for tool queries.');\n }\n \n // If no queryName provided, fall back to direct query parameter\n if (!queryName) {\n return query as string || null;\n }\n \n // If queryName provided but no language, we can't resolve\n if (!queryLanguage) {\n logger.error('queryLanguage is required when using queryName parameter. Supported languages: actions, cpp, csharp, go, java, javascript, python, ruby, swift');\n throw new Error('queryLanguage is required when using queryName parameter. Supported languages: actions, cpp, csharp, go, java, javascript, python, ruby, swift');\n }\n \n try {\n // Determine the query pack path - use absolute path to ensure it works regardless of cwd\n const defaultPackPath = resolveToolQueryPackPath(queryLanguage as string);\n const packPath = queryPack as string || defaultPackPath;\n \n logger.info(`Resolving query: ${queryName} for language: ${queryLanguage} in pack: ${packPath}`);\n \n // Execute codeql resolve queries to get available queries\n const { executeCodeQLCommand } = await import('./cli-executor');\n const resolveResult = await executeCodeQLCommand(\n 'resolve queries',\n { format: 'json' },\n [packPath]\n );\n \n if (!resolveResult.success) {\n logger.error('Failed to resolve queries:', resolveResult.stderr || resolveResult.error);\n throw new Error(`Failed to resolve queries: ${resolveResult.stderr || resolveResult.error}`);\n }\n \n // Parse the JSON output to find matching queries\n let resolvedQueries: string[];\n try {\n resolvedQueries = JSON.parse(resolveResult.stdout);\n } catch (parseError) {\n logger.error('Failed to parse resolve queries output:', parseError);\n throw new Error('Failed to parse resolve queries output');\n }\n \n // Find the query that matches the requested name exactly\n const matchingQuery = resolvedQueries.find(queryPath => {\n const fileName = basename(queryPath);\n // Match exact query name: \"PrintAST\" should match \"PrintAST.ql\" only\n return fileName === `${queryName}.ql`;\n });\n\n if (!matchingQuery) {\n logger.error(`Query \"${queryName}.ql\" not found in pack \"${packPath}\". Available queries:`, resolvedQueries.map(q => basename(q)));\n throw new Error(`Query \"${queryName}.ql\" not found in pack \"${packPath}\"`);\n }\n \n logger.info(`Resolved query \"${queryName}\" to: ${matchingQuery}`);\n return matchingQuery;\n \n } catch (error) {\n logger.error('Error resolving query path:', error);\n throw error;\n }\n}\n\n/**\n * Interpret BQRS file using codeql bqrs interpret\n */\nasync function interpretBQRSFile(\n bqrsPath: string,\n queryPath: string,\n format: string,\n outputPath: string,\n logger: { info: (_message: string, ..._args: unknown[]) => void; error: (_message: string, ..._args: unknown[]) => void }\n): Promise {\n try {\n // Extract query metadata to get id and kind\n const metadata = await extractQueryMetadata(queryPath);\n \n // Validate required metadata fields\n const missingFields = [];\n if (!metadata.id) missingFields.push('id');\n if (!metadata.kind) missingFields.push('kind');\n \n if (missingFields.length > 0) {\n return {\n success: false,\n exitCode: 1,\n stdout: '',\n stderr: '',\n error: `Query metadata is incomplete. Missing required field(s): ${missingFields.join(', ')}. Ensure the query file contains @id and @kind metadata.`\n };\n }\n \n // Sanitize metadata values to prevent command injection\n const sanitizedKind = (metadata.kind || '').replace(/[^a-zA-Z0-9_-]/g, '');\n const sanitizedId = (metadata.id || '').replace(/[^a-zA-Z0-9_/:-]/g, '');\n \n // Validate format for query kind\n const graphFormats = ['graphtext', 'dgml', 'dot'];\n if (graphFormats.includes(format) && metadata.kind !== 'graph') {\n return {\n success: false,\n exitCode: 1,\n stdout: '',\n stderr: '',\n error: `Format '${format}' is only compatible with @kind graph queries, but this query has @kind ${metadata.kind}`\n };\n }\n \n // Ensure output directory exists\n mkdirSync(dirname(outputPath), { recursive: true });\n \n // Build the codeql bqrs interpret command\n const params: Record = {\n format: format,\n output: outputPath,\n t: [`kind=${sanitizedKind}`, `id=${sanitizedId}`]\n };\n \n logger.info(`Interpreting BQRS file ${bqrsPath} with format ${format} to ${outputPath}`);\n \n // Execute codeql bqrs interpret\n const result = await executeCodeQLCommand(\n 'bqrs interpret',\n params,\n [bqrsPath]\n );\n \n return result;\n } catch (error) {\n return {\n success: false,\n exitCode: 1,\n stdout: '',\n stderr: '',\n error: `Failed to interpret BQRS file: ${error}`\n };\n }\n}\n\n/**\n * Get default output extension based on format\n */\nfunction getDefaultExtension(format: string): string {\n switch (format) {\n case 'sarif-latest':\n case 'sarifv2.1.0':\n return '.sarif';\n case 'csv':\n return '.csv';\n case 'graphtext':\n return '.txt';\n case 'dgml':\n return '.dgml';\n case 'dot':\n return '.dot';\n default:\n return '.txt';\n }\n}\n\n/**\n * Process query run results with optional interpretation or evaluation\n */\nasync function processQueryRunResults(\n result: CLIExecutionResult,\n params: Record,\n logger: { info: (_message: string, ..._args: unknown[]) => void; error: (_message: string, ..._args: unknown[]) => void }\n): Promise {\n try {\n const { format, interpretedOutput, evaluationFunction, evaluationOutput, output, query, queryName, queryLanguage } = params;\n \n // If no format or evaluationFunction specified, return as-is\n if (!format && !evaluationFunction) {\n return result;\n }\n \n // Ensure output (bqrs file) was generated\n if (!output) {\n return result;\n }\n \n const bqrsPath = output as string;\n \n // Determine the query path for metadata extraction\n let queryPath: string | null = null;\n \n if (query) {\n queryPath = query as string;\n } else if (queryName && queryLanguage) {\n // Try to resolve the query path again for evaluation\n queryPath = await resolveQueryPath(params, logger);\n }\n \n if (!queryPath) {\n logger.error('Cannot determine query path for interpretation/evaluation');\n return {\n ...result,\n stdout: result.stdout + '\\n\\nWarning: Query interpretation skipped - could not determine query path'\n };\n }\n \n // Handle new format parameter (preferred approach)\n if (format) {\n const outputFormat = format as string;\n \n // Determine output path\n let outputFilePath = interpretedOutput as string | undefined;\n if (!outputFilePath) {\n const ext = getDefaultExtension(outputFormat);\n outputFilePath = bqrsPath.replace('.bqrs', ext);\n }\n \n logger.info(`Interpreting query results from ${bqrsPath} with format: ${outputFormat}`);\n \n // Interpret the BQRS file\n const interpretResult = await interpretBQRSFile(\n bqrsPath,\n queryPath,\n outputFormat,\n outputFilePath,\n logger\n );\n \n if (interpretResult.success) {\n let enhancedOutput = result.stdout;\n enhancedOutput += `\\n\\nQuery results interpreted successfully with format: ${outputFormat}`;\n enhancedOutput += `\\nInterpreted output saved to: ${outputFilePath}`;\n \n return {\n ...result,\n stdout: enhancedOutput\n };\n } else {\n logger.error('Query interpretation failed:', interpretResult.error);\n return {\n ...result,\n stdout: result.stdout + `\\n\\nWarning: Query interpretation failed - ${interpretResult.error || interpretResult.stderr}`\n };\n }\n }\n \n // Handle legacy evaluationFunction parameter (deprecated)\n if (evaluationFunction) {\n logger.info(`Using deprecated evaluationFunction parameter. Consider using format parameter instead.`);\n logger.info(`Evaluating query results from ${bqrsPath} using function: ${evaluationFunction}`);\n \n // Perform the evaluation\n const evaluationResult: QueryEvaluationResult = await evaluateQueryResults(\n bqrsPath,\n queryPath,\n evaluationFunction as string,\n evaluationOutput as string | undefined\n );\n \n if (evaluationResult.success) {\n // Append evaluation results to the command output\n let enhancedOutput = result.stdout;\n \n if (evaluationResult.outputPath) {\n enhancedOutput += `\\n\\nQuery evaluation completed successfully.`;\n enhancedOutput += `\\nEvaluation output saved to: ${evaluationResult.outputPath}`;\n }\n \n if (evaluationResult.content) {\n enhancedOutput += `\\n\\n=== Query Results Evaluation ===\\n`;\n enhancedOutput += evaluationResult.content;\n }\n \n return {\n ...result,\n stdout: enhancedOutput\n };\n } else {\n // Evaluation failed, but don't fail the whole operation\n logger.error('Query evaluation failed:', evaluationResult.error);\n return {\n ...result,\n stdout: result.stdout + `\\n\\nWarning: Query evaluation failed - ${evaluationResult.error}`\n };\n }\n }\n \n return result;\n } catch (error) {\n logger.error('Error in query results processing:', error);\n return {\n ...result,\n stdout: result.stdout + `\\n\\nWarning: Query processing error - ${error}`\n };\n }\n}", "/**\n * Query results evaluation functions for processing .bqrs files\n */\n\nimport { executeCodeQLCommand } from './cli-executor';\nimport { logger } from '../utils/logger';\nimport { writeFileSync, readFileSync } from 'fs';\nimport { dirname, isAbsolute } from 'path';\nimport { mkdirSync } from 'fs';\n\nexport interface QueryEvaluationResult {\n success: boolean;\n outputPath?: string;\n content?: string;\n error?: string;\n}\n\nexport interface QueryMetadata {\n kind?: string;\n name?: string;\n description?: string;\n id?: string;\n tags?: string[];\n}\n\n/**\n * Built-in evaluation functions\n */\nexport const BUILT_IN_EVALUATORS = {\n 'json-decode': 'JSON format decoder for query results',\n 'csv-decode': 'CSV format decoder for query results', \n 'mermaid-graph': 'Mermaid diagram generator for @kind graph queries (like PrintAST)',\n} as const;\n\nexport type BuiltInEvaluator = keyof typeof BUILT_IN_EVALUATORS;\n\n/**\n * Extract metadata from a CodeQL query file\n */\nexport async function extractQueryMetadata(queryPath: string): Promise {\n try {\n const queryContent = readFileSync(queryPath, 'utf-8');\n const metadata: QueryMetadata = {};\n \n // Extract metadata from comments using regex patterns\n const kindMatch = queryContent.match(/@kind\\s+([^\\s]+)/);\n if (kindMatch) metadata.kind = kindMatch[1];\n \n const nameMatch = queryContent.match(/@name\\s+(.+)/);\n if (nameMatch) metadata.name = nameMatch[1].trim();\n \n const descMatch = queryContent.match(/@description\\s+(.+)/);\n if (descMatch) metadata.description = descMatch[1].trim();\n \n const idMatch = queryContent.match(/@id\\s+(.+)/);\n if (idMatch) metadata.id = idMatch[1].trim();\n \n const tagsMatch = queryContent.match(/@tags\\s+(.+)/);\n if (tagsMatch) {\n metadata.tags = tagsMatch[1].split(/\\s+/).filter(t => t.length > 0);\n }\n \n return metadata;\n } catch (error) {\n logger.error('Failed to extract query metadata:', error);\n return {};\n }\n}\n\n/**\n * JSON decoder - converts .bqrs to JSON format\n */\nexport async function evaluateWithJsonDecoder(\n bqrsPath: string, \n outputPath?: string\n): Promise {\n try {\n const result = await executeCodeQLCommand(\n 'bqrs decode',\n { format: 'json' },\n [bqrsPath]\n );\n \n if (!result.success) {\n return {\n success: false,\n error: `Failed to decode BQRS file: ${result.stderr || result.error}`\n };\n }\n \n const defaultOutputPath = outputPath || bqrsPath.replace('.bqrs', '.json');\n \n // Ensure output directory exists\n mkdirSync(dirname(defaultOutputPath), { recursive: true });\n \n // Write JSON results\n writeFileSync(defaultOutputPath, result.stdout);\n \n return {\n success: true,\n outputPath: defaultOutputPath,\n content: result.stdout\n };\n } catch (error) {\n return {\n success: false,\n error: `JSON evaluation failed: ${error}`\n };\n }\n}\n\n/**\n * CSV decoder - converts .bqrs to CSV format\n */\nexport async function evaluateWithCsvDecoder(\n bqrsPath: string,\n outputPath?: string\n): Promise {\n try {\n const result = await executeCodeQLCommand(\n 'bqrs decode',\n { format: 'csv' },\n [bqrsPath]\n );\n \n if (!result.success) {\n return {\n success: false,\n error: `Failed to decode BQRS file: ${result.stderr || result.error}`\n };\n }\n \n const defaultOutputPath = outputPath || bqrsPath.replace('.bqrs', '.csv');\n \n // Ensure output directory exists\n mkdirSync(dirname(defaultOutputPath), { recursive: true });\n \n // Write CSV results\n writeFileSync(defaultOutputPath, result.stdout);\n \n return {\n success: true,\n outputPath: defaultOutputPath,\n content: result.stdout\n };\n } catch (error) {\n return {\n success: false,\n error: `CSV evaluation failed: ${error}`\n };\n }\n}\n\n/**\n * Mermaid graph generator - converts @kind graph query results to mermaid diagrams\n */\nexport async function evaluateWithMermaidGraph(\n bqrsPath: string,\n queryPath: string,\n outputPath?: string\n): Promise {\n try {\n // First extract query metadata to confirm this is a graph query\n const metadata = await extractQueryMetadata(queryPath);\n \n if (metadata.kind !== 'graph') {\n logger.error(`Query is not a graph query (kind: ${metadata.kind}), mermaid-graph evaluation is only for @kind graph queries`);\n return {\n success: false,\n error: `Query is not a graph query (kind: ${metadata.kind}), mermaid-graph evaluation is only for @kind graph queries`\n };\n }\n \n // Decode the BQRS file to JSON first\n const jsonResult = await executeCodeQLCommand(\n 'bqrs decode',\n { format: 'json' },\n [bqrsPath]\n );\n \n if (!jsonResult.success) {\n return {\n success: false,\n error: `Failed to decode BQRS file: ${jsonResult.stderr || jsonResult.error}`\n };\n }\n \n // Parse the JSON results\n let queryResults;\n try {\n queryResults = JSON.parse(jsonResult.stdout);\n } catch (parseError) {\n return {\n success: false,\n error: `Failed to parse query results JSON: ${parseError}`\n };\n }\n \n // Generate mermaid diagram from graph results\n const mermaidContent = generateMermaidFromGraphResults(queryResults, metadata);\n \n const defaultOutputPath = outputPath || bqrsPath.replace('.bqrs', '.md');\n \n // Ensure output directory exists\n mkdirSync(dirname(defaultOutputPath), { recursive: true });\n \n // Write markdown file with mermaid diagram\n writeFileSync(defaultOutputPath, mermaidContent);\n \n return {\n success: true,\n outputPath: defaultOutputPath,\n content: mermaidContent\n };\n } catch (error) {\n return {\n success: false,\n error: `Mermaid graph evaluation failed: ${error}`\n };\n }\n}\n\n/**\n * Generate mermaid diagram from CodeQL graph query results\n */\nfunction generateMermaidFromGraphResults(queryResults: unknown, metadata: QueryMetadata): string {\n const queryName = sanitizeMarkdown(metadata.name || 'CodeQL Query Results');\n const queryDesc = sanitizeMarkdown(metadata.description || 'Graph visualization of CodeQL query results');\n \n let mermaidContent = `# ${queryName}\\n\\n${queryDesc}\\n\\n`;\n \n // Handle different result structures that CodeQL graph queries can produce\n if (!queryResults || typeof queryResults !== 'object') {\n mermaidContent += '```mermaid\\ngraph TD\\n A[No Results]\\n```\\n';\n return mermaidContent;\n }\n \n // Check if results have the expected structure for graph queries\n const tuples = queryResults.tuples || queryResults;\n \n if (!Array.isArray(tuples) || tuples.length === 0) {\n mermaidContent += '```mermaid\\ngraph TD\\n A[No Graph Data]\\n```\\n';\n return mermaidContent;\n }\n \n mermaidContent += '```mermaid\\ngraph TD\\n';\n \n // Track nodes and edges to avoid duplicates\n const nodes = new Set();\n const edges = new Set();\n \n // Process each tuple in the results\n tuples.forEach((tuple: unknown, index: number) => {\n if (Array.isArray(tuple) && tuple.length >= 2) {\n // Extract source and target from tuple\n const source = sanitizeNodeId(tuple[0]?.toString() || `node_${index}_0`);\n const target = sanitizeNodeId(tuple[1]?.toString() || `node_${index}_1`);\n const label = tuple[2]?.toString() || '';\n \n // Add nodes\n nodes.add(source);\n nodes.add(target);\n \n // Add edge\n const edgeId = `${source}_${target}`;\n if (!edges.has(edgeId)) {\n if (label) {\n mermaidContent += ` ${source} -->|${sanitizeLabel(label)}| ${target}\\n`;\n } else {\n mermaidContent += ` ${source} --> ${target}\\n`;\n }\n edges.add(edgeId);\n }\n } else if (typeof tuple === 'object' && tuple !== null) {\n // Handle object-based results\n const source = sanitizeNodeId(tuple.source?.toString() || tuple.from?.toString() || `node_${index}_src`);\n const target = sanitizeNodeId(tuple.target?.toString() || tuple.to?.toString() || `node_${index}_tgt`);\n const label = tuple.label?.toString() || tuple.relation?.toString() || '';\n \n nodes.add(source);\n nodes.add(target);\n \n const edgeId = `${source}_${target}`;\n if (!edges.has(edgeId)) {\n if (label) {\n mermaidContent += ` ${source} -->|${sanitizeLabel(label)}| ${target}\\n`;\n } else {\n mermaidContent += ` ${source} --> ${target}\\n`;\n }\n edges.add(edgeId);\n }\n }\n });\n \n // If no edges were created, create a simple diagram showing the first few nodes\n if (edges.size === 0 && nodes.size > 0) {\n const nodeArray = Array.from(nodes).slice(0, 10); // Limit to avoid clutter\n nodeArray.forEach((node, index) => {\n if (index === 0) {\n mermaidContent += ` ${node}[${sanitizeLabel(node)}]\\n`;\n } else {\n mermaidContent += ` ${nodeArray[0]} --> ${node}\\n`;\n }\n });\n }\n \n mermaidContent += '```\\n\\n';\n \n // Add statistics\n mermaidContent += `## Query Statistics\\n\\n`;\n mermaidContent += `- Total nodes: ${nodes.size}\\n`;\n mermaidContent += `- Total edges: ${edges.size}\\n`;\n mermaidContent += `- Total tuples processed: ${tuples.length}\\n`;\n \n return mermaidContent;\n}\n\n/**\n * Sanitize node IDs for mermaid compatibility\n */\nfunction sanitizeNodeId(id: string): string {\n return id\n .replace(/[^a-zA-Z0-9_]/g, '_')\n .replace(/^(\\d)/, 'n$1') // Prefix with 'n' if starts with number\n .substring(0, 50); // Limit length\n}\n\n/**\n * Sanitize labels for mermaid compatibility\n */\nfunction sanitizeLabel(label: string): string {\n return label\n .replace(/[|\"`<>\\n\\r\\t]/g, '') // Remove problematic characters including backticks, newlines, angle brackets\n .replace(/\\s+/g, ' ') // Normalize whitespace\n .trim()\n .substring(0, 30); // Limit length for readability\n}\n\n/**\n * Sanitize markdown content to prevent injection\n */\nfunction sanitizeMarkdown(content: string): string {\n return content\n .replace(/[<>\"`]/g, '') // Remove potentially dangerous characters\n .replace(/\\n/g, ' ') // Convert newlines to spaces\n .replace(/\\s+/g, ' ') // Normalize whitespace\n .trim()\n .substring(0, 100); // Limit length\n}\n\n/**\n * Main evaluation function that determines which evaluator to use\n */\nexport async function evaluateQueryResults(\n bqrsPath: string,\n queryPath: string,\n evaluationFunction?: string,\n outputPath?: string\n): Promise {\n try {\n // If no evaluation function specified, default to json-decode\n const evalFunc = evaluationFunction || 'json-decode';\n \n logger.info(`Evaluating query results with function: ${evalFunc}`);\n \n // Handle built-in evaluation functions\n switch (evalFunc) {\n case 'json-decode':\n return await evaluateWithJsonDecoder(bqrsPath, outputPath);\n \n case 'csv-decode':\n return await evaluateWithCsvDecoder(bqrsPath, outputPath);\n \n case 'mermaid-graph':\n return await evaluateWithMermaidGraph(bqrsPath, queryPath, outputPath);\n \n default:\n // Check if it's a path to a custom evaluation script\n if (isAbsolute(evalFunc)) {\n return await evaluateWithCustomScript(bqrsPath, queryPath, evalFunc, outputPath);\n } else {\n return {\n success: false,\n error: `Unknown evaluation function: ${evalFunc}. Available built-in functions: ${Object.keys(BUILT_IN_EVALUATORS).join(', ')}`\n };\n }\n }\n } catch (error) {\n return {\n success: false,\n error: `Query evaluation failed: ${error}`\n };\n }\n}\n\n/**\n * Execute custom evaluation script\n */\nasync function evaluateWithCustomScript(\n _bqrsPath: string,\n _queryPath: string,\n _scriptPath: string,\n _outputPath?: string\n): Promise {\n // TODO: Implement custom script execution\n // This would need to execute the script with bqrsPath and queryPath as arguments\n // and capture the output\n return {\n success: false,\n error: 'Custom evaluation scripts are not yet implemented'\n };\n}", "/**\n * Log directory management utilities for CodeQL query and test runs\n */\n\nimport { mkdirSync, existsSync } from 'fs';\nimport { join, resolve } from 'path';\nimport { randomBytes } from 'crypto';\nimport { getProjectTmpDir } from '../utils/temp-dir';\n\n/**\n * Ensure that a given path is within a base directory.\n * Throws an error if the path is outside the base directory.\n */\nfunction ensurePathWithinBase(baseDir: string, targetPath: string): string {\n const absBase = resolve(baseDir);\n const absTarget = resolve(targetPath);\n if (!absTarget.startsWith(absBase + '/') && absTarget !== absBase) {\n throw new Error(`Provided log directory is outside the allowed base directory: ${absBase}`);\n }\n return absTarget;\n}\n\n/**\n * Get or create a unique log directory for query/test runs\n * \n * @param logDir - Optional custom log directory from parameters\n * @returns Absolute path to the log directory\n */\nexport function getOrCreateLogDirectory(logDir?: string): string {\n // Use CODEQL_QUERY_LOG_DIR env var or default base\n const baseLogDir = process.env.CODEQL_QUERY_LOG_DIR || getProjectTmpDir('query-logs');\n\n // If logDir is explicitly provided, validate it is within baseLogDir\n if (logDir) {\n const absLogDir = ensurePathWithinBase(baseLogDir, logDir);\n if (!existsSync(absLogDir)) {\n mkdirSync(absLogDir, { recursive: true });\n }\n return absLogDir;\n }\n \n // Otherwise, use baseLogDir and create a unique subdirectory\n \n // Create base directory if it doesn't exist\n if (!existsSync(baseLogDir)) {\n mkdirSync(baseLogDir, { recursive: true });\n }\n \n // Generate unique subdirectory with timestamp and random ID\n const timestamp = new Date().toISOString().replace(/[:.]/g, '-');\n const uniqueId = randomBytes(4).toString('hex');\n const uniqueLogDir = join(baseLogDir, `query-run-${timestamp}-${uniqueId}`);\n \n mkdirSync(uniqueLogDir, { recursive: true });\n \n return uniqueLogDir;\n}\n", "/**\n * CodeQL BQRS info tool\n */\n\nimport { z } from 'zod';\nimport { CLIToolDefinition, createCodeQLSchemas, createBQRSResultProcessor } from '../../lib/cli-tool-registry';\n\nexport const codeqlBqrsInfoTool: CLIToolDefinition = {\n name: 'codeql_bqrs_info',\n description: 'Get metadata and information about BQRS result files',\n command: 'codeql',\n subcommand: 'bqrs info',\n inputSchema: {\n files: z.array(z.string()).describe('BQRS file(s) to examine'),\n verbose: createCodeQLSchemas.verbose(),\n additionalArgs: createCodeQLSchemas.additionalArgs()\n },\n examples: [\n 'codeql bqrs info results.bqrs',\n 'codeql bqrs info --verbose results.bqrs'\n ],\n resultProcessor: createBQRSResultProcessor()\n};", "/**\n * CodeQL BQRS interpret tool\n */\n\nimport { z } from 'zod';\nimport { CLIToolDefinition, createCodeQLSchemas, createBQRSResultProcessor } from '../../lib/cli-tool-registry';\n\nexport const codeqlBqrsInterpretTool: CLIToolDefinition = {\n name: 'codeql_bqrs_interpret',\n description: 'Interpret BQRS result files according to query metadata and generate output in specified formats (CSV, SARIF, graph formats)',\n command: 'codeql',\n subcommand: 'bqrs interpret',\n inputSchema: {\n file: z.string().describe('The BQRS file to interpret'),\n format: z.enum(['csv', 'sarif-latest', 'sarifv2.1.0', 'graphtext', 'dgml', 'dot'])\n .describe('Output format: csv (comma-separated), sarif-latest/sarifv2.1.0 (SARIF), graphtext/dgml/dot (graph formats, only for @kind graph queries)'),\n output: createCodeQLSchemas.output(),\n t: z.array(z.string())\n .describe('Query metadata key=value pairs. At least \"kind\" and \"id\" must be specified (e.g., [\"kind=graph\", \"id=js/print-ast\"])'),\n 'max-paths': z.number().optional()\n .describe('Maximum number of paths to produce for each alert with paths (default: 4)'),\n 'sarif-add-file-contents': z.boolean().optional()\n .describe('[SARIF only] Include full file contents for all files referenced in results'),\n 'sarif-add-snippets': z.boolean().optional()\n .describe('[SARIF only] Include code snippets for each location with context'),\n 'sarif-group-rules-by-pack': z.boolean().optional()\n .describe('[SARIF only] Place rule objects under their QL pack in tool.extensions property'),\n 'sarif-multicause-markdown': z.boolean().optional()\n .describe('[SARIF only] Include multi-cause alerts as Markdown-formatted lists'),\n 'sarif-category': z.string().optional()\n .describe('[SARIF only] Category for this analysis (distinguishes multiple analyses on same code)'),\n 'csv-location-format': z.enum(['uri', 'line-column', 'offset-length']).optional()\n .describe('[CSV only] Format for locations in CSV output (default: line-column)'),\n 'dot-location-url-format': z.string().optional()\n .describe('[DOT only] Format string for file location URLs (placeholders: {path}, {start:line}, {start:column}, {end:line}, {end:column}, {offset}, {length})'),\n threads: z.number().optional()\n .describe('Number of threads for computing paths (0 = one per core, -N = leave N cores unused)'),\n 'column-kind': z.enum(['utf8', 'utf16', 'utf32', 'bytes']).optional()\n .describe('[SARIF only] Column kind for interpreting location columns'),\n 'unicode-new-lines': z.boolean().optional()\n .describe('[SARIF only] Whether unicode newlines (U+2028, U+2029) are considered as newlines'),\n verbose: createCodeQLSchemas.verbose(),\n additionalArgs: createCodeQLSchemas.additionalArgs()\n },\n examples: [\n 'codeql bqrs interpret --format=sarif-latest --output=results.sarif -t kind=problem -t id=js/sql-injection results.bqrs',\n 'codeql bqrs interpret --format=graphtext --output=ast.txt -t kind=graph -t id=js/print-ast results.bqrs',\n 'codeql bqrs interpret --format=csv --csv-location-format=line-column --output=results.csv -t kind=problem -t id=js/xss results.bqrs',\n 'codeql bqrs interpret --format=dot --output=graph.dot -t kind=graph -t id=java/call-graph results.bqrs',\n 'codeql bqrs interpret --format=sarif-latest --sarif-add-snippets --sarif-category=security --output=results.sarif -t kind=path-problem -t id=go/path-injection results.bqrs'\n ],\n resultProcessor: createBQRSResultProcessor()\n};\n", "/**\n * CodeQL database analyze tool\n */\n\nimport { z } from 'zod';\nimport { CLIToolDefinition } from '../../lib/cli-tool-registry';\n\nexport const codeqlDatabaseAnalyzeTool: CLIToolDefinition = {\n name: 'codeql_database_analyze',\n description: 'Run queries or query suites against CodeQL databases',\n command: 'codeql',\n subcommand: 'database analyze',\n inputSchema: {\n database: z.string().describe('Path to the CodeQL database'),\n queries: z.string().describe('Queries or query suite to run'),\n output: z.string().optional().describe('Output file path'),\n format: z.enum(['csv', 'json', 'sarif-latest', 'sarifv2.1.0']).optional()\n .describe('Output format for results'),\n 'download-location': z.string().optional()\n .describe('Location to download missing dependencies'),\n threads: z.number().optional().describe('Number of threads to use'),\n ram: z.number().optional().describe('Amount of RAM to use (MB)'),\n timeout: z.number().optional().describe('Timeout in seconds'),\n verbose: z.boolean().optional().describe('Enable verbose output'),\n additionalArgs: z.array(z.string()).optional().describe('Additional command-line arguments')\n },\n examples: [\n 'codeql database analyze mydb queries.qls --format=sarif-latest --output=results.sarif',\n 'codeql database analyze mydb codeql/java-queries --format=csv'\n ]\n};", "/**\n * CodeQL database create tool\n */\n\nimport { z } from 'zod';\nimport { CLIToolDefinition, createDatabaseResultProcessor } from '../../lib/cli-tool-registry';\n\nexport const codeqlDatabaseCreateTool: CLIToolDefinition = {\n name: 'codeql_database_create',\n description: 'Create a CodeQL database from source code',\n command: 'codeql',\n subcommand: 'database create',\n inputSchema: {\n database: z.string().describe('Database path/name to create'),\n language: z.string().optional().describe('Programming language(s) to extract'),\n 'source-root': z.string().optional().describe('Root directory of source code'),\n command: z.string().optional().describe('Build command for compiled languages'),\n 'build-mode': z.enum(['none', 'autobuild', 'manual']).optional()\n .describe('Build mode: none (interpreted langs), autobuild, or manual'),\n threads: z.number().optional().describe('Number of threads to use'),\n ram: z.number().optional().describe('Amount of RAM to use (MB)'),\n verbose: z.boolean().optional().describe('Enable verbose output'),\n overwrite: z.boolean().optional().describe('Overwrite existing database if it exists'),\n 'no-cleanup': z.boolean().optional().describe('Skip database cleanup after finalization'),\n additionalArgs: z.array(z.string()).optional().describe('Additional command-line arguments')\n },\n examples: [\n 'codeql database create --language=java --source-root=/path/to/project mydb',\n 'codeql database create --language=cpp --command=\"make all\" mydb',\n 'codeql database create --language=python,javascript mydb'\n ],\n resultProcessor: createDatabaseResultProcessor()\n};", "/**\n * CodeQL find class position tool\n * \n * Inspired by JordyZomer/codeql-mcp repository:\n * - https://github.com/JordyZomer/codeql-mcp/blob/main/server.py\n * - https://github.com/JordyZomer/codeql-mcp/blob/main/codeqlclient.py\n */\n\nimport { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport { z } from 'zod';\nimport { readFile } from 'fs/promises';\nimport { logger } from '../../utils/logger';\n\nexport interface ClassPosition {\n start_line: number;\n start_col: number;\n end_line: number;\n end_col: number;\n}\n\n/**\n * Find the 1-based position of a class name identifier in a QL file.\n * Returns: { start_line, start_col, end_line, end_col }\n */\nexport async function findClassPosition(filepath: string, className: string): Promise {\n try {\n const content = await readFile(filepath, 'utf-8');\n const lines = content.split('\\n');\n\n for (let i = 0; i < lines.length; i++) {\n const line = lines[i];\n // Match class definition with the specific class name\n const classNameRegex = new RegExp(`\\\\bclass\\\\s+(${className.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&')})\\\\b`);\n const match = classNameRegex.exec(line);\n \n if (match) {\n const start_line = i + 1; // 1-based line numbering\n // The class name is in capture group 1\n const classNameStart = match.index + match[0].indexOf(match[1]);\n const start_col = classNameStart + 1; // 1-based column numbering\n const end_col = start_col + className.length - 1; // end_col is inclusive\n \n return {\n start_line,\n start_col,\n end_line: start_line,\n end_col\n };\n }\n }\n\n throw new Error(`Class name '${className}' not found in file: ${filepath}`);\n } catch (error) {\n if (error instanceof Error && error.message.includes('not found in file')) {\n throw error;\n }\n throw new Error(`Failed to read or parse file ${filepath}: ${error instanceof Error ? error.message : 'Unknown error'}`);\n }\n}\n\n/**\n * Register the find class position tool with the MCP server\n */\nexport function registerFindClassPositionTool(server: McpServer): void {\n server.tool(\n 'find_class_position',\n 'Finds startline, startcol, endline endcol of a class for quickeval',\n {\n file: z.string().describe('Path to the .ql file to search'),\n name: z.string().describe('Name of the class to find'),\n },\n async ({ file, name }) => {\n try {\n const position = await findClassPosition(file, name);\n return {\n content: [{ type: 'text', text: JSON.stringify(position, null, 2) }],\n };\n } catch (error) {\n logger.error('Error finding class position:', error);\n return {\n content: [\n {\n type: 'text',\n text: `Error: ${error instanceof Error ? error.message : 'Unknown error'}`,\n },\n ],\n isError: true,\n };\n }\n }\n );\n}", "/**\n * CodeQL find predicate position tool\n * \n * Inspired by JordyZomer/codeql-mcp repository:\n * - https://github.com/JordyZomer/codeql-mcp/blob/main/server.py\n * - https://github.com/JordyZomer/codeql-mcp/blob/main/codeqlclient.py\n */\n\nimport { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport { z } from 'zod';\nimport { readFile } from 'fs/promises';\nimport { logger } from '../../utils/logger';\n\nexport interface PredicatePosition {\n start_line: number;\n start_col: number;\n end_line: number;\n end_col: number;\n}\n\n/**\n * Find the 1-based position of a predicate name in a QL file.\n * Supports: \n * - predicate name(...) - predicates with no return type\n * - Type name(...) - predicates with return type (e.g., string foo())\n * - name(...) (inside class) - member predicates\n * Returns: { start_line, start_col, end_line, end_col }\n */\nexport async function findPredicatePosition(filepath: string, predicateName: string): Promise {\n try {\n const content = await readFile(filepath, 'utf-8');\n const lines = content.split('\\n');\n const escapedName = predicateName.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&');\n\n for (let i = 0; i < lines.length; i++) {\n const line = lines[i];\n \n // Match predicate definition with the specific predicate name\n // Pattern 1: predicate name(...)\n const predicateKeywordRegex = new RegExp(`\\\\bpredicate\\\\s+(${escapedName})\\\\s*\\\\(`);\n let match = predicateKeywordRegex.exec(line);\n \n // Pattern 2: Type name(...) - predicates with return type\n // Matches: string foo(), int bar(), MyClass baz(), etc.\n // Must start at beginning of line (with optional whitespace) or after certain keywords\n if (!match) {\n const returnTypeRegex = new RegExp(`(?:^|\\\\s)(?:abstract\\\\s+)?(?:cached\\\\s+)?(?:private\\\\s+)?(?:deprecated\\\\s+)?(?:\\\\w+)\\\\s+(${escapedName})\\\\s*\\\\(`);\n match = returnTypeRegex.exec(line);\n }\n \n if (match) {\n const start_line = i + 1; // 1-based line numbering\n // The predicate name is in capture group 1\n const predicateNameStart = match.index + match[0].indexOf(match[1]);\n const start_col = predicateNameStart + 1; // 1-based column numbering\n const end_col = start_col + predicateName.length - 1; // end_col is inclusive\n \n return {\n start_line,\n start_col,\n end_line: start_line,\n end_col\n };\n }\n }\n\n throw new Error(`Predicate name '${predicateName}' not found in file: ${filepath}`);\n } catch (error) {\n if (error instanceof Error && error.message.includes('not found in file')) {\n throw error;\n }\n throw new Error(`Failed to read or parse file ${filepath}: ${error instanceof Error ? error.message : 'Unknown error'}`);\n }\n}\n\n/**\n * Register the find predicate position tool with the MCP server\n */\nexport function registerFindPredicatePositionTool(server: McpServer): void {\n server.tool(\n 'find_predicate_position',\n 'Finds startline, startcol, endline endcol of a predicate for quickeval',\n {\n file: z.string().describe('Path to the .ql file to search'),\n name: z.string().describe('Name of the predicate to find'),\n },\n async ({ file, name }) => {\n try {\n const position = await findPredicatePosition(file, name);\n return {\n content: [{ type: 'text', text: JSON.stringify(position, null, 2) }],\n };\n } catch (error) {\n logger.error('Error finding predicate position:', error);\n return {\n content: [\n {\n type: 'text',\n text: `Error: ${error instanceof Error ? error.message : 'Unknown error'}`,\n },\n ],\n isError: true,\n };\n }\n }\n );\n}", "/**\n * CodeQL find query files tool\n * Discovers and tracks all files related to a CodeQL query\n */\n\nimport { z } from 'zod';\nimport { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport { findCodeQLQueryFiles } from '../../lib/query-file-finder';\nimport { logger } from '../../utils/logger';\n\n/**\n * Register the find_codeql_query_files tool\n */\nexport function registerFindCodeQLQueryFilesTool(server: McpServer): void {\n server.tool(\n 'find_codeql_query_files',\n 'Find and track all files and directories related to a CodeQL query, including resolved metadata',\n {\n queryPath: z.string().describe('Path to the CodeQL query file (.ql)'),\n language: z.string().optional().describe('Programming language (optional, will be inferred if not provided)'),\n resolveMetadata: z.boolean().optional().describe('Whether to resolve query metadata (default: true)')\n },\n async ({ queryPath, language, resolveMetadata }) => {\n try {\n const result = await findCodeQLQueryFiles(\n queryPath,\n language,\n resolveMetadata !== false // Default to true if not specified\n );\n\n return {\n content: [{ type: 'text', text: JSON.stringify(result, null, 2) }]\n };\n } catch (error) {\n logger.error('Error finding CodeQL query files:', error);\n return {\n content: [\n {\n type: 'text',\n text: `Error: ${error instanceof Error ? error.message : 'Unknown error'}`\n }\n ],\n isError: true\n };\n }\n }\n );\n}\n", "/**\n * CodeQL query file finder utilities\n * Handles discovery and tracking of query-related files and directories\n */\n\nimport * as fs from 'fs';\nimport * as path from 'path';\nimport * as yaml from 'js-yaml';\nimport { QueryFileInfo, QueryFilesResult } from '../types/codeql';\nimport { resolveQueryMetadata } from './metadata-resolver';\n\n// Supported CodeQL languages and their file extensions (alphabetically ordered)\nconst LANGUAGE_EXTENSIONS: Record = {\n actions: 'yml',\n cpp: 'cpp',\n csharp: 'cs',\n go: 'go',\n java: 'java',\n javascript: 'js',\n python: 'py',\n ruby: 'rb',\n swift: 'swift',\n typescript: 'ts'\n};\n\nconst KNOWN_LANGUAGES = Object.keys(LANGUAGE_EXTENSIONS);\n\n/**\n * Get the file extension for test code based on language\n */\nfunction getLanguageExtension(language: string): string {\n return LANGUAGE_EXTENSIONS[language.toLowerCase()] || 'txt';\n}\n\n/**\n * Infer the language from the query file's directory structure\n */\nfunction inferLanguageFromPath(queryPath: string): string {\n const parts = queryPath.split(path.sep);\n\n for (const part of parts) {\n if (KNOWN_LANGUAGES.includes(part.toLowerCase())) {\n return part.toLowerCase();\n }\n }\n\n // Default fallback\n return 'unknown';\n}\n\n/**\n * Find the nearest qlpack.yml or codeql-pack.yml file by walking up the directory tree\n */\nfunction findNearestQlpack(startPath: string): string | null {\n let currentPath = startPath;\n const root = path.parse(currentPath).root;\n\n while (currentPath !== root) {\n // Check for codeql-pack.yml first (newer format), then qlpack.yml\n for (const packFile of ['codeql-pack.yml', 'qlpack.yml']) {\n const packPath = path.join(currentPath, packFile);\n if (fs.existsSync(packPath) && fs.statSync(packPath).isFile()) {\n return packPath;\n }\n }\n currentPath = path.dirname(currentPath);\n }\n\n return null;\n}\n\n/**\n * Read and parse qlpack.yml file\n */\nfunction readQlpackMetadata(qlpackPath: string): Record | null {\n try {\n const content = fs.readFileSync(qlpackPath, 'utf-8');\n const parsed = yaml.load(content) as Record;\n return parsed;\n } catch (_error) {\n // If we can't parse it, return null rather than failing\n return null;\n }\n}\n\n/**\n * Check if a file exists and return QueryFileInfo\n */\nfunction checkFile(filePath: string): QueryFileInfo {\n try {\n const exists = fs.existsSync(filePath) && fs.statSync(filePath).isFile();\n return {\n exists,\n path: filePath // Always return path, whether it exists or not\n };\n } catch {\n return {\n exists: false,\n path: filePath // Return the path even on error\n };\n }\n}\n\n/**\n * Check if a directory exists and return QueryFileInfo\n */\nfunction checkDirectory(dirPath: string): QueryFileInfo {\n try {\n const exists = fs.existsSync(dirPath) && fs.statSync(dirPath).isDirectory();\n return {\n exists,\n path: dirPath // Always return path, whether it exists or not\n };\n } catch {\n return {\n exists: false,\n path: dirPath // Return the path even on error\n };\n }\n}\n\n/**\n * Find all test code files in the test directory\n */\nfunction findTestCodeFiles(testDir: string, queryName: string, language: string): string[] {\n if (!fs.existsSync(testDir)) {\n return [];\n }\n\n try {\n const files = fs.readdirSync(testDir);\n const languageExt = getLanguageExtension(language);\n const testFiles: string[] = [];\n\n // Look for files matching the query name or other test code files\n const allValidExtensions = [...new Set([...Object.values(LANGUAGE_EXTENSIONS), 'yaml'])]; // Include yaml as alias for yml\n\n for (const file of files) {\n const filePath = path.join(testDir, file);\n const stat = fs.statSync(filePath);\n\n if (stat.isFile()) {\n // Include the primary test file matching query name\n if (file === `${queryName}.${languageExt}`) {\n testFiles.push(filePath);\n }\n // Include other code files (but not .qlref, .expected, .actual files)\n else if (!file.endsWith('.qlref') && !file.endsWith('.expected') && !file.endsWith('.actual')) {\n const ext = path.extname(file).slice(1);\n if (ext === languageExt || allValidExtensions.includes(ext)) {\n testFiles.push(filePath);\n }\n }\n }\n }\n\n return testFiles;\n } catch {\n return [];\n }\n}\n\n/**\n * Find CodeQL query files and directories based on a query file path\n * Optionally resolves metadata if the query file exists\n */\nexport async function findCodeQLQueryFiles(\n queryFilePath: string,\n language?: string,\n resolveMetadata: boolean = true\n): Promise {\n // Resolve absolute path\n const absoluteQueryPath = path.resolve(queryFilePath);\n\n // Extract query name and directory\n const queryName = path.basename(absoluteQueryPath, '.ql');\n const queryDir = path.dirname(absoluteQueryPath);\n\n // Infer language if not provided\n const detectedLanguage = language || inferLanguageFromPath(absoluteQueryPath);\n\n // Check query file itself\n const queryPath = checkFile(absoluteQueryPath);\n const queryDirectory = checkDirectory(queryDir);\n\n // Check for documentation files\n const mdPath = path.join(queryDir, `${queryName}.md`);\n const qhelpPath = path.join(queryDir, `${queryName}.qhelp`);\n const mdInfo = checkFile(mdPath);\n const qhelpInfo = checkFile(qhelpPath);\n\n const documentationPath: QueryFileInfo = mdInfo.exists ? mdInfo : (qhelpInfo.exists ? qhelpInfo : {\n exists: false,\n path: mdPath // Suggest .md as the default\n });\n\n // Check for specification file\n const qspecPath = path.join(queryDir, `${queryName}.qspec`);\n const specificationPath = checkFile(qspecPath);\n\n // Determine test directory\n // Pattern: if query is in .../src/QueryName/, test should be in .../test/QueryName/\n let testDir: string;\n if (queryDir.includes(`${path.sep}src${path.sep}`)) {\n // Find the last occurrence of /src/ and replace it with /test/\n const parts = queryDir.split(path.sep);\n const srcIndex = parts.lastIndexOf('src');\n if (srcIndex !== -1) {\n parts[srcIndex] = 'test';\n testDir = parts.join(path.sep);\n } else {\n // Fallback in case split didn't find it\n testDir = path.join(path.dirname(queryDir), 'test', queryName);\n }\n } else {\n // Fallback: if not in src directory, construct test dir based on parent\n testDir = path.join(path.dirname(queryDir), 'test', queryName);\n }\n const testDirectory = checkDirectory(testDir);\n\n // Check for .qlref file\n const qlrefPath = path.join(testDir, `${queryName}.qlref`);\n const qlrefInfo = checkFile(qlrefPath);\n\n // Find test code files\n const testCodePaths = findTestCodeFiles(testDir, queryName, detectedLanguage);\n\n // Check for expected results\n const expectedPath = path.join(testDir, `${queryName}.expected`);\n const expectedResultsPath = checkFile(expectedPath);\n\n // Check for actual results\n const actualPath = path.join(testDir, `${queryName}.actual`);\n const actualResultsPath = checkFile(actualPath);\n\n // Check for test database\n const testprojPath = path.join(testDir, `${queryName}.testproj`);\n const testDatabasePath = checkDirectory(testprojPath);\n\n // Determine missing files\n const missingFiles: string[] = [];\n if (!queryPath.exists) missingFiles.push(queryPath.path);\n if (!documentationPath.exists) missingFiles.push(documentationPath.path);\n if (!specificationPath.exists) missingFiles.push(specificationPath.path);\n if (!testDirectory.exists) missingFiles.push(testDirectory.path);\n if (!qlrefInfo.exists) missingFiles.push(qlrefInfo.path);\n if (testCodePaths.length === 0) missingFiles.push(path.join(testDir, `${queryName}.${getLanguageExtension(detectedLanguage)}`));\n if (!expectedResultsPath.exists) missingFiles.push(expectedResultsPath.path);\n\n const allFilesExist = missingFiles.length === 0;\n\n // Resolve metadata if requested and query file exists\n let metadata: { [key: string]: string | string[] } | undefined;\n if (resolveMetadata && queryPath.exists) {\n const resolvedMetadata = await resolveQueryMetadata(absoluteQueryPath);\n if (resolvedMetadata) {\n metadata = resolvedMetadata;\n }\n }\n\n // Resolve pack metadata and directories by finding the nearest qlpack.yml files\n let packMetadata: Record | undefined;\n const queryPackPath = findNearestQlpack(queryDir);\n const queryPackDir = queryPackPath ? path.dirname(queryPackPath) : queryDir;\n if (queryPackPath) {\n const parsed = readQlpackMetadata(queryPackPath);\n if (parsed) {\n packMetadata = parsed;\n }\n }\n\n // Find pack directory for test files\n const testPackPath = findNearestQlpack(testDir);\n const testPackDir = testPackPath ? path.dirname(testPackPath) : testDir;\n\n return {\n queryName,\n language: detectedLanguage,\n\n allFilesExist,\n\n files: {\n query: {\n dir: queryDirectory.path,\n doc: path.basename(documentationPath.path),\n packDir: queryPackDir,\n query: path.basename(queryPath.path),\n spec: path.basename(specificationPath.path)\n },\n test: {\n actual: path.basename(actualResultsPath.path),\n dir: testDirectory.path,\n expected: path.basename(expectedResultsPath.path),\n packDir: testPackDir,\n qlref: path.basename(qlrefInfo.path),\n testCode: testCodePaths,\n testDatabaseDir: testDatabasePath.path\n }\n },\n\n metadata,\n\n missingFiles,\n\n packMetadata,\n\n status: {\n actualResultsExist: actualResultsPath.exists,\n documentationExists: documentationPath.exists,\n expectedResultsExist: expectedResultsPath.exists,\n hasTestCode: testCodePaths.length > 0,\n qlrefExists: qlrefInfo.exists,\n queryExists: queryPath.exists,\n specificationExists: specificationPath.exists,\n testDatabaseDirExists: testDatabasePath.exists,\n testDirectoryExists: testDirectory.exists\n }\n };\n}\n", "\n/*! js-yaml 4.1.1 https://github.com/nodeca/js-yaml @license MIT */\nfunction isNothing(subject) {\n return (typeof subject === 'undefined') || (subject === null);\n}\n\n\nfunction isObject(subject) {\n return (typeof subject === 'object') && (subject !== null);\n}\n\n\nfunction toArray(sequence) {\n if (Array.isArray(sequence)) return sequence;\n else if (isNothing(sequence)) return [];\n\n return [ sequence ];\n}\n\n\nfunction extend(target, source) {\n var index, length, key, sourceKeys;\n\n if (source) {\n sourceKeys = Object.keys(source);\n\n for (index = 0, length = sourceKeys.length; index < length; index += 1) {\n key = sourceKeys[index];\n target[key] = source[key];\n }\n }\n\n return target;\n}\n\n\nfunction repeat(string, count) {\n var result = '', cycle;\n\n for (cycle = 0; cycle < count; cycle += 1) {\n result += string;\n }\n\n return result;\n}\n\n\nfunction isNegativeZero(number) {\n return (number === 0) && (Number.NEGATIVE_INFINITY === 1 / number);\n}\n\n\nvar isNothing_1 = isNothing;\nvar isObject_1 = isObject;\nvar toArray_1 = toArray;\nvar repeat_1 = repeat;\nvar isNegativeZero_1 = isNegativeZero;\nvar extend_1 = extend;\n\nvar common = {\n\tisNothing: isNothing_1,\n\tisObject: isObject_1,\n\ttoArray: toArray_1,\n\trepeat: repeat_1,\n\tisNegativeZero: isNegativeZero_1,\n\textend: extend_1\n};\n\n// YAML error class. http://stackoverflow.com/questions/8458984\n\n\nfunction formatError(exception, compact) {\n var where = '', message = exception.reason || '(unknown reason)';\n\n if (!exception.mark) return message;\n\n if (exception.mark.name) {\n where += 'in \"' + exception.mark.name + '\" ';\n }\n\n where += '(' + (exception.mark.line + 1) + ':' + (exception.mark.column + 1) + ')';\n\n if (!compact && exception.mark.snippet) {\n where += '\\n\\n' + exception.mark.snippet;\n }\n\n return message + ' ' + where;\n}\n\n\nfunction YAMLException$1(reason, mark) {\n // Super constructor\n Error.call(this);\n\n this.name = 'YAMLException';\n this.reason = reason;\n this.mark = mark;\n this.message = formatError(this, false);\n\n // Include stack trace in error object\n if (Error.captureStackTrace) {\n // Chrome and NodeJS\n Error.captureStackTrace(this, this.constructor);\n } else {\n // FF, IE 10+ and Safari 6+. Fallback for others\n this.stack = (new Error()).stack || '';\n }\n}\n\n\n// Inherit from Error\nYAMLException$1.prototype = Object.create(Error.prototype);\nYAMLException$1.prototype.constructor = YAMLException$1;\n\n\nYAMLException$1.prototype.toString = function toString(compact) {\n return this.name + ': ' + formatError(this, compact);\n};\n\n\nvar exception = YAMLException$1;\n\n// get snippet for a single line, respecting maxLength\nfunction getLine(buffer, lineStart, lineEnd, position, maxLineLength) {\n var head = '';\n var tail = '';\n var maxHalfLength = Math.floor(maxLineLength / 2) - 1;\n\n if (position - lineStart > maxHalfLength) {\n head = ' ... ';\n lineStart = position - maxHalfLength + head.length;\n }\n\n if (lineEnd - position > maxHalfLength) {\n tail = ' ...';\n lineEnd = position + maxHalfLength - tail.length;\n }\n\n return {\n str: head + buffer.slice(lineStart, lineEnd).replace(/\\t/g, '\u2192') + tail,\n pos: position - lineStart + head.length // relative position\n };\n}\n\n\nfunction padStart(string, max) {\n return common.repeat(' ', max - string.length) + string;\n}\n\n\nfunction makeSnippet(mark, options) {\n options = Object.create(options || null);\n\n if (!mark.buffer) return null;\n\n if (!options.maxLength) options.maxLength = 79;\n if (typeof options.indent !== 'number') options.indent = 1;\n if (typeof options.linesBefore !== 'number') options.linesBefore = 3;\n if (typeof options.linesAfter !== 'number') options.linesAfter = 2;\n\n var re = /\\r?\\n|\\r|\\0/g;\n var lineStarts = [ 0 ];\n var lineEnds = [];\n var match;\n var foundLineNo = -1;\n\n while ((match = re.exec(mark.buffer))) {\n lineEnds.push(match.index);\n lineStarts.push(match.index + match[0].length);\n\n if (mark.position <= match.index && foundLineNo < 0) {\n foundLineNo = lineStarts.length - 2;\n }\n }\n\n if (foundLineNo < 0) foundLineNo = lineStarts.length - 1;\n\n var result = '', i, line;\n var lineNoLength = Math.min(mark.line + options.linesAfter, lineEnds.length).toString().length;\n var maxLineLength = options.maxLength - (options.indent + lineNoLength + 3);\n\n for (i = 1; i <= options.linesBefore; i++) {\n if (foundLineNo - i < 0) break;\n line = getLine(\n mark.buffer,\n lineStarts[foundLineNo - i],\n lineEnds[foundLineNo - i],\n mark.position - (lineStarts[foundLineNo] - lineStarts[foundLineNo - i]),\n maxLineLength\n );\n result = common.repeat(' ', options.indent) + padStart((mark.line - i + 1).toString(), lineNoLength) +\n ' | ' + line.str + '\\n' + result;\n }\n\n line = getLine(mark.buffer, lineStarts[foundLineNo], lineEnds[foundLineNo], mark.position, maxLineLength);\n result += common.repeat(' ', options.indent) + padStart((mark.line + 1).toString(), lineNoLength) +\n ' | ' + line.str + '\\n';\n result += common.repeat('-', options.indent + lineNoLength + 3 + line.pos) + '^' + '\\n';\n\n for (i = 1; i <= options.linesAfter; i++) {\n if (foundLineNo + i >= lineEnds.length) break;\n line = getLine(\n mark.buffer,\n lineStarts[foundLineNo + i],\n lineEnds[foundLineNo + i],\n mark.position - (lineStarts[foundLineNo] - lineStarts[foundLineNo + i]),\n maxLineLength\n );\n result += common.repeat(' ', options.indent) + padStart((mark.line + i + 1).toString(), lineNoLength) +\n ' | ' + line.str + '\\n';\n }\n\n return result.replace(/\\n$/, '');\n}\n\n\nvar snippet = makeSnippet;\n\nvar TYPE_CONSTRUCTOR_OPTIONS = [\n 'kind',\n 'multi',\n 'resolve',\n 'construct',\n 'instanceOf',\n 'predicate',\n 'represent',\n 'representName',\n 'defaultStyle',\n 'styleAliases'\n];\n\nvar YAML_NODE_KINDS = [\n 'scalar',\n 'sequence',\n 'mapping'\n];\n\nfunction compileStyleAliases(map) {\n var result = {};\n\n if (map !== null) {\n Object.keys(map).forEach(function (style) {\n map[style].forEach(function (alias) {\n result[String(alias)] = style;\n });\n });\n }\n\n return result;\n}\n\nfunction Type$1(tag, options) {\n options = options || {};\n\n Object.keys(options).forEach(function (name) {\n if (TYPE_CONSTRUCTOR_OPTIONS.indexOf(name) === -1) {\n throw new exception('Unknown option \"' + name + '\" is met in definition of \"' + tag + '\" YAML type.');\n }\n });\n\n // TODO: Add tag format check.\n this.options = options; // keep original options in case user wants to extend this type later\n this.tag = tag;\n this.kind = options['kind'] || null;\n this.resolve = options['resolve'] || function () { return true; };\n this.construct = options['construct'] || function (data) { return data; };\n this.instanceOf = options['instanceOf'] || null;\n this.predicate = options['predicate'] || null;\n this.represent = options['represent'] || null;\n this.representName = options['representName'] || null;\n this.defaultStyle = options['defaultStyle'] || null;\n this.multi = options['multi'] || false;\n this.styleAliases = compileStyleAliases(options['styleAliases'] || null);\n\n if (YAML_NODE_KINDS.indexOf(this.kind) === -1) {\n throw new exception('Unknown kind \"' + this.kind + '\" is specified for \"' + tag + '\" YAML type.');\n }\n}\n\nvar type = Type$1;\n\n/*eslint-disable max-len*/\n\n\n\n\n\nfunction compileList(schema, name) {\n var result = [];\n\n schema[name].forEach(function (currentType) {\n var newIndex = result.length;\n\n result.forEach(function (previousType, previousIndex) {\n if (previousType.tag === currentType.tag &&\n previousType.kind === currentType.kind &&\n previousType.multi === currentType.multi) {\n\n newIndex = previousIndex;\n }\n });\n\n result[newIndex] = currentType;\n });\n\n return result;\n}\n\n\nfunction compileMap(/* lists... */) {\n var result = {\n scalar: {},\n sequence: {},\n mapping: {},\n fallback: {},\n multi: {\n scalar: [],\n sequence: [],\n mapping: [],\n fallback: []\n }\n }, index, length;\n\n function collectType(type) {\n if (type.multi) {\n result.multi[type.kind].push(type);\n result.multi['fallback'].push(type);\n } else {\n result[type.kind][type.tag] = result['fallback'][type.tag] = type;\n }\n }\n\n for (index = 0, length = arguments.length; index < length; index += 1) {\n arguments[index].forEach(collectType);\n }\n return result;\n}\n\n\nfunction Schema$1(definition) {\n return this.extend(definition);\n}\n\n\nSchema$1.prototype.extend = function extend(definition) {\n var implicit = [];\n var explicit = [];\n\n if (definition instanceof type) {\n // Schema.extend(type)\n explicit.push(definition);\n\n } else if (Array.isArray(definition)) {\n // Schema.extend([ type1, type2, ... ])\n explicit = explicit.concat(definition);\n\n } else if (definition && (Array.isArray(definition.implicit) || Array.isArray(definition.explicit))) {\n // Schema.extend({ explicit: [ type1, type2, ... ], implicit: [ type1, type2, ... ] })\n if (definition.implicit) implicit = implicit.concat(definition.implicit);\n if (definition.explicit) explicit = explicit.concat(definition.explicit);\n\n } else {\n throw new exception('Schema.extend argument should be a Type, [ Type ], ' +\n 'or a schema definition ({ implicit: [...], explicit: [...] })');\n }\n\n implicit.forEach(function (type$1) {\n if (!(type$1 instanceof type)) {\n throw new exception('Specified list of YAML types (or a single Type object) contains a non-Type object.');\n }\n\n if (type$1.loadKind && type$1.loadKind !== 'scalar') {\n throw new exception('There is a non-scalar type in the implicit list of a schema. Implicit resolving of such types is not supported.');\n }\n\n if (type$1.multi) {\n throw new exception('There is a multi type in the implicit list of a schema. Multi tags can only be listed as explicit.');\n }\n });\n\n explicit.forEach(function (type$1) {\n if (!(type$1 instanceof type)) {\n throw new exception('Specified list of YAML types (or a single Type object) contains a non-Type object.');\n }\n });\n\n var result = Object.create(Schema$1.prototype);\n\n result.implicit = (this.implicit || []).concat(implicit);\n result.explicit = (this.explicit || []).concat(explicit);\n\n result.compiledImplicit = compileList(result, 'implicit');\n result.compiledExplicit = compileList(result, 'explicit');\n result.compiledTypeMap = compileMap(result.compiledImplicit, result.compiledExplicit);\n\n return result;\n};\n\n\nvar schema = Schema$1;\n\nvar str = new type('tag:yaml.org,2002:str', {\n kind: 'scalar',\n construct: function (data) { return data !== null ? data : ''; }\n});\n\nvar seq = new type('tag:yaml.org,2002:seq', {\n kind: 'sequence',\n construct: function (data) { return data !== null ? data : []; }\n});\n\nvar map = new type('tag:yaml.org,2002:map', {\n kind: 'mapping',\n construct: function (data) { return data !== null ? data : {}; }\n});\n\nvar failsafe = new schema({\n explicit: [\n str,\n seq,\n map\n ]\n});\n\nfunction resolveYamlNull(data) {\n if (data === null) return true;\n\n var max = data.length;\n\n return (max === 1 && data === '~') ||\n (max === 4 && (data === 'null' || data === 'Null' || data === 'NULL'));\n}\n\nfunction constructYamlNull() {\n return null;\n}\n\nfunction isNull(object) {\n return object === null;\n}\n\nvar _null = new type('tag:yaml.org,2002:null', {\n kind: 'scalar',\n resolve: resolveYamlNull,\n construct: constructYamlNull,\n predicate: isNull,\n represent: {\n canonical: function () { return '~'; },\n lowercase: function () { return 'null'; },\n uppercase: function () { return 'NULL'; },\n camelcase: function () { return 'Null'; },\n empty: function () { return ''; }\n },\n defaultStyle: 'lowercase'\n});\n\nfunction resolveYamlBoolean(data) {\n if (data === null) return false;\n\n var max = data.length;\n\n return (max === 4 && (data === 'true' || data === 'True' || data === 'TRUE')) ||\n (max === 5 && (data === 'false' || data === 'False' || data === 'FALSE'));\n}\n\nfunction constructYamlBoolean(data) {\n return data === 'true' ||\n data === 'True' ||\n data === 'TRUE';\n}\n\nfunction isBoolean(object) {\n return Object.prototype.toString.call(object) === '[object Boolean]';\n}\n\nvar bool = new type('tag:yaml.org,2002:bool', {\n kind: 'scalar',\n resolve: resolveYamlBoolean,\n construct: constructYamlBoolean,\n predicate: isBoolean,\n represent: {\n lowercase: function (object) { return object ? 'true' : 'false'; },\n uppercase: function (object) { return object ? 'TRUE' : 'FALSE'; },\n camelcase: function (object) { return object ? 'True' : 'False'; }\n },\n defaultStyle: 'lowercase'\n});\n\nfunction isHexCode(c) {\n return ((0x30/* 0 */ <= c) && (c <= 0x39/* 9 */)) ||\n ((0x41/* A */ <= c) && (c <= 0x46/* F */)) ||\n ((0x61/* a */ <= c) && (c <= 0x66/* f */));\n}\n\nfunction isOctCode(c) {\n return ((0x30/* 0 */ <= c) && (c <= 0x37/* 7 */));\n}\n\nfunction isDecCode(c) {\n return ((0x30/* 0 */ <= c) && (c <= 0x39/* 9 */));\n}\n\nfunction resolveYamlInteger(data) {\n if (data === null) return false;\n\n var max = data.length,\n index = 0,\n hasDigits = false,\n ch;\n\n if (!max) return false;\n\n ch = data[index];\n\n // sign\n if (ch === '-' || ch === '+') {\n ch = data[++index];\n }\n\n if (ch === '0') {\n // 0\n if (index + 1 === max) return true;\n ch = data[++index];\n\n // base 2, base 8, base 16\n\n if (ch === 'b') {\n // base 2\n index++;\n\n for (; index < max; index++) {\n ch = data[index];\n if (ch === '_') continue;\n if (ch !== '0' && ch !== '1') return false;\n hasDigits = true;\n }\n return hasDigits && ch !== '_';\n }\n\n\n if (ch === 'x') {\n // base 16\n index++;\n\n for (; index < max; index++) {\n ch = data[index];\n if (ch === '_') continue;\n if (!isHexCode(data.charCodeAt(index))) return false;\n hasDigits = true;\n }\n return hasDigits && ch !== '_';\n }\n\n\n if (ch === 'o') {\n // base 8\n index++;\n\n for (; index < max; index++) {\n ch = data[index];\n if (ch === '_') continue;\n if (!isOctCode(data.charCodeAt(index))) return false;\n hasDigits = true;\n }\n return hasDigits && ch !== '_';\n }\n }\n\n // base 10 (except 0)\n\n // value should not start with `_`;\n if (ch === '_') return false;\n\n for (; index < max; index++) {\n ch = data[index];\n if (ch === '_') continue;\n if (!isDecCode(data.charCodeAt(index))) {\n return false;\n }\n hasDigits = true;\n }\n\n // Should have digits and should not end with `_`\n if (!hasDigits || ch === '_') return false;\n\n return true;\n}\n\nfunction constructYamlInteger(data) {\n var value = data, sign = 1, ch;\n\n if (value.indexOf('_') !== -1) {\n value = value.replace(/_/g, '');\n }\n\n ch = value[0];\n\n if (ch === '-' || ch === '+') {\n if (ch === '-') sign = -1;\n value = value.slice(1);\n ch = value[0];\n }\n\n if (value === '0') return 0;\n\n if (ch === '0') {\n if (value[1] === 'b') return sign * parseInt(value.slice(2), 2);\n if (value[1] === 'x') return sign * parseInt(value.slice(2), 16);\n if (value[1] === 'o') return sign * parseInt(value.slice(2), 8);\n }\n\n return sign * parseInt(value, 10);\n}\n\nfunction isInteger(object) {\n return (Object.prototype.toString.call(object)) === '[object Number]' &&\n (object % 1 === 0 && !common.isNegativeZero(object));\n}\n\nvar int = new type('tag:yaml.org,2002:int', {\n kind: 'scalar',\n resolve: resolveYamlInteger,\n construct: constructYamlInteger,\n predicate: isInteger,\n represent: {\n binary: function (obj) { return obj >= 0 ? '0b' + obj.toString(2) : '-0b' + obj.toString(2).slice(1); },\n octal: function (obj) { return obj >= 0 ? '0o' + obj.toString(8) : '-0o' + obj.toString(8).slice(1); },\n decimal: function (obj) { return obj.toString(10); },\n /* eslint-disable max-len */\n hexadecimal: function (obj) { return obj >= 0 ? '0x' + obj.toString(16).toUpperCase() : '-0x' + obj.toString(16).toUpperCase().slice(1); }\n },\n defaultStyle: 'decimal',\n styleAliases: {\n binary: [ 2, 'bin' ],\n octal: [ 8, 'oct' ],\n decimal: [ 10, 'dec' ],\n hexadecimal: [ 16, 'hex' ]\n }\n});\n\nvar YAML_FLOAT_PATTERN = new RegExp(\n // 2.5e4, 2.5 and integers\n '^(?:[-+]?(?:[0-9][0-9_]*)(?:\\\\.[0-9_]*)?(?:[eE][-+]?[0-9]+)?' +\n // .2e4, .2\n // special case, seems not from spec\n '|\\\\.[0-9_]+(?:[eE][-+]?[0-9]+)?' +\n // .inf\n '|[-+]?\\\\.(?:inf|Inf|INF)' +\n // .nan\n '|\\\\.(?:nan|NaN|NAN))$');\n\nfunction resolveYamlFloat(data) {\n if (data === null) return false;\n\n if (!YAML_FLOAT_PATTERN.test(data) ||\n // Quick hack to not allow integers end with `_`\n // Probably should update regexp & check speed\n data[data.length - 1] === '_') {\n return false;\n }\n\n return true;\n}\n\nfunction constructYamlFloat(data) {\n var value, sign;\n\n value = data.replace(/_/g, '').toLowerCase();\n sign = value[0] === '-' ? -1 : 1;\n\n if ('+-'.indexOf(value[0]) >= 0) {\n value = value.slice(1);\n }\n\n if (value === '.inf') {\n return (sign === 1) ? Number.POSITIVE_INFINITY : Number.NEGATIVE_INFINITY;\n\n } else if (value === '.nan') {\n return NaN;\n }\n return sign * parseFloat(value, 10);\n}\n\n\nvar SCIENTIFIC_WITHOUT_DOT = /^[-+]?[0-9]+e/;\n\nfunction representYamlFloat(object, style) {\n var res;\n\n if (isNaN(object)) {\n switch (style) {\n case 'lowercase': return '.nan';\n case 'uppercase': return '.NAN';\n case 'camelcase': return '.NaN';\n }\n } else if (Number.POSITIVE_INFINITY === object) {\n switch (style) {\n case 'lowercase': return '.inf';\n case 'uppercase': return '.INF';\n case 'camelcase': return '.Inf';\n }\n } else if (Number.NEGATIVE_INFINITY === object) {\n switch (style) {\n case 'lowercase': return '-.inf';\n case 'uppercase': return '-.INF';\n case 'camelcase': return '-.Inf';\n }\n } else if (common.isNegativeZero(object)) {\n return '-0.0';\n }\n\n res = object.toString(10);\n\n // JS stringifier can build scientific format without dots: 5e-100,\n // while YAML requres dot: 5.e-100. Fix it with simple hack\n\n return SCIENTIFIC_WITHOUT_DOT.test(res) ? res.replace('e', '.e') : res;\n}\n\nfunction isFloat(object) {\n return (Object.prototype.toString.call(object) === '[object Number]') &&\n (object % 1 !== 0 || common.isNegativeZero(object));\n}\n\nvar float = new type('tag:yaml.org,2002:float', {\n kind: 'scalar',\n resolve: resolveYamlFloat,\n construct: constructYamlFloat,\n predicate: isFloat,\n represent: representYamlFloat,\n defaultStyle: 'lowercase'\n});\n\nvar json = failsafe.extend({\n implicit: [\n _null,\n bool,\n int,\n float\n ]\n});\n\nvar core = json;\n\nvar YAML_DATE_REGEXP = new RegExp(\n '^([0-9][0-9][0-9][0-9])' + // [1] year\n '-([0-9][0-9])' + // [2] month\n '-([0-9][0-9])$'); // [3] day\n\nvar YAML_TIMESTAMP_REGEXP = new RegExp(\n '^([0-9][0-9][0-9][0-9])' + // [1] year\n '-([0-9][0-9]?)' + // [2] month\n '-([0-9][0-9]?)' + // [3] day\n '(?:[Tt]|[ \\\\t]+)' + // ...\n '([0-9][0-9]?)' + // [4] hour\n ':([0-9][0-9])' + // [5] minute\n ':([0-9][0-9])' + // [6] second\n '(?:\\\\.([0-9]*))?' + // [7] fraction\n '(?:[ \\\\t]*(Z|([-+])([0-9][0-9]?)' + // [8] tz [9] tz_sign [10] tz_hour\n '(?::([0-9][0-9]))?))?$'); // [11] tz_minute\n\nfunction resolveYamlTimestamp(data) {\n if (data === null) return false;\n if (YAML_DATE_REGEXP.exec(data) !== null) return true;\n if (YAML_TIMESTAMP_REGEXP.exec(data) !== null) return true;\n return false;\n}\n\nfunction constructYamlTimestamp(data) {\n var match, year, month, day, hour, minute, second, fraction = 0,\n delta = null, tz_hour, tz_minute, date;\n\n match = YAML_DATE_REGEXP.exec(data);\n if (match === null) match = YAML_TIMESTAMP_REGEXP.exec(data);\n\n if (match === null) throw new Error('Date resolve error');\n\n // match: [1] year [2] month [3] day\n\n year = +(match[1]);\n month = +(match[2]) - 1; // JS month starts with 0\n day = +(match[3]);\n\n if (!match[4]) { // no hour\n return new Date(Date.UTC(year, month, day));\n }\n\n // match: [4] hour [5] minute [6] second [7] fraction\n\n hour = +(match[4]);\n minute = +(match[5]);\n second = +(match[6]);\n\n if (match[7]) {\n fraction = match[7].slice(0, 3);\n while (fraction.length < 3) { // milli-seconds\n fraction += '0';\n }\n fraction = +fraction;\n }\n\n // match: [8] tz [9] tz_sign [10] tz_hour [11] tz_minute\n\n if (match[9]) {\n tz_hour = +(match[10]);\n tz_minute = +(match[11] || 0);\n delta = (tz_hour * 60 + tz_minute) * 60000; // delta in mili-seconds\n if (match[9] === '-') delta = -delta;\n }\n\n date = new Date(Date.UTC(year, month, day, hour, minute, second, fraction));\n\n if (delta) date.setTime(date.getTime() - delta);\n\n return date;\n}\n\nfunction representYamlTimestamp(object /*, style*/) {\n return object.toISOString();\n}\n\nvar timestamp = new type('tag:yaml.org,2002:timestamp', {\n kind: 'scalar',\n resolve: resolveYamlTimestamp,\n construct: constructYamlTimestamp,\n instanceOf: Date,\n represent: representYamlTimestamp\n});\n\nfunction resolveYamlMerge(data) {\n return data === '<<' || data === null;\n}\n\nvar merge = new type('tag:yaml.org,2002:merge', {\n kind: 'scalar',\n resolve: resolveYamlMerge\n});\n\n/*eslint-disable no-bitwise*/\n\n\n\n\n\n// [ 64, 65, 66 ] -> [ padding, CR, LF ]\nvar BASE64_MAP = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=\\n\\r';\n\n\nfunction resolveYamlBinary(data) {\n if (data === null) return false;\n\n var code, idx, bitlen = 0, max = data.length, map = BASE64_MAP;\n\n // Convert one by one.\n for (idx = 0; idx < max; idx++) {\n code = map.indexOf(data.charAt(idx));\n\n // Skip CR/LF\n if (code > 64) continue;\n\n // Fail on illegal characters\n if (code < 0) return false;\n\n bitlen += 6;\n }\n\n // If there are any bits left, source was corrupted\n return (bitlen % 8) === 0;\n}\n\nfunction constructYamlBinary(data) {\n var idx, tailbits,\n input = data.replace(/[\\r\\n=]/g, ''), // remove CR/LF & padding to simplify scan\n max = input.length,\n map = BASE64_MAP,\n bits = 0,\n result = [];\n\n // Collect by 6*4 bits (3 bytes)\n\n for (idx = 0; idx < max; idx++) {\n if ((idx % 4 === 0) && idx) {\n result.push((bits >> 16) & 0xFF);\n result.push((bits >> 8) & 0xFF);\n result.push(bits & 0xFF);\n }\n\n bits = (bits << 6) | map.indexOf(input.charAt(idx));\n }\n\n // Dump tail\n\n tailbits = (max % 4) * 6;\n\n if (tailbits === 0) {\n result.push((bits >> 16) & 0xFF);\n result.push((bits >> 8) & 0xFF);\n result.push(bits & 0xFF);\n } else if (tailbits === 18) {\n result.push((bits >> 10) & 0xFF);\n result.push((bits >> 2) & 0xFF);\n } else if (tailbits === 12) {\n result.push((bits >> 4) & 0xFF);\n }\n\n return new Uint8Array(result);\n}\n\nfunction representYamlBinary(object /*, style*/) {\n var result = '', bits = 0, idx, tail,\n max = object.length,\n map = BASE64_MAP;\n\n // Convert every three bytes to 4 ASCII characters.\n\n for (idx = 0; idx < max; idx++) {\n if ((idx % 3 === 0) && idx) {\n result += map[(bits >> 18) & 0x3F];\n result += map[(bits >> 12) & 0x3F];\n result += map[(bits >> 6) & 0x3F];\n result += map[bits & 0x3F];\n }\n\n bits = (bits << 8) + object[idx];\n }\n\n // Dump tail\n\n tail = max % 3;\n\n if (tail === 0) {\n result += map[(bits >> 18) & 0x3F];\n result += map[(bits >> 12) & 0x3F];\n result += map[(bits >> 6) & 0x3F];\n result += map[bits & 0x3F];\n } else if (tail === 2) {\n result += map[(bits >> 10) & 0x3F];\n result += map[(bits >> 4) & 0x3F];\n result += map[(bits << 2) & 0x3F];\n result += map[64];\n } else if (tail === 1) {\n result += map[(bits >> 2) & 0x3F];\n result += map[(bits << 4) & 0x3F];\n result += map[64];\n result += map[64];\n }\n\n return result;\n}\n\nfunction isBinary(obj) {\n return Object.prototype.toString.call(obj) === '[object Uint8Array]';\n}\n\nvar binary = new type('tag:yaml.org,2002:binary', {\n kind: 'scalar',\n resolve: resolveYamlBinary,\n construct: constructYamlBinary,\n predicate: isBinary,\n represent: representYamlBinary\n});\n\nvar _hasOwnProperty$3 = Object.prototype.hasOwnProperty;\nvar _toString$2 = Object.prototype.toString;\n\nfunction resolveYamlOmap(data) {\n if (data === null) return true;\n\n var objectKeys = [], index, length, pair, pairKey, pairHasKey,\n object = data;\n\n for (index = 0, length = object.length; index < length; index += 1) {\n pair = object[index];\n pairHasKey = false;\n\n if (_toString$2.call(pair) !== '[object Object]') return false;\n\n for (pairKey in pair) {\n if (_hasOwnProperty$3.call(pair, pairKey)) {\n if (!pairHasKey) pairHasKey = true;\n else return false;\n }\n }\n\n if (!pairHasKey) return false;\n\n if (objectKeys.indexOf(pairKey) === -1) objectKeys.push(pairKey);\n else return false;\n }\n\n return true;\n}\n\nfunction constructYamlOmap(data) {\n return data !== null ? data : [];\n}\n\nvar omap = new type('tag:yaml.org,2002:omap', {\n kind: 'sequence',\n resolve: resolveYamlOmap,\n construct: constructYamlOmap\n});\n\nvar _toString$1 = Object.prototype.toString;\n\nfunction resolveYamlPairs(data) {\n if (data === null) return true;\n\n var index, length, pair, keys, result,\n object = data;\n\n result = new Array(object.length);\n\n for (index = 0, length = object.length; index < length; index += 1) {\n pair = object[index];\n\n if (_toString$1.call(pair) !== '[object Object]') return false;\n\n keys = Object.keys(pair);\n\n if (keys.length !== 1) return false;\n\n result[index] = [ keys[0], pair[keys[0]] ];\n }\n\n return true;\n}\n\nfunction constructYamlPairs(data) {\n if (data === null) return [];\n\n var index, length, pair, keys, result,\n object = data;\n\n result = new Array(object.length);\n\n for (index = 0, length = object.length; index < length; index += 1) {\n pair = object[index];\n\n keys = Object.keys(pair);\n\n result[index] = [ keys[0], pair[keys[0]] ];\n }\n\n return result;\n}\n\nvar pairs = new type('tag:yaml.org,2002:pairs', {\n kind: 'sequence',\n resolve: resolveYamlPairs,\n construct: constructYamlPairs\n});\n\nvar _hasOwnProperty$2 = Object.prototype.hasOwnProperty;\n\nfunction resolveYamlSet(data) {\n if (data === null) return true;\n\n var key, object = data;\n\n for (key in object) {\n if (_hasOwnProperty$2.call(object, key)) {\n if (object[key] !== null) return false;\n }\n }\n\n return true;\n}\n\nfunction constructYamlSet(data) {\n return data !== null ? data : {};\n}\n\nvar set = new type('tag:yaml.org,2002:set', {\n kind: 'mapping',\n resolve: resolveYamlSet,\n construct: constructYamlSet\n});\n\nvar _default = core.extend({\n implicit: [\n timestamp,\n merge\n ],\n explicit: [\n binary,\n omap,\n pairs,\n set\n ]\n});\n\n/*eslint-disable max-len,no-use-before-define*/\n\n\n\n\n\n\n\nvar _hasOwnProperty$1 = Object.prototype.hasOwnProperty;\n\n\nvar CONTEXT_FLOW_IN = 1;\nvar CONTEXT_FLOW_OUT = 2;\nvar CONTEXT_BLOCK_IN = 3;\nvar CONTEXT_BLOCK_OUT = 4;\n\n\nvar CHOMPING_CLIP = 1;\nvar CHOMPING_STRIP = 2;\nvar CHOMPING_KEEP = 3;\n\n\nvar PATTERN_NON_PRINTABLE = /[\\x00-\\x08\\x0B\\x0C\\x0E-\\x1F\\x7F-\\x84\\x86-\\x9F\\uFFFE\\uFFFF]|[\\uD800-\\uDBFF](?![\\uDC00-\\uDFFF])|(?:[^\\uD800-\\uDBFF]|^)[\\uDC00-\\uDFFF]/;\nvar PATTERN_NON_ASCII_LINE_BREAKS = /[\\x85\\u2028\\u2029]/;\nvar PATTERN_FLOW_INDICATORS = /[,\\[\\]\\{\\}]/;\nvar PATTERN_TAG_HANDLE = /^(?:!|!!|![a-z\\-]+!)$/i;\nvar PATTERN_TAG_URI = /^(?:!|[^,\\[\\]\\{\\}])(?:%[0-9a-f]{2}|[0-9a-z\\-#;\\/\\?:@&=\\+\\$,_\\.!~\\*'\\(\\)\\[\\]])*$/i;\n\n\nfunction _class(obj) { return Object.prototype.toString.call(obj); }\n\nfunction is_EOL(c) {\n return (c === 0x0A/* LF */) || (c === 0x0D/* CR */);\n}\n\nfunction is_WHITE_SPACE(c) {\n return (c === 0x09/* Tab */) || (c === 0x20/* Space */);\n}\n\nfunction is_WS_OR_EOL(c) {\n return (c === 0x09/* Tab */) ||\n (c === 0x20/* Space */) ||\n (c === 0x0A/* LF */) ||\n (c === 0x0D/* CR */);\n}\n\nfunction is_FLOW_INDICATOR(c) {\n return c === 0x2C/* , */ ||\n c === 0x5B/* [ */ ||\n c === 0x5D/* ] */ ||\n c === 0x7B/* { */ ||\n c === 0x7D/* } */;\n}\n\nfunction fromHexCode(c) {\n var lc;\n\n if ((0x30/* 0 */ <= c) && (c <= 0x39/* 9 */)) {\n return c - 0x30;\n }\n\n /*eslint-disable no-bitwise*/\n lc = c | 0x20;\n\n if ((0x61/* a */ <= lc) && (lc <= 0x66/* f */)) {\n return lc - 0x61 + 10;\n }\n\n return -1;\n}\n\nfunction escapedHexLen(c) {\n if (c === 0x78/* x */) { return 2; }\n if (c === 0x75/* u */) { return 4; }\n if (c === 0x55/* U */) { return 8; }\n return 0;\n}\n\nfunction fromDecimalCode(c) {\n if ((0x30/* 0 */ <= c) && (c <= 0x39/* 9 */)) {\n return c - 0x30;\n }\n\n return -1;\n}\n\nfunction simpleEscapeSequence(c) {\n /* eslint-disable indent */\n return (c === 0x30/* 0 */) ? '\\x00' :\n (c === 0x61/* a */) ? '\\x07' :\n (c === 0x62/* b */) ? '\\x08' :\n (c === 0x74/* t */) ? '\\x09' :\n (c === 0x09/* Tab */) ? '\\x09' :\n (c === 0x6E/* n */) ? '\\x0A' :\n (c === 0x76/* v */) ? '\\x0B' :\n (c === 0x66/* f */) ? '\\x0C' :\n (c === 0x72/* r */) ? '\\x0D' :\n (c === 0x65/* e */) ? '\\x1B' :\n (c === 0x20/* Space */) ? ' ' :\n (c === 0x22/* \" */) ? '\\x22' :\n (c === 0x2F/* / */) ? '/' :\n (c === 0x5C/* \\ */) ? '\\x5C' :\n (c === 0x4E/* N */) ? '\\x85' :\n (c === 0x5F/* _ */) ? '\\xA0' :\n (c === 0x4C/* L */) ? '\\u2028' :\n (c === 0x50/* P */) ? '\\u2029' : '';\n}\n\nfunction charFromCodepoint(c) {\n if (c <= 0xFFFF) {\n return String.fromCharCode(c);\n }\n // Encode UTF-16 surrogate pair\n // https://en.wikipedia.org/wiki/UTF-16#Code_points_U.2B010000_to_U.2B10FFFF\n return String.fromCharCode(\n ((c - 0x010000) >> 10) + 0xD800,\n ((c - 0x010000) & 0x03FF) + 0xDC00\n );\n}\n\n// set a property of a literal object, while protecting against prototype pollution,\n// see https://github.com/nodeca/js-yaml/issues/164 for more details\nfunction setProperty(object, key, value) {\n // used for this specific key only because Object.defineProperty is slow\n if (key === '__proto__') {\n Object.defineProperty(object, key, {\n configurable: true,\n enumerable: true,\n writable: true,\n value: value\n });\n } else {\n object[key] = value;\n }\n}\n\nvar simpleEscapeCheck = new Array(256); // integer, for fast access\nvar simpleEscapeMap = new Array(256);\nfor (var i = 0; i < 256; i++) {\n simpleEscapeCheck[i] = simpleEscapeSequence(i) ? 1 : 0;\n simpleEscapeMap[i] = simpleEscapeSequence(i);\n}\n\n\nfunction State$1(input, options) {\n this.input = input;\n\n this.filename = options['filename'] || null;\n this.schema = options['schema'] || _default;\n this.onWarning = options['onWarning'] || null;\n // (Hidden) Remove? makes the loader to expect YAML 1.1 documents\n // if such documents have no explicit %YAML directive\n this.legacy = options['legacy'] || false;\n\n this.json = options['json'] || false;\n this.listener = options['listener'] || null;\n\n this.implicitTypes = this.schema.compiledImplicit;\n this.typeMap = this.schema.compiledTypeMap;\n\n this.length = input.length;\n this.position = 0;\n this.line = 0;\n this.lineStart = 0;\n this.lineIndent = 0;\n\n // position of first leading tab in the current line,\n // used to make sure there are no tabs in the indentation\n this.firstTabInLine = -1;\n\n this.documents = [];\n\n /*\n this.version;\n this.checkLineBreaks;\n this.tagMap;\n this.anchorMap;\n this.tag;\n this.anchor;\n this.kind;\n this.result;*/\n\n}\n\n\nfunction generateError(state, message) {\n var mark = {\n name: state.filename,\n buffer: state.input.slice(0, -1), // omit trailing \\0\n position: state.position,\n line: state.line,\n column: state.position - state.lineStart\n };\n\n mark.snippet = snippet(mark);\n\n return new exception(message, mark);\n}\n\nfunction throwError(state, message) {\n throw generateError(state, message);\n}\n\nfunction throwWarning(state, message) {\n if (state.onWarning) {\n state.onWarning.call(null, generateError(state, message));\n }\n}\n\n\nvar directiveHandlers = {\n\n YAML: function handleYamlDirective(state, name, args) {\n\n var match, major, minor;\n\n if (state.version !== null) {\n throwError(state, 'duplication of %YAML directive');\n }\n\n if (args.length !== 1) {\n throwError(state, 'YAML directive accepts exactly one argument');\n }\n\n match = /^([0-9]+)\\.([0-9]+)$/.exec(args[0]);\n\n if (match === null) {\n throwError(state, 'ill-formed argument of the YAML directive');\n }\n\n major = parseInt(match[1], 10);\n minor = parseInt(match[2], 10);\n\n if (major !== 1) {\n throwError(state, 'unacceptable YAML version of the document');\n }\n\n state.version = args[0];\n state.checkLineBreaks = (minor < 2);\n\n if (minor !== 1 && minor !== 2) {\n throwWarning(state, 'unsupported YAML version of the document');\n }\n },\n\n TAG: function handleTagDirective(state, name, args) {\n\n var handle, prefix;\n\n if (args.length !== 2) {\n throwError(state, 'TAG directive accepts exactly two arguments');\n }\n\n handle = args[0];\n prefix = args[1];\n\n if (!PATTERN_TAG_HANDLE.test(handle)) {\n throwError(state, 'ill-formed tag handle (first argument) of the TAG directive');\n }\n\n if (_hasOwnProperty$1.call(state.tagMap, handle)) {\n throwError(state, 'there is a previously declared suffix for \"' + handle + '\" tag handle');\n }\n\n if (!PATTERN_TAG_URI.test(prefix)) {\n throwError(state, 'ill-formed tag prefix (second argument) of the TAG directive');\n }\n\n try {\n prefix = decodeURIComponent(prefix);\n } catch (err) {\n throwError(state, 'tag prefix is malformed: ' + prefix);\n }\n\n state.tagMap[handle] = prefix;\n }\n};\n\n\nfunction captureSegment(state, start, end, checkJson) {\n var _position, _length, _character, _result;\n\n if (start < end) {\n _result = state.input.slice(start, end);\n\n if (checkJson) {\n for (_position = 0, _length = _result.length; _position < _length; _position += 1) {\n _character = _result.charCodeAt(_position);\n if (!(_character === 0x09 ||\n (0x20 <= _character && _character <= 0x10FFFF))) {\n throwError(state, 'expected valid JSON character');\n }\n }\n } else if (PATTERN_NON_PRINTABLE.test(_result)) {\n throwError(state, 'the stream contains non-printable characters');\n }\n\n state.result += _result;\n }\n}\n\nfunction mergeMappings(state, destination, source, overridableKeys) {\n var sourceKeys, key, index, quantity;\n\n if (!common.isObject(source)) {\n throwError(state, 'cannot merge mappings; the provided source object is unacceptable');\n }\n\n sourceKeys = Object.keys(source);\n\n for (index = 0, quantity = sourceKeys.length; index < quantity; index += 1) {\n key = sourceKeys[index];\n\n if (!_hasOwnProperty$1.call(destination, key)) {\n setProperty(destination, key, source[key]);\n overridableKeys[key] = true;\n }\n }\n}\n\nfunction storeMappingPair(state, _result, overridableKeys, keyTag, keyNode, valueNode,\n startLine, startLineStart, startPos) {\n\n var index, quantity;\n\n // The output is a plain object here, so keys can only be strings.\n // We need to convert keyNode to a string, but doing so can hang the process\n // (deeply nested arrays that explode exponentially using aliases).\n if (Array.isArray(keyNode)) {\n keyNode = Array.prototype.slice.call(keyNode);\n\n for (index = 0, quantity = keyNode.length; index < quantity; index += 1) {\n if (Array.isArray(keyNode[index])) {\n throwError(state, 'nested arrays are not supported inside keys');\n }\n\n if (typeof keyNode === 'object' && _class(keyNode[index]) === '[object Object]') {\n keyNode[index] = '[object Object]';\n }\n }\n }\n\n // Avoid code execution in load() via toString property\n // (still use its own toString for arrays, timestamps,\n // and whatever user schema extensions happen to have @@toStringTag)\n if (typeof keyNode === 'object' && _class(keyNode) === '[object Object]') {\n keyNode = '[object Object]';\n }\n\n\n keyNode = String(keyNode);\n\n if (_result === null) {\n _result = {};\n }\n\n if (keyTag === 'tag:yaml.org,2002:merge') {\n if (Array.isArray(valueNode)) {\n for (index = 0, quantity = valueNode.length; index < quantity; index += 1) {\n mergeMappings(state, _result, valueNode[index], overridableKeys);\n }\n } else {\n mergeMappings(state, _result, valueNode, overridableKeys);\n }\n } else {\n if (!state.json &&\n !_hasOwnProperty$1.call(overridableKeys, keyNode) &&\n _hasOwnProperty$1.call(_result, keyNode)) {\n state.line = startLine || state.line;\n state.lineStart = startLineStart || state.lineStart;\n state.position = startPos || state.position;\n throwError(state, 'duplicated mapping key');\n }\n\n setProperty(_result, keyNode, valueNode);\n delete overridableKeys[keyNode];\n }\n\n return _result;\n}\n\nfunction readLineBreak(state) {\n var ch;\n\n ch = state.input.charCodeAt(state.position);\n\n if (ch === 0x0A/* LF */) {\n state.position++;\n } else if (ch === 0x0D/* CR */) {\n state.position++;\n if (state.input.charCodeAt(state.position) === 0x0A/* LF */) {\n state.position++;\n }\n } else {\n throwError(state, 'a line break is expected');\n }\n\n state.line += 1;\n state.lineStart = state.position;\n state.firstTabInLine = -1;\n}\n\nfunction skipSeparationSpace(state, allowComments, checkIndent) {\n var lineBreaks = 0,\n ch = state.input.charCodeAt(state.position);\n\n while (ch !== 0) {\n while (is_WHITE_SPACE(ch)) {\n if (ch === 0x09/* Tab */ && state.firstTabInLine === -1) {\n state.firstTabInLine = state.position;\n }\n ch = state.input.charCodeAt(++state.position);\n }\n\n if (allowComments && ch === 0x23/* # */) {\n do {\n ch = state.input.charCodeAt(++state.position);\n } while (ch !== 0x0A/* LF */ && ch !== 0x0D/* CR */ && ch !== 0);\n }\n\n if (is_EOL(ch)) {\n readLineBreak(state);\n\n ch = state.input.charCodeAt(state.position);\n lineBreaks++;\n state.lineIndent = 0;\n\n while (ch === 0x20/* Space */) {\n state.lineIndent++;\n ch = state.input.charCodeAt(++state.position);\n }\n } else {\n break;\n }\n }\n\n if (checkIndent !== -1 && lineBreaks !== 0 && state.lineIndent < checkIndent) {\n throwWarning(state, 'deficient indentation');\n }\n\n return lineBreaks;\n}\n\nfunction testDocumentSeparator(state) {\n var _position = state.position,\n ch;\n\n ch = state.input.charCodeAt(_position);\n\n // Condition state.position === state.lineStart is tested\n // in parent on each call, for efficiency. No needs to test here again.\n if ((ch === 0x2D/* - */ || ch === 0x2E/* . */) &&\n ch === state.input.charCodeAt(_position + 1) &&\n ch === state.input.charCodeAt(_position + 2)) {\n\n _position += 3;\n\n ch = state.input.charCodeAt(_position);\n\n if (ch === 0 || is_WS_OR_EOL(ch)) {\n return true;\n }\n }\n\n return false;\n}\n\nfunction writeFoldedLines(state, count) {\n if (count === 1) {\n state.result += ' ';\n } else if (count > 1) {\n state.result += common.repeat('\\n', count - 1);\n }\n}\n\n\nfunction readPlainScalar(state, nodeIndent, withinFlowCollection) {\n var preceding,\n following,\n captureStart,\n captureEnd,\n hasPendingContent,\n _line,\n _lineStart,\n _lineIndent,\n _kind = state.kind,\n _result = state.result,\n ch;\n\n ch = state.input.charCodeAt(state.position);\n\n if (is_WS_OR_EOL(ch) ||\n is_FLOW_INDICATOR(ch) ||\n ch === 0x23/* # */ ||\n ch === 0x26/* & */ ||\n ch === 0x2A/* * */ ||\n ch === 0x21/* ! */ ||\n ch === 0x7C/* | */ ||\n ch === 0x3E/* > */ ||\n ch === 0x27/* ' */ ||\n ch === 0x22/* \" */ ||\n ch === 0x25/* % */ ||\n ch === 0x40/* @ */ ||\n ch === 0x60/* ` */) {\n return false;\n }\n\n if (ch === 0x3F/* ? */ || ch === 0x2D/* - */) {\n following = state.input.charCodeAt(state.position + 1);\n\n if (is_WS_OR_EOL(following) ||\n withinFlowCollection && is_FLOW_INDICATOR(following)) {\n return false;\n }\n }\n\n state.kind = 'scalar';\n state.result = '';\n captureStart = captureEnd = state.position;\n hasPendingContent = false;\n\n while (ch !== 0) {\n if (ch === 0x3A/* : */) {\n following = state.input.charCodeAt(state.position + 1);\n\n if (is_WS_OR_EOL(following) ||\n withinFlowCollection && is_FLOW_INDICATOR(following)) {\n break;\n }\n\n } else if (ch === 0x23/* # */) {\n preceding = state.input.charCodeAt(state.position - 1);\n\n if (is_WS_OR_EOL(preceding)) {\n break;\n }\n\n } else if ((state.position === state.lineStart && testDocumentSeparator(state)) ||\n withinFlowCollection && is_FLOW_INDICATOR(ch)) {\n break;\n\n } else if (is_EOL(ch)) {\n _line = state.line;\n _lineStart = state.lineStart;\n _lineIndent = state.lineIndent;\n skipSeparationSpace(state, false, -1);\n\n if (state.lineIndent >= nodeIndent) {\n hasPendingContent = true;\n ch = state.input.charCodeAt(state.position);\n continue;\n } else {\n state.position = captureEnd;\n state.line = _line;\n state.lineStart = _lineStart;\n state.lineIndent = _lineIndent;\n break;\n }\n }\n\n if (hasPendingContent) {\n captureSegment(state, captureStart, captureEnd, false);\n writeFoldedLines(state, state.line - _line);\n captureStart = captureEnd = state.position;\n hasPendingContent = false;\n }\n\n if (!is_WHITE_SPACE(ch)) {\n captureEnd = state.position + 1;\n }\n\n ch = state.input.charCodeAt(++state.position);\n }\n\n captureSegment(state, captureStart, captureEnd, false);\n\n if (state.result) {\n return true;\n }\n\n state.kind = _kind;\n state.result = _result;\n return false;\n}\n\nfunction readSingleQuotedScalar(state, nodeIndent) {\n var ch,\n captureStart, captureEnd;\n\n ch = state.input.charCodeAt(state.position);\n\n if (ch !== 0x27/* ' */) {\n return false;\n }\n\n state.kind = 'scalar';\n state.result = '';\n state.position++;\n captureStart = captureEnd = state.position;\n\n while ((ch = state.input.charCodeAt(state.position)) !== 0) {\n if (ch === 0x27/* ' */) {\n captureSegment(state, captureStart, state.position, true);\n ch = state.input.charCodeAt(++state.position);\n\n if (ch === 0x27/* ' */) {\n captureStart = state.position;\n state.position++;\n captureEnd = state.position;\n } else {\n return true;\n }\n\n } else if (is_EOL(ch)) {\n captureSegment(state, captureStart, captureEnd, true);\n writeFoldedLines(state, skipSeparationSpace(state, false, nodeIndent));\n captureStart = captureEnd = state.position;\n\n } else if (state.position === state.lineStart && testDocumentSeparator(state)) {\n throwError(state, 'unexpected end of the document within a single quoted scalar');\n\n } else {\n state.position++;\n captureEnd = state.position;\n }\n }\n\n throwError(state, 'unexpected end of the stream within a single quoted scalar');\n}\n\nfunction readDoubleQuotedScalar(state, nodeIndent) {\n var captureStart,\n captureEnd,\n hexLength,\n hexResult,\n tmp,\n ch;\n\n ch = state.input.charCodeAt(state.position);\n\n if (ch !== 0x22/* \" */) {\n return false;\n }\n\n state.kind = 'scalar';\n state.result = '';\n state.position++;\n captureStart = captureEnd = state.position;\n\n while ((ch = state.input.charCodeAt(state.position)) !== 0) {\n if (ch === 0x22/* \" */) {\n captureSegment(state, captureStart, state.position, true);\n state.position++;\n return true;\n\n } else if (ch === 0x5C/* \\ */) {\n captureSegment(state, captureStart, state.position, true);\n ch = state.input.charCodeAt(++state.position);\n\n if (is_EOL(ch)) {\n skipSeparationSpace(state, false, nodeIndent);\n\n // TODO: rework to inline fn with no type cast?\n } else if (ch < 256 && simpleEscapeCheck[ch]) {\n state.result += simpleEscapeMap[ch];\n state.position++;\n\n } else if ((tmp = escapedHexLen(ch)) > 0) {\n hexLength = tmp;\n hexResult = 0;\n\n for (; hexLength > 0; hexLength--) {\n ch = state.input.charCodeAt(++state.position);\n\n if ((tmp = fromHexCode(ch)) >= 0) {\n hexResult = (hexResult << 4) + tmp;\n\n } else {\n throwError(state, 'expected hexadecimal character');\n }\n }\n\n state.result += charFromCodepoint(hexResult);\n\n state.position++;\n\n } else {\n throwError(state, 'unknown escape sequence');\n }\n\n captureStart = captureEnd = state.position;\n\n } else if (is_EOL(ch)) {\n captureSegment(state, captureStart, captureEnd, true);\n writeFoldedLines(state, skipSeparationSpace(state, false, nodeIndent));\n captureStart = captureEnd = state.position;\n\n } else if (state.position === state.lineStart && testDocumentSeparator(state)) {\n throwError(state, 'unexpected end of the document within a double quoted scalar');\n\n } else {\n state.position++;\n captureEnd = state.position;\n }\n }\n\n throwError(state, 'unexpected end of the stream within a double quoted scalar');\n}\n\nfunction readFlowCollection(state, nodeIndent) {\n var readNext = true,\n _line,\n _lineStart,\n _pos,\n _tag = state.tag,\n _result,\n _anchor = state.anchor,\n following,\n terminator,\n isPair,\n isExplicitPair,\n isMapping,\n overridableKeys = Object.create(null),\n keyNode,\n keyTag,\n valueNode,\n ch;\n\n ch = state.input.charCodeAt(state.position);\n\n if (ch === 0x5B/* [ */) {\n terminator = 0x5D;/* ] */\n isMapping = false;\n _result = [];\n } else if (ch === 0x7B/* { */) {\n terminator = 0x7D;/* } */\n isMapping = true;\n _result = {};\n } else {\n return false;\n }\n\n if (state.anchor !== null) {\n state.anchorMap[state.anchor] = _result;\n }\n\n ch = state.input.charCodeAt(++state.position);\n\n while (ch !== 0) {\n skipSeparationSpace(state, true, nodeIndent);\n\n ch = state.input.charCodeAt(state.position);\n\n if (ch === terminator) {\n state.position++;\n state.tag = _tag;\n state.anchor = _anchor;\n state.kind = isMapping ? 'mapping' : 'sequence';\n state.result = _result;\n return true;\n } else if (!readNext) {\n throwError(state, 'missed comma between flow collection entries');\n } else if (ch === 0x2C/* , */) {\n // \"flow collection entries can never be completely empty\", as per YAML 1.2, section 7.4\n throwError(state, \"expected the node content, but found ','\");\n }\n\n keyTag = keyNode = valueNode = null;\n isPair = isExplicitPair = false;\n\n if (ch === 0x3F/* ? */) {\n following = state.input.charCodeAt(state.position + 1);\n\n if (is_WS_OR_EOL(following)) {\n isPair = isExplicitPair = true;\n state.position++;\n skipSeparationSpace(state, true, nodeIndent);\n }\n }\n\n _line = state.line; // Save the current line.\n _lineStart = state.lineStart;\n _pos = state.position;\n composeNode(state, nodeIndent, CONTEXT_FLOW_IN, false, true);\n keyTag = state.tag;\n keyNode = state.result;\n skipSeparationSpace(state, true, nodeIndent);\n\n ch = state.input.charCodeAt(state.position);\n\n if ((isExplicitPair || state.line === _line) && ch === 0x3A/* : */) {\n isPair = true;\n ch = state.input.charCodeAt(++state.position);\n skipSeparationSpace(state, true, nodeIndent);\n composeNode(state, nodeIndent, CONTEXT_FLOW_IN, false, true);\n valueNode = state.result;\n }\n\n if (isMapping) {\n storeMappingPair(state, _result, overridableKeys, keyTag, keyNode, valueNode, _line, _lineStart, _pos);\n } else if (isPair) {\n _result.push(storeMappingPair(state, null, overridableKeys, keyTag, keyNode, valueNode, _line, _lineStart, _pos));\n } else {\n _result.push(keyNode);\n }\n\n skipSeparationSpace(state, true, nodeIndent);\n\n ch = state.input.charCodeAt(state.position);\n\n if (ch === 0x2C/* , */) {\n readNext = true;\n ch = state.input.charCodeAt(++state.position);\n } else {\n readNext = false;\n }\n }\n\n throwError(state, 'unexpected end of the stream within a flow collection');\n}\n\nfunction readBlockScalar(state, nodeIndent) {\n var captureStart,\n folding,\n chomping = CHOMPING_CLIP,\n didReadContent = false,\n detectedIndent = false,\n textIndent = nodeIndent,\n emptyLines = 0,\n atMoreIndented = false,\n tmp,\n ch;\n\n ch = state.input.charCodeAt(state.position);\n\n if (ch === 0x7C/* | */) {\n folding = false;\n } else if (ch === 0x3E/* > */) {\n folding = true;\n } else {\n return false;\n }\n\n state.kind = 'scalar';\n state.result = '';\n\n while (ch !== 0) {\n ch = state.input.charCodeAt(++state.position);\n\n if (ch === 0x2B/* + */ || ch === 0x2D/* - */) {\n if (CHOMPING_CLIP === chomping) {\n chomping = (ch === 0x2B/* + */) ? CHOMPING_KEEP : CHOMPING_STRIP;\n } else {\n throwError(state, 'repeat of a chomping mode identifier');\n }\n\n } else if ((tmp = fromDecimalCode(ch)) >= 0) {\n if (tmp === 0) {\n throwError(state, 'bad explicit indentation width of a block scalar; it cannot be less than one');\n } else if (!detectedIndent) {\n textIndent = nodeIndent + tmp - 1;\n detectedIndent = true;\n } else {\n throwError(state, 'repeat of an indentation width identifier');\n }\n\n } else {\n break;\n }\n }\n\n if (is_WHITE_SPACE(ch)) {\n do { ch = state.input.charCodeAt(++state.position); }\n while (is_WHITE_SPACE(ch));\n\n if (ch === 0x23/* # */) {\n do { ch = state.input.charCodeAt(++state.position); }\n while (!is_EOL(ch) && (ch !== 0));\n }\n }\n\n while (ch !== 0) {\n readLineBreak(state);\n state.lineIndent = 0;\n\n ch = state.input.charCodeAt(state.position);\n\n while ((!detectedIndent || state.lineIndent < textIndent) &&\n (ch === 0x20/* Space */)) {\n state.lineIndent++;\n ch = state.input.charCodeAt(++state.position);\n }\n\n if (!detectedIndent && state.lineIndent > textIndent) {\n textIndent = state.lineIndent;\n }\n\n if (is_EOL(ch)) {\n emptyLines++;\n continue;\n }\n\n // End of the scalar.\n if (state.lineIndent < textIndent) {\n\n // Perform the chomping.\n if (chomping === CHOMPING_KEEP) {\n state.result += common.repeat('\\n', didReadContent ? 1 + emptyLines : emptyLines);\n } else if (chomping === CHOMPING_CLIP) {\n if (didReadContent) { // i.e. only if the scalar is not empty.\n state.result += '\\n';\n }\n }\n\n // Break this `while` cycle and go to the funciton's epilogue.\n break;\n }\n\n // Folded style: use fancy rules to handle line breaks.\n if (folding) {\n\n // Lines starting with white space characters (more-indented lines) are not folded.\n if (is_WHITE_SPACE(ch)) {\n atMoreIndented = true;\n // except for the first content line (cf. Example 8.1)\n state.result += common.repeat('\\n', didReadContent ? 1 + emptyLines : emptyLines);\n\n // End of more-indented block.\n } else if (atMoreIndented) {\n atMoreIndented = false;\n state.result += common.repeat('\\n', emptyLines + 1);\n\n // Just one line break - perceive as the same line.\n } else if (emptyLines === 0) {\n if (didReadContent) { // i.e. only if we have already read some scalar content.\n state.result += ' ';\n }\n\n // Several line breaks - perceive as different lines.\n } else {\n state.result += common.repeat('\\n', emptyLines);\n }\n\n // Literal style: just add exact number of line breaks between content lines.\n } else {\n // Keep all line breaks except the header line break.\n state.result += common.repeat('\\n', didReadContent ? 1 + emptyLines : emptyLines);\n }\n\n didReadContent = true;\n detectedIndent = true;\n emptyLines = 0;\n captureStart = state.position;\n\n while (!is_EOL(ch) && (ch !== 0)) {\n ch = state.input.charCodeAt(++state.position);\n }\n\n captureSegment(state, captureStart, state.position, false);\n }\n\n return true;\n}\n\nfunction readBlockSequence(state, nodeIndent) {\n var _line,\n _tag = state.tag,\n _anchor = state.anchor,\n _result = [],\n following,\n detected = false,\n ch;\n\n // there is a leading tab before this token, so it can't be a block sequence/mapping;\n // it can still be flow sequence/mapping or a scalar\n if (state.firstTabInLine !== -1) return false;\n\n if (state.anchor !== null) {\n state.anchorMap[state.anchor] = _result;\n }\n\n ch = state.input.charCodeAt(state.position);\n\n while (ch !== 0) {\n if (state.firstTabInLine !== -1) {\n state.position = state.firstTabInLine;\n throwError(state, 'tab characters must not be used in indentation');\n }\n\n if (ch !== 0x2D/* - */) {\n break;\n }\n\n following = state.input.charCodeAt(state.position + 1);\n\n if (!is_WS_OR_EOL(following)) {\n break;\n }\n\n detected = true;\n state.position++;\n\n if (skipSeparationSpace(state, true, -1)) {\n if (state.lineIndent <= nodeIndent) {\n _result.push(null);\n ch = state.input.charCodeAt(state.position);\n continue;\n }\n }\n\n _line = state.line;\n composeNode(state, nodeIndent, CONTEXT_BLOCK_IN, false, true);\n _result.push(state.result);\n skipSeparationSpace(state, true, -1);\n\n ch = state.input.charCodeAt(state.position);\n\n if ((state.line === _line || state.lineIndent > nodeIndent) && (ch !== 0)) {\n throwError(state, 'bad indentation of a sequence entry');\n } else if (state.lineIndent < nodeIndent) {\n break;\n }\n }\n\n if (detected) {\n state.tag = _tag;\n state.anchor = _anchor;\n state.kind = 'sequence';\n state.result = _result;\n return true;\n }\n return false;\n}\n\nfunction readBlockMapping(state, nodeIndent, flowIndent) {\n var following,\n allowCompact,\n _line,\n _keyLine,\n _keyLineStart,\n _keyPos,\n _tag = state.tag,\n _anchor = state.anchor,\n _result = {},\n overridableKeys = Object.create(null),\n keyTag = null,\n keyNode = null,\n valueNode = null,\n atExplicitKey = false,\n detected = false,\n ch;\n\n // there is a leading tab before this token, so it can't be a block sequence/mapping;\n // it can still be flow sequence/mapping or a scalar\n if (state.firstTabInLine !== -1) return false;\n\n if (state.anchor !== null) {\n state.anchorMap[state.anchor] = _result;\n }\n\n ch = state.input.charCodeAt(state.position);\n\n while (ch !== 0) {\n if (!atExplicitKey && state.firstTabInLine !== -1) {\n state.position = state.firstTabInLine;\n throwError(state, 'tab characters must not be used in indentation');\n }\n\n following = state.input.charCodeAt(state.position + 1);\n _line = state.line; // Save the current line.\n\n //\n // Explicit notation case. There are two separate blocks:\n // first for the key (denoted by \"?\") and second for the value (denoted by \":\")\n //\n if ((ch === 0x3F/* ? */ || ch === 0x3A/* : */) && is_WS_OR_EOL(following)) {\n\n if (ch === 0x3F/* ? */) {\n if (atExplicitKey) {\n storeMappingPair(state, _result, overridableKeys, keyTag, keyNode, null, _keyLine, _keyLineStart, _keyPos);\n keyTag = keyNode = valueNode = null;\n }\n\n detected = true;\n atExplicitKey = true;\n allowCompact = true;\n\n } else if (atExplicitKey) {\n // i.e. 0x3A/* : */ === character after the explicit key.\n atExplicitKey = false;\n allowCompact = true;\n\n } else {\n throwError(state, 'incomplete explicit mapping pair; a key node is missed; or followed by a non-tabulated empty line');\n }\n\n state.position += 1;\n ch = following;\n\n //\n // Implicit notation case. Flow-style node as the key first, then \":\", and the value.\n //\n } else {\n _keyLine = state.line;\n _keyLineStart = state.lineStart;\n _keyPos = state.position;\n\n if (!composeNode(state, flowIndent, CONTEXT_FLOW_OUT, false, true)) {\n // Neither implicit nor explicit notation.\n // Reading is done. Go to the epilogue.\n break;\n }\n\n if (state.line === _line) {\n ch = state.input.charCodeAt(state.position);\n\n while (is_WHITE_SPACE(ch)) {\n ch = state.input.charCodeAt(++state.position);\n }\n\n if (ch === 0x3A/* : */) {\n ch = state.input.charCodeAt(++state.position);\n\n if (!is_WS_OR_EOL(ch)) {\n throwError(state, 'a whitespace character is expected after the key-value separator within a block mapping');\n }\n\n if (atExplicitKey) {\n storeMappingPair(state, _result, overridableKeys, keyTag, keyNode, null, _keyLine, _keyLineStart, _keyPos);\n keyTag = keyNode = valueNode = null;\n }\n\n detected = true;\n atExplicitKey = false;\n allowCompact = false;\n keyTag = state.tag;\n keyNode = state.result;\n\n } else if (detected) {\n throwError(state, 'can not read an implicit mapping pair; a colon is missed');\n\n } else {\n state.tag = _tag;\n state.anchor = _anchor;\n return true; // Keep the result of `composeNode`.\n }\n\n } else if (detected) {\n throwError(state, 'can not read a block mapping entry; a multiline key may not be an implicit key');\n\n } else {\n state.tag = _tag;\n state.anchor = _anchor;\n return true; // Keep the result of `composeNode`.\n }\n }\n\n //\n // Common reading code for both explicit and implicit notations.\n //\n if (state.line === _line || state.lineIndent > nodeIndent) {\n if (atExplicitKey) {\n _keyLine = state.line;\n _keyLineStart = state.lineStart;\n _keyPos = state.position;\n }\n\n if (composeNode(state, nodeIndent, CONTEXT_BLOCK_OUT, true, allowCompact)) {\n if (atExplicitKey) {\n keyNode = state.result;\n } else {\n valueNode = state.result;\n }\n }\n\n if (!atExplicitKey) {\n storeMappingPair(state, _result, overridableKeys, keyTag, keyNode, valueNode, _keyLine, _keyLineStart, _keyPos);\n keyTag = keyNode = valueNode = null;\n }\n\n skipSeparationSpace(state, true, -1);\n ch = state.input.charCodeAt(state.position);\n }\n\n if ((state.line === _line || state.lineIndent > nodeIndent) && (ch !== 0)) {\n throwError(state, 'bad indentation of a mapping entry');\n } else if (state.lineIndent < nodeIndent) {\n break;\n }\n }\n\n //\n // Epilogue.\n //\n\n // Special case: last mapping's node contains only the key in explicit notation.\n if (atExplicitKey) {\n storeMappingPair(state, _result, overridableKeys, keyTag, keyNode, null, _keyLine, _keyLineStart, _keyPos);\n }\n\n // Expose the resulting mapping.\n if (detected) {\n state.tag = _tag;\n state.anchor = _anchor;\n state.kind = 'mapping';\n state.result = _result;\n }\n\n return detected;\n}\n\nfunction readTagProperty(state) {\n var _position,\n isVerbatim = false,\n isNamed = false,\n tagHandle,\n tagName,\n ch;\n\n ch = state.input.charCodeAt(state.position);\n\n if (ch !== 0x21/* ! */) return false;\n\n if (state.tag !== null) {\n throwError(state, 'duplication of a tag property');\n }\n\n ch = state.input.charCodeAt(++state.position);\n\n if (ch === 0x3C/* < */) {\n isVerbatim = true;\n ch = state.input.charCodeAt(++state.position);\n\n } else if (ch === 0x21/* ! */) {\n isNamed = true;\n tagHandle = '!!';\n ch = state.input.charCodeAt(++state.position);\n\n } else {\n tagHandle = '!';\n }\n\n _position = state.position;\n\n if (isVerbatim) {\n do { ch = state.input.charCodeAt(++state.position); }\n while (ch !== 0 && ch !== 0x3E/* > */);\n\n if (state.position < state.length) {\n tagName = state.input.slice(_position, state.position);\n ch = state.input.charCodeAt(++state.position);\n } else {\n throwError(state, 'unexpected end of the stream within a verbatim tag');\n }\n } else {\n while (ch !== 0 && !is_WS_OR_EOL(ch)) {\n\n if (ch === 0x21/* ! */) {\n if (!isNamed) {\n tagHandle = state.input.slice(_position - 1, state.position + 1);\n\n if (!PATTERN_TAG_HANDLE.test(tagHandle)) {\n throwError(state, 'named tag handle cannot contain such characters');\n }\n\n isNamed = true;\n _position = state.position + 1;\n } else {\n throwError(state, 'tag suffix cannot contain exclamation marks');\n }\n }\n\n ch = state.input.charCodeAt(++state.position);\n }\n\n tagName = state.input.slice(_position, state.position);\n\n if (PATTERN_FLOW_INDICATORS.test(tagName)) {\n throwError(state, 'tag suffix cannot contain flow indicator characters');\n }\n }\n\n if (tagName && !PATTERN_TAG_URI.test(tagName)) {\n throwError(state, 'tag name cannot contain such characters: ' + tagName);\n }\n\n try {\n tagName = decodeURIComponent(tagName);\n } catch (err) {\n throwError(state, 'tag name is malformed: ' + tagName);\n }\n\n if (isVerbatim) {\n state.tag = tagName;\n\n } else if (_hasOwnProperty$1.call(state.tagMap, tagHandle)) {\n state.tag = state.tagMap[tagHandle] + tagName;\n\n } else if (tagHandle === '!') {\n state.tag = '!' + tagName;\n\n } else if (tagHandle === '!!') {\n state.tag = 'tag:yaml.org,2002:' + tagName;\n\n } else {\n throwError(state, 'undeclared tag handle \"' + tagHandle + '\"');\n }\n\n return true;\n}\n\nfunction readAnchorProperty(state) {\n var _position,\n ch;\n\n ch = state.input.charCodeAt(state.position);\n\n if (ch !== 0x26/* & */) return false;\n\n if (state.anchor !== null) {\n throwError(state, 'duplication of an anchor property');\n }\n\n ch = state.input.charCodeAt(++state.position);\n _position = state.position;\n\n while (ch !== 0 && !is_WS_OR_EOL(ch) && !is_FLOW_INDICATOR(ch)) {\n ch = state.input.charCodeAt(++state.position);\n }\n\n if (state.position === _position) {\n throwError(state, 'name of an anchor node must contain at least one character');\n }\n\n state.anchor = state.input.slice(_position, state.position);\n return true;\n}\n\nfunction readAlias(state) {\n var _position, alias,\n ch;\n\n ch = state.input.charCodeAt(state.position);\n\n if (ch !== 0x2A/* * */) return false;\n\n ch = state.input.charCodeAt(++state.position);\n _position = state.position;\n\n while (ch !== 0 && !is_WS_OR_EOL(ch) && !is_FLOW_INDICATOR(ch)) {\n ch = state.input.charCodeAt(++state.position);\n }\n\n if (state.position === _position) {\n throwError(state, 'name of an alias node must contain at least one character');\n }\n\n alias = state.input.slice(_position, state.position);\n\n if (!_hasOwnProperty$1.call(state.anchorMap, alias)) {\n throwError(state, 'unidentified alias \"' + alias + '\"');\n }\n\n state.result = state.anchorMap[alias];\n skipSeparationSpace(state, true, -1);\n return true;\n}\n\nfunction composeNode(state, parentIndent, nodeContext, allowToSeek, allowCompact) {\n var allowBlockStyles,\n allowBlockScalars,\n allowBlockCollections,\n indentStatus = 1, // 1: this>parent, 0: this=parent, -1: this parentIndent) {\n indentStatus = 1;\n } else if (state.lineIndent === parentIndent) {\n indentStatus = 0;\n } else if (state.lineIndent < parentIndent) {\n indentStatus = -1;\n }\n }\n }\n\n if (indentStatus === 1) {\n while (readTagProperty(state) || readAnchorProperty(state)) {\n if (skipSeparationSpace(state, true, -1)) {\n atNewLine = true;\n allowBlockCollections = allowBlockStyles;\n\n if (state.lineIndent > parentIndent) {\n indentStatus = 1;\n } else if (state.lineIndent === parentIndent) {\n indentStatus = 0;\n } else if (state.lineIndent < parentIndent) {\n indentStatus = -1;\n }\n } else {\n allowBlockCollections = false;\n }\n }\n }\n\n if (allowBlockCollections) {\n allowBlockCollections = atNewLine || allowCompact;\n }\n\n if (indentStatus === 1 || CONTEXT_BLOCK_OUT === nodeContext) {\n if (CONTEXT_FLOW_IN === nodeContext || CONTEXT_FLOW_OUT === nodeContext) {\n flowIndent = parentIndent;\n } else {\n flowIndent = parentIndent + 1;\n }\n\n blockIndent = state.position - state.lineStart;\n\n if (indentStatus === 1) {\n if (allowBlockCollections &&\n (readBlockSequence(state, blockIndent) ||\n readBlockMapping(state, blockIndent, flowIndent)) ||\n readFlowCollection(state, flowIndent)) {\n hasContent = true;\n } else {\n if ((allowBlockScalars && readBlockScalar(state, flowIndent)) ||\n readSingleQuotedScalar(state, flowIndent) ||\n readDoubleQuotedScalar(state, flowIndent)) {\n hasContent = true;\n\n } else if (readAlias(state)) {\n hasContent = true;\n\n if (state.tag !== null || state.anchor !== null) {\n throwError(state, 'alias node should not have any properties');\n }\n\n } else if (readPlainScalar(state, flowIndent, CONTEXT_FLOW_IN === nodeContext)) {\n hasContent = true;\n\n if (state.tag === null) {\n state.tag = '?';\n }\n }\n\n if (state.anchor !== null) {\n state.anchorMap[state.anchor] = state.result;\n }\n }\n } else if (indentStatus === 0) {\n // Special case: block sequences are allowed to have same indentation level as the parent.\n // http://www.yaml.org/spec/1.2/spec.html#id2799784\n hasContent = allowBlockCollections && readBlockSequence(state, blockIndent);\n }\n }\n\n if (state.tag === null) {\n if (state.anchor !== null) {\n state.anchorMap[state.anchor] = state.result;\n }\n\n } else if (state.tag === '?') {\n // Implicit resolving is not allowed for non-scalar types, and '?'\n // non-specific tag is only automatically assigned to plain scalars.\n //\n // We only need to check kind conformity in case user explicitly assigns '?'\n // tag, for example like this: \"! [0]\"\n //\n if (state.result !== null && state.kind !== 'scalar') {\n throwError(state, 'unacceptable node kind for ! tag; it should be \"scalar\", not \"' + state.kind + '\"');\n }\n\n for (typeIndex = 0, typeQuantity = state.implicitTypes.length; typeIndex < typeQuantity; typeIndex += 1) {\n type = state.implicitTypes[typeIndex];\n\n if (type.resolve(state.result)) { // `state.result` updated in resolver if matched\n state.result = type.construct(state.result);\n state.tag = type.tag;\n if (state.anchor !== null) {\n state.anchorMap[state.anchor] = state.result;\n }\n break;\n }\n }\n } else if (state.tag !== '!') {\n if (_hasOwnProperty$1.call(state.typeMap[state.kind || 'fallback'], state.tag)) {\n type = state.typeMap[state.kind || 'fallback'][state.tag];\n } else {\n // looking for multi type\n type = null;\n typeList = state.typeMap.multi[state.kind || 'fallback'];\n\n for (typeIndex = 0, typeQuantity = typeList.length; typeIndex < typeQuantity; typeIndex += 1) {\n if (state.tag.slice(0, typeList[typeIndex].tag.length) === typeList[typeIndex].tag) {\n type = typeList[typeIndex];\n break;\n }\n }\n }\n\n if (!type) {\n throwError(state, 'unknown tag !<' + state.tag + '>');\n }\n\n if (state.result !== null && type.kind !== state.kind) {\n throwError(state, 'unacceptable node kind for !<' + state.tag + '> tag; it should be \"' + type.kind + '\", not \"' + state.kind + '\"');\n }\n\n if (!type.resolve(state.result, state.tag)) { // `state.result` updated in resolver if matched\n throwError(state, 'cannot resolve a node with !<' + state.tag + '> explicit tag');\n } else {\n state.result = type.construct(state.result, state.tag);\n if (state.anchor !== null) {\n state.anchorMap[state.anchor] = state.result;\n }\n }\n }\n\n if (state.listener !== null) {\n state.listener('close', state);\n }\n return state.tag !== null || state.anchor !== null || hasContent;\n}\n\nfunction readDocument(state) {\n var documentStart = state.position,\n _position,\n directiveName,\n directiveArgs,\n hasDirectives = false,\n ch;\n\n state.version = null;\n state.checkLineBreaks = state.legacy;\n state.tagMap = Object.create(null);\n state.anchorMap = Object.create(null);\n\n while ((ch = state.input.charCodeAt(state.position)) !== 0) {\n skipSeparationSpace(state, true, -1);\n\n ch = state.input.charCodeAt(state.position);\n\n if (state.lineIndent > 0 || ch !== 0x25/* % */) {\n break;\n }\n\n hasDirectives = true;\n ch = state.input.charCodeAt(++state.position);\n _position = state.position;\n\n while (ch !== 0 && !is_WS_OR_EOL(ch)) {\n ch = state.input.charCodeAt(++state.position);\n }\n\n directiveName = state.input.slice(_position, state.position);\n directiveArgs = [];\n\n if (directiveName.length < 1) {\n throwError(state, 'directive name must not be less than one character in length');\n }\n\n while (ch !== 0) {\n while (is_WHITE_SPACE(ch)) {\n ch = state.input.charCodeAt(++state.position);\n }\n\n if (ch === 0x23/* # */) {\n do { ch = state.input.charCodeAt(++state.position); }\n while (ch !== 0 && !is_EOL(ch));\n break;\n }\n\n if (is_EOL(ch)) break;\n\n _position = state.position;\n\n while (ch !== 0 && !is_WS_OR_EOL(ch)) {\n ch = state.input.charCodeAt(++state.position);\n }\n\n directiveArgs.push(state.input.slice(_position, state.position));\n }\n\n if (ch !== 0) readLineBreak(state);\n\n if (_hasOwnProperty$1.call(directiveHandlers, directiveName)) {\n directiveHandlers[directiveName](state, directiveName, directiveArgs);\n } else {\n throwWarning(state, 'unknown document directive \"' + directiveName + '\"');\n }\n }\n\n skipSeparationSpace(state, true, -1);\n\n if (state.lineIndent === 0 &&\n state.input.charCodeAt(state.position) === 0x2D/* - */ &&\n state.input.charCodeAt(state.position + 1) === 0x2D/* - */ &&\n state.input.charCodeAt(state.position + 2) === 0x2D/* - */) {\n state.position += 3;\n skipSeparationSpace(state, true, -1);\n\n } else if (hasDirectives) {\n throwError(state, 'directives end mark is expected');\n }\n\n composeNode(state, state.lineIndent - 1, CONTEXT_BLOCK_OUT, false, true);\n skipSeparationSpace(state, true, -1);\n\n if (state.checkLineBreaks &&\n PATTERN_NON_ASCII_LINE_BREAKS.test(state.input.slice(documentStart, state.position))) {\n throwWarning(state, 'non-ASCII line breaks are interpreted as content');\n }\n\n state.documents.push(state.result);\n\n if (state.position === state.lineStart && testDocumentSeparator(state)) {\n\n if (state.input.charCodeAt(state.position) === 0x2E/* . */) {\n state.position += 3;\n skipSeparationSpace(state, true, -1);\n }\n return;\n }\n\n if (state.position < (state.length - 1)) {\n throwError(state, 'end of the stream or a document separator is expected');\n } else {\n return;\n }\n}\n\n\nfunction loadDocuments(input, options) {\n input = String(input);\n options = options || {};\n\n if (input.length !== 0) {\n\n // Add tailing `\\n` if not exists\n if (input.charCodeAt(input.length - 1) !== 0x0A/* LF */ &&\n input.charCodeAt(input.length - 1) !== 0x0D/* CR */) {\n input += '\\n';\n }\n\n // Strip BOM\n if (input.charCodeAt(0) === 0xFEFF) {\n input = input.slice(1);\n }\n }\n\n var state = new State$1(input, options);\n\n var nullpos = input.indexOf('\\0');\n\n if (nullpos !== -1) {\n state.position = nullpos;\n throwError(state, 'null byte is not allowed in input');\n }\n\n // Use 0 as string terminator. That significantly simplifies bounds check.\n state.input += '\\0';\n\n while (state.input.charCodeAt(state.position) === 0x20/* Space */) {\n state.lineIndent += 1;\n state.position += 1;\n }\n\n while (state.position < (state.length - 1)) {\n readDocument(state);\n }\n\n return state.documents;\n}\n\n\nfunction loadAll$1(input, iterator, options) {\n if (iterator !== null && typeof iterator === 'object' && typeof options === 'undefined') {\n options = iterator;\n iterator = null;\n }\n\n var documents = loadDocuments(input, options);\n\n if (typeof iterator !== 'function') {\n return documents;\n }\n\n for (var index = 0, length = documents.length; index < length; index += 1) {\n iterator(documents[index]);\n }\n}\n\n\nfunction load$1(input, options) {\n var documents = loadDocuments(input, options);\n\n if (documents.length === 0) {\n /*eslint-disable no-undefined*/\n return undefined;\n } else if (documents.length === 1) {\n return documents[0];\n }\n throw new exception('expected a single document in the stream, but found more');\n}\n\n\nvar loadAll_1 = loadAll$1;\nvar load_1 = load$1;\n\nvar loader = {\n\tloadAll: loadAll_1,\n\tload: load_1\n};\n\n/*eslint-disable no-use-before-define*/\n\n\n\n\n\nvar _toString = Object.prototype.toString;\nvar _hasOwnProperty = Object.prototype.hasOwnProperty;\n\nvar CHAR_BOM = 0xFEFF;\nvar CHAR_TAB = 0x09; /* Tab */\nvar CHAR_LINE_FEED = 0x0A; /* LF */\nvar CHAR_CARRIAGE_RETURN = 0x0D; /* CR */\nvar CHAR_SPACE = 0x20; /* Space */\nvar CHAR_EXCLAMATION = 0x21; /* ! */\nvar CHAR_DOUBLE_QUOTE = 0x22; /* \" */\nvar CHAR_SHARP = 0x23; /* # */\nvar CHAR_PERCENT = 0x25; /* % */\nvar CHAR_AMPERSAND = 0x26; /* & */\nvar CHAR_SINGLE_QUOTE = 0x27; /* ' */\nvar CHAR_ASTERISK = 0x2A; /* * */\nvar CHAR_COMMA = 0x2C; /* , */\nvar CHAR_MINUS = 0x2D; /* - */\nvar CHAR_COLON = 0x3A; /* : */\nvar CHAR_EQUALS = 0x3D; /* = */\nvar CHAR_GREATER_THAN = 0x3E; /* > */\nvar CHAR_QUESTION = 0x3F; /* ? */\nvar CHAR_COMMERCIAL_AT = 0x40; /* @ */\nvar CHAR_LEFT_SQUARE_BRACKET = 0x5B; /* [ */\nvar CHAR_RIGHT_SQUARE_BRACKET = 0x5D; /* ] */\nvar CHAR_GRAVE_ACCENT = 0x60; /* ` */\nvar CHAR_LEFT_CURLY_BRACKET = 0x7B; /* { */\nvar CHAR_VERTICAL_LINE = 0x7C; /* | */\nvar CHAR_RIGHT_CURLY_BRACKET = 0x7D; /* } */\n\nvar ESCAPE_SEQUENCES = {};\n\nESCAPE_SEQUENCES[0x00] = '\\\\0';\nESCAPE_SEQUENCES[0x07] = '\\\\a';\nESCAPE_SEQUENCES[0x08] = '\\\\b';\nESCAPE_SEQUENCES[0x09] = '\\\\t';\nESCAPE_SEQUENCES[0x0A] = '\\\\n';\nESCAPE_SEQUENCES[0x0B] = '\\\\v';\nESCAPE_SEQUENCES[0x0C] = '\\\\f';\nESCAPE_SEQUENCES[0x0D] = '\\\\r';\nESCAPE_SEQUENCES[0x1B] = '\\\\e';\nESCAPE_SEQUENCES[0x22] = '\\\\\"';\nESCAPE_SEQUENCES[0x5C] = '\\\\\\\\';\nESCAPE_SEQUENCES[0x85] = '\\\\N';\nESCAPE_SEQUENCES[0xA0] = '\\\\_';\nESCAPE_SEQUENCES[0x2028] = '\\\\L';\nESCAPE_SEQUENCES[0x2029] = '\\\\P';\n\nvar DEPRECATED_BOOLEANS_SYNTAX = [\n 'y', 'Y', 'yes', 'Yes', 'YES', 'on', 'On', 'ON',\n 'n', 'N', 'no', 'No', 'NO', 'off', 'Off', 'OFF'\n];\n\nvar DEPRECATED_BASE60_SYNTAX = /^[-+]?[0-9_]+(?::[0-9_]+)+(?:\\.[0-9_]*)?$/;\n\nfunction compileStyleMap(schema, map) {\n var result, keys, index, length, tag, style, type;\n\n if (map === null) return {};\n\n result = {};\n keys = Object.keys(map);\n\n for (index = 0, length = keys.length; index < length; index += 1) {\n tag = keys[index];\n style = String(map[tag]);\n\n if (tag.slice(0, 2) === '!!') {\n tag = 'tag:yaml.org,2002:' + tag.slice(2);\n }\n type = schema.compiledTypeMap['fallback'][tag];\n\n if (type && _hasOwnProperty.call(type.styleAliases, style)) {\n style = type.styleAliases[style];\n }\n\n result[tag] = style;\n }\n\n return result;\n}\n\nfunction encodeHex(character) {\n var string, handle, length;\n\n string = character.toString(16).toUpperCase();\n\n if (character <= 0xFF) {\n handle = 'x';\n length = 2;\n } else if (character <= 0xFFFF) {\n handle = 'u';\n length = 4;\n } else if (character <= 0xFFFFFFFF) {\n handle = 'U';\n length = 8;\n } else {\n throw new exception('code point within a string may not be greater than 0xFFFFFFFF');\n }\n\n return '\\\\' + handle + common.repeat('0', length - string.length) + string;\n}\n\n\nvar QUOTING_TYPE_SINGLE = 1,\n QUOTING_TYPE_DOUBLE = 2;\n\nfunction State(options) {\n this.schema = options['schema'] || _default;\n this.indent = Math.max(1, (options['indent'] || 2));\n this.noArrayIndent = options['noArrayIndent'] || false;\n this.skipInvalid = options['skipInvalid'] || false;\n this.flowLevel = (common.isNothing(options['flowLevel']) ? -1 : options['flowLevel']);\n this.styleMap = compileStyleMap(this.schema, options['styles'] || null);\n this.sortKeys = options['sortKeys'] || false;\n this.lineWidth = options['lineWidth'] || 80;\n this.noRefs = options['noRefs'] || false;\n this.noCompatMode = options['noCompatMode'] || false;\n this.condenseFlow = options['condenseFlow'] || false;\n this.quotingType = options['quotingType'] === '\"' ? QUOTING_TYPE_DOUBLE : QUOTING_TYPE_SINGLE;\n this.forceQuotes = options['forceQuotes'] || false;\n this.replacer = typeof options['replacer'] === 'function' ? options['replacer'] : null;\n\n this.implicitTypes = this.schema.compiledImplicit;\n this.explicitTypes = this.schema.compiledExplicit;\n\n this.tag = null;\n this.result = '';\n\n this.duplicates = [];\n this.usedDuplicates = null;\n}\n\n// Indents every line in a string. Empty lines (\\n only) are not indented.\nfunction indentString(string, spaces) {\n var ind = common.repeat(' ', spaces),\n position = 0,\n next = -1,\n result = '',\n line,\n length = string.length;\n\n while (position < length) {\n next = string.indexOf('\\n', position);\n if (next === -1) {\n line = string.slice(position);\n position = length;\n } else {\n line = string.slice(position, next + 1);\n position = next + 1;\n }\n\n if (line.length && line !== '\\n') result += ind;\n\n result += line;\n }\n\n return result;\n}\n\nfunction generateNextLine(state, level) {\n return '\\n' + common.repeat(' ', state.indent * level);\n}\n\nfunction testImplicitResolving(state, str) {\n var index, length, type;\n\n for (index = 0, length = state.implicitTypes.length; index < length; index += 1) {\n type = state.implicitTypes[index];\n\n if (type.resolve(str)) {\n return true;\n }\n }\n\n return false;\n}\n\n// [33] s-white ::= s-space | s-tab\nfunction isWhitespace(c) {\n return c === CHAR_SPACE || c === CHAR_TAB;\n}\n\n// Returns true if the character can be printed without escaping.\n// From YAML 1.2: \"any allowed characters known to be non-printable\n// should also be escaped. [However,] This isn\u2019t mandatory\"\n// Derived from nb-char - \\t - #x85 - #xA0 - #x2028 - #x2029.\nfunction isPrintable(c) {\n return (0x00020 <= c && c <= 0x00007E)\n || ((0x000A1 <= c && c <= 0x00D7FF) && c !== 0x2028 && c !== 0x2029)\n || ((0x0E000 <= c && c <= 0x00FFFD) && c !== CHAR_BOM)\n || (0x10000 <= c && c <= 0x10FFFF);\n}\n\n// [34] ns-char ::= nb-char - s-white\n// [27] nb-char ::= c-printable - b-char - c-byte-order-mark\n// [26] b-char ::= b-line-feed | b-carriage-return\n// Including s-white (for some reason, examples doesn't match specs in this aspect)\n// ns-char ::= c-printable - b-line-feed - b-carriage-return - c-byte-order-mark\nfunction isNsCharOrWhitespace(c) {\n return isPrintable(c)\n && c !== CHAR_BOM\n // - b-char\n && c !== CHAR_CARRIAGE_RETURN\n && c !== CHAR_LINE_FEED;\n}\n\n// [127] ns-plain-safe(c) ::= c = flow-out \u21D2 ns-plain-safe-out\n// c = flow-in \u21D2 ns-plain-safe-in\n// c = block-key \u21D2 ns-plain-safe-out\n// c = flow-key \u21D2 ns-plain-safe-in\n// [128] ns-plain-safe-out ::= ns-char\n// [129] ns-plain-safe-in ::= ns-char - c-flow-indicator\n// [130] ns-plain-char(c) ::= ( ns-plain-safe(c) - \u201C:\u201D - \u201C#\u201D )\n// | ( /* An ns-char preceding */ \u201C#\u201D )\n// | ( \u201C:\u201D /* Followed by an ns-plain-safe(c) */ )\nfunction isPlainSafe(c, prev, inblock) {\n var cIsNsCharOrWhitespace = isNsCharOrWhitespace(c);\n var cIsNsChar = cIsNsCharOrWhitespace && !isWhitespace(c);\n return (\n // ns-plain-safe\n inblock ? // c = flow-in\n cIsNsCharOrWhitespace\n : cIsNsCharOrWhitespace\n // - c-flow-indicator\n && c !== CHAR_COMMA\n && c !== CHAR_LEFT_SQUARE_BRACKET\n && c !== CHAR_RIGHT_SQUARE_BRACKET\n && c !== CHAR_LEFT_CURLY_BRACKET\n && c !== CHAR_RIGHT_CURLY_BRACKET\n )\n // ns-plain-char\n && c !== CHAR_SHARP // false on '#'\n && !(prev === CHAR_COLON && !cIsNsChar) // false on ': '\n || (isNsCharOrWhitespace(prev) && !isWhitespace(prev) && c === CHAR_SHARP) // change to true on '[^ ]#'\n || (prev === CHAR_COLON && cIsNsChar); // change to true on ':[^ ]'\n}\n\n// Simplified test for values allowed as the first character in plain style.\nfunction isPlainSafeFirst(c) {\n // Uses a subset of ns-char - c-indicator\n // where ns-char = nb-char - s-white.\n // No support of ( ( \u201C?\u201D | \u201C:\u201D | \u201C-\u201D ) /* Followed by an ns-plain-safe(c)) */ ) part\n return isPrintable(c) && c !== CHAR_BOM\n && !isWhitespace(c) // - s-white\n // - (c-indicator ::=\n // \u201C-\u201D | \u201C?\u201D | \u201C:\u201D | \u201C,\u201D | \u201C[\u201D | \u201C]\u201D | \u201C{\u201D | \u201C}\u201D\n && c !== CHAR_MINUS\n && c !== CHAR_QUESTION\n && c !== CHAR_COLON\n && c !== CHAR_COMMA\n && c !== CHAR_LEFT_SQUARE_BRACKET\n && c !== CHAR_RIGHT_SQUARE_BRACKET\n && c !== CHAR_LEFT_CURLY_BRACKET\n && c !== CHAR_RIGHT_CURLY_BRACKET\n // | \u201C#\u201D | \u201C&\u201D | \u201C*\u201D | \u201C!\u201D | \u201C|\u201D | \u201C=\u201D | \u201C>\u201D | \u201C'\u201D | \u201C\"\u201D\n && c !== CHAR_SHARP\n && c !== CHAR_AMPERSAND\n && c !== CHAR_ASTERISK\n && c !== CHAR_EXCLAMATION\n && c !== CHAR_VERTICAL_LINE\n && c !== CHAR_EQUALS\n && c !== CHAR_GREATER_THAN\n && c !== CHAR_SINGLE_QUOTE\n && c !== CHAR_DOUBLE_QUOTE\n // | \u201C%\u201D | \u201C@\u201D | \u201C`\u201D)\n && c !== CHAR_PERCENT\n && c !== CHAR_COMMERCIAL_AT\n && c !== CHAR_GRAVE_ACCENT;\n}\n\n// Simplified test for values allowed as the last character in plain style.\nfunction isPlainSafeLast(c) {\n // just not whitespace or colon, it will be checked to be plain character later\n return !isWhitespace(c) && c !== CHAR_COLON;\n}\n\n// Same as 'string'.codePointAt(pos), but works in older browsers.\nfunction codePointAt(string, pos) {\n var first = string.charCodeAt(pos), second;\n if (first >= 0xD800 && first <= 0xDBFF && pos + 1 < string.length) {\n second = string.charCodeAt(pos + 1);\n if (second >= 0xDC00 && second <= 0xDFFF) {\n // https://mathiasbynens.be/notes/javascript-encoding#surrogate-formulae\n return (first - 0xD800) * 0x400 + second - 0xDC00 + 0x10000;\n }\n }\n return first;\n}\n\n// Determines whether block indentation indicator is required.\nfunction needIndentIndicator(string) {\n var leadingSpaceRe = /^\\n* /;\n return leadingSpaceRe.test(string);\n}\n\nvar STYLE_PLAIN = 1,\n STYLE_SINGLE = 2,\n STYLE_LITERAL = 3,\n STYLE_FOLDED = 4,\n STYLE_DOUBLE = 5;\n\n// Determines which scalar styles are possible and returns the preferred style.\n// lineWidth = -1 => no limit.\n// Pre-conditions: str.length > 0.\n// Post-conditions:\n// STYLE_PLAIN or STYLE_SINGLE => no \\n are in the string.\n// STYLE_LITERAL => no lines are suitable for folding (or lineWidth is -1).\n// STYLE_FOLDED => a line > lineWidth and can be folded (and lineWidth != -1).\nfunction chooseScalarStyle(string, singleLineOnly, indentPerLevel, lineWidth,\n testAmbiguousType, quotingType, forceQuotes, inblock) {\n\n var i;\n var char = 0;\n var prevChar = null;\n var hasLineBreak = false;\n var hasFoldableLine = false; // only checked if shouldTrackWidth\n var shouldTrackWidth = lineWidth !== -1;\n var previousLineBreak = -1; // count the first line correctly\n var plain = isPlainSafeFirst(codePointAt(string, 0))\n && isPlainSafeLast(codePointAt(string, string.length - 1));\n\n if (singleLineOnly || forceQuotes) {\n // Case: no block styles.\n // Check for disallowed characters to rule out plain and single.\n for (i = 0; i < string.length; char >= 0x10000 ? i += 2 : i++) {\n char = codePointAt(string, i);\n if (!isPrintable(char)) {\n return STYLE_DOUBLE;\n }\n plain = plain && isPlainSafe(char, prevChar, inblock);\n prevChar = char;\n }\n } else {\n // Case: block styles permitted.\n for (i = 0; i < string.length; char >= 0x10000 ? i += 2 : i++) {\n char = codePointAt(string, i);\n if (char === CHAR_LINE_FEED) {\n hasLineBreak = true;\n // Check if any line can be folded.\n if (shouldTrackWidth) {\n hasFoldableLine = hasFoldableLine ||\n // Foldable line = too long, and not more-indented.\n (i - previousLineBreak - 1 > lineWidth &&\n string[previousLineBreak + 1] !== ' ');\n previousLineBreak = i;\n }\n } else if (!isPrintable(char)) {\n return STYLE_DOUBLE;\n }\n plain = plain && isPlainSafe(char, prevChar, inblock);\n prevChar = char;\n }\n // in case the end is missing a \\n\n hasFoldableLine = hasFoldableLine || (shouldTrackWidth &&\n (i - previousLineBreak - 1 > lineWidth &&\n string[previousLineBreak + 1] !== ' '));\n }\n // Although every style can represent \\n without escaping, prefer block styles\n // for multiline, since they're more readable and they don't add empty lines.\n // Also prefer folding a super-long line.\n if (!hasLineBreak && !hasFoldableLine) {\n // Strings interpretable as another type have to be quoted;\n // e.g. the string 'true' vs. the boolean true.\n if (plain && !forceQuotes && !testAmbiguousType(string)) {\n return STYLE_PLAIN;\n }\n return quotingType === QUOTING_TYPE_DOUBLE ? STYLE_DOUBLE : STYLE_SINGLE;\n }\n // Edge case: block indentation indicator can only have one digit.\n if (indentPerLevel > 9 && needIndentIndicator(string)) {\n return STYLE_DOUBLE;\n }\n // At this point we know block styles are valid.\n // Prefer literal style unless we want to fold.\n if (!forceQuotes) {\n return hasFoldableLine ? STYLE_FOLDED : STYLE_LITERAL;\n }\n return quotingType === QUOTING_TYPE_DOUBLE ? STYLE_DOUBLE : STYLE_SINGLE;\n}\n\n// Note: line breaking/folding is implemented for only the folded style.\n// NB. We drop the last trailing newline (if any) of a returned block scalar\n// since the dumper adds its own newline. This always works:\n// \u2022 No ending newline => unaffected; already using strip \"-\" chomping.\n// \u2022 Ending newline => removed then restored.\n// Importantly, this keeps the \"+\" chomp indicator from gaining an extra line.\nfunction writeScalar(state, string, level, iskey, inblock) {\n state.dump = (function () {\n if (string.length === 0) {\n return state.quotingType === QUOTING_TYPE_DOUBLE ? '\"\"' : \"''\";\n }\n if (!state.noCompatMode) {\n if (DEPRECATED_BOOLEANS_SYNTAX.indexOf(string) !== -1 || DEPRECATED_BASE60_SYNTAX.test(string)) {\n return state.quotingType === QUOTING_TYPE_DOUBLE ? ('\"' + string + '\"') : (\"'\" + string + \"'\");\n }\n }\n\n var indent = state.indent * Math.max(1, level); // no 0-indent scalars\n // As indentation gets deeper, let the width decrease monotonically\n // to the lower bound min(state.lineWidth, 40).\n // Note that this implies\n // state.lineWidth \u2264 40 + state.indent: width is fixed at the lower bound.\n // state.lineWidth > 40 + state.indent: width decreases until the lower bound.\n // This behaves better than a constant minimum width which disallows narrower options,\n // or an indent threshold which causes the width to suddenly increase.\n var lineWidth = state.lineWidth === -1\n ? -1 : Math.max(Math.min(state.lineWidth, 40), state.lineWidth - indent);\n\n // Without knowing if keys are implicit/explicit, assume implicit for safety.\n var singleLineOnly = iskey\n // No block styles in flow mode.\n || (state.flowLevel > -1 && level >= state.flowLevel);\n function testAmbiguity(string) {\n return testImplicitResolving(state, string);\n }\n\n switch (chooseScalarStyle(string, singleLineOnly, state.indent, lineWidth,\n testAmbiguity, state.quotingType, state.forceQuotes && !iskey, inblock)) {\n\n case STYLE_PLAIN:\n return string;\n case STYLE_SINGLE:\n return \"'\" + string.replace(/'/g, \"''\") + \"'\";\n case STYLE_LITERAL:\n return '|' + blockHeader(string, state.indent)\n + dropEndingNewline(indentString(string, indent));\n case STYLE_FOLDED:\n return '>' + blockHeader(string, state.indent)\n + dropEndingNewline(indentString(foldString(string, lineWidth), indent));\n case STYLE_DOUBLE:\n return '\"' + escapeString(string) + '\"';\n default:\n throw new exception('impossible error: invalid scalar style');\n }\n }());\n}\n\n// Pre-conditions: string is valid for a block scalar, 1 <= indentPerLevel <= 9.\nfunction blockHeader(string, indentPerLevel) {\n var indentIndicator = needIndentIndicator(string) ? String(indentPerLevel) : '';\n\n // note the special case: the string '\\n' counts as a \"trailing\" empty line.\n var clip = string[string.length - 1] === '\\n';\n var keep = clip && (string[string.length - 2] === '\\n' || string === '\\n');\n var chomp = keep ? '+' : (clip ? '' : '-');\n\n return indentIndicator + chomp + '\\n';\n}\n\n// (See the note for writeScalar.)\nfunction dropEndingNewline(string) {\n return string[string.length - 1] === '\\n' ? string.slice(0, -1) : string;\n}\n\n// Note: a long line without a suitable break point will exceed the width limit.\n// Pre-conditions: every char in str isPrintable, str.length > 0, width > 0.\nfunction foldString(string, width) {\n // In folded style, $k$ consecutive newlines output as $k+1$ newlines\u2014\n // unless they're before or after a more-indented line, or at the very\n // beginning or end, in which case $k$ maps to $k$.\n // Therefore, parse each chunk as newline(s) followed by a content line.\n var lineRe = /(\\n+)([^\\n]*)/g;\n\n // first line (possibly an empty line)\n var result = (function () {\n var nextLF = string.indexOf('\\n');\n nextLF = nextLF !== -1 ? nextLF : string.length;\n lineRe.lastIndex = nextLF;\n return foldLine(string.slice(0, nextLF), width);\n }());\n // If we haven't reached the first content line yet, don't add an extra \\n.\n var prevMoreIndented = string[0] === '\\n' || string[0] === ' ';\n var moreIndented;\n\n // rest of the lines\n var match;\n while ((match = lineRe.exec(string))) {\n var prefix = match[1], line = match[2];\n moreIndented = (line[0] === ' ');\n result += prefix\n + (!prevMoreIndented && !moreIndented && line !== ''\n ? '\\n' : '')\n + foldLine(line, width);\n prevMoreIndented = moreIndented;\n }\n\n return result;\n}\n\n// Greedy line breaking.\n// Picks the longest line under the limit each time,\n// otherwise settles for the shortest line over the limit.\n// NB. More-indented lines *cannot* be folded, as that would add an extra \\n.\nfunction foldLine(line, width) {\n if (line === '' || line[0] === ' ') return line;\n\n // Since a more-indented line adds a \\n, breaks can't be followed by a space.\n var breakRe = / [^ ]/g; // note: the match index will always be <= length-2.\n var match;\n // start is an inclusive index. end, curr, and next are exclusive.\n var start = 0, end, curr = 0, next = 0;\n var result = '';\n\n // Invariants: 0 <= start <= length-1.\n // 0 <= curr <= next <= max(0, length-2). curr - start <= width.\n // Inside the loop:\n // A match implies length >= 2, so curr and next are <= length-2.\n while ((match = breakRe.exec(line))) {\n next = match.index;\n // maintain invariant: curr - start <= width\n if (next - start > width) {\n end = (curr > start) ? curr : next; // derive end <= length-2\n result += '\\n' + line.slice(start, end);\n // skip the space that was output as \\n\n start = end + 1; // derive start <= length-1\n }\n curr = next;\n }\n\n // By the invariants, start <= length-1, so there is something left over.\n // It is either the whole string or a part starting from non-whitespace.\n result += '\\n';\n // Insert a break if the remainder is too long and there is a break available.\n if (line.length - start > width && curr > start) {\n result += line.slice(start, curr) + '\\n' + line.slice(curr + 1);\n } else {\n result += line.slice(start);\n }\n\n return result.slice(1); // drop extra \\n joiner\n}\n\n// Escapes a double-quoted string.\nfunction escapeString(string) {\n var result = '';\n var char = 0;\n var escapeSeq;\n\n for (var i = 0; i < string.length; char >= 0x10000 ? i += 2 : i++) {\n char = codePointAt(string, i);\n escapeSeq = ESCAPE_SEQUENCES[char];\n\n if (!escapeSeq && isPrintable(char)) {\n result += string[i];\n if (char >= 0x10000) result += string[i + 1];\n } else {\n result += escapeSeq || encodeHex(char);\n }\n }\n\n return result;\n}\n\nfunction writeFlowSequence(state, level, object) {\n var _result = '',\n _tag = state.tag,\n index,\n length,\n value;\n\n for (index = 0, length = object.length; index < length; index += 1) {\n value = object[index];\n\n if (state.replacer) {\n value = state.replacer.call(object, String(index), value);\n }\n\n // Write only valid elements, put null instead of invalid elements.\n if (writeNode(state, level, value, false, false) ||\n (typeof value === 'undefined' &&\n writeNode(state, level, null, false, false))) {\n\n if (_result !== '') _result += ',' + (!state.condenseFlow ? ' ' : '');\n _result += state.dump;\n }\n }\n\n state.tag = _tag;\n state.dump = '[' + _result + ']';\n}\n\nfunction writeBlockSequence(state, level, object, compact) {\n var _result = '',\n _tag = state.tag,\n index,\n length,\n value;\n\n for (index = 0, length = object.length; index < length; index += 1) {\n value = object[index];\n\n if (state.replacer) {\n value = state.replacer.call(object, String(index), value);\n }\n\n // Write only valid elements, put null instead of invalid elements.\n if (writeNode(state, level + 1, value, true, true, false, true) ||\n (typeof value === 'undefined' &&\n writeNode(state, level + 1, null, true, true, false, true))) {\n\n if (!compact || _result !== '') {\n _result += generateNextLine(state, level);\n }\n\n if (state.dump && CHAR_LINE_FEED === state.dump.charCodeAt(0)) {\n _result += '-';\n } else {\n _result += '- ';\n }\n\n _result += state.dump;\n }\n }\n\n state.tag = _tag;\n state.dump = _result || '[]'; // Empty sequence if no valid values.\n}\n\nfunction writeFlowMapping(state, level, object) {\n var _result = '',\n _tag = state.tag,\n objectKeyList = Object.keys(object),\n index,\n length,\n objectKey,\n objectValue,\n pairBuffer;\n\n for (index = 0, length = objectKeyList.length; index < length; index += 1) {\n\n pairBuffer = '';\n if (_result !== '') pairBuffer += ', ';\n\n if (state.condenseFlow) pairBuffer += '\"';\n\n objectKey = objectKeyList[index];\n objectValue = object[objectKey];\n\n if (state.replacer) {\n objectValue = state.replacer.call(object, objectKey, objectValue);\n }\n\n if (!writeNode(state, level, objectKey, false, false)) {\n continue; // Skip this pair because of invalid key;\n }\n\n if (state.dump.length > 1024) pairBuffer += '? ';\n\n pairBuffer += state.dump + (state.condenseFlow ? '\"' : '') + ':' + (state.condenseFlow ? '' : ' ');\n\n if (!writeNode(state, level, objectValue, false, false)) {\n continue; // Skip this pair because of invalid value.\n }\n\n pairBuffer += state.dump;\n\n // Both key and value are valid.\n _result += pairBuffer;\n }\n\n state.tag = _tag;\n state.dump = '{' + _result + '}';\n}\n\nfunction writeBlockMapping(state, level, object, compact) {\n var _result = '',\n _tag = state.tag,\n objectKeyList = Object.keys(object),\n index,\n length,\n objectKey,\n objectValue,\n explicitPair,\n pairBuffer;\n\n // Allow sorting keys so that the output file is deterministic\n if (state.sortKeys === true) {\n // Default sorting\n objectKeyList.sort();\n } else if (typeof state.sortKeys === 'function') {\n // Custom sort function\n objectKeyList.sort(state.sortKeys);\n } else if (state.sortKeys) {\n // Something is wrong\n throw new exception('sortKeys must be a boolean or a function');\n }\n\n for (index = 0, length = objectKeyList.length; index < length; index += 1) {\n pairBuffer = '';\n\n if (!compact || _result !== '') {\n pairBuffer += generateNextLine(state, level);\n }\n\n objectKey = objectKeyList[index];\n objectValue = object[objectKey];\n\n if (state.replacer) {\n objectValue = state.replacer.call(object, objectKey, objectValue);\n }\n\n if (!writeNode(state, level + 1, objectKey, true, true, true)) {\n continue; // Skip this pair because of invalid key.\n }\n\n explicitPair = (state.tag !== null && state.tag !== '?') ||\n (state.dump && state.dump.length > 1024);\n\n if (explicitPair) {\n if (state.dump && CHAR_LINE_FEED === state.dump.charCodeAt(0)) {\n pairBuffer += '?';\n } else {\n pairBuffer += '? ';\n }\n }\n\n pairBuffer += state.dump;\n\n if (explicitPair) {\n pairBuffer += generateNextLine(state, level);\n }\n\n if (!writeNode(state, level + 1, objectValue, true, explicitPair)) {\n continue; // Skip this pair because of invalid value.\n }\n\n if (state.dump && CHAR_LINE_FEED === state.dump.charCodeAt(0)) {\n pairBuffer += ':';\n } else {\n pairBuffer += ': ';\n }\n\n pairBuffer += state.dump;\n\n // Both key and value are valid.\n _result += pairBuffer;\n }\n\n state.tag = _tag;\n state.dump = _result || '{}'; // Empty mapping if no valid pairs.\n}\n\nfunction detectType(state, object, explicit) {\n var _result, typeList, index, length, type, style;\n\n typeList = explicit ? state.explicitTypes : state.implicitTypes;\n\n for (index = 0, length = typeList.length; index < length; index += 1) {\n type = typeList[index];\n\n if ((type.instanceOf || type.predicate) &&\n (!type.instanceOf || ((typeof object === 'object') && (object instanceof type.instanceOf))) &&\n (!type.predicate || type.predicate(object))) {\n\n if (explicit) {\n if (type.multi && type.representName) {\n state.tag = type.representName(object);\n } else {\n state.tag = type.tag;\n }\n } else {\n state.tag = '?';\n }\n\n if (type.represent) {\n style = state.styleMap[type.tag] || type.defaultStyle;\n\n if (_toString.call(type.represent) === '[object Function]') {\n _result = type.represent(object, style);\n } else if (_hasOwnProperty.call(type.represent, style)) {\n _result = type.represent[style](object, style);\n } else {\n throw new exception('!<' + type.tag + '> tag resolver accepts not \"' + style + '\" style');\n }\n\n state.dump = _result;\n }\n\n return true;\n }\n }\n\n return false;\n}\n\n// Serializes `object` and writes it to global `result`.\n// Returns true on success, or false on invalid object.\n//\nfunction writeNode(state, level, object, block, compact, iskey, isblockseq) {\n state.tag = null;\n state.dump = object;\n\n if (!detectType(state, object, false)) {\n detectType(state, object, true);\n }\n\n var type = _toString.call(state.dump);\n var inblock = block;\n var tagStr;\n\n if (block) {\n block = (state.flowLevel < 0 || state.flowLevel > level);\n }\n\n var objectOrArray = type === '[object Object]' || type === '[object Array]',\n duplicateIndex,\n duplicate;\n\n if (objectOrArray) {\n duplicateIndex = state.duplicates.indexOf(object);\n duplicate = duplicateIndex !== -1;\n }\n\n if ((state.tag !== null && state.tag !== '?') || duplicate || (state.indent !== 2 && level > 0)) {\n compact = false;\n }\n\n if (duplicate && state.usedDuplicates[duplicateIndex]) {\n state.dump = '*ref_' + duplicateIndex;\n } else {\n if (objectOrArray && duplicate && !state.usedDuplicates[duplicateIndex]) {\n state.usedDuplicates[duplicateIndex] = true;\n }\n if (type === '[object Object]') {\n if (block && (Object.keys(state.dump).length !== 0)) {\n writeBlockMapping(state, level, state.dump, compact);\n if (duplicate) {\n state.dump = '&ref_' + duplicateIndex + state.dump;\n }\n } else {\n writeFlowMapping(state, level, state.dump);\n if (duplicate) {\n state.dump = '&ref_' + duplicateIndex + ' ' + state.dump;\n }\n }\n } else if (type === '[object Array]') {\n if (block && (state.dump.length !== 0)) {\n if (state.noArrayIndent && !isblockseq && level > 0) {\n writeBlockSequence(state, level - 1, state.dump, compact);\n } else {\n writeBlockSequence(state, level, state.dump, compact);\n }\n if (duplicate) {\n state.dump = '&ref_' + duplicateIndex + state.dump;\n }\n } else {\n writeFlowSequence(state, level, state.dump);\n if (duplicate) {\n state.dump = '&ref_' + duplicateIndex + ' ' + state.dump;\n }\n }\n } else if (type === '[object String]') {\n if (state.tag !== '?') {\n writeScalar(state, state.dump, level, iskey, inblock);\n }\n } else if (type === '[object Undefined]') {\n return false;\n } else {\n if (state.skipInvalid) return false;\n throw new exception('unacceptable kind of an object to dump ' + type);\n }\n\n if (state.tag !== null && state.tag !== '?') {\n // Need to encode all characters except those allowed by the spec:\n //\n // [35] ns-dec-digit ::= [#x30-#x39] /* 0-9 */\n // [36] ns-hex-digit ::= ns-dec-digit\n // | [#x41-#x46] /* A-F */ | [#x61-#x66] /* a-f */\n // [37] ns-ascii-letter ::= [#x41-#x5A] /* A-Z */ | [#x61-#x7A] /* a-z */\n // [38] ns-word-char ::= ns-dec-digit | ns-ascii-letter | \u201C-\u201D\n // [39] ns-uri-char ::= \u201C%\u201D ns-hex-digit ns-hex-digit | ns-word-char | \u201C#\u201D\n // | \u201C;\u201D | \u201C/\u201D | \u201C?\u201D | \u201C:\u201D | \u201C@\u201D | \u201C&\u201D | \u201C=\u201D | \u201C+\u201D | \u201C$\u201D | \u201C,\u201D\n // | \u201C_\u201D | \u201C.\u201D | \u201C!\u201D | \u201C~\u201D | \u201C*\u201D | \u201C'\u201D | \u201C(\u201D | \u201C)\u201D | \u201C[\u201D | \u201C]\u201D\n //\n // Also need to encode '!' because it has special meaning (end of tag prefix).\n //\n tagStr = encodeURI(\n state.tag[0] === '!' ? state.tag.slice(1) : state.tag\n ).replace(/!/g, '%21');\n\n if (state.tag[0] === '!') {\n tagStr = '!' + tagStr;\n } else if (tagStr.slice(0, 18) === 'tag:yaml.org,2002:') {\n tagStr = '!!' + tagStr.slice(18);\n } else {\n tagStr = '!<' + tagStr + '>';\n }\n\n state.dump = tagStr + ' ' + state.dump;\n }\n }\n\n return true;\n}\n\nfunction getDuplicateReferences(object, state) {\n var objects = [],\n duplicatesIndexes = [],\n index,\n length;\n\n inspectNode(object, objects, duplicatesIndexes);\n\n for (index = 0, length = duplicatesIndexes.length; index < length; index += 1) {\n state.duplicates.push(objects[duplicatesIndexes[index]]);\n }\n state.usedDuplicates = new Array(length);\n}\n\nfunction inspectNode(object, objects, duplicatesIndexes) {\n var objectKeyList,\n index,\n length;\n\n if (object !== null && typeof object === 'object') {\n index = objects.indexOf(object);\n if (index !== -1) {\n if (duplicatesIndexes.indexOf(index) === -1) {\n duplicatesIndexes.push(index);\n }\n } else {\n objects.push(object);\n\n if (Array.isArray(object)) {\n for (index = 0, length = object.length; index < length; index += 1) {\n inspectNode(object[index], objects, duplicatesIndexes);\n }\n } else {\n objectKeyList = Object.keys(object);\n\n for (index = 0, length = objectKeyList.length; index < length; index += 1) {\n inspectNode(object[objectKeyList[index]], objects, duplicatesIndexes);\n }\n }\n }\n }\n}\n\nfunction dump$1(input, options) {\n options = options || {};\n\n var state = new State(options);\n\n if (!state.noRefs) getDuplicateReferences(input, state);\n\n var value = input;\n\n if (state.replacer) {\n value = state.replacer.call({ '': value }, '', value);\n }\n\n if (writeNode(state, 0, value, true, true)) return state.dump + '\\n';\n\n return '';\n}\n\nvar dump_1 = dump$1;\n\nvar dumper = {\n\tdump: dump_1\n};\n\nfunction renamed(from, to) {\n return function () {\n throw new Error('Function yaml.' + from + ' is removed in js-yaml 4. ' +\n 'Use yaml.' + to + ' instead, which is now safe by default.');\n };\n}\n\n\nvar Type = type;\nvar Schema = schema;\nvar FAILSAFE_SCHEMA = failsafe;\nvar JSON_SCHEMA = json;\nvar CORE_SCHEMA = core;\nvar DEFAULT_SCHEMA = _default;\nvar load = loader.load;\nvar loadAll = loader.loadAll;\nvar dump = dumper.dump;\nvar YAMLException = exception;\n\n// Re-export all types in case user wants to create custom schema\nvar types = {\n binary: binary,\n float: float,\n map: map,\n null: _null,\n pairs: pairs,\n set: set,\n timestamp: timestamp,\n bool: bool,\n int: int,\n merge: merge,\n omap: omap,\n seq: seq,\n str: str\n};\n\n// Removed functions from JS-YAML 3.0.x\nvar safeLoad = renamed('safeLoad', 'load');\nvar safeLoadAll = renamed('safeLoadAll', 'loadAll');\nvar safeDump = renamed('safeDump', 'dump');\n\nvar jsYaml = {\n\tType: Type,\n\tSchema: Schema,\n\tFAILSAFE_SCHEMA: FAILSAFE_SCHEMA,\n\tJSON_SCHEMA: JSON_SCHEMA,\n\tCORE_SCHEMA: CORE_SCHEMA,\n\tDEFAULT_SCHEMA: DEFAULT_SCHEMA,\n\tload: load,\n\tloadAll: loadAll,\n\tdump: dump,\n\tYAMLException: YAMLException,\n\ttypes: types,\n\tsafeLoad: safeLoad,\n\tsafeLoadAll: safeLoadAll,\n\tsafeDump: safeDump\n};\n\nexport { CORE_SCHEMA, DEFAULT_SCHEMA, FAILSAFE_SCHEMA, JSON_SCHEMA, Schema, Type, YAMLException, jsYaml as default, dump, load, loadAll, safeDump, safeLoad, safeLoadAll, types };\n", "/**\n * CodeQL metadata resolver utilities\n * Handles resolution of query metadata using the CodeQL CLI\n */\n\nimport { executeCodeQLCommand } from './cli-executor';\nimport { logger } from '../utils/logger';\n\n/**\n * Query metadata structure returned by codeql resolve metadata\n */\nexport interface QueryMetadata {\n [key: string]: string | string[];\n}\n\n/**\n * Resolve metadata for a CodeQL query file\n * @param queryPath - Absolute or relative path to the .ql query file\n * @returns Parsed metadata object or null if resolution fails\n */\nexport async function resolveQueryMetadata(queryPath: string): Promise {\n try {\n logger.info(`Resolving metadata for query: ${queryPath}`);\n\n const result = await executeCodeQLCommand(\n 'resolve metadata',\n { format: 'json' },\n [queryPath]\n );\n\n if (!result.success) {\n logger.error(`Failed to resolve metadata for ${queryPath}:`, result.stderr || result.error);\n return null;\n }\n\n // Parse the JSON output\n try {\n const metadata = JSON.parse(result.stdout);\n return metadata;\n } catch (parseError) {\n logger.error(`Failed to parse metadata JSON for ${queryPath}:`, parseError);\n return null;\n }\n } catch (error) {\n logger.error(`Error resolving metadata for ${queryPath}:`, error);\n return null;\n }\n}\n", "/**\n * CodeQL generate log-summary tool\n */\n\nimport { z } from 'zod';\nimport { CLIToolDefinition, createCodeQLSchemas, defaultCLIResultProcessor } from '../../lib/cli-tool-registry';\n\nexport const codeqlGenerateLogSummaryTool: CLIToolDefinition = {\n name: 'codeql_generate_log-summary',\n description: 'Create a summary of a structured JSON evaluator event log file',\n command: 'codeql',\n subcommand: 'generate log-summary',\n inputSchema: {\n inputLog: z.string().describe('Path to the evaluator log file to summarize'),\n outputFile: z.string().optional().describe('Path to write the summary (optional, defaults to stdout)'),\n format: z.enum(['text', 'predicates', 'overall']).optional()\n .describe('Output format: text (human-readable), predicates (JSON), or overall (stats)'),\n 'minify-output': z.boolean().optional().describe('Minify JSON output'),\n utc: z.boolean().optional().describe('Force UTC timestamps'),\n 'deduplicate-stage-summaries': z.boolean().optional().describe('Deduplicate stage summaries'),\n verbose: createCodeQLSchemas.verbose(),\n additionalArgs: createCodeQLSchemas.additionalArgs()\n },\n examples: [\n 'codeql generate log-summary --format=text -- evaluator-log.json.txt summary.txt',\n 'codeql generate log-summary --format=predicates --minify-output -- evaluator-log.json.txt',\n 'codeql generate log-summary --format=overall -- evaluator-log.json.txt overall-stats.json'\n ],\n resultProcessor: defaultCLIResultProcessor\n};", "/**\n * CodeQL generate query-help tool\n */\n\nimport { z } from 'zod';\nimport { CLIToolDefinition, createCodeQLSchemas, defaultCLIResultProcessor } from '../../lib/cli-tool-registry';\n\nexport const codeqlGenerateQueryHelpTool: CLIToolDefinition = {\n name: 'codeql_generate_query-help',\n description: 'Generate query help documentation from QLDoc comments',\n command: 'codeql',\n subcommand: 'generate query-help',\n inputSchema: {\n query: z.string().describe('Path to the query file to generate help for'),\n outputFile: z.string().optional().describe('Path to write the help documentation'),\n format: z.enum(['markdown', 'text', 'html']).optional()\n .describe('Output format for the help documentation'),\n verbose: createCodeQLSchemas.verbose(),\n additionalArgs: createCodeQLSchemas.additionalArgs()\n },\n examples: [\n 'codeql generate query-help -- MyQuery.ql',\n 'codeql generate query-help --format=markdown -- MyQuery.ql help.md',\n 'codeql generate query-help --format=html -- MyQuery.ql help.html'\n ],\n resultProcessor: defaultCLIResultProcessor\n};", "/**\n * list_codeql_databases tool\n *\n * Discovers CodeQL databases in configured base directories.\n * Scans each directory in `CODEQL_DATABASES_BASE_DIRS` for subdirectories\n * containing `codeql-database.yml`, extracts metadata (language, CLI version,\n * creation time), and returns the list.\n */\n\nimport { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport { existsSync, readdirSync, readFileSync, statSync } from 'fs';\nimport { join } from 'path';\nimport { z } from 'zod';\nimport { getDatabaseBaseDirs } from '../../lib/discovery-config';\nimport { logger } from '../../utils/logger';\n\nexport interface DatabaseInfo {\n cliVersion?: string;\n creationTime?: string;\n language?: string;\n name: string;\n path: string;\n}\n\n/**\n * Parse `codeql-database.yml` to extract metadata.\n * Uses simple line-based parsing to avoid a YAML dependency.\n */\nfunction parseDatabaseYml(ymlPath: string): Partial {\n try {\n const content = readFileSync(ymlPath, 'utf-8');\n const info: Partial = {};\n\n for (const line of content.split('\\n')) {\n const trimmed = line.trim();\n const colonIdx = trimmed.indexOf(':');\n if (colonIdx === -1) continue;\n\n const key = trimmed.substring(0, colonIdx).trim();\n const value = trimmed.substring(colonIdx + 1).trim().replace(/^[\"']|[\"']$/g, '');\n\n switch (key) {\n case 'primaryLanguage':\n info.language = value;\n break;\n case 'cliVersion':\n info.cliVersion = value;\n break;\n case 'creationTime':\n info.creationTime = value;\n break;\n }\n }\n\n return info;\n } catch {\n return {};\n }\n}\n\n/**\n * Discover CodeQL databases in the given base directories.\n *\n * @param baseDirs - Directories to scan for database subdirectories\n * @param language - Optional language filter\n * @returns List of discovered databases with metadata\n */\nexport async function discoverDatabases(\n baseDirs: string[],\n language?: string,\n): Promise {\n const databases: DatabaseInfo[] = [];\n\n for (const baseDir of baseDirs) {\n if (!existsSync(baseDir)) {\n continue;\n }\n\n let entries: string[];\n try {\n entries = readdirSync(baseDir);\n } catch {\n continue;\n }\n\n for (const entry of entries) {\n const entryPath = join(baseDir, entry);\n\n // Skip non-directories\n try {\n if (!statSync(entryPath).isDirectory()) {\n continue;\n }\n } catch {\n continue;\n }\n\n // Check for codeql-database.yml\n const ymlPath = join(entryPath, 'codeql-database.yml');\n if (!existsSync(ymlPath)) {\n continue;\n }\n\n const metadata = parseDatabaseYml(ymlPath);\n\n // Apply language filter\n if (language && metadata.language !== language) {\n continue;\n }\n\n databases.push({\n cliVersion: metadata.cliVersion,\n creationTime: metadata.creationTime,\n language: metadata.language,\n name: entry,\n path: entryPath,\n });\n }\n }\n\n return databases;\n}\n\n/**\n * Register the list_codeql_databases tool with the MCP server.\n */\nexport function registerListDatabasesTool(server: McpServer): void {\n server.tool(\n 'list_codeql_databases',\n 'List CodeQL databases discovered in configured base directories (set via CODEQL_DATABASES_BASE_DIRS env var). Returns path, language, CLI version, and creation time for each database.',\n {\n language: z\n .string()\n .optional()\n .describe('Filter databases by language (e.g., \"javascript\", \"python\")'),\n },\n async ({ language }) => {\n try {\n const baseDirs = getDatabaseBaseDirs();\n\n if (baseDirs.length === 0) {\n return {\n content: [\n {\n type: 'text' as const,\n text: 'No database base directories configured. Set the CODEQL_DATABASES_BASE_DIRS environment variable to a colon-separated list of directories to search.',\n },\n ],\n };\n }\n\n const databases = await discoverDatabases(baseDirs, language);\n\n if (databases.length === 0) {\n const filterMsg = language ? ` for language \"${language}\"` : '';\n return {\n content: [\n {\n type: 'text' as const,\n text: `No CodeQL databases found${filterMsg} in: ${baseDirs.join(', ')}`,\n },\n ],\n };\n }\n\n const lines = [\n `Found ${databases.length} CodeQL database(s):`,\n '',\n ...databases.map((db) => {\n const parts = [` ${db.name}`];\n parts.push(` Path: ${db.path}`);\n if (db.language) parts.push(` Language: ${db.language}`);\n if (db.cliVersion) parts.push(` CLI Version: ${db.cliVersion}`);\n if (db.creationTime) parts.push(` Created: ${db.creationTime}`);\n return parts.join('\\n');\n }),\n ];\n\n return {\n content: [{ type: 'text' as const, text: lines.join('\\n') }],\n };\n } catch (error) {\n logger.error('Error listing databases:', error);\n return {\n content: [\n {\n type: 'text' as const,\n text: `Error: ${error instanceof Error ? error.message : 'Unknown error'}`,\n },\n ],\n isError: true,\n };\n }\n },\n );\n}\n", "/**\n * Discovery configuration for locating CodeQL databases and query run results.\n *\n * Reads colon-separated directory lists from environment variables:\n * - `CODEQL_DATABASES_BASE_DIRS` \u2014 directories to search for CodeQL databases\n * - `CODEQL_QUERY_RUN_RESULTS_DIRS` \u2014 directories containing per-run query result subdirectories\n *\n * The VS Code extension sets these automatically from vscode-codeql storage paths.\n * CLI users can set them manually.\n */\n\n/**\n * Parse a colon-separated list of directories from an environment variable.\n */\nfunction parsePathList(envValue: string | undefined): string[] {\n if (!envValue) {\n return [];\n }\n return envValue\n .split(':')\n .map((p) => p.trim())\n .filter((p) => p.length > 0);\n}\n\n/**\n * Get the list of base directories to search for CodeQL databases.\n *\n * Each directory is expected to contain one or more CodeQL database directories\n * (each with a `codeql-database.yml` file).\n *\n * Set via `CODEQL_DATABASES_BASE_DIRS` (colon-separated).\n */\nexport function getDatabaseBaseDirs(): string[] {\n return parsePathList(process.env.CODEQL_DATABASES_BASE_DIRS);\n}\n\n/**\n * Get the list of directories containing per-run query result subdirectories.\n *\n * Each directory is expected to contain subdirectories named like\n * `.ql-/`, each holding artifacts such as\n * `evaluator-log.jsonl`, `results.bqrs`, and `results-interpreted.sarif`.\n *\n * Set via `CODEQL_QUERY_RUN_RESULTS_DIRS` (colon-separated).\n */\nexport function getQueryRunResultsDirs(): string[] {\n return parsePathList(process.env.CODEQL_QUERY_RUN_RESULTS_DIRS);\n}\n", "/**\n * list_query_run_results tool\n *\n * Discovers per-query-run result directories in configured search paths.\n * Scans each directory in `CODEQL_QUERY_RUN_RESULTS_DIRS` for subdirectories\n * matching the `.ql-` naming convention used by vscode-codeql.\n * Reports which artifacts (evaluator logs, BQRS, SARIF) are present in each run.\n */\n\nimport { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport { existsSync, readdirSync, readFileSync, statSync } from 'fs';\nimport { join } from 'path';\nimport { z } from 'zod';\nimport { getQueryRunResultsDirs } from '../../lib/discovery-config';\nimport { logger } from '../../utils/logger';\n\nexport interface QueryRunResult {\n hasBqrs: boolean;\n hasEvaluatorLog: boolean;\n hasSarif: boolean;\n path: string;\n queryName: string;\n runId: string;\n timestamp?: string;\n}\n\n/**\n * Pattern matching vscode-codeql query run directory names: `.ql-`\n */\nconst QUERY_RUN_DIR_PATTERN = /^(.+\\.ql)-(.+)$/;\n\n/**\n * Discover query run result directories in the given search paths.\n *\n * @param resultsDirs - Directories to scan for per-run subdirectories\n * @param queryName - Optional query name filter (e.g., \"UI5Xss.ql\")\n * @returns List of discovered query run results with artifact inventory\n */\nexport async function discoverQueryRunResults(\n resultsDirs: string[],\n queryName?: string,\n): Promise {\n const results: QueryRunResult[] = [];\n\n for (const dir of resultsDirs) {\n if (!existsSync(dir)) {\n continue;\n }\n\n let entries: string[];\n try {\n entries = readdirSync(dir);\n } catch {\n continue;\n }\n\n for (const entry of entries) {\n const entryPath = join(dir, entry);\n\n // Skip non-directories\n try {\n if (!statSync(entryPath).isDirectory()) {\n continue;\n }\n } catch {\n continue;\n }\n\n // Match the naming pattern\n const match = QUERY_RUN_DIR_PATTERN.exec(entry);\n if (!match) {\n continue;\n }\n\n const [, name, runId] = match;\n\n // Apply query name filter\n if (queryName && name !== queryName) {\n continue;\n }\n\n // Check which artifacts are present\n const hasEvaluatorLog = existsSync(join(entryPath, 'evaluator-log.jsonl'));\n const hasBqrs = existsSync(join(entryPath, 'results.bqrs'));\n const hasSarif = existsSync(join(entryPath, 'results-interpreted.sarif'));\n\n // Read timestamp if available\n let timestamp: string | undefined;\n const timestampPath = join(entryPath, 'timestamp');\n if (existsSync(timestampPath)) {\n try {\n timestamp = readFileSync(timestampPath, 'utf-8').trim();\n } catch {\n // Ignore read errors\n }\n }\n\n results.push({\n hasBqrs,\n hasEvaluatorLog,\n hasSarif,\n path: entryPath,\n queryName: name,\n runId,\n timestamp,\n });\n }\n }\n\n return results;\n}\n\n/**\n * Register the list_query_run_results tool with the MCP server.\n */\nexport function registerListQueryRunResultsTool(server: McpServer): void {\n server.tool(\n 'list_query_run_results',\n 'List discovered query run result directories (set via CODEQL_QUERY_RUN_RESULTS_DIRS env var). Returns path, query name, timestamp, and available artifacts for each run.',\n {\n queryName: z\n .string()\n .optional()\n .describe('Filter results by query name (e.g., \"UI5Xss.ql\")'),\n },\n async ({ queryName }) => {\n try {\n const resultsDirs = getQueryRunResultsDirs();\n\n if (resultsDirs.length === 0) {\n return {\n content: [\n {\n type: 'text' as const,\n text: 'No query run results directories configured. Set the CODEQL_QUERY_RUN_RESULTS_DIRS environment variable to a colon-separated list of directories to search.',\n },\n ],\n };\n }\n\n const runs = await discoverQueryRunResults(resultsDirs, queryName);\n\n if (runs.length === 0) {\n const filterMsg = queryName ? ` for query \"${queryName}\"` : '';\n return {\n content: [\n {\n type: 'text' as const,\n text: `No query run results found${filterMsg} in: ${resultsDirs.join(', ')}`,\n },\n ],\n };\n }\n\n const lines = [\n `Found ${runs.length} query run result(s):`,\n '',\n ...runs.map((run) => {\n const artifacts: string[] = [];\n if (run.hasEvaluatorLog) artifacts.push('evaluator-log');\n if (run.hasBqrs) artifacts.push('bqrs');\n if (run.hasSarif) artifacts.push('sarif');\n const parts = [` ${run.queryName} (${run.runId})`];\n parts.push(` Path: ${run.path}`);\n if (run.timestamp) parts.push(` Timestamp: ${run.timestamp}`);\n parts.push(` Artifacts: ${artifacts.length > 0 ? artifacts.join(', ') : 'none'}`);\n return parts.join('\\n');\n }),\n ];\n\n return {\n content: [{ type: 'text' as const, text: lines.join('\\n') }],\n };\n } catch (error) {\n logger.error('Error listing query run results:', error);\n return {\n content: [\n {\n type: 'text' as const,\n text: `Error: ${error instanceof Error ? error.message : 'Unknown error'}`,\n },\n ],\n isError: true,\n };\n }\n },\n );\n}\n", "/**\n * CodeQL pack install tool\n */\n\nimport { z } from 'zod';\nimport { CLIToolDefinition, createCodeQLSchemas } from '../../lib/cli-tool-registry';\n\nexport const codeqlPackInstallTool: CLIToolDefinition = {\n name: 'codeql_pack_install',\n description: 'Install CodeQL pack dependencies',\n command: 'codeql',\n subcommand: 'pack install',\n inputSchema: {\n packDir: z.string().optional().describe('Directory containing qlpack.yml (default: current)'),\n force: z.boolean().optional().describe('Force reinstall of dependencies'),\n 'no-strict-mode': z.boolean().optional()\n .describe('Allow non-strict dependency resolution'),\n verbose: createCodeQLSchemas.verbose(),\n additionalArgs: createCodeQLSchemas.additionalArgs()\n },\n examples: [\n 'codeql pack install',\n 'codeql pack install --force /path/to/pack',\n 'codeql pack install --no-strict-mode'\n ]\n};", "/**\n * CodeQL pack ls tool\n */\n\nimport { z } from 'zod';\nimport { CLIToolDefinition, createCodeQLSchemas, defaultCLIResultProcessor } from '../../lib/cli-tool-registry';\n\nexport const codeqlPackLsTool: CLIToolDefinition = {\n name: 'codeql_pack_ls',\n description: 'List CodeQL packs under some local directory path',\n command: 'codeql',\n subcommand: 'pack ls',\n inputSchema: {\n dir: z.string().optional().describe('The root directory of the package or workspace, defaults to the current working directory'),\n format: z.enum(['text', 'json']).optional()\n .describe('Output format: text (default) or json'),\n groups: z.string().optional()\n .describe('List of CodeQL pack groups to include or exclude'),\n verbose: createCodeQLSchemas.verbose(),\n additionalArgs: createCodeQLSchemas.additionalArgs()\n },\n examples: [\n 'codeql pack ls -- .',\n 'codeql pack ls --format=json -- /path/to/pack-directory',\n 'codeql pack ls --format=json --groups=queries,tests -- .'\n ],\n resultProcessor: defaultCLIResultProcessor\n};", "/**\n * CodeQL query profiling tool\n */\n\nimport { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport { z } from 'zod';\nimport { executeCodeQLCommand } from '../../lib/cli-executor';\nimport { logger } from '../../utils/logger';\nimport { writeFileSync, readFileSync, existsSync } from 'fs';\nimport { join, dirname, basename } from 'path';\nimport { mkdirSync } from 'fs';\n\ninterface EvaluatorLogEvent {\n time: string;\n type: string;\n eventId: number;\n nanoTime: number;\n [key: string]: unknown;\n}\n\ninterface PipelineNode {\n eventId: number;\n name: string;\n position?: string;\n type?: string;\n startTime: number;\n endTime: number;\n duration: number;\n resultSize?: number;\n tupleCount?: number;\n dependencies: string[];\n dependencyEventIds: number[];\n}\n\ninterface ProfileData {\n queryName: string;\n totalDuration: number;\n totalEvents: number;\n pipelines: PipelineNode[];\n}\n\n/**\n * Parse evaluator log and create profile data\n */\nfunction parseEvaluatorLog(logPath: string): ProfileData {\n const logContent = readFileSync(logPath, 'utf-8');\n \n // Split by empty lines to get each JSON object (handles both JSONL and pretty-printed JSON)\n const jsonObjects = logContent.split('\\n\\n').filter((s) => s.trim());\n const events: EvaluatorLogEvent[] = jsonObjects\n .map((obj) => {\n try {\n return JSON.parse(obj);\n } catch (_error) {\n logger.warn(`Failed to parse evaluator log object: ${obj.substring(0, 100)}...`);\n return null;\n }\n })\n .filter((event): event is EvaluatorLogEvent => event !== null);\n\n // Map to track pipeline nodes by their start event ID\n const pipelineMap = new Map>();\n // Map to track dependency event IDs by predicate name\n const predicateNameToEventId = new Map();\n \n let queryName = '';\n let queryStartTime = 0;\n let queryEndTime = 0;\n\n for (const event of events) {\n switch (event.type) {\n case 'QUERY_STARTED':\n queryName = (event.queryName as string) || '';\n queryStartTime = event.nanoTime;\n break;\n\n case 'QUERY_COMPLETED':\n queryEndTime = event.nanoTime;\n break;\n\n case 'PREDICATE_STARTED': {\n const predicateName = event.predicateName as string;\n const position = event.position as string | undefined;\n const predicateType = event.predicateType as string | undefined;\n const dependencies = event.dependencies as Record | undefined;\n \n // Track this predicate's event ID by name for dependency resolution\n predicateNameToEventId.set(predicateName, event.eventId);\n \n // Get dependency event IDs\n const dependencyEventIds: number[] = [];\n const dependencyNames: string[] = [];\n if (dependencies) {\n for (const depName of Object.keys(dependencies)) {\n dependencyNames.push(depName);\n const depEventId = predicateNameToEventId.get(depName);\n if (depEventId !== undefined) {\n dependencyEventIds.push(depEventId);\n }\n }\n }\n\n pipelineMap.set(event.eventId, {\n eventId: event.eventId,\n name: predicateName,\n position,\n type: predicateType,\n startTime: event.nanoTime,\n dependencies: dependencyNames,\n dependencyEventIds,\n });\n break;\n }\n\n case 'PREDICATE_COMPLETED': {\n const startEventId = event.startEvent as number;\n const pipelineInfo = pipelineMap.get(startEventId);\n if (pipelineInfo) {\n const startEvent = events.find((e) => e.eventId === startEventId);\n if (startEvent) {\n const duration = (event.nanoTime - startEvent.nanoTime) / 1_000_000; // Convert to ms\n pipelineInfo.endTime = event.nanoTime;\n pipelineInfo.duration = duration;\n pipelineInfo.resultSize = event.resultSize as number | undefined;\n pipelineInfo.tupleCount = event.tupleCount as number | undefined;\n }\n }\n break;\n }\n }\n }\n\n // Convert to array and maintain original evaluation order (by eventId)\n const pipelines: PipelineNode[] = Array.from(pipelineMap.values())\n .filter((p): p is PipelineNode => p.duration !== undefined)\n .sort((a, b) => a.eventId - b.eventId);\n\n const totalDuration = queryEndTime > 0 ? (queryEndTime - queryStartTime) / 1_000_000 : 0;\n\n return {\n queryName,\n totalDuration,\n totalEvents: events.length,\n pipelines,\n };\n}\n\n/**\n * Format profile data as JSON\n */\nfunction formatAsJson(profile: ProfileData): string {\n return JSON.stringify(profile, null, 2);\n}\n\n/**\n * Format profile data as Mermaid diagram\n * Creates a graph showing the query evaluation pipelines in order of execution\n * with dependencies as edges, annotated with duration and result sizes\n */\nfunction formatAsMermaid(profile: ProfileData): string {\n const lines: string[] = [];\n\n lines.push('```mermaid');\n lines.push('graph TD');\n lines.push('');\n \n // Add query root node\n lines.push(` QUERY[\"${basename(profile.queryName)}
Total: ${profile.totalDuration.toFixed(2)}ms\"]`);\n lines.push('');\n \n // Create nodes for each pipeline in evaluation order (already sorted by eventId)\n profile.pipelines.forEach((pipeline) => {\n const nodeId = `P${pipeline.eventId}`;\n const duration = pipeline.duration.toFixed(2);\n const resultSize = pipeline.resultSize !== undefined ? pipeline.resultSize : '?';\n // Sanitize predicate name for Mermaid\n const name = pipeline.name.replace(/[<>]/g, '').substring(0, 40);\n lines.push(` ${nodeId}[\"${name}
${duration}ms | ${resultSize} results\"]`);\n });\n \n lines.push('');\n \n // Add edges from QUERY to root pipelines (those with no dependencies)\n const rootPipelines = profile.pipelines.filter((p) => p.dependencies.length === 0);\n \n rootPipelines.forEach((pipeline) => {\n lines.push(` QUERY --> P${pipeline.eventId}`);\n });\n \n lines.push('');\n \n // Add edges between pipelines based on dependencies (using eventIds to preserve links)\n profile.pipelines.forEach((pipeline) => {\n pipeline.dependencyEventIds.forEach((depEventId) => {\n const duration = pipeline.duration.toFixed(2);\n lines.push(` P${depEventId} -->|\"${duration}ms\"| P${pipeline.eventId}`);\n });\n });\n \n lines.push('');\n lines.push(' classDef default fill:#e1f5ff,stroke:#333,stroke-width:2px');\n lines.push(' classDef query fill:#ffe1e1,stroke:#333,stroke-width:3px');\n lines.push(' class QUERY query');\n lines.push('```');\n\n return lines.join('\\n');\n}\n\n/**\n * Register the profile_codeql_query tool\n */\nexport function registerProfileCodeQLQueryTool(server: McpServer): void {\n server.tool(\n 'profile_codeql_query',\n 'Profile the performance of a CodeQL query run against a specific database by analyzing the evaluator log JSON file',\n {\n query: z.string().describe('Path to the .ql query file'),\n database: z.string().describe('Path to the CodeQL database directory'),\n evaluatorLog: z\n .string()\n .optional()\n .describe(\n 'Path to an existing structured JSON log (e.g., evaluator-log.jsonl) file. If not provided, the tool will run the query to generate one.'\n ),\n outputDir: z\n .string()\n .optional()\n .describe('Directory to write profiling data files (defaults to same directory as evaluator log)'),\n },\n async (params) => {\n try {\n const { query, database, evaluatorLog, outputDir } = params;\n let logPath = evaluatorLog;\n let bqrsPath: string | undefined;\n let sarifPath: string | undefined;\n\n // If evaluator log not provided, run the query to generate one\n if (!logPath) {\n logger.info('No evaluator log provided, running query to generate one');\n\n // Determine output directory\n const defaultOutputDir = outputDir || join(dirname(query as string), 'profile-output');\n mkdirSync(defaultOutputDir, { recursive: true });\n\n logPath = join(defaultOutputDir, 'evaluator-log.jsonl');\n bqrsPath = join(defaultOutputDir, 'query-results.bqrs');\n sarifPath = join(defaultOutputDir, 'query-results.sarif');\n\n // Run query with evaluator logging and tuple counting\n const queryResult = await executeCodeQLCommand(\n 'query run',\n {\n database: database as string,\n output: bqrsPath,\n 'evaluator-log': logPath,\n 'tuple-counting': true,\n 'evaluator-log-level': 5,\n },\n [query as string]\n );\n\n if (!queryResult.success) {\n return {\n content: [\n {\n type: 'text' as const,\n text: `Failed to run query: ${queryResult.stderr || queryResult.error}`,\n },\n ],\n isError: true,\n };\n }\n\n // Generate SARIF interpretation\n if (existsSync(bqrsPath)) {\n try {\n const sarifResult = await executeCodeQLCommand(\n 'bqrs interpret',\n { format: 'sarif-latest', output: sarifPath },\n [bqrsPath]\n );\n\n if (sarifResult.success) {\n logger.info(`Generated SARIF interpretation at ${sarifPath}`);\n }\n } catch (error) {\n logger.warn(`Failed to generate SARIF interpretation: ${error}`);\n }\n }\n }\n\n // Verify evaluator log exists\n if (!existsSync(logPath)) {\n return {\n content: [\n {\n type: 'text' as const,\n text: `Evaluator log not found at: ${logPath}`,\n },\n ],\n isError: true,\n };\n }\n\n // Parse the evaluator log\n logger.info(`Parsing evaluator log from: ${logPath}`);\n const profile = parseEvaluatorLog(logPath);\n\n // Determine output directory for profile\n const profileOutputDir = outputDir || dirname(logPath);\n mkdirSync(profileOutputDir, { recursive: true });\n\n // Write profile JSON file\n const jsonPath = join(profileOutputDir, 'query-evaluation-profile.json');\n const jsonContent = formatAsJson(profile);\n writeFileSync(jsonPath, jsonContent);\n logger.info(`Profile JSON written to: ${jsonPath}`);\n\n // Write profile Mermaid diagram file\n const mdPath = join(profileOutputDir, 'query-evaluation-profile.md');\n const mdContent = formatAsMermaid(profile);\n writeFileSync(mdPath, mdContent);\n logger.info(`Profile Mermaid diagram written to: ${mdPath}`);\n\n // Build response message\n const outputFiles: string[] = [\n `Profile JSON: ${jsonPath}`,\n `Profile Mermaid: ${mdPath}`,\n `Evaluator Log: ${logPath}`,\n ];\n\n if (bqrsPath) {\n outputFiles.push(`Query Results (BQRS): ${bqrsPath}`);\n }\n\n if (sarifPath && existsSync(sarifPath)) {\n outputFiles.push(`Query Results (SARIF): ${sarifPath}`);\n }\n\n const responseText = [\n 'Query profiling completed successfully!',\n '',\n 'Output Files:',\n ...outputFiles.map((f) => ` - ${f}`),\n '',\n 'Profile Summary:',\n ` - Query: ${basename(profile.queryName)}`,\n ` - Total Duration: ${profile.totalDuration.toFixed(2)} ms`,\n ` - Total Pipelines: ${profile.pipelines.length}`,\n ` - Total Events: ${profile.totalEvents}`,\n '',\n 'First 5 Pipeline Nodes (in evaluation order):',\n ...profile.pipelines.slice(0, 5).map((p, idx) => {\n return ` ${idx + 1}. ${p.name} (${p.duration.toFixed(2)} ms, ${p.resultSize || '?'} results)`;\n }),\n ].join('\\n');\n\n return {\n content: [\n {\n type: 'text' as const,\n text: responseText,\n },\n ],\n };\n } catch (error) {\n logger.error('Error profiling CodeQL query:', error);\n\n return {\n content: [\n {\n type: 'text' as const,\n text: `Failed to profile query: ${error instanceof Error ? error.message : String(error)}`,\n },\n ],\n isError: true,\n };\n }\n }\n );\n}\n", "/**\n * CodeQL query compile tool\n */\n\nimport { z } from 'zod';\nimport { CLIToolDefinition } from '../../lib/cli-tool-registry';\n\nexport const codeqlQueryCompileTool: CLIToolDefinition = {\n name: 'codeql_query_compile',\n description: 'Compile and validate CodeQL queries',\n command: 'codeql',\n subcommand: 'query compile',\n inputSchema: {\n query: z.string().describe('Path to the CodeQL query file (.ql)'),\n database: z.string().optional().describe('Path to the CodeQL database'),\n library: z.string().optional().describe('Path to query library'),\n output: z.string().optional().describe('Output file path'),\n warnings: z.enum(['hide', 'show', 'error']).optional()\n .describe('How to handle compilation warnings'),\n verbose: z.boolean().optional().describe('Enable verbose output'),\n additionalArgs: z.array(z.string()).optional().describe('Additional command-line arguments')\n },\n examples: [\n 'codeql query compile --database=/path/to/db MyQuery.ql',\n 'codeql query compile --library=/path/to/lib --output=compiled.qlo MyQuery.ql'\n ]\n};", "/**\n * CodeQL query format tool\n */\n\nimport { z } from 'zod';\nimport { CLIToolDefinition, createCodeQLSchemas, defaultCLIResultProcessor, CLIExecutionResult } from '../../lib/cli-tool-registry';\n\n/**\n * Custom result processor for codeql query format tool\n * Exit code 1 with --check-only means \"file would change\" - this is success for format checking\n */\nfunction formatResultProcessor(result: CLIExecutionResult, params: Record): string {\n const isCheckOnly = params['check-only'];\n const hasFormatChanges = result.exitCode === 1;\n \n if (isCheckOnly && hasFormatChanges) {\n // Mark as success for the CLI tool registry since detecting format changes is the intended behavior\n result.success = true;\n return result.stdout || result.stderr || 'File would change by autoformatting.';\n }\n \n return defaultCLIResultProcessor(result, params);\n}\n\nexport const codeqlQueryFormatTool: CLIToolDefinition = {\n name: 'codeql_query_format',\n description: 'Automatically format CodeQL source code files',\n command: 'codeql',\n subcommand: 'query format',\n inputSchema: {\n files: z.array(z.string()).describe('One or more .ql or .qll source files to format'),\n output: z.string().optional().describe('Write formatted code to this file instead of stdout'),\n 'in-place': z.boolean().optional().describe('Overwrite each input file with formatted version'),\n 'check-only': z.boolean().optional().describe('Check formatting without writing output'),\n backup: z.string().optional().describe('Backup extension when overwriting existing files'),\n 'no-syntax-errors': z.boolean().optional().describe('Ignore syntax errors and pretend file is formatted'),\n verbose: createCodeQLSchemas.verbose(),\n additionalArgs: createCodeQLSchemas.additionalArgs()\n },\n examples: [\n 'codeql query format -i -- ExampleQuery.ql',\n 'codeql query format --in-place -- queries/*.ql',\n 'codeql query format --check-only -- queries/*.ql'\n ],\n resultProcessor: formatResultProcessor\n};", "/**\n * CodeQL query run tool\n */\n\nimport { z } from 'zod';\nimport { CLIToolDefinition, createCodeQLSchemas } from '../../lib/cli-tool-registry';\n\nexport const codeqlQueryRunTool: CLIToolDefinition = {\n name: 'codeql_query_run',\n description: 'Execute a CodeQL query against a database. Use either \"query\" parameter for direct file path OR \"queryName\" + \"queryLanguage\" for pre-defined tool queries.',\n command: 'codeql',\n subcommand: 'query run',\n inputSchema: {\n query: z.string().optional().describe('Path to the CodeQL query file (.ql) - cannot be used with queryName'),\n queryName: z.string().optional().describe('Name of pre-defined query to run (e.g., \"PrintAST\", \"CallGraphFrom\", \"CallGraphTo\") - requires queryLanguage'),\n queryLanguage: z.string().optional().describe('Programming language for tools queries (e.g., \"javascript\", \"java\", \"python\") - required when using queryName'),\n queryPack: z.string().optional().describe('Query pack path (defaults to server/ql//tools/src/ for tool queries)'),\n sourceFiles: z.string().optional().describe('Comma-separated list of source file paths for PrintAST queries (e.g., \"src/main.js,src/utils.js\" or just \"main.js\")'),\n sourceFunction: z.string().optional().describe('Comma-separated list of source function names for CallGraphFrom queries (e.g., \"main,processData\")'),\n targetFunction: z.string().optional().describe('Comma-separated list of target function names for CallGraphTo queries (e.g., \"helper,validateInput\")'),\n database: createCodeQLSchemas.database(),\n output: createCodeQLSchemas.output(),\n external: z.array(z.string()).optional()\n .describe('External predicate data: predicate=file.csv'),\n timeout: createCodeQLSchemas.timeout(),\n logDir: z.string().optional()\n .describe('Custom directory for query execution logs (overrides CODEQL_QUERY_LOG_DIR environment variable). If not provided, uses CODEQL_QUERY_LOG_DIR or defaults to .tmp/query-logs/'),\n 'evaluator-log': z.string().optional().describe('Path to save evaluator log (deprecated: use logDir instead)'),\n 'evaluator-log-minify': z.boolean().optional()\n .describe('Minimize evaluator log for smaller size'),\n 'evaluator-log-level': z.number().min(1).max(5).optional()\n .describe('Evaluator log verbosity level (1-5, default 5)'),\n 'tuple-counting': z.boolean().optional()\n .describe('Display tuple counts for each evaluation step in evaluator logs'),\n format: z.enum(['sarif-latest', 'sarifv2.1.0', 'csv', 'graphtext', 'dgml', 'dot']).optional()\n .describe('Output format for query results via codeql bqrs interpret. Defaults to sarif-latest for @kind problem/path-problem queries, graphtext for @kind graph queries. Graph formats (graphtext, dgml, dot) only work with @kind graph queries.'),\n interpretedOutput: z.string().optional()\n .describe('Output file for interpreted results (e.g., results.sarif, results.txt). If not provided, defaults based on format: .sarif for SARIF, .txt for graphtext/csv, .dgml for dgml, .dot for dot'),\n evaluationFunction: z.string().optional()\n .describe('[DEPRECATED - use format parameter instead] Built-in function for query results evaluation (e.g., \"mermaid-graph\", \"json-decode\", \"csv-decode\") or path to custom evaluation script'),\n evaluationOutput: z.string().optional()\n .describe('[DEPRECATED - use interpretedOutput parameter instead] Output file for evaluation results'),\n verbose: createCodeQLSchemas.verbose(),\n additionalArgs: createCodeQLSchemas.additionalArgs()\n },\n examples: [\n 'codeql query run --database=mydb --output=results.bqrs MyQuery.ql',\n 'codeql query run --database=mydb --query-name=PrintAST --query-language=javascript --source-files=src/index.js --output=results.bqrs --format=graphtext --interpreted-output=results.txt',\n 'codeql query run --database=mydb --external=data=input.csv --output=results.bqrs MyQuery.ql --format=sarif-latest --interpreted-output=results.sarif',\n 'codeql query run --database=mydb --evaluator-log=eval.log --tuple-counting --evaluator-log-level=5 --output=results.bqrs MyQuery.ql',\n 'codeql query run --database=mydb --query-name=PrintAST --query-language=javascript --source-files=\"main.js,utils.js\" --format=graphtext',\n 'codeql query run --database=mydb --log-dir=/custom/log/path --tuple-counting --output=results.bqrs MyQuery.ql'\n ]\n};", "/**\n * CodeQL quick evaluate tool\n * \n * Inspired by JordyZomer/codeql-mcp repository:\n * - https://github.com/JordyZomer/codeql-mcp/blob/main/server.py\n * - https://github.com/JordyZomer/codeql-mcp/blob/main/codeqlclient.py\n */\n\nimport { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport { z } from 'zod';\nimport { join, resolve } from 'path';\nimport { findClassPosition } from './find-class-position';\nimport { findPredicatePosition } from './find-predicate-position';\nimport { logger } from '../../utils/logger';\nimport { getProjectTmpDir } from '../../utils/temp-dir';\n\nexport interface QuickEvaluateParams {\n file: string;\n db: string;\n symbol: string;\n output_path?: string;\n}\n\n/**\n * Quick evaluate either a class or a predicate in a CodeQL query.\n * This allows debugging a select portion of QL code without running the whole query.\n */\nexport async function quickEvaluate({\n file,\n db: _db,\n symbol,\n output_path\n}: QuickEvaluateParams): Promise {\n try {\n // Try to find as a class first, then as a predicate\n try {\n await findClassPosition(file, symbol);\n } catch {\n try {\n await findPredicatePosition(file, symbol);\n } catch {\n throw new Error(`Symbol '${symbol}' not found as class or predicate in file: ${file}`);\n }\n }\n \n const resolvedOutput = resolve(output_path || join(getProjectTmpDir('quickeval'), 'quickeval.bqrs'));\n \n // For now, return the resolved output path\n // In a full implementation, this would use the CodeQL CLI or query server\n // to perform the actual quick evaluation with the position parameters\n return resolvedOutput;\n } catch (error) {\n throw new Error(`CodeQL evaluation failed: ${error instanceof Error ? error.message : 'Unknown error'}`);\n }\n}\n\n/**\n * Register the quick evaluate tool with the MCP server\n */\nexport function registerQuickEvaluateTool(server: McpServer): void {\n server.tool(\n 'quick_evaluate',\n 'Quick evaluate either a class or a predicate in a CodeQL query for debugging',\n {\n file: z.string().describe('Path to the .ql file containing the symbol'),\n db: z.string().describe('Path to the CodeQL database'),\n symbol: z.string().describe('Name of the class or predicate to evaluate'),\n output_path: z.string().optional().describe('Output path for results (defaults to project-local .tmp/quickeval/)'),\n },\n async ({ file, db, symbol, output_path }) => {\n try {\n const result = await quickEvaluate({ file, db, symbol, output_path });\n return {\n content: [{ type: 'text', text: result }],\n };\n } catch (error) {\n logger.error('Error in quick evaluate:', error);\n return {\n content: [\n {\n type: 'text',\n text: `Error: ${error instanceof Error ? error.message : 'Unknown error'}`,\n },\n ],\n isError: true,\n };\n }\n }\n );\n}", "/**\n * CodeQL register database tool\n * \n * Inspired by JordyZomer/codeql-mcp repository:\n * - https://github.com/JordyZomer/codeql-mcp/blob/main/server.py\n * - https://github.com/JordyZomer/codeql-mcp/blob/main/codeqlclient.py\n */\n\nimport { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport { z } from 'zod';\nimport { access, constants } from 'fs/promises';\nimport { resolve } from 'path';\nimport { logger } from '../../utils/logger';\n\nexport interface DatabaseRegistration {\n uri: string;\n content: {\n sourceArchiveZip: string;\n dbDir: string;\n };\n}\n\n/**\n * Register a CodeQL database given a local path to the database directory.\n * Validates that the database exists and has required structure.\n * Supports both full databases (with src.zip) and test databases (with src/ folder).\n */\nexport async function registerDatabase(dbPath: string): Promise {\n try {\n const resolvedPath = resolve(dbPath);\n \n // Check if database directory exists\n await access(resolvedPath, constants.F_OK);\n \n // Check for codeql-database.yml (required for all CodeQL databases)\n const dbYmlPath = resolve(resolvedPath, 'codeql-database.yml');\n await access(dbYmlPath, constants.F_OK);\n \n // Check if src.zip exists (for full databases) OR src/ directory exists (for test databases)\n const srcZipPath = resolve(resolvedPath, 'src.zip');\n const srcDirPath = resolve(resolvedPath, 'src');\n \n let hasSrcZip = false;\n let hasSrcDir = false;\n \n try {\n await access(srcZipPath, constants.F_OK);\n hasSrcZip = true;\n } catch {\n // src.zip not found, check for src/ directory\n }\n \n if (!hasSrcZip) {\n try {\n await access(srcDirPath, constants.F_OK);\n hasSrcDir = true;\n } catch {\n // src directory not found either\n }\n }\n \n if (!hasSrcZip && !hasSrcDir) {\n throw new Error(`Missing required source archive (src.zip) or source directory (src/) in: ${dbPath}`);\n }\n \n // For now, we just validate and return success message\n // In a full implementation, this would register with a query server\n const sourceType = hasSrcZip ? 'src.zip' : 'src/';\n return `Database registered: ${dbPath} (source: ${sourceType})`;\n } catch (error) {\n if (error instanceof Error) {\n const errorCode = (error as { code?: string }).code;\n if (errorCode === 'ENOENT') {\n if (error.message.includes('codeql-database.yml')) {\n throw new Error(`Missing required codeql-database.yml in: ${dbPath}`);\n }\n throw new Error(`Database path does not exist: ${dbPath}`);\n }\n if (errorCode === 'EACCES') {\n throw new Error(`Database path does not exist: ${dbPath}`);\n }\n }\n throw new Error(`Failed to register database: ${error instanceof Error ? error.message : 'Unknown error'}`);\n }\n}\n\n/**\n * Register the register database tool with the MCP server\n */\nexport function registerRegisterDatabaseTool(server: McpServer): void {\n server.tool(\n 'register_database',\n 'Register a CodeQL database given a local path to the database directory',\n {\n db_path: z.string().describe('Path to the CodeQL database directory'),\n },\n async ({ db_path }) => {\n try {\n const result = await registerDatabase(db_path);\n return {\n content: [{ type: 'text', text: result }],\n };\n } catch (error) {\n logger.error('Error registering database:', error);\n return {\n content: [\n {\n type: 'text',\n text: `Error: ${error instanceof Error ? error.message : 'Unknown error'}`,\n },\n ],\n isError: true,\n };\n }\n }\n );\n}", "/**\n * CodeQL resolve database tool\n */\n\nimport { z } from 'zod';\nimport { CLIToolDefinition, createCodeQLSchemas, defaultCLIResultProcessor } from '../../lib/cli-tool-registry';\n\nexport const codeqlResolveDatabaseTool: CLIToolDefinition = {\n name: 'codeql_resolve_database',\n description: 'Resolve database path and validate database structure',\n command: 'codeql',\n subcommand: 'resolve database',\n inputSchema: {\n database: z.string().describe('Database path to resolve'),\n format: z.enum(['text', 'json', 'betterjson']).optional()\n .describe('Output format for database information'),\n verbose: createCodeQLSchemas.verbose(),\n additionalArgs: createCodeQLSchemas.additionalArgs()\n },\n examples: [\n 'codeql resolve database -- /path/to/database',\n 'codeql resolve database --format=json -- my-database',\n 'codeql resolve database --format=betterjson -- database-dir'\n ],\n resultProcessor: defaultCLIResultProcessor\n};", "/**\n * CodeQL resolve languages tool\n */\n\nimport { z } from 'zod';\nimport { CLIToolDefinition, defaultCLIResultProcessor } from '../../lib/cli-tool-registry';\n\nexport const codeqlResolveLanguagesTool: CLIToolDefinition = {\n name: 'codeql_resolve_languages',\n description: 'List installed CodeQL extractor packs',\n command: 'codeql',\n subcommand: 'resolve languages',\n inputSchema: {\n format: z.enum(['text', 'json', 'betterjson']).optional()\n .describe('Output format for language information'),\n verbose: z.boolean().optional().describe('Enable verbose output'),\n additionalArgs: z.array(z.string()).optional().describe('Additional command-line arguments')\n },\n examples: [\n 'codeql resolve languages --format=text',\n 'codeql resolve languages --format=json',\n 'codeql resolve languages --format=betterjson'\n ],\n resultProcessor: defaultCLIResultProcessor\n};", "/**\n * CodeQL resolve library-path tool\n */\n\nimport { z } from 'zod';\nimport { CLIToolDefinition, defaultCLIResultProcessor } from '../../lib/cli-tool-registry';\n\nexport const codeqlResolveLibraryPathTool: CLIToolDefinition = {\n name: 'codeql_resolve_library-path',\n description: 'Resolve library path for CodeQL queries and libraries',\n command: 'codeql',\n subcommand: 'resolve library-path',\n inputSchema: {\n language: z.string().optional().describe('Programming language to resolve library path for'),\n format: z.enum(['text', 'json', 'betterjson']).optional()\n .describe('Output format for library path information'),\n verbose: z.boolean().optional().describe('Enable verbose output'),\n additionalArgs: z.array(z.string()).optional().describe('Additional command-line arguments')\n },\n examples: [\n 'codeql resolve library-path --language=java',\n 'codeql resolve library-path --format=json --language=python',\n 'codeql resolve library-path --format=betterjson'\n ],\n resultProcessor: defaultCLIResultProcessor\n};", "/**\n * CodeQL resolve metadata tool\n */\n\nimport { z } from 'zod';\nimport { CLIToolDefinition, defaultCLIResultProcessor } from '../../lib/cli-tool-registry';\n\nexport const codeqlResolveMetadataTool: CLIToolDefinition = {\n name: 'codeql_resolve_metadata',\n description: 'Resolve and return the key-value metadata pairs from a CodeQL query source file.',\n command: 'codeql',\n subcommand: 'resolve metadata',\n inputSchema: {\n query: z.string().describe('Query file to resolve metadata for'),\n format: z.enum(['json']).optional()\n .describe('Output format for metadata information (always JSON, optional for future compatibility)'),\n verbose: z.boolean().optional().describe('Enable verbose output'),\n additionalArgs: z.array(z.string()).optional().describe('Additional command-line arguments')\n },\n examples: [\n 'codeql resolve metadata -- relative-path/2/MyQuery.ql',\n 'codeql resolve metadata --format=json -- /absolute-plus/relative-path/2/MyQuery.ql'\n ],\n resultProcessor: defaultCLIResultProcessor\n};", "/**\n * CodeQL resolve qlref tool\n */\n\nimport { z } from 'zod';\nimport { CLIToolDefinition, createCodeQLSchemas, defaultCLIResultProcessor } from '../../lib/cli-tool-registry';\n\nexport const codeqlResolveQlrefTool: CLIToolDefinition = {\n name: 'codeql_resolve_qlref',\n description: 'Resolve qlref files to their corresponding query files',\n command: 'codeql',\n subcommand: 'resolve qlref',\n inputSchema: {\n qlref: z.string().describe('Path to the .qlref file to resolve'),\n format: z.enum(['text', 'json', 'betterjson']).optional()\n .describe('Output format for qlref resolution'),\n verbose: createCodeQLSchemas.verbose(),\n additionalArgs: createCodeQLSchemas.additionalArgs()\n },\n examples: [\n 'codeql resolve qlref -- test/MyQuery.qlref',\n 'codeql resolve qlref --format=json -- test/MyQuery.qlref',\n 'codeql resolve qlref --format=betterjson -- test/MyQuery.qlref'\n ],\n resultProcessor: defaultCLIResultProcessor\n};", "/**\n * CodeQL resolve queries tool\n */\n\nimport { z } from 'zod';\nimport { CLIToolDefinition, createCodeQLSchemas, CLIExecutionResult } from '../../lib/cli-tool-registry';\n\n/**\n * Result processor that only returns stdout for JSON formats\n * This prevents warnings/info from stderr from corrupting JSON output\n */\nconst jsonOnlyResultProcessor = (\n result: CLIExecutionResult,\n params: Record\n): string => {\n if (!result.success) {\n return `Command failed (exit code ${result.exitCode || 'unknown'}):\\n${result.error || result.stderr}`;\n }\n\n // For JSON formats (including bylanguage), only return stdout to avoid mixing warnings with JSON\n if (params.format === 'json' || params.format === 'betterjson' || params.format === 'bylanguage') {\n return result.stdout || '[]';\n }\n\n // For text format, include warnings\n let output = '';\n\n if (result.stdout) {\n output += result.stdout;\n }\n\n if (result.stderr) {\n if (output) {\n output += '\\n\\nWarnings/Info:\\n';\n }\n output += result.stderr;\n }\n\n if (!output) {\n output = 'Command executed successfully (no output)';\n }\n\n return output;\n};\n\nexport const codeqlResolveQueriesTool: CLIToolDefinition = {\n name: 'codeql_resolve_queries',\n description: 'List available CodeQL queries found on the local filesystem',\n command: 'codeql',\n subcommand: 'resolve queries',\n inputSchema: {\n directory: z.string().optional().describe('Directory to search for queries'),\n language: z.string().optional().describe('Filter queries by programming language'),\n format: z.enum(['text', 'json', 'betterjson', 'bylanguage']).optional()\n .describe('Output format for query list'),\n 'additional-packs': z.union([z.string(), z.array(z.string())]).optional()\n .describe('Additional pack directories to search for CodeQL packs'),\n verbose: createCodeQLSchemas.verbose(),\n additionalArgs: createCodeQLSchemas.additionalArgs()\n },\n examples: [\n 'codeql resolve queries',\n 'codeql resolve queries --language=java --format=json',\n 'codeql resolve queries --format=betterjson -- /path/to/queries',\n 'codeql resolve queries --additional-packs=/path/to/packs codeql/java-queries'\n ],\n resultProcessor: jsonOnlyResultProcessor\n};", "/**\n * CodeQL resolve tests tool\n */\n\nimport { z } from 'zod';\nimport { CLIToolDefinition, createCodeQLSchemas, defaultCLIResultProcessor } from '../../lib/cli-tool-registry';\n\nexport const codeqlResolveTestsTool: CLIToolDefinition = {\n name: 'codeql_resolve_tests',\n description: 'Resolve the local filesystem paths of unit tests and/or queries under some base directory',\n command: 'codeql',\n subcommand: 'resolve tests',\n inputSchema: {\n tests: z.array(z.string()).optional().describe('One or more tests (.ql, .qlref files, or test directories)'),\n format: z.enum(['text', 'json']).optional()\n .describe('Output format for test list'),\n verbose: createCodeQLSchemas.verbose(),\n additionalArgs: createCodeQLSchemas.additionalArgs()\n },\n examples: [\n 'codeql resolve tests',\n 'codeql resolve tests --format=json -- test-directory',\n 'codeql resolve tests --format=json -- test1.ql test2.ql'\n ],\n resultProcessor: defaultCLIResultProcessor\n};", "/**\n * CodeQL test accept tool\n */\n\nimport { z } from 'zod';\nimport { CLIToolDefinition, createCodeQLSchemas, defaultCLIResultProcessor } from '../../lib/cli-tool-registry';\n\nexport const codeqlTestAcceptTool: CLIToolDefinition = {\n name: 'codeql_test_accept',\n description: 'Accept new test results as the expected baseline',\n command: 'codeql',\n subcommand: 'test accept',\n inputSchema: {\n tests: z.array(z.string()).describe('One or more tests (.ql, .qlref files, or test directories)'),\n verbose: createCodeQLSchemas.verbose(),\n additionalArgs: createCodeQLSchemas.additionalArgs()\n },\n examples: [\n 'codeql test accept -- languages/java/test/MyQuery/MyQuery.qlref',\n 'codeql test accept -- languages/java/test/MyQuery/',\n 'codeql test accept -- languages/java/src/MyQuery/MyQuery.ql'\n ],\n resultProcessor: defaultCLIResultProcessor\n};", "/**\n * CodeQL test extract tool\n */\n\nimport { z } from 'zod';\nimport { CLIToolDefinition, createCodeQLSchemas, defaultCLIResultProcessor } from '../../lib/cli-tool-registry';\n\nexport const codeqlTestExtractTool: CLIToolDefinition = {\n name: 'codeql_test_extract',\n description: 'Extract test databases for CodeQL query tests',\n command: 'codeql',\n subcommand: 'test extract',\n inputSchema: {\n tests: z.array(z.string()).describe('One or more test directories or files'),\n language: z.string().optional().describe('Programming language for extraction'),\n threads: createCodeQLSchemas.threads(),\n ram: createCodeQLSchemas.ram(),\n verbose: createCodeQLSchemas.verbose(),\n additionalArgs: createCodeQLSchemas.additionalArgs()\n },\n examples: [\n 'codeql test extract -- languages/java/test/MyQuery/',\n 'codeql test extract --language=java --threads=4 -- test-directory',\n 'codeql test extract --threads=2 --ram=2048 -- multiple/test/directories'\n ],\n resultProcessor: defaultCLIResultProcessor\n};", "/**\n * CodeQL test run tool\n */\n\nimport { CLIToolDefinition, createCodeQLSchemas } from '../../lib/cli-tool-registry';\nimport { z } from 'zod';\n\nexport const codeqlTestRunTool: CLIToolDefinition = {\n name: 'codeql_test_run',\n description: 'Run CodeQL query tests',\n command: 'codeql',\n subcommand: 'test run',\n inputSchema: {\n tests: z.array(z.string()).describe('One or more tests (.ql, .qlref files, or test directories)'),\n 'show-extractor-output': z.boolean().optional()\n .describe('Show output from extractors during test execution'),\n 'keep-databases': z.boolean().optional()\n .describe('Keep test databases after running tests'),\n 'learn': z.boolean().optional()\n .describe('Accept current output as expected for failing tests'),\n logDir: z.string().optional()\n .describe('Custom directory for test execution logs (overrides CODEQL_QUERY_LOG_DIR environment variable). If not provided, uses CODEQL_QUERY_LOG_DIR or defaults to .tmp/query-logs/'),\n threads: createCodeQLSchemas.threads(),\n ram: createCodeQLSchemas.ram(),\n verbose: createCodeQLSchemas.verbose(),\n additionalArgs: createCodeQLSchemas.additionalArgs()\n },\n examples: [\n 'codeql test run /path/to/tests',\n 'codeql test run --learn /path/to/failing/tests',\n 'codeql test run --threads=4 --keep-databases /path/to/tests',\n 'codeql test run --log-dir=/custom/log/path /path/to/tests'\n ]\n};", "/**\n * CodeQL tools registration for MCP server\n * Includes both high-level helpers and CLI command wrappers\n */\n\nimport { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport { z } from 'zod';\nimport { validateCodeQLSyntax } from '../lib/validation';\nimport { createCodeQLQuery } from '../lib/query-scaffolding';\nimport { registerCLITool } from '../lib/cli-tool-registry';\nimport {\n codeqlBqrsDecodeTool,\n codeqlBqrsInfoTool,\n codeqlBqrsInterpretTool,\n codeqlDatabaseAnalyzeTool,\n codeqlDatabaseCreateTool,\n codeqlGenerateLogSummaryTool,\n codeqlGenerateQueryHelpTool,\n codeqlPackInstallTool,\n codeqlPackLsTool,\n codeqlQueryCompileTool,\n codeqlQueryFormatTool,\n codeqlQueryRunTool,\n codeqlResolveDatabaseTool,\n codeqlResolveLanguagesTool,\n codeqlResolveLibraryPathTool,\n codeqlResolveMetadataTool,\n codeqlResolveQlrefTool,\n codeqlResolveQueriesTool,\n codeqlResolveTestsTool,\n codeqlTestAcceptTool,\n codeqlTestExtractTool,\n codeqlTestRunTool,\n registerFindClassPositionTool,\n registerFindCodeQLQueryFilesTool,\n registerFindPredicatePositionTool,\n registerListDatabasesTool,\n registerListQueryRunResultsTool,\n registerProfileCodeQLQueryTool,\n registerQuickEvaluateTool,\n registerRegisterDatabaseTool\n} from './codeql';\nimport { logger } from '../utils/logger';\n\n/**\n * Register all CodeQL tools with the MCP server\n */\nexport function registerCodeQLTools(server: McpServer): void {\n // Register high-level helper tools\n \n // Tool: Validate CodeQL Query (heuristic-based)\n server.tool(\n 'validate_codeql_query',\n 'Quick heuristic validation for CodeQL query structure - checks for common patterns like from/where/select clauses and metadata presence. Does NOT compile the query. For authoritative validation with actual compilation, use codeql_lsp_diagnostics instead.',\n {\n query: z.string().describe('The CodeQL query to validate'),\n language: z.string().optional().describe('Target programming language'),\n },\n async ({ query, language }) => {\n try {\n const validation = validateCodeQLSyntax(query, language);\n return {\n content: [{ type: 'text', text: JSON.stringify(validation, null, 2) }],\n };\n } catch (error) {\n logger.error('Error validating CodeQL query:', error);\n return {\n content: [\n {\n type: 'text',\n text: `Error: ${error instanceof Error ? error.message : 'Unknown error'}`,\n },\n ],\n isError: true,\n };\n }\n }\n );\n\n // Tool: Create CodeQL Query\n server.tool(\n 'create_codeql_query',\n 'Create directory structure and files for a new CodeQL query with tests',\n {\n basePath: z.string().describe('Base path where src/ and test/ directories will be created'),\n queryName: z.string().describe('Name of the query (e.g., MySecurityQuery)'),\n language: z.string().describe('Target programming language (e.g., javascript, python, java)'),\n description: z.string().optional().describe('Description of what the query does'),\n queryId: z.string().optional().describe('Custom query ID (defaults to language/example/queryname)'),\n },\n async ({ basePath, queryName, language, description, queryId }) => {\n try {\n const result = createCodeQLQuery({\n basePath,\n queryName,\n language,\n description,\n queryId\n });\n \n const summary = {\n success: true,\n queryPath: result.queryPath,\n testPath: result.testPath,\n qlrefPath: result.qlrefPath,\n testCodePath: result.testCodePath,\n filesCreated: result.filesCreated,\n nextSteps: [\n 'Review and customize the generated query in: ' + result.queryPath,\n 'Add test cases to: ' + result.testCodePath,\n 'Run codeql_pack_install to install dependencies',\n 'Run codeql_test_extract to create test database',\n 'Run codeql_test_run to execute tests'\n ]\n };\n \n return {\n content: [{ type: 'text', text: JSON.stringify(summary, null, 2) }],\n };\n } catch (error) {\n logger.error('Error creating CodeQL query:', error);\n return {\n content: [\n {\n type: 'text',\n text: `Error: ${error instanceof Error ? error.message : 'Unknown error'}`,\n },\n ],\n isError: true,\n };\n }\n }\n );\n\n // Register CLI tools (alphabetically by tool name)\n registerCLITool(server, codeqlBqrsDecodeTool);\n registerCLITool(server, codeqlBqrsInfoTool);\n registerCLITool(server, codeqlBqrsInterpretTool);\n registerCLITool(server, codeqlDatabaseAnalyzeTool);\n registerCLITool(server, codeqlDatabaseCreateTool);\n registerCLITool(server, codeqlGenerateLogSummaryTool);\n registerCLITool(server, codeqlGenerateQueryHelpTool);\n registerCLITool(server, codeqlPackInstallTool);\n registerCLITool(server, codeqlPackLsTool);\n registerCLITool(server, codeqlQueryCompileTool);\n registerCLITool(server, codeqlQueryFormatTool);\n registerCLITool(server, codeqlQueryRunTool);\n registerCLITool(server, codeqlResolveDatabaseTool);\n registerCLITool(server, codeqlResolveLanguagesTool);\n registerCLITool(server, codeqlResolveLibraryPathTool);\n registerCLITool(server, codeqlResolveMetadataTool);\n registerCLITool(server, codeqlResolveQlrefTool);\n registerCLITool(server, codeqlResolveQueriesTool);\n registerCLITool(server, codeqlResolveTestsTool);\n registerCLITool(server, codeqlTestAcceptTool);\n registerCLITool(server, codeqlTestExtractTool);\n registerCLITool(server, codeqlTestRunTool);\n\n // Register new MCP tools (inspired by JordyZomer/codeql-mcp repository)\n registerFindClassPositionTool(server);\n registerFindCodeQLQueryFilesTool(server);\n registerFindPredicatePositionTool(server);\n registerListDatabasesTool(server);\n registerListQueryRunResultsTool(server);\n registerProfileCodeQLQueryTool(server);\n registerQuickEvaluateTool(server);\n registerRegisterDatabaseTool(server);\n}\n", "/**\n * CodeQL query validation utilities\n */\n\nimport { resolve, normalize, isAbsolute, relative } from 'path';\n\nexport interface CodeQLValidationResult {\n isValid: boolean;\n errors: string[];\n warnings: string[];\n suggestions: string[];\n}\n\n/**\n * Validates CodeQL query syntax and structure\n */\nexport function validateCodeQLSyntax(query: string, _language?: string): CodeQLValidationResult {\n const validation: CodeQLValidationResult = {\n isValid: true,\n errors: [],\n warnings: [],\n suggestions: [],\n };\n\n if (!query.trim()) {\n validation.isValid = false;\n validation.errors.push('Query cannot be empty');\n return validation;\n }\n\n if (!query.includes('from') && !query.includes('select')) {\n validation.warnings.push('Query should typically include \"from\" and \"select\" clauses');\n }\n\n if (!query.includes('@name') && !query.includes('@description')) {\n validation.suggestions.push('Consider adding @name and @description metadata');\n }\n\n return validation;\n}\n\n/**\n * Validates a file path to prevent path traversal attacks\n * @param filePath - The file path to validate\n * @param workspaceRoot - Optional workspace root directory. If not provided, allows any absolute path but still blocks traversal attempts\n * @returns The validated absolute path\n * @throws Error if the path contains path traversal sequences\n */\nexport function validateFilePath(filePath: string, workspaceRoot?: string): string {\n // Normalize the path to resolve any . or .. segments\n const normalizedPath = normalize(filePath);\n \n // Check for path traversal attempts in the normalized path\n // This blocks paths like \"../../../etc/passwd\" even after normalization\n if (normalizedPath.includes('..')) {\n throw new Error(`Invalid file path: path traversal detected in \"${filePath}\"`);\n }\n \n // Resolve to absolute path\n const absolutePath = isAbsolute(normalizedPath) \n ? normalizedPath \n : resolve(workspaceRoot || process.cwd(), normalizedPath);\n \n // If workspace root is specified, ensure the resolved path is within it\n if (workspaceRoot) {\n const relativePath = relative(workspaceRoot, absolutePath);\n \n // If relative path starts with .. or is absolute, it's outside workspace\n if (relativePath.startsWith('..') || isAbsolute(relativePath)) {\n throw new Error(`Invalid file path: \"${filePath}\" is outside the workspace root`);\n }\n }\n \n return absolutePath;\n}", "/**\n * CodeQL query scaffolding utilities\n * Handles creation of query directory structure and files\n */\n\nimport * as fs from 'fs';\nimport * as path from 'path';\n\nexport interface QueryScaffoldingOptions {\n basePath: string;\n queryName: string;\n language: string;\n description?: string;\n queryId?: string;\n}\n\nexport interface QueryScaffoldingResult {\n queryPath: string;\n testPath: string;\n qlrefPath: string;\n testCodePath: string;\n filesCreated: string[];\n}\n\n/**\n * Get the file extension for test code based on language\n */\nfunction getLanguageExtension(language: string): string {\n const extensions: Record = {\n javascript: 'js',\n typescript: 'ts',\n python: 'py',\n java: 'java',\n csharp: 'cs',\n cpp: 'cpp',\n go: 'go',\n ruby: 'rb',\n actions: 'yml'\n };\n return extensions[language.toLowerCase()] || 'txt';\n}\n\n/**\n * Generate query template content\n */\nfunction generateQueryTemplate(\n queryName: string,\n language: string,\n description?: string,\n queryId?: string\n): string {\n const desc = description || `${queryName} query`;\n const id = queryId || `${language}/example/${queryName.toLowerCase()}`;\n \n return `/**\n * @id ${id}\n * @name ${queryName}\n * @description ${desc}\n * @kind problem\n * @precision medium\n * @problem.severity warning\n */\n\nimport ${language}\n\n// TODO: Implement query logic\nfrom File f\nwhere f.getBaseName() = \"${queryName}.${getLanguageExtension(language)}\"\nselect f, \"TODO: Add query logic\"\n`;\n}\n\n/**\n * Create the directory structure and files for a new CodeQL query\n */\nexport function createCodeQLQuery(options: QueryScaffoldingOptions): QueryScaffoldingResult {\n const { basePath, queryName, language, description, queryId } = options;\n \n // Resolve absolute paths\n const absoluteBasePath = path.resolve(basePath);\n \n // Define paths with intermediate directory\n const srcDir = path.join(absoluteBasePath, 'src', queryName);\n const testDir = path.join(absoluteBasePath, 'test', queryName);\n \n const queryPath = path.join(srcDir, `${queryName}.ql`);\n const qlrefPath = path.join(testDir, `${queryName}.qlref`);\n const testCodePath = path.join(testDir, `${queryName}.${getLanguageExtension(language)}`);\n \n const filesCreated: string[] = [];\n \n try {\n // Create directories (recursive: true is a no-op if they already exist)\n fs.mkdirSync(srcDir, { recursive: true });\n fs.mkdirSync(testDir, { recursive: true });\n \n // Create files atomically using 'wx' flag (exclusive create) to avoid\n // TOCTOU race between existsSync check and writeFileSync (CWE-367).\n // The 'wx' flag fails with EEXIST if the file already exists.\n try {\n const queryContent = generateQueryTemplate(queryName, language, description, queryId);\n fs.writeFileSync(queryPath, queryContent, { encoding: 'utf8', flag: 'wx' });\n filesCreated.push(queryPath);\n } catch (e: unknown) {\n const err = e as { code?: string };\n if (err.code !== 'EEXIST') throw e;\n }\n \n try {\n const qlrefContent = `${queryName}/${queryName}.ql\\n`;\n fs.writeFileSync(qlrefPath, qlrefContent, { encoding: 'utf8', flag: 'wx' });\n filesCreated.push(qlrefPath);\n } catch (e: unknown) {\n const err = e as { code?: string };\n if (err.code !== 'EEXIST') throw e;\n }\n \n try {\n const testCodeContent = `// Test code for ${queryName}\\n// TODO: Add test cases\\n`;\n fs.writeFileSync(testCodePath, testCodeContent, { encoding: 'utf8', flag: 'wx' });\n filesCreated.push(testCodePath);\n } catch (e: unknown) {\n const err = e as { code?: string };\n if (err.code !== 'EEXIST') throw e;\n }\n \n return {\n queryPath,\n testPath: testDir,\n qlrefPath,\n testCodePath,\n filesCreated\n };\n } catch (error) {\n throw new Error(`Failed to create query scaffolding: ${error instanceof Error ? error.message : 'Unknown error'}`);\n }\n}\n", "/**\n * CodeQL learning resources utilities\n */\n\nimport { readFileSync } from 'fs';\nimport { join, dirname } from 'path';\nimport { fileURLToPath } from 'url';\n\nconst __filename = fileURLToPath(import.meta.url);\nconst __dirname = dirname(__filename);\n\n/**\n * Get the getting started guide content\n */\nexport function getGettingStartedGuide(): string {\n try {\n return readFileSync(join(__dirname, '../resources/getting-started.md'), 'utf-8');\n } catch {\n return 'Getting started guide not available';\n }\n}\n\n/**\n * Get the query basics guide content\n */\nexport function getQueryBasicsGuide(): string {\n try {\n return readFileSync(join(__dirname, '../resources/query-basics.md'), 'utf-8');\n } catch {\n return 'Query basics guide not available';\n }\n}\n\n/**\n * Get the security templates content\n */\nexport function getSecurityTemplates(): string {\n try {\n return readFileSync(join(__dirname, '../resources/security-templates.md'), 'utf-8');\n } catch {\n return 'Security templates not available';\n }\n}\n\n/**\n * Get the performance patterns content\n */\nexport function getPerformancePatterns(): string {\n try {\n return readFileSync(join(__dirname, '../resources/performance-patterns.md'), 'utf-8');\n } catch {\n return 'Performance patterns not available';\n }\n}", "/**\n * CodeQL resources registration for MCP server\n */\n\nimport { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport {\n getGettingStartedGuide,\n getQueryBasicsGuide,\n getSecurityTemplates,\n getPerformancePatterns,\n} from '../lib/resources';\n\n/**\n * Register all CodeQL resources with the MCP server\n */\nexport function registerCodeQLResources(server: McpServer): void {\n // Getting Started Guide\n server.resource(\n 'CodeQL Getting Started',\n 'codeql://learning/getting-started',\n {\n description: 'Comprehensive introduction to CodeQL for beginners',\n mimeType: 'text/markdown',\n },\n async () => {\n return {\n contents: [\n {\n uri: 'codeql://learning/getting-started',\n mimeType: 'text/markdown',\n text: getGettingStartedGuide(),\n },\n ],\n };\n }\n );\n\n // Query Basics Guide\n server.resource(\n 'CodeQL Query Basics',\n 'codeql://learning/query-basics',\n {\n description: 'Learn the fundamentals of writing CodeQL queries',\n mimeType: 'text/markdown',\n },\n async () => {\n return {\n contents: [\n {\n uri: 'codeql://learning/query-basics',\n mimeType: 'text/markdown',\n text: getQueryBasicsGuide(),\n },\n ],\n };\n }\n );\n\n // Security Templates\n server.resource(\n 'CodeQL Security Templates',\n 'codeql://templates/security',\n {\n description: 'Ready-to-use security query templates',\n mimeType: 'text/markdown',\n },\n async () => {\n return {\n contents: [\n {\n uri: 'codeql://templates/security',\n mimeType: 'text/markdown',\n text: getSecurityTemplates(),\n },\n ],\n };\n }\n );\n\n // Performance Patterns\n server.resource(\n 'CodeQL Performance Patterns',\n 'codeql://patterns/performance',\n {\n description: 'Best practices for writing efficient CodeQL queries',\n mimeType: 'text/markdown',\n },\n async () => {\n return {\n contents: [\n {\n uri: 'codeql://patterns/performance',\n mimeType: 'text/markdown',\n text: getPerformancePatterns(),\n },\n ],\n };\n }\n );\n}\n", "/**\n * CodeQL LSP Diagnostics tool for MCP server.\n *\n * Provides real-time QL code validation through LSP communication.\n * Renamed from `codeql_language_server_eval` to `codeql_lsp_diagnostics`\n * for consistency with the `codeql_lsp_*` tool naming convention.\n */\n\nimport { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport { z } from 'zod';\nimport { Diagnostic, LanguageServerOptions } from '../../lib/language-server';\nimport { logger } from '../../utils/logger';\nimport { getProjectTmpDir } from '../../utils/temp-dir';\nimport { join } from 'path';\nimport { pathToFileURL } from 'url';\nimport { getInitializedLanguageServer } from './lsp-server-helper';\n\nexport interface LspDiagnosticsParams {\n qlCode: string;\n serverOptions?: LanguageServerOptions;\n workspaceUri?: string;\n}\n\nexport interface LspDiagnosticsResult {\n diagnostics: Diagnostic[];\n formattedOutput: string;\n isValid: boolean;\n summary: {\n errorCount: number;\n hintCount: number;\n infoCount: number;\n warningCount: number;\n };\n}\n\n/**\n * Format diagnostics for human-readable output.\n */\nfunction formatDiagnostics(diagnostics: Diagnostic[]): string {\n if (diagnostics.length === 0) {\n return '\u2705 No issues found in QL code';\n }\n\n const lines: string[] = [];\n lines.push(`Found ${diagnostics.length} issue(s):\\n`);\n\n diagnostics.forEach((diagnostic, index) => {\n const severityIcon = getSeverityIcon(diagnostic.severity);\n const severityName = getSeverityName(diagnostic.severity);\n const location = `Line ${diagnostic.range.start.line + 1}, Column ${diagnostic.range.start.character + 1}`;\n\n lines.push(`${index + 1}. ${severityIcon} ${severityName} at ${location}`);\n lines.push(` ${diagnostic.message}`);\n if (diagnostic.source) {\n lines.push(` Source: ${diagnostic.source}`);\n }\n if (diagnostic.code) {\n lines.push(` Code: ${diagnostic.code}`);\n }\n lines.push('');\n });\n\n return lines.join('\\n');\n}\n\nfunction getSeverityIcon(severity: number): string {\n switch (severity) {\n case 1: return '\u274C'; // Error\n case 2: return '\u26A0\uFE0F'; // Warning\n case 3: return '\u2139\uFE0F'; // Information\n case 4: return '\uD83D\uDCA1'; // Hint\n default: return '\u2753';\n }\n}\n\nfunction getSeverityName(severity: number): string {\n switch (severity) {\n case 1: return 'Error';\n case 2: return 'Warning';\n case 3: return 'Information';\n case 4: return 'Hint';\n default: return 'Unknown';\n }\n}\n\n/**\n * Evaluate QL code using the CodeQL Language Server and return diagnostics.\n */\nexport async function lspDiagnostics({\n qlCode,\n workspaceUri,\n serverOptions = {}\n}: LspDiagnosticsParams): Promise {\n try {\n logger.info('Evaluating QL code via Language Server...');\n\n const languageServer = await getInitializedLanguageServer({\n serverOptions,\n workspaceUri,\n });\n\n // Generate unique URI for this evaluation\n const evalUri = pathToFileURL(join(getProjectTmpDir('lsp-eval'), `eval_${Date.now()}.ql`)).href;\n\n const diagnostics = await languageServer.evaluateQL(qlCode, evalUri);\n\n // Count diagnostics by severity\n const summary = {\n errorCount: diagnostics.filter(d => d.severity === 1).length,\n hintCount: diagnostics.filter(d => d.severity === 4).length,\n infoCount: diagnostics.filter(d => d.severity === 3).length,\n warningCount: diagnostics.filter(d => d.severity === 2).length,\n };\n\n const isValid = summary.errorCount === 0;\n const formattedOutput = formatDiagnostics(diagnostics);\n\n logger.info(`QL evaluation complete. Valid: ${isValid}, Issues: ${diagnostics.length}`);\n\n return {\n diagnostics,\n formattedOutput,\n isValid,\n summary,\n };\n\n } catch (error) {\n logger.error('Error evaluating QL code:', error);\n throw new Error(`QL evaluation failed: ${error instanceof Error ? error.message : 'Unknown error'}`);\n }\n}\n\n/**\n * Shutdown the language server via the server manager.\n */\nexport async function shutdownDiagnosticsServer(): Promise {\n const { getServerManager } = await import('../../lib/server-manager');\n const manager = getServerManager();\n await manager.shutdownServer('language');\n}\n\n/**\n * Register the codeql_lsp_diagnostics tool with the MCP server.\n */\nexport function registerLspDiagnosticsTool(server: McpServer): void {\n server.tool(\n 'codeql_lsp_diagnostics',\n 'Authoritative syntax and semantic validation of CodeQL (QL) code via the CodeQL Language Server. Compiles the query and provides real-time diagnostics with precise error locations. Use this for accurate validation; for quick heuristic checks without compilation, use validate_codeql_query instead. Note: inline ql_code is evaluated as a virtual document and cannot resolve pack imports (e.g. `import javascript`). For validating queries with imports, use codeql_query_compile on the actual file instead.',\n {\n log_level: z.enum(['OFF', 'ERROR', 'WARN', 'INFO', 'DEBUG', 'TRACE', 'ALL']).optional().describe('Language server log level'),\n ql_code: z.string().describe('The CodeQL (QL) code to evaluate for syntax and semantic errors'),\n search_path: z.string().optional().describe('Optional search path for CodeQL libraries'),\n workspace_uri: z.string().optional().describe('Optional workspace URI for context (defaults to ./ql directory)'),\n },\n async ({ ql_code, workspace_uri, search_path, log_level }) => {\n try {\n const serverOptions: LanguageServerOptions = {};\n\n if (search_path) {\n serverOptions.searchPath = search_path;\n }\n if (log_level) {\n serverOptions.loglevel = log_level;\n }\n\n const result = await lspDiagnostics({\n qlCode: ql_code,\n serverOptions,\n workspaceUri: workspace_uri,\n });\n\n // Return structured result\n const responseContent = {\n diagnostics: result.diagnostics.map(d => ({\n code: d.code,\n column: d.range.start.character + 1, // Convert to 1-based column numbers\n line: d.range.start.line + 1, // Convert to 1-based line numbers\n message: d.message,\n severity: getSeverityName(d.severity),\n source: d.source,\n })),\n formattedOutput: result.formattedOutput,\n isValid: result.isValid,\n summary: result.summary,\n };\n\n return {\n content: [\n {\n text: JSON.stringify(responseContent, null, 2),\n type: 'text',\n }\n ],\n };\n\n } catch (error) {\n logger.error('Error in codeql_lsp_diagnostics tool:', error);\n return {\n content: [\n {\n text: `Error: ${error instanceof Error ? error.message : 'Unknown error'}`,\n type: 'text',\n },\n ],\n isError: true,\n };\n }\n }\n );\n\n // NOTE: Cleanup is handled centrally by shutdownServerManager() in\n // codeql-development-mcp-server.ts (setupGracefulShutdown). Registering\n // additional process.on('SIGINT'/'SIGTERM') handlers here would\n // accumulate on repeated calls and is unnecessary.\n}\n", "/**\n * Shared helper for obtaining a running, initialized CodeQL Language Server.\n *\n * Both `lsp-diagnostics.ts` and `lsp-handlers.ts` need to:\n * 1. Build a `LanguageServerConfig` with sensible defaults\n * 2. Obtain a server instance from the `CodeQLServerManager`\n * 3. Resolve a workspace URI (relative \u2192 absolute \u2192 `file://`)\n * 4. Initialize the server with the resolved workspace\n *\n * Centralizing this logic avoids duplication and ensures consistent\n * default behaviour across all LSP tools.\n */\n\nimport { isAbsolute, resolve } from 'path';\nimport { pathToFileURL } from 'url';\n\nimport { CodeQLLanguageServer, LanguageServerOptions } from '../../lib/language-server';\nimport { LanguageServerConfig } from '../../lib/server-config';\nimport { getServerManager } from '../../lib/server-manager';\nimport { logger } from '../../utils/logger';\n\n/**\n * Options accepted by {@link getInitializedLanguageServer}.\n */\nexport interface InitializedServerOptions {\n /** Language-server-level options (loglevel, searchPath, etc.). */\n serverOptions?: LanguageServerOptions;\n /** Workspace URI \u2014 may be a `file://` URI, absolute path, or relative path. */\n workspaceUri?: string;\n}\n\n/**\n * Return a running, initialized `CodeQLLanguageServer`.\n *\n * - Resolves `searchPath` to the bundled `ql` directory when not provided.\n * - Converts relative / bare-directory `workspaceUri` paths to `file://` URIs\n * resolved against `getUserWorkspaceDir()` (respects `CODEQL_MCP_WORKSPACE`).\n * - Falls back to the bundled `ql` directory when no workspace is given.\n * - Delegates lifecycle management to the global `CodeQLServerManager`.\n */\nexport async function getInitializedLanguageServer(\n opts: InitializedServerOptions = {},\n): Promise {\n const { packageRootDir: pkgRoot, getUserWorkspaceDir } = await import('../../utils/package-paths');\n const options = opts.serverOptions ?? {};\n\n const config: LanguageServerConfig = {\n checkErrors: 'ON_CHANGE',\n loglevel: options.loglevel ?? 'WARN',\n searchPath: options.searchPath ?? resolve(pkgRoot, 'ql'),\n synchronous: options.synchronous,\n verbosity: options.verbosity,\n };\n\n const manager = getServerManager();\n const server = await manager.getLanguageServer(config);\n\n // Normalize workspace URI: convert relative / bare directory paths to\n // file:// URIs against getUserWorkspaceDir() (respects CODEQL_MCP_WORKSPACE).\n let effectiveUri = opts.workspaceUri;\n if (effectiveUri && !effectiveUri.startsWith('file://')) {\n const absWorkspace = isAbsolute(effectiveUri)\n ? effectiveUri\n : resolve(getUserWorkspaceDir(), effectiveUri);\n effectiveUri = pathToFileURL(absWorkspace).href;\n }\n effectiveUri = effectiveUri ?? pathToFileURL(resolve(pkgRoot, 'ql')).href;\n\n await server.initialize(effectiveUri);\n logger.debug(`Language server initialized with workspace: ${effectiveUri}`);\n\n return server;\n}\n", "/**\n * CodeQL LSP tool handlers.\n *\n * Bridges MCP tool invocations to LSP requests on the CodeQL Language Server.\n * Each handler acquires a language server via the CodeQLServerManager,\n * opens the requested document, sends the LSP request, and returns the result.\n */\n\nimport { readFile } from 'fs/promises';\nimport { isAbsolute, resolve } from 'path';\nimport { pathToFileURL } from 'url';\n\nimport {\n CompletionItem,\n LSPLocation,\n TextDocumentPositionParams,\n} from '../../lib/language-server';\nimport { logger } from '../../utils/logger';\nimport { getUserWorkspaceDir } from '../../utils/package-paths';\nimport { getInitializedLanguageServer } from './lsp-server-helper';\n\n/**\n * Common parameters for LSP tool invocations.\n */\nexport interface LSPToolParams {\n /** 0-based character offset within the line. */\n character: number;\n /** Optional override for the file content (if not reading from disk). */\n fileContent?: string;\n /**\n * Path to the QL file. May be absolute or relative.\n * Relative paths are resolved against `getUserWorkspaceDir()`\n * (respects the `CODEQL_MCP_WORKSPACE` environment variable).\n */\n filePath: string;\n /** 0-based line number in the document. */\n line: number;\n /** Optional search path for CodeQL libraries. */\n searchPath?: string;\n /** Optional workspace URI for context. */\n workspaceUri?: string;\n}\n\n/**\n * Get a running, initialized language server for the given parameters.\n */\nasync function getInitializedServer(params: LSPToolParams) {\n return getInitializedLanguageServer({\n serverOptions: { searchPath: params.searchPath },\n workspaceUri: params.workspaceUri,\n });\n}\n\n/**\n * Resolve the file path to an absolute path and file:// URI.\n */\nfunction prepareDocumentPosition(\n params: LSPToolParams,\n): { absPath: string; docUri: string } {\n // Resolve relative paths against getUserWorkspaceDir() so that\n // CODEQL_MCP_WORKSPACE is respected and behaviour is consistent across tools.\n const absPath = isAbsolute(params.filePath)\n ? params.filePath\n : resolve(getUserWorkspaceDir(), params.filePath);\n const docUri = pathToFileURL(absPath).href;\n\n return { absPath, docUri };\n}\n\n/**\n * Read file content and open the document in the language server.\n */\nasync function openDocumentForPosition(\n server: Awaited>,\n params: LSPToolParams,\n absPath: string,\n docUri: string,\n): Promise {\n // Read file content from disk or use provided content\n let text: string;\n if (params.fileContent) {\n text = params.fileContent;\n } else {\n try {\n text = await readFile(absPath, 'utf-8');\n } catch (error) {\n throw new Error(`Cannot read file: ${absPath}: ${error instanceof Error ? error.message : error}`);\n }\n }\n\n // Open the document so the language server knows about it\n server.openDocument(docUri, text);\n\n return {\n position: { character: params.character, line: params.line },\n textDocument: { uri: docUri },\n };\n}\n\n/**\n * Get code completions at a position.\n */\nexport async function lspCompletion(params: LSPToolParams): Promise {\n logger.info(`LSP completion at ${params.filePath}:${params.line}:${params.character}`);\n const server = await getInitializedServer(params);\n const { absPath, docUri } = prepareDocumentPosition(params);\n const positionParams = await openDocumentForPosition(server, params, absPath, docUri);\n\n try {\n return await server.getCompletions(positionParams);\n } finally {\n server.closeDocument(docUri);\n }\n}\n\n/**\n * Go to definition of a symbol at a position.\n */\nexport async function lspDefinition(params: LSPToolParams): Promise {\n logger.info(`LSP definition at ${params.filePath}:${params.line}:${params.character}`);\n const server = await getInitializedServer(params);\n const { absPath, docUri } = prepareDocumentPosition(params);\n const positionParams = await openDocumentForPosition(server, params, absPath, docUri);\n\n try {\n return await server.getDefinition(positionParams);\n } finally {\n server.closeDocument(docUri);\n }\n}\n\n/**\n * Find all references to a symbol at a position.\n */\nexport async function lspReferences(params: LSPToolParams): Promise {\n logger.info(`LSP references at ${params.filePath}:${params.line}:${params.character}`);\n const server = await getInitializedServer(params);\n const { absPath, docUri } = prepareDocumentPosition(params);\n const positionParams = await openDocumentForPosition(server, params, absPath, docUri);\n\n try {\n return await server.getReferences({\n ...positionParams,\n context: { includeDeclaration: true },\n });\n } finally {\n server.closeDocument(docUri);\n }\n}\n", "/**\n * CodeQL LSP MCP tool definitions.\n *\n * Registers four LSP-based tools:\n * - codeql_lsp_completion \u2013 code completions at cursor position\n * - codeql_lsp_definition \u2013 go to definition\n * - codeql_lsp_diagnostics \u2013 QL code validation via LSP diagnostics\n * - codeql_lsp_references \u2013 find all references\n */\n\nimport { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport { z } from 'zod';\nimport { registerLspDiagnosticsTool } from './lsp-diagnostics';\nimport {\n lspCompletion,\n lspDefinition,\n lspReferences,\n} from './lsp-handlers';\nimport { logger } from '../../utils/logger';\n\n/**\n * Shared Zod schema for the common LSP tool parameters.\n */\nconst lspParamsSchema = {\n character: z.number().int().min(0).describe('0-based character offset within the line'),\n file_content: z.string().optional().describe('Optional file content override (reads from disk if omitted)'),\n file_path: z.string().describe('Path to the CodeQL (.ql/.qll) file. Relative paths are resolved against the user workspace directory (see CODEQL_MCP_WORKSPACE).'),\n line: z.number().int().min(0).describe('0-based line number in the document'),\n search_path: z.string().optional().describe('Optional search path for CodeQL libraries'),\n workspace_uri: z.string().optional().describe('Optional workspace URI for context (defaults to ./ql directory)'),\n};\n\n/**\n * Helper to build the handler params from the raw MCP tool input.\n */\nfunction toHandlerParams(input: {\n character: number;\n file_content?: string;\n file_path: string;\n line: number;\n search_path?: string;\n workspace_uri?: string;\n}) {\n return {\n character: input.character,\n fileContent: input.file_content,\n filePath: input.file_path,\n line: input.line,\n searchPath: input.search_path,\n workspaceUri: input.workspace_uri,\n };\n}\n\n/**\n * Register all LSP-based tools with the MCP server.\n */\nexport function registerLSPTools(server: McpServer): void {\n // --- codeql_lsp_diagnostics (relocated from codeql_language_server_eval) ---\n registerLspDiagnosticsTool(server);\n\n // --- codeql_lsp_completion ---\n server.tool(\n 'codeql_lsp_completion',\n 'Get code completions at a cursor position in a CodeQL file. Returns completion items with labels, documentation, and insert text. The file must be a .ql or .qll file. IMPORTANT: Set workspace_uri to the pack or workspace root directory for dependency resolution; without it, completions for imported libraries will be empty.',\n lspParamsSchema,\n async (input) => {\n try {\n const items = await lspCompletion(toHandlerParams(input));\n return {\n content: [{\n text: JSON.stringify({\n completionCount: items.length,\n items: items.map((item) => ({\n detail: item.detail,\n documentation: item.documentation,\n insertText: item.insertText,\n kind: item.kind,\n label: item.label,\n })),\n }, null, 2),\n type: 'text' as const,\n }],\n };\n } catch (error) {\n logger.error('codeql_lsp_completion error:', error);\n return {\n content: [{ text: `Error: ${error instanceof Error ? error.message : 'Unknown error'}`, type: 'text' as const }],\n isError: true,\n };\n }\n },\n );\n\n // --- codeql_lsp_definition ---\n server.tool(\n 'codeql_lsp_definition',\n 'Go to the definition of a CodeQL symbol at a given position. Returns one or more file locations where the symbol is defined. Set workspace_uri to the pack root for dependency resolution.',\n lspParamsSchema,\n async (input) => {\n try {\n const locations = await lspDefinition(toHandlerParams(input));\n return {\n content: [{\n text: JSON.stringify({\n definitionCount: locations.length,\n locations: locations.map((loc) => ({\n endCharacter: loc.range.end.character,\n endLine: loc.range.end.line + 1,\n startCharacter: loc.range.start.character,\n startLine: loc.range.start.line + 1,\n uri: loc.uri,\n })),\n }, null, 2),\n type: 'text' as const,\n }],\n };\n } catch (error) {\n logger.error('codeql_lsp_definition error:', error);\n return {\n content: [{ text: `Error: ${error instanceof Error ? error.message : 'Unknown error'}`, type: 'text' as const }],\n isError: true,\n };\n }\n },\n );\n\n // --- codeql_lsp_references ---\n server.tool(\n 'codeql_lsp_references',\n 'Find all references to a CodeQL symbol at a given position. Returns file locations of all usages, including the declaration. Set workspace_uri to the pack root for dependency resolution.',\n lspParamsSchema,\n async (input) => {\n try {\n const locations = await lspReferences(toHandlerParams(input));\n return {\n content: [{\n text: JSON.stringify({\n locations: locations.map((loc) => ({\n endCharacter: loc.range.end.character,\n endLine: loc.range.end.line + 1,\n startCharacter: loc.range.start.character,\n startLine: loc.range.start.line + 1,\n uri: loc.uri,\n })),\n referenceCount: locations.length,\n }, null, 2),\n type: 'text' as const,\n }],\n };\n } catch (error) {\n logger.error('codeql_lsp_references error:', error);\n return {\n content: [{ text: `Error: ${error instanceof Error ? error.message : 'Unknown error'}`, type: 'text' as const }],\n isError: true,\n };\n }\n },\n );\n}\n", "/**\n * Language-specific resources implementation\n * Dynamically loads and serves language-specific AST references and security patterns\n */\n\nimport { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport { readFileSync, existsSync } from 'fs';\nimport { join } from 'path';\nimport { LANGUAGE_RESOURCES } from '../types/language-types';\nimport { workspaceRootDir } from '../utils/package-paths';\nimport { logger } from '../utils/logger';\n\n/**\n * Get the base path for ql resources.\n * Uses the workspace root (monorepo root or package root) so that\n * resource files are found regardless of the server's process.cwd().\n */\nfunction getQLBasePath(): string {\n return workspaceRootDir;\n}\n\n/**\n * Load content from a resource file\n */\nfunction loadResourceContent(relativePath: string): string | null {\n try {\n const fullPath = join(getQLBasePath(), relativePath);\n \n if (!existsSync(fullPath)) {\n logger.warn(`Resource file not found: ${fullPath}`);\n return null;\n }\n \n return readFileSync(fullPath, 'utf-8');\n } catch (error) {\n logger.error(`Error loading resource file ${relativePath}:`, error);\n return null;\n }\n}\n\n/**\n * Register language-specific AST resources\n */\nexport function registerLanguageASTResources(server: McpServer): void {\n for (const langResource of LANGUAGE_RESOURCES) {\n if (!langResource.astFile) continue;\n \n const resourceUri = `codeql://languages/${langResource.language}/ast`;\n \n server.resource(\n `${langResource.language.toUpperCase()} AST Reference`,\n resourceUri,\n {\n description: `CodeQL AST class reference for ${langResource.language} programs`,\n mimeType: 'text/markdown'\n },\n async () => {\n const content = loadResourceContent(langResource.astFile!);\n \n if (!content) {\n return {\n contents: [{\n uri: resourceUri,\n mimeType: 'text/markdown',\n text: `# ${langResource.language.toUpperCase()} AST Reference\\n\\nResource file not found or could not be loaded.`\n }]\n };\n }\n \n return {\n contents: [{\n uri: resourceUri,\n mimeType: 'text/markdown',\n text: content\n }]\n };\n }\n );\n }\n}\n\n/**\n * Register language-specific security pattern resources\n */\nexport function registerLanguageSecurityResources(server: McpServer): void {\n for (const langResource of LANGUAGE_RESOURCES) {\n if (!langResource.securityFile) continue;\n \n const resourceUri = `codeql://languages/${langResource.language}/security`;\n \n server.resource(\n `${langResource.language.toUpperCase()} Security Patterns`,\n resourceUri,\n {\n description: `CodeQL security query patterns and framework modeling for ${langResource.language}`,\n mimeType: 'text/markdown'\n },\n async () => {\n const content = loadResourceContent(langResource.securityFile!);\n \n if (!content) {\n return {\n contents: [{\n uri: resourceUri,\n mimeType: 'text/markdown',\n text: `# ${langResource.language.toUpperCase()} Security Patterns\\n\\nResource file not found or could not be loaded.`\n }]\n };\n }\n \n return {\n contents: [{\n uri: resourceUri,\n mimeType: 'text/markdown',\n text: content\n }]\n };\n }\n );\n }\n}\n\n/**\n * Register additional language-specific resources (like Go's dataflow patterns)\n */\nexport function registerLanguageAdditionalResources(server: McpServer): void {\n for (const langResource of LANGUAGE_RESOURCES) {\n if (!langResource.additionalFiles) continue;\n \n for (const [resourceType, filePath] of Object.entries(langResource.additionalFiles)) {\n const resourceUri = `codeql://languages/${langResource.language}/${resourceType}`;\n \n server.resource(\n `${langResource.language.toUpperCase()} ${resourceType.replace('-', ' ').replace(/\\b\\w/g, l => l.toUpperCase())}`,\n resourceUri,\n {\n description: `CodeQL ${resourceType.replace('-', ' ')} guide for ${langResource.language}`,\n mimeType: 'text/markdown'\n },\n async () => {\n const content = loadResourceContent(filePath);\n \n if (!content) {\n return {\n contents: [{\n uri: resourceUri,\n mimeType: 'text/markdown',\n text: `# ${langResource.language.toUpperCase()} ${resourceType.replace('-', ' ').replace(/\\b\\w/g, l => l.toUpperCase())}\\n\\nResource file not found or could not be loaded.`\n }]\n };\n }\n \n return {\n contents: [{\n uri: resourceUri,\n mimeType: 'text/markdown',\n text: content\n }]\n };\n }\n );\n }\n }\n}\n\n/**\n * Register all language-specific resources\n */\nexport function registerLanguageResources(server: McpServer): void {\n logger.info('Registering language-specific resources...');\n \n // Register AST references for all languages\n registerLanguageASTResources(server);\n \n // Register security patterns for languages that have them\n registerLanguageSecurityResources(server);\n \n // Register additional resources (like Go's dataflow patterns)\n registerLanguageAdditionalResources(server);\n \n logger.info(`Registered resources for ${LANGUAGE_RESOURCES.length} languages`);\n}", "/**\n * Type definitions and constants for language-specific resources\n */\n\n// Language mappings to resource files\nexport interface LanguageResource {\n language: string;\n astFile?: string;\n securityFile?: string;\n additionalFiles?: Record;\n}\n\nexport const LANGUAGE_RESOURCES: LanguageResource[] = [\n {\n language: 'actions',\n astFile: 'ql/languages/actions/tools/dev/actions_ast.prompt.md'\n },\n {\n language: 'cpp',\n astFile: 'ql/languages/cpp/tools/dev/cpp_ast.prompt.md',\n securityFile: 'ql/languages/cpp/tools/dev/cpp_security_query_guide.prompt.md'\n },\n {\n language: 'csharp',\n astFile: 'ql/languages/csharp/tools/dev/csharp_ast.prompt.md',\n securityFile: 'ql/languages/csharp/tools/dev/csharp_security_query_guide.prompt.md'\n },\n {\n language: 'go',\n astFile: 'ql/languages/go/tools/dev/go_ast.prompt.md',\n securityFile: 'ql/languages/go/tools/dev/go_security_query_guide.prompt.md',\n additionalFiles: {\n 'dataflow': 'ql/languages/go/tools/dev/go_dataflow.prompt.md',\n 'library-modeling': 'ql/languages/go/tools/dev/go_library_modeling.prompt.md',\n 'basic-queries': 'ql/languages/go/tools/dev/go_basic_queries.prompt.md'\n }\n },\n {\n language: 'java',\n astFile: 'ql/languages/java/tools/dev/java_ast.prompt.md'\n },\n {\n language: 'javascript',\n astFile: 'ql/languages/javascript/tools/dev/javascript_ast.prompt.md',\n securityFile: 'ql/languages/javascript/tools/dev/javascript_security_query_guide.prompt.md'\n },\n {\n language: 'python',\n astFile: 'ql/languages/python/tools/dev/python_ast.prompt.md',\n securityFile: 'ql/languages/python/tools/dev/python_security_query_guide.prompt.md'\n },\n {\n language: 'ql',\n astFile: 'ql/languages/ql/tools/dev/ql_ast.prompt.md'\n },\n {\n language: 'ruby',\n astFile: 'ql/languages/ruby/tools/dev/ruby_ast.prompt.md'\n }\n];", "/**\n * MCP Server workflow prompts for CodeQL development\n *\n * All prompt content is loaded from .prompt.md files in this directory.\n * This file only handles prompt registration and parameter processing.\n */\n\nimport { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport { z } from 'zod';\nimport { basename } from 'path';\nimport { loadPromptTemplate, processPromptTemplate } from './prompt-loader';\nimport { logger } from '../utils/logger';\n\n/** Supported CodeQL languages for tools queries */\nexport const SUPPORTED_LANGUAGES = [\n 'actions',\n 'cpp',\n 'csharp',\n 'go',\n 'java',\n 'javascript',\n 'python',\n 'ruby',\n 'swift'\n] as const;\n\n// \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n// Exported parameter schemas for each workflow prompt.\n//\n// Extracting the schemas makes it easy to unit-test required vs optional\n// validation independently of the MCP server registration.\n//\n// **Convention for VS Code UX consistency**:\n// Every prompt MUST expose at least one parameter \u2013 even if all parameters\n// are optional \u2013 so that VS Code always displays the parameter input dialog\n// and allows the user to customize the prompt before Copilot Chat processes\n// it. The `description` field on each Zod schema member doubles as the\n// placeholder text shown in the VS Code input box.\n// \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n/**\n * Schema for test_driven_development prompt parameters.\n *\n * - `language` is **required** \u2013 the TDD workflow is language-specific.\n * - `queryName` is optional \u2013 defaults to '[QueryName]' if omitted.\n */\nexport const testDrivenDevelopmentSchema = z.object({\n language: z\n .enum(SUPPORTED_LANGUAGES)\n .describe('Programming language for the query'),\n queryName: z\n .string()\n .optional()\n .describe('Name of the query to develop'),\n});\n\n/**\n * Schema for tools_query_workflow prompt parameters.\n *\n * - `language` and `database` are **required**.\n * - `sourceFiles`, `sourceFunction`, `targetFunction` are optional context.\n */\nexport const toolsQueryWorkflowSchema = z.object({\n database: z\n .string()\n .describe('Path to the CodeQL database'),\n language: z\n .enum(SUPPORTED_LANGUAGES)\n .describe('Programming language for the tools queries'),\n sourceFiles: z\n .string()\n .optional()\n .describe('Comma-separated source file names for PrintAST (e.g., \"main.js,utils.js\")'),\n sourceFunction: z\n .string()\n .optional()\n .describe('Function name for PrintCFG or CallGraphFrom (e.g., \"processData\")'),\n targetFunction: z\n .string()\n .optional()\n .describe('Function name for CallGraphTo (e.g., \"validate\")'),\n});\n\n/**\n * Schema for workshop_creation_workflow prompt parameters.\n * Uses z.coerce.number() for numStages to handle string inputs from VSCode slash commands.\n *\n * - `queryPath` and `language` are **required**.\n * - `workshopName` and `numStages` are optional.\n */\nexport const workshopCreationWorkflowSchema = z.object({\n queryPath: z\n .string()\n .describe('Path to the production-grade CodeQL query (.ql or .qlref)'),\n language: z\n .enum(SUPPORTED_LANGUAGES)\n .describe('Programming language of the query'),\n workshopName: z\n .string()\n .optional()\n .describe('Name for the workshop directory'),\n numStages: z\n .coerce.number()\n .optional()\n .describe('Number of incremental stages (default: 4-8)'),\n});\n\n/**\n * Schema for ql_tdd_basic prompt parameters.\n *\n * All parameters are optional \u2013 but at least one should be present so the\n * VS Code quick-pick dialog appears.\n */\nexport const qlTddBasicSchema = z.object({\n language: z\n .enum(SUPPORTED_LANGUAGES)\n .optional()\n .describe('Programming language for the query (optional)'),\n queryName: z\n .string()\n .optional()\n .describe('Name of the query to develop'),\n});\n\n/**\n * Schema for ql_tdd_advanced prompt parameters.\n *\n * All parameters are optional.\n */\nexport const qlTddAdvancedSchema = z.object({\n database: z\n .string()\n .optional()\n .describe('Path to the CodeQL database for analysis'),\n language: z\n .enum(SUPPORTED_LANGUAGES)\n .optional()\n .describe('Programming language for the query (optional)'),\n queryName: z\n .string()\n .optional()\n .describe('Name of the query to develop'),\n});\n\n/**\n * Schema for sarif_rank_false_positives / sarif_rank_true_positives.\n *\n * Both parameters are optional.\n */\nexport const sarifRankSchema = z.object({\n queryId: z\n .string()\n .optional()\n .describe('CodeQL query/rule identifier'),\n sarifPath: z\n .string()\n .optional()\n .describe('Path to the SARIF file to analyze'),\n});\n\n/**\n * Schema for explain_codeql_query prompt parameters.\n *\n * - `queryPath` and `language` are **required**.\n * - `databasePath` is optional.\n */\nexport const explainCodeqlQuerySchema = z.object({\n databasePath: z\n .string()\n .optional()\n .describe('Optional path to a real CodeQL database for profiling'),\n language: z\n .enum(SUPPORTED_LANGUAGES)\n .describe('Programming language of the query'),\n queryPath: z\n .string()\n .describe('Path to the CodeQL query file (.ql or .qlref)'),\n});\n\n/**\n * Schema for document_codeql_query prompt parameters.\n *\n * - `queryPath` and `language` are **required**.\n */\nexport const documentCodeqlQuerySchema = z.object({\n language: z\n .enum(SUPPORTED_LANGUAGES)\n .describe('Programming language of the query'),\n queryPath: z\n .string()\n .describe('Path to the CodeQL query file (.ql or .qlref)'),\n});\n\n/**\n * Schema for ql_lsp_iterative_development prompt parameters.\n *\n * All parameters are optional.\n */\nexport const qlLspIterativeDevelopmentSchema = z.object({\n language: z\n .enum(SUPPORTED_LANGUAGES)\n .optional()\n .describe('Programming language for the query'),\n queryPath: z\n .string()\n .optional()\n .describe('Path to the query file being developed'),\n workspaceUri: z\n .string()\n .optional()\n .describe('Workspace URI for LSP dependency resolution'),\n});\n\n// \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n// Prompt names (exported for testing)\n// \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n/** Names of every workflow prompt registered with the MCP server. */\nexport const WORKFLOW_PROMPT_NAMES = [\n 'document_codeql_query',\n 'explain_codeql_query',\n 'ql_lsp_iterative_development',\n 'ql_tdd_advanced',\n 'ql_tdd_basic',\n 'sarif_rank_false_positives',\n 'sarif_rank_true_positives',\n 'test_driven_development',\n 'tools_query_workflow',\n 'workshop_creation_workflow',\n] as const;\n\n/**\n * Register MCP workflow prompts\n *\n * Each prompt loads its content from a corresponding .prompt.md file\n * and processes any parameter substitutions.\n *\n * **UX note**: Every prompt schema is passed to `server.prompt()` so that\n * VS Code always displays the parameter-input quick-pick before the prompt\n * is sent to Copilot Chat. This lets users review and customise the values.\n */\nexport function registerWorkflowPrompts(server: McpServer): void {\n // Test-Driven Development Prompt\n server.prompt(\n 'test_driven_development',\n 'Test-driven development workflow for CodeQL queries using MCP tools',\n testDrivenDevelopmentSchema.shape,\n async ({ language, queryName }) => {\n const template = loadPromptTemplate('ql-tdd-basic.prompt.md');\n const content = processPromptTemplate(template, {\n language,\n queryName: queryName || '[QueryName]'\n });\n\n return {\n messages: [\n {\n role: 'user',\n content: {\n type: 'text',\n text: `## Context\\n\\n- **Language**: ${language}\\n${queryName ? `- **Query Name**: ${queryName}\\n` : ''}\\n${content}`\n }\n }\n ]\n };\n }\n );\n\n // Tools Query Workflow Prompt\n server.prompt(\n 'tools_query_workflow',\n 'Guide for using built-in tools queries (PrintAST, PrintCFG, CallGraphFrom, CallGraphTo) to understand code structure',\n toolsQueryWorkflowSchema.shape,\n async ({\n language,\n database,\n sourceFiles,\n sourceFunction,\n targetFunction\n }) => {\n const template = loadPromptTemplate('tools-query-workflow.prompt.md');\n const content = processPromptTemplate(template, {\n language,\n database\n });\n\n const contextSection = buildToolsQueryContext(\n language,\n database,\n sourceFiles,\n sourceFunction,\n targetFunction\n );\n\n return {\n messages: [\n {\n role: 'user',\n content: {\n type: 'text',\n text: contextSection + content\n }\n }\n ]\n };\n }\n );\n\n // Workshop Creation Workflow Prompt\n server.prompt(\n 'workshop_creation_workflow',\n 'Guide for creating CodeQL query development workshops from production-grade queries',\n workshopCreationWorkflowSchema.shape,\n async ({ queryPath, language, workshopName, numStages }) => {\n const template = loadPromptTemplate('workshop-creation-workflow.prompt.md');\n\n // Derive workshop name from query path if not provided\n const derivedName =\n workshopName ||\n basename(queryPath)\n .replace(/\\.(ql|qlref)$/, '')\n .toLowerCase()\n .replace(/[^a-z0-9]+/g, '-') ||\n 'codeql-workshop';\n\n const contextSection = buildWorkshopContext(\n queryPath,\n language,\n derivedName,\n numStages\n );\n\n return {\n messages: [\n {\n role: 'user',\n content: {\n type: 'text',\n text: contextSection + template\n }\n }\n ]\n };\n }\n );\n\n // TDD Basic Prompt - Test-Driven Development Checklist\n server.prompt(\n 'ql_tdd_basic',\n 'Test-driven CodeQL query development checklist - write tests first, implement query, iterate until tests pass',\n qlTddBasicSchema.shape,\n async ({ language, queryName }) => {\n const template = loadPromptTemplate('ql-tdd-basic.prompt.md');\n\n let contextSection = '## Your Development Context\\n\\n';\n if (language) {\n contextSection += `- **Language**: ${language}\\n`;\n }\n if (queryName) {\n contextSection += `- **Query Name**: ${queryName}\\n`;\n }\n if (language || queryName) {\n contextSection += '\\n';\n }\n\n return {\n messages: [\n {\n role: 'user',\n content: {\n type: 'text',\n text: contextSection + template\n }\n }\n ]\n };\n }\n );\n\n // TDD Advanced Prompt - Advanced Techniques with AST/CFG/CallGraph\n server.prompt(\n 'ql_tdd_advanced',\n 'Advanced test-driven CodeQL development with AST visualization, control flow, and call graph analysis',\n qlTddAdvancedSchema.shape,\n async ({ language, queryName, database }) => {\n const template = loadPromptTemplate('ql-tdd-advanced.prompt.md');\n\n let contextSection = '## Your Development Context\\n\\n';\n if (language) {\n contextSection += `- **Language**: ${language}\\n`;\n }\n if (queryName) {\n contextSection += `- **Query Name**: ${queryName}\\n`;\n }\n if (database) {\n contextSection += `- **Database**: ${database}\\n`;\n }\n if (language || queryName || database) {\n contextSection += '\\n';\n }\n\n return {\n messages: [\n {\n role: 'user',\n content: {\n type: 'text',\n text: contextSection + template\n }\n }\n ]\n };\n }\n );\n\n // SARIF Rank False Positives Prompt\n server.prompt(\n 'sarif_rank_false_positives',\n 'Analyze SARIF results to identify likely false positives in CodeQL query results',\n sarifRankSchema.shape,\n async ({ queryId, sarifPath }) => {\n const template = loadPromptTemplate('sarif-rank-false-positives.prompt.md');\n\n let contextSection = '## Analysis Context\\n\\n';\n if (queryId) {\n contextSection += `- **Query ID**: ${queryId}\\n`;\n }\n if (sarifPath) {\n contextSection += `- **SARIF File**: ${sarifPath}\\n`;\n }\n if (queryId || sarifPath) {\n contextSection += '\\n';\n }\n\n return {\n messages: [\n {\n role: 'user',\n content: {\n type: 'text',\n text: contextSection + template\n }\n }\n ]\n };\n }\n );\n\n // SARIF Rank True Positives Prompt\n server.prompt(\n 'sarif_rank_true_positives',\n 'Analyze SARIF results to identify likely true positives in CodeQL query results',\n sarifRankSchema.shape,\n async ({ queryId, sarifPath }) => {\n const template = loadPromptTemplate('sarif-rank-true-positives.prompt.md');\n\n let contextSection = '## Analysis Context\\n\\n';\n if (queryId) {\n contextSection += `- **Query ID**: ${queryId}\\n`;\n }\n if (sarifPath) {\n contextSection += `- **SARIF File**: ${sarifPath}\\n`;\n }\n if (queryId || sarifPath) {\n contextSection += '\\n';\n }\n\n return {\n messages: [\n {\n role: 'user',\n content: {\n type: 'text',\n text: contextSection + template\n }\n }\n ]\n };\n }\n );\n\n // Explain CodeQL Query Prompt (for workshop learning content)\n server.prompt(\n 'explain_codeql_query',\n 'Generate detailed explanation of a CodeQL query for workshop learning content - uses MCP tools to gather context and produces both verbal explanations and mermaid evaluation diagrams',\n explainCodeqlQuerySchema.shape,\n async ({ queryPath, language, databasePath }) => {\n const template = loadPromptTemplate('explain-codeql-query.prompt.md');\n\n let contextSection = '## Query to Explain\\n\\n';\n contextSection += `- **Query Path**: ${queryPath}\\n`;\n contextSection += `- **Language**: ${language}\\n`;\n if (databasePath) {\n contextSection += `- **Database Path**: ${databasePath}\\n`;\n }\n contextSection += '\\n';\n\n return {\n messages: [\n {\n role: 'user',\n content: {\n type: 'text',\n text: contextSection + template\n }\n }\n ]\n };\n }\n );\n\n // Document CodeQL Query Prompt\n server.prompt(\n 'document_codeql_query',\n 'Create or update documentation for a CodeQL query - generates standardized markdown documentation as a sibling file to the query',\n documentCodeqlQuerySchema.shape,\n async ({ queryPath, language }) => {\n const template = loadPromptTemplate('document-codeql-query.prompt.md');\n\n const contextSection = `## Query to Document\n\n- **Query Path**: ${queryPath}\n- **Language**: ${language}\n\n`;\n\n return {\n messages: [\n {\n role: 'user',\n content: {\n type: 'text',\n text: contextSection + template\n }\n }\n ]\n };\n }\n );\n\n // LSP-powered Iterative Development Prompt\n server.prompt(\n 'ql_lsp_iterative_development',\n 'Iterative CodeQL query development using LSP tools for completion, navigation, and validation',\n qlLspIterativeDevelopmentSchema.shape,\n async ({ language, queryPath, workspaceUri }) => {\n const template = loadPromptTemplate('ql-lsp-iterative-development.prompt.md');\n\n let contextSection = '## Your Development Context\\n\\n';\n if (language) {\n contextSection += `- **Language**: ${language}\\n`;\n }\n if (queryPath) {\n contextSection += `- **Query Path**: ${queryPath}\\n`;\n }\n if (workspaceUri) {\n contextSection += `- **Workspace URI**: ${workspaceUri}\\n`;\n }\n if (language || queryPath || workspaceUri) {\n contextSection += '\\n';\n }\n\n return {\n messages: [\n {\n role: 'user',\n content: {\n type: 'text',\n text: contextSection + template,\n },\n },\n ],\n };\n }\n );\n\n logger.info(`Registered ${WORKFLOW_PROMPT_NAMES.length} workflow prompts`);\n}\n\n/**\n * Build context section for tools query workflow\n */\nexport function buildToolsQueryContext(\n language: string,\n database: string,\n sourceFiles?: string,\n sourceFunction?: string,\n targetFunction?: string\n): string {\n const lines = [\n '## Your Context',\n '',\n `- **Language**: ${language}`,\n `- **Database**: ${database}`\n ];\n\n if (sourceFiles) {\n lines.push(`- **Source Files**: ${sourceFiles}`);\n }\n if (sourceFunction) {\n lines.push(`- **Source Function**: ${sourceFunction}`);\n }\n if (targetFunction) {\n lines.push(`- **Target Function**: ${targetFunction}`);\n }\n\n lines.push('', '## Recommended Next Steps', '');\n\n if (sourceFiles) {\n lines.push(\n `1. Run \\`codeql_query_run\\` with queryName=\"PrintAST\", sourceFiles=\"${sourceFiles}\"`\n );\n } else {\n lines.push('1. Identify source files to analyze with PrintAST');\n }\n\n if (sourceFunction) {\n lines.push(\n `2. Run \\`codeql_query_run\\` with queryName=\"PrintCFG\" or \"CallGraphFrom\", sourceFunction=\"${sourceFunction}\"`\n );\n } else {\n lines.push(\n '2. Identify key functions for CFG or call graph analysis'\n );\n }\n\n if (targetFunction) {\n lines.push(\n `3. Run \\`codeql_query_run\\` with queryName=\"CallGraphTo\", targetFunction=\"${targetFunction}\"`\n );\n } else {\n lines.push('3. Identify target functions to find callers');\n }\n\n lines.push('', '');\n return lines.join('\\n');\n}\n\n/**\n * Build context section for workshop creation workflow\n */\nexport function buildWorkshopContext(\n queryPath: string,\n language: string,\n workshopName: string,\n numStages?: number\n): string {\n return `## Your Workshop Context\n\n- **Target Query**: ${queryPath}\n- **Language**: ${language}\n- **Workshop Name**: ${workshopName}\n- **Suggested Stages**: ${numStages || '4-8 (auto-detect based on query complexity)'}\n\n## Immediate Actions\n\n1. **Locate query files**: Use \\`find_codeql_query_files\\` with queryPath=\"${queryPath}\"\n2. **Understand query for learning content**: Use the \\`explain_codeql_query\\` prompt with queryPath=\"${queryPath}\" and language=\"${language}\"\n3. **Document each workshop stage**: Use the \\`document_codeql_query\\` prompt to create/update documentation for each solution query\n4. **Verify tests pass**: Use \\`codeql_test_run\\` on existing tests\n5. **Run tools queries**: Generate AST/CFG understanding for workshop materials\n\n`;\n}\n", "/**\n * Utility functions for loading prompt template files\n */\n\nimport { readFileSync } from 'fs';\nimport { join, dirname } from 'path';\nimport { fileURLToPath } from 'url';\n\nconst __filename = fileURLToPath(import.meta.url);\nconst __dirname = dirname(__filename);\n\n/**\n * Load a prompt template from a .prompt.md file\n */\nexport function loadPromptTemplate(promptFileName: string): string {\n try {\n const promptPath = join(__dirname, promptFileName);\n return readFileSync(promptPath, 'utf-8');\n } catch (error) {\n return `Prompt template '${promptFileName}' not available: ${error instanceof Error ? error.message : 'Unknown error'}`;\n }\n}\n\n/**\n * Process prompt template by replacing placeholders with actual values\n */\nexport function processPromptTemplate(template: string, variables: Record): string {\n let processed = template;\n \n // Replace variables in the format {{variable}} or {variable}\n for (const [key, value] of Object.entries(variables)) {\n const patterns = [\n new RegExp(`\\\\{\\\\{${key}\\\\}\\\\}`, 'g'),\n new RegExp(`\\\\{${key}\\\\}`, 'g')\n ];\n \n for (const pattern of patterns) {\n processed = processed.replace(pattern, value);\n }\n }\n \n return processed;\n}", "/**\n * Monitoring Tools - MCP tool implementations for session management and reporting\n * Provides the MCP Tool APIs specified in the monitoring specification\n */\n\nimport { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport { z } from 'zod';\nimport { randomUUID } from 'crypto';\nimport { sessionDataManager } from '../lib/session-data-manager';\nimport {\n QueryDevelopmentSession,\n SessionFilter,\n QualityScoreRecord,\n ComparisonReport,\n AggregateReport,\n ExportResult,\n FunctionalTestResult,\n} from '../types/monitoring';\nimport { logger } from '../utils/logger';\n\n/**\n * Register all monitoring and reporting tools with the MCP server\n * Note: These tools are opt-in and disabled by default for end-users.\n * Set enableMonitoringTools: true in monitoring config to enable them.\n */\nexport function registerMonitoringTools(server: McpServer): void {\n const config = sessionDataManager.getConfig();\n \n // Check if monitoring tools are enabled (opt-in, disabled by default)\n if (!config.enableMonitoringTools) {\n logger.info('Monitoring tools are disabled (opt-in). Set enableMonitoringTools: true to enable session_* tools.');\n return;\n }\n\n // Session Management Tools - session_start removed per feedback (auto-creation instead)\n registerSessionEndTool(server);\n registerSessionGetTool(server);\n registerSessionListTool(server);\n registerSessionUpdateStateTool(server);\n\n // Session Analytics Tools\n registerSessionGetCallHistoryTool(server);\n registerSessionGetTestHistoryTool(server);\n registerSessionGetScoreHistoryTool(server);\n registerSessionCalculateCurrentScoreTool(server);\n\n // Batch Operations Tools\n registerSessionsCompareTool(server);\n registerSessionsAggregateTool(server);\n registerSessionsExportTool(server);\n\n // Note: Functional Testing Support Tools are internal only, not exposed as MCP tools\n\n logger.info('Registered monitoring and reporting tools');\n}\n\n/**\n * Session Management Tools\n */\n\n// session_start tool removed - sessions are now auto-created when needed\n// Sessions are automatically created when MCP tools are called with queryPath\n// If explicit session creation is needed, provide sessionId=null and it will auto-create\n\nfunction registerSessionEndTool(server: McpServer): void {\n server.tool(\n 'session_end',\n 'End a query development session with final status',\n {\n sessionId: z.string().describe('ID of the session to end'),\n status: z.enum(['completed', 'failed', 'abandoned']).describe('Final status of the session'),\n },\n async ({ sessionId, status }) => {\n try {\n const session = await sessionDataManager.endSession(sessionId, status);\n \n if (!session) {\n return {\n content: [\n {\n type: 'text',\n text: `Session not found: ${sessionId}`,\n },\n ],\n isError: true,\n };\n }\n\n return {\n content: [\n {\n type: 'text',\n text: JSON.stringify(session, null, 2),\n },\n ],\n };\n } catch (error) {\n logger.error('Error ending session:', error);\n return {\n content: [\n {\n type: 'text',\n text: `Error ending session: ${error instanceof Error ? error.message : 'Unknown error'}`,\n },\n ],\n isError: true,\n };\n }\n }\n );\n}\n\nfunction registerSessionGetTool(server: McpServer): void {\n server.tool(\n 'session_get',\n 'Get complete details of a specific query development session',\n {\n sessionId: z.string().describe('ID of the session to retrieve'),\n },\n async ({ sessionId }) => {\n try {\n const session = await sessionDataManager.getSession(sessionId);\n \n if (!session) {\n return {\n content: [\n {\n type: 'text',\n text: `Session not found: ${sessionId}`,\n },\n ],\n isError: true,\n };\n }\n\n return {\n content: [\n {\n type: 'text',\n text: JSON.stringify(session, null, 2),\n },\n ],\n };\n } catch (error) {\n logger.error('Error getting session:', error);\n return {\n content: [\n {\n type: 'text',\n text: `Error getting session: ${error instanceof Error ? error.message : 'Unknown error'}`,\n },\n ],\n isError: true,\n };\n }\n }\n );\n}\n\nfunction registerSessionListTool(server: McpServer): void {\n server.tool(\n 'session_list',\n 'List query development sessions with optional filtering',\n {\n queryPath: z.string().optional().describe('Filter by query path (partial match)'),\n status: z.string().optional().describe('Filter by session status'),\n dateRange: z.array(z.string()).length(2).optional().describe('Filter by date range [start, end] (ISO timestamps)'),\n language: z.string().optional().describe('Filter by programming language'),\n queryType: z.string().optional().describe('Filter by query type'),\n },\n async ({ queryPath, status, dateRange, language, queryType }) => {\n try {\n const filters: SessionFilter = {};\n if (queryPath) filters.queryPath = queryPath;\n if (status) filters.status = status;\n if (dateRange) filters.dateRange = [dateRange[0], dateRange[1]];\n if (language) filters.language = language;\n if (queryType) filters.queryType = queryType;\n\n const sessions = await sessionDataManager.listSessions(\n Object.keys(filters).length > 0 ? filters : undefined\n );\n\n const sessionList = {\n totalSessions: sessions.length,\n sessions: sessions.map(s => ({\n sessionId: s.sessionId,\n queryPath: s.queryPath,\n language: s.language,\n status: s.status,\n startTime: s.startTime,\n endTime: s.endTime,\n mcpCallsCount: s.mcpCalls.length,\n testExecutionsCount: s.testExecutions.length,\n currentScore: s.qualityScores.length > 0 \n ? s.qualityScores[s.qualityScores.length - 1].overallScore \n : null,\n })),\n };\n\n return {\n content: [\n {\n type: 'text',\n text: JSON.stringify(sessionList, null, 2),\n },\n ],\n recommendations: generateListRecommendations(sessions),\n };\n } catch (error) {\n logger.error('Error listing sessions:', error);\n return {\n content: [\n {\n type: 'text',\n text: `Error listing sessions: ${error instanceof Error ? error.message : 'Unknown error'}`,\n },\n ],\n isError: true,\n };\n }\n }\n );\n}\n\nfunction registerSessionUpdateStateTool(server: McpServer): void {\n server.tool(\n 'session_update_state',\n 'Update the current state of a query development session',\n {\n sessionId: z.string().describe('ID of the session to update'),\n filesPresent: z.array(z.string()).optional().describe('List of files present in the query development'),\n compilationStatus: z.enum(['unknown', 'success', 'failed']).optional().describe('Current compilation status'),\n testStatus: z.enum(['unknown', 'passing', 'failing', 'no_tests']).optional().describe('Current test status'),\n documentationStatus: z.enum(['unknown', 'present', 'missing', 'incomplete']).optional().describe('Documentation status'),\n },\n async ({ sessionId, filesPresent, compilationStatus, testStatus, documentationStatus }) => {\n try {\n const stateUpdate: Record = {};\n if (filesPresent !== undefined) stateUpdate.filesPresent = filesPresent;\n if (compilationStatus !== undefined) stateUpdate.compilationStatus = compilationStatus;\n if (testStatus !== undefined) stateUpdate.testStatus = testStatus;\n if (documentationStatus !== undefined) stateUpdate.documentationStatus = documentationStatus;\n\n const session = await sessionDataManager.updateSessionState(sessionId, stateUpdate);\n \n if (!session) {\n return {\n content: [\n {\n type: 'text',\n text: `Session not found: ${sessionId}`,\n },\n ],\n isError: true,\n };\n }\n\n return {\n content: [\n {\n type: 'text',\n text: JSON.stringify(session, null, 2),\n },\n ],\n recommendations: generateRecommendations(session, 'session_update_state'),\n };\n } catch (error) {\n logger.error('Error updating session state:', error);\n return {\n content: [\n {\n type: 'text',\n text: `Error updating session state: ${error instanceof Error ? error.message : 'Unknown error'}`,\n },\n ],\n isError: true,\n };\n }\n }\n );\n}\n\n/**\n * Session Analytics Tools\n */\n\nfunction registerSessionGetCallHistoryTool(server: McpServer): void {\n server.tool(\n 'session_get_call_history',\n 'Get MCP call history for a specific session',\n {\n sessionId: z.string().describe('ID of the session'),\n limit: z.number().optional().describe('Maximum number of calls to return (most recent first)'),\n },\n async ({ sessionId, limit }) => {\n try {\n const session = await sessionDataManager.getSession(sessionId);\n \n if (!session) {\n return {\n content: [\n {\n type: 'text',\n text: `Session not found: ${sessionId}`,\n },\n ],\n isError: true,\n };\n }\n\n let calls = [...session.mcpCalls].reverse(); // Most recent first\n if (limit && limit > 0) {\n calls = calls.slice(0, limit);\n }\n\n return {\n content: [\n {\n type: 'text',\n text: JSON.stringify({\n sessionId,\n totalCalls: session.mcpCalls.length,\n callHistory: calls,\n }, null, 2),\n },\n ],\n };\n } catch (error) {\n logger.error('Error getting call history:', error);\n return {\n content: [\n {\n type: 'text',\n text: `Error getting call history: ${error instanceof Error ? error.message : 'Unknown error'}`,\n },\n ],\n isError: true,\n };\n }\n }\n );\n}\n\nfunction registerSessionGetTestHistoryTool(server: McpServer): void {\n server.tool(\n 'session_get_test_history',\n 'Get test execution history for a specific session',\n {\n sessionId: z.string().describe('ID of the session'),\n limit: z.number().optional().describe('Maximum number of test executions to return (most recent first)'),\n },\n async ({ sessionId, limit }) => {\n try {\n const session = await sessionDataManager.getSession(sessionId);\n \n if (!session) {\n return {\n content: [\n {\n type: 'text',\n text: `Session not found: ${sessionId}`,\n },\n ],\n isError: true,\n };\n }\n\n let tests = [...session.testExecutions].reverse(); // Most recent first\n if (limit && limit > 0) {\n tests = tests.slice(0, limit);\n }\n\n return {\n content: [\n {\n type: 'text',\n text: JSON.stringify({\n sessionId,\n totalTests: session.testExecutions.length,\n testHistory: tests,\n }, null, 2),\n },\n ],\n };\n } catch (error) {\n logger.error('Error getting test history:', error);\n return {\n content: [\n {\n type: 'text',\n text: `Error getting test history: ${error instanceof Error ? error.message : 'Unknown error'}`,\n },\n ],\n isError: true,\n };\n }\n }\n );\n}\n\nfunction registerSessionGetScoreHistoryTool(server: McpServer): void {\n server.tool(\n 'session_get_score_history',\n 'Get quality score history for a specific session',\n {\n sessionId: z.string().describe('ID of the session'),\n limit: z.number().optional().describe('Maximum number of scores to return (most recent first)'),\n },\n async ({ sessionId, limit }) => {\n try {\n const session = await sessionDataManager.getSession(sessionId);\n \n if (!session) {\n return {\n content: [\n {\n type: 'text',\n text: `Session not found: ${sessionId}`,\n },\n ],\n isError: true,\n };\n }\n\n let scores = [...session.qualityScores].reverse(); // Most recent first\n if (limit && limit > 0) {\n scores = scores.slice(0, limit);\n }\n\n return {\n content: [\n {\n type: 'text',\n text: JSON.stringify({\n sessionId,\n totalScores: session.qualityScores.length,\n scoreHistory: scores,\n }, null, 2),\n },\n ],\n };\n } catch (error) {\n logger.error('Error getting score history:', error);\n return {\n content: [\n {\n type: 'text',\n text: `Error getting score history: ${error instanceof Error ? error.message : 'Unknown error'}`,\n },\n ],\n isError: true,\n };\n }\n }\n );\n}\n\nfunction registerSessionCalculateCurrentScoreTool(server: McpServer): void {\n server.tool(\n 'session_calculate_current_score',\n 'Calculate current quality score for a session based on its state',\n {\n sessionId: z.string().describe('ID of the session'),\n },\n async ({ sessionId }) => {\n try {\n const session = await sessionDataManager.getSession(sessionId);\n \n if (!session) {\n return {\n content: [\n {\n type: 'text',\n text: `Session not found: ${sessionId}`,\n },\n ],\n isError: true,\n };\n }\n\n // Calculate quality score based on current state\n const scoreRecord = calculateQualityScore(session);\n \n // Add the score to the session\n await sessionDataManager.addQualityScore(sessionId, scoreRecord);\n \n // Get updated session with new score\n const updatedSession = await sessionDataManager.getSession(sessionId);\n\n return {\n content: [\n {\n type: 'text',\n text: JSON.stringify(scoreRecord, null, 2),\n },\n ],\n recommendations: generateRecommendations(updatedSession, 'session_calculate_current_score'),\n };\n } catch (error) {\n logger.error('Error calculating current score:', error);\n return {\n content: [\n {\n type: 'text',\n text: `Error calculating current score: ${error instanceof Error ? error.message : 'Unknown error'}`,\n },\n ],\n isError: true,\n };\n }\n }\n );\n}\n\n/**\n * Batch Operations Tools\n */\n\nfunction registerSessionsCompareTool(server: McpServer): void {\n server.tool(\n 'sessions_compare',\n 'Compare multiple query development sessions across specified dimensions',\n {\n sessionIds: z.array(z.string()).describe('Array of session IDs to compare'),\n dimensions: z.array(z.string()).optional().describe('Specific dimensions to compare (default: all)'),\n },\n async ({ sessionIds, dimensions }) => {\n try {\n const sessions = await Promise.all(\n sessionIds.map(id => sessionDataManager.getSession(id))\n );\n\n const validSessions = sessions.filter(s => s !== null) as QueryDevelopmentSession[];\n \n if (validSessions.length === 0) {\n return {\n content: [\n {\n type: 'text',\n text: 'No valid sessions found for comparison',\n },\n ],\n isError: true,\n };\n }\n\n const comparison = await compareSessions(validSessions, dimensions);\n\n return {\n content: [\n {\n type: 'text',\n text: JSON.stringify(comparison, null, 2),\n },\n ],\n };\n } catch (error) {\n logger.error('Error comparing sessions:', error);\n return {\n content: [\n {\n type: 'text',\n text: `Error comparing sessions: ${error instanceof Error ? error.message : 'Unknown error'}`,\n },\n ],\n isError: true,\n };\n }\n }\n );\n}\n\nfunction registerSessionsAggregateTool(server: McpServer): void {\n server.tool(\n 'sessions_aggregate',\n 'Generate aggregate insights from multiple sessions based on filters',\n {\n queryPath: z.string().optional().describe('Filter by query path (partial match)'),\n status: z.string().optional().describe('Filter by session status'),\n dateRange: z.array(z.string()).length(2).optional().describe('Filter by date range [start, end] (ISO timestamps)'),\n language: z.string().optional().describe('Filter by programming language'),\n queryType: z.string().optional().describe('Filter by query type'),\n },\n async ({ queryPath, status, dateRange, language, queryType }) => {\n try {\n const filters: SessionFilter = {};\n if (queryPath) filters.queryPath = queryPath;\n if (status) filters.status = status;\n if (dateRange) filters.dateRange = [dateRange[0], dateRange[1]];\n if (language) filters.language = language;\n if (queryType) filters.queryType = queryType;\n\n const sessions = await sessionDataManager.listSessions(\n Object.keys(filters).length > 0 ? filters : undefined\n );\n\n const aggregate = await aggregateSessions(sessions, filters);\n\n return {\n content: [\n {\n type: 'text',\n text: JSON.stringify(aggregate, null, 2),\n },\n ],\n };\n } catch (error) {\n logger.error('Error aggregating sessions:', error);\n return {\n content: [\n {\n type: 'text',\n text: `Error aggregating sessions: ${error instanceof Error ? error.message : 'Unknown error'}`,\n },\n ],\n isError: true,\n };\n }\n }\n );\n}\n\nfunction registerSessionsExportTool(server: McpServer): void {\n server.tool(\n 'sessions_export',\n 'Export session data in specified format for external analysis',\n {\n sessionIds: z.array(z.string()).describe('Array of session IDs to export'),\n format: z.enum(['json', 'html', 'markdown']).optional().default('json').describe('Export format'),\n },\n async ({ sessionIds, format = 'json' }) => {\n try {\n const sessions = await Promise.all(\n sessionIds.map(id => sessionDataManager.getSession(id))\n );\n\n const validSessions = sessions.filter(s => s !== null) as QueryDevelopmentSession[];\n \n if (validSessions.length === 0) {\n return {\n content: [\n {\n type: 'text',\n text: 'No valid sessions found for export',\n },\n ],\n isError: true,\n };\n }\n\n const exportResult = await exportSessions(validSessions, format);\n\n return {\n content: [\n {\n type: 'text',\n text: JSON.stringify(exportResult, null, 2),\n },\n ],\n };\n } catch (error) {\n logger.error('Error exporting sessions:', error);\n return {\n content: [\n {\n type: 'text',\n text: `Error exporting sessions: ${error instanceof Error ? error.message : 'Unknown error'}`,\n },\n ],\n isError: true,\n };\n }\n }\n );\n}\n\n/**\n * Helper Functions\n */\n\n/**\n * Calculate quality score for a session based on current state and history\n */\nfunction calculateQualityScore(session: QueryDevelopmentSession): QualityScoreRecord {\n const timestamp = new Date().toISOString();\n \n // Calculate syntactic correctness (25%)\n const syntacticCorrectness = session.currentState.compilationStatus === 'success' ? 100 :\n session.currentState.compilationStatus === 'failed' ? 0 : 50;\n\n // Calculate test coverage and results (30%)\n const testCoverageResults = session.currentState.testStatus === 'passing' ? 100 :\n session.currentState.testStatus === 'failing' ? 25 :\n session.currentState.testStatus === 'no_tests' ? 0 : 50;\n\n // Calculate documentation quality (20%)\n const documentationQuality = session.currentState.documentationStatus === 'present' ? 100 :\n session.currentState.documentationStatus === 'incomplete' ? 60 :\n session.currentState.documentationStatus === 'missing' ? 0 : 50;\n\n // Calculate functional correctness (25%) - based on successful test runs\n const successfulTests = session.testExecutions.filter(t => t.success && t.type === 'test_run').length;\n const totalTests = session.testExecutions.filter(t => t.type === 'test_run').length;\n const functionalCorrectness = totalTests > 0 ? (successfulTests / totalTests) * 100 : 50;\n\n // Calculate overall score\n const overallScore = Math.round(\n (syntacticCorrectness * 0.25) +\n (testCoverageResults * 0.30) +\n (documentationQuality * 0.20) +\n (functionalCorrectness * 0.25)\n );\n\n // Determine grade\n const grade = overallScore >= 90 ? 'A' :\n overallScore >= 80 ? 'B' :\n overallScore >= 70 ? 'C' :\n overallScore >= 60 ? 'D' : 'F';\n\n // Generate recommendations\n const recommendations: string[] = [];\n if (syntacticCorrectness < 100) {\n recommendations.push('Fix compilation errors to improve syntactic correctness');\n }\n if (testCoverageResults < 70) {\n recommendations.push('Add comprehensive tests and ensure they pass');\n }\n if (documentationQuality < 80) {\n recommendations.push('Add or improve query documentation with examples');\n }\n if (functionalCorrectness < 80) {\n recommendations.push('Improve test pass rate and verify query logic');\n }\n\n return {\n scoreId: randomUUID(),\n timestamp,\n overallScore,\n dimensions: {\n syntacticCorrectness,\n testCoverageResults,\n documentationQuality,\n functionalCorrectness,\n },\n grade,\n recommendations,\n };\n}\n\n/**\n * Compare multiple sessions\n */\nasync function compareSessions(\n sessions: QueryDevelopmentSession[],\n dimensions?: string[]\n): Promise {\n const timestamp = new Date().toISOString();\n const sessionIds = sessions.map(s => s.sessionId);\n \n const results: Record = {\n sessionCount: sessions.length,\n sessionOverview: sessions.map(s => ({\n sessionId: s.sessionId,\n queryPath: s.queryPath,\n status: s.status,\n mcpCallsCount: s.mcpCalls.length,\n duration: s.endTime ? \n new Date(s.endTime).getTime() - new Date(s.startTime).getTime() : \n new Date().getTime() - new Date(s.startTime).getTime(),\n currentScore: s.qualityScores.length > 0 ? \n s.qualityScores[s.qualityScores.length - 1].overallScore : null,\n })),\n };\n\n if (!dimensions || dimensions.includes('quality')) {\n const qualityScores = sessions.map(s => \n s.qualityScores.length > 0 ? s.qualityScores[s.qualityScores.length - 1] : null\n );\n results.qualityComparison = {\n averageScore: qualityScores\n .filter(q => q !== null)\n .reduce((sum, q) => sum + q!.overallScore, 0) / qualityScores.filter(q => q !== null).length,\n scoreRange: {\n min: Math.min(...qualityScores.filter(q => q !== null).map(q => q!.overallScore)),\n max: Math.max(...qualityScores.filter(q => q !== null).map(q => q!.overallScore)),\n },\n };\n }\n\n if (!dimensions || dimensions.includes('activity')) {\n results.activityComparison = {\n totalMCPCalls: sessions.reduce((sum, s) => sum + s.mcpCalls.length, 0),\n averageCallsPerSession: sessions.reduce((sum, s) => sum + s.mcpCalls.length, 0) / sessions.length,\n mostActiveTool: getMostUsedTool(sessions),\n };\n }\n\n return {\n sessionIds,\n dimensions: dimensions || ['all'],\n timestamp,\n results,\n };\n}\n\n/**\n * Aggregate insights from multiple sessions\n */\nasync function aggregateSessions(\n sessions: QueryDevelopmentSession[],\n filters: SessionFilter\n): Promise {\n const timestamp = new Date().toISOString();\n \n const completedSessions = sessions.filter(s => s.status === 'completed');\n const successRate = sessions.length > 0 ? completedSessions.length / sessions.length : 0;\n \n const qualityScores = sessions\n .map(s => s.qualityScores.length > 0 ? s.qualityScores[s.qualityScores.length - 1].overallScore : null)\n .filter(score => score !== null) as number[];\n \n const averageQualityScore = qualityScores.length > 0 ? \n qualityScores.reduce((sum, score) => sum + score, 0) / qualityScores.length : 0;\n\n const commonPatterns = identifyCommonPatterns(sessions);\n const recommendations = generateAggregateRecommendations(sessions);\n\n return {\n filters,\n timestamp,\n totalSessions: sessions.length,\n successRate,\n averageQualityScore,\n commonPatterns,\n recommendations,\n };\n}\n\n/**\n * Export sessions in specified format\n */\nasync function exportSessions(\n sessions: QueryDevelopmentSession[],\n format: 'json' | 'html' | 'markdown'\n): Promise {\n const timestamp = new Date().toISOString();\n const filename = `session-export-${timestamp.replace(/[:.]/g, '-')}.${format}`;\n \n let content: string;\n \n switch (format) {\n case 'json':\n content = JSON.stringify(sessions, null, 2);\n break;\n case 'html':\n content = generateHTMLReport(sessions);\n break;\n case 'markdown':\n content = generateMarkdownReport(sessions);\n break;\n }\n\n return {\n format,\n filename,\n content,\n timestamp,\n };\n}\n\n/**\n * Utility functions\n */\n\nfunction getMostUsedTool(sessions: QueryDevelopmentSession[]): string {\n const toolCounts: Record = {};\n \n sessions.forEach(session => {\n session.mcpCalls.forEach(call => {\n toolCounts[call.toolName] = (toolCounts[call.toolName] || 0) + 1;\n });\n });\n\n return Object.entries(toolCounts)\n .sort(([, a], [, b]) => b - a)[0]?.[0] || 'none';\n}\n\nfunction identifyCommonPatterns(sessions: QueryDevelopmentSession[]): string[] {\n const patterns: string[] = [];\n \n const commonTools = getMostUsedTool(sessions);\n if (commonTools && commonTools !== 'none') {\n patterns.push(`Most commonly used tool: ${commonTools}`);\n }\n\n const completionRate = sessions.filter(s => s.status === 'completed').length / sessions.length;\n if (completionRate > 0.8) {\n patterns.push('High completion rate indicates effective workflow');\n } else if (completionRate < 0.5) {\n patterns.push('Low completion rate suggests workflow issues');\n }\n\n return patterns;\n}\n\nfunction generateAggregateRecommendations(sessions: QueryDevelopmentSession[]): string[] {\n const recommendations: string[] = [];\n \n const failedSessions = sessions.filter(s => s.status === 'failed');\n if (failedSessions.length > sessions.length * 0.3) {\n recommendations.push('High failure rate - consider improving error handling and guidance');\n }\n\n const averageCallsPerSession = sessions.reduce((sum, s) => sum + s.mcpCalls.length, 0) / sessions.length;\n if (averageCallsPerSession > 20) {\n recommendations.push('High number of MCP calls per session - consider workflow optimization');\n }\n\n return recommendations;\n}\n\nfunction generateHTMLReport(sessions: QueryDevelopmentSession[]): string {\n const html = `\n\n\n\n Session Export Report\n \n\n\n

Query Development Sessions Report

\n

Generated: ${new Date().toISOString()}

\n

Total Sessions: ${sessions.length}

\n \n ${sessions.map(session => `\n
\n

Session: ${session.sessionId}

\n

Query Path: ${session.queryPath}

\n

Status: ${session.status}

\n

Language: ${session.language}

\n

Start Time: ${session.startTime}

\n

MCP Calls: ${session.mcpCalls.length}

\n

Test Executions: ${session.testExecutions.length}

\n

Quality Scores: ${session.qualityScores.length}

\n
\n `).join('')}\n\n`;\n \n return html;\n}\n\nfunction generateMarkdownReport(sessions: QueryDevelopmentSession[]): string {\n const md = `# Query Development Sessions Report\n\nGenerated: ${new Date().toISOString()}\nTotal Sessions: ${sessions.length}\n\n## Session Summary\n\n| Session ID | Query Path | Status | Language | MCP Calls | Test Executions |\n|------------|-----------|--------|----------|-----------|-----------------|\n${sessions.map(session => \n `| ${session.sessionId} | ${session.queryPath} | ${session.status} | ${session.language} | ${session.mcpCalls.length} | ${session.testExecutions.length} |`\n).join('\\n')}\n\n## Detailed Sessions\n\n${sessions.map(session => `\n### Session: ${session.sessionId}\n\n- **Query Path:** ${session.queryPath}\n- **Status:** ${session.status}\n- **Language:** ${session.language}\n- **Start Time:** ${session.startTime}\n- **End Time:** ${session.endTime || 'N/A'}\n- **MCP Calls:** ${session.mcpCalls.length}\n- **Test Executions:** ${session.testExecutions.length}\n- **Quality Scores:** ${session.qualityScores.length}\n\n${session.recommendations.length > 0 ? `\n**Current Recommendations:**\n${session.recommendations.map(rec => `- ${rec}`).join('\\n')}\n` : ''}\n`).join('\\n')}`;\n\n return md;\n}\n\nfunction _calculateAverageDuration(sessions: QueryDevelopmentSession[]): number {\n const completedSessions = sessions.filter(s => s.endTime);\n if (completedSessions.length === 0) return 0;\n\n const totalDuration = completedSessions.reduce((sum, session) => {\n return sum + (new Date(session.endTime!).getTime() - new Date(session.startTime).getTime());\n }, 0);\n\n return totalDuration / completedSessions.length;\n}\n\nfunction _identifyFailureReasons(results: FunctionalTestResult[]): string[] {\n const failedResults = results.filter(r => !r.passed);\n const reasons: Record = {};\n\n failedResults.forEach(result => {\n Object.entries(result.criteria).forEach(([criterion, passed]) => {\n if (!passed) {\n reasons[criterion] = (reasons[criterion] || 0) + 1;\n }\n });\n });\n\n return Object.entries(reasons)\n .sort(([, a], [, b]) => b - a)\n .map(([reason, count]) => `${reason}: ${count} sessions`);\n}\n\n/**\n * Generate recommendations for MCP tool responses\n * Returns a map of MCP primitive paths to recommendation reasons\n */\nfunction generateRecommendations(\n session: QueryDevelopmentSession | null,\n currentTool: string\n): Record {\n if (!session) {\n return {};\n }\n\n const recommendations: Record = {};\n\n // Session state-based recommendations\n if (session.currentState.compilationStatus === 'failed') {\n recommendations['codeql_query_format'] = 'Format query to fix potential syntax issues';\n recommendations['codeql_query_compile'] = 'Recompile after fixing syntax errors';\n } else if (session.currentState.compilationStatus === 'success') {\n if (session.currentState.testStatus === 'unknown' || session.currentState.testStatus === 'no_tests') {\n recommendations['codeql_test_run'] = 'Run tests to validate query functionality';\n } else if (session.currentState.testStatus === 'failing') {\n recommendations['session_get_test_history'] = 'Review test failures to identify issues';\n recommendations['codeql_query_compile'] = 'Verify query logic matches test expectations';\n } else if (session.currentState.testStatus === 'passing') {\n recommendations['session_calculate_current_score'] = 'Calculate quality score for completed query';\n }\n }\n\n // Tool-specific follow-up recommendations\n switch (currentTool) {\n case 'session_get':\n if (session.mcpCalls.length === 0) {\n recommendations['codeql_query_compile'] = 'Start development by compiling the query';\n }\n break;\n case 'session_end':\n if (session.status === 'completed') {\n recommendations['sessions_export'] = 'Export session data for analysis';\n }\n break;\n case 'session_calculate_current_score': {\n const latestScore = session.qualityScores[session.qualityScores.length - 1];\n if (latestScore && latestScore.overallScore < 80) {\n if (latestScore.dimensions.syntacticCorrectness < 100) {\n recommendations['codeql_query_format'] = 'Improve syntax and formatting';\n }\n if (latestScore.dimensions.testCoverageResults < 70) {\n recommendations['codeql_test_run'] = 'Improve test coverage and results';\n }\n }\n break;\n }\n case 'session_update_state':\n // Recommend next logical step based on updated state\n if (session.currentState.compilationStatus === 'success' && session.currentState.testStatus === 'unknown') {\n recommendations['codeql_test_run'] = 'Run tests now that compilation is successful';\n }\n break;\n }\n\n return recommendations;\n}\n\n/**\n * Generate recommendations for session list results\n */\nfunction generateListRecommendations(sessions: QueryDevelopmentSession[]): Record {\n const recommendations: Record = {};\n\n const activeSessions = sessions.filter(s => s.status === 'active');\n const completedSessions = sessions.filter(s => s.status === 'completed');\n\n if (activeSessions.length > 0) {\n recommendations['session_get'] = `Review details of ${activeSessions.length} active session(s)`;\n }\n\n if (completedSessions.length > 1) {\n recommendations['sessions_compare'] = 'Compare completed sessions to identify patterns';\n recommendations['sessions_aggregate'] = 'Generate aggregate insights from multiple sessions';\n }\n\n if (sessions.length > 5) {\n recommendations['sessions_export'] = 'Export session data for comprehensive analysis';\n }\n\n return recommendations;\n}", "function checkArgs(adapter, defaultData) {\n if (adapter === undefined)\n throw new Error('lowdb: missing adapter');\n if (defaultData === undefined)\n throw new Error('lowdb: missing default data');\n}\nexport class Low {\n adapter;\n data;\n constructor(adapter, defaultData) {\n checkArgs(adapter, defaultData);\n this.adapter = adapter;\n this.data = defaultData;\n }\n async read() {\n const data = await this.adapter.read();\n if (data)\n this.data = data;\n }\n async write() {\n if (this.data)\n await this.adapter.write(this.data);\n }\n async update(fn) {\n fn(this.data);\n await this.write();\n }\n}\nexport class LowSync {\n adapter;\n data;\n constructor(adapter, defaultData) {\n checkArgs(adapter, defaultData);\n this.adapter = adapter;\n this.data = defaultData;\n }\n read() {\n const data = this.adapter.read();\n if (data)\n this.data = data;\n }\n write() {\n if (this.data)\n this.adapter.write(this.data);\n }\n update(fn) {\n fn(this.data);\n this.write();\n }\n}\n", "import { readFileSync, renameSync, writeFileSync } from 'node:fs';\nimport { readFile } from 'node:fs/promises';\nimport path from 'node:path';\nimport { Writer } from 'steno';\nexport class TextFile {\n #filename;\n #writer;\n constructor(filename) {\n this.#filename = filename;\n this.#writer = new Writer(filename);\n }\n async read() {\n let data;\n try {\n data = await readFile(this.#filename, 'utf-8');\n }\n catch (e) {\n if (e.code === 'ENOENT') {\n return null;\n }\n throw e;\n }\n return data;\n }\n write(str) {\n return this.#writer.write(str);\n }\n}\nexport class TextFileSync {\n #tempFilename;\n #filename;\n constructor(filename) {\n this.#filename = filename;\n const f = filename.toString();\n this.#tempFilename = path.join(path.dirname(f), `.${path.basename(f)}.tmp`);\n }\n read() {\n let data;\n try {\n data = readFileSync(this.#filename, 'utf-8');\n }\n catch (e) {\n if (e.code === 'ENOENT') {\n return null;\n }\n throw e;\n }\n return data;\n }\n write(str) {\n writeFileSync(this.#tempFilename, str);\n renameSync(this.#tempFilename, this.#filename);\n }\n}\n", "import { TextFile, TextFileSync } from './TextFile.js';\nexport class DataFile {\n #adapter;\n #parse;\n #stringify;\n constructor(filename, { parse, stringify, }) {\n this.#adapter = new TextFile(filename);\n this.#parse = parse;\n this.#stringify = stringify;\n }\n async read() {\n const data = await this.#adapter.read();\n if (data === null) {\n return null;\n }\n else {\n return this.#parse(data);\n }\n }\n write(obj) {\n return this.#adapter.write(this.#stringify(obj));\n }\n}\nexport class DataFileSync {\n #adapter;\n #parse;\n #stringify;\n constructor(filename, { parse, stringify, }) {\n this.#adapter = new TextFileSync(filename);\n this.#parse = parse;\n this.#stringify = stringify;\n }\n read() {\n const data = this.#adapter.read();\n if (data === null) {\n return null;\n }\n else {\n return this.#parse(data);\n }\n }\n write(obj) {\n this.#adapter.write(this.#stringify(obj));\n }\n}\n", "import { DataFile, DataFileSync } from './DataFile.js';\nexport class JSONFile extends DataFile {\n constructor(filename) {\n super(filename, {\n parse: JSON.parse,\n stringify: (data) => JSON.stringify(data, null, 2),\n });\n }\n}\nexport class JSONFileSync extends DataFileSync {\n constructor(filename) {\n super(filename, {\n parse: JSON.parse,\n stringify: (data) => JSON.stringify(data, null, 2),\n });\n }\n}\n", "/**\n * Session Data Management\n * Provides unified JSON storage and session lifecycle management using lowdb\n */\n\nimport { Low } from 'lowdb';\nimport { JSONFileSync } from 'lowdb/node';\nimport { mkdirSync, writeFileSync } from 'fs';\nimport { join } from 'path';\nimport { randomUUID } from 'crypto';\nimport { getProjectTmpBase } from '../utils/temp-dir';\nimport {\n QueryDevelopmentSession,\n QueryState,\n MCPCallRecord,\n TestExecutionRecord,\n QualityScoreRecord,\n SessionFilter,\n MonitoringConfig,\n MonitoringConfigSchema,\n} from '../types/monitoring';\nimport { logger } from '../utils/logger';\n\n/**\n * Database schema for lowdb - sessions only\n */\ninterface SessionDatabase {\n sessions: QueryDevelopmentSession[];\n}\n\n/**\n * Session Data Manager - handles all session persistence and lifecycle\n */\nexport class SessionDataManager {\n private db: Low;\n private config: MonitoringConfig;\n private storageDir: string;\n\n constructor(configOverrides: Partial = {}) {\n this.config = MonitoringConfigSchema.parse({\n ...MonitoringConfigSchema.parse({}),\n ...configOverrides,\n });\n\n this.storageDir = this.config.storageLocation;\n this.ensureStorageDirectory();\n\n const adapter = new JSONFileSync(join(this.storageDir, 'sessions.json'));\n this.db = new Low(adapter, {\n sessions: [],\n });\n\n this.initializeDatabase();\n }\n\n /**\n * Initialize the database and ensure it's properly set up\n */\n async initialize(): Promise {\n await this.initializeDatabase();\n }\n\n /**\n * Initialize the database and ensure it's properly set up\n */\n private async initializeDatabase(): Promise {\n try {\n await this.db.read();\n \n logger.info(`Session data manager initialized with ${this.db.data.sessions.length} sessions`);\n } catch (error) {\n logger.error('Failed to initialize session database:', error);\n throw error;\n }\n }\n\n /**\n * Ensure storage directory structure exists\n */\n private ensureStorageDirectory(): void {\n try {\n // mkdirSync with recursive: true is a no-op if directories already exist\n mkdirSync(this.storageDir, { recursive: true });\n\n // Create subdirectories\n const subdirs = ['sessions-archive', 'exports'];\n for (const subdir of subdirs) {\n mkdirSync(join(this.storageDir, subdir), { recursive: true });\n }\n\n // Use 'wx' flag (exclusive create) to atomically create config only\n // if it doesn't exist, avoiding TOCTOU race (CWE-367).\n const configPath = join(this.storageDir, 'config.json');\n try {\n writeFileSync(configPath, JSON.stringify(this.config, null, 2), { flag: 'wx' });\n } catch (e: unknown) {\n const err = e as { code?: string };\n if (err.code !== 'EEXIST') throw e;\n }\n\n logger.debug(`Storage directory initialized: ${this.storageDir}`);\n } catch (error) {\n logger.error('Failed to create storage directory:', error);\n throw error;\n }\n }\n\n /**\n * Start a new query development session\n */\n async startSession(\n queryPath: string,\n language?: string,\n queryType?: string,\n description?: string\n ): Promise {\n const sessionId = randomUUID();\n const startTime = new Date().toISOString();\n\n const session: QueryDevelopmentSession = {\n sessionId,\n queryPath,\n language: language || 'unknown',\n queryType,\n description,\n startTime,\n status: 'active',\n mcpCalls: [],\n testExecutions: [],\n qualityScores: [],\n currentState: {\n filesPresent: [],\n compilationStatus: 'unknown',\n testStatus: 'unknown',\n documentationStatus: 'unknown',\n lastActivity: startTime,\n },\n recommendations: [],\n };\n\n await this.db.read();\n this.db.data.sessions.push(session);\n await this.db.write();\n\n logger.info(`Started new session: ${sessionId} for query: ${queryPath}`);\n return sessionId;\n }\n\n /**\n * End a session with final status\n */\n async endSession(\n sessionId: string,\n status: 'completed' | 'failed' | 'abandoned'\n ): Promise {\n await this.db.read();\n \n const session = this.db.data.sessions.find(s => s.sessionId === sessionId);\n if (!session) {\n logger.warn(`Session not found: ${sessionId}`);\n return null;\n }\n\n session.status = status;\n session.endTime = new Date().toISOString();\n session.currentState.lastActivity = session.endTime;\n\n await this.db.write();\n\n // Archive completed session if enabled\n if (this.config.archiveCompletedSessions && status === 'completed') {\n await this.archiveSession(sessionId);\n }\n\n logger.info(`Ended session: ${sessionId} with status: ${status}`);\n return session;\n }\n\n /**\n * Get a specific session by ID\n */\n async getSession(sessionId: string): Promise {\n await this.db.read();\n const session = this.db.data.sessions.find(s => s.sessionId === sessionId);\n return session || null;\n }\n\n /**\n * List sessions with optional filtering\n */\n async listSessions(filters?: SessionFilter): Promise {\n await this.db.read();\n let sessions = [...this.db.data.sessions];\n\n if (filters) {\n if (filters.queryPath) {\n sessions = sessions.filter(s => s.queryPath.includes(filters.queryPath!));\n }\n if (filters.status) {\n sessions = sessions.filter(s => s.status === filters.status);\n }\n if (filters.language) {\n sessions = sessions.filter(s => s.language === filters.language);\n }\n if (filters.queryType) {\n sessions = sessions.filter(s => s.queryType === filters.queryType);\n }\n if (filters.dateRange) {\n const [start, end] = filters.dateRange;\n sessions = sessions.filter(s => \n s.startTime >= start && s.startTime <= end\n );\n }\n }\n\n return sessions;\n }\n\n /**\n * Update session state\n */\n async updateSessionState(\n sessionId: string,\n stateUpdate: Partial\n ): Promise {\n await this.db.read();\n \n const session = this.db.data.sessions.find(s => s.sessionId === sessionId);\n if (!session) {\n logger.warn(`Session not found: ${sessionId}`);\n return null;\n }\n\n session.currentState = {\n ...session.currentState,\n ...stateUpdate,\n lastActivity: new Date().toISOString(),\n };\n\n await this.db.write();\n return session;\n }\n\n /**\n * Add MCP call record to session\n */\n async addMCPCall(sessionId: string, callRecord: MCPCallRecord): Promise {\n await this.db.read();\n \n const session = this.db.data.sessions.find(s => s.sessionId === sessionId);\n if (!session) {\n logger.warn(`Session not found for MCP call: ${sessionId}`);\n return;\n }\n\n session.mcpCalls.push(callRecord);\n session.currentState.lastActivity = callRecord.timestamp;\n\n // Update next suggested tool if provided\n if (callRecord.nextSuggestedTool) {\n session.nextSuggestedTool = callRecord.nextSuggestedTool;\n }\n\n await this.db.write();\n }\n\n /**\n * Add test execution record to session\n */\n async addTestExecution(sessionId: string, testRecord: TestExecutionRecord): Promise {\n await this.db.read();\n \n const session = this.db.data.sessions.find(s => s.sessionId === sessionId);\n if (!session) {\n logger.warn(`Session not found for test execution: ${sessionId}`);\n return;\n }\n\n session.testExecutions.push(testRecord);\n session.currentState.lastActivity = testRecord.timestamp;\n\n // Update compilation/test status based on execution\n if (testRecord.type === 'compilation') {\n session.currentState.compilationStatus = testRecord.success ? 'success' : 'failed';\n } else if (testRecord.type === 'test_run') {\n session.currentState.testStatus = testRecord.success ? 'passing' : 'failing';\n }\n\n await this.db.write();\n }\n\n /**\n * Add quality score record to session\n */\n async addQualityScore(sessionId: string, scoreRecord: QualityScoreRecord): Promise {\n await this.db.read();\n \n const session = this.db.data.sessions.find(s => s.sessionId === sessionId);\n if (!session) {\n logger.warn(`Session not found for quality score: ${sessionId}`);\n return;\n }\n\n session.qualityScores.push(scoreRecord);\n session.currentState.lastActivity = scoreRecord.timestamp;\n session.recommendations = scoreRecord.recommendations;\n\n await this.db.write();\n }\n\n /**\n * Archive a completed session to monthly file\n */\n private async archiveSession(sessionId: string): Promise {\n try {\n const session = await this.getSession(sessionId);\n if (!session) return;\n\n const date = new Date(session.endTime || session.startTime);\n const monthDir = `${date.getFullYear()}-${String(date.getMonth() + 1).padStart(2, '0')}`;\n const archiveDir = join(this.storageDir, 'sessions-archive', monthDir);\n\n mkdirSync(archiveDir, { recursive: true });\n\n const archiveFile = join(archiveDir, `${sessionId}.json`);\n writeFileSync(archiveFile, JSON.stringify(session, null, 2));\n\n // Remove from active sessions\n await this.db.read();\n this.db.data.sessions = this.db.data.sessions.filter(s => s.sessionId !== sessionId);\n await this.db.write();\n\n logger.info(`Archived session: ${sessionId} to ${archiveFile}`);\n } catch (error) {\n logger.error(`Failed to archive session ${sessionId}:`, error);\n }\n }\n\n /**\n * Get active sessions for a specific query path\n */\n async getActiveSessionsForQuery(queryPath: string): Promise {\n await this.db.read();\n return this.db.data.sessions.filter(s => \n s.queryPath === queryPath && s.status === 'active'\n );\n }\n\n /**\n * Clean up old sessions based on retention policy\n */\n async cleanupOldSessions(): Promise {\n const cutoffDate = new Date();\n cutoffDate.setDate(cutoffDate.getDate() - this.config.retentionDays);\n const cutoffTimestamp = cutoffDate.toISOString();\n\n await this.db.read();\n const sessionsToRemove = this.db.data.sessions.filter(s => \n s.endTime && s.endTime < cutoffTimestamp\n );\n\n if (sessionsToRemove.length > 0) {\n this.db.data.sessions = this.db.data.sessions.filter(s => \n !s.endTime || s.endTime >= cutoffTimestamp\n );\n await this.db.write();\n\n logger.info(`Cleaned up ${sessionsToRemove.length} old sessions`);\n }\n }\n\n /**\n * Get configuration\n */\n getConfig(): MonitoringConfig {\n return this.config;\n }\n\n /**\n * Update configuration\n */\n async updateConfig(configUpdate: Partial): Promise {\n this.config = MonitoringConfigSchema.parse({\n ...this.config,\n ...configUpdate,\n });\n\n // Update config.json file only\n const configPath = join(this.storageDir, 'config.json');\n writeFileSync(configPath, JSON.stringify(this.config, null, 2));\n\n logger.info('Updated monitoring configuration');\n }\n}\n\n/**\n * Parse boolean environment variable\n */\nfunction parseBoolEnv(envVar: string | undefined, defaultValue: boolean): boolean {\n if (envVar === undefined) return defaultValue;\n return envVar.toLowerCase() === 'true' || envVar === '1';\n}\n\n// Export singleton instance with environment variable support\nexport const sessionDataManager = new SessionDataManager({\n storageLocation: process.env.MONITORING_STORAGE_LOCATION || join(getProjectTmpBase(), '.ql-mcp-tracking'),\n enableMonitoringTools: parseBoolEnv(process.env.ENABLE_MONITORING_TOOLS, false),\n});", "import { z } from 'zod';\n\n/**\n * Monitoring and Reporting types for CodeQL Development MCP Server\n * Based on the specification in docs/mcp-server-monitoring-and-reporting.md\n */\n\n/**\n * MCP Call Record - captures individual MCP tool calls\n */\nexport const MCPCallRecordSchema = z.object({\n callId: z.string(),\n timestamp: z.string(), // ISO timestamp\n toolName: z.string(),\n parameters: z.record(z.any()),\n result: z.any(),\n success: z.boolean(),\n duration: z.number(), // milliseconds\n nextSuggestedTool: z.string().optional(),\n});\n\nexport type MCPCallRecord = z.infer;\n\n/**\n * Test Execution Record - captures query compilation and test runs\n */\nexport const TestExecutionRecordSchema = z.object({\n executionId: z.string(),\n timestamp: z.string(),\n type: z.enum(['compilation', 'test_run', 'database_build']),\n success: z.boolean(),\n details: z.record(z.any()),\n metrics: z.object({\n passRate: z.number().optional(),\n coverage: z.number().optional(),\n performance: z.number().optional(),\n }).optional(),\n});\n\nexport type TestExecutionRecord = z.infer;\n\n/**\n * Quality Score Record - multi-dimensional quality assessment\n */\nexport const QualityScoreRecordSchema = z.object({\n scoreId: z.string(),\n timestamp: z.string(),\n overallScore: z.number().min(0).max(100), // 0-100\n dimensions: z.object({\n syntacticCorrectness: z.number().min(0).max(100),\n testCoverageResults: z.number().min(0).max(100),\n documentationQuality: z.number().min(0).max(100),\n functionalCorrectness: z.number().min(0).max(100),\n }),\n grade: z.enum(['A', 'B', 'C', 'D', 'F']),\n recommendations: z.array(z.string()),\n});\n\nexport type QualityScoreRecord = z.infer;\n\n/**\n * Query State - current state of the query development\n */\nexport const QueryStateSchema = z.object({\n filesPresent: z.array(z.string()),\n compilationStatus: z.enum(['unknown', 'success', 'failed']),\n testStatus: z.enum(['unknown', 'passing', 'failing', 'no_tests']),\n documentationStatus: z.enum(['unknown', 'present', 'missing', 'incomplete']),\n lastActivity: z.string(), // ISO timestamp\n});\n\nexport type QueryState = z.infer;\n\n/**\n * Query Development Session - main data structure for tracking\n */\nexport const QueryDevelopmentSessionSchema = z.object({\n // Session Metadata\n sessionId: z.string(),\n queryPath: z.string(),\n language: z.string(),\n queryType: z.string().optional(),\n description: z.string().optional(),\n startTime: z.string(), // ISO timestamp\n endTime: z.string().optional(), // ISO timestamp\n status: z.enum(['active', 'completed', 'failed', 'abandoned']),\n\n // MCP Call History\n mcpCalls: z.array(MCPCallRecordSchema),\n\n // Test Execution Records\n testExecutions: z.array(TestExecutionRecordSchema),\n\n // Quality Metrics\n qualityScores: z.array(QualityScoreRecordSchema),\n\n // Development State\n currentState: QueryStateSchema,\n recommendations: z.array(z.string()),\n nextSuggestedTool: z.string().optional(),\n});\n\nexport type QueryDevelopmentSession = z.infer;\n\n/**\n * Session Filter for listing and searching\n */\nexport const SessionFilterSchema = z.object({\n queryPath: z.string().optional(),\n status: z.string().optional(),\n dateRange: z.tuple([z.string(), z.string()]).optional(),\n language: z.string().optional(),\n queryType: z.string().optional(),\n});\n\nexport type SessionFilter = z.infer;\n\n/**\n * Comparison Report for analyzing multiple sessions\n */\nexport const ComparisonReportSchema = z.object({\n sessionIds: z.array(z.string()),\n dimensions: z.array(z.string()),\n timestamp: z.string(),\n results: z.record(z.any()),\n});\n\nexport type ComparisonReport = z.infer;\n\n/**\n * Aggregate Report for batch analysis\n */\nexport const AggregateReportSchema = z.object({\n filters: SessionFilterSchema,\n timestamp: z.string(),\n totalSessions: z.number(),\n successRate: z.number(),\n averageQualityScore: z.number(),\n commonPatterns: z.array(z.string()),\n recommendations: z.array(z.string()),\n});\n\nexport type AggregateReport = z.infer;\n\n/**\n * Export Result for data export operations\n */\nexport const ExportResultSchema = z.object({\n format: z.enum(['json', 'html', 'markdown']),\n filename: z.string(),\n content: z.string(),\n timestamp: z.string(),\n});\n\nexport type ExportResult = z.infer;\n\n/**\n * Functional Test Result for automated testing\n */\nexport const FunctionalTestResultSchema = z.object({\n sessionId: z.string(),\n queryPath: z.string(),\n passed: z.boolean(),\n criteria: z.record(z.any()),\n details: z.record(z.any()),\n timestamp: z.string(),\n});\n\nexport type FunctionalTestResult = z.infer;\n\n/**\n * Test Report for comprehensive test analysis\n */\nexport const TestReportSchema = z.object({\n sessionIds: z.array(z.string()),\n criteria: z.record(z.any()),\n timestamp: z.string(),\n overallPassRate: z.number(),\n results: z.array(FunctionalTestResultSchema),\n summary: z.record(z.any()),\n});\n\nexport type TestReport = z.infer;\n\n/**\n * Monitoring Configuration\n */\nexport const MonitoringConfigSchema = z.object({\n storageLocation: z.string().default('.ql-mcp-tracking/'),\n autoTrackSessions: z.boolean().default(true),\n retentionDays: z.number().default(90),\n includeCallParameters: z.boolean().default(true),\n includeCallResults: z.boolean().default(true),\n maxActiveSessionsPerQuery: z.number().default(3),\n scoringFrequency: z.enum(['per_call', 'periodic', 'manual']).default('per_call'),\n archiveCompletedSessions: z.boolean().default(true),\n enableRecommendations: z.boolean().default(true),\n enableMonitoringTools: z.boolean().default(false), // Opt-in: session_* tools disabled by default for end-users\n});\n\nexport type MonitoringConfig = z.infer;"], + "mappings": "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", + "names": ["type", "resolve", "setTimeout", "resolve", "setTimeout", "clearTimeout", "join", "resolve", "spawn", "delimiter", "EventEmitter", "clearTimeout", "setTimeout", "resolve", "spawn", "delimiter", "EventEmitter", "clearTimeout", "setTimeout", "resolve", "mkdirSync", "join", "type", "packageRootDir", "resolve", "existsSync", "delimiter", "dirname", "isAbsolute", "binary", "getServerManager", "resolve", "pathToFileURL", "z", "readFileSync", "dirname", "isAbsolute", "mkdirSync", "mkdirSync", "existsSync", "join", "resolve", "timestamp", "writeFileSync", "existsSync", "mkdirSync", "basename", "dirname", "isAbsolute", "join", "resolve", "logger", "executeCodeQLCommand", "basename", "mkdirSync", "dirname", "z", "z", "z", "z", "z", "z", "z", "z", "z", "z", "readFile", "z", "exception", "map", "schema", "type", "extend", "str", "string", "z", "z", "z", "z", "z", "existsSync", "readdirSync", "readFileSync", "statSync", "join", "z", "readFileSync", "existsSync", "readdirSync", "join", "statSync", "z", "existsSync", "readdirSync", "readFileSync", "statSync", "join", "z", "existsSync", "readdirSync", "join", "statSync", "timestamp", "readFileSync", "z", "z", "z", "z", "z", "z", "writeFileSync", "readFileSync", "existsSync", "join", "dirname", "basename", "mkdirSync", "z", "z", "z", "z", "z", "z", "join", "resolve", "resolve", "join", "z", "z", "resolve", "z", "z", "z", "z", "z", "z", "z", "z", "z", "z", "z", "z", "z", "z", "z", "z", "z", "z", "z", "z", "fs", "path", "getLanguageExtension", "z", "readFileSync", "join", "dirname", "fileURLToPath", "__filename", "__dirname", "z", "join", "pathToFileURL", "isAbsolute", "resolve", "pathToFileURL", "getUserWorkspaceDir", "pathToFileURL", "join", "z", "readFile", "isAbsolute", "resolve", "pathToFileURL", "isAbsolute", "resolve", "pathToFileURL", "readFile", "z", "z", "readFileSync", "existsSync", "join", "join", "existsSync", "readFileSync", "z", "basename", "readFileSync", "join", "dirname", "fileURLToPath", "__filename", "__dirname", "z", "basename", "z", "randomUUID", "readFileSync", "writeFileSync", "path", "path", "readFileSync", "str", "writeFileSync", "parse", "mkdirSync", "writeFileSync", "join", "randomUUID", "z", "join", "mkdirSync", "writeFileSync", "randomUUID", "z", "timestamp", "randomUUID", "resolve", "pathToFileURL"] } diff --git a/server/src/lib/cli-executor.ts b/server/src/lib/cli-executor.ts index 696ccf43..4a834c57 100644 --- a/server/src/lib/cli-executor.ts +++ b/server/src/lib/cli-executor.ts @@ -548,10 +548,14 @@ export async function executeCodeQLCommand( // Fresh-process execution (for FRESH_PROCESS_SUBCOMMANDS, CWD-specific // calls, or as a fallback when the cli-server is unavailable). + // Use 0 (no timeout) because CodeQL operations such as query evaluation, + // database analysis, profiling, and test runs are inherently long-running + // and should not be killed by a process timeout. return executeCLICommand({ command: 'codeql', args, - cwd + cwd, + timeout: 0 }); } diff --git a/server/src/lib/discovery-config.ts b/server/src/lib/discovery-config.ts new file mode 100644 index 00000000..1bd200a6 --- /dev/null +++ b/server/src/lib/discovery-config.ts @@ -0,0 +1,48 @@ +/** + * Discovery configuration for locating CodeQL databases and query run results. + * + * Reads colon-separated directory lists from environment variables: + * - `CODEQL_DATABASES_BASE_DIRS` — directories to search for CodeQL databases + * - `CODEQL_QUERY_RUN_RESULTS_DIRS` — directories containing per-run query result subdirectories + * + * The VS Code extension sets these automatically from vscode-codeql storage paths. + * CLI users can set them manually. + */ + +/** + * Parse a colon-separated list of directories from an environment variable. + */ +function parsePathList(envValue: string | undefined): string[] { + if (!envValue) { + return []; + } + return envValue + .split(':') + .map((p) => p.trim()) + .filter((p) => p.length > 0); +} + +/** + * Get the list of base directories to search for CodeQL databases. + * + * Each directory is expected to contain one or more CodeQL database directories + * (each with a `codeql-database.yml` file). + * + * Set via `CODEQL_DATABASES_BASE_DIRS` (colon-separated). + */ +export function getDatabaseBaseDirs(): string[] { + return parsePathList(process.env.CODEQL_DATABASES_BASE_DIRS); +} + +/** + * Get the list of directories containing per-run query result subdirectories. + * + * Each directory is expected to contain subdirectories named like + * `.ql-/`, each holding artifacts such as + * `evaluator-log.jsonl`, `results.bqrs`, and `results-interpreted.sarif`. + * + * Set via `CODEQL_QUERY_RUN_RESULTS_DIRS` (colon-separated). + */ +export function getQueryRunResultsDirs(): string[] { + return parsePathList(process.env.CODEQL_QUERY_RUN_RESULTS_DIRS); +} diff --git a/server/src/tools/codeql-tools.ts b/server/src/tools/codeql-tools.ts index f1d91124..f2ca05db 100644 --- a/server/src/tools/codeql-tools.ts +++ b/server/src/tools/codeql-tools.ts @@ -34,6 +34,8 @@ import { registerFindClassPositionTool, registerFindCodeQLQueryFilesTool, registerFindPredicatePositionTool, + registerListDatabasesTool, + registerListQueryRunResultsTool, registerProfileCodeQLQueryTool, registerQuickEvaluateTool, registerRegisterDatabaseTool @@ -158,6 +160,8 @@ export function registerCodeQLTools(server: McpServer): void { registerFindClassPositionTool(server); registerFindCodeQLQueryFilesTool(server); registerFindPredicatePositionTool(server); + registerListDatabasesTool(server); + registerListQueryRunResultsTool(server); registerProfileCodeQLQueryTool(server); registerQuickEvaluateTool(server); registerRegisterDatabaseTool(server); diff --git a/server/src/tools/codeql/index.ts b/server/src/tools/codeql/index.ts index d8232423..c550f248 100644 --- a/server/src/tools/codeql/index.ts +++ b/server/src/tools/codeql/index.ts @@ -13,6 +13,8 @@ export { registerFindCodeQLQueryFilesTool } from './find-query-files'; export { codeqlGenerateLogSummaryTool } from './generate-log-summary'; export { codeqlGenerateQueryHelpTool } from './generate-query-help'; // codeql_lsp_diagnostics has moved to server/src/tools/lsp/lsp-diagnostics.ts +export { registerListDatabasesTool } from './list-databases'; +export { registerListQueryRunResultsTool } from './list-query-run-results'; export { codeqlPackInstallTool } from './pack-install'; export { codeqlPackLsTool } from './pack-ls'; export { registerProfileCodeQLQueryTool } from './profile-codeql-query'; diff --git a/server/src/tools/codeql/list-databases.ts b/server/src/tools/codeql/list-databases.ts new file mode 100644 index 00000000..f991ab88 --- /dev/null +++ b/server/src/tools/codeql/list-databases.ts @@ -0,0 +1,196 @@ +/** + * list_codeql_databases tool + * + * Discovers CodeQL databases in configured base directories. + * Scans each directory in `CODEQL_DATABASES_BASE_DIRS` for subdirectories + * containing `codeql-database.yml`, extracts metadata (language, CLI version, + * creation time), and returns the list. + */ + +import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js'; +import { existsSync, readdirSync, readFileSync, statSync } from 'fs'; +import { join } from 'path'; +import { z } from 'zod'; +import { getDatabaseBaseDirs } from '../../lib/discovery-config'; +import { logger } from '../../utils/logger'; + +export interface DatabaseInfo { + cliVersion?: string; + creationTime?: string; + language?: string; + name: string; + path: string; +} + +/** + * Parse `codeql-database.yml` to extract metadata. + * Uses simple line-based parsing to avoid a YAML dependency. + */ +function parseDatabaseYml(ymlPath: string): Partial { + try { + const content = readFileSync(ymlPath, 'utf-8'); + const info: Partial = {}; + + for (const line of content.split('\n')) { + const trimmed = line.trim(); + const colonIdx = trimmed.indexOf(':'); + if (colonIdx === -1) continue; + + const key = trimmed.substring(0, colonIdx).trim(); + const value = trimmed.substring(colonIdx + 1).trim().replace(/^["']|["']$/g, ''); + + switch (key) { + case 'primaryLanguage': + info.language = value; + break; + case 'cliVersion': + info.cliVersion = value; + break; + case 'creationTime': + info.creationTime = value; + break; + } + } + + return info; + } catch { + return {}; + } +} + +/** + * Discover CodeQL databases in the given base directories. + * + * @param baseDirs - Directories to scan for database subdirectories + * @param language - Optional language filter + * @returns List of discovered databases with metadata + */ +export async function discoverDatabases( + baseDirs: string[], + language?: string, +): Promise { + const databases: DatabaseInfo[] = []; + + for (const baseDir of baseDirs) { + if (!existsSync(baseDir)) { + continue; + } + + let entries: string[]; + try { + entries = readdirSync(baseDir); + } catch { + continue; + } + + for (const entry of entries) { + const entryPath = join(baseDir, entry); + + // Skip non-directories + try { + if (!statSync(entryPath).isDirectory()) { + continue; + } + } catch { + continue; + } + + // Check for codeql-database.yml + const ymlPath = join(entryPath, 'codeql-database.yml'); + if (!existsSync(ymlPath)) { + continue; + } + + const metadata = parseDatabaseYml(ymlPath); + + // Apply language filter + if (language && metadata.language !== language) { + continue; + } + + databases.push({ + cliVersion: metadata.cliVersion, + creationTime: metadata.creationTime, + language: metadata.language, + name: entry, + path: entryPath, + }); + } + } + + return databases; +} + +/** + * Register the list_codeql_databases tool with the MCP server. + */ +export function registerListDatabasesTool(server: McpServer): void { + server.tool( + 'list_codeql_databases', + 'List CodeQL databases discovered in configured base directories (set via CODEQL_DATABASES_BASE_DIRS env var). Returns path, language, CLI version, and creation time for each database.', + { + language: z + .string() + .optional() + .describe('Filter databases by language (e.g., "javascript", "python")'), + }, + async ({ language }) => { + try { + const baseDirs = getDatabaseBaseDirs(); + + if (baseDirs.length === 0) { + return { + content: [ + { + type: 'text' as const, + text: 'No database base directories configured. Set the CODEQL_DATABASES_BASE_DIRS environment variable to a colon-separated list of directories to search.', + }, + ], + }; + } + + const databases = await discoverDatabases(baseDirs, language); + + if (databases.length === 0) { + const filterMsg = language ? ` for language "${language}"` : ''; + return { + content: [ + { + type: 'text' as const, + text: `No CodeQL databases found${filterMsg} in: ${baseDirs.join(', ')}`, + }, + ], + }; + } + + const lines = [ + `Found ${databases.length} CodeQL database(s):`, + '', + ...databases.map((db) => { + const parts = [` ${db.name}`]; + parts.push(` Path: ${db.path}`); + if (db.language) parts.push(` Language: ${db.language}`); + if (db.cliVersion) parts.push(` CLI Version: ${db.cliVersion}`); + if (db.creationTime) parts.push(` Created: ${db.creationTime}`); + return parts.join('\n'); + }), + ]; + + return { + content: [{ type: 'text' as const, text: lines.join('\n') }], + }; + } catch (error) { + logger.error('Error listing databases:', error); + return { + content: [ + { + type: 'text' as const, + text: `Error: ${error instanceof Error ? error.message : 'Unknown error'}`, + }, + ], + isError: true, + }; + } + }, + ); +} diff --git a/server/src/tools/codeql/list-query-run-results.ts b/server/src/tools/codeql/list-query-run-results.ts new file mode 100644 index 00000000..ed612589 --- /dev/null +++ b/server/src/tools/codeql/list-query-run-results.ts @@ -0,0 +1,188 @@ +/** + * list_query_run_results tool + * + * Discovers per-query-run result directories in configured search paths. + * Scans each directory in `CODEQL_QUERY_RUN_RESULTS_DIRS` for subdirectories + * matching the `.ql-` naming convention used by vscode-codeql. + * Reports which artifacts (evaluator logs, BQRS, SARIF) are present in each run. + */ + +import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js'; +import { existsSync, readdirSync, readFileSync, statSync } from 'fs'; +import { join } from 'path'; +import { z } from 'zod'; +import { getQueryRunResultsDirs } from '../../lib/discovery-config'; +import { logger } from '../../utils/logger'; + +export interface QueryRunResult { + hasBqrs: boolean; + hasEvaluatorLog: boolean; + hasSarif: boolean; + path: string; + queryName: string; + runId: string; + timestamp?: string; +} + +/** + * Pattern matching vscode-codeql query run directory names: `.ql-` + */ +const QUERY_RUN_DIR_PATTERN = /^(.+\.ql)-(.+)$/; + +/** + * Discover query run result directories in the given search paths. + * + * @param resultsDirs - Directories to scan for per-run subdirectories + * @param queryName - Optional query name filter (e.g., "UI5Xss.ql") + * @returns List of discovered query run results with artifact inventory + */ +export async function discoverQueryRunResults( + resultsDirs: string[], + queryName?: string, +): Promise { + const results: QueryRunResult[] = []; + + for (const dir of resultsDirs) { + if (!existsSync(dir)) { + continue; + } + + let entries: string[]; + try { + entries = readdirSync(dir); + } catch { + continue; + } + + for (const entry of entries) { + const entryPath = join(dir, entry); + + // Skip non-directories + try { + if (!statSync(entryPath).isDirectory()) { + continue; + } + } catch { + continue; + } + + // Match the naming pattern + const match = QUERY_RUN_DIR_PATTERN.exec(entry); + if (!match) { + continue; + } + + const [, name, runId] = match; + + // Apply query name filter + if (queryName && name !== queryName) { + continue; + } + + // Check which artifacts are present + const hasEvaluatorLog = existsSync(join(entryPath, 'evaluator-log.jsonl')); + const hasBqrs = existsSync(join(entryPath, 'results.bqrs')); + const hasSarif = existsSync(join(entryPath, 'results-interpreted.sarif')); + + // Read timestamp if available + let timestamp: string | undefined; + const timestampPath = join(entryPath, 'timestamp'); + if (existsSync(timestampPath)) { + try { + timestamp = readFileSync(timestampPath, 'utf-8').trim(); + } catch { + // Ignore read errors + } + } + + results.push({ + hasBqrs, + hasEvaluatorLog, + hasSarif, + path: entryPath, + queryName: name, + runId, + timestamp, + }); + } + } + + return results; +} + +/** + * Register the list_query_run_results tool with the MCP server. + */ +export function registerListQueryRunResultsTool(server: McpServer): void { + server.tool( + 'list_query_run_results', + 'List discovered query run result directories (set via CODEQL_QUERY_RUN_RESULTS_DIRS env var). Returns path, query name, timestamp, and available artifacts for each run.', + { + queryName: z + .string() + .optional() + .describe('Filter results by query name (e.g., "UI5Xss.ql")'), + }, + async ({ queryName }) => { + try { + const resultsDirs = getQueryRunResultsDirs(); + + if (resultsDirs.length === 0) { + return { + content: [ + { + type: 'text' as const, + text: 'No query run results directories configured. Set the CODEQL_QUERY_RUN_RESULTS_DIRS environment variable to a colon-separated list of directories to search.', + }, + ], + }; + } + + const runs = await discoverQueryRunResults(resultsDirs, queryName); + + if (runs.length === 0) { + const filterMsg = queryName ? ` for query "${queryName}"` : ''; + return { + content: [ + { + type: 'text' as const, + text: `No query run results found${filterMsg} in: ${resultsDirs.join(', ')}`, + }, + ], + }; + } + + const lines = [ + `Found ${runs.length} query run result(s):`, + '', + ...runs.map((run) => { + const artifacts: string[] = []; + if (run.hasEvaluatorLog) artifacts.push('evaluator-log'); + if (run.hasBqrs) artifacts.push('bqrs'); + if (run.hasSarif) artifacts.push('sarif'); + const parts = [` ${run.queryName} (${run.runId})`]; + parts.push(` Path: ${run.path}`); + if (run.timestamp) parts.push(` Timestamp: ${run.timestamp}`); + parts.push(` Artifacts: ${artifacts.length > 0 ? artifacts.join(', ') : 'none'}`); + return parts.join('\n'); + }), + ]; + + return { + content: [{ type: 'text' as const, text: lines.join('\n') }], + }; + } catch (error) { + logger.error('Error listing query run results:', error); + return { + content: [ + { + type: 'text' as const, + text: `Error: ${error instanceof Error ? error.message : 'Unknown error'}`, + }, + ], + isError: true, + }; + } + }, + ); +} diff --git a/server/test/src/lib/discovery-config.test.ts b/server/test/src/lib/discovery-config.test.ts new file mode 100644 index 00000000..2ae087bc --- /dev/null +++ b/server/test/src/lib/discovery-config.test.ts @@ -0,0 +1,86 @@ +/** + * Tests for discovery configuration: env var parsing for database and + * query-run-results directory discovery. + */ + +import { afterEach, beforeEach, describe, expect, it } from 'vitest'; +import { + getDatabaseBaseDirs, + getQueryRunResultsDirs, +} from '../../../src/lib/discovery-config'; + +describe('Discovery Configuration', () => { + const originalEnv = process.env; + + beforeEach(() => { + process.env = { ...originalEnv }; + }); + + afterEach(() => { + process.env = originalEnv; + }); + + describe('getDatabaseBaseDirs', () => { + it('should return empty array when env var is not set', () => { + delete process.env.CODEQL_DATABASES_BASE_DIRS; + expect(getDatabaseBaseDirs()).toEqual([]); + }); + + it('should return empty array when env var is empty string', () => { + process.env.CODEQL_DATABASES_BASE_DIRS = ''; + expect(getDatabaseBaseDirs()).toEqual([]); + }); + + it('should parse single directory', () => { + process.env.CODEQL_DATABASES_BASE_DIRS = '/path/to/databases'; + expect(getDatabaseBaseDirs()).toEqual(['/path/to/databases']); + }); + + it('should parse colon-separated directories', () => { + process.env.CODEQL_DATABASES_BASE_DIRS = '/path/one:/path/two:/path/three'; + expect(getDatabaseBaseDirs()).toEqual(['/path/one', '/path/two', '/path/three']); + }); + + it('should trim whitespace from paths', () => { + process.env.CODEQL_DATABASES_BASE_DIRS = ' /path/one : /path/two '; + expect(getDatabaseBaseDirs()).toEqual(['/path/one', '/path/two']); + }); + + it('should filter out empty segments from consecutive colons', () => { + process.env.CODEQL_DATABASES_BASE_DIRS = '/path/one::/path/two'; + expect(getDatabaseBaseDirs()).toEqual(['/path/one', '/path/two']); + }); + }); + + describe('getQueryRunResultsDirs', () => { + it('should return empty array when env var is not set', () => { + delete process.env.CODEQL_QUERY_RUN_RESULTS_DIRS; + expect(getQueryRunResultsDirs()).toEqual([]); + }); + + it('should return empty array when env var is empty string', () => { + process.env.CODEQL_QUERY_RUN_RESULTS_DIRS = ''; + expect(getQueryRunResultsDirs()).toEqual([]); + }); + + it('should parse single directory', () => { + process.env.CODEQL_QUERY_RUN_RESULTS_DIRS = '/path/to/queries'; + expect(getQueryRunResultsDirs()).toEqual(['/path/to/queries']); + }); + + it('should parse colon-separated directories', () => { + process.env.CODEQL_QUERY_RUN_RESULTS_DIRS = '/global/queries:/workspace/queries'; + expect(getQueryRunResultsDirs()).toEqual(['/global/queries', '/workspace/queries']); + }); + + it('should trim whitespace from paths', () => { + process.env.CODEQL_QUERY_RUN_RESULTS_DIRS = ' /path/one : /path/two '; + expect(getQueryRunResultsDirs()).toEqual(['/path/one', '/path/two']); + }); + + it('should filter out empty segments from consecutive colons', () => { + process.env.CODEQL_QUERY_RUN_RESULTS_DIRS = '/path/one::/path/two'; + expect(getQueryRunResultsDirs()).toEqual(['/path/one', '/path/two']); + }); + }); +}); diff --git a/server/test/src/tools/codeql-tools.test.ts b/server/test/src/tools/codeql-tools.test.ts index d6e74b33..990360a9 100644 --- a/server/test/src/tools/codeql-tools.test.ts +++ b/server/test/src/tools/codeql-tools.test.ts @@ -31,6 +31,8 @@ describe('registerCodeQLTools', () => { expect(toolNames).toContain('create_codeql_query'); expect(toolNames).toContain('find_class_position'); expect(toolNames).toContain('find_predicate_position'); + expect(toolNames).toContain('list_codeql_databases'); + expect(toolNames).toContain('list_query_run_results'); expect(toolNames).toContain('quick_evaluate'); expect(toolNames).toContain('register_database'); @@ -39,9 +41,9 @@ describe('registerCodeQLTools', () => { // rank_sarif_results has been removed in favor of SARIF prompts expect(toolNames).not.toContain('rank_sarif_results'); - // Total tools registered: 2 high-level helpers + 6 specialized tools + 22 CLI tools = 30 + // Total tools registered: 2 high-level helpers + 8 specialized tools + 22 CLI tools = 32 // (codeql_lsp_diagnostics moved to registerLSPTools in tools/lsp/) - expect(mockServer.tool).toHaveBeenCalledTimes(30); + expect(mockServer.tool).toHaveBeenCalledTimes(32); }); it('should register validate_codeql_query with correct parameters', () => { diff --git a/server/test/src/tools/codeql/list-databases.test.ts b/server/test/src/tools/codeql/list-databases.test.ts new file mode 100644 index 00000000..c6fa481d --- /dev/null +++ b/server/test/src/tools/codeql/list-databases.test.ts @@ -0,0 +1,144 @@ +/** + * Tests for list_codeql_databases tool + */ + +import { afterEach, beforeEach, describe, expect, it } from 'vitest'; +import { mkdirSync, writeFileSync } from 'fs'; +import { join } from 'path'; +import { createTestTempDir, cleanupTestTempDir } from '../../../utils/temp-dir'; +import { + DatabaseInfo, + discoverDatabases, +} from '../../../../src/tools/codeql/list-databases'; + +describe('list_codeql_databases', () => { + let testDir: string; + + beforeEach(() => { + testDir = createTestTempDir('list-databases'); + }); + + afterEach(() => { + cleanupTestTempDir(testDir); + }); + + describe('discoverDatabases', () => { + it('should return empty array when no base dirs are provided', async () => { + const result = await discoverDatabases([]); + expect(result).toEqual([]); + }); + + it('should return empty array when base dir does not exist', async () => { + const result = await discoverDatabases([join(testDir, 'nonexistent')]); + expect(result).toEqual([]); + }); + + it('should discover a database with codeql-database.yml', async () => { + // Arrange: create a fake database directory + const dbDir = join(testDir, 'my-database'); + mkdirSync(dbDir, { recursive: true }); + writeFileSync( + join(dbDir, 'codeql-database.yml'), + 'primaryLanguage: javascript\ncreationMetadata:\n cliVersion: "2.24.1"\n creationTime: "2026-01-15T10:00:00Z"\n' + ); + mkdirSync(join(dbDir, 'db-javascript'), { recursive: true }); + writeFileSync(join(dbDir, 'src.zip'), ''); + + // Act + const result = await discoverDatabases([testDir]); + + // Assert + expect(result).toHaveLength(1); + expect(result[0].path).toBe(dbDir); + expect(result[0].language).toBe('javascript'); + expect(result[0].cliVersion).toBe('2.24.1'); + }); + + it('should discover multiple databases in a single base dir', async () => { + // Arrange + for (const name of ['db-java', 'db-python']) { + const dbDir = join(testDir, name); + mkdirSync(dbDir, { recursive: true }); + const lang = name.replace('db-', ''); + writeFileSync( + join(dbDir, 'codeql-database.yml'), + `primaryLanguage: ${lang}\n` + ); + } + + // Act + const result = await discoverDatabases([testDir]); + + // Assert + expect(result).toHaveLength(2); + const languages = result.map((d: DatabaseInfo) => d.language).sort(); + expect(languages).toEqual(['java', 'python']); + }); + + it('should discover databases across multiple base dirs', async () => { + // Arrange + const dir1 = join(testDir, 'dir1'); + const dir2 = join(testDir, 'dir2'); + const db1 = join(dir1, 'db-a'); + const db2 = join(dir2, 'db-b'); + for (const d of [db1, db2]) { + mkdirSync(d, { recursive: true }); + writeFileSync(join(d, 'codeql-database.yml'), 'primaryLanguage: cpp\n'); + } + + // Act + const result = await discoverDatabases([dir1, dir2]); + + // Assert + expect(result).toHaveLength(2); + }); + + it('should skip directories without codeql-database.yml', async () => { + // Arrange + const notADb = join(testDir, 'not-a-db'); + mkdirSync(notADb, { recursive: true }); + writeFileSync(join(notADb, 'random-file.txt'), 'hello'); + + const realDb = join(testDir, 'real-db'); + mkdirSync(realDb, { recursive: true }); + writeFileSync(join(realDb, 'codeql-database.yml'), 'primaryLanguage: go\n'); + + // Act + const result = await discoverDatabases([testDir]); + + // Assert + expect(result).toHaveLength(1); + expect(result[0].language).toBe('go'); + }); + + it('should filter by language when specified', async () => { + // Arrange + for (const lang of ['javascript', 'python', 'java']) { + const dbDir = join(testDir, `db-${lang}`); + mkdirSync(dbDir, { recursive: true }); + writeFileSync(join(dbDir, 'codeql-database.yml'), `primaryLanguage: ${lang}\n`); + } + + // Act + const result = await discoverDatabases([testDir], 'python'); + + // Assert + expect(result).toHaveLength(1); + expect(result[0].language).toBe('python'); + }); + + it('should skip files (not directories) in base dir', async () => { + // Arrange + writeFileSync(join(testDir, 'not-a-dir.txt'), 'hello'); + const dbDir = join(testDir, 'real-db'); + mkdirSync(dbDir, { recursive: true }); + writeFileSync(join(dbDir, 'codeql-database.yml'), 'primaryLanguage: ruby\n'); + + // Act + const result = await discoverDatabases([testDir]); + + // Assert + expect(result).toHaveLength(1); + }); + }); +}); diff --git a/server/test/src/tools/codeql/list-query-run-results.test.ts b/server/test/src/tools/codeql/list-query-run-results.test.ts new file mode 100644 index 00000000..b4408268 --- /dev/null +++ b/server/test/src/tools/codeql/list-query-run-results.test.ts @@ -0,0 +1,141 @@ +/** + * Tests for list_query_run_results tool + */ + +import { afterEach, beforeEach, describe, expect, it } from 'vitest'; +import { mkdirSync, writeFileSync } from 'fs'; +import { join } from 'path'; +import { createTestTempDir, cleanupTestTempDir } from '../../../utils/temp-dir'; +import { + discoverQueryRunResults, + QueryRunResult, +} from '../../../../src/tools/codeql/list-query-run-results'; + +describe('list_query_run_results', () => { + let testDir: string; + + beforeEach(() => { + testDir = createTestTempDir('list-query-run-results'); + }); + + afterEach(() => { + cleanupTestTempDir(testDir); + }); + + describe('discoverQueryRunResults', () => { + it('should return empty array when no result dirs are provided', async () => { + const result = await discoverQueryRunResults([]); + expect(result).toEqual([]); + }); + + it('should return empty array when result dir does not exist', async () => { + const result = await discoverQueryRunResults([join(testDir, 'nonexistent')]); + expect(result).toEqual([]); + }); + + it('should discover a query run result directory with artifacts', async () => { + // Arrange: create a fake vscode-codeql query run directory + const runDir = join(testDir, 'UI5Xss.ql-abc123'); + mkdirSync(runDir, { recursive: true }); + writeFileSync(join(runDir, 'evaluator-log.jsonl'), '{}'); + writeFileSync(join(runDir, 'results.bqrs'), ''); + writeFileSync(join(runDir, 'results-interpreted.sarif'), '{}'); + writeFileSync(join(runDir, 'timestamp'), '2026-02-16T20:00:00Z'); + + // Act + const result = await discoverQueryRunResults([testDir]); + + // Assert + expect(result).toHaveLength(1); + expect(result[0].queryName).toBe('UI5Xss.ql'); + expect(result[0].runId).toBe('abc123'); + expect(result[0].hasEvaluatorLog).toBe(true); + expect(result[0].hasBqrs).toBe(true); + expect(result[0].hasSarif).toBe(true); + }); + + it('should discover run with partial artifacts', async () => { + // Arrange: run dir with only query.log and timestamp + const runDir = join(testDir, 'MyQuery.ql-xyz789'); + mkdirSync(runDir, { recursive: true }); + writeFileSync(join(runDir, 'query.log'), 'log content'); + writeFileSync(join(runDir, 'timestamp'), '2026-01-01T00:00:00Z'); + + // Act + const result = await discoverQueryRunResults([testDir]); + + // Assert + expect(result).toHaveLength(1); + expect(result[0].queryName).toBe('MyQuery.ql'); + expect(result[0].hasEvaluatorLog).toBe(false); + expect(result[0].hasBqrs).toBe(false); + expect(result[0].hasSarif).toBe(false); + }); + + it('should discover multiple runs across multiple dirs', async () => { + // Arrange + const dir1 = join(testDir, 'dir1'); + const dir2 = join(testDir, 'dir2'); + const run1 = join(dir1, 'A.ql-111'); + const run2 = join(dir2, 'B.ql-222'); + for (const d of [run1, run2]) { + mkdirSync(d, { recursive: true }); + writeFileSync(join(d, 'timestamp'), 'x'); + } + + // Act + const result = await discoverQueryRunResults([dir1, dir2]); + + // Assert + expect(result).toHaveLength(2); + }); + + it('should filter by query name', async () => { + // Arrange + for (const name of ['UI5Xss.ql-aaa', 'LogInjection.ql-bbb', 'UI5Xss.ql-ccc']) { + const runDir = join(testDir, name); + mkdirSync(runDir, { recursive: true }); + writeFileSync(join(runDir, 'timestamp'), 'x'); + } + + // Act + const result = await discoverQueryRunResults([testDir], 'UI5Xss.ql'); + + // Assert + expect(result).toHaveLength(2); + expect(result.every((r: QueryRunResult) => r.queryName === 'UI5Xss.ql')).toBe(true); + }); + + it('should skip directories that do not match query run naming pattern', async () => { + // Arrange: directory without the - pattern + const notARun = join(testDir, 'random-directory'); + mkdirSync(notARun, { recursive: true }); + writeFileSync(join(notARun, 'some-file.txt'), ''); + + const realRun = join(testDir, 'Test.ql-abc'); + mkdirSync(realRun, { recursive: true }); + writeFileSync(join(realRun, 'timestamp'), 'x'); + + // Act + const result = await discoverQueryRunResults([testDir]); + + // Assert + expect(result).toHaveLength(1); + expect(result[0].queryName).toBe('Test.ql'); + }); + + it('should read timestamp from timestamp file', async () => { + // Arrange + const runDir = join(testDir, 'Q.ql-ts1'); + mkdirSync(runDir, { recursive: true }); + writeFileSync(join(runDir, 'timestamp'), '2026-02-16T15:30:00.000Z'); + + // Act + const result = await discoverQueryRunResults([testDir]); + + // Assert + expect(result).toHaveLength(1); + expect(result[0].timestamp).toBe('2026-02-16T15:30:00.000Z'); + }); + }); +}); diff --git a/tsconfig.json b/tsconfig.json index c927b521..3039d554 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -15,6 +15,9 @@ "references": [ { "path": "./server" + }, + { + "path": "./extensions/vscode" } ] } \ No newline at end of file From 84faf530f95b5618b4bdd8fac8ccefcd7e8c445d Mon Sep 17 00:00:00 2001 From: Nathan Randall Date: Tue, 17 Feb 2026 20:53:22 -0700 Subject: [PATCH 02/14] Add profile_codeql_query_from_logs tool & other - Add `list_mrva_run_results` tool to discover Multi-Repository Variant Analysis run results from `CODEQL_MRVA_RUN_RESULTS_DIRS` directories - Add `profile_codeql_query_from_logs` tool to parse evaluator logs into performance profiles (JSON + Mermaid) without re-running queries - Add reusable evaluator log parser supporting both raw and summary formats - Extend `codeql_database_analyze` with logDir, evaluator-log, and tuple-counting parameters, matching `codeql_query_run` logging support - Generate evaluator log summaries post-execution for query run and database analyze commands - Add `getMrvaRunResultsDirs` to discovery config for MRVA env var - Add unit tests for all new tools and libraries --- .../multi_query_raw_log/README.md | 25 + .../after/monitoring-state.json | 26 + .../after/query-evaluation-profile.json | 75 + .../after/query-evaluation-profile.md | 26 + .../before/evaluator-log.jsonl | 298 ++++ .../before/monitoring-state.json | 3 + .../multi_query_raw_log/test-config.json | 8 + .../single_query_raw_log/README.md | 19 + .../after/monitoring-state.json | 26 + .../after/query-evaluation-profile.json | 118 ++ .../after/query-evaluation-profile.md | 29 + .../before/evaluator-log.jsonl | 525 +++++++ .../before/monitoring-state.json | 3 + .../single_query_raw_log/test-config.json | 8 + client/src/lib/integration-test-runner.js | 13 + docs/ql-mcp/tools.md | 28 +- docs/vscode/IMPLEMENTATION.md | 312 ++++ docs/vscode/extension.md | 8 +- .../vscode/src/bridge/environment-builder.ts | 9 + server/dist/codeql-development-mcp-server.js | 1378 ++++++++++++----- .../dist/codeql-development-mcp-server.js.map | 8 +- server/src/lib/cli-tool-registry.ts | 60 +- server/src/lib/discovery-config.ts | 18 +- server/src/lib/evaluator-log-parser.ts | 440 ++++++ server/src/tools/codeql-tools.ts | 4 + server/src/tools/codeql/database-analyze.ts | 11 +- server/src/tools/codeql/index.ts | 2 + .../src/tools/codeql/list-mrva-run-results.ts | 282 ++++ .../codeql/profile-codeql-query-from-logs.ts | 296 ++++ server/test/src/lib/discovery-config.test.ts | 33 + .../test/src/lib/evaluator-log-parser.test.ts | 660 ++++++++ server/test/src/tools/codeql-tools.test.ts | 5 +- .../codeql/list-mrva-run-results.test.ts | 241 +++ .../profile-codeql-query-from-logs.test.ts | 380 +++++ 34 files changed, 4978 insertions(+), 399 deletions(-) create mode 100644 client/integration-tests/primitives/tools/profile_codeql_query_from_logs/multi_query_raw_log/README.md create mode 100644 client/integration-tests/primitives/tools/profile_codeql_query_from_logs/multi_query_raw_log/after/monitoring-state.json create mode 100644 client/integration-tests/primitives/tools/profile_codeql_query_from_logs/multi_query_raw_log/after/query-evaluation-profile.json create mode 100644 client/integration-tests/primitives/tools/profile_codeql_query_from_logs/multi_query_raw_log/after/query-evaluation-profile.md create mode 100644 client/integration-tests/primitives/tools/profile_codeql_query_from_logs/multi_query_raw_log/before/evaluator-log.jsonl create mode 100644 client/integration-tests/primitives/tools/profile_codeql_query_from_logs/multi_query_raw_log/before/monitoring-state.json create mode 100644 client/integration-tests/primitives/tools/profile_codeql_query_from_logs/multi_query_raw_log/test-config.json create mode 100644 client/integration-tests/primitives/tools/profile_codeql_query_from_logs/single_query_raw_log/README.md create mode 100644 client/integration-tests/primitives/tools/profile_codeql_query_from_logs/single_query_raw_log/after/monitoring-state.json create mode 100644 client/integration-tests/primitives/tools/profile_codeql_query_from_logs/single_query_raw_log/after/query-evaluation-profile.json create mode 100644 client/integration-tests/primitives/tools/profile_codeql_query_from_logs/single_query_raw_log/after/query-evaluation-profile.md create mode 100644 client/integration-tests/primitives/tools/profile_codeql_query_from_logs/single_query_raw_log/before/evaluator-log.jsonl create mode 100644 client/integration-tests/primitives/tools/profile_codeql_query_from_logs/single_query_raw_log/before/monitoring-state.json create mode 100644 client/integration-tests/primitives/tools/profile_codeql_query_from_logs/single_query_raw_log/test-config.json create mode 100644 docs/vscode/IMPLEMENTATION.md create mode 100644 server/src/lib/evaluator-log-parser.ts create mode 100644 server/src/tools/codeql/list-mrva-run-results.ts create mode 100644 server/src/tools/codeql/profile-codeql-query-from-logs.ts create mode 100644 server/test/src/lib/evaluator-log-parser.test.ts create mode 100644 server/test/src/tools/codeql/list-mrva-run-results.test.ts create mode 100644 server/test/src/tools/codeql/profile-codeql-query-from-logs.test.ts diff --git a/client/integration-tests/primitives/tools/profile_codeql_query_from_logs/multi_query_raw_log/README.md b/client/integration-tests/primitives/tools/profile_codeql_query_from_logs/multi_query_raw_log/README.md new file mode 100644 index 00000000..393c3589 --- /dev/null +++ b/client/integration-tests/primitives/tools/profile_codeql_query_from_logs/multi_query_raw_log/README.md @@ -0,0 +1,25 @@ +# `profile_codeql_query_from_logs` - multi_query_raw_log + +## Purpose + +Tests the `profile_codeql_query_from_logs` tool with a multi-query raw +evaluator log (`evaluator-log.jsonl`) produced by `codeql database analyze`. + +This validates that the parser correctly groups predicates by their +`queryCausingWork` event ID reference, producing separate per-query profiles. + +## Inputs + +- `before/evaluator-log.jsonl` — Raw evaluator log containing two queries + (QueryA.ql and QueryB.ql) with distinct predicates grouped by + `queryCausingWork` event ID references. +- `test-config.json` — Specifies `evaluatorLog`, `outputDir`, and `topN=10`. + +## Outputs + +- `after/query-evaluation-profile.json` — Structured profile with two queries: + QueryA (2 predicates, 1 cache hit, 200ms) and QueryB (3 predicates, 0 cache + hits, 300ms). +- `after/query-evaluation-profile.md` — Mermaid diagram with multi-query + layout showing a root node branching to Q0 (QueryA) and Q1 (QueryB) with + their respective predicate nodes. diff --git a/client/integration-tests/primitives/tools/profile_codeql_query_from_logs/multi_query_raw_log/after/monitoring-state.json b/client/integration-tests/primitives/tools/profile_codeql_query_from_logs/multi_query_raw_log/after/monitoring-state.json new file mode 100644 index 00000000..9f2b10cc --- /dev/null +++ b/client/integration-tests/primitives/tools/profile_codeql_query_from_logs/multi_query_raw_log/after/monitoring-state.json @@ -0,0 +1,26 @@ +{ + "sessions": [ + { + "id": "integration_test_session", + "calls": [ + { + "tool": "profile_codeql_query_from_logs", + "timestamp": "2025-10-08T21:00:00.000Z", + "status": "success", + "arguments": { + "evaluatorLog": "client/integration-tests/primitives/tools/profile_codeql_query_from_logs/multi_query_raw_log/before/evaluator-log.jsonl", + "outputDir": "client/integration-tests/primitives/tools/profile_codeql_query_from_logs/multi_query_raw_log/after", + "topN": 10 + }, + "response": { + "message": "Query log profiling completed successfully", + "filesGenerated": [ + "query-evaluation-profile.json", + "query-evaluation-profile.md" + ] + } + } + ] + } + ] +} diff --git a/client/integration-tests/primitives/tools/profile_codeql_query_from_logs/multi_query_raw_log/after/query-evaluation-profile.json b/client/integration-tests/primitives/tools/profile_codeql_query_from_logs/multi_query_raw_log/after/query-evaluation-profile.json new file mode 100644 index 00000000..b3baef85 --- /dev/null +++ b/client/integration-tests/primitives/tools/profile_codeql_query_from_logs/multi_query_raw_log/after/query-evaluation-profile.json @@ -0,0 +1,75 @@ +{ + "codeqlVersion": "2.23.1", + "logFormat": "raw", + "queries": [ + { + "queryName": "/workspace/QueryA.ql", + "totalDurationMs": 200, + "predicateCount": 2, + "predicates": [ + { + "predicateName": "QueryA::source/0#abc123", + "position": "/workspace/QueryA.ql:10,1-12,5", + "durationMs": 65, + "resultSize": 5, + "pipelineCount": 1, + "evaluationStrategy": "SIMPLE_INTENSIONAL", + "dependencies": [] + }, + { + "predicateName": "QueryA::sink/0#def456", + "position": "/workspace/QueryA.ql:14,1-16,5", + "durationMs": 45, + "resultSize": 3, + "pipelineCount": 1, + "evaluationStrategy": "SIMPLE_INTENSIONAL", + "dependencies": [ + "QueryA::source/0#abc123" + ] + } + ], + "cacheHits": 1 + }, + { + "queryName": "/workspace/QueryB.ql", + "totalDurationMs": 300, + "predicateCount": 3, + "predicates": [ + { + "predicateName": "QueryB::entryPoint/0#jkl012", + "position": "/workspace/QueryB.ql:8,1-10,3", + "durationMs": 95, + "resultSize": 8, + "pipelineCount": 1, + "evaluationStrategy": "EXTENSIONAL", + "dependencies": [] + }, + { + "predicateName": "QueryB::flowStep/2#mno345", + "position": "/workspace/QueryB.ql:12,1-18,5", + "durationMs": 95, + "resultSize": 12, + "pipelineCount": 1, + "evaluationStrategy": "SIMPLE_INTENSIONAL", + "dependencies": [ + "QueryB::entryPoint/0#jkl012" + ] + }, + { + "predicateName": "QueryB::result/3#pqr678", + "position": "/workspace/QueryB.ql:20,1-22,5", + "durationMs": 45, + "resultSize": 2, + "pipelineCount": 1, + "evaluationStrategy": "SIMPLE_INTENSIONAL", + "dependencies": [ + "QueryB::flowStep/2#mno345", + "QueryB::entryPoint/0#jkl012" + ] + } + ], + "cacheHits": 0 + } + ], + "totalEvents": 27 +} \ No newline at end of file diff --git a/client/integration-tests/primitives/tools/profile_codeql_query_from_logs/multi_query_raw_log/after/query-evaluation-profile.md b/client/integration-tests/primitives/tools/profile_codeql_query_from_logs/multi_query_raw_log/after/query-evaluation-profile.md new file mode 100644 index 00000000..f1cb0ca4 --- /dev/null +++ b/client/integration-tests/primitives/tools/profile_codeql_query_from_logs/multi_query_raw_log/after/query-evaluation-profile.md @@ -0,0 +1,26 @@ +```mermaid +graph TD + + ROOT["Evaluation Log
2 queries"] + + Q0["QueryA.ql
200.00ms
Predicates: 2"] + ROOT --> Q0 + Q0P0["QueryA::source/0#abc123
65.00ms | 5 results"] + Q0 --> Q0P0 + Q0P1["QueryA::sink/0#def456
45.00ms | 3 results"] + Q0 --> Q0P1 + + Q1["QueryB.ql
300.00ms
Predicates: 3"] + ROOT --> Q1 + Q1P0["QueryB::entryPoint/0#jkl012
95.00ms | 8 results"] + Q1 --> Q1P0 + Q1P1["QueryB::flowStep/2#mno345
95.00ms | 12 results"] + Q1 --> Q1P1 + Q1P2["QueryB::result/3#pqr678
45.00ms | 2 results"] + Q1 --> Q1P2 + + + classDef default fill:#e1f5ff,stroke:#333,stroke-width:2px + classDef query fill:#ffe1e1,stroke:#333,stroke-width:3px + class QUERY query +``` \ No newline at end of file diff --git a/client/integration-tests/primitives/tools/profile_codeql_query_from_logs/multi_query_raw_log/before/evaluator-log.jsonl b/client/integration-tests/primitives/tools/profile_codeql_query_from_logs/multi_query_raw_log/before/evaluator-log.jsonl new file mode 100644 index 00000000..f0452dd8 --- /dev/null +++ b/client/integration-tests/primitives/tools/profile_codeql_query_from_logs/multi_query_raw_log/before/evaluator-log.jsonl @@ -0,0 +1,298 @@ +{ + "time" : "2025-10-08T20:00:00.000000000Z", + "type" : "LOG_HEADER", + "eventId" : 0, + "nanoTime" : 100000000, + "codeqlVersion" : "2.23.1", + "logVersion" : "0.5.0" +} + +{ + "time" : "2025-10-08T20:00:01.000000000Z", + "type" : "QUERY_STARTED", + "eventId" : 1, + "nanoTime" : 1000000000, + "queryName" : "/workspace/QueryA.ql", + "stages" : [ 0, 1 ] +} + +{ + "time" : "2025-10-08T20:00:01.010000000Z", + "type" : "PREDICATE_STARTED", + "eventId" : 2, + "nanoTime" : 1010000000, + "raHash" : "a1b2c3d4e5f601234567890ab01", + "predicateName" : "QueryA::source/0#abc123", + "appearsAs" : { + "QueryA::source/0#abc123" : [ 0 ] + }, + "predicateType" : "SIMPLE_INTENSIONAL", + "position" : "/workspace/QueryA.ql:10,1-12,5", + "dependencies" : { }, + "queryCausingWork" : 1 +} + +{ + "time" : "2025-10-08T20:00:01.020000000Z", + "type" : "PIPELINE_STARTED", + "eventId" : 3, + "nanoTime" : 1020000000, + "predicateStartEvent" : 2, + "raReference" : "pipeline" +} + +{ + "time" : "2025-10-08T20:00:01.070000000Z", + "type" : "PIPELINE_COMPLETED", + "eventId" : 4, + "nanoTime" : 1070000000, + "startEvent" : 3, + "counts" : [ 5 ], + "duplicationPercentages" : [ 0 ], + "resultSize" : 5 +} + +{ + "time" : "2025-10-08T20:00:01.075000000Z", + "type" : "PREDICATE_COMPLETED", + "eventId" : 5, + "nanoTime" : 1075000000, + "startEvent" : 2, + "resultSize" : 5 +} + +{ + "time" : "2025-10-08T20:00:01.080000000Z", + "type" : "PREDICATE_STARTED", + "eventId" : 6, + "nanoTime" : 1080000000, + "raHash" : "b2c3d4e5f6012345678901bc02", + "predicateName" : "QueryA::sink/0#def456", + "appearsAs" : { + "QueryA::sink/0#def456" : [ 0 ] + }, + "predicateType" : "SIMPLE_INTENSIONAL", + "position" : "/workspace/QueryA.ql:14,1-16,5", + "dependencies" : { + "QueryA::source/0#abc123" : "a1b2c3d4e5f601234567890ab01" + }, + "queryCausingWork" : 1 +} + +{ + "time" : "2025-10-08T20:00:01.090000000Z", + "type" : "PIPELINE_STARTED", + "eventId" : 7, + "nanoTime" : 1090000000, + "predicateStartEvent" : 6, + "raReference" : "pipeline" +} + +{ + "time" : "2025-10-08T20:00:01.120000000Z", + "type" : "PIPELINE_COMPLETED", + "eventId" : 8, + "nanoTime" : 1120000000, + "startEvent" : 7, + "counts" : [ 3 ], + "duplicationPercentages" : [ 0 ], + "resultSize" : 3 +} + +{ + "time" : "2025-10-08T20:00:01.125000000Z", + "type" : "PREDICATE_COMPLETED", + "eventId" : 9, + "nanoTime" : 1125000000, + "startEvent" : 6, + "resultSize" : 3 +} + +{ + "time" : "2025-10-08T20:00:01.130000000Z", + "type" : "CACHE_LOOKUP", + "eventId" : 10, + "nanoTime" : 1130000000, + "raHash" : "c3d4e5f60123456789012cd03", + "predicateName" : "QueryA::cached_helper/1#ghi789", + "appearsAs" : { + "QueryA::cached_helper/1#ghi789" : [ 0 ] + }, + "isCached" : true, + "cacheLookupResult" : "RELATION_CACHE_HIT", + "relationSize" : 10 +} + +{ + "time" : "2025-10-08T20:00:01.200000000Z", + "type" : "QUERY_COMPLETED", + "eventId" : 11, + "nanoTime" : 1200000000, + "startEvent" : 1, + "terminationType" : "COMPLETED_SUCCESSFULLY" +} + +{ + "time" : "2025-10-08T20:00:02.000000000Z", + "type" : "QUERY_STARTED", + "eventId" : 12, + "nanoTime" : 2000000000, + "queryName" : "/workspace/QueryB.ql", + "stages" : [ 0, 1 ] +} + +{ + "time" : "2025-10-08T20:00:02.010000000Z", + "type" : "PREDICATE_STARTED", + "eventId" : 13, + "nanoTime" : 2010000000, + "raHash" : "d4e5f601234567890123de04", + "predicateName" : "QueryB::entryPoint/0#jkl012", + "appearsAs" : { + "QueryB::entryPoint/0#jkl012" : [ 0 ] + }, + "predicateType" : "EXTENSIONAL", + "position" : "/workspace/QueryB.ql:8,1-10,3", + "dependencies" : { }, + "queryCausingWork" : 12 +} + +{ + "time" : "2025-10-08T20:00:02.020000000Z", + "type" : "PIPELINE_STARTED", + "eventId" : 14, + "nanoTime" : 2020000000, + "predicateStartEvent" : 13, + "raReference" : "pipeline" +} + +{ + "time" : "2025-10-08T20:00:02.100000000Z", + "type" : "PIPELINE_COMPLETED", + "eventId" : 15, + "nanoTime" : 2100000000, + "startEvent" : 14, + "counts" : [ 8 ], + "duplicationPercentages" : [ 0 ], + "resultSize" : 8 +} + +{ + "time" : "2025-10-08T20:00:02.105000000Z", + "type" : "PREDICATE_COMPLETED", + "eventId" : 16, + "nanoTime" : 2105000000, + "startEvent" : 13, + "resultSize" : 8 +} + +{ + "time" : "2025-10-08T20:00:02.110000000Z", + "type" : "PREDICATE_STARTED", + "eventId" : 17, + "nanoTime" : 2110000000, + "raHash" : "e5f6012345678901234ef05", + "predicateName" : "QueryB::flowStep/2#mno345", + "appearsAs" : { + "QueryB::flowStep/2#mno345" : [ 0 ] + }, + "predicateType" : "SIMPLE_INTENSIONAL", + "position" : "/workspace/QueryB.ql:12,1-18,5", + "dependencies" : { + "QueryB::entryPoint/0#jkl012" : "d4e5f601234567890123de04" + }, + "queryCausingWork" : 12 +} + +{ + "time" : "2025-10-08T20:00:02.120000000Z", + "type" : "PIPELINE_STARTED", + "eventId" : 18, + "nanoTime" : 2120000000, + "predicateStartEvent" : 17, + "raReference" : "pipeline" +} + +{ + "time" : "2025-10-08T20:00:02.200000000Z", + "type" : "PIPELINE_COMPLETED", + "eventId" : 19, + "nanoTime" : 2200000000, + "startEvent" : 18, + "counts" : [ 12 ], + "duplicationPercentages" : [ 0 ], + "resultSize" : 12 +} + +{ + "time" : "2025-10-08T20:00:02.205000000Z", + "type" : "PREDICATE_COMPLETED", + "eventId" : 20, + "nanoTime" : 2205000000, + "startEvent" : 17, + "resultSize" : 12 +} + +{ + "time" : "2025-10-08T20:00:02.210000000Z", + "type" : "PREDICATE_STARTED", + "eventId" : 21, + "nanoTime" : 2210000000, + "raHash" : "f601234567890123456fg06", + "predicateName" : "QueryB::result/3#pqr678", + "appearsAs" : { + "QueryB::result/3#pqr678" : [ 0 ] + }, + "predicateType" : "SIMPLE_INTENSIONAL", + "position" : "/workspace/QueryB.ql:20,1-22,5", + "dependencies" : { + "QueryB::flowStep/2#mno345" : "e5f6012345678901234ef05", + "QueryB::entryPoint/0#jkl012" : "d4e5f601234567890123de04" + }, + "queryCausingWork" : 12 +} + +{ + "time" : "2025-10-08T20:00:02.220000000Z", + "type" : "PIPELINE_STARTED", + "eventId" : 22, + "nanoTime" : 2220000000, + "predicateStartEvent" : 21, + "raReference" : "pipeline" +} + +{ + "time" : "2025-10-08T20:00:02.250000000Z", + "type" : "PIPELINE_COMPLETED", + "eventId" : 23, + "nanoTime" : 2250000000, + "startEvent" : 22, + "counts" : [ 2 ], + "duplicationPercentages" : [ 0 ], + "resultSize" : 2 +} + +{ + "time" : "2025-10-08T20:00:02.255000000Z", + "type" : "PREDICATE_COMPLETED", + "eventId" : 24, + "nanoTime" : 2255000000, + "startEvent" : 21, + "resultSize" : 2 +} + +{ + "time" : "2025-10-08T20:00:02.300000000Z", + "type" : "QUERY_COMPLETED", + "eventId" : 25, + "nanoTime" : 2300000000, + "startEvent" : 12, + "terminationType" : "COMPLETED_SUCCESSFULLY" +} + +{ + "time" : "2025-10-08T20:00:02.500000000Z", + "type" : "LOG_FOOTER", + "eventId" : 26, + "nanoTime" : 2500000000 +} diff --git a/client/integration-tests/primitives/tools/profile_codeql_query_from_logs/multi_query_raw_log/before/monitoring-state.json b/client/integration-tests/primitives/tools/profile_codeql_query_from_logs/multi_query_raw_log/before/monitoring-state.json new file mode 100644 index 00000000..f56218ab --- /dev/null +++ b/client/integration-tests/primitives/tools/profile_codeql_query_from_logs/multi_query_raw_log/before/monitoring-state.json @@ -0,0 +1,3 @@ +{ + "sessions": [] +} diff --git a/client/integration-tests/primitives/tools/profile_codeql_query_from_logs/multi_query_raw_log/test-config.json b/client/integration-tests/primitives/tools/profile_codeql_query_from_logs/multi_query_raw_log/test-config.json new file mode 100644 index 00000000..4629205f --- /dev/null +++ b/client/integration-tests/primitives/tools/profile_codeql_query_from_logs/multi_query_raw_log/test-config.json @@ -0,0 +1,8 @@ +{ + "toolName": "profile_codeql_query_from_logs", + "arguments": { + "evaluatorLog": "client/integration-tests/primitives/tools/profile_codeql_query_from_logs/multi_query_raw_log/before/evaluator-log.jsonl", + "outputDir": "client/integration-tests/primitives/tools/profile_codeql_query_from_logs/multi_query_raw_log/after", + "topN": 10 + } +} diff --git a/client/integration-tests/primitives/tools/profile_codeql_query_from_logs/single_query_raw_log/README.md b/client/integration-tests/primitives/tools/profile_codeql_query_from_logs/single_query_raw_log/README.md new file mode 100644 index 00000000..c3b2cd66 --- /dev/null +++ b/client/integration-tests/primitives/tools/profile_codeql_query_from_logs/single_query_raw_log/README.md @@ -0,0 +1,19 @@ +# `profile_codeql_query_from_logs` - single_query_raw_log + +## Purpose + +Tests the `profile_codeql_query_from_logs` tool with a single-query raw +evaluator log (`evaluator-log.jsonl`) produced by `codeql query run`. + +## Inputs + +- `before/evaluator-log.jsonl` — Raw evaluator log from a single + `codeql query run` execution (ExampleQuery1.ql against a JavaScript database). +- `test-config.json` — Specifies `evaluatorLog`, `outputDir`, and `topN=10`. + +## Outputs + +- `after/query-evaluation-profile.json` — Structured profile with one query, + 9 predicates, 1 cache hit, and 203.81ms total duration. +- `after/query-evaluation-profile.md` — Mermaid diagram with single-query + layout showing top 9 predicates. diff --git a/client/integration-tests/primitives/tools/profile_codeql_query_from_logs/single_query_raw_log/after/monitoring-state.json b/client/integration-tests/primitives/tools/profile_codeql_query_from_logs/single_query_raw_log/after/monitoring-state.json new file mode 100644 index 00000000..41770d1c --- /dev/null +++ b/client/integration-tests/primitives/tools/profile_codeql_query_from_logs/single_query_raw_log/after/monitoring-state.json @@ -0,0 +1,26 @@ +{ + "sessions": [ + { + "id": "integration_test_session", + "calls": [ + { + "tool": "profile_codeql_query_from_logs", + "timestamp": "2025-10-08T21:00:00.000Z", + "status": "success", + "arguments": { + "evaluatorLog": "client/integration-tests/primitives/tools/profile_codeql_query_from_logs/single_query_raw_log/before/evaluator-log.jsonl", + "outputDir": "client/integration-tests/primitives/tools/profile_codeql_query_from_logs/single_query_raw_log/after", + "topN": 10 + }, + "response": { + "message": "Query log profiling completed successfully", + "filesGenerated": [ + "query-evaluation-profile.json", + "query-evaluation-profile.md" + ] + } + } + ] + } + ] +} diff --git a/client/integration-tests/primitives/tools/profile_codeql_query_from_logs/single_query_raw_log/after/query-evaluation-profile.json b/client/integration-tests/primitives/tools/profile_codeql_query_from_logs/single_query_raw_log/after/query-evaluation-profile.json new file mode 100644 index 00000000..3892c146 --- /dev/null +++ b/client/integration-tests/primitives/tools/profile_codeql_query_from_logs/single_query_raw_log/after/query-evaluation-profile.json @@ -0,0 +1,118 @@ +{ + "codeqlVersion": "2.23.1", + "logFormat": "raw", + "queries": [ + { + "queryName": "/home/runner/work/codeql-development-mcp-server/codeql-development-mcp-server/server/ql/javascript/examples/src/ExampleQuery1/ExampleQuery1.ql", + "totalDurationMs": 203.810255, + "predicateCount": 9, + "predicates": [ + { + "predicateName": "files", + "position": "/home/runner/.codeql/packages/codeql/javascript-all/2.6.11/semmlecode.javascript.dbscheme:21,1-24,3", + "durationMs": 20.935413, + "resultSize": 1, + "evaluationStrategy": "EXTENSIONAL", + "dependencies": [] + }, + { + "predicateName": "Files::Container.splitAbsolutePath/2#dispred#43b82b7b_120#join_rhs", + "position": "/home/runner/.codeql/packages/codeql/util/2.0.18/codeql/util/FileSystem.qll:220,5-221,90", + "durationMs": 58.515141, + "resultSize": 27, + "pipelineCount": 1, + "evaluationStrategy": "SIMPLE_INTENSIONAL", + "dependencies": [ + "cached_Files::Container.splitAbsolutePath/2#dispred#43b82b7b" + ] + }, + { + "predicateName": "m#Files::Impl::File.getURL/0#dispred#3f789d74#bf", + "position": "/home/runner/.codeql/packages/codeql/util/2.0.18/codeql/util/FileSystem.qll:220,5-221,90", + "durationMs": 9.624717, + "resultSize": 1, + "pipelineCount": 1, + "evaluationStrategy": "SIMPLE_INTENSIONAL", + "dependencies": [ + "Files::Container.splitAbsolutePath/2#dispred#43b82b7b_120#join_rhs", + "files" + ] + }, + { + "predicateName": "m#Files::Container.getAbsolutePath/0#dispred#051b95e1#bf", + "position": "/home/runner/.codeql/packages/codeql/util/2.0.18/codeql/util/FileSystem.qll:63,5-87,66", + "durationMs": 2.809672, + "resultSize": 1, + "pipelineCount": 1, + "evaluationStrategy": "SIMPLE_INTENSIONAL", + "dependencies": [ + "m#Files::Impl::File.getURL/0#dispred#3f789d74#bf" + ] + }, + { + "predicateName": "Files::Container.getAbsolutePath/0#dispred#051b95e1#bf", + "position": "/home/runner/.codeql/packages/codeql/util/2.0.18/codeql/util/FileSystem.qll:63,5-87,66", + "durationMs": 4.144162, + "resultSize": 1, + "pipelineCount": 1, + "evaluationStrategy": "SIMPLE_INTENSIONAL", + "dependencies": [ + "m#Files::Container.getAbsolutePath/0#dispred#051b95e1#bf", + "files" + ] + }, + { + "predicateName": "Files::Impl::File.getURL/0#dispred#3f789d74#bf", + "position": "/home/runner/.codeql/packages/codeql/util/2.0.18/codeql/util/FileSystem.qll:220,5-221,90", + "durationMs": 11.275248, + "resultSize": 1, + "pipelineCount": 1, + "evaluationStrategy": "SIMPLE_INTENSIONAL", + "dependencies": [ + "m#Files::Impl::File.getURL/0#dispred#3f789d74#bf", + "Files::Container.getAbsolutePath/0#dispred#051b95e1#bf" + ] + }, + { + "predicateName": "Files::Impl::File.getURL/0#dispred#3f789d74#bf_0#antijoin_rhs", + "position": "/home/runner/work/codeql-development-mcp-server/codeql-development-mcp-server/server/ql/javascript/examples/src/ExampleQuery1/ExampleQuery1.ql:13,1-15,80", + "durationMs": 0.72059, + "resultSize": 1, + "pipelineCount": 1, + "evaluationStrategy": "SIMPLE_INTENSIONAL", + "dependencies": [ + "Files::Impl::File.getURL/0#dispred#3f789d74#bf" + ] + }, + { + "predicateName": "Files::Container.getAbsolutePath/0#dispred#051b95e1#bf_0#antijoin_rhs", + "position": "/home/runner/work/codeql-development-mcp-server/codeql-development-mcp-server/server/ql/javascript/examples/src/ExampleQuery1/ExampleQuery1.ql:13,1-15,80", + "durationMs": 3.705741, + "resultSize": 1, + "pipelineCount": 1, + "evaluationStrategy": "SIMPLE_INTENSIONAL", + "dependencies": [ + "Files::Container.getAbsolutePath/0#dispred#051b95e1#bf" + ] + }, + { + "predicateName": "#select#query", + "position": "/home/runner/work/codeql-development-mcp-server/codeql-development-mcp-server/server/ql/javascript/examples/src/ExampleQuery1/ExampleQuery1.ql:13,1-15,80", + "durationMs": 9.013914, + "resultSize": 1, + "pipelineCount": 1, + "evaluationStrategy": "SIMPLE_INTENSIONAL", + "dependencies": [ + "m#Files::Impl::File.getURL/0#dispred#3f789d74#bf", + "Files::Container.getAbsolutePath/0#dispred#051b95e1#bf", + "Files::Container.getAbsolutePath/0#dispred#051b95e1#bf_0#antijoin_rhs", + "Files::Impl::File.getURL/0#dispred#3f789d74#bf", + "Files::Impl::File.getURL/0#dispred#3f789d74#bf_0#antijoin_rhs" + ] + } + ], + "cacheHits": 1 + } + ], + "totalEvents": 39 +} \ No newline at end of file diff --git a/client/integration-tests/primitives/tools/profile_codeql_query_from_logs/single_query_raw_log/after/query-evaluation-profile.md b/client/integration-tests/primitives/tools/profile_codeql_query_from_logs/single_query_raw_log/after/query-evaluation-profile.md new file mode 100644 index 00000000..d2f151a7 --- /dev/null +++ b/client/integration-tests/primitives/tools/profile_codeql_query_from_logs/single_query_raw_log/after/query-evaluation-profile.md @@ -0,0 +1,29 @@ +```mermaid +graph TD + + QUERY["ExampleQuery1.ql
Total: 203.81ms
Predicates: 9"] + + P0["Files::Container.splitAbsolutePath/2#dispred#43b82
58.52ms | 27 results"] + P1["files
20.94ms | 1 results"] + P2["Files::Impl::File.getURL/0#dispred#3f789d74#bf
11.28ms | 1 results"] + P3["m#Files::Impl::File.getURL/0#dispred#3f789d74#bf
9.62ms | 1 results"] + P4["#select#query
9.01ms | 1 results"] + P5["Files::Container.getAbsolutePath/0#dispred#051b95e
4.14ms | 1 results"] + P6["Files::Container.getAbsolutePath/0#dispred#051b95e
3.71ms | 1 results"] + P7["m#Files::Container.getAbsolutePath/0#dispred#051b9
2.81ms | 1 results"] + P8["Files::Impl::File.getURL/0#dispred#3f789d74#bf_0#a
0.72ms | 1 results"] + + QUERY --> P0 + QUERY --> P1 + QUERY --> P2 + QUERY --> P3 + QUERY --> P4 + QUERY --> P5 + QUERY --> P6 + QUERY --> P7 + QUERY --> P8 + + classDef default fill:#e1f5ff,stroke:#333,stroke-width:2px + classDef query fill:#ffe1e1,stroke:#333,stroke-width:3px + class QUERY query +``` \ No newline at end of file diff --git a/client/integration-tests/primitives/tools/profile_codeql_query_from_logs/single_query_raw_log/before/evaluator-log.jsonl b/client/integration-tests/primitives/tools/profile_codeql_query_from_logs/single_query_raw_log/before/evaluator-log.jsonl new file mode 100644 index 00000000..d6f1d1ec --- /dev/null +++ b/client/integration-tests/primitives/tools/profile_codeql_query_from_logs/single_query_raw_log/before/evaluator-log.jsonl @@ -0,0 +1,525 @@ +{ + "time" : "2025-10-08T19:49:44.529804209Z", + "type" : "LOG_HEADER", + "eventId" : 0, + "nanoTime" : 150740557, + "codeqlVersion" : "2.23.1", + "logVersion" : "0.5.0" +} + +{ + "time" : "2025-10-08T19:49:47.021957550Z", + "type" : "QUERY_STARTED", + "eventId" : 1, + "nanoTime" : 2643027949, + "queryName" : "/home/runner/work/codeql-development-mcp-server/codeql-development-mcp-server/server/ql/javascript/examples/src/ExampleQuery1/ExampleQuery1.ql", + "stages" : [ 0, 1 ] +} + +{ + "time" : "2025-10-08T19:49:47.039960021Z", + "type" : "CACHE_LOOKUP", + "eventId" : 2, + "nanoTime" : 2660906268, + "raHash" : "c992f399aemf3184r199npq9ll1", + "predicateName" : "cached_Files::Container.splitAbsolutePath/2#dispred#43b82b7b", + "appearsAs" : { + "cached_Files::Container.splitAbsolutePath/2#dispred#43b82b7b" : [ 0 ] + }, + "isCached" : true, + "cacheLookupResult" : "RELATION_CACHE_HIT", + "relationSize" : 27 +} + +{ + "time" : "2025-10-08T19:49:47.050725894Z", + "type" : "PREDICATE_STARTED", + "eventId" : 3, + "nanoTime" : 2671659226, + "raHash" : "ec93749gflo5p51uulng0fggcp3", + "predicateName" : "files", + "appearsAs" : { + "files" : [ 0, 1 ] + }, + "predicateType" : "EXTENSIONAL", + "position" : "/home/runner/.codeql/packages/codeql/javascript-all/2.6.11/semmlecode.javascript.dbscheme:21,1-24,3", + "dependencies" : { }, + "queryCausingWork" : 1 +} + +{ + "time" : "2025-10-08T19:49:47.071485507Z", + "type" : "PREDICATE_COMPLETED", + "eventId" : 4, + "nanoTime" : 2692594639, + "startEvent" : 3, + "resultSize" : 1 +} + +{ + "time" : "2025-10-08T19:49:47.087274311Z", + "type" : "PREDICATE_STARTED", + "eventId" : 5, + "nanoTime" : 2708624143, + "raHash" : "a583e3e5r8hoigirv1fb4dg4co6", + "predicateName" : "Files::Container.splitAbsolutePath/2#dispred#43b82b7b_120#join_rhs", + "appearsAs" : { + "Files::Container.splitAbsolutePath/2#dispred#43b82b7b_120#join_rhs" : [ 1 ] + }, + "predicateType" : "SIMPLE_INTENSIONAL", + "position" : "/home/runner/.codeql/packages/codeql/util/2.0.18/codeql/util/FileSystem.qll:220,5-221,90", + "ra" : { + "pipeline" : [ + " {3} r1 = SCAN `cached_Files::Container.splitAbsolutePath/2#dispred#43b82b7b` OUTPUT In.1, In.2, In.0", + " return r1" + ] + }, + "dependencies" : { + "cached_Files::Container.splitAbsolutePath/2#dispred#43b82b7b" : "c992f399aemf3184r199npq9ll1" + }, + "queryCausingWork" : 1 +} + +{ + "time" : "2025-10-08T19:49:47.106645173Z", + "type" : "PIPELINE_STARTED", + "eventId" : 6, + "nanoTime" : 2727534823, + "predicateStartEvent" : 5, + "raReference" : "pipeline" +} + +{ + "time" : "2025-10-08T19:49:47.134628216Z", + "type" : "PIPELINE_COMPLETED", + "eventId" : 7, + "nanoTime" : 2755517616, + "startEvent" : 6, + "counts" : [ 27 ], + "duplicationPercentages" : [ 3 ], + "resultSize" : 27 +} + +{ + "time" : "2025-10-08T19:49:47.146245576Z", + "type" : "PREDICATE_COMPLETED", + "eventId" : 8, + "nanoTime" : 2767139284, + "startEvent" : 5, + "resultSize" : 27 +} + +{ + "time" : "2025-10-08T19:49:47.149212523Z", + "type" : "PREDICATE_STARTED", + "eventId" : 9, + "nanoTime" : 2770110139, + "raHash" : "535002to029tt7tlvjkjqp7i3v1", + "predicateName" : "m#Files::Impl::File.getURL/0#dispred#3f789d74#bf", + "appearsAs" : { + "m#Files::Impl::File.getURL/0#dispred#3f789d74#bf" : [ 1 ] + }, + "predicateType" : "SIMPLE_INTENSIONAL", + "position" : "/home/runner/.codeql/packages/codeql/util/2.0.18/codeql/util/FileSystem.qll:220,5-221,90", + "ra" : { + "pipeline" : [ + " {2} r1 = CONSTANT(unique string, unique int)[\"ExampleQuery1.js\",1]", + " {1} | JOIN WITH `Files::Container.splitAbsolutePath/2#dispred#43b82b7b_120#join_rhs` ON FIRST 2 OUTPUT Rhs.2", + " {1} | JOIN WITH files ON FIRST 1 OUTPUT Lhs.0", + " return r1" + ] + }, + "dependencies" : { + "Files::Container.splitAbsolutePath/2#dispred#43b82b7b_120#join_rhs" : "a583e3e5r8hoigirv1fb4dg4co6", + "files" : "ec93749gflo5p51uulng0fggcp3" + }, + "queryCausingWork" : 1 +} + +{ + "time" : "2025-10-08T19:49:47.154622196Z", + "type" : "PIPELINE_STARTED", + "eventId" : 10, + "nanoTime" : 2775505835, + "predicateStartEvent" : 9, + "raReference" : "pipeline" +} + +{ + "time" : "2025-10-08T19:49:47.158192553Z", + "type" : "PIPELINE_COMPLETED", + "eventId" : 11, + "nanoTime" : 2779072606, + "startEvent" : 10, + "counts" : [ 1, 1, 1 ], + "duplicationPercentages" : [ 0, 0, 0 ], + "resultSize" : 1 +} + +{ + "time" : "2025-10-08T19:49:47.158856216Z", + "type" : "PREDICATE_COMPLETED", + "eventId" : 12, + "nanoTime" : 2779734856, + "startEvent" : 9, + "resultSize" : 1 +} + +{ + "time" : "2025-10-08T19:49:47.162134767Z", + "type" : "PREDICATE_STARTED", + "eventId" : 13, + "nanoTime" : 2783012486, + "raHash" : "940dd3n42vb479n5h52qepmkgnc", + "predicateName" : "m#Files::Container.getAbsolutePath/0#dispred#051b95e1#bf", + "appearsAs" : { + "m#Files::Container.getAbsolutePath/0#dispred#051b95e1#bf" : [ 1 ] + }, + "predicateType" : "SIMPLE_INTENSIONAL", + "position" : "/home/runner/.codeql/packages/codeql/util/2.0.18/codeql/util/FileSystem.qll:63,5-87,66", + "ra" : { + "pipeline" : [ + " return `m#Files::Impl::File.getURL/0#dispred#3f789d74#bf`" + ] + }, + "dependencies" : { + "m#Files::Impl::File.getURL/0#dispred#3f789d74#bf" : "535002to029tt7tlvjkjqp7i3v1" + }, + "queryCausingWork" : 1 +} + +{ + "time" : "2025-10-08T19:49:47.162267255Z", + "type" : "PIPELINE_STARTED", + "eventId" : 14, + "nanoTime" : 2783142379, + "predicateStartEvent" : 13, + "raReference" : "pipeline" +} + +{ + "time" : "2025-10-08T19:49:47.164692548Z", + "type" : "PIPELINE_COMPLETED", + "eventId" : 15, + "nanoTime" : 2785568984, + "startEvent" : 14, + "counts" : [ ], + "duplicationPercentages" : [ ], + "resultSize" : 1 +} + +{ + "time" : "2025-10-08T19:49:47.164947796Z", + "type" : "PREDICATE_COMPLETED", + "eventId" : 16, + "nanoTime" : 2785822158, + "startEvent" : 13, + "resultSize" : 1 +} + +{ + "time" : "2025-10-08T19:49:47.165433155Z", + "type" : "PREDICATE_STARTED", + "eventId" : 17, + "nanoTime" : 2786308509, + "raHash" : "5d0580ok8avjj0ck0uc01oaqp2e", + "predicateName" : "Files::Container.getAbsolutePath/0#dispred#051b95e1#bf", + "appearsAs" : { + "Files::Container.getAbsolutePath/0#dispred#051b95e1#bf" : [ 1 ] + }, + "predicateType" : "SIMPLE_INTENSIONAL", + "position" : "/home/runner/.codeql/packages/codeql/util/2.0.18/codeql/util/FileSystem.qll:63,5-87,66", + "ra" : { + "pipeline" : [ + " {2} r1 = JOIN `m#Files::Container.getAbsolutePath/0#dispred#051b95e1#bf` WITH files ON FIRST 1 OUTPUT Lhs.0, Rhs.1", + " return r1" + ] + }, + "dependencies" : { + "m#Files::Container.getAbsolutePath/0#dispred#051b95e1#bf" : "940dd3n42vb479n5h52qepmkgnc", + "files" : "ec93749gflo5p51uulng0fggcp3" + }, + "queryCausingWork" : 1 +} + +{ + "time" : "2025-10-08T19:49:47.165551527Z", + "type" : "PIPELINE_STARTED", + "eventId" : 18, + "nanoTime" : 2786425498, + "predicateStartEvent" : 17, + "raReference" : "pipeline" +} + +{ + "time" : "2025-10-08T19:49:47.166018732Z", + "type" : "PIPELINE_COMPLETED", + "eventId" : 19, + "nanoTime" : 2786893585, + "startEvent" : 18, + "counts" : [ 1 ], + "duplicationPercentages" : [ 0 ], + "resultSize" : 1 +} + +{ + "time" : "2025-10-08T19:49:47.166289499Z", + "type" : "PREDICATE_COMPLETED", + "eventId" : 20, + "nanoTime" : 2790452671, + "startEvent" : 17, + "resultSize" : 1 +} + +{ + "time" : "2025-10-08T19:49:47.173633475Z", + "type" : "PREDICATE_STARTED", + "eventId" : 21, + "nanoTime" : 2794513007, + "raHash" : "8180853tra2v3i5sr7q4ja1qcr3", + "predicateName" : "Files::Impl::File.getURL/0#dispred#3f789d74#bf", + "appearsAs" : { + "Files::Impl::File.getURL/0#dispred#3f789d74#bf" : [ 1 ] + }, + "predicateType" : "SIMPLE_INTENSIONAL", + "position" : "/home/runner/.codeql/packages/codeql/util/2.0.18/codeql/util/FileSystem.qll:220,5-221,90", + "ra" : { + "pipeline" : [ + " {4} r1 = JOIN `m#Files::Impl::File.getURL/0#dispred#3f789d74#bf` WITH `Files::Container.getAbsolutePath/0#dispred#051b95e1#bf` ON FIRST 1 OUTPUT Lhs.0, _, Rhs.1, _", + " {2} | REWRITE WITH Tmp.1 := \"file://\", Tmp.3 := \":0:0:0:0\", Out.1 := (Tmp.1 ++ In.2 ++ Tmp.3) KEEPING 2", + " return r1" + ] + }, + "dependencies" : { + "m#Files::Impl::File.getURL/0#dispred#3f789d74#bf" : "535002to029tt7tlvjkjqp7i3v1", + "Files::Container.getAbsolutePath/0#dispred#051b95e1#bf" : "5d0580ok8avjj0ck0uc01oaqp2e" + }, + "queryCausingWork" : 1 +} + +{ + "time" : "2025-10-08T19:49:47.175164242Z", + "type" : "PIPELINE_STARTED", + "eventId" : 22, + "nanoTime" : 2796041690, + "predicateStartEvent" : 21, + "raReference" : "pipeline" +} + +{ + "time" : "2025-10-08T19:49:47.181902583Z", + "type" : "PIPELINE_COMPLETED", + "eventId" : 23, + "nanoTime" : 2802782305, + "startEvent" : 22, + "counts" : [ 1, 1 ], + "duplicationPercentages" : [ 0, 0 ], + "resultSize" : 1 +} + +{ + "time" : "2025-10-08T19:49:47.184910367Z", + "type" : "PREDICATE_COMPLETED", + "eventId" : 24, + "nanoTime" : 2805788255, + "startEvent" : 21, + "resultSize" : 1 +} + +{ + "time" : "2025-10-08T19:49:47.185605148Z", + "type" : "PREDICATE_STARTED", + "eventId" : 25, + "nanoTime" : 2806487966, + "raHash" : "56196b1sn5ab4rg4jgblcgss0b3", + "predicateName" : "Files::Impl::File.getURL/0#dispred#3f789d74#bf_0#antijoin_rhs", + "appearsAs" : { + "Files::Impl::File.getURL/0#dispred#3f789d74#bf_0#antijoin_rhs" : [ 1 ] + }, + "predicateType" : "SIMPLE_INTENSIONAL", + "position" : "/home/runner/work/codeql-development-mcp-server/codeql-development-mcp-server/server/ql/javascript/examples/src/ExampleQuery1/ExampleQuery1.ql:13,1-15,80", + "ra" : { + "pipeline" : [ + " {1} r1 = SCAN `Files::Impl::File.getURL/0#dispred#3f789d74#bf` OUTPUT In.0", + " return r1" + ] + }, + "dependencies" : { + "Files::Impl::File.getURL/0#dispred#3f789d74#bf" : "8180853tra2v3i5sr7q4ja1qcr3" + }, + "queryCausingWork" : 1 +} + +{ + "time" : "2025-10-08T19:49:47.185730042Z", + "type" : "PIPELINE_STARTED", + "eventId" : 26, + "nanoTime" : 2806604664, + "predicateStartEvent" : 25, + "raReference" : "pipeline" +} + +{ + "time" : "2025-10-08T19:49:47.186079697Z", + "type" : "PIPELINE_COMPLETED", + "eventId" : 27, + "nanoTime" : 2806954851, + "startEvent" : 26, + "counts" : [ 1 ], + "duplicationPercentages" : [ 0 ], + "resultSize" : 1 +} + +{ + "time" : "2025-10-08T19:49:47.186333212Z", + "type" : "PREDICATE_COMPLETED", + "eventId" : 28, + "nanoTime" : 2807208556, + "startEvent" : 25, + "resultSize" : 1 +} + +{ + "time" : "2025-10-08T19:49:47.186718804Z", + "type" : "PREDICATE_STARTED", + "eventId" : 29, + "nanoTime" : 2807593857, + "raHash" : "bdc5c3gf4co1b8r0591sebsj05b", + "predicateName" : "Files::Container.getAbsolutePath/0#dispred#051b95e1#bf_0#antijoin_rhs", + "appearsAs" : { + "Files::Container.getAbsolutePath/0#dispred#051b95e1#bf_0#antijoin_rhs" : [ 1 ] + }, + "predicateType" : "SIMPLE_INTENSIONAL", + "position" : "/home/runner/work/codeql-development-mcp-server/codeql-development-mcp-server/server/ql/javascript/examples/src/ExampleQuery1/ExampleQuery1.ql:13,1-15,80", + "ra" : { + "pipeline" : [ + " {1} r1 = SCAN `Files::Container.getAbsolutePath/0#dispred#051b95e1#bf` OUTPUT In.0", + " return r1" + ] + }, + "dependencies" : { + "Files::Container.getAbsolutePath/0#dispred#051b95e1#bf" : "5d0580ok8avjj0ck0uc01oaqp2e" + }, + "queryCausingWork" : 1 +} + +{ + "time" : "2025-10-08T19:49:47.186816487Z", + "type" : "PIPELINE_STARTED", + "eventId" : 30, + "nanoTime" : 2807690178, + "predicateStartEvent" : 29, + "raReference" : "pipeline" +} + +{ + "time" : "2025-10-08T19:49:47.187117691Z", + "type" : "PIPELINE_COMPLETED", + "eventId" : 31, + "nanoTime" : 2807992294, + "startEvent" : 30, + "counts" : [ 1 ], + "duplicationPercentages" : [ 0 ], + "resultSize" : 1 +} + +{ + "time" : "2025-10-08T19:49:47.190423483Z", + "type" : "PREDICATE_COMPLETED", + "eventId" : 32, + "nanoTime" : 2811299598, + "startEvent" : 29, + "resultSize" : 1 +} + +{ + "time" : "2025-10-08T19:49:47.191409730Z", + "type" : "PREDICATE_STARTED", + "eventId" : 33, + "nanoTime" : 2812285565, + "raHash" : "54c915k0noqin86q4p528fuifd5", + "predicateName" : "#select#query", + "appearsAs" : { + "#select#query" : [ 1 ] + }, + "predicateType" : "SIMPLE_INTENSIONAL", + "position" : "/home/runner/work/codeql-development-mcp-server/codeql-development-mcp-server/server/ql/javascript/examples/src/ExampleQuery1/ExampleQuery1.ql:13,1-15,80", + "ra" : { + "pipeline" : [ + " {2} r1 = JOIN `m#Files::Impl::File.getURL/0#dispred#3f789d74#bf` WITH `Files::Container.getAbsolutePath/0#dispred#051b95e1#bf` ON FIRST 1 OUTPUT Lhs.0, Rhs.1", + "", + " {1} r2 = `m#Files::Impl::File.getURL/0#dispred#3f789d74#bf` AND NOT `Files::Container.getAbsolutePath/0#dispred#051b95e1#bf_0#antijoin_rhs`(FIRST 1)", + " {2} | SCAN OUTPUT In.0, _", + " {2} | REWRITE WITH Out.1 := \"(no string representation)\"", + "", + " {2} r3 = r1 UNION r2", + " {4} | JOIN WITH `Files::Impl::File.getURL/0#dispred#3f789d74#bf` ON FIRST 1 OUTPUT Lhs.0, Lhs.1, Rhs.1, _", + " {4} | REWRITE WITH Out.3 := \"Example test code file found for codeql_test_extract example query.\"", + "", + " {1} r4 = `m#Files::Impl::File.getURL/0#dispred#3f789d74#bf` AND NOT `Files::Container.getAbsolutePath/0#dispred#051b95e1#bf_0#antijoin_rhs`(FIRST 1)", + " {2} | SCAN OUTPUT In.0, _", + " {2} | REWRITE WITH Out.1 := \"(no string representation)\"", + "", + " {2} r5 = r1 UNION r4", + " {2} | AND NOT `Files::Impl::File.getURL/0#dispred#3f789d74#bf_0#antijoin_rhs`(FIRST 1)", + " {4} | SCAN OUTPUT In.0, In.1, _, _", + " {4} | REWRITE WITH Out.2 := \"\", Out.3 := \"Example test code file found for codeql_test_extract example query.\"", + "", + " {4} r6 = r3 UNION r5", + " return r6" + ] + }, + "dependencies" : { + "m#Files::Impl::File.getURL/0#dispred#3f789d74#bf" : "535002to029tt7tlvjkjqp7i3v1", + "Files::Container.getAbsolutePath/0#dispred#051b95e1#bf" : "5d0580ok8avjj0ck0uc01oaqp2e", + "Files::Container.getAbsolutePath/0#dispred#051b95e1#bf_0#antijoin_rhs" : "bdc5c3gf4co1b8r0591sebsj05b", + "Files::Impl::File.getURL/0#dispred#3f789d74#bf" : "8180853tra2v3i5sr7q4ja1qcr3", + "Files::Impl::File.getURL/0#dispred#3f789d74#bf_0#antijoin_rhs" : "56196b1sn5ab4rg4jgblcgss0b3" + }, + "queryCausingWork" : 1 +} + +{ + "time" : "2025-10-08T19:49:47.193543417Z", + "type" : "PIPELINE_STARTED", + "eventId" : 34, + "nanoTime" : 2814420885, + "predicateStartEvent" : 33, + "raReference" : "pipeline" +} + +{ + "time" : "2025-10-08T19:49:47.197753292Z", + "type" : "PIPELINE_COMPLETED", + "eventId" : 35, + "nanoTime" : 2818630580, + "startEvent" : 34, + "counts" : [ 1, -1, -1, 0, 0, -1, 1, 1, 1, -1, -1, 0, 0, -1, 1, -1, 0, 0, -1, 1 ], + "duplicationPercentages" : [ 0, -1, -1, 0, 0, -1, 0, 0, 0, -1, -1, 0, 0, -1, 0, -1, 0, 0, -1, 0 ], + "resultSize" : 1 +} + +{ + "time" : "2025-10-08T19:49:47.200422492Z", + "type" : "PREDICATE_COMPLETED", + "eventId" : 36, + "nanoTime" : 2821299479, + "startEvent" : 33, + "resultSize" : 1 +} + +{ + "time" : "2025-10-08T19:49:47.225950056Z", + "type" : "QUERY_COMPLETED", + "eventId" : 37, + "nanoTime" : 2846838204, + "startEvent" : 1, + "terminationType" : "COMPLETED_SUCCESSFULLY" +} + +{ + "time" : "2025-10-08T19:49:47.243890810Z", + "type" : "LOG_FOOTER", + "eventId" : 38, + "nanoTime" : 2864779539 +} \ No newline at end of file diff --git a/client/integration-tests/primitives/tools/profile_codeql_query_from_logs/single_query_raw_log/before/monitoring-state.json b/client/integration-tests/primitives/tools/profile_codeql_query_from_logs/single_query_raw_log/before/monitoring-state.json new file mode 100644 index 00000000..f56218ab --- /dev/null +++ b/client/integration-tests/primitives/tools/profile_codeql_query_from_logs/single_query_raw_log/before/monitoring-state.json @@ -0,0 +1,3 @@ +{ + "sessions": [] +} diff --git a/client/integration-tests/primitives/tools/profile_codeql_query_from_logs/single_query_raw_log/test-config.json b/client/integration-tests/primitives/tools/profile_codeql_query_from_logs/single_query_raw_log/test-config.json new file mode 100644 index 00000000..c64f5c12 --- /dev/null +++ b/client/integration-tests/primitives/tools/profile_codeql_query_from_logs/single_query_raw_log/test-config.json @@ -0,0 +1,8 @@ +{ + "toolName": "profile_codeql_query_from_logs", + "arguments": { + "evaluatorLog": "client/integration-tests/primitives/tools/profile_codeql_query_from_logs/single_query_raw_log/before/evaluator-log.jsonl", + "outputDir": "client/integration-tests/primitives/tools/profile_codeql_query_from_logs/single_query_raw_log/after", + "topN": 10 + } +} diff --git a/client/src/lib/integration-test-runner.js b/client/src/lib/integration-test-runner.js index 6166f30d..7631ee21 100644 --- a/client/src/lib/integration-test-runner.js +++ b/client/src/lib/integration-test-runner.js @@ -1024,6 +1024,19 @@ export class IntegrationTestRunner { } else { throw new Error(`test-config.json not found for ${toolName}/${testCase}`); } + } else if (toolName === "profile_codeql_query_from_logs") { + // Read from test-config.json for profile_codeql_query_from_logs tool + const testConfigPath = path.join(testCaseDir, "test-config.json"); + if (fs.existsSync(testConfigPath)) { + const testConfig = JSON.parse(fs.readFileSync(testConfigPath, "utf8")); + if (testConfig.arguments) { + Object.assign(params, testConfig.arguments); + } else { + throw new Error(`test-config.json missing arguments for ${toolName}/${testCase}`); + } + } else { + throw new Error(`test-config.json not found for ${toolName}/${testCase}`); + } } else if (toolName === "validate_codeql_query") { params.query = "from int i select i"; params.language = "java"; diff --git a/docs/ql-mcp/tools.md b/docs/ql-mcp/tools.md index 84980810..c04a9f0e 100644 --- a/docs/ql-mcp/tools.md +++ b/docs/ql-mcp/tools.md @@ -4,7 +4,7 @@ ## Overview -The server exposes **36 default tools** and **11 opt-in monitoring tools**. Default tools are registered on startup; monitoring tools require explicit opt-in (see [Monitoring and Reporting](../mcp-server-monitoring-and-reporting.md)). Users control which tools are enabled in their MCP client configuration. +The server exposes **38 default tools** and **11 opt-in monitoring tools**. Default tools are registered on startup; monitoring tools require explicit opt-in (see [Monitoring and Reporting](../mcp-server-monitoring-and-reporting.md)). Users control which tools are enabled in their MCP client configuration. ## Default Tools @@ -46,18 +46,20 @@ The server exposes **36 default tools** and **11 opt-in monitoring tools**. Defa ### Query Development Tools -| Tool | Description | -| ------------------------- | ------------------------------------------------------------------------------------------------------------------ | -| `create_codeql_query` | Create directory structure and files for a new CodeQL query with tests | -| `find_class_position` | Find the start/end line and column of a class for quick evaluation | -| `find_codeql_query_files` | Find and track all files and directories related to a CodeQL query, including resolved metadata | -| `find_predicate_position` | Find the start/end line and column of a predicate for quick evaluation | -| `list_codeql_databases` | List CodeQL databases discovered in configured base directories (`CODEQL_DATABASES_BASE_DIRS`) | -| `list_query_run_results` | List discovered query run result directories with artifact inventory (`CODEQL_QUERY_RUN_RESULTS_DIRS`) | -| `profile_codeql_query` | Profile the performance of a CodeQL query run against a specific database by analyzing the evaluator log JSON file | -| `quick_evaluate` | Quick evaluate either a class or a predicate in a CodeQL query for debugging | -| `register_database` | Register a CodeQL database given a local path to the database directory | -| `validate_codeql_query` | Quick heuristic validation for CodeQL query structure (does not compile the query) | +| Tool | Description | +| -------------------------------- | ------------------------------------------------------------------------------------------------------------------ | +| `create_codeql_query` | Create directory structure and files for a new CodeQL query with tests | +| `find_class_position` | Find the start/end line and column of a class for quick evaluation | +| `find_codeql_query_files` | Find and track all files and directories related to a CodeQL query, including resolved metadata | +| `find_predicate_position` | Find the start/end line and column of a predicate for quick evaluation | +| `list_codeql_databases` | List CodeQL databases discovered in configured base directories (`CODEQL_DATABASES_BASE_DIRS`) | +| `list_mrva_run_results` | List MRVA (Multi-Repository Variant Analysis) run results with per-repo details (`CODEQL_MRVA_RUN_RESULTS_DIRS`) | +| `list_query_run_results` | List discovered query run result directories with artifact inventory (`CODEQL_QUERY_RUN_RESULTS_DIRS`) | +| `profile_codeql_query` | Profile the performance of a CodeQL query run against a specific database by analyzing the evaluator log JSON file | +| `profile_codeql_query_from_logs` | Parse existing CodeQL evaluator logs into a performance profile without re-running the query | +| `quick_evaluate` | Quick evaluate either a class or a predicate in a CodeQL query for debugging | +| `register_database` | Register a CodeQL database given a local path to the database directory | +| `validate_codeql_query` | Quick heuristic validation for CodeQL query structure (does not compile the query) | ## Optional Monitoring Tools diff --git a/docs/vscode/IMPLEMENTATION.md b/docs/vscode/IMPLEMENTATION.md new file mode 100644 index 00000000..8d1887cc --- /dev/null +++ b/docs/vscode/IMPLEMENTATION.md @@ -0,0 +1,312 @@ +# VS Code Extension — Implementation Tracker + +> Tracks the implementation and testing of new features that integrate the +> `codeql-development-mcp-server` with the `github.vscode-codeql` extension. + +## Branch + +`dd/vscode-extension/1` (base: `main`) + +## Completed on Branch + +The initial commit (`9ea4b14`) adds: + +- **VS Code extension** (`extensions/vscode/`) — registers the MCP server, + discovers the CodeQL CLI, installs tool query packs, and bridges the + vscode-codeql extension (database/query-results watchers). +- **Server: `list_codeql_databases` tool** — discovers databases from + `CODEQL_DATABASES_BASE_DIRS`. +- **Server: `list_query_run_results` tool** — discovers query run result + directories from `CODEQL_QUERY_RUN_RESULTS_DIRS`. +- **Server: `discovery-config` module** — parses colon-separated env var + directory lists. +- Docs: `docs/vscode/extension.md`, updated `docs/ql-mcp/tools.md`. + +--- + +## TODO 1: `list_mrva_run_results` Tool + +**Status:** Not started + +### Purpose + +List available MRVA (Multi-Repository Variant Analysis) run results stored by +the vscode-codeql extension. + +### Directory Structure (observed) + +``` +~/Library/Application Support/Code/User/globalStorage/github.vscode-codeql/variant-analyses/ +├── 20438/ +│ └── timestamp +├── 20439/ +│ └── timestamp +├── 20440/ +│ ├── repo_states.json +│ └── timestamp +├── 20442/ +│ ├── repo_states.json +│ ├── timestamp +│ ├── arduino/Arduino/ +│ │ ├── repo_task.json # VariantAnalysisRepositoryTask +│ │ ├── results.zip +│ │ └── results/ +│ │ ├── results.sarif +│ │ └── results.bqrs +│ └── exported-results/ +│ └── results_/ +│ ├── _summary.md +│ └── -.md +``` + +### `repo_task.json` Schema + +```json +{ + "repository": { "id": 919161, "fullName": "arduino/Arduino", "private": false }, + "analysisStatus": "succeeded", + "resultCount": 1, + "artifactSizeInBytes": 14311, + "databaseCommitSha": "a0df6e0...", + "sourceLocationPrefix": "/home/runner/work/Arduino/Arduino", + "artifactUrl": "https://..." +} +``` + +### `repo_states.json` Schema + +```json +{ + "": { + "repositoryId": 919161, + "downloadStatus": "succeeded" + } +} +``` + +### Implementation Plan + +1. **`server/src/lib/discovery-config.ts`** — add `getMrvaRunResultsDirs()` + reading from `CODEQL_MRVA_RUN_RESULTS_DIRS` env var. +2. **`server/src/tools/codeql/list-mrva-run-results.ts`** — new tool that: + - Scans each dir in `CODEQL_MRVA_RUN_RESULTS_DIRS` for numeric + subdirectories (the MRVA run ID). + - For each run, reads `repo_states.json` and enumerates + `//repo_task.json` entries. + - Reports: run ID, timestamp, number of repos scanned, per-repo status, + result counts, available artifacts (SARIF, BQRS). + - Supports optional filtering by run ID. +3. **`server/src/tools/codeql/index.ts`** — export the new registration fn. +4. **`server/src/tools/codeql-tools.ts`** — register the new tool. +5. **`extensions/vscode/src/bridge/environment-builder.ts`** — set + `CODEQL_MRVA_RUN_RESULTS_DIRS` to `storagePaths.getVariantAnalysisStoragePath()`. +6. **Unit tests:** `server/test/src/tools/codeql/list-mrva-run-results.test.ts` + and `server/test/src/lib/discovery-config.test.ts` (extend). +7. **Client integration tests:** + `client/integration-tests/primitives/tools/list_mrva_run_results/`. + +### Acceptance Criteria + +- [ ] Tool returns structured list of MRVA runs with repo details. +- [ ] Tool handles: empty dirs, missing `repo_states.json`, partial downloads. +- [ ] VS Code extension automatically sets the env var. +- [ ] Unit tests pass. +- [ ] Client integration tests pass. + +--- + +## TODO 2: `profile_codeql_query_from_logs` Tool + +**Status:** Not started + +### Purpose + +Parse CodeQL query evaluation logs into a performance profile, without +requiring re-execution of the query. Works with logs from: + +- `codeql query run` (single query → single QUERY_STARTED/COMPLETED) +- `codeql database analyze` (multiple queries → multiple QUERY_STARTED/COMPLETED) +- vscode-codeql query runs (stored under `CODEQL_QUERY_RUN_RESULTS_DIRS`) + +### Evaluator Log Format (`evaluator-log.jsonl`) + +Pretty-printed JSON objects separated by `}\n{`. Event types observed: + +| Event Type | Single Query | Multi Query | Description | +| --------------------- | ------------ | ----------- | ---------------------------------- | +| `LOG_HEADER` | 1 | 1 | Version info, start time | +| `QUERY_STARTED` | 1 | N | Query name, eventId | +| `PREDICATE_STARTED` | many | many | Has `queryCausingWork` → eventId | +| `PREDICATE_COMPLETED` | many | many | `startEvent`, duration, resultSize | +| `PIPELINE_STARTED` | many | many | `predicateStartEvent`, raReference | +| `PIPELINE_COMPLETED` | many | many | Mirrors PIPELINE_STARTED | +| `CACHE_LOOKUP` | some | some | Cache hits | +| `SENTINEL_EMPTY` | many | many | Empty predicate evaluations | +| `QUERY_COMPLETED` | 1 | N | `startEvent` → query eventId | +| `LOG_FOOTER` | 1 | 1 | End marker | + +**Key multi-query insight:** Each `PREDICATE_STARTED` event has +`queryCausingWork` referencing the `eventId` of the `QUERY_STARTED` event that +triggered it. This allows grouping predicates by query in `database analyze` +logs. + +### vscode-codeql Generated Files Per Query Run + +| File | Size | Purpose | +| ------------------------------------ | -------- | ---------------------------- | +| `evaluator-log.jsonl` | ~13-80MB | Raw structured evaluator log | +| `evaluator-log.summary` | ~23MB | Human-readable summary | +| `evaluator-log.summary.jsonl` | ~18MB | Machine-readable summary | +| `evaluator-log.summary.map` | ~1MB | Source mapping | +| `evaluator-log.summary.symbols.json` | ~1.6MB | Symbol metadata | +| `evaluator-log-end.summary` | ~61KB | End-of-evaluation summary | +| `query.log` | ~7.6MB | Full query server log | +| `results.bqrs` | varies | Binary query results | +| `results-interpreted.sarif` | varies | Interpreted SARIF results | +| `results.dil` | ~26MB | DIL representation | +| `timestamp` | 13B | ISO timestamp | + +### `evaluator-log.summary.jsonl` Format + +Unlike the raw log, the summary uses **different key sets** per event type +(no `type` field). Key patterns: + +1. **Header**: `{ summaryLogVersion, codeqlVersion, startTime }` +2. **Sentinel empty**: `{ completionTime, raHash, predicateName, appearsAs, +evaluationStrategy: "SENTINEL_EMPTY", sentinelRaHash, isCached? }` +3. **Computed predicate**: `{ completionTime, raHash, predicateName, appearsAs, +evaluationStrategy, dependencies, millis, pipelineRuns, position?, +queryCausingWork, ra, resultSize }` +4. **Recursive predicate**: additionally has `deltaSizes, layerSize, +predicateIterationMillis, mainHash` + +### Implementation Plan + +1. **`server/src/lib/evaluator-log-parser.ts`** — reusable streaming parser: + - `parseEvaluatorLogStreaming(logPath, callback)` — stream-parses raw + `evaluator-log.jsonl` using readline + brace-depth tracking. + - `parseEvaluatorLogSummary(logPath, callback)` — stream-parses + `evaluator-log.summary.jsonl`. + - Shared `ProfileData` interface with per-query breakdown. +2. **`server/src/tools/codeql/profile-codeql-query-from-logs.ts`** — new tool: + - Input: `evaluatorLog` (path to `evaluator-log.jsonl` or + `evaluator-log.summary.jsonl`) + optional `outputDir`. + - Auto-detects format (raw vs summary) from the first event. + - Produces `ProfileData` with: + - Per-query breakdown (for multi-query logs). + - Top-N most expensive predicates. + - Total duration, pipeline counts, cache hit rates. + - Outputs JSON profile + optional Mermaid diagram. + - Works with logs from any source: query runs, database analyze, + vscode-codeql query history. +3. **`server/src/tools/codeql/index.ts`** — export new registration fn. +4. **`server/src/tools/codeql-tools.ts`** — register the new tool. +5. **Unit tests:** `server/test/src/lib/evaluator-log-parser.test.ts` and + `server/test/src/tools/codeql/profile-codeql-query-from-logs.test.ts`. +6. **Client integration tests:** + `client/integration-tests/primitives/tools/profile_codeql_query_from_logs/`. + +### Acceptance Criteria + +- [ ] Parses single-query `evaluator-log.jsonl` (from `codeql query run`). +- [ ] Parses multi-query `evaluator-log.jsonl` (from `codeql database analyze`). +- [ ] Parses `evaluator-log.summary.jsonl` (from vscode-codeql query history). +- [ ] Produces per-query profiling breakdown for multi-query logs. +- [ ] Reports top-N most expensive predicates with durations. +- [ ] Handles large logs (80MB+) without excessive memory usage. +- [ ] Unit tests pass. +- [ ] Client integration tests pass. + +--- + +## TODO 3: Enhance `codeql_query_run` and `codeql_database_analyze` Logging + +**Status:** Not started + +### Purpose + +Both tools should always produce the full set of log files that vscode-codeql +generates per query run, so that `profile_codeql_query_from_logs` can analyze +any run without special setup. This will allow deprecating and eventually +removing the `profile_codeql_query` tool. + +### Current State + +**`codeql_query_run`** already: + +- Sets `--evaluator-log` to the log directory ✓ +- Sets `--output` for BQRS ✓ +- Generates SARIF interpretation post-run ✓ +- Creates a `timestamp` file ✓ +- Uses `--logdir` and `--verbosity=progress+` ✓ +- Uses `timeout: 0` (no timeout) via FRESH_PROCESS_SUBCOMMANDS ✓ + +**Missing for `codeql_query_run`:** + +- Does NOT run `codeql generate log-summary` to produce summary files. +- Does NOT enable `--tuple-counting` by default when evaluator logging is on. + +**`codeql_database_analyze`** currently: + +- Has NO log directory setup ✗ +- Does NOT set `--evaluator-log` automatically ✗ +- Does NOT generate summary files ✗ +- Does NOT create a timestamp ✗ +- Does NOT have a `logDir` parameter ✗ +- Uses `timeout: 0` via FRESH_PROCESS_SUBCOMMANDS ✓ + +### Implementation Plan + +1. **`server/src/tools/codeql/database-analyze.ts`** — add `logDir` parameter + and `evaluator-log` / `tuple-counting` / `evaluator-log-level` options to + the input schema. +2. **`server/src/lib/cli-tool-registry.ts`** — in the `registerCLITool`: + - Add `codeql_database_analyze` alongside `codeql_query_run` in the log + directory setup block (set `--evaluator-log`, `--logdir`, `timestamp`, + `--verbosity`). + - For both tools, after successful execution, run + `codeql generate log-summary --format=jsonl` piping the raw evaluator log + to produce `evaluator-log.summary.jsonl`. + - Enable `--tuple-counting` by default when evaluator logging is active. +3. **Update unit tests** for the modified tools. + +### Acceptance Criteria + +- [ ] `codeql_query_run` produces: `evaluator-log.jsonl`, + `evaluator-log.summary.jsonl`, `results.bqrs`, `results-interpreted.sarif`, + `timestamp`. +- [ ] `codeql_database_analyze` produces the same set of log files. +- [ ] `--tuple-counting` is enabled by default for both tools. +- [ ] Logs are discoverable by `list_query_run_results`. +- [ ] Unit tests pass. + +--- + +## TODO 4: VS Code Extension Updates + +**Status:** Not started + +### `environment-builder.ts` Changes + +- Set `CODEQL_DATABASES_BASE_DIRS` from database storage path. +- Set `CODEQL_QUERY_RUN_RESULTS_DIRS` → `storagePaths.getQueryStoragePath()` +- Set `CODEQL_MRVA_RUN_RESULTS_DIRS` → `storagePaths.getVariantAnalysisStoragePath()` + +### Documentation Updates + +- `docs/ql-mcp/tools.md` — add `list_mrva_run_results` and + `profile_codeql_query_from_logs` to tool tables. +- `docs/vscode/extension.md` — document the new env vars and discovery. + +--- + +## Test Data + +Fresh evaluator logs generated for testing: + +| Log | Location | Queries | Size | +| --------------------------------------- | --------------------------------------------------------------- | ---------------------------- | ---- | +| Single query (`codeql query run`) | `.tmp/logs-query-run/evaluator-log.jsonl` | 1 (ListRemoteFlowSources.ql) | 13MB | +| Multi query (`codeql database analyze`) | `.tmp/logs-db-analyze/evaluator-log.jsonl` | 10 (UI5 pack) | 79MB | +| vscode-codeql query run | `~/Library/.../queries/UI5Xss.ql-*/evaluator-log.jsonl` | 1 | 30MB | +| vscode-codeql query run | `~/Library/.../queries/UI5Xss.ql-*/evaluator-log.summary.jsonl` | 1 | 18MB | diff --git a/docs/vscode/extension.md b/docs/vscode/extension.md index e6ee84cf..03421d58 100644 --- a/docs/vscode/extension.md +++ b/docs/vscode/extension.md @@ -39,8 +39,12 @@ On activation the extension: `mcp.json` edits. 5. **Bridges the CodeQL extension** — watches for databases and query results created by the CodeQL extension and passes their locations to the MCP server - via `CODEQL_DATABASES_BASE_DIRS` and `CODEQL_QUERY_RUN_RESULTS_DIRS` - environment variables. + via environment variables: + - `CODEQL_ADDITIONAL_PACKS` — workspace folders and vscode-codeql database storage + - `CODEQL_QUERY_RUN_RESULTS_DIRS` — vscode-codeql query result directories + (enables `list_query_run_results` and `profile_codeql_query_from_logs`) + - `CODEQL_MRVA_RUN_RESULTS_DIRS` — vscode-codeql variant analysis result + directories (enables `list_mrva_run_results`) ## Settings diff --git a/extensions/vscode/src/bridge/environment-builder.ts b/extensions/vscode/src/bridge/environment-builder.ts index e3fd4282..dab0bdaa 100644 --- a/extensions/vscode/src/bridge/environment-builder.ts +++ b/extensions/vscode/src/bridge/environment-builder.ts @@ -78,6 +78,15 @@ export class EnvironmentBuilder extends DisposableObject { env.CODEQL_ADDITIONAL_PACKS = additionalPaths.join(':'); + // Database discovery directory for list_codeql_databases + env.CODEQL_DATABASES_BASE_DIRS = this.storagePaths.getDatabaseStoragePath(); + + // MRVA run results directory for variant analysis discovery + env.CODEQL_MRVA_RUN_RESULTS_DIRS = this.storagePaths.getVariantAnalysisStoragePath(); + + // Query run results directory for query history discovery + env.CODEQL_QUERY_RUN_RESULTS_DIRS = this.storagePaths.getQueryStoragePath(); + // User-configured additional environment variables const config = vscode.workspace.getConfiguration('codeql-mcp'); const additionalEnv = config.get>('additionalEnv', {}); diff --git a/server/dist/codeql-development-mcp-server.js b/server/dist/codeql-development-mcp-server.js index 07b3b689..d7d03d53 100755 --- a/server/dist/codeql-development-mcp-server.js +++ b/server/dist/codeql-development-mcp-server.js @@ -2264,7 +2264,7 @@ function registerCLITool(server, definition) { break; } let queryLogDir; - if (name === "codeql_query_run" || name === "codeql_test_run") { + if (name === "codeql_query_run" || name === "codeql_test_run" || name === "codeql_database_analyze") { queryLogDir = getOrCreateLogDirectory(customLogDir); logger.info(`Using log directory for ${name}: ${queryLogDir}`); const timestampPath = join5(queryLogDir, "timestamp"); @@ -2273,10 +2273,13 @@ function registerCLITool(server, definition) { if (!options.verbosity) { options.verbosity = "progress+"; } + if (!options["evaluator-log"]) { + options["evaluator-log"] = join5(queryLogDir, "evaluator-log.jsonl"); + } + if (options["tuple-counting"] === void 0) { + options["tuple-counting"] = true; + } if (name === "codeql_query_run") { - if (!options["evaluator-log"]) { - options["evaluator-log"] = join5(queryLogDir, "evaluator-log.jsonl"); - } if (!options.output) { options.output = join5(queryLogDir, "results.bqrs"); } @@ -2291,7 +2294,7 @@ function registerCLITool(server, definition) { } const defaultExamplesPath = resolve4(packageRootDir, "ql", "javascript", "examples"); const additionalPacksPath = process.env.CODEQL_ADDITIONAL_PACKS || (existsSync4(defaultExamplesPath) ? defaultExamplesPath : void 0); - if (additionalPacksPath && (name === "codeql_test_run" || name === "codeql_query_run" || name === "codeql_query_compile")) { + if (additionalPacksPath && (name === "codeql_test_run" || name === "codeql_query_run" || name === "codeql_query_compile" || name === "codeql_database_analyze")) { options["additional-packs"] = additionalPacksPath; } if (name === "codeql_test_run") { @@ -2322,6 +2325,24 @@ function registerCLITool(server, definition) { } result = await processQueryRunResults(result, params, logger); } + if ((name === "codeql_query_run" || name === "codeql_database_analyze") && result.success && queryLogDir) { + const evalLogPath = options["evaluator-log"]; + if (evalLogPath && existsSync4(evalLogPath)) { + try { + const summaryPath = evalLogPath.replace(/\.jsonl$/, ".summary.jsonl"); + const summaryResult = await executeCodeQLCommand( + "generate log-summary", + { format: "predicates" }, + [evalLogPath, summaryPath] + ); + if (summaryResult.success) { + logger.info(`Generated evaluator log summary at ${summaryPath}`); + } + } catch (error) { + logger.warn(`Failed to generate evaluator log summary: ${error}`); + } + } + } const processedResult = resultProcessor(result, params); return { content: [{ @@ -2728,12 +2749,17 @@ var codeqlDatabaseAnalyzeTool = { threads: z5.number().optional().describe("Number of threads to use"), ram: z5.number().optional().describe("Amount of RAM to use (MB)"), timeout: z5.number().optional().describe("Timeout in seconds"), + logDir: z5.string().optional().describe("Custom directory for analysis execution logs (overrides CODEQL_QUERY_LOG_DIR environment variable). If not provided, uses CODEQL_QUERY_LOG_DIR or defaults to .tmp/query-logs/"), + "evaluator-log": z5.string().optional().describe("Path to save evaluator log. If not provided and logDir is set, defaults to /evaluator-log.jsonl"), + "tuple-counting": z5.boolean().optional().describe("Display tuple counts for each evaluation step in evaluator logs"), + "evaluator-log-level": z5.number().min(1).max(5).optional().describe("Evaluator log verbosity level (1-5, default 5)"), verbose: z5.boolean().optional().describe("Enable verbose output"), additionalArgs: z5.array(z5.string()).optional().describe("Additional command-line arguments") }, examples: [ "codeql database analyze mydb queries.qls --format=sarif-latest --output=results.sarif", - "codeql database analyze mydb codeql/java-queries --format=csv" + "codeql database analyze mydb codeql/java-queries --format=csv", + "codeql database analyze mydb queries.qls --format=sarif-latest --output=results.sarif --log-dir=/path/to/logs --tuple-counting" ] }; @@ -5833,6 +5859,9 @@ function parsePathList(envValue) { function getDatabaseBaseDirs() { return parsePathList(process.env.CODEQL_DATABASES_BASE_DIRS); } +function getMrvaRunResultsDirs() { + return parsePathList(process.env.CODEQL_MRVA_RUN_RESULTS_DIRS); +} function getQueryRunResultsDirs() { return parsePathList(process.env.CODEQL_QUERY_RUN_RESULTS_DIRS); } @@ -5969,13 +5998,14 @@ function registerListDatabasesTool(server) { ); } -// src/tools/codeql/list-query-run-results.ts +// src/tools/codeql/list-mrva-run-results.ts import { existsSync as existsSync7, readdirSync as readdirSync3, readFileSync as readFileSync5, statSync as statSync3 } from "fs"; import { join as join8 } from "path"; import { z as z13 } from "zod"; init_logger(); -var QUERY_RUN_DIR_PATTERN = /^(.+\.ql)-(.+)$/; -async function discoverQueryRunResults(resultsDirs, queryName) { +var NUMERIC_DIR_PATTERN = /^\d+$/; +var SKIP_DIRS = /* @__PURE__ */ new Set([".DS_Store", "exported-results"]); +async function discoverMrvaRunResults(resultsDirs, runId) { const results = []; for (const dir of resultsDirs) { if (!existsSync7(dir)) { @@ -5996,6 +6026,193 @@ async function discoverQueryRunResults(resultsDirs, queryName) { } catch { continue; } + if (!NUMERIC_DIR_PATTERN.test(entry)) { + continue; + } + if (runId && entry !== runId) { + continue; + } + let timestamp2; + const timestampPath = join8(entryPath, "timestamp"); + if (existsSync7(timestampPath)) { + try { + timestamp2 = readFileSync5(timestampPath, "utf-8").trim(); + } catch { + } + } + const repositories = discoverRepoResults(entryPath); + results.push({ + path: entryPath, + repositories, + runId: entry, + timestamp: timestamp2 + }); + } + } + return results; +} +function discoverRepoResults(runPath) { + const repos = []; + let ownerEntries; + try { + ownerEntries = readdirSync3(runPath); + } catch { + return repos; + } + for (const ownerEntry of ownerEntries) { + if (SKIP_DIRS.has(ownerEntry)) { + continue; + } + const ownerPath = join8(runPath, ownerEntry); + try { + if (!statSync3(ownerPath).isDirectory()) { + continue; + } + } catch { + continue; + } + let repoEntries; + try { + repoEntries = readdirSync3(ownerPath); + } catch { + continue; + } + for (const repoEntry of repoEntries) { + const repoPath = join8(ownerPath, repoEntry); + try { + if (!statSync3(repoPath).isDirectory()) { + continue; + } + } catch { + continue; + } + const fullName = `${ownerEntry}/${repoEntry}`; + let analysisStatus; + let resultCount; + const repoTaskPath = join8(repoPath, "repo_task.json"); + if (existsSync7(repoTaskPath)) { + try { + const raw = readFileSync5(repoTaskPath, "utf-8"); + const task = JSON.parse(raw); + if (typeof task.analysisStatus === "string") { + analysisStatus = task.analysisStatus; + } + if (typeof task.resultCount === "number") { + resultCount = task.resultCount; + } + } catch { + } + } + const hasSarif = existsSync7(join8(repoPath, "results", "results.sarif")); + const hasBqrs = existsSync7(join8(repoPath, "results", "results.bqrs")); + repos.push({ + analysisStatus, + fullName, + hasBqrs, + hasSarif, + resultCount + }); + } + } + return repos; +} +function registerListMrvaRunResultsTool(server) { + server.tool( + "list_mrva_run_results", + "List discovered MRVA (Multi-Repository Variant Analysis) run results (set via CODEQL_MRVA_RUN_RESULTS_DIRS env var). Returns run ID, timestamp, repositories scanned, analysis status, and available artifacts for each run.", + { + runId: z13.string().optional().describe('Filter results by run ID (e.g., "20442")') + }, + async ({ runId }) => { + try { + const resultsDirs = getMrvaRunResultsDirs(); + if (resultsDirs.length === 0) { + return { + content: [ + { + type: "text", + text: "No MRVA run results directories configured. Set the CODEQL_MRVA_RUN_RESULTS_DIRS environment variable to a colon-separated list of directories to search." + } + ] + }; + } + const runs = await discoverMrvaRunResults(resultsDirs, runId); + if (runs.length === 0) { + const filterMsg = runId ? ` for run ID "${runId}"` : ""; + return { + content: [ + { + type: "text", + text: `No MRVA run results found${filterMsg} in: ${resultsDirs.join(", ")}` + } + ] + }; + } + const lines = [ + `Found ${runs.length} MRVA run result(s):`, + "", + ...runs.map((run) => { + const parts = [` Run ${run.runId}`]; + parts.push(` Path: ${run.path}`); + if (run.timestamp) parts.push(` Timestamp: ${run.timestamp}`); + parts.push(` Repositories: ${run.repositories.length}`); + for (const repo of run.repositories) { + const artifacts = []; + if (repo.hasSarif) artifacts.push("sarif"); + if (repo.hasBqrs) artifacts.push("bqrs"); + const status = repo.analysisStatus ?? "unknown"; + const count = repo.resultCount !== void 0 ? `, ${repo.resultCount} result(s)` : ""; + parts.push(` ${repo.fullName} [${status}${count}] artifacts: ${artifacts.length > 0 ? artifacts.join(", ") : "none"}`); + } + return parts.join("\n"); + }) + ]; + return { + content: [{ type: "text", text: lines.join("\n") }] + }; + } catch (error) { + logger.error("Error listing MRVA run results:", error); + return { + content: [ + { + type: "text", + text: `Error: ${error instanceof Error ? error.message : "Unknown error"}` + } + ], + isError: true + }; + } + } + ); +} + +// src/tools/codeql/list-query-run-results.ts +import { existsSync as existsSync8, readdirSync as readdirSync4, readFileSync as readFileSync6, statSync as statSync4 } from "fs"; +import { join as join9 } from "path"; +import { z as z14 } from "zod"; +init_logger(); +var QUERY_RUN_DIR_PATTERN = /^(.+\.ql)-(.+)$/; +async function discoverQueryRunResults(resultsDirs, queryName) { + const results = []; + for (const dir of resultsDirs) { + if (!existsSync8(dir)) { + continue; + } + let entries; + try { + entries = readdirSync4(dir); + } catch { + continue; + } + for (const entry of entries) { + const entryPath = join9(dir, entry); + try { + if (!statSync4(entryPath).isDirectory()) { + continue; + } + } catch { + continue; + } const match = QUERY_RUN_DIR_PATTERN.exec(entry); if (!match) { continue; @@ -6004,14 +6221,14 @@ async function discoverQueryRunResults(resultsDirs, queryName) { if (queryName && name !== queryName) { continue; } - const hasEvaluatorLog = existsSync7(join8(entryPath, "evaluator-log.jsonl")); - const hasBqrs = existsSync7(join8(entryPath, "results.bqrs")); - const hasSarif = existsSync7(join8(entryPath, "results-interpreted.sarif")); + const hasEvaluatorLog = existsSync8(join9(entryPath, "evaluator-log.jsonl")); + const hasBqrs = existsSync8(join9(entryPath, "results.bqrs")); + const hasSarif = existsSync8(join9(entryPath, "results-interpreted.sarif")); let timestamp2; - const timestampPath = join8(entryPath, "timestamp"); - if (existsSync7(timestampPath)) { + const timestampPath = join9(entryPath, "timestamp"); + if (existsSync8(timestampPath)) { try { - timestamp2 = readFileSync5(timestampPath, "utf-8").trim(); + timestamp2 = readFileSync6(timestampPath, "utf-8").trim(); } catch { } } @@ -6033,7 +6250,7 @@ function registerListQueryRunResultsTool(server) { "list_query_run_results", "List discovered query run result directories (set via CODEQL_QUERY_RUN_RESULTS_DIRS env var). Returns path, query name, timestamp, and available artifacts for each run.", { - queryName: z13.string().optional().describe('Filter results by query name (e.g., "UI5Xss.ql")') + queryName: z14.string().optional().describe('Filter results by query name (e.g., "UI5Xss.ql")') }, async ({ queryName }) => { try { @@ -6095,16 +6312,16 @@ function registerListQueryRunResultsTool(server) { } // src/tools/codeql/pack-install.ts -import { z as z14 } from "zod"; +import { z as z15 } from "zod"; var codeqlPackInstallTool = { name: "codeql_pack_install", description: "Install CodeQL pack dependencies", command: "codeql", subcommand: "pack install", inputSchema: { - packDir: z14.string().optional().describe("Directory containing qlpack.yml (default: current)"), - force: z14.boolean().optional().describe("Force reinstall of dependencies"), - "no-strict-mode": z14.boolean().optional().describe("Allow non-strict dependency resolution"), + packDir: z15.string().optional().describe("Directory containing qlpack.yml (default: current)"), + force: z15.boolean().optional().describe("Force reinstall of dependencies"), + "no-strict-mode": z15.boolean().optional().describe("Allow non-strict dependency resolution"), verbose: createCodeQLSchemas.verbose(), additionalArgs: createCodeQLSchemas.additionalArgs() }, @@ -6116,16 +6333,16 @@ var codeqlPackInstallTool = { }; // src/tools/codeql/pack-ls.ts -import { z as z15 } from "zod"; +import { z as z16 } from "zod"; var codeqlPackLsTool = { name: "codeql_pack_ls", description: "List CodeQL packs under some local directory path", command: "codeql", subcommand: "pack ls", inputSchema: { - dir: z15.string().optional().describe("The root directory of the package or workspace, defaults to the current working directory"), - format: z15.enum(["text", "json"]).optional().describe("Output format: text (default) or json"), - groups: z15.string().optional().describe("List of CodeQL pack groups to include or exclude"), + dir: z16.string().optional().describe("The root directory of the package or workspace, defaults to the current working directory"), + format: z16.enum(["text", "json"]).optional().describe("Output format: text (default) or json"), + groups: z16.string().optional().describe("List of CodeQL pack groups to include or exclude"), verbose: createCodeQLSchemas.verbose(), additionalArgs: createCodeQLSchemas.additionalArgs() }, @@ -6137,15 +6354,456 @@ var codeqlPackLsTool = { resultProcessor: defaultCLIResultProcessor }; +// src/tools/codeql/profile-codeql-query-from-logs.ts +import { existsSync as existsSync9, mkdirSync as mkdirSync6, writeFileSync as writeFileSync3 } from "fs"; +import { basename as basename4, dirname as dirname6, join as join10 } from "path"; +import { z as z17 } from "zod"; + +// src/lib/evaluator-log-parser.ts +init_logger(); +import { readFileSync as readFileSync7 } from "fs"; +function detectLogFormat(firstEvent) { + if (typeof firstEvent.type === "string") { + return "raw"; + } + return "summary"; +} +function splitJsonObjects(content) { + const trimmed = content.trim(); + if (trimmed.length === 0) { + return []; + } + const parts = trimmed.split(/\n\}\s*\n\s*\{/); + if (parts.length === 1) { + return [trimmed]; + } + return parts.map((part, idx) => { + if (idx === 0) { + return part + "\n}"; + } + if (idx === parts.length - 1) { + return "{\n" + part; + } + return "{\n" + part + "\n}"; + }); +} +function parseJsonObjects(logPath) { + const content = readFileSync7(logPath, "utf-8"); + const objectStrings = splitJsonObjects(content); + const results = []; + for (const objStr of objectStrings) { + try { + results.push(JSON.parse(objStr)); + } catch { + logger.warn( + `Failed to parse evaluator log object: ${objStr.substring(0, 120)}...` + ); + } + } + return results; +} +function parseRawEvaluatorLog(logPath) { + const events = parseJsonObjects(logPath); + let codeqlVersion; + const queryStartEvents = /* @__PURE__ */ new Map(); + const predicateStartEvents = /* @__PURE__ */ new Map(); + const queryPredicates = /* @__PURE__ */ new Map(); + const queryEndNanoTimes = /* @__PURE__ */ new Map(); + const queryCacheHits = /* @__PURE__ */ new Map(); + let firstQueryEventId; + for (const event of events) { + const eventType = event.type; + switch (eventType) { + case "LOG_HEADER": { + codeqlVersion = event.codeqlVersion; + break; + } + case "QUERY_STARTED": { + const eid = event.eventId; + const qName = event.queryName || "unknown"; + queryStartEvents.set(eid, { + queryName: qName, + nanoTime: event.nanoTime + }); + queryPredicates.set(eid, []); + queryCacheHits.set(eid, 0); + if (firstQueryEventId === void 0) { + firstQueryEventId = eid; + } + break; + } + case "QUERY_COMPLETED": { + const startEid = event.startEvent; + queryEndNanoTimes.set(startEid, event.nanoTime); + break; + } + case "PREDICATE_STARTED": { + const eid = event.eventId; + const deps = event.dependencies; + predicateStartEvents.set(eid, { + predicateName: event.predicateName || "unknown", + position: event.position, + predicateType: event.predicateType, + dependencies: deps ? Object.keys(deps) : [], + queryCausingWork: event.queryCausingWork, + nanoTime: event.nanoTime, + pipelineCount: 0 + }); + break; + } + case "PIPELINE_COMPLETED": { + const pipelineStartEid = event.startEvent; + const pipelineStartEvt = events.find( + (e) => e.type === "PIPELINE_STARTED" && e.eventId === pipelineStartEid + ); + if (pipelineStartEvt) { + const predEid = pipelineStartEvt.predicateStartEvent; + const predStart = predicateStartEvents.get(predEid); + if (predStart) { + predStart.pipelineCount += 1; + } + } + break; + } + case "PREDICATE_COMPLETED": { + const startEid = event.startEvent; + const predStart = predicateStartEvents.get(startEid); + if (predStart) { + const durationNs = event.nanoTime - predStart.nanoTime; + const durationMs = durationNs / 1e6; + const profile = { + predicateName: predStart.predicateName, + position: predStart.position, + durationMs, + resultSize: event.resultSize, + pipelineCount: predStart.pipelineCount > 0 ? predStart.pipelineCount : void 0, + evaluationStrategy: predStart.predicateType, + dependencies: predStart.dependencies + }; + const qEid = predStart.queryCausingWork ?? firstQueryEventId; + if (qEid !== void 0) { + let arr = queryPredicates.get(qEid); + if (!arr) { + arr = []; + queryPredicates.set(qEid, arr); + } + arr.push(profile); + } + } + break; + } + case "CACHE_LOOKUP": { + const qEid = event.queryCausingWork ?? firstQueryEventId; + if (qEid !== void 0) { + queryCacheHits.set(qEid, (queryCacheHits.get(qEid) ?? 0) + 1); + } + break; + } + } + } + const queries = []; + for (const [qEid, startInfo] of queryStartEvents) { + const predicates = queryPredicates.get(qEid) ?? []; + const endNano = queryEndNanoTimes.get(qEid); + const totalDurationMs = endNano !== void 0 ? (endNano - startInfo.nanoTime) / 1e6 : predicates.reduce((sum, p) => sum + p.durationMs, 0); + queries.push({ + queryName: startInfo.queryName, + totalDurationMs, + predicateCount: predicates.length, + predicates, + cacheHits: queryCacheHits.get(qEid) ?? 0 + }); + } + return { + codeqlVersion, + logFormat: "raw", + queries, + totalEvents: events.length + }; +} +function parseSummaryLog(logPath) { + const events = parseJsonObjects(logPath); + let codeqlVersion; + const queryPredicatesMap = /* @__PURE__ */ new Map(); + const queryTotalMs = /* @__PURE__ */ new Map(); + const queryCacheHits = /* @__PURE__ */ new Map(); + for (const event of events) { + if (event.summaryLogVersion !== void 0) { + codeqlVersion = event.codeqlVersion; + continue; + } + const strategy = event.evaluationStrategy; + if (strategy === "SENTINEL_EMPTY") { + continue; + } + if (event.millis === void 0) { + continue; + } + const predicateName = event.predicateName || "unknown"; + const millis = event.millis; + const queryName = event.queryCausingWork || "unknown"; + const deps = event.dependencies; + const pipelineRuns = event.pipelineRuns; + const profile = { + predicateName, + position: event.position, + durationMs: millis, + resultSize: event.resultSize, + pipelineCount: pipelineRuns, + evaluationStrategy: strategy, + dependencies: deps ? Object.keys(deps) : [] + }; + if (event.isCached === true || strategy === "CACHEHIT") { + queryCacheHits.set( + queryName, + (queryCacheHits.get(queryName) ?? 0) + 1 + ); + } + let arr = queryPredicatesMap.get(queryName); + if (!arr) { + arr = []; + queryPredicatesMap.set(queryName, arr); + } + arr.push(profile); + queryTotalMs.set( + queryName, + (queryTotalMs.get(queryName) ?? 0) + millis + ); + } + const queries = []; + for (const [queryName, predicates] of queryPredicatesMap) { + queries.push({ + queryName, + totalDurationMs: queryTotalMs.get(queryName) ?? 0, + predicateCount: predicates.length, + predicates, + cacheHits: queryCacheHits.get(queryName) ?? 0 + }); + } + return { + codeqlVersion, + logFormat: "summary", + queries, + totalEvents: events.length + }; +} +function parseEvaluatorLog(logPath) { + const events = parseJsonObjects(logPath); + if (events.length === 0) { + return { + logFormat: "raw", + queries: [], + totalEvents: 0 + }; + } + const format = detectLogFormat(events[0]); + if (format === "raw") { + return parseRawEvaluatorLog(logPath); + } + return parseSummaryLog(logPath); +} + +// src/tools/codeql/profile-codeql-query-from-logs.ts +init_logger(); +function formatAsJson(profile) { + return JSON.stringify(profile, null, 2); +} +function formatAsMermaid(profile, topN) { + const lines = []; + lines.push("```mermaid"); + lines.push("graph TD"); + lines.push(""); + if (profile.queries.length <= 1) { + const query = profile.queries[0] ?? { + queryName: "unknown", + totalDurationMs: 0, + predicates: [], + predicateCount: 0, + cacheHits: 0 + }; + const qLabel = sanitizeMermaid(basename4(query.queryName)); + lines.push( + ` QUERY["${qLabel}
Total: ${query.totalDurationMs.toFixed(2)}ms
Predicates: ${query.predicateCount}"]` + ); + lines.push(""); + const topPredicates = getTopPredicates(query.predicates, topN); + topPredicates.forEach((pred, idx) => { + const nodeId = `P${idx}`; + const name = sanitizeMermaid(pred.predicateName).substring(0, 50); + const dur = pred.durationMs.toFixed(2); + const size = pred.resultSize !== void 0 ? String(pred.resultSize) : "?"; + lines.push( + ` ${nodeId}["${name}
${dur}ms | ${size} results"]` + ); + }); + lines.push(""); + topPredicates.forEach((_pred, idx) => { + lines.push(` QUERY --> P${idx}`); + }); + } else { + lines.push( + ` ROOT["Evaluation Log
${profile.queries.length} queries"]` + ); + lines.push(""); + profile.queries.forEach((query, qIdx) => { + const qNodeId = `Q${qIdx}`; + const qLabel = sanitizeMermaid(basename4(query.queryName)); + lines.push( + ` ${qNodeId}["${qLabel}
${query.totalDurationMs.toFixed(2)}ms
Predicates: ${query.predicateCount}"]` + ); + lines.push(` ROOT --> ${qNodeId}`); + const topPredicates = getTopPredicates(query.predicates, topN); + topPredicates.forEach((pred, pIdx) => { + const nodeId = `Q${qIdx}P${pIdx}`; + const name = sanitizeMermaid(pred.predicateName).substring(0, 50); + const dur = pred.durationMs.toFixed(2); + const size = pred.resultSize !== void 0 ? String(pred.resultSize) : "?"; + lines.push( + ` ${nodeId}["${name}
${dur}ms | ${size} results"]` + ); + lines.push(` ${qNodeId} --> ${nodeId}`); + }); + lines.push(""); + }); + } + lines.push(""); + lines.push( + " classDef default fill:#e1f5ff,stroke:#333,stroke-width:2px" + ); + lines.push( + " classDef query fill:#ffe1e1,stroke:#333,stroke-width:3px" + ); + lines.push(" class QUERY query"); + lines.push("```"); + return lines.join("\n"); +} +function sanitizeMermaid(text) { + return text.replace(/[<>"]/g, ""); +} +function getTopPredicates(predicates, topN) { + return [...predicates].sort((a, b) => b.durationMs - a.durationMs).slice(0, topN); +} +function buildTextSummary(profile, topN, outputFiles) { + const sections = []; + sections.push("Query log profiling completed successfully!"); + sections.push(""); + sections.push("Output Files:"); + for (const f of outputFiles) { + sections.push(` - ${f}`); + } + sections.push(""); + sections.push(`Log Format: ${profile.logFormat}`); + if (profile.codeqlVersion) { + sections.push(`CodeQL Version: ${profile.codeqlVersion}`); + } + sections.push(`Total Events: ${profile.totalEvents}`); + sections.push(`Queries: ${profile.queries.length}`); + for (const query of profile.queries) { + sections.push(""); + sections.push(`--- ${basename4(query.queryName)} ---`); + sections.push(` Total Duration: ${query.totalDurationMs.toFixed(2)} ms`); + sections.push(` Predicates Evaluated: ${query.predicateCount}`); + sections.push(` Cache Hits: ${query.cacheHits}`); + const top = getTopPredicates(query.predicates, topN); + if (top.length > 0) { + sections.push(` Top ${top.length} Most Expensive Predicates:`); + top.forEach((pred, idx) => { + const sizeStr = pred.resultSize !== void 0 ? `, ${pred.resultSize} results` : ""; + sections.push( + ` ${idx + 1}. ${pred.predicateName} (${pred.durationMs.toFixed(2)} ms${sizeStr})` + ); + }); + } + } + return sections.join("\n"); +} +function registerProfileCodeQLQueryFromLogsTool(server) { + server.tool( + "profile_codeql_query_from_logs", + "Parse CodeQL query evaluation logs into a performance profile without re-running the query. Works with logs from codeql query run, codeql database analyze, or vscode-codeql query history.", + { + evaluatorLog: z17.string().describe( + "Path to evaluator-log.jsonl or evaluator-log.summary.jsonl" + ), + outputDir: z17.string().optional().describe( + "Directory to write profile output files (defaults to same directory as log)" + ), + topN: z17.number().optional().describe( + "Number of most expensive predicates to highlight (default: 20)" + ) + }, + async (params) => { + try { + const { evaluatorLog, outputDir, topN } = params; + const effectiveTopN = topN ?? 20; + if (!existsSync9(evaluatorLog)) { + return { + content: [ + { + type: "text", + text: `Evaluator log not found at: ${evaluatorLog}` + } + ], + isError: true + }; + } + logger.info(`Parsing evaluator log from: ${evaluatorLog}`); + const profile = parseEvaluatorLog(evaluatorLog); + const profileOutputDir = outputDir ?? dirname6(evaluatorLog); + mkdirSync6(profileOutputDir, { recursive: true }); + const jsonPath = join10( + profileOutputDir, + "query-evaluation-profile.json" + ); + writeFileSync3(jsonPath, formatAsJson(profile)); + logger.info(`Profile JSON written to: ${jsonPath}`); + const mdPath = join10( + profileOutputDir, + "query-evaluation-profile.md" + ); + writeFileSync3(mdPath, formatAsMermaid(profile, effectiveTopN)); + logger.info(`Profile Mermaid diagram written to: ${mdPath}`); + const outputFilesList = [ + `Profile JSON: ${jsonPath}`, + `Profile Mermaid: ${mdPath}`, + `Evaluator Log: ${evaluatorLog}` + ]; + const responseText = buildTextSummary( + profile, + effectiveTopN, + outputFilesList + ); + return { + content: [{ type: "text", text: responseText }] + }; + } catch (error) { + logger.error( + "Error profiling CodeQL query from logs:", + error + ); + return { + content: [ + { + type: "text", + text: `Failed to profile query from logs: ${error instanceof Error ? error.message : String(error)}` + } + ], + isError: true + }; + } + } + ); +} + // src/tools/codeql/profile-codeql-query.ts init_cli_executor(); init_logger(); -import { z as z16 } from "zod"; -import { writeFileSync as writeFileSync3, readFileSync as readFileSync6, existsSync as existsSync8 } from "fs"; -import { join as join9, dirname as dirname6, basename as basename4 } from "path"; -import { mkdirSync as mkdirSync6 } from "fs"; -function parseEvaluatorLog(logPath) { - const logContent = readFileSync6(logPath, "utf-8"); +import { z as z18 } from "zod"; +import { writeFileSync as writeFileSync4, readFileSync as readFileSync8, existsSync as existsSync10 } from "fs"; +import { join as join11, dirname as dirname7, basename as basename5 } from "path"; +import { mkdirSync as mkdirSync7 } from "fs"; +function parseEvaluatorLog2(logPath) { + const logContent = readFileSync8(logPath, "utf-8"); const jsonObjects = logContent.split("\n\n").filter((s) => s.trim()); const events = jsonObjects.map((obj) => { try { @@ -6223,15 +6881,15 @@ function parseEvaluatorLog(logPath) { pipelines }; } -function formatAsJson(profile) { +function formatAsJson2(profile) { return JSON.stringify(profile, null, 2); } -function formatAsMermaid(profile) { +function formatAsMermaid2(profile) { const lines = []; lines.push("```mermaid"); lines.push("graph TD"); lines.push(""); - lines.push(` QUERY["${basename4(profile.queryName)}
Total: ${profile.totalDuration.toFixed(2)}ms"]`); + lines.push(` QUERY["${basename5(profile.queryName)}
Total: ${profile.totalDuration.toFixed(2)}ms"]`); lines.push(""); profile.pipelines.forEach((pipeline) => { const nodeId = `P${pipeline.eventId}`; @@ -6264,12 +6922,12 @@ function registerProfileCodeQLQueryTool(server) { "profile_codeql_query", "Profile the performance of a CodeQL query run against a specific database by analyzing the evaluator log JSON file", { - query: z16.string().describe("Path to the .ql query file"), - database: z16.string().describe("Path to the CodeQL database directory"), - evaluatorLog: z16.string().optional().describe( + query: z18.string().describe("Path to the .ql query file"), + database: z18.string().describe("Path to the CodeQL database directory"), + evaluatorLog: z18.string().optional().describe( "Path to an existing structured JSON log (e.g., evaluator-log.jsonl) file. If not provided, the tool will run the query to generate one." ), - outputDir: z16.string().optional().describe("Directory to write profiling data files (defaults to same directory as evaluator log)") + outputDir: z18.string().optional().describe("Directory to write profiling data files (defaults to same directory as evaluator log)") }, async (params) => { try { @@ -6279,11 +6937,11 @@ function registerProfileCodeQLQueryTool(server) { let sarifPath; if (!logPath) { logger.info("No evaluator log provided, running query to generate one"); - const defaultOutputDir = outputDir || join9(dirname6(query), "profile-output"); - mkdirSync6(defaultOutputDir, { recursive: true }); - logPath = join9(defaultOutputDir, "evaluator-log.jsonl"); - bqrsPath = join9(defaultOutputDir, "query-results.bqrs"); - sarifPath = join9(defaultOutputDir, "query-results.sarif"); + const defaultOutputDir = outputDir || join11(dirname7(query), "profile-output"); + mkdirSync7(defaultOutputDir, { recursive: true }); + logPath = join11(defaultOutputDir, "evaluator-log.jsonl"); + bqrsPath = join11(defaultOutputDir, "query-results.bqrs"); + sarifPath = join11(defaultOutputDir, "query-results.sarif"); const queryResult = await executeCodeQLCommand( "query run", { @@ -6306,7 +6964,7 @@ function registerProfileCodeQLQueryTool(server) { isError: true }; } - if (existsSync8(bqrsPath)) { + if (existsSync10(bqrsPath)) { try { const sarifResult = await executeCodeQLCommand( "bqrs interpret", @@ -6321,7 +6979,7 @@ function registerProfileCodeQLQueryTool(server) { } } } - if (!existsSync8(logPath)) { + if (!existsSync10(logPath)) { return { content: [ { @@ -6333,16 +6991,16 @@ function registerProfileCodeQLQueryTool(server) { }; } logger.info(`Parsing evaluator log from: ${logPath}`); - const profile = parseEvaluatorLog(logPath); - const profileOutputDir = outputDir || dirname6(logPath); - mkdirSync6(profileOutputDir, { recursive: true }); - const jsonPath = join9(profileOutputDir, "query-evaluation-profile.json"); - const jsonContent = formatAsJson(profile); - writeFileSync3(jsonPath, jsonContent); + const profile = parseEvaluatorLog2(logPath); + const profileOutputDir = outputDir || dirname7(logPath); + mkdirSync7(profileOutputDir, { recursive: true }); + const jsonPath = join11(profileOutputDir, "query-evaluation-profile.json"); + const jsonContent = formatAsJson2(profile); + writeFileSync4(jsonPath, jsonContent); logger.info(`Profile JSON written to: ${jsonPath}`); - const mdPath = join9(profileOutputDir, "query-evaluation-profile.md"); - const mdContent = formatAsMermaid(profile); - writeFileSync3(mdPath, mdContent); + const mdPath = join11(profileOutputDir, "query-evaluation-profile.md"); + const mdContent = formatAsMermaid2(profile); + writeFileSync4(mdPath, mdContent); logger.info(`Profile Mermaid diagram written to: ${mdPath}`); const outputFiles = [ `Profile JSON: ${jsonPath}`, @@ -6352,7 +7010,7 @@ function registerProfileCodeQLQueryTool(server) { if (bqrsPath) { outputFiles.push(`Query Results (BQRS): ${bqrsPath}`); } - if (sarifPath && existsSync8(sarifPath)) { + if (sarifPath && existsSync10(sarifPath)) { outputFiles.push(`Query Results (SARIF): ${sarifPath}`); } const responseText = [ @@ -6362,7 +7020,7 @@ function registerProfileCodeQLQueryTool(server) { ...outputFiles.map((f) => ` - ${f}`), "", "Profile Summary:", - ` - Query: ${basename4(profile.queryName)}`, + ` - Query: ${basename5(profile.queryName)}`, ` - Total Duration: ${profile.totalDuration.toFixed(2)} ms`, ` - Total Pipelines: ${profile.pipelines.length}`, ` - Total Events: ${profile.totalEvents}`, @@ -6397,20 +7055,20 @@ function registerProfileCodeQLQueryTool(server) { } // src/tools/codeql/query-compile.ts -import { z as z17 } from "zod"; +import { z as z19 } from "zod"; var codeqlQueryCompileTool = { name: "codeql_query_compile", description: "Compile and validate CodeQL queries", command: "codeql", subcommand: "query compile", inputSchema: { - query: z17.string().describe("Path to the CodeQL query file (.ql)"), - database: z17.string().optional().describe("Path to the CodeQL database"), - library: z17.string().optional().describe("Path to query library"), - output: z17.string().optional().describe("Output file path"), - warnings: z17.enum(["hide", "show", "error"]).optional().describe("How to handle compilation warnings"), - verbose: z17.boolean().optional().describe("Enable verbose output"), - additionalArgs: z17.array(z17.string()).optional().describe("Additional command-line arguments") + query: z19.string().describe("Path to the CodeQL query file (.ql)"), + database: z19.string().optional().describe("Path to the CodeQL database"), + library: z19.string().optional().describe("Path to query library"), + output: z19.string().optional().describe("Output file path"), + warnings: z19.enum(["hide", "show", "error"]).optional().describe("How to handle compilation warnings"), + verbose: z19.boolean().optional().describe("Enable verbose output"), + additionalArgs: z19.array(z19.string()).optional().describe("Additional command-line arguments") }, examples: [ "codeql query compile --database=/path/to/db MyQuery.ql", @@ -6419,7 +7077,7 @@ var codeqlQueryCompileTool = { }; // src/tools/codeql/query-format.ts -import { z as z18 } from "zod"; +import { z as z20 } from "zod"; function formatResultProcessor(result, params) { const isCheckOnly = params["check-only"]; const hasFormatChanges = result.exitCode === 1; @@ -6435,12 +7093,12 @@ var codeqlQueryFormatTool = { command: "codeql", subcommand: "query format", inputSchema: { - files: z18.array(z18.string()).describe("One or more .ql or .qll source files to format"), - output: z18.string().optional().describe("Write formatted code to this file instead of stdout"), - "in-place": z18.boolean().optional().describe("Overwrite each input file with formatted version"), - "check-only": z18.boolean().optional().describe("Check formatting without writing output"), - backup: z18.string().optional().describe("Backup extension when overwriting existing files"), - "no-syntax-errors": z18.boolean().optional().describe("Ignore syntax errors and pretend file is formatted"), + files: z20.array(z20.string()).describe("One or more .ql or .qll source files to format"), + output: z20.string().optional().describe("Write formatted code to this file instead of stdout"), + "in-place": z20.boolean().optional().describe("Overwrite each input file with formatted version"), + "check-only": z20.boolean().optional().describe("Check formatting without writing output"), + backup: z20.string().optional().describe("Backup extension when overwriting existing files"), + "no-syntax-errors": z20.boolean().optional().describe("Ignore syntax errors and pretend file is formatted"), verbose: createCodeQLSchemas.verbose(), additionalArgs: createCodeQLSchemas.additionalArgs() }, @@ -6453,33 +7111,33 @@ var codeqlQueryFormatTool = { }; // src/tools/codeql/query-run.ts -import { z as z19 } from "zod"; +import { z as z21 } from "zod"; var codeqlQueryRunTool = { name: "codeql_query_run", description: 'Execute a CodeQL query against a database. Use either "query" parameter for direct file path OR "queryName" + "queryLanguage" for pre-defined tool queries.', command: "codeql", subcommand: "query run", inputSchema: { - query: z19.string().optional().describe("Path to the CodeQL query file (.ql) - cannot be used with queryName"), - queryName: z19.string().optional().describe('Name of pre-defined query to run (e.g., "PrintAST", "CallGraphFrom", "CallGraphTo") - requires queryLanguage'), - queryLanguage: z19.string().optional().describe('Programming language for tools queries (e.g., "javascript", "java", "python") - required when using queryName'), - queryPack: z19.string().optional().describe("Query pack path (defaults to server/ql//tools/src/ for tool queries)"), - sourceFiles: z19.string().optional().describe('Comma-separated list of source file paths for PrintAST queries (e.g., "src/main.js,src/utils.js" or just "main.js")'), - sourceFunction: z19.string().optional().describe('Comma-separated list of source function names for CallGraphFrom queries (e.g., "main,processData")'), - targetFunction: z19.string().optional().describe('Comma-separated list of target function names for CallGraphTo queries (e.g., "helper,validateInput")'), + query: z21.string().optional().describe("Path to the CodeQL query file (.ql) - cannot be used with queryName"), + queryName: z21.string().optional().describe('Name of pre-defined query to run (e.g., "PrintAST", "CallGraphFrom", "CallGraphTo") - requires queryLanguage'), + queryLanguage: z21.string().optional().describe('Programming language for tools queries (e.g., "javascript", "java", "python") - required when using queryName'), + queryPack: z21.string().optional().describe("Query pack path (defaults to server/ql//tools/src/ for tool queries)"), + sourceFiles: z21.string().optional().describe('Comma-separated list of source file paths for PrintAST queries (e.g., "src/main.js,src/utils.js" or just "main.js")'), + sourceFunction: z21.string().optional().describe('Comma-separated list of source function names for CallGraphFrom queries (e.g., "main,processData")'), + targetFunction: z21.string().optional().describe('Comma-separated list of target function names for CallGraphTo queries (e.g., "helper,validateInput")'), database: createCodeQLSchemas.database(), output: createCodeQLSchemas.output(), - external: z19.array(z19.string()).optional().describe("External predicate data: predicate=file.csv"), + external: z21.array(z21.string()).optional().describe("External predicate data: predicate=file.csv"), timeout: createCodeQLSchemas.timeout(), - logDir: z19.string().optional().describe("Custom directory for query execution logs (overrides CODEQL_QUERY_LOG_DIR environment variable). If not provided, uses CODEQL_QUERY_LOG_DIR or defaults to .tmp/query-logs/"), - "evaluator-log": z19.string().optional().describe("Path to save evaluator log (deprecated: use logDir instead)"), - "evaluator-log-minify": z19.boolean().optional().describe("Minimize evaluator log for smaller size"), - "evaluator-log-level": z19.number().min(1).max(5).optional().describe("Evaluator log verbosity level (1-5, default 5)"), - "tuple-counting": z19.boolean().optional().describe("Display tuple counts for each evaluation step in evaluator logs"), - format: z19.enum(["sarif-latest", "sarifv2.1.0", "csv", "graphtext", "dgml", "dot"]).optional().describe("Output format for query results via codeql bqrs interpret. Defaults to sarif-latest for @kind problem/path-problem queries, graphtext for @kind graph queries. Graph formats (graphtext, dgml, dot) only work with @kind graph queries."), - interpretedOutput: z19.string().optional().describe("Output file for interpreted results (e.g., results.sarif, results.txt). If not provided, defaults based on format: .sarif for SARIF, .txt for graphtext/csv, .dgml for dgml, .dot for dot"), - evaluationFunction: z19.string().optional().describe('[DEPRECATED - use format parameter instead] Built-in function for query results evaluation (e.g., "mermaid-graph", "json-decode", "csv-decode") or path to custom evaluation script'), - evaluationOutput: z19.string().optional().describe("[DEPRECATED - use interpretedOutput parameter instead] Output file for evaluation results"), + logDir: z21.string().optional().describe("Custom directory for query execution logs (overrides CODEQL_QUERY_LOG_DIR environment variable). If not provided, uses CODEQL_QUERY_LOG_DIR or defaults to .tmp/query-logs/"), + "evaluator-log": z21.string().optional().describe("Path to save evaluator log (deprecated: use logDir instead)"), + "evaluator-log-minify": z21.boolean().optional().describe("Minimize evaluator log for smaller size"), + "evaluator-log-level": z21.number().min(1).max(5).optional().describe("Evaluator log verbosity level (1-5, default 5)"), + "tuple-counting": z21.boolean().optional().describe("Display tuple counts for each evaluation step in evaluator logs"), + format: z21.enum(["sarif-latest", "sarifv2.1.0", "csv", "graphtext", "dgml", "dot"]).optional().describe("Output format for query results via codeql bqrs interpret. Defaults to sarif-latest for @kind problem/path-problem queries, graphtext for @kind graph queries. Graph formats (graphtext, dgml, dot) only work with @kind graph queries."), + interpretedOutput: z21.string().optional().describe("Output file for interpreted results (e.g., results.sarif, results.txt). If not provided, defaults based on format: .sarif for SARIF, .txt for graphtext/csv, .dgml for dgml, .dot for dot"), + evaluationFunction: z21.string().optional().describe('[DEPRECATED - use format parameter instead] Built-in function for query results evaluation (e.g., "mermaid-graph", "json-decode", "csv-decode") or path to custom evaluation script'), + evaluationOutput: z21.string().optional().describe("[DEPRECATED - use interpretedOutput parameter instead] Output file for evaluation results"), verbose: createCodeQLSchemas.verbose(), additionalArgs: createCodeQLSchemas.additionalArgs() }, @@ -6494,8 +7152,8 @@ var codeqlQueryRunTool = { }; // src/tools/codeql/quick-evaluate.ts -import { z as z20 } from "zod"; -import { join as join10, resolve as resolve6 } from "path"; +import { z as z22 } from "zod"; +import { join as join12, resolve as resolve6 } from "path"; init_logger(); init_temp_dir(); async function quickEvaluate({ @@ -6514,7 +7172,7 @@ async function quickEvaluate({ throw new Error(`Symbol '${symbol}' not found as class or predicate in file: ${file}`); } } - const resolvedOutput = resolve6(output_path || join10(getProjectTmpDir("quickeval"), "quickeval.bqrs")); + const resolvedOutput = resolve6(output_path || join12(getProjectTmpDir("quickeval"), "quickeval.bqrs")); return resolvedOutput; } catch (error) { throw new Error(`CodeQL evaluation failed: ${error instanceof Error ? error.message : "Unknown error"}`); @@ -6525,10 +7183,10 @@ function registerQuickEvaluateTool(server) { "quick_evaluate", "Quick evaluate either a class or a predicate in a CodeQL query for debugging", { - file: z20.string().describe("Path to the .ql file containing the symbol"), - db: z20.string().describe("Path to the CodeQL database"), - symbol: z20.string().describe("Name of the class or predicate to evaluate"), - output_path: z20.string().optional().describe("Output path for results (defaults to project-local .tmp/quickeval/)") + file: z22.string().describe("Path to the .ql file containing the symbol"), + db: z22.string().describe("Path to the CodeQL database"), + symbol: z22.string().describe("Name of the class or predicate to evaluate"), + output_path: z22.string().optional().describe("Output path for results (defaults to project-local .tmp/quickeval/)") }, async ({ file, db, symbol, output_path }) => { try { @@ -6554,7 +7212,7 @@ function registerQuickEvaluateTool(server) { // src/tools/codeql/register-database.ts init_logger(); -import { z as z21 } from "zod"; +import { z as z23 } from "zod"; import { access, constants } from "fs/promises"; import { resolve as resolve7 } from "path"; async function registerDatabase(dbPath) { @@ -6605,7 +7263,7 @@ function registerRegisterDatabaseTool(server) { "register_database", "Register a CodeQL database given a local path to the database directory", { - db_path: z21.string().describe("Path to the CodeQL database directory") + db_path: z23.string().describe("Path to the CodeQL database directory") }, async ({ db_path }) => { try { @@ -6630,15 +7288,15 @@ function registerRegisterDatabaseTool(server) { } // src/tools/codeql/resolve-database.ts -import { z as z22 } from "zod"; +import { z as z24 } from "zod"; var codeqlResolveDatabaseTool = { name: "codeql_resolve_database", description: "Resolve database path and validate database structure", command: "codeql", subcommand: "resolve database", inputSchema: { - database: z22.string().describe("Database path to resolve"), - format: z22.enum(["text", "json", "betterjson"]).optional().describe("Output format for database information"), + database: z24.string().describe("Database path to resolve"), + format: z24.enum(["text", "json", "betterjson"]).optional().describe("Output format for database information"), verbose: createCodeQLSchemas.verbose(), additionalArgs: createCodeQLSchemas.additionalArgs() }, @@ -6651,16 +7309,16 @@ var codeqlResolveDatabaseTool = { }; // src/tools/codeql/resolve-languages.ts -import { z as z23 } from "zod"; +import { z as z25 } from "zod"; var codeqlResolveLanguagesTool = { name: "codeql_resolve_languages", description: "List installed CodeQL extractor packs", command: "codeql", subcommand: "resolve languages", inputSchema: { - format: z23.enum(["text", "json", "betterjson"]).optional().describe("Output format for language information"), - verbose: z23.boolean().optional().describe("Enable verbose output"), - additionalArgs: z23.array(z23.string()).optional().describe("Additional command-line arguments") + format: z25.enum(["text", "json", "betterjson"]).optional().describe("Output format for language information"), + verbose: z25.boolean().optional().describe("Enable verbose output"), + additionalArgs: z25.array(z25.string()).optional().describe("Additional command-line arguments") }, examples: [ "codeql resolve languages --format=text", @@ -6671,17 +7329,17 @@ var codeqlResolveLanguagesTool = { }; // src/tools/codeql/resolve-library-path.ts -import { z as z24 } from "zod"; +import { z as z26 } from "zod"; var codeqlResolveLibraryPathTool = { name: "codeql_resolve_library-path", description: "Resolve library path for CodeQL queries and libraries", command: "codeql", subcommand: "resolve library-path", inputSchema: { - language: z24.string().optional().describe("Programming language to resolve library path for"), - format: z24.enum(["text", "json", "betterjson"]).optional().describe("Output format for library path information"), - verbose: z24.boolean().optional().describe("Enable verbose output"), - additionalArgs: z24.array(z24.string()).optional().describe("Additional command-line arguments") + language: z26.string().optional().describe("Programming language to resolve library path for"), + format: z26.enum(["text", "json", "betterjson"]).optional().describe("Output format for library path information"), + verbose: z26.boolean().optional().describe("Enable verbose output"), + additionalArgs: z26.array(z26.string()).optional().describe("Additional command-line arguments") }, examples: [ "codeql resolve library-path --language=java", @@ -6692,17 +7350,17 @@ var codeqlResolveLibraryPathTool = { }; // src/tools/codeql/resolve-metadata.ts -import { z as z25 } from "zod"; +import { z as z27 } from "zod"; var codeqlResolveMetadataTool = { name: "codeql_resolve_metadata", description: "Resolve and return the key-value metadata pairs from a CodeQL query source file.", command: "codeql", subcommand: "resolve metadata", inputSchema: { - query: z25.string().describe("Query file to resolve metadata for"), - format: z25.enum(["json"]).optional().describe("Output format for metadata information (always JSON, optional for future compatibility)"), - verbose: z25.boolean().optional().describe("Enable verbose output"), - additionalArgs: z25.array(z25.string()).optional().describe("Additional command-line arguments") + query: z27.string().describe("Query file to resolve metadata for"), + format: z27.enum(["json"]).optional().describe("Output format for metadata information (always JSON, optional for future compatibility)"), + verbose: z27.boolean().optional().describe("Enable verbose output"), + additionalArgs: z27.array(z27.string()).optional().describe("Additional command-line arguments") }, examples: [ "codeql resolve metadata -- relative-path/2/MyQuery.ql", @@ -6712,15 +7370,15 @@ var codeqlResolveMetadataTool = { }; // src/tools/codeql/resolve-qlref.ts -import { z as z26 } from "zod"; +import { z as z28 } from "zod"; var codeqlResolveQlrefTool = { name: "codeql_resolve_qlref", description: "Resolve qlref files to their corresponding query files", command: "codeql", subcommand: "resolve qlref", inputSchema: { - qlref: z26.string().describe("Path to the .qlref file to resolve"), - format: z26.enum(["text", "json", "betterjson"]).optional().describe("Output format for qlref resolution"), + qlref: z28.string().describe("Path to the .qlref file to resolve"), + format: z28.enum(["text", "json", "betterjson"]).optional().describe("Output format for qlref resolution"), verbose: createCodeQLSchemas.verbose(), additionalArgs: createCodeQLSchemas.additionalArgs() }, @@ -6733,7 +7391,7 @@ var codeqlResolveQlrefTool = { }; // src/tools/codeql/resolve-queries.ts -import { z as z27 } from "zod"; +import { z as z29 } from "zod"; var jsonOnlyResultProcessor = (result, params) => { if (!result.success) { return `Command failed (exit code ${result.exitCode || "unknown"}): @@ -6763,10 +7421,10 @@ var codeqlResolveQueriesTool = { command: "codeql", subcommand: "resolve queries", inputSchema: { - directory: z27.string().optional().describe("Directory to search for queries"), - language: z27.string().optional().describe("Filter queries by programming language"), - format: z27.enum(["text", "json", "betterjson", "bylanguage"]).optional().describe("Output format for query list"), - "additional-packs": z27.union([z27.string(), z27.array(z27.string())]).optional().describe("Additional pack directories to search for CodeQL packs"), + directory: z29.string().optional().describe("Directory to search for queries"), + language: z29.string().optional().describe("Filter queries by programming language"), + format: z29.enum(["text", "json", "betterjson", "bylanguage"]).optional().describe("Output format for query list"), + "additional-packs": z29.union([z29.string(), z29.array(z29.string())]).optional().describe("Additional pack directories to search for CodeQL packs"), verbose: createCodeQLSchemas.verbose(), additionalArgs: createCodeQLSchemas.additionalArgs() }, @@ -6780,15 +7438,15 @@ var codeqlResolveQueriesTool = { }; // src/tools/codeql/resolve-tests.ts -import { z as z28 } from "zod"; +import { z as z30 } from "zod"; var codeqlResolveTestsTool = { name: "codeql_resolve_tests", description: "Resolve the local filesystem paths of unit tests and/or queries under some base directory", command: "codeql", subcommand: "resolve tests", inputSchema: { - tests: z28.array(z28.string()).optional().describe("One or more tests (.ql, .qlref files, or test directories)"), - format: z28.enum(["text", "json"]).optional().describe("Output format for test list"), + tests: z30.array(z30.string()).optional().describe("One or more tests (.ql, .qlref files, or test directories)"), + format: z30.enum(["text", "json"]).optional().describe("Output format for test list"), verbose: createCodeQLSchemas.verbose(), additionalArgs: createCodeQLSchemas.additionalArgs() }, @@ -6801,14 +7459,14 @@ var codeqlResolveTestsTool = { }; // src/tools/codeql/test-accept.ts -import { z as z29 } from "zod"; +import { z as z31 } from "zod"; var codeqlTestAcceptTool = { name: "codeql_test_accept", description: "Accept new test results as the expected baseline", command: "codeql", subcommand: "test accept", inputSchema: { - tests: z29.array(z29.string()).describe("One or more tests (.ql, .qlref files, or test directories)"), + tests: z31.array(z31.string()).describe("One or more tests (.ql, .qlref files, or test directories)"), verbose: createCodeQLSchemas.verbose(), additionalArgs: createCodeQLSchemas.additionalArgs() }, @@ -6821,15 +7479,15 @@ var codeqlTestAcceptTool = { }; // src/tools/codeql/test-extract.ts -import { z as z30 } from "zod"; +import { z as z32 } from "zod"; var codeqlTestExtractTool = { name: "codeql_test_extract", description: "Extract test databases for CodeQL query tests", command: "codeql", subcommand: "test extract", inputSchema: { - tests: z30.array(z30.string()).describe("One or more test directories or files"), - language: z30.string().optional().describe("Programming language for extraction"), + tests: z32.array(z32.string()).describe("One or more test directories or files"), + language: z32.string().optional().describe("Programming language for extraction"), threads: createCodeQLSchemas.threads(), ram: createCodeQLSchemas.ram(), verbose: createCodeQLSchemas.verbose(), @@ -6844,18 +7502,18 @@ var codeqlTestExtractTool = { }; // src/tools/codeql/test-run.ts -import { z as z31 } from "zod"; +import { z as z33 } from "zod"; var codeqlTestRunTool = { name: "codeql_test_run", description: "Run CodeQL query tests", command: "codeql", subcommand: "test run", inputSchema: { - tests: z31.array(z31.string()).describe("One or more tests (.ql, .qlref files, or test directories)"), - "show-extractor-output": z31.boolean().optional().describe("Show output from extractors during test execution"), - "keep-databases": z31.boolean().optional().describe("Keep test databases after running tests"), - "learn": z31.boolean().optional().describe("Accept current output as expected for failing tests"), - logDir: z31.string().optional().describe("Custom directory for test execution logs (overrides CODEQL_QUERY_LOG_DIR environment variable). If not provided, uses CODEQL_QUERY_LOG_DIR or defaults to .tmp/query-logs/"), + tests: z33.array(z33.string()).describe("One or more tests (.ql, .qlref files, or test directories)"), + "show-extractor-output": z33.boolean().optional().describe("Show output from extractors during test execution"), + "keep-databases": z33.boolean().optional().describe("Keep test databases after running tests"), + "learn": z33.boolean().optional().describe("Accept current output as expected for failing tests"), + logDir: z33.string().optional().describe("Custom directory for test execution logs (overrides CODEQL_QUERY_LOG_DIR environment variable). If not provided, uses CODEQL_QUERY_LOG_DIR or defaults to .tmp/query-logs/"), threads: createCodeQLSchemas.threads(), ram: createCodeQLSchemas.ram(), verbose: createCodeQLSchemas.verbose(), @@ -6870,7 +7528,7 @@ var codeqlTestRunTool = { }; // src/tools/codeql-tools.ts -import { z as z32 } from "zod"; +import { z as z34 } from "zod"; // src/lib/validation.ts function validateCodeQLSyntax(query, _language) { @@ -6989,8 +7647,8 @@ function registerCodeQLTools(server) { "validate_codeql_query", "Quick heuristic validation for CodeQL query structure - checks for common patterns like from/where/select clauses and metadata presence. Does NOT compile the query. For authoritative validation with actual compilation, use codeql_lsp_diagnostics instead.", { - query: z32.string().describe("The CodeQL query to validate"), - language: z32.string().optional().describe("Target programming language") + query: z34.string().describe("The CodeQL query to validate"), + language: z34.string().optional().describe("Target programming language") }, async ({ query, language }) => { try { @@ -7016,11 +7674,11 @@ function registerCodeQLTools(server) { "create_codeql_query", "Create directory structure and files for a new CodeQL query with tests", { - basePath: z32.string().describe("Base path where src/ and test/ directories will be created"), - queryName: z32.string().describe("Name of the query (e.g., MySecurityQuery)"), - language: z32.string().describe("Target programming language (e.g., javascript, python, java)"), - description: z32.string().optional().describe("Description of what the query does"), - queryId: z32.string().optional().describe("Custom query ID (defaults to language/example/queryname)") + basePath: z34.string().describe("Base path where src/ and test/ directories will be created"), + queryName: z34.string().describe("Name of the query (e.g., MySecurityQuery)"), + language: z34.string().describe("Target programming language (e.g., javascript, python, java)"), + description: z34.string().optional().describe("Description of what the query does"), + queryId: z34.string().optional().describe("Custom query ID (defaults to language/example/queryname)") }, async ({ basePath, queryName, language, description, queryId }) => { try { @@ -7089,42 +7747,44 @@ function registerCodeQLTools(server) { registerFindCodeQLQueryFilesTool(server); registerFindPredicatePositionTool(server); registerListDatabasesTool(server); + registerListMrvaRunResultsTool(server); registerListQueryRunResultsTool(server); + registerProfileCodeQLQueryFromLogsTool(server); registerProfileCodeQLQueryTool(server); registerQuickEvaluateTool(server); registerRegisterDatabaseTool(server); } // src/lib/resources.ts -import { readFileSync as readFileSync7 } from "fs"; -import { join as join12, dirname as dirname7 } from "path"; +import { readFileSync as readFileSync9 } from "fs"; +import { join as join14, dirname as dirname8 } from "path"; import { fileURLToPath as fileURLToPath2 } from "url"; var __filename2 = fileURLToPath2(import.meta.url); -var __dirname2 = dirname7(__filename2); +var __dirname2 = dirname8(__filename2); function getGettingStartedGuide() { try { - return readFileSync7(join12(__dirname2, "../resources/getting-started.md"), "utf-8"); + return readFileSync9(join14(__dirname2, "../resources/getting-started.md"), "utf-8"); } catch { return "Getting started guide not available"; } } function getQueryBasicsGuide() { try { - return readFileSync7(join12(__dirname2, "../resources/query-basics.md"), "utf-8"); + return readFileSync9(join14(__dirname2, "../resources/query-basics.md"), "utf-8"); } catch { return "Query basics guide not available"; } } function getSecurityTemplates() { try { - return readFileSync7(join12(__dirname2, "../resources/security-templates.md"), "utf-8"); + return readFileSync9(join14(__dirname2, "../resources/security-templates.md"), "utf-8"); } catch { return "Security templates not available"; } } function getPerformancePatterns() { try { - return readFileSync7(join12(__dirname2, "../resources/performance-patterns.md"), "utf-8"); + return readFileSync9(join14(__dirname2, "../resources/performance-patterns.md"), "utf-8"); } catch { return "Performance patterns not available"; } @@ -7213,8 +7873,8 @@ function registerCodeQLResources(server) { // src/tools/lsp/lsp-diagnostics.ts init_logger(); init_temp_dir(); -import { z as z33 } from "zod"; -import { join as join13 } from "path"; +import { z as z35 } from "zod"; +import { join as join15 } from "path"; import { pathToFileURL as pathToFileURL3 } from "url"; // src/tools/lsp/lsp-server-helper.ts @@ -7312,7 +7972,7 @@ async function lspDiagnostics({ serverOptions, workspaceUri }); - const evalUri = pathToFileURL3(join13(getProjectTmpDir("lsp-eval"), `eval_${Date.now()}.ql`)).href; + const evalUri = pathToFileURL3(join15(getProjectTmpDir("lsp-eval"), `eval_${Date.now()}.ql`)).href; const diagnostics = await languageServer.evaluateQL(qlCode, evalUri); const summary = { errorCount: diagnostics.filter((d) => d.severity === 1).length, @@ -7339,10 +7999,10 @@ function registerLspDiagnosticsTool(server) { "codeql_lsp_diagnostics", "Authoritative syntax and semantic validation of CodeQL (QL) code via the CodeQL Language Server. Compiles the query and provides real-time diagnostics with precise error locations. Use this for accurate validation; for quick heuristic checks without compilation, use validate_codeql_query instead. Note: inline ql_code is evaluated as a virtual document and cannot resolve pack imports (e.g. `import javascript`). For validating queries with imports, use codeql_query_compile on the actual file instead.", { - log_level: z33.enum(["OFF", "ERROR", "WARN", "INFO", "DEBUG", "TRACE", "ALL"]).optional().describe("Language server log level"), - ql_code: z33.string().describe("The CodeQL (QL) code to evaluate for syntax and semantic errors"), - search_path: z33.string().optional().describe("Optional search path for CodeQL libraries"), - workspace_uri: z33.string().optional().describe("Optional workspace URI for context (defaults to ./ql directory)") + log_level: z35.enum(["OFF", "ERROR", "WARN", "INFO", "DEBUG", "TRACE", "ALL"]).optional().describe("Language server log level"), + ql_code: z35.string().describe("The CodeQL (QL) code to evaluate for syntax and semantic errors"), + search_path: z35.string().optional().describe("Optional search path for CodeQL libraries"), + workspace_uri: z35.string().optional().describe("Optional workspace URI for context (defaults to ./ql directory)") }, async ({ ql_code, workspace_uri, search_path, log_level }) => { try { @@ -7469,15 +8129,15 @@ async function lspReferences(params) { } // src/tools/lsp/lsp-tools.ts -import { z as z34 } from "zod"; +import { z as z36 } from "zod"; init_logger(); var lspParamsSchema = { - character: z34.number().int().min(0).describe("0-based character offset within the line"), - file_content: z34.string().optional().describe("Optional file content override (reads from disk if omitted)"), - file_path: z34.string().describe("Path to the CodeQL (.ql/.qll) file. Relative paths are resolved against the user workspace directory (see CODEQL_MCP_WORKSPACE)."), - line: z34.number().int().min(0).describe("0-based line number in the document"), - search_path: z34.string().optional().describe("Optional search path for CodeQL libraries"), - workspace_uri: z34.string().optional().describe("Optional workspace URI for context (defaults to ./ql directory)") + character: z36.number().int().min(0).describe("0-based character offset within the line"), + file_content: z36.string().optional().describe("Optional file content override (reads from disk if omitted)"), + file_path: z36.string().describe("Path to the CodeQL (.ql/.qll) file. Relative paths are resolved against the user workspace directory (see CODEQL_MCP_WORKSPACE)."), + line: z36.number().int().min(0).describe("0-based line number in the document"), + search_path: z36.string().optional().describe("Optional search path for CodeQL libraries"), + workspace_uri: z36.string().optional().describe("Optional workspace URI for context (defaults to ./ql directory)") }; function toHandlerParams(input) { return { @@ -7587,8 +8247,8 @@ function registerLSPTools(server) { } // src/resources/language-resources.ts -import { readFileSync as readFileSync8, existsSync as existsSync9 } from "fs"; -import { join as join14 } from "path"; +import { readFileSync as readFileSync10, existsSync as existsSync11 } from "fs"; +import { join as join16 } from "path"; // src/types/language-types.ts var LANGUAGE_RESOURCES = [ @@ -7648,12 +8308,12 @@ function getQLBasePath() { } function loadResourceContent(relativePath) { try { - const fullPath = join14(getQLBasePath(), relativePath); - if (!existsSync9(fullPath)) { + const fullPath = join16(getQLBasePath(), relativePath); + if (!existsSync11(fullPath)) { logger.warn(`Resource file not found: ${fullPath}`); return null; } - return readFileSync8(fullPath, "utf-8"); + return readFileSync10(fullPath, "utf-8"); } catch (error) { logger.error(`Error loading resource file ${relativePath}:`, error); return null; @@ -7775,19 +8435,19 @@ function registerLanguageResources(server) { } // src/prompts/workflow-prompts.ts -import { z as z35 } from "zod"; -import { basename as basename5 } from "path"; +import { z as z37 } from "zod"; +import { basename as basename6 } from "path"; // src/prompts/prompt-loader.ts -import { readFileSync as readFileSync9 } from "fs"; -import { join as join15, dirname as dirname8 } from "path"; +import { readFileSync as readFileSync11 } from "fs"; +import { join as join17, dirname as dirname9 } from "path"; import { fileURLToPath as fileURLToPath3 } from "url"; var __filename3 = fileURLToPath3(import.meta.url); -var __dirname3 = dirname8(__filename3); +var __dirname3 = dirname9(__filename3); function loadPromptTemplate(promptFileName) { try { - const promptPath = join15(__dirname3, promptFileName); - return readFileSync9(promptPath, "utf-8"); + const promptPath = join17(__dirname3, promptFileName); + return readFileSync11(promptPath, "utf-8"); } catch (error) { return `Prompt template '${promptFileName}' not available: ${error instanceof Error ? error.message : "Unknown error"}`; } @@ -7819,49 +8479,49 @@ var SUPPORTED_LANGUAGES = [ "ruby", "swift" ]; -var testDrivenDevelopmentSchema = z35.object({ - language: z35.enum(SUPPORTED_LANGUAGES).describe("Programming language for the query"), - queryName: z35.string().optional().describe("Name of the query to develop") +var testDrivenDevelopmentSchema = z37.object({ + language: z37.enum(SUPPORTED_LANGUAGES).describe("Programming language for the query"), + queryName: z37.string().optional().describe("Name of the query to develop") }); -var toolsQueryWorkflowSchema = z35.object({ - database: z35.string().describe("Path to the CodeQL database"), - language: z35.enum(SUPPORTED_LANGUAGES).describe("Programming language for the tools queries"), - sourceFiles: z35.string().optional().describe('Comma-separated source file names for PrintAST (e.g., "main.js,utils.js")'), - sourceFunction: z35.string().optional().describe('Function name for PrintCFG or CallGraphFrom (e.g., "processData")'), - targetFunction: z35.string().optional().describe('Function name for CallGraphTo (e.g., "validate")') +var toolsQueryWorkflowSchema = z37.object({ + database: z37.string().describe("Path to the CodeQL database"), + language: z37.enum(SUPPORTED_LANGUAGES).describe("Programming language for the tools queries"), + sourceFiles: z37.string().optional().describe('Comma-separated source file names for PrintAST (e.g., "main.js,utils.js")'), + sourceFunction: z37.string().optional().describe('Function name for PrintCFG or CallGraphFrom (e.g., "processData")'), + targetFunction: z37.string().optional().describe('Function name for CallGraphTo (e.g., "validate")') }); -var workshopCreationWorkflowSchema = z35.object({ - queryPath: z35.string().describe("Path to the production-grade CodeQL query (.ql or .qlref)"), - language: z35.enum(SUPPORTED_LANGUAGES).describe("Programming language of the query"), - workshopName: z35.string().optional().describe("Name for the workshop directory"), - numStages: z35.coerce.number().optional().describe("Number of incremental stages (default: 4-8)") +var workshopCreationWorkflowSchema = z37.object({ + queryPath: z37.string().describe("Path to the production-grade CodeQL query (.ql or .qlref)"), + language: z37.enum(SUPPORTED_LANGUAGES).describe("Programming language of the query"), + workshopName: z37.string().optional().describe("Name for the workshop directory"), + numStages: z37.coerce.number().optional().describe("Number of incremental stages (default: 4-8)") }); -var qlTddBasicSchema = z35.object({ - language: z35.enum(SUPPORTED_LANGUAGES).optional().describe("Programming language for the query (optional)"), - queryName: z35.string().optional().describe("Name of the query to develop") +var qlTddBasicSchema = z37.object({ + language: z37.enum(SUPPORTED_LANGUAGES).optional().describe("Programming language for the query (optional)"), + queryName: z37.string().optional().describe("Name of the query to develop") }); -var qlTddAdvancedSchema = z35.object({ - database: z35.string().optional().describe("Path to the CodeQL database for analysis"), - language: z35.enum(SUPPORTED_LANGUAGES).optional().describe("Programming language for the query (optional)"), - queryName: z35.string().optional().describe("Name of the query to develop") +var qlTddAdvancedSchema = z37.object({ + database: z37.string().optional().describe("Path to the CodeQL database for analysis"), + language: z37.enum(SUPPORTED_LANGUAGES).optional().describe("Programming language for the query (optional)"), + queryName: z37.string().optional().describe("Name of the query to develop") }); -var sarifRankSchema = z35.object({ - queryId: z35.string().optional().describe("CodeQL query/rule identifier"), - sarifPath: z35.string().optional().describe("Path to the SARIF file to analyze") +var sarifRankSchema = z37.object({ + queryId: z37.string().optional().describe("CodeQL query/rule identifier"), + sarifPath: z37.string().optional().describe("Path to the SARIF file to analyze") }); -var explainCodeqlQuerySchema = z35.object({ - databasePath: z35.string().optional().describe("Optional path to a real CodeQL database for profiling"), - language: z35.enum(SUPPORTED_LANGUAGES).describe("Programming language of the query"), - queryPath: z35.string().describe("Path to the CodeQL query file (.ql or .qlref)") +var explainCodeqlQuerySchema = z37.object({ + databasePath: z37.string().optional().describe("Optional path to a real CodeQL database for profiling"), + language: z37.enum(SUPPORTED_LANGUAGES).describe("Programming language of the query"), + queryPath: z37.string().describe("Path to the CodeQL query file (.ql or .qlref)") }); -var documentCodeqlQuerySchema = z35.object({ - language: z35.enum(SUPPORTED_LANGUAGES).describe("Programming language of the query"), - queryPath: z35.string().describe("Path to the CodeQL query file (.ql or .qlref)") +var documentCodeqlQuerySchema = z37.object({ + language: z37.enum(SUPPORTED_LANGUAGES).describe("Programming language of the query"), + queryPath: z37.string().describe("Path to the CodeQL query file (.ql or .qlref)") }); -var qlLspIterativeDevelopmentSchema = z35.object({ - language: z35.enum(SUPPORTED_LANGUAGES).optional().describe("Programming language for the query"), - queryPath: z35.string().optional().describe("Path to the query file being developed"), - workspaceUri: z35.string().optional().describe("Workspace URI for LSP dependency resolution") +var qlLspIterativeDevelopmentSchema = z37.object({ + language: z37.enum(SUPPORTED_LANGUAGES).optional().describe("Programming language for the query"), + queryPath: z37.string().optional().describe("Path to the query file being developed"), + workspaceUri: z37.string().optional().describe("Workspace URI for LSP dependency resolution") }); var WORKFLOW_PROMPT_NAMES = [ "document_codeql_query", @@ -7946,7 +8606,7 @@ ${content}` workshopCreationWorkflowSchema.shape, async ({ queryPath, language, workshopName, numStages }) => { const template = loadPromptTemplate("workshop-creation-workflow.prompt.md"); - const derivedName = workshopName || basename5(queryPath).replace(/\.(ql|qlref)$/, "").toLowerCase().replace(/[^a-z0-9]+/g, "-") || "codeql-workshop"; + const derivedName = workshopName || basename6(queryPath).replace(/\.(ql|qlref)$/, "").toLowerCase().replace(/[^a-z0-9]+/g, "-") || "codeql-workshop"; const contextSection = buildWorkshopContext( queryPath, language, @@ -8248,7 +8908,7 @@ function buildWorkshopContext(queryPath, language, workshopName, numStages) { } // src/tools/monitoring-tools.ts -import { z as z37 } from "zod"; +import { z as z39 } from "zod"; import { randomUUID as randomUUID3 } from "crypto"; // ../node_modules/lowdb/lib/core/Low.js @@ -8282,7 +8942,7 @@ var Low = class { }; // ../node_modules/lowdb/lib/adapters/node/TextFile.js -import { readFileSync as readFileSync10, renameSync, writeFileSync as writeFileSync5 } from "node:fs"; +import { readFileSync as readFileSync12, renameSync, writeFileSync as writeFileSync6 } from "node:fs"; import path3 from "node:path"; var TextFileSync = class { #tempFilename; @@ -8295,7 +8955,7 @@ var TextFileSync = class { read() { let data; try { - data = readFileSync10(this.#filename, "utf-8"); + data = readFileSync12(this.#filename, "utf-8"); } catch (e) { if (e.code === "ENOENT") { return null; @@ -8305,7 +8965,7 @@ var TextFileSync = class { return data; } write(str2) { - writeFileSync5(this.#tempFilename, str2); + writeFileSync6(this.#tempFilename, str2); renameSync(this.#tempFilename, this.#filename); } }; @@ -8345,136 +9005,136 @@ var JSONFileSync = class extends DataFileSync { // src/lib/session-data-manager.ts init_temp_dir(); -import { mkdirSync as mkdirSync8, writeFileSync as writeFileSync6 } from "fs"; -import { join as join16 } from "path"; +import { mkdirSync as mkdirSync9, writeFileSync as writeFileSync7 } from "fs"; +import { join as join18 } from "path"; import { randomUUID as randomUUID2 } from "crypto"; // src/types/monitoring.ts -import { z as z36 } from "zod"; -var MCPCallRecordSchema = z36.object({ - callId: z36.string(), - timestamp: z36.string(), +import { z as z38 } from "zod"; +var MCPCallRecordSchema = z38.object({ + callId: z38.string(), + timestamp: z38.string(), // ISO timestamp - toolName: z36.string(), - parameters: z36.record(z36.any()), - result: z36.any(), - success: z36.boolean(), - duration: z36.number(), + toolName: z38.string(), + parameters: z38.record(z38.any()), + result: z38.any(), + success: z38.boolean(), + duration: z38.number(), // milliseconds - nextSuggestedTool: z36.string().optional() + nextSuggestedTool: z38.string().optional() }); -var TestExecutionRecordSchema = z36.object({ - executionId: z36.string(), - timestamp: z36.string(), - type: z36.enum(["compilation", "test_run", "database_build"]), - success: z36.boolean(), - details: z36.record(z36.any()), - metrics: z36.object({ - passRate: z36.number().optional(), - coverage: z36.number().optional(), - performance: z36.number().optional() +var TestExecutionRecordSchema = z38.object({ + executionId: z38.string(), + timestamp: z38.string(), + type: z38.enum(["compilation", "test_run", "database_build"]), + success: z38.boolean(), + details: z38.record(z38.any()), + metrics: z38.object({ + passRate: z38.number().optional(), + coverage: z38.number().optional(), + performance: z38.number().optional() }).optional() }); -var QualityScoreRecordSchema = z36.object({ - scoreId: z36.string(), - timestamp: z36.string(), - overallScore: z36.number().min(0).max(100), +var QualityScoreRecordSchema = z38.object({ + scoreId: z38.string(), + timestamp: z38.string(), + overallScore: z38.number().min(0).max(100), // 0-100 - dimensions: z36.object({ - syntacticCorrectness: z36.number().min(0).max(100), - testCoverageResults: z36.number().min(0).max(100), - documentationQuality: z36.number().min(0).max(100), - functionalCorrectness: z36.number().min(0).max(100) + dimensions: z38.object({ + syntacticCorrectness: z38.number().min(0).max(100), + testCoverageResults: z38.number().min(0).max(100), + documentationQuality: z38.number().min(0).max(100), + functionalCorrectness: z38.number().min(0).max(100) }), - grade: z36.enum(["A", "B", "C", "D", "F"]), - recommendations: z36.array(z36.string()) + grade: z38.enum(["A", "B", "C", "D", "F"]), + recommendations: z38.array(z38.string()) }); -var QueryStateSchema = z36.object({ - filesPresent: z36.array(z36.string()), - compilationStatus: z36.enum(["unknown", "success", "failed"]), - testStatus: z36.enum(["unknown", "passing", "failing", "no_tests"]), - documentationStatus: z36.enum(["unknown", "present", "missing", "incomplete"]), - lastActivity: z36.string() +var QueryStateSchema = z38.object({ + filesPresent: z38.array(z38.string()), + compilationStatus: z38.enum(["unknown", "success", "failed"]), + testStatus: z38.enum(["unknown", "passing", "failing", "no_tests"]), + documentationStatus: z38.enum(["unknown", "present", "missing", "incomplete"]), + lastActivity: z38.string() // ISO timestamp }); -var QueryDevelopmentSessionSchema = z36.object({ +var QueryDevelopmentSessionSchema = z38.object({ // Session Metadata - sessionId: z36.string(), - queryPath: z36.string(), - language: z36.string(), - queryType: z36.string().optional(), - description: z36.string().optional(), - startTime: z36.string(), + sessionId: z38.string(), + queryPath: z38.string(), + language: z38.string(), + queryType: z38.string().optional(), + description: z38.string().optional(), + startTime: z38.string(), // ISO timestamp - endTime: z36.string().optional(), + endTime: z38.string().optional(), // ISO timestamp - status: z36.enum(["active", "completed", "failed", "abandoned"]), + status: z38.enum(["active", "completed", "failed", "abandoned"]), // MCP Call History - mcpCalls: z36.array(MCPCallRecordSchema), + mcpCalls: z38.array(MCPCallRecordSchema), // Test Execution Records - testExecutions: z36.array(TestExecutionRecordSchema), + testExecutions: z38.array(TestExecutionRecordSchema), // Quality Metrics - qualityScores: z36.array(QualityScoreRecordSchema), + qualityScores: z38.array(QualityScoreRecordSchema), // Development State currentState: QueryStateSchema, - recommendations: z36.array(z36.string()), - nextSuggestedTool: z36.string().optional() + recommendations: z38.array(z38.string()), + nextSuggestedTool: z38.string().optional() }); -var SessionFilterSchema = z36.object({ - queryPath: z36.string().optional(), - status: z36.string().optional(), - dateRange: z36.tuple([z36.string(), z36.string()]).optional(), - language: z36.string().optional(), - queryType: z36.string().optional() +var SessionFilterSchema = z38.object({ + queryPath: z38.string().optional(), + status: z38.string().optional(), + dateRange: z38.tuple([z38.string(), z38.string()]).optional(), + language: z38.string().optional(), + queryType: z38.string().optional() }); -var ComparisonReportSchema = z36.object({ - sessionIds: z36.array(z36.string()), - dimensions: z36.array(z36.string()), - timestamp: z36.string(), - results: z36.record(z36.any()) +var ComparisonReportSchema = z38.object({ + sessionIds: z38.array(z38.string()), + dimensions: z38.array(z38.string()), + timestamp: z38.string(), + results: z38.record(z38.any()) }); -var AggregateReportSchema = z36.object({ +var AggregateReportSchema = z38.object({ filters: SessionFilterSchema, - timestamp: z36.string(), - totalSessions: z36.number(), - successRate: z36.number(), - averageQualityScore: z36.number(), - commonPatterns: z36.array(z36.string()), - recommendations: z36.array(z36.string()) + timestamp: z38.string(), + totalSessions: z38.number(), + successRate: z38.number(), + averageQualityScore: z38.number(), + commonPatterns: z38.array(z38.string()), + recommendations: z38.array(z38.string()) }); -var ExportResultSchema = z36.object({ - format: z36.enum(["json", "html", "markdown"]), - filename: z36.string(), - content: z36.string(), - timestamp: z36.string() +var ExportResultSchema = z38.object({ + format: z38.enum(["json", "html", "markdown"]), + filename: z38.string(), + content: z38.string(), + timestamp: z38.string() }); -var FunctionalTestResultSchema = z36.object({ - sessionId: z36.string(), - queryPath: z36.string(), - passed: z36.boolean(), - criteria: z36.record(z36.any()), - details: z36.record(z36.any()), - timestamp: z36.string() +var FunctionalTestResultSchema = z38.object({ + sessionId: z38.string(), + queryPath: z38.string(), + passed: z38.boolean(), + criteria: z38.record(z38.any()), + details: z38.record(z38.any()), + timestamp: z38.string() }); -var TestReportSchema = z36.object({ - sessionIds: z36.array(z36.string()), - criteria: z36.record(z36.any()), - timestamp: z36.string(), - overallPassRate: z36.number(), - results: z36.array(FunctionalTestResultSchema), - summary: z36.record(z36.any()) +var TestReportSchema = z38.object({ + sessionIds: z38.array(z38.string()), + criteria: z38.record(z38.any()), + timestamp: z38.string(), + overallPassRate: z38.number(), + results: z38.array(FunctionalTestResultSchema), + summary: z38.record(z38.any()) }); -var MonitoringConfigSchema = z36.object({ - storageLocation: z36.string().default(".ql-mcp-tracking/"), - autoTrackSessions: z36.boolean().default(true), - retentionDays: z36.number().default(90), - includeCallParameters: z36.boolean().default(true), - includeCallResults: z36.boolean().default(true), - maxActiveSessionsPerQuery: z36.number().default(3), - scoringFrequency: z36.enum(["per_call", "periodic", "manual"]).default("per_call"), - archiveCompletedSessions: z36.boolean().default(true), - enableRecommendations: z36.boolean().default(true), - enableMonitoringTools: z36.boolean().default(false) +var MonitoringConfigSchema = z38.object({ + storageLocation: z38.string().default(".ql-mcp-tracking/"), + autoTrackSessions: z38.boolean().default(true), + retentionDays: z38.number().default(90), + includeCallParameters: z38.boolean().default(true), + includeCallResults: z38.boolean().default(true), + maxActiveSessionsPerQuery: z38.number().default(3), + scoringFrequency: z38.enum(["per_call", "periodic", "manual"]).default("per_call"), + archiveCompletedSessions: z38.boolean().default(true), + enableRecommendations: z38.boolean().default(true), + enableMonitoringTools: z38.boolean().default(false) // Opt-in: session_* tools disabled by default for end-users }); @@ -8491,7 +9151,7 @@ var SessionDataManager = class { }); this.storageDir = this.config.storageLocation; this.ensureStorageDirectory(); - const adapter = new JSONFileSync(join16(this.storageDir, "sessions.json")); + const adapter = new JSONFileSync(join18(this.storageDir, "sessions.json")); this.db = new Low(adapter, { sessions: [] }); @@ -8520,14 +9180,14 @@ var SessionDataManager = class { */ ensureStorageDirectory() { try { - mkdirSync8(this.storageDir, { recursive: true }); + mkdirSync9(this.storageDir, { recursive: true }); const subdirs = ["sessions-archive", "exports"]; for (const subdir of subdirs) { - mkdirSync8(join16(this.storageDir, subdir), { recursive: true }); + mkdirSync9(join18(this.storageDir, subdir), { recursive: true }); } - const configPath = join16(this.storageDir, "config.json"); + const configPath = join18(this.storageDir, "config.json"); try { - writeFileSync6(configPath, JSON.stringify(this.config, null, 2), { flag: "wx" }); + writeFileSync7(configPath, JSON.stringify(this.config, null, 2), { flag: "wx" }); } catch (e) { const err = e; if (err.code !== "EEXIST") throw e; @@ -8704,10 +9364,10 @@ var SessionDataManager = class { if (!session) return; const date = new Date(session.endTime || session.startTime); const monthDir = `${date.getFullYear()}-${String(date.getMonth() + 1).padStart(2, "0")}`; - const archiveDir = join16(this.storageDir, "sessions-archive", monthDir); - mkdirSync8(archiveDir, { recursive: true }); - const archiveFile = join16(archiveDir, `${sessionId}.json`); - writeFileSync6(archiveFile, JSON.stringify(session, null, 2)); + const archiveDir = join18(this.storageDir, "sessions-archive", monthDir); + mkdirSync9(archiveDir, { recursive: true }); + const archiveFile = join18(archiveDir, `${sessionId}.json`); + writeFileSync7(archiveFile, JSON.stringify(session, null, 2)); await this.db.read(); this.db.data.sessions = this.db.data.sessions.filter((s) => s.sessionId !== sessionId); await this.db.write(); @@ -8758,8 +9418,8 @@ var SessionDataManager = class { ...this.config, ...configUpdate }); - const configPath = join16(this.storageDir, "config.json"); - writeFileSync6(configPath, JSON.stringify(this.config, null, 2)); + const configPath = join18(this.storageDir, "config.json"); + writeFileSync7(configPath, JSON.stringify(this.config, null, 2)); logger.info("Updated monitoring configuration"); } }; @@ -8768,7 +9428,7 @@ function parseBoolEnv(envVar, defaultValue) { return envVar.toLowerCase() === "true" || envVar === "1"; } var sessionDataManager = new SessionDataManager({ - storageLocation: process.env.MONITORING_STORAGE_LOCATION || join16(getProjectTmpBase(), ".ql-mcp-tracking"), + storageLocation: process.env.MONITORING_STORAGE_LOCATION || join18(getProjectTmpBase(), ".ql-mcp-tracking"), enableMonitoringTools: parseBoolEnv(process.env.ENABLE_MONITORING_TOOLS, false) }); @@ -8798,8 +9458,8 @@ function registerSessionEndTool(server) { "session_end", "End a query development session with final status", { - sessionId: z37.string().describe("ID of the session to end"), - status: z37.enum(["completed", "failed", "abandoned"]).describe("Final status of the session") + sessionId: z39.string().describe("ID of the session to end"), + status: z39.enum(["completed", "failed", "abandoned"]).describe("Final status of the session") }, async ({ sessionId, status }) => { try { @@ -8843,7 +9503,7 @@ function registerSessionGetTool(server) { "session_get", "Get complete details of a specific query development session", { - sessionId: z37.string().describe("ID of the session to retrieve") + sessionId: z39.string().describe("ID of the session to retrieve") }, async ({ sessionId }) => { try { @@ -8887,11 +9547,11 @@ function registerSessionListTool(server) { "session_list", "List query development sessions with optional filtering", { - queryPath: z37.string().optional().describe("Filter by query path (partial match)"), - status: z37.string().optional().describe("Filter by session status"), - dateRange: z37.array(z37.string()).length(2).optional().describe("Filter by date range [start, end] (ISO timestamps)"), - language: z37.string().optional().describe("Filter by programming language"), - queryType: z37.string().optional().describe("Filter by query type") + queryPath: z39.string().optional().describe("Filter by query path (partial match)"), + status: z39.string().optional().describe("Filter by session status"), + dateRange: z39.array(z39.string()).length(2).optional().describe("Filter by date range [start, end] (ISO timestamps)"), + language: z39.string().optional().describe("Filter by programming language"), + queryType: z39.string().optional().describe("Filter by query type") }, async ({ queryPath, status, dateRange, language, queryType }) => { try { @@ -8947,11 +9607,11 @@ function registerSessionUpdateStateTool(server) { "session_update_state", "Update the current state of a query development session", { - sessionId: z37.string().describe("ID of the session to update"), - filesPresent: z37.array(z37.string()).optional().describe("List of files present in the query development"), - compilationStatus: z37.enum(["unknown", "success", "failed"]).optional().describe("Current compilation status"), - testStatus: z37.enum(["unknown", "passing", "failing", "no_tests"]).optional().describe("Current test status"), - documentationStatus: z37.enum(["unknown", "present", "missing", "incomplete"]).optional().describe("Documentation status") + sessionId: z39.string().describe("ID of the session to update"), + filesPresent: z39.array(z39.string()).optional().describe("List of files present in the query development"), + compilationStatus: z39.enum(["unknown", "success", "failed"]).optional().describe("Current compilation status"), + testStatus: z39.enum(["unknown", "passing", "failing", "no_tests"]).optional().describe("Current test status"), + documentationStatus: z39.enum(["unknown", "present", "missing", "incomplete"]).optional().describe("Documentation status") }, async ({ sessionId, filesPresent, compilationStatus, testStatus, documentationStatus }) => { try { @@ -9001,8 +9661,8 @@ function registerSessionGetCallHistoryTool(server) { "session_get_call_history", "Get MCP call history for a specific session", { - sessionId: z37.string().describe("ID of the session"), - limit: z37.number().optional().describe("Maximum number of calls to return (most recent first)") + sessionId: z39.string().describe("ID of the session"), + limit: z39.number().optional().describe("Maximum number of calls to return (most recent first)") }, async ({ sessionId, limit }) => { try { @@ -9054,8 +9714,8 @@ function registerSessionGetTestHistoryTool(server) { "session_get_test_history", "Get test execution history for a specific session", { - sessionId: z37.string().describe("ID of the session"), - limit: z37.number().optional().describe("Maximum number of test executions to return (most recent first)") + sessionId: z39.string().describe("ID of the session"), + limit: z39.number().optional().describe("Maximum number of test executions to return (most recent first)") }, async ({ sessionId, limit }) => { try { @@ -9107,8 +9767,8 @@ function registerSessionGetScoreHistoryTool(server) { "session_get_score_history", "Get quality score history for a specific session", { - sessionId: z37.string().describe("ID of the session"), - limit: z37.number().optional().describe("Maximum number of scores to return (most recent first)") + sessionId: z39.string().describe("ID of the session"), + limit: z39.number().optional().describe("Maximum number of scores to return (most recent first)") }, async ({ sessionId, limit }) => { try { @@ -9160,7 +9820,7 @@ function registerSessionCalculateCurrentScoreTool(server) { "session_calculate_current_score", "Calculate current quality score for a session based on its state", { - sessionId: z37.string().describe("ID of the session") + sessionId: z39.string().describe("ID of the session") }, async ({ sessionId }) => { try { @@ -9208,8 +9868,8 @@ function registerSessionsCompareTool(server) { "sessions_compare", "Compare multiple query development sessions across specified dimensions", { - sessionIds: z37.array(z37.string()).describe("Array of session IDs to compare"), - dimensions: z37.array(z37.string()).optional().describe("Specific dimensions to compare (default: all)") + sessionIds: z39.array(z39.string()).describe("Array of session IDs to compare"), + dimensions: z39.array(z39.string()).optional().describe("Specific dimensions to compare (default: all)") }, async ({ sessionIds, dimensions }) => { try { @@ -9257,11 +9917,11 @@ function registerSessionsAggregateTool(server) { "sessions_aggregate", "Generate aggregate insights from multiple sessions based on filters", { - queryPath: z37.string().optional().describe("Filter by query path (partial match)"), - status: z37.string().optional().describe("Filter by session status"), - dateRange: z37.array(z37.string()).length(2).optional().describe("Filter by date range [start, end] (ISO timestamps)"), - language: z37.string().optional().describe("Filter by programming language"), - queryType: z37.string().optional().describe("Filter by query type") + queryPath: z39.string().optional().describe("Filter by query path (partial match)"), + status: z39.string().optional().describe("Filter by session status"), + dateRange: z39.array(z39.string()).length(2).optional().describe("Filter by date range [start, end] (ISO timestamps)"), + language: z39.string().optional().describe("Filter by programming language"), + queryType: z39.string().optional().describe("Filter by query type") }, async ({ queryPath, status, dateRange, language, queryType }) => { try { @@ -9303,8 +9963,8 @@ function registerSessionsExportTool(server) { "sessions_export", "Export session data in specified format for external analysis", { - sessionIds: z37.array(z37.string()).describe("Array of session IDs to export"), - format: z37.enum(["json", "html", "markdown"]).optional().default("json").describe("Export format") + sessionIds: z39.array(z39.string()).describe("Array of session IDs to export"), + format: z39.enum(["json", "html", "markdown"]).optional().default("json").describe("Export format") }, async ({ sessionIds, format = "json" }) => { try { diff --git a/server/dist/codeql-development-mcp-server.js.map b/server/dist/codeql-development-mcp-server.js.map index 1d9467e0..8e56f45d 100644 --- a/server/dist/codeql-development-mcp-server.js.map +++ b/server/dist/codeql-development-mcp-server.js.map @@ -1,7 +1,7 @@ { "version": 3, - "sources": ["../src/utils/logger.ts", "../src/lib/server-config.ts", "../src/utils/package-paths.ts", "../src/utils/temp-dir.ts", "../src/utils/process-ready.ts", "../src/lib/language-server.ts", "../src/lib/query-server.ts", "../src/lib/cli-server.ts", "../src/lib/server-manager.ts", "../src/lib/cli-executor.ts", "../src/codeql-development-mcp-server.ts", "../src/tools/codeql/bqrs-decode.ts", "../src/lib/cli-tool-registry.ts", "../src/lib/query-results-evaluator.ts", "../src/lib/log-directory-manager.ts", "../src/tools/codeql/bqrs-info.ts", "../src/tools/codeql/bqrs-interpret.ts", "../src/tools/codeql/database-analyze.ts", "../src/tools/codeql/database-create.ts", "../src/tools/codeql/find-class-position.ts", "../src/tools/codeql/find-predicate-position.ts", "../src/tools/codeql/find-query-files.ts", "../src/lib/query-file-finder.ts", "../../node_modules/js-yaml/dist/js-yaml.mjs", "../src/lib/metadata-resolver.ts", "../src/tools/codeql/generate-log-summary.ts", "../src/tools/codeql/generate-query-help.ts", "../src/tools/codeql/list-databases.ts", "../src/lib/discovery-config.ts", "../src/tools/codeql/list-query-run-results.ts", "../src/tools/codeql/pack-install.ts", "../src/tools/codeql/pack-ls.ts", "../src/tools/codeql/profile-codeql-query.ts", "../src/tools/codeql/query-compile.ts", "../src/tools/codeql/query-format.ts", "../src/tools/codeql/query-run.ts", "../src/tools/codeql/quick-evaluate.ts", "../src/tools/codeql/register-database.ts", "../src/tools/codeql/resolve-database.ts", "../src/tools/codeql/resolve-languages.ts", "../src/tools/codeql/resolve-library-path.ts", "../src/tools/codeql/resolve-metadata.ts", "../src/tools/codeql/resolve-qlref.ts", "../src/tools/codeql/resolve-queries.ts", "../src/tools/codeql/resolve-tests.ts", "../src/tools/codeql/test-accept.ts", "../src/tools/codeql/test-extract.ts", "../src/tools/codeql/test-run.ts", "../src/tools/codeql-tools.ts", "../src/lib/validation.ts", "../src/lib/query-scaffolding.ts", "../src/lib/resources.ts", "../src/tools/codeql-resources.ts", "../src/tools/lsp/lsp-diagnostics.ts", "../src/tools/lsp/lsp-server-helper.ts", "../src/tools/lsp/lsp-handlers.ts", "../src/tools/lsp/lsp-tools.ts", "../src/resources/language-resources.ts", "../src/types/language-types.ts", "../src/prompts/workflow-prompts.ts", "../src/prompts/prompt-loader.ts", "../src/tools/monitoring-tools.ts", "../../node_modules/lowdb/lib/core/Low.js", "../../node_modules/lowdb/lib/adapters/node/TextFile.js", "../../node_modules/lowdb/lib/adapters/node/DataFile.js", "../../node_modules/lowdb/lib/adapters/node/JSONFile.js", "../src/lib/session-data-manager.ts", "../src/types/monitoring.ts"], - "sourcesContent": ["/**\n * Simple logger utility.\n *\n * All log output is written to stderr. In stdio transport mode, stdout is\n * reserved exclusively for the MCP JSON-RPC protocol \u2014 any non-protocol\n * bytes on stdout would corrupt the message stream.\n */\nexport const logger = {\n info: (message: string, ...args: unknown[]) => {\n console.error(`[INFO] ${new Date().toISOString()} ${message}`, ...args);\n },\n error: (message: string, ...args: unknown[]) => {\n console.error(`[ERROR] ${new Date().toISOString()} ${message}`, ...args);\n },\n warn: (message: string, ...args: unknown[]) => {\n console.error(`[WARN] ${new Date().toISOString()} ${message}`, ...args);\n },\n debug: (message: string, ...args: unknown[]) => {\n if (process.env.DEBUG) {\n console.error(`[DEBUG] ${new Date().toISOString()} ${message}`, ...args);\n }\n },\n};\n", "/**\n * Configuration types for CodeQL background server processes.\n *\n * CodeQL provides three background server types:\n * 1. language-server \u2013 LSP-based QL validation (JSON-RPC over stdio)\n * 2. query-server2 \u2013 Query evaluation (custom protocol over stdio)\n * 3. cli-server \u2013 JVM reuse for CLI commands (custom protocol over stdio)\n *\n * Each server type has its own configuration options, but they share common\n * settings like searchPath and commonCaches.\n */\n\nimport { createHash } from 'crypto';\n\n/**\n * Server types supported by CodeQL.\n */\nexport type CodeQLServerType = 'cli' | 'language' | 'query';\n\n/**\n * Common configuration shared across all server types.\n */\nexport interface BaseServerConfig {\n /** Path to QL packs (like `codeql query compile --search-path`). */\n searchPath?: string;\n /** Location for cached data (compilation plans, downloaded packs). */\n commonCaches?: string;\n /** Directory for detailed logs. */\n logdir?: string;\n}\n\n/**\n * Configuration for the CodeQL Language Server.\n */\nexport interface LanguageServerConfig extends BaseServerConfig {\n /** Error checking mode. Default: ON_CHANGE */\n checkErrors?: 'EXPLICIT' | 'ON_CHANGE';\n /** Log level for the language server. */\n loglevel?: 'ALL' | 'DEBUG' | 'ERROR' | 'INFO' | 'OFF' | 'TRACE' | 'WARN';\n /** Single-threaded execution. */\n synchronous?: boolean;\n /** Verbosity level for progress. */\n verbosity?: 'errors' | 'progress' | 'progress+' | 'progress++' | 'progress+++' | 'warnings';\n}\n\n/**\n * Configuration for the CodeQL Query Server (query-server2).\n */\nexport interface QueryServerConfig extends BaseServerConfig {\n /** Thread count. 0 = one per core, -N = leave N cores free. */\n threads?: number;\n /** Query evaluation timeout in seconds. */\n timeout?: number;\n /** Maximum disk cache size in MB for intermediate results. */\n maxDiskCache?: number;\n /** Path for structured evaluator performance logs. */\n evaluatorLog?: string;\n /** Include tuple counts in evaluation logs. */\n tupleCounting?: boolean;\n /** Enable debug mode. */\n debug?: boolean;\n}\n\n/**\n * Configuration for the CodeQL CLI Server.\n */\nexport interface CLIServerConfig extends BaseServerConfig {\n // cli-server has fewer options \u2014 just commonCaches and logdir.\n}\n\n/**\n * Union of all server configurations (discriminated by usage context).\n */\nexport type ServerConfig = CLIServerConfig | LanguageServerConfig | QueryServerConfig;\n\n/**\n * Compute a deterministic hash for a server configuration.\n * Used to detect configuration changes that require a server restart.\n *\n * @param type - The server type.\n * @param config - The server configuration.\n * @returns A hex-encoded SHA-256 hash of the canonical JSON representation.\n */\nexport function computeConfigHash(type: CodeQLServerType, config: ServerConfig): string {\n // Deep-sort all keys to ensure deterministic serialization regardless of\n // property insertion order.\n const sortKeys = (_key: string, value: unknown): unknown => {\n if (value && typeof value === 'object' && !Array.isArray(value)) {\n const sorted: Record = {};\n for (const k of Object.keys(value as Record).sort()) {\n sorted[k] = (value as Record)[k];\n }\n return sorted;\n }\n return value;\n };\n const canonical = JSON.stringify({ config, type }, sortKeys);\n return createHash('sha256').update(canonical).digest('hex');\n}\n\n/**\n * Build command-line arguments for a language server from its configuration.\n */\nexport function buildLanguageServerArgs(config: LanguageServerConfig): string[] {\n const args: string[] = [\n 'execute', 'language-server',\n `--check-errors=${config.checkErrors ?? 'ON_CHANGE'}`,\n ];\n\n if (config.searchPath) {\n args.push(`--search-path=${config.searchPath}`);\n }\n if (config.commonCaches) {\n args.push(`--common-caches=${config.commonCaches}`);\n }\n if (config.logdir) {\n args.push(`--logdir=${config.logdir}`);\n }\n if (config.loglevel) {\n args.push(`--loglevel=${config.loglevel}`);\n }\n if (config.synchronous) {\n args.push('--synchronous');\n }\n if (config.verbosity) {\n args.push(`--verbosity=${config.verbosity}`);\n }\n\n return args;\n}\n\n/**\n * Build command-line arguments for a query server from its configuration.\n */\nexport function buildQueryServerArgs(config: QueryServerConfig): string[] {\n const args: string[] = [\n 'execute', 'query-server2',\n ];\n\n if (config.searchPath) {\n args.push(`--search-path=${config.searchPath}`);\n }\n if (config.commonCaches) {\n args.push(`--common-caches=${config.commonCaches}`);\n }\n if (config.logdir) {\n args.push(`--logdir=${config.logdir}`);\n }\n if (config.threads !== undefined) {\n args.push(`--threads=${config.threads}`);\n }\n if (config.timeout !== undefined) {\n args.push(`--timeout=${config.timeout}`);\n }\n if (config.maxDiskCache !== undefined) {\n args.push(`--max-disk-cache=${config.maxDiskCache}`);\n }\n if (config.evaluatorLog) {\n args.push(`--evaluator-log=${config.evaluatorLog}`);\n }\n if (config.debug) {\n args.push('--debug');\n args.push('--tuple-counting');\n } else if (config.tupleCounting) {\n args.push('--tuple-counting');\n }\n\n return args;\n}\n\n/**\n * Build command-line arguments for a CLI server from its configuration.\n */\nexport function buildCLIServerArgs(config: CLIServerConfig): string[] {\n const args: string[] = [\n 'execute', 'cli-server',\n ];\n\n if (config.commonCaches) {\n args.push(`--common-caches=${config.commonCaches}`);\n }\n if (config.logdir) {\n args.push(`--logdir=${config.logdir}`);\n }\n\n return args;\n}\n", "/**\n * Utilities for resolving filesystem paths relative to the server package root.\n *\n * The server can run from three different directory layouts:\n *\n * 1. **Source** (dev): `server/src/lib/` \u2192 packageRoot = `server/`\n * 2. **Bundle in monorepo** (dev/CI): `server/dist/` \u2192 packageRoot = `server/`\n * 3. **Bundle via npm** (production): `/dist/` \u2192 packageRoot = `/`\n *\n * In all three cases, the bundled QL tool query packs live at\n * `/ql//tools/src/`.\n *\n * The \"workspace root\" (monorepo root) is one level above packageRoot when\n * running from the monorepo checkout, and the packageRoot itself when running\n * from an npm install (no parent monorepo).\n */\n\nimport { dirname, resolve } from 'path';\nimport { existsSync, readFileSync } from 'fs';\nimport { fileURLToPath } from 'url';\n\nconst __filename = fileURLToPath(import.meta.url);\nconst __dirname = dirname(__filename);\n\n/**\n * Detect whether the current __dirname looks like source code (`src/lib` or\n * `src/utils`) vs a bundled flat output directory (`dist/`).\n *\n * Uses a tail-of-path check so that unrelated `/src/` segments earlier in the\n * install path (e.g. `~/src/project/node_modules/.../dist`) don't cause a\n * false positive.\n */\nfunction isRunningFromSource(dir: string): boolean {\n const normalized = dir.replace(/\\\\/g, '/');\n return /\\/src(\\/[^/]+)?$/.test(normalized);\n}\n\n/**\n * Get the server package root directory.\n *\n * - From source (`server/src/utils/`): up 2 levels \u2192 `server/`\n * - From bundle (`server/dist/` or `/dist/`): up 1 level \u2192 package root\n */\nexport function getPackageRootDir(currentDir: string = __dirname): string {\n return isRunningFromSource(currentDir)\n ? resolve(currentDir, '..', '..') // src/utils \u2192 server/\n : resolve(currentDir, '..'); // dist/ \u2192 package root\n}\n\n/**\n * Get the workspace root directory (monorepo root when applicable).\n *\n * If a `package.json` with `workspaces` exists one level above the package\n * root, we're in a monorepo and that parent is the workspace root. Otherwise,\n * the packageRoot itself is the workspace root (npm install scenario).\n */\nexport function getWorkspaceRootDir(packageRoot?: string): string {\n const pkgRoot = packageRoot ?? getPackageRootDir();\n const parentDir = resolve(pkgRoot, '..');\n\n // In the monorepo, the parent directory contains a package.json with workspaces\n try {\n const parentPkgPath = resolve(parentDir, 'package.json');\n if (existsSync(parentPkgPath)) {\n const parentPkg = JSON.parse(readFileSync(parentPkgPath, 'utf8'));\n if (parentPkg.workspaces) {\n return parentDir;\n }\n }\n } catch {\n // Not in a monorepo \u2014 fall through\n }\n\n return pkgRoot;\n}\n\n/**\n * Resolve the path to a tool query pack's source directory.\n *\n * @param language - CodeQL language identifier (e.g., \"javascript\", \"cpp\")\n * @param packageRoot - Override the package root (for testing)\n * @returns Absolute path to `ql//tools/src/`\n */\nexport function resolveToolQueryPackPath(language: string, packageRoot?: string): string {\n const pkgRoot = packageRoot ?? getPackageRootDir();\n return resolve(pkgRoot, 'ql', language, 'tools', 'src');\n}\n\n/**\n * Read the package version from the nearest package.json.\n *\n * Cached at first call so the file is read at most once per process.\n */\nlet _cachedVersion: string | undefined;\nexport function getPackageVersion(): string {\n if (_cachedVersion !== undefined) return _cachedVersion;\n try {\n const pkgPath = resolve(getPackageRootDir(), 'package.json');\n const pkg = JSON.parse(readFileSync(pkgPath, 'utf8'));\n _cachedVersion = pkg.version ?? '0.0.0';\n } catch {\n _cachedVersion = '0.0.0';\n }\n return _cachedVersion as string;\n}\n\n/**\n * Get the effective workspace directory for resolving user-supplied relative\n * paths (test directories, database paths, pack dirs, etc.).\n *\n * In a monorepo checkout the workspace root is the monorepo parent. In an\n * npm-installed layout, `workspaceRootDir` falls back to `packageRootDir`\n * which may be read-only and is not the user's project. In that case we\n * fall back to `process.cwd()` so that relative paths resolve against the\n * directory the user actually invoked the server from.\n *\n * Override with `CODEQL_MCP_WORKSPACE` for deterministic behavior.\n */\nexport function getUserWorkspaceDir(): string {\n if (process.env.CODEQL_MCP_WORKSPACE) {\n return process.env.CODEQL_MCP_WORKSPACE;\n }\n // When workspaceRootDir === packageRootDir we are NOT in a monorepo\n // (npm-installed), so fall back to process.cwd().\n if (workspaceRootDir === packageRootDir) {\n return process.cwd();\n }\n return workspaceRootDir;\n}\n\n// Pre-computed values for use throughout the server\nexport const packageRootDir = getPackageRootDir();\nexport const workspaceRootDir = getWorkspaceRootDir(packageRootDir);\n", "/**\n * Secure project-local temporary directory utilities.\n *\n * All temporary files are created under `/.tmp/` which is\n * `.gitignore`d. This avoids writing to the OS temp directory\n * (`os.tmpdir()` / `/tmp`), which is world-readable and triggers\n * CWE-377 / CWE-378 (js/insecure-temporary-file).\n */\n\nimport { mkdirSync, mkdtempSync } from 'fs';\nimport { isAbsolute, join, resolve } from 'path';\nimport { getPackageRootDir } from './package-paths';\n\n/**\n * Base directory for all project-local temporary data.\n *\n * Resolution order:\n * 1. `CODEQL_MCP_TMP_DIR` environment variable \u2014 for read-only package root\n * scenarios (e.g., npm global installs where the package directory is not\n * writable). Relative paths are resolved against process.cwd().\n * 2. `/.tmp` \u2014 default; excluded from version control.\n */\nconst PROJECT_TMP_BASE = process.env.CODEQL_MCP_TMP_DIR\n ? (isAbsolute(process.env.CODEQL_MCP_TMP_DIR) \n ? process.env.CODEQL_MCP_TMP_DIR \n : resolve(process.cwd(), process.env.CODEQL_MCP_TMP_DIR))\n : join(getPackageRootDir(), '.tmp');\n\n/**\n * Return the project-local `.tmp` base directory, creating it if needed.\n */\nexport function getProjectTmpBase(): string {\n mkdirSync(PROJECT_TMP_BASE, { recursive: true });\n return PROJECT_TMP_BASE;\n}\n\n/**\n * Create a unique temporary directory under the project `.tmp` root.\n *\n * Works identically to `fs.mkdtempSync(os.tmpdir(), prefix)` but is\n * scoped to the repository.\n *\n * @param prefix - Directory name prefix (e.g. `'codeql-external-'`).\n * @returns Absolute path to the newly created directory.\n */\nexport function createProjectTempDir(prefix: string): string {\n const base = getProjectTmpBase();\n return mkdtempSync(join(base, prefix));\n}\n\n/**\n * Return a deterministic subdirectory under `.tmp/`, creating it\n * if it does not already exist.\n *\n * Useful for well-known scratch areas such as `query-logs` or `quickeval`.\n *\n * @param name - Subdirectory name (e.g. `'query-logs'`).\n * @returns Absolute path to the subdirectory.\n */\nexport function getProjectTmpDir(name: string): string {\n const dir = join(getProjectTmpBase(), name);\n mkdirSync(dir, { recursive: true });\n return dir;\n}\n", "/**\n * Utility for waiting until a spawned child process is ready.\n *\n * CodeQL background servers (cli-server, query-server2, language-server) run\n * on the JVM and emit stderr log output once the JVM has initialised. Rather\n * than sleeping for a hard-coded duration \u2014 which is fragile on both fast and\n * slow machines \u2014 this helper resolves as soon as the first stderr output\n * arrives (indicating the JVM is alive), or when the maximum timeout expires.\n * It also rejects immediately if the process exits or errors before becoming\n * ready, giving callers a clear error instead of a silent hang.\n */\n\nimport { ChildProcess } from 'child_process';\nimport { clearTimeout, setTimeout } from 'timers';\nimport { logger } from './logger';\n\n/** Default maximum wait for a CodeQL server to become ready (30 s). */\nconst DEFAULT_READY_TIMEOUT_MS = 30_000;\n\n/**\n * Options for {@link waitForProcessReady}.\n */\nexport interface ProcessReadyOptions {\n /**\n * Maximum time in milliseconds to wait for the process to emit its first\n * stderr output. If the timeout is reached without a signal the promise\n * still resolves (best-effort) so the caller can attempt communication.\n *\n * Default: 30 000 ms.\n */\n timeoutMs?: number;\n}\n\n/**\n * Wait until a child process signals readiness.\n *\n * \"Ready\" is defined as any of:\n * 1. The process emits data on **stderr** (JVM startup log line).\n * 2. The process emits data on **stdout** (initial protocol message).\n * 3. The maximum timeout elapses (best-effort resolve).\n *\n * The promise **rejects** if the process emits an `error` event or exits\n * before any of the above conditions are met.\n *\n * @param child - The spawned child process.\n * @param name - A human-readable label for log messages.\n * @param opts - Optional configuration.\n */\nexport function waitForProcessReady(\n child: ChildProcess,\n name: string,\n opts?: ProcessReadyOptions,\n): Promise {\n const timeoutMs = opts?.timeoutMs ?? DEFAULT_READY_TIMEOUT_MS;\n\n return new Promise((resolve, reject) => {\n let settled = false;\n\n const cleanup = () => {\n settled = true;\n child.stderr?.removeListener('data', onStderr);\n child.stdout?.removeListener('data', onStdout);\n child.removeListener('error', onError);\n child.removeListener('exit', onExit);\n clearTimeout(timer);\n };\n\n const onStderr = () => {\n if (settled) return;\n logger.debug(`${name}: ready (stderr output detected)`);\n cleanup();\n resolve();\n };\n\n const onStdout = () => {\n if (settled) return;\n logger.debug(`${name}: ready (stdout output detected)`);\n cleanup();\n resolve();\n };\n\n const onError = (error: Error) => {\n if (settled) return;\n cleanup();\n reject(new Error(`${name} failed to start: ${error.message}`));\n };\n\n const onExit = (code: number | null) => {\n if (settled) return;\n cleanup();\n reject(new Error(`${name} exited before becoming ready (code: ${code})`));\n };\n\n const timer = setTimeout(() => {\n if (settled) return;\n logger.warn(`${name}: readiness timeout (${timeoutMs} ms) \u2014 proceeding anyway`);\n cleanup();\n resolve(); // best-effort: let the caller attempt communication\n }, timeoutMs);\n\n child.stderr?.on('data', onStderr);\n child.stdout?.on('data', onStdout);\n child.on('error', onError);\n child.on('exit', onExit);\n\n // If the process was dead before we even attached listeners, reject now\n if (child.killed || child.exitCode !== null) {\n cleanup();\n reject(new Error(`${name} is not running (exitCode: ${child.exitCode})`));\n }\n });\n}\n", "/**\n * CodeQL Language Server manager for LSP communication\n * Manages the lifecycle and communication with the CodeQL language server process\n */\n\nimport { spawn, ChildProcess } from 'child_process';\nimport { EventEmitter } from 'events';\nimport { setTimeout, clearTimeout } from 'timers';\nimport { pathToFileURL } from 'url';\nimport { delimiter, join } from 'path';\nimport { logger } from '../utils/logger';\nimport { getPackageVersion } from '../utils/package-paths';\nimport { getProjectTmpDir } from '../utils/temp-dir';\nimport { getResolvedCodeQLDir } from './cli-executor';\nimport { waitForProcessReady } from '../utils/process-ready';\n\nexport interface LSPMessage {\n jsonrpc: '2.0';\n id?: number | string;\n method: string;\n params?: unknown;\n result?: unknown;\n error?: {\n code: number;\n message: string;\n data?: unknown;\n };\n}\n\nexport interface Diagnostic {\n range: {\n start: { line: number; character: number };\n end: { line: number; character: number };\n };\n severity: number; // 1=Error, 2=Warning, 3=Information, 4=Hint\n source?: string;\n message: string;\n code?: string | number;\n}\n\nexport interface PublishDiagnosticsParams {\n uri: string;\n diagnostics: Diagnostic[];\n}\n\nexport interface LanguageServerOptions {\n searchPath?: string;\n logdir?: string;\n loglevel?: 'ALL' | 'DEBUG' | 'ERROR' | 'INFO' | 'OFF' | 'TRACE' | 'WARN';\n synchronous?: boolean;\n verbosity?: 'errors' | 'progress' | 'progress+' | 'progress++' | 'progress+++' | 'warnings';\n}\n\n/**\n * Position in a text document (0-based line and character).\n */\nexport interface LSPPosition {\n character: number;\n line: number;\n}\n\n/**\n * A range in a text document.\n */\nexport interface LSPRange {\n end: LSPPosition;\n start: LSPPosition;\n}\n\n/**\n * A location in a resource (file URI + range).\n */\nexport interface LSPLocation {\n range: LSPRange;\n uri: string;\n}\n\n/**\n * Identifies a text document by its URI.\n */\nexport interface TextDocumentIdentifier {\n uri: string;\n}\n\n/**\n * A text document position (document + position within it).\n */\nexport interface TextDocumentPositionParams {\n position: LSPPosition;\n textDocument: TextDocumentIdentifier;\n}\n\n/**\n * A completion item returned by the language server.\n */\nexport interface CompletionItem {\n detail?: string;\n documentation?: string | { kind: string; value: string };\n insertText?: string;\n kind?: number;\n label: string;\n sortText?: string;\n}\n\nexport class CodeQLLanguageServer extends EventEmitter {\n private server: ChildProcess | null = null;\n private messageId = 1;\n private pendingResponses = new Map void; reject: (_error: Error) => void }>();\n private isInitialized = false;\n private currentWorkspaceUri: string | undefined;\n private messageBuffer = '';\n\n constructor(private _options: LanguageServerOptions = {}) {\n super();\n }\n\n async start(): Promise {\n if (this.server) {\n throw new Error('Language server is already running');\n }\n\n logger.info('Starting CodeQL Language Server...');\n\n const args = [\n 'execute', 'language-server',\n '--check-errors=ON_CHANGE'\n ];\n\n // Add optional arguments\n if (this._options.searchPath) {\n args.push(`--search-path=${this._options.searchPath}`);\n }\n if (this._options.logdir) {\n args.push(`--logdir=${this._options.logdir}`);\n }\n if (this._options.loglevel) {\n args.push(`--loglevel=${this._options.loglevel}`);\n }\n if (this._options.synchronous) {\n args.push('--synchronous');\n }\n if (this._options.verbosity) {\n args.push(`--verbosity=${this._options.verbosity}`);\n }\n\n // Build environment with CODEQL_PATH directory prepended to PATH\n // (mirrors the approach in cli-executor.ts getSafeEnvironment).\n const spawnEnv = { ...process.env };\n const codeqlDir = getResolvedCodeQLDir();\n if (codeqlDir && spawnEnv.PATH) {\n spawnEnv.PATH = `${codeqlDir}${delimiter}${spawnEnv.PATH}`;\n } else if (codeqlDir) {\n spawnEnv.PATH = codeqlDir;\n }\n\n this.server = spawn('codeql', args, {\n stdio: ['pipe', 'pipe', 'pipe'],\n env: spawnEnv\n });\n\n this.server.stderr?.on('data', (data) => {\n logger.debug('CodeQL LS stderr:', data.toString());\n });\n\n this.server.stdout?.on('data', (data) => {\n this.handleStdout(data);\n });\n\n this.server.on('error', (error) => {\n logger.error('CodeQL Language Server error:', error);\n this.emit('error', error);\n });\n\n this.server.on('exit', (code) => {\n logger.info('CodeQL Language Server exited with code:', code);\n this.server = null;\n this.isInitialized = false;\n this.emit('exit', code);\n });\n\n // Wait for the JVM to initialise (resolves on first stderr/stdout output)\n await waitForProcessReady(this.server, 'CodeQL Language Server');\n }\n\n private handleStdout(data: Buffer): void {\n this.messageBuffer += data.toString();\n \n let headerEnd = this.messageBuffer.indexOf('\\r\\n\\r\\n');\n while (headerEnd !== -1) {\n const header = this.messageBuffer.substring(0, headerEnd);\n const contentLengthMatch = header.match(/Content-Length: (\\d+)/);\n \n if (contentLengthMatch) {\n const contentLength = parseInt(contentLengthMatch[1]);\n const messageStart = headerEnd + 4;\n const messageEnd = messageStart + contentLength;\n \n if (this.messageBuffer.length >= messageEnd) {\n const messageContent = this.messageBuffer.substring(messageStart, messageEnd);\n this.messageBuffer = this.messageBuffer.substring(messageEnd);\n \n try {\n const message: LSPMessage = JSON.parse(messageContent);\n this.handleMessage(message);\n } catch (error) {\n logger.error('Failed to parse LSP message:', error, messageContent);\n }\n \n headerEnd = this.messageBuffer.indexOf('\\r\\n\\r\\n');\n } else {\n break;\n }\n } else {\n logger.error('Invalid LSP header:', header);\n this.messageBuffer = '';\n break;\n }\n }\n }\n\n private handleMessage(message: LSPMessage): void {\n logger.debug('Received LSP message:', message);\n\n // Handle responses to our requests\n if (message.id !== undefined && this.pendingResponses.has(Number(message.id))) {\n const pending = this.pendingResponses.get(Number(message.id))!;\n this.pendingResponses.delete(Number(message.id));\n \n if (message.error) {\n pending.reject(new Error(`LSP Error: ${message.error.message}`));\n } else {\n pending.resolve(message.result);\n }\n return;\n }\n\n // Handle notifications from server\n if (message.method === 'textDocument/publishDiagnostics') {\n this.emit('diagnostics', message.params as PublishDiagnosticsParams);\n }\n }\n\n private sendMessage(message: LSPMessage): void {\n if (!this.server?.stdin) {\n throw new Error('Language server is not running');\n }\n\n const messageStr = JSON.stringify(message);\n const contentLength = Buffer.byteLength(messageStr, 'utf8');\n const header = `Content-Length: ${contentLength}\\r\\n\\r\\n`;\n const fullMessage = header + messageStr;\n\n logger.debug('Sending LSP message:', fullMessage);\n this.server.stdin.write(fullMessage);\n }\n\n private sendRequest(method: string, params?: unknown): Promise {\n const id = this.messageId++;\n const message: LSPMessage = {\n jsonrpc: '2.0',\n id,\n method,\n params\n };\n\n return new Promise((resolve, reject) => {\n // Wrap resolve/reject to clear the timer when the promise settles.\n const timer = setTimeout(() => {\n if (this.pendingResponses.has(id)) {\n this.pendingResponses.delete(id);\n reject(new Error(`LSP request timeout for method: ${method}`));\n }\n }, 60_000); // 60 second timeout (Windows CI cold JVM can exceed 30s)\n\n this.pendingResponses.set(id, {\n reject: (err: Error) => { clearTimeout(timer); reject(err); },\n resolve: (val: unknown) => { clearTimeout(timer); resolve(val); },\n });\n this.sendMessage(message);\n });\n }\n\n private sendNotification(method: string, params?: unknown): void {\n const message: LSPMessage = {\n jsonrpc: '2.0',\n method,\n params\n };\n this.sendMessage(message);\n }\n\n /**\n * Initialize the language server with an optional workspace URI.\n *\n * If the server is already initialized with a different workspace, a\n * `workspace/didChangeWorkspaceFolders` notification is sent to update\n * the workspace context instead of requiring a full restart.\n */\n async initialize(workspaceUri?: string): Promise {\n if (this.isInitialized) {\n // If workspace changed, notify the server\n if (workspaceUri && workspaceUri !== this.currentWorkspaceUri) {\n await this.updateWorkspace(workspaceUri);\n }\n return;\n }\n\n logger.info('Initializing CodeQL Language Server...');\n\n const initParams = {\n processId: process.pid,\n clientInfo: {\n name: 'codeql-development-mcp-server',\n version: getPackageVersion()\n },\n capabilities: {\n textDocument: {\n completion: { completionItem: { snippetSupport: false } },\n definition: {},\n publishDiagnostics: {},\n references: {},\n synchronization: {\n didClose: true,\n didChange: true,\n didOpen: true,\n },\n },\n workspace: {\n workspaceFolders: true,\n },\n }\n };\n\n if (workspaceUri) {\n (initParams as unknown as { workspaceFolders: unknown[] }).workspaceFolders = [{\n uri: workspaceUri,\n name: 'codeql-workspace'\n }];\n }\n\n await this.sendRequest('initialize', initParams);\n this.sendNotification('initialized', {});\n\n this.currentWorkspaceUri = workspaceUri;\n this.isInitialized = true;\n logger.info('CodeQL Language Server initialized successfully');\n }\n\n /**\n * Update the workspace folders on a running, initialized server.\n */\n private async updateWorkspace(newUri: string): Promise {\n logger.info(`Updating workspace from ${this.currentWorkspaceUri} to ${newUri}`);\n\n const removed = this.currentWorkspaceUri\n ? [{ uri: this.currentWorkspaceUri, name: 'codeql-workspace' }]\n : [];\n\n this.sendNotification('workspace/didChangeWorkspaceFolders', {\n event: {\n added: [{ uri: newUri, name: 'codeql-workspace' }],\n removed,\n },\n });\n\n this.currentWorkspaceUri = newUri;\n }\n\n /**\n * Get the current workspace URI.\n */\n getWorkspaceUri(): string | undefined {\n return this.currentWorkspaceUri;\n }\n\n async evaluateQL(qlCode: string, uri?: string): Promise {\n if (!this.isInitialized) {\n throw new Error('Language server is not initialized');\n }\n\n // Default to a project-local virtual URI rather than /tmp\n const documentUri = uri || pathToFileURL(join(getProjectTmpDir('lsp-eval'), 'eval.ql')).href;\n\n return new Promise((resolve, reject) => {\n let diagnosticsReceived = false;\n const timeout = setTimeout(() => {\n if (!diagnosticsReceived) {\n this.removeListener('diagnostics', diagnosticsHandler);\n reject(new Error('Timeout waiting for diagnostics'));\n }\n }, 90_000); // 90s \u2014 first call triggers JVM start + compilation; Windows CI is slow\n\n // Listen for diagnostics\n const diagnosticsHandler = (params: PublishDiagnosticsParams) => {\n if (params.uri === documentUri) {\n diagnosticsReceived = true;\n clearTimeout(timeout);\n this.removeListener('diagnostics', diagnosticsHandler);\n\n // Close the document\n this.sendNotification('textDocument/didClose', {\n textDocument: { uri: documentUri }\n });\n\n resolve(params.diagnostics);\n }\n };\n\n this.on('diagnostics', diagnosticsHandler);\n\n // Open the document with the QL code\n this.sendNotification('textDocument/didOpen', {\n textDocument: {\n uri: documentUri,\n languageId: 'ql',\n version: 1,\n text: qlCode\n }\n });\n });\n }\n\n // ---- LSP feature methods (issue #1) ----\n\n /**\n * Get code completions at a position in a document.\n */\n async getCompletions(params: TextDocumentPositionParams): Promise {\n if (!this.isInitialized) {\n throw new Error('Language server is not initialized');\n }\n if (!this.isRunning()) {\n throw new Error('Language server process is not running');\n }\n const result = await this.sendRequest('textDocument/completion', params);\n // The result may be a CompletionList or CompletionItem[]\n if (result && typeof result === 'object' && 'items' in (result as object)) {\n return (result as { items: CompletionItem[] }).items;\n }\n return (result as CompletionItem[]) || [];\n }\n\n /**\n * Find the definition(s) of a symbol at a position.\n */\n async getDefinition(params: TextDocumentPositionParams): Promise {\n if (!this.isInitialized) {\n throw new Error('Language server is not initialized');\n }\n if (!this.isRunning()) {\n throw new Error('Language server process is not running');\n }\n const result = await this.sendRequest('textDocument/definition', params);\n return this.normalizeLocations(result);\n }\n\n /**\n * Find all references to a symbol at a position.\n */\n async getReferences(params: TextDocumentPositionParams & { context?: { includeDeclaration: boolean } }): Promise {\n if (!this.isInitialized) {\n throw new Error('Language server is not initialized');\n }\n if (!this.isRunning()) {\n throw new Error('Language server process is not running');\n }\n const result = await this.sendRequest('textDocument/references', {\n ...params,\n context: params.context ?? { includeDeclaration: true },\n });\n return this.normalizeLocations(result);\n }\n\n /**\n * Open a text document in the language server.\n * The document must be opened before requesting completions, definitions, etc.\n */\n openDocument(uri: string, text: string, languageId = 'ql', version = 1): void {\n if (!this.isInitialized) {\n throw new Error('Language server is not initialized');\n }\n this.sendNotification('textDocument/didOpen', {\n textDocument: { uri, languageId, version, text },\n });\n }\n\n /**\n * Close a text document in the language server.\n */\n closeDocument(uri: string): void {\n if (!this.isInitialized) {\n throw new Error('Language server is not initialized');\n }\n this.sendNotification('textDocument/didClose', {\n textDocument: { uri },\n });\n }\n\n /**\n * Normalize a definition/references/implementation result to Location[].\n * The LSP spec allows Location | Location[] | LocationLink[].\n */\n private normalizeLocations(result: unknown): LSPLocation[] {\n if (!result) return [];\n if (Array.isArray(result)) {\n return result.map((item) => {\n // LocationLink has targetUri/targetRange\n if ('targetUri' in item) {\n return { uri: item.targetUri, range: item.targetRange } as LSPLocation;\n }\n return item as LSPLocation;\n });\n }\n // Single Location\n if (typeof result === 'object' && 'uri' in (result as object)) {\n return [result as LSPLocation];\n }\n return [];\n }\n\n async shutdown(): Promise {\n if (!this.server) {\n return;\n }\n\n logger.info('Shutting down CodeQL Language Server...');\n\n try {\n await this.sendRequest('shutdown', {});\n if (this.server) {\n this.sendNotification('exit', {});\n }\n } catch (error) {\n logger.warn('Error during graceful shutdown:', error);\n }\n\n // Force kill if needed\n await new Promise((resolve) => {\n const timer = setTimeout(() => {\n if (this.server) {\n this.server.kill('SIGTERM');\n }\n resolve();\n }, 1000);\n\n if (this.server) {\n this.server.once('exit', () => {\n clearTimeout(timer);\n this.server = null;\n resolve();\n });\n } else {\n clearTimeout(timer);\n resolve();\n }\n });\n\n this.isInitialized = false;\n }\n\n isRunning(): boolean {\n return this.server !== null && !this.server.killed;\n }\n}", "/**\n * CodeQL Query Server (query-server2) client.\n *\n * Manages a long-lived `codeql execute query-server2` process that evaluates\n * queries using a custom JSON-RPC protocol over stdio. Reusing the server\n * avoids repeated JVM startup for each query evaluation.\n *\n * Protocol: The query-server2 uses JSON-RPC with Content-Length headers\n * (same framing as LSP) over stdin/stdout.\n */\n\nimport { ChildProcess, spawn } from 'child_process';\nimport { delimiter } from 'path';\nimport { EventEmitter } from 'events';\nimport { clearTimeout, setTimeout } from 'timers';\nimport { buildQueryServerArgs, QueryServerConfig } from './server-config';\nimport { getResolvedCodeQLDir } from './cli-executor';\nimport { logger } from '../utils/logger';\nimport { waitForProcessReady } from '../utils/process-ready';\n\n/**\n * A pending request awaiting a response from the query server.\n */\ninterface PendingRequest {\n reject: (_error: Error) => void;\n resolve: (_value: unknown) => void;\n}\n\n/**\n * Client for the CodeQL query-server2 process.\n *\n * Spawns `codeql execute query-server2` and communicates over stdin/stdout\n * using JSON-RPC with Content-Length framing.\n */\nexport class CodeQLQueryServer extends EventEmitter {\n private messageBuffer = '';\n private messageId = 1;\n private pendingRequests = new Map();\n private process: ChildProcess | null = null;\n private readonly config: QueryServerConfig;\n\n constructor(config: QueryServerConfig) {\n super();\n this.config = config;\n }\n\n /**\n * Start the query-server2 process.\n */\n async start(): Promise {\n if (this.process) {\n throw new Error('Query server is already running');\n }\n\n logger.info('Starting CodeQL Query Server (query-server2)...');\n\n const args = buildQueryServerArgs(this.config);\n\n // Build environment with CODEQL_PATH directory prepended to PATH\n const spawnEnv = { ...process.env };\n const codeqlDir = getResolvedCodeQLDir();\n if (codeqlDir && spawnEnv.PATH) {\n spawnEnv.PATH = `${codeqlDir}${delimiter}${spawnEnv.PATH}`;\n } else if (codeqlDir) {\n spawnEnv.PATH = codeqlDir;\n }\n\n this.process = spawn('codeql', args, {\n stdio: ['pipe', 'pipe', 'pipe'],\n env: spawnEnv,\n });\n\n this.process.stderr?.on('data', (data: Buffer) => {\n logger.debug('QueryServer2 stderr:', data.toString());\n });\n\n this.process.stdout?.on('data', (data: Buffer) => {\n this.handleStdout(data);\n });\n\n this.process.on('error', (error: Error) => {\n logger.error('Query server process error:', error);\n this.emit('error', error);\n });\n\n this.process.on('exit', (code: number | null) => {\n logger.info(`Query server exited with code: ${code}`);\n this.rejectAllPending(new Error(`Query server exited with code: ${code}`));\n this.process = null;\n this.emit('exit', code);\n });\n\n // Wait for the JVM to initialise (resolves on first stderr/stdout output)\n await waitForProcessReady(this.process, 'CodeQL Query Server');\n logger.info('CodeQL Query Server started');\n }\n\n /**\n * Send a request to the query server and await the response.\n *\n * @param method - The JSON-RPC method name.\n * @param params - The method parameters.\n * @param timeoutMs - Request timeout in milliseconds (default: 300000 = 5 min).\n * @returns The result from the server.\n */\n sendRequest(method: string, params?: unknown, timeoutMs = 300_000): Promise {\n const id = this.messageId++;\n const message = {\n id,\n jsonrpc: '2.0' as const,\n method,\n params,\n };\n\n return new Promise((resolve, reject) => {\n this.pendingRequests.set(id, { reject, resolve });\n\n try {\n this.sendRaw(message);\n } catch (error) {\n // Clean up immediately \u2014 sendRaw() failed so no response will arrive.\n this.pendingRequests.delete(id);\n reject(error instanceof Error ? error : new Error(String(error)));\n return;\n }\n\n const timer = setTimeout(() => {\n if (this.pendingRequests.has(id)) {\n this.pendingRequests.delete(id);\n reject(new Error(`Query server request timeout for method: ${method}`));\n }\n }, timeoutMs);\n\n // Clear the timeout when the promise settles\n const originalResolve = resolve;\n const originalReject = reject;\n const wrapped = {\n reject: (err: Error) => { clearTimeout(timer); originalReject(err); },\n resolve: (val: unknown) => { clearTimeout(timer); originalResolve(val); },\n };\n this.pendingRequests.set(id, wrapped);\n });\n }\n\n /**\n * Gracefully shut down the query server.\n */\n async shutdown(): Promise {\n if (!this.process) {\n return;\n }\n\n logger.info('Shutting down CodeQL Query Server...');\n\n try {\n await this.sendRequest('shutdown', {}, 5000);\n } catch (error) {\n logger.warn('Error during query server graceful shutdown:', error);\n }\n\n // Force kill if process lingers\n await new Promise((resolve) => {\n const timer = setTimeout(() => {\n if (this.process) {\n this.process.kill('SIGTERM');\n this.process = null;\n }\n resolve();\n }, 2000);\n\n if (this.process) {\n this.process.once('exit', () => {\n clearTimeout(timer);\n this.process = null;\n resolve();\n });\n } else {\n clearTimeout(timer);\n resolve();\n }\n });\n }\n\n /**\n * Whether the query server process is running.\n */\n isRunning(): boolean {\n return this.process !== null && !this.process.killed;\n }\n\n // ---- private helpers ----\n\n private handleStdout(data: Buffer): void {\n this.messageBuffer += data.toString();\n\n let headerEnd = this.messageBuffer.indexOf('\\r\\n\\r\\n');\n while (headerEnd !== -1) {\n const header = this.messageBuffer.substring(0, headerEnd);\n const contentLengthMatch = header.match(/Content-Length: (\\d+)/);\n\n if (contentLengthMatch) {\n const contentLength = parseInt(contentLengthMatch[1]);\n const messageStart = headerEnd + 4;\n const messageEnd = messageStart + contentLength;\n\n if (this.messageBuffer.length >= messageEnd) {\n const messageContent = this.messageBuffer.substring(messageStart, messageEnd);\n this.messageBuffer = this.messageBuffer.substring(messageEnd);\n\n try {\n const message = JSON.parse(messageContent);\n this.handleMessage(message);\n } catch (error) {\n logger.error('Failed to parse query server message:', error);\n }\n\n headerEnd = this.messageBuffer.indexOf('\\r\\n\\r\\n');\n } else {\n break;\n }\n } else {\n logger.error('Invalid query server header:', header);\n this.messageBuffer = '';\n break;\n }\n }\n }\n\n private handleMessage(message: { error?: { message: string }; id?: number; method?: string; params?: unknown; result?: unknown }): void {\n logger.debug('QueryServer2 message:', message);\n\n // Handle responses\n if (message.id !== undefined && this.pendingRequests.has(Number(message.id))) {\n const pending = this.pendingRequests.get(Number(message.id))!;\n this.pendingRequests.delete(Number(message.id));\n\n if (message.error) {\n pending.reject(new Error(`Query server error: ${message.error.message}`));\n } else {\n pending.resolve(message.result);\n }\n return;\n }\n\n // Handle notifications (progress, etc.)\n if (message.method) {\n this.emit('notification', { method: message.method, params: message.params });\n }\n }\n\n private rejectAllPending(error: Error): void {\n for (const [id, pending] of this.pendingRequests) {\n pending.reject(error);\n this.pendingRequests.delete(id);\n }\n }\n\n private sendRaw(message: object): void {\n if (!this.process?.stdin) {\n throw new Error('Query server is not running');\n }\n\n const body = JSON.stringify(message);\n const contentLength = Buffer.byteLength(body, 'utf8');\n const frame = `Content-Length: ${contentLength}\\r\\n\\r\\n${body}`;\n this.process.stdin.write(frame);\n }\n}\n", "/**\n * CodeQL CLI Server client.\n *\n * Manages a long-lived `codeql execute cli-server` process that executes CLI\n * commands without repeated JVM startup overhead. Commands are serialized as\n * JSON arrays followed by a NUL byte, and responses are NUL-terminated JSON.\n *\n * Inspired by the `CodeQLCliServer` class in github/vscode-codeql.\n */\n\nimport { ChildProcess, spawn } from 'child_process';\nimport { delimiter } from 'path';\nimport { EventEmitter } from 'events';\nimport { clearTimeout, setTimeout } from 'timers';\nimport { buildCLIServerArgs, CLIServerConfig } from './server-config';\nimport { getResolvedCodeQLDir } from './cli-executor';\nimport { logger } from '../utils/logger';\nimport { waitForProcessReady } from '../utils/process-ready';\n\n/**\n * A queued command waiting to be sent to the CLI server.\n */\ninterface QueuedCommand {\n args: string[];\n reject: (_error: Error) => void;\n resolve: (_value: string) => void;\n}\n\n/**\n * Client for the CodeQL CLI Server process.\n *\n * The cli-server uses a simple NUL-delimited protocol:\n * - **Request**: JSON array of command arguments, followed by a NUL byte.\n * - **Response**: command stdout, terminated by a NUL byte on stdout.\n * stderr is forwarded as-is.\n */\nexport class CodeQLCLIServer extends EventEmitter {\n private commandInProgress = false;\n private commandQueue: Array<() => void> = [];\n private readonly config: CLIServerConfig;\n private currentReject: ((_error: Error) => void) | null = null;\n private currentResolve: ((_value: string) => void) | null = null;\n private nullBuffer = Buffer.alloc(1);\n private process: ChildProcess | null = null;\n private stdoutBuffer = '';\n\n constructor(config: CLIServerConfig) {\n super();\n this.config = config;\n }\n\n /**\n * Start the cli-server process.\n */\n async start(): Promise {\n if (this.process) {\n throw new Error('CLI server is already running');\n }\n\n logger.info('Starting CodeQL CLI Server...');\n\n const args = buildCLIServerArgs(this.config);\n\n const spawnEnv = { ...process.env };\n const codeqlDir = getResolvedCodeQLDir();\n if (codeqlDir && spawnEnv.PATH) {\n spawnEnv.PATH = `${codeqlDir}${delimiter}${spawnEnv.PATH}`;\n } else if (codeqlDir) {\n spawnEnv.PATH = codeqlDir;\n }\n\n this.process = spawn('codeql', args, {\n stdio: ['pipe', 'pipe', 'pipe'],\n env: spawnEnv,\n });\n\n this.process.stdout?.on('data', (data: Buffer) => {\n this.handleStdout(data);\n });\n\n this.process.stderr?.on('data', (data: Buffer) => {\n logger.debug('CLIServer stderr:', data.toString());\n });\n\n this.process.on('error', (error: Error) => {\n logger.error('CLI server process error:', error);\n if (this.currentReject) {\n this.currentReject(error);\n this.currentReject = null;\n this.currentResolve = null;\n }\n this.emit('error', error);\n });\n\n this.process.on('exit', (code: number | null) => {\n logger.info(`CLI server exited with code: ${code}`);\n if (this.currentReject) {\n this.currentReject(new Error(`CLI server exited unexpectedly with code: ${code}`));\n this.currentReject = null;\n this.currentResolve = null;\n }\n this.process = null;\n this.emit('exit', code);\n });\n\n // Wait for the JVM to initialise (resolves on first stderr/stdout output)\n await waitForProcessReady(this.process, 'CodeQL CLI Server');\n logger.info('CodeQL CLI Server started');\n }\n\n /**\n * Run a CodeQL CLI command through the persistent server.\n *\n * Commands are serialized and queued; only one command runs at a time.\n *\n * @param args - The full command arguments (e.g. `['resolve', 'qlpacks']`).\n * @returns The stdout output from the command.\n */\n runCommand(args: string[]): Promise {\n return new Promise((resolve, reject) => {\n const execute = () => {\n this.executeCommand({ args, reject, resolve });\n };\n\n if (this.commandInProgress) {\n this.commandQueue.push(execute);\n } else {\n execute();\n }\n });\n }\n\n /**\n * Gracefully shut down the CLI server.\n */\n async shutdown(): Promise {\n if (!this.process) {\n return;\n }\n\n logger.info('Shutting down CodeQL CLI Server...');\n\n try {\n // Send shutdown command\n this.process.stdin?.write(JSON.stringify(['shutdown']), 'utf8');\n this.process.stdin?.write(this.nullBuffer);\n } catch (error) {\n logger.warn('Error during CLI server shutdown request:', error);\n }\n\n // Give it a moment, then force kill\n await new Promise((resolve) => {\n const timer = setTimeout(() => {\n if (this.process) {\n this.process.kill('SIGTERM');\n this.process = null;\n }\n resolve();\n }, 2000);\n\n if (this.process) {\n this.process.once('exit', () => {\n clearTimeout(timer);\n this.process = null;\n resolve();\n });\n } else {\n clearTimeout(timer);\n resolve();\n }\n });\n\n this.commandInProgress = false;\n this.commandQueue = [];\n logger.info('CodeQL CLI Server stopped');\n }\n\n /**\n * Whether the CLI server process is running.\n */\n isRunning(): boolean {\n return this.process !== null && !this.process.killed;\n }\n\n // ---- private helpers ----\n\n private executeCommand(cmd: QueuedCommand): void {\n if (!this.process?.stdin) {\n cmd.reject(new Error('CLI server is not running'));\n return;\n }\n\n this.commandInProgress = true;\n this.currentResolve = cmd.resolve;\n this.currentReject = cmd.reject;\n\n try {\n this.process.stdin.write(JSON.stringify(cmd.args), 'utf8');\n this.process.stdin.write(this.nullBuffer);\n } catch (error) {\n this.commandInProgress = false;\n this.currentResolve = null;\n this.currentReject = null;\n cmd.reject(error instanceof Error ? error : new Error(String(error)));\n this.runNext();\n }\n }\n\n private handleStdout(data: Buffer): void {\n this.stdoutBuffer += data.toString();\n\n // Process all NUL-delimited responses in the buffer\n let nulIndex = this.stdoutBuffer.indexOf('\\0');\n while (nulIndex !== -1) {\n const result = this.stdoutBuffer.substring(0, nulIndex);\n this.stdoutBuffer = this.stdoutBuffer.substring(nulIndex + 1);\n\n if (this.currentResolve) {\n this.currentResolve(result);\n this.currentResolve = null;\n this.currentReject = null;\n }\n\n this.commandInProgress = false;\n this.runNext();\n\n nulIndex = this.stdoutBuffer.indexOf('\\0');\n }\n }\n\n private runNext(): void {\n const next = this.commandQueue.shift();\n if (next) {\n next();\n }\n }\n}\n", "/**\n * CodeQL Server Manager\n *\n * Manages the lifecycle of CodeQL background server processes:\n * - language-server (LSP-based QL validation)\n * - query-server2 (query evaluation)\n * - cli-server (JVM reuse for CLI commands)\n *\n * Servers are keyed by a hash of their configuration. When a caller requests\n * a server with a different configuration, the old server is shut down and a\n * new one is started. Session-specific cache directories provide isolation.\n */\n\nimport { mkdirSync } from 'fs';\nimport { join } from 'path';\nimport { randomUUID } from 'crypto';\nimport {\n CLIServerConfig,\n CodeQLServerType,\n computeConfigHash,\n LanguageServerConfig,\n QueryServerConfig,\n ServerConfig,\n} from './server-config';\nimport { CodeQLLanguageServer } from './language-server';\nimport { CodeQLQueryServer } from './query-server';\nimport { CodeQLCLIServer } from './cli-server';\nimport { getProjectTmpDir } from '../utils/temp-dir';\nimport { logger } from '../utils/logger';\n\n/**\n * Entry in the managed servers map.\n */\ninterface ManagedServer {\n configHash: string;\n server: CodeQLCLIServer | CodeQLLanguageServer | CodeQLQueryServer;\n sessionId: string;\n type: CodeQLServerType;\n}\n\n/**\n * Options for creating a session-specific cache layout.\n */\nexport interface SessionCacheOptions {\n /** Override the session ID (defaults to a random UUID). */\n sessionId?: string;\n}\n\n/**\n * Manages CodeQL background server processes with config-aware caching.\n *\n * Callers should use `getLanguageServer()`, `getQueryServer()`, or\n * `getCLIServer()` to obtain a running server. If the requested\n * configuration differs from the currently running server of that type, the\n * old server is stopped and replaced.\n */\nexport class CodeQLServerManager {\n /** Keyed by `CodeQLServerType` \u2014 at most one per type at a time. */\n private servers = new Map();\n\n /** In-flight `getOrRestart` promises, keyed by server type, to serialize concurrent calls. */\n private pendingStarts = new Map>();\n\n /** The session ID used for cache isolation. */\n private sessionId: string;\n\n /** Root directory for session-specific caches. */\n private sessionCacheDir: string;\n\n constructor(options?: SessionCacheOptions) {\n this.sessionId = options?.sessionId ?? randomUUID();\n this.sessionCacheDir = join(\n getProjectTmpDir('codeql-cache'),\n this.sessionId,\n );\n // Pre-create the cache directory tree\n for (const subdir of ['compilation-cache', 'logs', 'query-cache']) {\n mkdirSync(join(this.sessionCacheDir, subdir), { recursive: true });\n }\n logger.info(`CodeQLServerManager initialized (session: ${this.sessionId})`);\n }\n\n // ---- Public API ----\n\n /**\n * Get the current session ID.\n */\n getSessionId(): string {\n return this.sessionId;\n }\n\n /**\n * Get the session-specific cache directory.\n */\n getCacheDir(): string {\n return this.sessionCacheDir;\n }\n\n /**\n * Return the session-specific log directory.\n */\n getLogDir(): string {\n return join(this.sessionCacheDir, 'logs');\n }\n\n /**\n * Get or create a Language Server with the given configuration.\n *\n * If a language server is already running with the same config it is reused.\n * If the config has changed the old server is shut down first.\n */\n async getLanguageServer(config: LanguageServerConfig): Promise {\n const enriched = this.enrichConfig(config) as LanguageServerConfig;\n return this.getOrRestart('language', enriched, () => {\n // Convert LanguageServerConfig to the LanguageServerOptions the existing class expects\n return new CodeQLLanguageServer({\n loglevel: enriched.loglevel,\n logdir: enriched.logdir,\n searchPath: enriched.searchPath,\n synchronous: enriched.synchronous,\n verbosity: enriched.verbosity,\n });\n }) as Promise;\n }\n\n /**\n * Get or create a Query Server with the given configuration.\n */\n async getQueryServer(config: QueryServerConfig): Promise {\n const enriched = this.enrichConfig(config) as QueryServerConfig;\n return this.getOrRestart('query', enriched, () => {\n return new CodeQLQueryServer(enriched);\n }) as Promise;\n }\n\n /**\n * Get or create a CLI Server with the given configuration.\n */\n async getCLIServer(config: CLIServerConfig): Promise {\n const enriched = this.enrichConfig(config) as CLIServerConfig;\n return this.getOrRestart('cli', enriched, () => {\n return new CodeQLCLIServer(enriched);\n }) as Promise;\n }\n\n /**\n * Shut down a specific server type.\n */\n async shutdownServer(type: CodeQLServerType): Promise {\n const managed = this.servers.get(type);\n if (!managed) return;\n\n logger.info(`Shutting down ${type} server (session: ${managed.sessionId})`);\n await this.stopServer(managed);\n this.servers.delete(type);\n }\n\n /**\n * Shut down all managed servers.\n */\n async shutdownAll(): Promise {\n logger.info(`Shutting down all servers for session: ${this.sessionId}`);\n const shutdownPromises = Array.from(this.servers.entries()).map(\n async ([type, managed]) => {\n try {\n await this.stopServer(managed);\n } catch (error) {\n logger.error(`Error shutting down ${type} server:`, error);\n }\n },\n );\n await Promise.all(shutdownPromises);\n this.servers.clear();\n logger.info('All servers shut down');\n }\n\n /**\n * Check whether a server of the given type is currently running.\n */\n isRunning(type: CodeQLServerType): boolean {\n const managed = this.servers.get(type);\n if (!managed) return false;\n return managed.server.isRunning();\n }\n\n /**\n * Get status information for all managed servers.\n */\n getStatus(): Record {\n const status: Record = {\n cli: null,\n language: null,\n query: null,\n };\n for (const [type, managed] of this.servers) {\n status[type] = {\n configHash: managed.configHash,\n running: managed.server.isRunning(),\n sessionId: managed.sessionId,\n };\n }\n return status as Record;\n }\n\n // ---- Private helpers ----\n\n /**\n * Eagerly start the language server so the JVM is warm when the first\n * LSP tool call arrives. Uses the default configuration that\n * `lsp-handlers.ts` / `lsp-diagnostics.ts` would create on the first\n * `getLanguageServer()` call. The server is stored in the managed-servers\n * map and reused by subsequent tool invocations.\n *\n * This is fire-and-forget: errors are logged but do not prevent the MCP\n * server from starting.\n */\n async warmUpLanguageServer(): Promise {\n try {\n // Lazy-import to avoid circular dependency at module level\n const { packageRootDir } = await import('../utils/package-paths');\n const { resolve } = await import('path');\n\n const config: LanguageServerConfig = {\n checkErrors: 'ON_CHANGE',\n loglevel: 'WARN',\n searchPath: resolve(packageRootDir, 'ql'),\n };\n logger.info('Warming up language server (background JVM start)...');\n await this.getLanguageServer(config);\n logger.info('Language server warm-up complete');\n } catch (error) {\n logger.warn('Language server warm-up failed (will retry on first tool call):', error);\n }\n }\n\n /**\n * Eagerly start the CLI server so the JVM is warm when the first\n * `executeCodeQLCommand()` call routes through it.\n *\n * The CLI server uses only session-scoped `commonCaches` and `logdir`,\n * both injected by `enrichConfig()`. Passing an empty config is\n * intentional \u2014 it matches what `executeCodeQLCommand()` will request.\n *\n * Fire-and-forget: errors are logged but do not block startup.\n */\n async warmUpCLIServer(): Promise {\n try {\n logger.info('Warming up CLI server (background JVM start)...');\n await this.getCLIServer({});\n logger.info('CLI server warm-up complete');\n } catch (error) {\n logger.warn('CLI server warm-up failed (will retry on first tool call):', error);\n }\n }\n\n /**\n * Enrich a config with session-specific defaults for commonCaches and logdir.\n */\n private enrichConfig(config: T): T {\n return {\n ...config,\n commonCaches: config.commonCaches ?? this.sessionCacheDir,\n logdir: config.logdir ?? this.getLogDir(),\n };\n }\n\n /**\n * Get an existing server if its config matches, otherwise stop the old\n * one and start a new server.\n *\n * Concurrent calls for the same server type are serialized via\n * `pendingStarts` to avoid spawning duplicate server processes.\n */\n private async getOrRestart(\n type: CodeQLServerType,\n config: ServerConfig,\n factory: () => CodeQLCLIServer | CodeQLLanguageServer | CodeQLQueryServer,\n ): Promise {\n // If another call is already starting a server of this type, wait for it\n // to settle (success or failure) and then re-check whether the result is\n // still usable.\n const inflight = this.pendingStarts.get(type);\n if (inflight) {\n try { await inflight; } catch { /* swallow \u2014 original caller handles the rejection */ }\n }\n\n const work = this.doGetOrRestart(type, config, factory);\n this.pendingStarts.set(type, work);\n try {\n return await work;\n } finally {\n // Ensure `work` has settled before removing the pendingStarts entry so\n // that concurrent callers waiting on the same promise see a consistent\n // map state. The try/catch avoids re-throwing a rejection that the\n // outer `try` block already handles.\n try { await work; } catch { /* already handled */ }\n if (this.pendingStarts.get(type) === work) {\n this.pendingStarts.delete(type);\n }\n }\n }\n\n /**\n * Core logic for getOrRestart, separated to allow serialization.\n */\n private async doGetOrRestart(\n type: CodeQLServerType,\n config: ServerConfig,\n factory: () => CodeQLCLIServer | CodeQLLanguageServer | CodeQLQueryServer,\n ): Promise {\n const hash = computeConfigHash(type, config);\n const existing = this.servers.get(type);\n\n // Reuse if config matches and server is still running\n if (existing && existing.configHash === hash && existing.server.isRunning()) {\n logger.debug(`Reusing existing ${type} server (hash: ${hash.substring(0, 8)})`);\n return existing.server;\n }\n\n // Config changed or server died \u2014 stop the old one\n if (existing) {\n logger.info(`${type} server config changed or dead, restarting...`);\n await this.stopServer(existing);\n this.servers.delete(type);\n }\n\n // Start a new server\n const server = factory();\n await server.start();\n\n this.servers.set(type, {\n configHash: hash,\n server,\n sessionId: this.sessionId,\n type,\n });\n\n logger.info(`${type} server started (hash: ${hash.substring(0, 8)})`);\n return server;\n }\n\n /**\n * Stop a managed server, ignoring errors.\n */\n private async stopServer(managed: ManagedServer): Promise {\n try {\n await managed.server.shutdown();\n } catch (error) {\n logger.warn(`Error stopping ${managed.type} server:`, error);\n // Best-effort \u2014 don't propagate\n }\n }\n}\n\n/**\n * Global server manager singleton.\n *\n * Initialized lazily by `getServerManager()`. The MCP server entry point\n * should call `initServerManager()` at startup and `shutdownServerManager()`\n * at graceful shutdown.\n */\nlet globalServerManager: CodeQLServerManager | null = null;\n\n/**\n * Initialize the global server manager (idempotent).\n */\nexport function initServerManager(options?: SessionCacheOptions): CodeQLServerManager {\n if (!globalServerManager) {\n globalServerManager = new CodeQLServerManager(options);\n }\n return globalServerManager;\n}\n\n/**\n * Get the global server manager, creating it if needed.\n */\nexport function getServerManager(): CodeQLServerManager {\n if (!globalServerManager) {\n globalServerManager = new CodeQLServerManager();\n }\n return globalServerManager;\n}\n\n/**\n * Shut down the global server manager and all its servers.\n */\nexport async function shutdownServerManager(): Promise {\n if (globalServerManager) {\n await globalServerManager.shutdownAll();\n globalServerManager = null;\n }\n}\n\n/**\n * Reset the global server manager (for testing only).\n */\nexport function resetServerManager(): void {\n globalServerManager = null;\n}\n", "/**\n * Generic CLI command execution utilities for CodeQL and QLT commands\n */\n\nimport { execFile } from 'child_process';\nimport { existsSync } from 'fs';\nimport { basename, delimiter, dirname, isAbsolute } from 'path';\nimport { promisify } from 'util';\nimport { logger } from '../utils/logger';\n\nconst execFileAsync = promisify(execFile);\n\nexport interface CLIExecutionResult {\n stdout: string;\n stderr: string;\n success: boolean;\n error?: string;\n exitCode?: number;\n}\n\nexport interface CLIExecutionOptions {\n command: string;\n args: string[];\n cwd?: string;\n timeout?: number;\n env?: Record;\n}\n\n// Whitelist of allowed commands to prevent arbitrary command execution\nconst ALLOWED_COMMANDS = new Set([\n 'codeql',\n 'git',\n 'node',\n 'npm',\n 'qlt',\n 'which'\n]);\n\n// Additional commands allowed in test environments\nlet testCommands: Set | null = null;\n\n// Whitelist of safe environment variables to pass to child processes\n// This prevents potentially malicious environment variables from being passed through\nconst SAFE_ENV_VARS = [\n 'HOME', // User home directory\n 'LANG', // Locale setting\n 'LC_ALL', // Locale setting\n 'LC_CTYPE', // Locale setting\n 'PATH', // Required to find executables\n 'SHELL', // User's shell (Unix)\n 'TEMP', // Temporary directory (Windows)\n 'TERM', // Terminal type (Unix)\n 'TMP', // Temporary directory (Windows)\n 'TMPDIR', // Temporary directory (Unix)\n 'USER', // Current user (Unix)\n 'USERNAME', // Current user (Windows)\n] as const;\n\n// Whitelist of safe environment variable prefixes\n// These are needed for CodeQL and Node.js functionality\nconst SAFE_ENV_PREFIXES = [\n 'CODEQL_', // CodeQL-specific variables\n 'NODE_', // Node.js-specific variables (for npm, etc.)\n] as const;\n\n// Pattern for dangerous control characters in CLI arguments\n// Rejected characters:\n// \\x01-\\x08: SOH through BS (start of heading, text, null control chars, backspace)\n// \\x0B: Vertical tab - rarely used legitimately, can cause display issues\n// \\x0C: Form feed - can cause unexpected page breaks in output\n// \\x0E-\\x1F: SO through US (shift out/in, device controls, separators)\n// Allowed characters:\n// \\x00: Null byte - handled separately for clearer error messaging\n// \\x09: Horizontal tab - commonly used in file paths and arguments\n// \\x0A: Newline (LF) - may appear in multi-line arguments\n// \\x0D: Carriage return (CR) - may appear with newlines on Windows\n// eslint-disable-next-line no-control-regex\nconst DANGEROUS_CONTROL_CHARS = /[\\x01-\\x08\\x0B\\x0C\\x0E-\\x1F]/;\n\n/**\n * Enable test-specific commands for testing purposes\n * This should only be called in test environments\n */\nexport function enableTestCommands(): void {\n testCommands = new Set([\n 'cat',\n 'echo',\n 'ls',\n 'sh',\n 'sleep'\n ]);\n}\n\n/**\n * Disable test-specific commands\n */\nexport function disableTestCommands(): void {\n testCommands = null;\n}\n\n/**\n * Check if a command is allowed\n */\nfunction isCommandAllowed(command: string): boolean {\n return ALLOWED_COMMANDS.has(command) || (testCommands !== null && testCommands.has(command));\n}\n\n// Resolved CodeQL binary directory from CODEQL_PATH.\n// When set, this directory is prepended to PATH for all child processes\n// so that `execFile('codeql', ...)` finds the correct binary via execvp().\n// Using PATH lookup (rather than an absolute path) is essential because\n// execvp() handles shell-script shebangs correctly, whereas passing an\n// absolute path to execFile() can fail with ENOENT for shell scripts.\nlet resolvedCodeQLDir: string | null = null;\n\n// Cached result from resolveCodeQLBinary(). `undefined` means not yet resolved.\nlet resolvedBinaryResult: string | undefined;\n\n/**\n * Resolve the CodeQL CLI binary path.\n *\n * Resolution order:\n * 1. `CODEQL_PATH` environment variable \u2014 must point to an existing file whose\n * basename is `codeql` (or `codeql.exe` / `codeql.cmd` on Windows).\n * The parent directory is prepended to PATH for child processes.\n * 2. Falls back to the bare `codeql` command (resolved via PATH at exec time).\n *\n * The resolved value is cached for the lifetime of the process. Call this once\n * at startup; subsequent calls are a no-op and return the cached value.\n */\nexport function resolveCodeQLBinary(): string {\n // Short-circuit if already resolved\n if (resolvedBinaryResult !== undefined) {\n return resolvedBinaryResult;\n }\n\n const envPath = process.env.CODEQL_PATH;\n\n if (!envPath) {\n resolvedCodeQLDir = null;\n resolvedBinaryResult = 'codeql';\n return resolvedBinaryResult;\n }\n\n // Validate the path points to a plausible CodeQL binary\n const base = basename(envPath).toLowerCase();\n const validBaseNames = ['codeql', 'codeql.exe', 'codeql.cmd'];\n if (!validBaseNames.includes(base)) {\n throw new Error(\n `CODEQL_PATH must point to a CodeQL CLI binary (expected basename: codeql), got: ${base}`\n );\n }\n\n // Require an absolute path to avoid ambiguity\n if (!isAbsolute(envPath)) {\n throw new Error(\n `CODEQL_PATH must be an absolute path, got: ${envPath}`\n );\n }\n\n // Verify the file exists\n if (!existsSync(envPath)) {\n throw new Error(\n `CODEQL_PATH points to a file that does not exist: ${envPath}`\n );\n }\n\n resolvedCodeQLDir = dirname(envPath);\n resolvedBinaryResult = 'codeql';\n logger.info(`CodeQL CLI resolved via CODEQL_PATH: ${envPath} (dir: ${resolvedCodeQLDir})`);\n return resolvedBinaryResult;\n}\n\n/**\n * Get the currently resolved CodeQL binary directory, or null if using PATH.\n */\nexport function getResolvedCodeQLDir(): string | null {\n return resolvedCodeQLDir;\n}\n\n/**\n * Reset the resolved CodeQL binary to the default (for testing only).\n */\nexport function resetResolvedCodeQLBinary(): void {\n resolvedCodeQLDir = null;\n resolvedBinaryResult = undefined;\n}\n\n/**\n * Validate that the resolved CodeQL binary is actually callable.\n *\n * Runs `codeql version --format=terse` and verifies the process exits\n * successfully. This catches the case where `CODEQL_PATH` is unset and\n * `codeql` is not on PATH \u2014 the server would otherwise start normally\n * but every tool invocation would fail.\n *\n * @returns The version string reported by the CodeQL CLI.\n * @throws Error if the binary is not reachable or returns a non-zero exit code.\n */\nexport async function validateCodeQLBinaryReachable(): Promise {\n const binary = resolvedBinaryResult ?? 'codeql';\n const env = { ...process.env };\n if (resolvedCodeQLDir) {\n env.PATH = resolvedCodeQLDir + delimiter + (env.PATH || '');\n }\n\n try {\n const { stdout } = await execFileAsync(binary, ['version', '--format=terse'], {\n env,\n timeout: 15_000,\n });\n return stdout.trim();\n } catch (err: unknown) {\n const message = err instanceof Error ? err.message : String(err);\n throw new Error(\n `CodeQL CLI is not reachable (binary: ${binary}). ` +\n `Ensure codeql is on PATH or set the CODEQL_PATH environment variable ` +\n `to the absolute path of the CodeQL CLI binary. Details: ${message}`\n );\n }\n}\n\n/**\n * Sanitize a CLI argument to prevent potential issues with special characters.\n * \n * While execFile() does not spawn a shell (preventing shell injection), we still\n * validate arguments to:\n * 1. Reject null bytes that could truncate strings in C-based commands\n * 2. Reject control characters that could cause unexpected behavior\n * 3. Provide defense-in-depth against potential issues\n * \n * @param arg - The argument to sanitize\n * @returns The sanitized argument\n * @throws Error if the argument contains dangerous characters\n */\nexport function sanitizeCLIArgument(arg: string): string {\n // Reject null bytes - these can truncate strings in C-based commands\n // Error message intentionally excludes argument content to avoid logging potentially sensitive data\n if (arg.includes('\\0')) {\n throw new Error(`CLI argument contains null byte: argument rejected for security`);\n }\n \n // Reject control characters using the module-level constant pattern\n if (DANGEROUS_CONTROL_CHARS.test(arg)) {\n // Error message intentionally excludes argument content to avoid logging potentially sensitive data\n throw new Error(`CLI argument contains control characters: argument rejected for security`);\n }\n \n return arg;\n}\n\n/**\n * Sanitize an array of CLI arguments\n * @param args - The arguments to sanitize\n * @returns The sanitized arguments\n * @throws Error if any argument contains dangerous characters\n */\nexport function sanitizeCLIArguments(args: string[]): string[] {\n return args.map(sanitizeCLIArgument);\n}\n\n/**\n * Filter environment variables to only include safe ones\n * This prevents potentially malicious environment variables from being passed to child processes\n */\nfunction getSafeEnvironment(additionalEnv?: Record): Record {\n const safeEnv: Record = {};\n \n // Copy whitelisted environment variables from process.env\n for (const key of SAFE_ENV_VARS) {\n if (process.env[key] !== undefined) {\n safeEnv[key] = process.env[key]!;\n }\n }\n \n // Copy environment variables with whitelisted prefixes\n for (const [key, value] of Object.entries(process.env)) {\n if (value !== undefined && SAFE_ENV_PREFIXES.some(prefix => key.startsWith(prefix))) {\n safeEnv[key] = value;\n }\n }\n \n // When CODEQL_PATH was set, prepend the resolved directory to PATH so that\n // `execFile('codeql', ...)` finds the user-specified binary via execvp().\n // This approach (PATH manipulation + bare command name) is essential because\n // execvp() handles shell-script shebangs correctly, whereas passing an\n // absolute path to execFile() fails with ENOENT for shell-script launchers.\n if (resolvedCodeQLDir && safeEnv.PATH) {\n safeEnv.PATH = `${resolvedCodeQLDir}${delimiter}${safeEnv.PATH}`;\n } else if (resolvedCodeQLDir) {\n safeEnv.PATH = resolvedCodeQLDir;\n }\n \n // Merge with explicitly provided environment variables\n // These are trusted as they come from the application code, not external sources\n if (additionalEnv) {\n Object.assign(safeEnv, additionalEnv);\n }\n \n return safeEnv;\n}\n\n/**\n * Execute a CLI command and return the result.\n * \n * Security: This function uses execFile() instead of exec() to avoid shell interpretation.\n * Arguments are passed directly to the executable as an array, preventing shell injection.\n * Additional security measures include:\n * - Command whitelist validation\n * - Shell metacharacter detection in command names\n * - CLI argument sanitization (null bytes, control characters)\n * - Environment variable filtering\n */\nexport async function executeCLICommand(options: CLIExecutionOptions): Promise {\n try {\n const { command, args, cwd, timeout = 300000, env } = options; // 5 minute default timeout\n \n // Validate command is in the whitelist to prevent arbitrary command execution\n if (!isCommandAllowed(command)) {\n throw new Error(`Command not allowed: ${command}. Only whitelisted commands can be executed.`);\n }\n \n // Validate command to ensure it doesn't contain shell metacharacters\n if (command.includes(';') || command.includes('|') || command.includes('&') || \n command.includes('$') || command.includes('`') || command.includes('\\n') ||\n command.includes('\\r')) {\n throw new Error(`Invalid command: contains shell metacharacters: ${command}`);\n }\n \n // Sanitize CLI arguments to prevent issues with special characters\n // This provides defense-in-depth even though execFile() doesn't use a shell\n const sanitizedArgs = sanitizeCLIArguments(args);\n \n logger.info(`Executing CLI command: ${command}`, { args: sanitizedArgs, cwd, timeout });\n \n const execOptions = {\n cwd,\n timeout,\n env: getSafeEnvironment(env),\n };\n \n // execFile() is used instead of exec() to avoid shell interpretation\n // Arguments are passed as an array, not interpolated into a command string\n const { stdout, stderr } = await execFileAsync(command, sanitizedArgs, execOptions);\n\n return {\n stdout,\n stderr,\n success: true,\n exitCode: 0\n };\n\n } catch (error: unknown) {\n logger.error('CLI command execution failed:', error);\n \n const err = error as Error & { code?: number; stdout?: string; stderr?: string };\n const errorMessage = err instanceof Error ? err.message : String(error);\n const exitCode = err.code || 1;\n \n return {\n stdout: err.stdout || '',\n stderr: err.stderr || errorMessage,\n success: false,\n error: errorMessage,\n exitCode\n };\n }\n}\n\n/**\n * Build CodeQL command arguments with proper escaping\n */\nexport function buildCodeQLArgs(subcommand: string, options: Record): string[] {\n const args = [subcommand];\n \n // Single-letter parameters that should use -key=value format (with equals sign)\n // Note: CodeQL CLI uses -t=key=value format for metadata, not -t key=value\n const singleLetterParams = new Set(['t', 'o', 'v', 'q', 'h', 'J']);\n \n for (const [key, value] of Object.entries(options)) {\n if (value === undefined || value === null) {\n continue;\n }\n \n const isSingleLetter = key.length === 1 && singleLetterParams.has(key);\n \n if (typeof value === 'boolean') {\n if (value) {\n args.push(isSingleLetter ? `-${key}` : `--${key}`);\n }\n } else if (Array.isArray(value)) {\n // Handle array values (e.g., multiple -t flags for metadata)\n for (const item of value) {\n if (isSingleLetter) {\n // For single-letter params like -t, use -key=value format\n args.push(`-${key}=${String(item)}`);\n } else {\n // For long params, use --key=value format\n args.push(`--${key}=${String(item)}`);\n }\n }\n } else {\n // Handle string, number, and other values\n if (isSingleLetter) {\n // For single-letter params, use -key=value format\n args.push(`-${key}=${String(value)}`);\n } else {\n args.push(`--${key}=${String(value)}`);\n }\n }\n }\n \n return args;\n}\n\n/**\n * Build QLT command arguments with proper escaping\n */\nexport function buildQLTArgs(subcommand: string, options: Record): string[] {\n const args = [subcommand];\n \n for (const [key, value] of Object.entries(options)) {\n if (value === undefined || value === null) {\n continue;\n }\n \n if (typeof value === 'boolean') {\n if (value) {\n args.push(`--${key}`);\n }\n } else if (Array.isArray(value)) {\n // Handle array values\n for (const item of value) {\n args.push(`--${key}`, String(item));\n }\n } else {\n // Handle string, number, and other values\n args.push(`--${key}`, String(value));\n }\n }\n \n return args;\n}\n\n/**\n * CodeQL subcommands that MUST run as fresh processes.\n *\n * These cannot use the cli-server because they:\n * - Spawn extractors or other long-running child processes (database create, test extract)\n * - Produce multi-event NUL-delimited streams (test run)\n * - Are compound orchestration commands (database analyze)\n *\n * Everything else is routed through the persistent cli-server JVM for\n * sub-second execution instead of 2-5 s JVM cold-start per invocation.\n */\nconst FRESH_PROCESS_SUBCOMMANDS = new Set([\n 'database analyze',\n 'database create',\n 'test extract',\n 'test run',\n]);\n\n/**\n * Execute a CodeQL command.\n *\n * By default, commands are routed through the persistent `codeql execute\n * cli-server` process managed by {@link CodeQLServerManager}, eliminating\n * repeated JVM startup overhead (~2-5 s savings per call).\n *\n * Commands listed in {@link FRESH_PROCESS_SUBCOMMANDS} (e.g. `database create`,\n * `test run`) are always executed as fresh processes because they either spawn\n * child extractors, produce streaming output, or require a dedicated working\n * directory.\n *\n * If the cli-server is not available (e.g. during early startup before\n * `initServerManager()` is called), the function falls back transparently to\n * a fresh process.\n */\nexport async function executeCodeQLCommand(\n subcommand: string,\n options: Record,\n additionalArgs: string[] = [],\n cwd?: string\n): Promise {\n const args = buildCodeQLArgs(subcommand, options);\n args.push(...additionalArgs);\n\n // Determine whether this subcommand can use the persistent cli-server.\n // Commands that need a specific CWD also must use a fresh process because\n // the cli-server's CWD is fixed at startup.\n const canUseCLIServer = !FRESH_PROCESS_SUBCOMMANDS.has(subcommand) && !cwd;\n\n if (canUseCLIServer) {\n try {\n // Lazy-import to avoid circular dependency at module level.\n // Use getServerManager() (not initServerManager()) \u2014 if the manager\n // hasn't been initialized yet (e.g. during tests or early startup),\n // this creates one, but we only attempt to *use* the cli-server if\n // it is already running (warmed up at MCP server startup). We never\n // block on starting a new cli-server here \u2014 that would add JVM\n // startup latency to the first fresh-process-fallback call.\n const { getServerManager } = await import('./server-manager');\n const manager = getServerManager();\n\n if (manager.isRunning('cli')) {\n const cliServer = await manager.getCLIServer({});\n const sanitizedArgs = sanitizeCLIArguments(args);\n\n logger.info(`Executing CodeQL command via cli-server: ${subcommand}`, { args: sanitizedArgs });\n\n const stdout = await cliServer.runCommand(sanitizedArgs);\n\n return {\n stdout,\n stderr: '',\n success: true,\n exitCode: 0,\n };\n } else {\n logger.debug(`cli-server not yet running for \"${subcommand}\", using fresh process`);\n }\n } catch (error) {\n // If the cli-server call fails, check whether it's a command-level\n // error (the CLI returned non-zero) or a transport/startup error.\n // For transport errors we fall back to a fresh process; for command\n // errors we return the failure directly.\n const message = error instanceof Error ? error.message : String(error);\n\n // Transport-level errors that warrant a fallback:\n if (message.includes('CLI server is not running') ||\n message.includes('CLI server exited') ||\n message.includes('failed to start')) {\n logger.warn(`cli-server unavailable for \"${subcommand}\", falling back to fresh process: ${message}`);\n // Fall through to fresh-process execution below\n } else {\n // Command-level error \u2014 return it as a failed result\n logger.error(`cli-server command failed for \"${subcommand}\": ${message}`);\n return {\n stdout: '',\n stderr: message,\n success: false,\n error: message,\n exitCode: 1,\n };\n }\n }\n }\n\n // Fresh-process execution (for FRESH_PROCESS_SUBCOMMANDS, CWD-specific\n // calls, or as a fallback when the cli-server is unavailable).\n // Use 0 (no timeout) because CodeQL operations such as query evaluation,\n // database analysis, profiling, and test runs are inherently long-running\n // and should not be killed by a process timeout.\n return executeCLICommand({\n command: 'codeql',\n args,\n cwd,\n timeout: 0\n });\n}\n\n/**\n * Execute a QLT command\n */\nexport async function executeQLTCommand(\n subcommand: string, \n options: Record, \n additionalArgs: string[] = []\n): Promise {\n const args = buildQLTArgs(subcommand, options);\n args.push(...additionalArgs);\n \n return executeCLICommand({\n command: 'qlt',\n args\n });\n}\n\n/**\n * Get help text for a CLI command\n */\nexport async function getCommandHelp(command: string, subcommand?: string): Promise {\n const args = subcommand ? [subcommand, '--help'] : ['--help'];\n \n const result = await executeCLICommand({\n command,\n args\n });\n \n return result.stdout || result.stderr || 'No help available';\n}\n\n/**\n * Validate that a command exists on the system.\n */\nexport async function validateCommandExists(command: string): Promise {\n try {\n const result = await executeCLICommand({\n command: 'which',\n args: [command]\n });\n return result.success;\n } catch {\n return false;\n }\n}", "/**\n * CodeQL Development MCP McpServer\n * Main entry point for the server\n */\n\nimport { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';\nimport { StreamableHTTPServerTransport } from '@modelcontextprotocol/sdk/server/streamableHttp.js';\nimport express from 'express';\nimport cors from 'cors';\nimport dotenv from 'dotenv';\nimport { realpathSync } from 'fs';\nimport { resolve } from 'path';\nimport { pathToFileURL } from 'url';\nimport { registerCodeQLTools, registerCodeQLResources } from './tools';\nimport { registerLSPTools } from './tools/lsp';\nimport { registerLanguageResources } from './resources/language-resources';\nimport { registerWorkflowPrompts } from './prompts/workflow-prompts';\nimport { registerMonitoringTools } from './tools/monitoring-tools';\nimport { sessionDataManager } from './lib/session-data-manager';\nimport { resolveCodeQLBinary, validateCodeQLBinaryReachable } from './lib/cli-executor';\nimport { initServerManager, shutdownServerManager } from './lib/server-manager';\nimport { packageRootDir } from './utils/package-paths';\nimport { logger } from './utils/logger';\n\n// Load environment variables from a .env file co-located with the package root.\n// Uses the package directory (not CWD) so that npm-installed users don't\n// accidentally inherit a .env from their project.\n// Set DOTENV_CONFIG_QUIET to suppress the dotenv banner that would otherwise\n// leak to stdout and corrupt the MCP stdio JSON-RPC channel.\ndotenv.config({ path: resolve(packageRootDir, '.env'), quiet: true });\n\nconst PACKAGE_NAME = 'codeql-development-mcp-server';\nconst VERSION = '2.24.1';\n\n/**\n * Start the MCP server\n */\nexport async function startServer(mode: 'stdio' | 'http' = 'stdio'): Promise {\n logger.info(`Starting CodeQL Development MCP McpServer v${VERSION} in ${mode} mode`);\n\n // Resolve the CodeQL CLI binary path (honors CODEQL_PATH env var).\n // This must happen before any tool registration so that all CodeQL commands\n // use the user-specified binary.\n const codeqlBinary = resolveCodeQLBinary();\n logger.info(`CodeQL CLI binary: ${codeqlBinary}`);\n\n // Validate that the resolved binary is actually callable. This catches\n // misconfigurations early (e.g. codeql not on PATH and CODEQL_PATH unset)\n // instead of failing silently and producing confusing tool-level errors.\n const codeqlVersion = await validateCodeQLBinaryReachable();\n logger.info(`CodeQL CLI version: ${codeqlVersion}`);\n\n const server = new McpServer({\n name: PACKAGE_NAME,\n version: VERSION,\n });\n\n // Register CodeQL tools (legacy high-level helpers)\n registerCodeQLTools(server);\n\n // Register LSP-based tools (diagnostics, completion, definition, references)\n registerLSPTools(server);\n\n // Register CodeQL resources (static guides)\n registerCodeQLResources(server);\n\n // Register language-specific resources (AST references, security patterns)\n registerLanguageResources(server);\n\n // Register high-level workflow prompts (complete development workflows)\n registerWorkflowPrompts(server);\n\n // Register monitoring and reporting tools\n registerMonitoringTools(server);\n\n // Initialize session data manager\n await sessionDataManager.initialize();\n\n // Initialize the CodeQL background server manager and eagerly start the\n // language server and CLI server JVMs so they are warm when the first tool\n // calls arrive. This avoids 2-60 s cold-start penalties per JVM.\n const manager = initServerManager();\n Promise.all([\n manager.warmUpLanguageServer(),\n manager.warmUpCLIServer(),\n ]).catch(() => { /* individual errors logged inside each warm-up method */ });\n\n if (mode === 'stdio') {\n const transport = new StdioServerTransport();\n await server.connect(transport);\n logger.info('McpServer started successfully on STDIO transport');\n } else {\n // HTTP mode\n const app = express();\n app.use(cors());\n app.use(express.json());\n\n const transport = new StreamableHTTPServerTransport({\n sessionIdGenerator: () => Math.random().toString(36).substring(7),\n });\n await server.connect(transport);\n\n app.all('/mcp', (req, res) => {\n transport.handleRequest(req, res, req.body).catch((err) => {\n logger.error('Error handling MCP request:', err);\n if (!res.headersSent) {\n res.status(500).json({ error: 'Internal McpServer Error' });\n }\n });\n });\n\n app.get('/', (_req, res) => {\n res.json({\n name: PACKAGE_NAME,\n version: VERSION,\n description: 'CodeQL Development MCP McpServer',\n status: 'running',\n });\n });\n\n const host = process.env.HTTP_HOST || 'localhost';\n const port = Number(process.env.HTTP_PORT || process.env.PORT) || 3000;\n \n // Return a promise that keeps the process alive\n return new Promise((resolve, reject) => {\n const httpServer = app.listen(port, host, () => {\n logger.info(`HTTP server listening on http://${host}:${port}/mcp`);\n resolve();\n });\n \n httpServer.on('error', (error) => {\n logger.error('HTTP server error:', error);\n reject(error);\n });\n });\n }\n\n setupGracefulShutdown(server);\n return server;\n}\n\n/**\n * Set up graceful shutdown handling\n */\nfunction setupGracefulShutdown(server: McpServer): void {\n const shutdown = async () => {\n logger.info('Shutting down server...');\n try {\n // Shut down all CodeQL background servers first\n await shutdownServerManager();\n await server.close();\n logger.info('McpServer closed gracefully');\n process.exit(0);\n } catch (error) {\n logger.error('Error during shutdown:', error);\n process.exit(1);\n }\n };\n\n process.on('SIGINT', shutdown);\n process.on('SIGTERM', shutdown);\n}\n\n/**\n * Main function to start the server\n */\nasync function main(): Promise {\n try {\n const transportMode = (process.env.TRANSPORT_MODE || 'stdio').toLowerCase();\n const mode: 'stdio' | 'http' = transportMode === 'http' ? 'http' : 'stdio';\n await startServer(mode);\n } catch (error) {\n logger.error('Failed to start server:', error);\n process.exit(1);\n }\n}\n\n// Start the server if this file is run directly.\n// Use realpathSync to resolve npm/npx symlinks so the guard works for both\n// direct invocation and globally-installed npm bin entries.\nconst scriptPath = process.argv[1] ? realpathSync(resolve(process.argv[1])) : undefined;\nif (scriptPath && import.meta.url === pathToFileURL(scriptPath).href) {\n main();\n}\n", "/**\n * CodeQL BQRS decode tool\n */\n\nimport { z } from 'zod';\nimport { CLIToolDefinition, createCodeQLSchemas, createBQRSResultProcessor } from '../../lib/cli-tool-registry';\n\nexport const codeqlBqrsDecodeTool: CLIToolDefinition = {\n name: 'codeql_bqrs_decode',\n description: 'Decode BQRS result files to human-readable formats',\n command: 'codeql',\n subcommand: 'bqrs decode',\n inputSchema: {\n files: z.array(z.string()).describe('BQRS file(s) to decode'),\n output: createCodeQLSchemas.output(),\n format: z.enum(['csv', 'json']).optional().describe('Output format'),\n 'max-paths': z.number().optional().describe('Maximum number of paths to output'),\n 'start-at': z.number().optional().describe('Start output at result number'),\n 'max-results': z.number().optional().describe('Maximum number of results'),\n verbose: createCodeQLSchemas.verbose(),\n additionalArgs: createCodeQLSchemas.additionalArgs()\n },\n examples: [\n 'codeql bqrs decode --format=csv --output=results.csv results.bqrs',\n 'codeql bqrs decode --format=json --max-results=100 results.bqrs'\n ],\n resultProcessor: createBQRSResultProcessor()\n};", "/**\n * Generic tool registry for creating MCP tools from CLI command definitions\n */\n\nimport { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport { z } from 'zod';\nimport { executeCodeQLCommand, executeQLTCommand, CLIExecutionResult } from './cli-executor';\nimport { logger } from '../utils/logger';\nimport { evaluateQueryResults, QueryEvaluationResult, extractQueryMetadata } from './query-results-evaluator';\nimport { getOrCreateLogDirectory } from './log-directory-manager';\nimport { getUserWorkspaceDir, packageRootDir, resolveToolQueryPackPath } from '../utils/package-paths';\nimport { writeFileSync, rmSync, existsSync, mkdirSync } from 'fs';\nimport { basename, dirname, isAbsolute, join, resolve } from 'path';\nimport { createProjectTempDir } from '../utils/temp-dir';\n\nexport type { CLIExecutionResult } from './cli-executor';\n\nexport interface CLIToolDefinition {\n name: string;\n description: string;\n command: 'codeql' | 'qlt';\n subcommand: string;\n inputSchema: Record;\n examples?: string[];\n resultProcessor?: (_result: CLIExecutionResult, _params: Record) => string;\n}\n\n/**\n * Default result processor that formats CLI output appropriately\n */\nexport const defaultCLIResultProcessor = (\n result: CLIExecutionResult, \n _params: Record\n): string => {\n if (!result.success) {\n return `Command failed (exit code ${result.exitCode || 'unknown'}):\\n${result.error || result.stderr}`;\n }\n \n let output = '';\n \n if (result.stdout) {\n output += result.stdout;\n }\n \n if (result.stderr) {\n if (output) {\n output += '\\n\\nWarnings/Info:\\n';\n }\n output += result.stderr;\n }\n \n if (!output) {\n output = 'Command executed successfully (no output)';\n }\n \n return output;\n};\n\n/**\n * Register a CLI tool with the MCP server\n */\nexport function registerCLITool(server: McpServer, definition: CLIToolDefinition): void {\n const {\n name,\n description,\n command,\n subcommand,\n inputSchema,\n resultProcessor = defaultCLIResultProcessor\n } = definition;\n\n server.tool(\n name,\n description,\n inputSchema,\n async (params: Record) => {\n // Track temporary directories for cleanup\n const tempDirsToCleanup: string[] = [];\n \n try {\n logger.info(`Executing CLI tool: ${name}`, { command, subcommand, params });\n\n // Separate positional arguments from named options\n // Extract tool-specific parameters that should not be passed to CLI\n // Note: format is extracted for tools that use it internally but not on CLI\n // For codeql_bqrs_interpret, codeql_bqrs_decode, codeql_generate_query-help, and codeql_database_analyze, format should be passed to CLI\n const formatShouldBePassedToCLI = name === 'codeql_bqrs_interpret' || name === 'codeql_bqrs_decode' || name === 'codeql_generate_query-help' || name === 'codeql_database_analyze';\n \n const extractedParams = formatShouldBePassedToCLI\n ? {\n _positional: params._positional || [],\n files: params.files,\n file: params.file,\n dir: params.dir,\n packDir: params.packDir,\n tests: params.tests,\n query: params.query,\n queryName: params.queryName,\n queryLanguage: params.queryLanguage,\n queryPack: params.queryPack,\n sourceFiles: params.sourceFiles,\n sourceFunction: params.sourceFunction,\n targetFunction: params.targetFunction,\n interpretedOutput: params.interpretedOutput,\n evaluationFunction: params.evaluationFunction,\n evaluationOutput: params.evaluationOutput,\n directory: params.directory,\n logDir: params.logDir,\n qlref: params.qlref\n }\n : {\n _positional: params._positional || [],\n files: params.files,\n file: params.file,\n dir: params.dir,\n packDir: params.packDir,\n tests: params.tests,\n query: params.query,\n queryName: params.queryName,\n queryLanguage: params.queryLanguage,\n queryPack: params.queryPack, \n sourceFiles: params.sourceFiles,\n sourceFunction: params.sourceFunction,\n targetFunction: params.targetFunction,\n format: params.format,\n interpretedOutput: params.interpretedOutput,\n evaluationFunction: params.evaluationFunction,\n evaluationOutput: params.evaluationOutput,\n directory: params.directory,\n logDir: params.logDir,\n qlref: params.qlref\n };\n\n const {\n _positional = [],\n files,\n file,\n dir,\n packDir,\n tests,\n query,\n queryName,\n queryLanguage: _queryLanguage,\n queryPack: _queryPack,\n sourceFiles,\n sourceFunction,\n targetFunction,\n format: _format,\n interpretedOutput: _interpretedOutput,\n evaluationFunction: _evaluationFunction,\n evaluationOutput: _evaluationOutput,\n directory,\n logDir: customLogDir,\n qlref,\n } = extractedParams;\n\n // Get remaining options (everything not extracted above)\n const options = {...params};\n Object.keys(extractedParams).forEach(key => delete options[key]);\n let positionalArgs = Array.isArray(_positional) ? _positional as string[] : [_positional as string];\n\n // Handle files parameter as positional arguments for certain tools\n if (files && Array.isArray(files)) {\n positionalArgs = [...positionalArgs, ...files as string[]];\n }\n\n // Handle file parameter as positional argument for BQRS tools\n if (file && name.startsWith('codeql_bqrs_')) {\n positionalArgs = [...positionalArgs, file as string];\n }\n\n // Handle qlref parameter as positional argument for resolve qlref tool\n if (qlref && name === 'codeql_resolve_qlref') {\n positionalArgs = [...positionalArgs, qlref as string];\n }\n\n // Handle database parameter as positional argument for resolve database tool\n if (options.database && name === 'codeql_resolve_database') {\n positionalArgs = [...positionalArgs, options.database as string];\n delete options.database;\n }\n\n // Handle database parameter as positional argument for database create tool\n if (options.database && name === 'codeql_database_create') {\n positionalArgs = [...positionalArgs, options.database as string];\n delete options.database;\n }\n\n // Handle database and queries parameters as positional arguments for database analyze tool\n if (name === 'codeql_database_analyze') {\n if (options.database) {\n positionalArgs = [...positionalArgs, options.database as string];\n delete options.database;\n }\n if (options.queries) {\n positionalArgs = [...positionalArgs, options.queries as string];\n delete options.queries;\n }\n }\n\n // Handle query parameter as positional argument for generate query-help tool\n if (query && name === 'codeql_generate_query-help') {\n positionalArgs = [...positionalArgs, query as string];\n }\n\n // Handle dir parameter as positional argument for pack tools\n if (dir && (name === 'codeql_pack_ls')) {\n positionalArgs = [...positionalArgs, dir as string];\n }\n \n // Handle tool-specific parameters using switch pattern for better maintainability\n switch (name) {\n case 'codeql_test_accept':\n case 'codeql_test_extract':\n case 'codeql_test_run':\n case 'codeql_resolve_tests':\n // Handle tests parameter as positional arguments for test tools.\n // Resolve relative paths against the user's effective workspace\n // directory. In monorepo layouts this is the repo root; in npm-\n // installed layouts it falls back to process.cwd().\n if (tests && Array.isArray(tests)) {\n const userDir = getUserWorkspaceDir();\n positionalArgs = [...positionalArgs, ...(tests as string[]).map(\n t => isAbsolute(t) ? t : resolve(userDir, t)\n )];\n }\n break;\n \n case 'codeql_query_run': {\n // Resolve database path to absolute path if it's relative\n if (options.database && typeof options.database === 'string' && !isAbsolute(options.database)) {\n options.database = resolve(getUserWorkspaceDir(), options.database);\n logger.info(`Resolved database path to: ${options.database}`);\n }\n \n // Implement query resolution logic with enhanced results processing\n const resolvedQuery = await resolveQueryPath(params, logger);\n if (resolvedQuery) {\n positionalArgs = [...positionalArgs, resolvedQuery];\n } else if (query) {\n positionalArgs = [...positionalArgs, query as string];\n }\n \n // Handle external predicates for tool queries\n if (queryName === 'PrintAST' && sourceFiles) {\n // Create a CSV file with the source file paths for the external predicate\n // The external predicate expects a CSV file with one column containing file paths\n const filePaths = (sourceFiles as string).split(',').map((f: string) => f.trim());\n let tempDir: string;\n let csvPath: string;\n try {\n tempDir = createProjectTempDir('codeql-external-');\n tempDirsToCleanup.push(tempDir); // Track for cleanup\n csvPath = join(tempDir, 'selectedSourceFiles.csv');\n\n // Create CSV content\n const csvContent = filePaths.join('\\n') + '\\n';\n\n writeFileSync(csvPath, csvContent, 'utf8');\n } catch (err) {\n logger.error(`Failed to create external predicate CSV for PrintAST query at path ${csvPath || '[unknown]'}: ${err instanceof Error ? err.message : String(err)}`);\n throw err;\n }\n \n // Add the external predicate with the CSV file path\n const currentExternal = options.external || [];\n const externalArray = Array.isArray(currentExternal) ? currentExternal : [currentExternal];\n externalArray.push(`selectedSourceFiles=${csvPath}`);\n options.external = externalArray;\n \n logger.info(`Created external predicate CSV at ${csvPath} for files: ${filePaths.join(', ')}`);\n }\n \n // Handle external predicates for CallGraphFrom queries\n if (queryName === 'CallGraphFrom' && sourceFunction) {\n const functionNames = (sourceFunction as string).split(',').map((f: string) => f.trim());\n let tempDir: string;\n let csvPath: string;\n try {\n tempDir = createProjectTempDir('codeql-external-');\n tempDirsToCleanup.push(tempDir);\n csvPath = join(tempDir, 'sourceFunction.csv');\n\n // Create CSV content\n const csvContent = functionNames.join('\\n') + '\\n';\n\n writeFileSync(csvPath, csvContent, 'utf8');\n } catch (err) {\n logger.error(`Failed to create external predicate CSV for CallGraphFrom query at path ${csvPath || '[unknown]'}: ${err instanceof Error ? err.message : String(err)}`);\n throw err;\n }\n \n // Add the external predicate with the CSV file path\n const currentExternal = options.external || [];\n const externalArray = Array.isArray(currentExternal) ? currentExternal : [currentExternal];\n externalArray.push(`sourceFunction=${csvPath}`);\n options.external = externalArray;\n \n logger.info(`Created external predicate CSV at ${csvPath} for functions: ${functionNames.join(', ')}`);\n }\n \n // Handle external predicates for CallGraphTo queries\n if (queryName === 'CallGraphTo' && targetFunction) {\n const functionNames = (targetFunction as string).split(',').map((f: string) => f.trim());\n let tempDir: string;\n let csvPath: string;\n try {\n tempDir = createProjectTempDir('codeql-external-');\n tempDirsToCleanup.push(tempDir);\n csvPath = join(tempDir, 'targetFunction.csv');\n\n // Create CSV content\n const csvContent = functionNames.join('\\n') + '\\n';\n\n writeFileSync(csvPath, csvContent, 'utf8');\n } catch (err) {\n logger.error(`Failed to create external predicate CSV for CallGraphTo query at path ${csvPath || '[unknown]'}: ${err instanceof Error ? err.message : String(err)}`);\n throw err;\n }\n \n // Add the external predicate with the CSV file path\n const currentExternal = options.external || [];\n const externalArray = Array.isArray(currentExternal) ? currentExternal : [currentExternal];\n externalArray.push(`targetFunction=${csvPath}`);\n options.external = externalArray;\n \n logger.info(`Created external predicate CSV at ${csvPath} for functions: ${functionNames.join(', ')}`);\n }\n break;\n }\n \n case 'codeql_query_compile':\n case 'codeql_resolve_metadata':\n // Handle query parameter as positional argument for query compilation and metadata tools\n if (query) {\n positionalArgs = [...positionalArgs, query as string];\n }\n break;\n \n case 'codeql_resolve_queries':\n // Handle directory parameter as positional argument\n if (directory) {\n positionalArgs = [...positionalArgs, directory as string];\n }\n break;\n \n default:\n // No special parameter handling needed for other tools\n break;\n }\n\n // Set up logging directory for query/test runs\n let queryLogDir: string | undefined;\n if (name === 'codeql_query_run' || name === 'codeql_test_run') {\n queryLogDir = getOrCreateLogDirectory(customLogDir as string | undefined);\n logger.info(`Using log directory for ${name}: ${queryLogDir}`);\n \n // Create timestamp file to track when query/test run started\n const timestampPath = join(queryLogDir, 'timestamp');\n writeFileSync(timestampPath, Date.now().toString(), 'utf8');\n \n // Set the --logdir option for CodeQL CLI\n options.logdir = queryLogDir;\n \n // Set verbosity to progress+ to generate detailed query.log/test.log\n if (!options.verbosity) {\n options.verbosity = 'progress+';\n }\n \n // For query run, also handle the deprecated evaluator-log parameter and default output\n if (name === 'codeql_query_run') {\n // If evaluator-log was explicitly provided (deprecated), use it\n // Otherwise, set it to the log directory\n if (!options['evaluator-log']) {\n options['evaluator-log'] = join(queryLogDir, 'evaluator-log.jsonl');\n }\n \n // If output was not explicitly provided, set it to the log directory\n if (!options.output) {\n options.output = join(queryLogDir, 'results.bqrs');\n }\n }\n }\n\n let result: CLIExecutionResult;\n \n if (command === 'codeql') {\n // For pack commands, set the working directory to where qlpack.yml is located.\n // Resolve to absolute path since the MCP server's cwd may differ from\n // the workspace root (especially when launched by VS Code).\n let cwd: string | undefined;\n if ((name === 'codeql_pack_install' || name === 'codeql_pack_ls') && (dir || packDir)) {\n const rawCwd = (dir || packDir) as string;\n // Resolve relative paths against the user's effective workspace\n // directory rather than a potentially read-only package root.\n cwd = isAbsolute(rawCwd) ? rawCwd : resolve(getUserWorkspaceDir(), rawCwd);\n }\n \n // Add --additional-packs for commands that need to access local test packs.\n // Only set the default examples path when it actually exists on disk\n // (it may be absent in npm-installed layouts where ql/javascript/examples/\n // is not included in the published package).\n const defaultExamplesPath = resolve(packageRootDir, 'ql', 'javascript', 'examples');\n const additionalPacksPath = process.env.CODEQL_ADDITIONAL_PACKS\n || (existsSync(defaultExamplesPath) ? defaultExamplesPath : undefined);\n if (additionalPacksPath && (name === 'codeql_test_run' || name === 'codeql_query_run' || name === 'codeql_query_compile')) {\n options['additional-packs'] = additionalPacksPath;\n }\n \n // Keep test databases for codeql_test_run to allow subsequent query runs\n if (name === 'codeql_test_run') {\n options['keep-databases'] = true;\n }\n \n result = await executeCodeQLCommand(subcommand, options, positionalArgs, cwd);\n } else if (command === 'qlt') {\n result = await executeQLTCommand(subcommand, options, positionalArgs);\n } else {\n throw new Error(`Unsupported command: ${command}`);\n }\n\n // Post-execution processing for codeql_query_run\n if (name === 'codeql_query_run' && result.success && queryLogDir) {\n // Generate SARIF interpretation if results.bqrs exists\n const bqrsPath = options.output as string;\n const sarifPath = join(queryLogDir, 'results.sarif');\n \n if (existsSync(bqrsPath)) {\n try {\n const sarifResult = await executeCodeQLCommand(\n 'bqrs interpret',\n { format: 'sarif-latest', output: sarifPath },\n [bqrsPath]\n );\n \n if (sarifResult.success) {\n logger.info(`Generated SARIF interpretation at ${sarifPath}`);\n }\n } catch (error) {\n logger.warn(`Failed to generate SARIF interpretation: ${error}`);\n }\n }\n \n // Process evaluation results\n result = await processQueryRunResults(result, params, logger);\n }\n\n // Process the result\n const processedResult = resultProcessor(result, params);\n\n return {\n content: [{\n type: 'text' as const,\n text: processedResult\n }],\n isError: !result.success\n };\n\n } catch (error) {\n logger.error(`Error in CLI tool ${name}:`, error);\n \n return {\n content: [{\n type: 'text' as const,\n text: `Failed to execute CLI tool: ${error instanceof Error ? error.message : String(error)}`\n }],\n isError: true\n };\n } finally {\n // Clean up temporary directories\n for (const tempDir of tempDirsToCleanup) {\n try {\n rmSync(tempDir, { recursive: true, force: true });\n logger.info(`Cleaned up temporary directory: ${tempDir}`);\n } catch (cleanupError) {\n logger.error(`Failed to clean up temporary directory ${tempDir}:`, cleanupError);\n }\n }\n }\n }\n );\n}\n\n/**\n * Helper function to create common CodeQL input schemas\n */\nexport const createCodeQLSchemas = {\n database: () => z.string().describe('Path to the CodeQL database'),\n \n query: () => z.string().describe('Path to the CodeQL query file (.ql)'),\n \n output: () => z.string().optional().describe('Output file path'),\n \n outputFormat: () => z.enum(['csv', 'json', 'bqrs', 'sarif-latest', 'sarifv2.1.0']).optional()\n .describe('Output format for results'),\n \n language: () => z.string().optional().describe('Programming language'),\n \n threads: () => z.number().optional().describe('Number of threads to use'),\n \n ram: () => z.number().optional().describe('Amount of RAM to use (MB)'),\n \n timeout: () => z.number().optional().describe('Timeout in seconds'),\n \n verbose: () => z.boolean().optional().describe('Enable verbose output'),\n \n additionalArgs: () => z.array(z.string()).optional().describe('Additional command-line arguments'),\n \n positionalArgs: () => z.array(z.string()).optional().describe('Positional arguments')\n .transform((val) => ({ _positional: val }))\n};\n\n/**\n * Helper function to create common QLT input schemas\n */\nexport const createQLTSchemas = {\n language: () => z.string().describe('Programming language'),\n \n output: () => z.string().optional().describe('Output directory or file path'),\n \n template: () => z.string().optional().describe('Template to use'),\n \n name: () => z.string().optional().describe('Name for generated query'),\n \n description: () => z.string().optional().describe('Description for generated query'),\n \n verbose: () => z.boolean().optional().describe('Enable verbose output'),\n \n force: () => z.boolean().optional().describe('Force overwrite existing files'),\n \n additionalArgs: () => z.array(z.string()).optional().describe('Additional command-line arguments')\n};\n\n/**\n * Create a result processor that formats BQRS output specially\n */\nexport const createBQRSResultProcessor = () => (\n result: CLIExecutionResult, \n params: Record\n): string => {\n if (!result.success) {\n return defaultCLIResultProcessor(result, params);\n }\n \n // For BQRS commands, provide more context about the output\n let output = result.stdout;\n \n if (params.output) {\n output += `\\n\\nResults saved to: ${params.output}`;\n }\n \n if (result.stderr) {\n output += `\\n\\nAdditional information:\\n${result.stderr}`;\n }\n \n return output;\n};\n\n/**\n * Create a result processor that formats database creation output\n */\nexport const createDatabaseResultProcessor = () => (\n result: CLIExecutionResult, \n params: Record\n): string => {\n if (!result.success) {\n return defaultCLIResultProcessor(result, params);\n }\n \n let output = 'Database creation completed successfully';\n \n if (params.database || params._positional) {\n const dbPath = params.database || (Array.isArray(params._positional) ? params._positional[0] : params._positional);\n output += `\\n\\nDatabase location: ${dbPath}`;\n }\n \n if (result.stdout) {\n output += `\\n\\nOutput:\\n${result.stdout}`;\n }\n \n if (result.stderr) {\n output += `\\n\\nAdditional information:\\n${result.stderr}`;\n }\n \n return output;\n};\n\n/**\n * Resolve query path for codeql_query_run tool\n * If queryName and queryLanguage are provided, resolve using codeql resolve queries\n */\nasync function resolveQueryPath(\n params: Record, \n logger: { info: (_message: string, ..._args: unknown[]) => void; error: (_message: string, ..._args: unknown[]) => void }\n): Promise {\n const { queryName, queryLanguage, queryPack, query } = params;\n \n // Validate parameter usage - queryName and query are mutually exclusive\n if (queryName && query) {\n logger.error('Cannot use both \"query\" and \"queryName\" parameters simultaneously. Use either \"query\" for direct file path OR \"queryName\" + \"queryLanguage\" for tool queries.');\n throw new Error('Cannot use both \"query\" and \"queryName\" parameters simultaneously. Use either \"query\" for direct file path OR \"queryName\" + \"queryLanguage\" for tool queries.');\n }\n \n // If no queryName provided, fall back to direct query parameter\n if (!queryName) {\n return query as string || null;\n }\n \n // If queryName provided but no language, we can't resolve\n if (!queryLanguage) {\n logger.error('queryLanguage is required when using queryName parameter. Supported languages: actions, cpp, csharp, go, java, javascript, python, ruby, swift');\n throw new Error('queryLanguage is required when using queryName parameter. Supported languages: actions, cpp, csharp, go, java, javascript, python, ruby, swift');\n }\n \n try {\n // Determine the query pack path - use absolute path to ensure it works regardless of cwd\n const defaultPackPath = resolveToolQueryPackPath(queryLanguage as string);\n const packPath = queryPack as string || defaultPackPath;\n \n logger.info(`Resolving query: ${queryName} for language: ${queryLanguage} in pack: ${packPath}`);\n \n // Execute codeql resolve queries to get available queries\n const { executeCodeQLCommand } = await import('./cli-executor');\n const resolveResult = await executeCodeQLCommand(\n 'resolve queries',\n { format: 'json' },\n [packPath]\n );\n \n if (!resolveResult.success) {\n logger.error('Failed to resolve queries:', resolveResult.stderr || resolveResult.error);\n throw new Error(`Failed to resolve queries: ${resolveResult.stderr || resolveResult.error}`);\n }\n \n // Parse the JSON output to find matching queries\n let resolvedQueries: string[];\n try {\n resolvedQueries = JSON.parse(resolveResult.stdout);\n } catch (parseError) {\n logger.error('Failed to parse resolve queries output:', parseError);\n throw new Error('Failed to parse resolve queries output');\n }\n \n // Find the query that matches the requested name exactly\n const matchingQuery = resolvedQueries.find(queryPath => {\n const fileName = basename(queryPath);\n // Match exact query name: \"PrintAST\" should match \"PrintAST.ql\" only\n return fileName === `${queryName}.ql`;\n });\n\n if (!matchingQuery) {\n logger.error(`Query \"${queryName}.ql\" not found in pack \"${packPath}\". Available queries:`, resolvedQueries.map(q => basename(q)));\n throw new Error(`Query \"${queryName}.ql\" not found in pack \"${packPath}\"`);\n }\n \n logger.info(`Resolved query \"${queryName}\" to: ${matchingQuery}`);\n return matchingQuery;\n \n } catch (error) {\n logger.error('Error resolving query path:', error);\n throw error;\n }\n}\n\n/**\n * Interpret BQRS file using codeql bqrs interpret\n */\nasync function interpretBQRSFile(\n bqrsPath: string,\n queryPath: string,\n format: string,\n outputPath: string,\n logger: { info: (_message: string, ..._args: unknown[]) => void; error: (_message: string, ..._args: unknown[]) => void }\n): Promise {\n try {\n // Extract query metadata to get id and kind\n const metadata = await extractQueryMetadata(queryPath);\n \n // Validate required metadata fields\n const missingFields = [];\n if (!metadata.id) missingFields.push('id');\n if (!metadata.kind) missingFields.push('kind');\n \n if (missingFields.length > 0) {\n return {\n success: false,\n exitCode: 1,\n stdout: '',\n stderr: '',\n error: `Query metadata is incomplete. Missing required field(s): ${missingFields.join(', ')}. Ensure the query file contains @id and @kind metadata.`\n };\n }\n \n // Sanitize metadata values to prevent command injection\n const sanitizedKind = (metadata.kind || '').replace(/[^a-zA-Z0-9_-]/g, '');\n const sanitizedId = (metadata.id || '').replace(/[^a-zA-Z0-9_/:-]/g, '');\n \n // Validate format for query kind\n const graphFormats = ['graphtext', 'dgml', 'dot'];\n if (graphFormats.includes(format) && metadata.kind !== 'graph') {\n return {\n success: false,\n exitCode: 1,\n stdout: '',\n stderr: '',\n error: `Format '${format}' is only compatible with @kind graph queries, but this query has @kind ${metadata.kind}`\n };\n }\n \n // Ensure output directory exists\n mkdirSync(dirname(outputPath), { recursive: true });\n \n // Build the codeql bqrs interpret command\n const params: Record = {\n format: format,\n output: outputPath,\n t: [`kind=${sanitizedKind}`, `id=${sanitizedId}`]\n };\n \n logger.info(`Interpreting BQRS file ${bqrsPath} with format ${format} to ${outputPath}`);\n \n // Execute codeql bqrs interpret\n const result = await executeCodeQLCommand(\n 'bqrs interpret',\n params,\n [bqrsPath]\n );\n \n return result;\n } catch (error) {\n return {\n success: false,\n exitCode: 1,\n stdout: '',\n stderr: '',\n error: `Failed to interpret BQRS file: ${error}`\n };\n }\n}\n\n/**\n * Get default output extension based on format\n */\nfunction getDefaultExtension(format: string): string {\n switch (format) {\n case 'sarif-latest':\n case 'sarifv2.1.0':\n return '.sarif';\n case 'csv':\n return '.csv';\n case 'graphtext':\n return '.txt';\n case 'dgml':\n return '.dgml';\n case 'dot':\n return '.dot';\n default:\n return '.txt';\n }\n}\n\n/**\n * Process query run results with optional interpretation or evaluation\n */\nasync function processQueryRunResults(\n result: CLIExecutionResult,\n params: Record,\n logger: { info: (_message: string, ..._args: unknown[]) => void; error: (_message: string, ..._args: unknown[]) => void }\n): Promise {\n try {\n const { format, interpretedOutput, evaluationFunction, evaluationOutput, output, query, queryName, queryLanguage } = params;\n \n // If no format or evaluationFunction specified, return as-is\n if (!format && !evaluationFunction) {\n return result;\n }\n \n // Ensure output (bqrs file) was generated\n if (!output) {\n return result;\n }\n \n const bqrsPath = output as string;\n \n // Determine the query path for metadata extraction\n let queryPath: string | null = null;\n \n if (query) {\n queryPath = query as string;\n } else if (queryName && queryLanguage) {\n // Try to resolve the query path again for evaluation\n queryPath = await resolveQueryPath(params, logger);\n }\n \n if (!queryPath) {\n logger.error('Cannot determine query path for interpretation/evaluation');\n return {\n ...result,\n stdout: result.stdout + '\\n\\nWarning: Query interpretation skipped - could not determine query path'\n };\n }\n \n // Handle new format parameter (preferred approach)\n if (format) {\n const outputFormat = format as string;\n \n // Determine output path\n let outputFilePath = interpretedOutput as string | undefined;\n if (!outputFilePath) {\n const ext = getDefaultExtension(outputFormat);\n outputFilePath = bqrsPath.replace('.bqrs', ext);\n }\n \n logger.info(`Interpreting query results from ${bqrsPath} with format: ${outputFormat}`);\n \n // Interpret the BQRS file\n const interpretResult = await interpretBQRSFile(\n bqrsPath,\n queryPath,\n outputFormat,\n outputFilePath,\n logger\n );\n \n if (interpretResult.success) {\n let enhancedOutput = result.stdout;\n enhancedOutput += `\\n\\nQuery results interpreted successfully with format: ${outputFormat}`;\n enhancedOutput += `\\nInterpreted output saved to: ${outputFilePath}`;\n \n return {\n ...result,\n stdout: enhancedOutput\n };\n } else {\n logger.error('Query interpretation failed:', interpretResult.error);\n return {\n ...result,\n stdout: result.stdout + `\\n\\nWarning: Query interpretation failed - ${interpretResult.error || interpretResult.stderr}`\n };\n }\n }\n \n // Handle legacy evaluationFunction parameter (deprecated)\n if (evaluationFunction) {\n logger.info(`Using deprecated evaluationFunction parameter. Consider using format parameter instead.`);\n logger.info(`Evaluating query results from ${bqrsPath} using function: ${evaluationFunction}`);\n \n // Perform the evaluation\n const evaluationResult: QueryEvaluationResult = await evaluateQueryResults(\n bqrsPath,\n queryPath,\n evaluationFunction as string,\n evaluationOutput as string | undefined\n );\n \n if (evaluationResult.success) {\n // Append evaluation results to the command output\n let enhancedOutput = result.stdout;\n \n if (evaluationResult.outputPath) {\n enhancedOutput += `\\n\\nQuery evaluation completed successfully.`;\n enhancedOutput += `\\nEvaluation output saved to: ${evaluationResult.outputPath}`;\n }\n \n if (evaluationResult.content) {\n enhancedOutput += `\\n\\n=== Query Results Evaluation ===\\n`;\n enhancedOutput += evaluationResult.content;\n }\n \n return {\n ...result,\n stdout: enhancedOutput\n };\n } else {\n // Evaluation failed, but don't fail the whole operation\n logger.error('Query evaluation failed:', evaluationResult.error);\n return {\n ...result,\n stdout: result.stdout + `\\n\\nWarning: Query evaluation failed - ${evaluationResult.error}`\n };\n }\n }\n \n return result;\n } catch (error) {\n logger.error('Error in query results processing:', error);\n return {\n ...result,\n stdout: result.stdout + `\\n\\nWarning: Query processing error - ${error}`\n };\n }\n}", "/**\n * Query results evaluation functions for processing .bqrs files\n */\n\nimport { executeCodeQLCommand } from './cli-executor';\nimport { logger } from '../utils/logger';\nimport { writeFileSync, readFileSync } from 'fs';\nimport { dirname, isAbsolute } from 'path';\nimport { mkdirSync } from 'fs';\n\nexport interface QueryEvaluationResult {\n success: boolean;\n outputPath?: string;\n content?: string;\n error?: string;\n}\n\nexport interface QueryMetadata {\n kind?: string;\n name?: string;\n description?: string;\n id?: string;\n tags?: string[];\n}\n\n/**\n * Built-in evaluation functions\n */\nexport const BUILT_IN_EVALUATORS = {\n 'json-decode': 'JSON format decoder for query results',\n 'csv-decode': 'CSV format decoder for query results', \n 'mermaid-graph': 'Mermaid diagram generator for @kind graph queries (like PrintAST)',\n} as const;\n\nexport type BuiltInEvaluator = keyof typeof BUILT_IN_EVALUATORS;\n\n/**\n * Extract metadata from a CodeQL query file\n */\nexport async function extractQueryMetadata(queryPath: string): Promise {\n try {\n const queryContent = readFileSync(queryPath, 'utf-8');\n const metadata: QueryMetadata = {};\n \n // Extract metadata from comments using regex patterns\n const kindMatch = queryContent.match(/@kind\\s+([^\\s]+)/);\n if (kindMatch) metadata.kind = kindMatch[1];\n \n const nameMatch = queryContent.match(/@name\\s+(.+)/);\n if (nameMatch) metadata.name = nameMatch[1].trim();\n \n const descMatch = queryContent.match(/@description\\s+(.+)/);\n if (descMatch) metadata.description = descMatch[1].trim();\n \n const idMatch = queryContent.match(/@id\\s+(.+)/);\n if (idMatch) metadata.id = idMatch[1].trim();\n \n const tagsMatch = queryContent.match(/@tags\\s+(.+)/);\n if (tagsMatch) {\n metadata.tags = tagsMatch[1].split(/\\s+/).filter(t => t.length > 0);\n }\n \n return metadata;\n } catch (error) {\n logger.error('Failed to extract query metadata:', error);\n return {};\n }\n}\n\n/**\n * JSON decoder - converts .bqrs to JSON format\n */\nexport async function evaluateWithJsonDecoder(\n bqrsPath: string, \n outputPath?: string\n): Promise {\n try {\n const result = await executeCodeQLCommand(\n 'bqrs decode',\n { format: 'json' },\n [bqrsPath]\n );\n \n if (!result.success) {\n return {\n success: false,\n error: `Failed to decode BQRS file: ${result.stderr || result.error}`\n };\n }\n \n const defaultOutputPath = outputPath || bqrsPath.replace('.bqrs', '.json');\n \n // Ensure output directory exists\n mkdirSync(dirname(defaultOutputPath), { recursive: true });\n \n // Write JSON results\n writeFileSync(defaultOutputPath, result.stdout);\n \n return {\n success: true,\n outputPath: defaultOutputPath,\n content: result.stdout\n };\n } catch (error) {\n return {\n success: false,\n error: `JSON evaluation failed: ${error}`\n };\n }\n}\n\n/**\n * CSV decoder - converts .bqrs to CSV format\n */\nexport async function evaluateWithCsvDecoder(\n bqrsPath: string,\n outputPath?: string\n): Promise {\n try {\n const result = await executeCodeQLCommand(\n 'bqrs decode',\n { format: 'csv' },\n [bqrsPath]\n );\n \n if (!result.success) {\n return {\n success: false,\n error: `Failed to decode BQRS file: ${result.stderr || result.error}`\n };\n }\n \n const defaultOutputPath = outputPath || bqrsPath.replace('.bqrs', '.csv');\n \n // Ensure output directory exists\n mkdirSync(dirname(defaultOutputPath), { recursive: true });\n \n // Write CSV results\n writeFileSync(defaultOutputPath, result.stdout);\n \n return {\n success: true,\n outputPath: defaultOutputPath,\n content: result.stdout\n };\n } catch (error) {\n return {\n success: false,\n error: `CSV evaluation failed: ${error}`\n };\n }\n}\n\n/**\n * Mermaid graph generator - converts @kind graph query results to mermaid diagrams\n */\nexport async function evaluateWithMermaidGraph(\n bqrsPath: string,\n queryPath: string,\n outputPath?: string\n): Promise {\n try {\n // First extract query metadata to confirm this is a graph query\n const metadata = await extractQueryMetadata(queryPath);\n \n if (metadata.kind !== 'graph') {\n logger.error(`Query is not a graph query (kind: ${metadata.kind}), mermaid-graph evaluation is only for @kind graph queries`);\n return {\n success: false,\n error: `Query is not a graph query (kind: ${metadata.kind}), mermaid-graph evaluation is only for @kind graph queries`\n };\n }\n \n // Decode the BQRS file to JSON first\n const jsonResult = await executeCodeQLCommand(\n 'bqrs decode',\n { format: 'json' },\n [bqrsPath]\n );\n \n if (!jsonResult.success) {\n return {\n success: false,\n error: `Failed to decode BQRS file: ${jsonResult.stderr || jsonResult.error}`\n };\n }\n \n // Parse the JSON results\n let queryResults;\n try {\n queryResults = JSON.parse(jsonResult.stdout);\n } catch (parseError) {\n return {\n success: false,\n error: `Failed to parse query results JSON: ${parseError}`\n };\n }\n \n // Generate mermaid diagram from graph results\n const mermaidContent = generateMermaidFromGraphResults(queryResults, metadata);\n \n const defaultOutputPath = outputPath || bqrsPath.replace('.bqrs', '.md');\n \n // Ensure output directory exists\n mkdirSync(dirname(defaultOutputPath), { recursive: true });\n \n // Write markdown file with mermaid diagram\n writeFileSync(defaultOutputPath, mermaidContent);\n \n return {\n success: true,\n outputPath: defaultOutputPath,\n content: mermaidContent\n };\n } catch (error) {\n return {\n success: false,\n error: `Mermaid graph evaluation failed: ${error}`\n };\n }\n}\n\n/**\n * Generate mermaid diagram from CodeQL graph query results\n */\nfunction generateMermaidFromGraphResults(queryResults: unknown, metadata: QueryMetadata): string {\n const queryName = sanitizeMarkdown(metadata.name || 'CodeQL Query Results');\n const queryDesc = sanitizeMarkdown(metadata.description || 'Graph visualization of CodeQL query results');\n \n let mermaidContent = `# ${queryName}\\n\\n${queryDesc}\\n\\n`;\n \n // Handle different result structures that CodeQL graph queries can produce\n if (!queryResults || typeof queryResults !== 'object') {\n mermaidContent += '```mermaid\\ngraph TD\\n A[No Results]\\n```\\n';\n return mermaidContent;\n }\n \n // Check if results have the expected structure for graph queries\n const tuples = queryResults.tuples || queryResults;\n \n if (!Array.isArray(tuples) || tuples.length === 0) {\n mermaidContent += '```mermaid\\ngraph TD\\n A[No Graph Data]\\n```\\n';\n return mermaidContent;\n }\n \n mermaidContent += '```mermaid\\ngraph TD\\n';\n \n // Track nodes and edges to avoid duplicates\n const nodes = new Set();\n const edges = new Set();\n \n // Process each tuple in the results\n tuples.forEach((tuple: unknown, index: number) => {\n if (Array.isArray(tuple) && tuple.length >= 2) {\n // Extract source and target from tuple\n const source = sanitizeNodeId(tuple[0]?.toString() || `node_${index}_0`);\n const target = sanitizeNodeId(tuple[1]?.toString() || `node_${index}_1`);\n const label = tuple[2]?.toString() || '';\n \n // Add nodes\n nodes.add(source);\n nodes.add(target);\n \n // Add edge\n const edgeId = `${source}_${target}`;\n if (!edges.has(edgeId)) {\n if (label) {\n mermaidContent += ` ${source} -->|${sanitizeLabel(label)}| ${target}\\n`;\n } else {\n mermaidContent += ` ${source} --> ${target}\\n`;\n }\n edges.add(edgeId);\n }\n } else if (typeof tuple === 'object' && tuple !== null) {\n // Handle object-based results\n const source = sanitizeNodeId(tuple.source?.toString() || tuple.from?.toString() || `node_${index}_src`);\n const target = sanitizeNodeId(tuple.target?.toString() || tuple.to?.toString() || `node_${index}_tgt`);\n const label = tuple.label?.toString() || tuple.relation?.toString() || '';\n \n nodes.add(source);\n nodes.add(target);\n \n const edgeId = `${source}_${target}`;\n if (!edges.has(edgeId)) {\n if (label) {\n mermaidContent += ` ${source} -->|${sanitizeLabel(label)}| ${target}\\n`;\n } else {\n mermaidContent += ` ${source} --> ${target}\\n`;\n }\n edges.add(edgeId);\n }\n }\n });\n \n // If no edges were created, create a simple diagram showing the first few nodes\n if (edges.size === 0 && nodes.size > 0) {\n const nodeArray = Array.from(nodes).slice(0, 10); // Limit to avoid clutter\n nodeArray.forEach((node, index) => {\n if (index === 0) {\n mermaidContent += ` ${node}[${sanitizeLabel(node)}]\\n`;\n } else {\n mermaidContent += ` ${nodeArray[0]} --> ${node}\\n`;\n }\n });\n }\n \n mermaidContent += '```\\n\\n';\n \n // Add statistics\n mermaidContent += `## Query Statistics\\n\\n`;\n mermaidContent += `- Total nodes: ${nodes.size}\\n`;\n mermaidContent += `- Total edges: ${edges.size}\\n`;\n mermaidContent += `- Total tuples processed: ${tuples.length}\\n`;\n \n return mermaidContent;\n}\n\n/**\n * Sanitize node IDs for mermaid compatibility\n */\nfunction sanitizeNodeId(id: string): string {\n return id\n .replace(/[^a-zA-Z0-9_]/g, '_')\n .replace(/^(\\d)/, 'n$1') // Prefix with 'n' if starts with number\n .substring(0, 50); // Limit length\n}\n\n/**\n * Sanitize labels for mermaid compatibility\n */\nfunction sanitizeLabel(label: string): string {\n return label\n .replace(/[|\"`<>\\n\\r\\t]/g, '') // Remove problematic characters including backticks, newlines, angle brackets\n .replace(/\\s+/g, ' ') // Normalize whitespace\n .trim()\n .substring(0, 30); // Limit length for readability\n}\n\n/**\n * Sanitize markdown content to prevent injection\n */\nfunction sanitizeMarkdown(content: string): string {\n return content\n .replace(/[<>\"`]/g, '') // Remove potentially dangerous characters\n .replace(/\\n/g, ' ') // Convert newlines to spaces\n .replace(/\\s+/g, ' ') // Normalize whitespace\n .trim()\n .substring(0, 100); // Limit length\n}\n\n/**\n * Main evaluation function that determines which evaluator to use\n */\nexport async function evaluateQueryResults(\n bqrsPath: string,\n queryPath: string,\n evaluationFunction?: string,\n outputPath?: string\n): Promise {\n try {\n // If no evaluation function specified, default to json-decode\n const evalFunc = evaluationFunction || 'json-decode';\n \n logger.info(`Evaluating query results with function: ${evalFunc}`);\n \n // Handle built-in evaluation functions\n switch (evalFunc) {\n case 'json-decode':\n return await evaluateWithJsonDecoder(bqrsPath, outputPath);\n \n case 'csv-decode':\n return await evaluateWithCsvDecoder(bqrsPath, outputPath);\n \n case 'mermaid-graph':\n return await evaluateWithMermaidGraph(bqrsPath, queryPath, outputPath);\n \n default:\n // Check if it's a path to a custom evaluation script\n if (isAbsolute(evalFunc)) {\n return await evaluateWithCustomScript(bqrsPath, queryPath, evalFunc, outputPath);\n } else {\n return {\n success: false,\n error: `Unknown evaluation function: ${evalFunc}. Available built-in functions: ${Object.keys(BUILT_IN_EVALUATORS).join(', ')}`\n };\n }\n }\n } catch (error) {\n return {\n success: false,\n error: `Query evaluation failed: ${error}`\n };\n }\n}\n\n/**\n * Execute custom evaluation script\n */\nasync function evaluateWithCustomScript(\n _bqrsPath: string,\n _queryPath: string,\n _scriptPath: string,\n _outputPath?: string\n): Promise {\n // TODO: Implement custom script execution\n // This would need to execute the script with bqrsPath and queryPath as arguments\n // and capture the output\n return {\n success: false,\n error: 'Custom evaluation scripts are not yet implemented'\n };\n}", "/**\n * Log directory management utilities for CodeQL query and test runs\n */\n\nimport { mkdirSync, existsSync } from 'fs';\nimport { join, resolve } from 'path';\nimport { randomBytes } from 'crypto';\nimport { getProjectTmpDir } from '../utils/temp-dir';\n\n/**\n * Ensure that a given path is within a base directory.\n * Throws an error if the path is outside the base directory.\n */\nfunction ensurePathWithinBase(baseDir: string, targetPath: string): string {\n const absBase = resolve(baseDir);\n const absTarget = resolve(targetPath);\n if (!absTarget.startsWith(absBase + '/') && absTarget !== absBase) {\n throw new Error(`Provided log directory is outside the allowed base directory: ${absBase}`);\n }\n return absTarget;\n}\n\n/**\n * Get or create a unique log directory for query/test runs\n * \n * @param logDir - Optional custom log directory from parameters\n * @returns Absolute path to the log directory\n */\nexport function getOrCreateLogDirectory(logDir?: string): string {\n // Use CODEQL_QUERY_LOG_DIR env var or default base\n const baseLogDir = process.env.CODEQL_QUERY_LOG_DIR || getProjectTmpDir('query-logs');\n\n // If logDir is explicitly provided, validate it is within baseLogDir\n if (logDir) {\n const absLogDir = ensurePathWithinBase(baseLogDir, logDir);\n if (!existsSync(absLogDir)) {\n mkdirSync(absLogDir, { recursive: true });\n }\n return absLogDir;\n }\n \n // Otherwise, use baseLogDir and create a unique subdirectory\n \n // Create base directory if it doesn't exist\n if (!existsSync(baseLogDir)) {\n mkdirSync(baseLogDir, { recursive: true });\n }\n \n // Generate unique subdirectory with timestamp and random ID\n const timestamp = new Date().toISOString().replace(/[:.]/g, '-');\n const uniqueId = randomBytes(4).toString('hex');\n const uniqueLogDir = join(baseLogDir, `query-run-${timestamp}-${uniqueId}`);\n \n mkdirSync(uniqueLogDir, { recursive: true });\n \n return uniqueLogDir;\n}\n", "/**\n * CodeQL BQRS info tool\n */\n\nimport { z } from 'zod';\nimport { CLIToolDefinition, createCodeQLSchemas, createBQRSResultProcessor } from '../../lib/cli-tool-registry';\n\nexport const codeqlBqrsInfoTool: CLIToolDefinition = {\n name: 'codeql_bqrs_info',\n description: 'Get metadata and information about BQRS result files',\n command: 'codeql',\n subcommand: 'bqrs info',\n inputSchema: {\n files: z.array(z.string()).describe('BQRS file(s) to examine'),\n verbose: createCodeQLSchemas.verbose(),\n additionalArgs: createCodeQLSchemas.additionalArgs()\n },\n examples: [\n 'codeql bqrs info results.bqrs',\n 'codeql bqrs info --verbose results.bqrs'\n ],\n resultProcessor: createBQRSResultProcessor()\n};", "/**\n * CodeQL BQRS interpret tool\n */\n\nimport { z } from 'zod';\nimport { CLIToolDefinition, createCodeQLSchemas, createBQRSResultProcessor } from '../../lib/cli-tool-registry';\n\nexport const codeqlBqrsInterpretTool: CLIToolDefinition = {\n name: 'codeql_bqrs_interpret',\n description: 'Interpret BQRS result files according to query metadata and generate output in specified formats (CSV, SARIF, graph formats)',\n command: 'codeql',\n subcommand: 'bqrs interpret',\n inputSchema: {\n file: z.string().describe('The BQRS file to interpret'),\n format: z.enum(['csv', 'sarif-latest', 'sarifv2.1.0', 'graphtext', 'dgml', 'dot'])\n .describe('Output format: csv (comma-separated), sarif-latest/sarifv2.1.0 (SARIF), graphtext/dgml/dot (graph formats, only for @kind graph queries)'),\n output: createCodeQLSchemas.output(),\n t: z.array(z.string())\n .describe('Query metadata key=value pairs. At least \"kind\" and \"id\" must be specified (e.g., [\"kind=graph\", \"id=js/print-ast\"])'),\n 'max-paths': z.number().optional()\n .describe('Maximum number of paths to produce for each alert with paths (default: 4)'),\n 'sarif-add-file-contents': z.boolean().optional()\n .describe('[SARIF only] Include full file contents for all files referenced in results'),\n 'sarif-add-snippets': z.boolean().optional()\n .describe('[SARIF only] Include code snippets for each location with context'),\n 'sarif-group-rules-by-pack': z.boolean().optional()\n .describe('[SARIF only] Place rule objects under their QL pack in tool.extensions property'),\n 'sarif-multicause-markdown': z.boolean().optional()\n .describe('[SARIF only] Include multi-cause alerts as Markdown-formatted lists'),\n 'sarif-category': z.string().optional()\n .describe('[SARIF only] Category for this analysis (distinguishes multiple analyses on same code)'),\n 'csv-location-format': z.enum(['uri', 'line-column', 'offset-length']).optional()\n .describe('[CSV only] Format for locations in CSV output (default: line-column)'),\n 'dot-location-url-format': z.string().optional()\n .describe('[DOT only] Format string for file location URLs (placeholders: {path}, {start:line}, {start:column}, {end:line}, {end:column}, {offset}, {length})'),\n threads: z.number().optional()\n .describe('Number of threads for computing paths (0 = one per core, -N = leave N cores unused)'),\n 'column-kind': z.enum(['utf8', 'utf16', 'utf32', 'bytes']).optional()\n .describe('[SARIF only] Column kind for interpreting location columns'),\n 'unicode-new-lines': z.boolean().optional()\n .describe('[SARIF only] Whether unicode newlines (U+2028, U+2029) are considered as newlines'),\n verbose: createCodeQLSchemas.verbose(),\n additionalArgs: createCodeQLSchemas.additionalArgs()\n },\n examples: [\n 'codeql bqrs interpret --format=sarif-latest --output=results.sarif -t kind=problem -t id=js/sql-injection results.bqrs',\n 'codeql bqrs interpret --format=graphtext --output=ast.txt -t kind=graph -t id=js/print-ast results.bqrs',\n 'codeql bqrs interpret --format=csv --csv-location-format=line-column --output=results.csv -t kind=problem -t id=js/xss results.bqrs',\n 'codeql bqrs interpret --format=dot --output=graph.dot -t kind=graph -t id=java/call-graph results.bqrs',\n 'codeql bqrs interpret --format=sarif-latest --sarif-add-snippets --sarif-category=security --output=results.sarif -t kind=path-problem -t id=go/path-injection results.bqrs'\n ],\n resultProcessor: createBQRSResultProcessor()\n};\n", "/**\n * CodeQL database analyze tool\n */\n\nimport { z } from 'zod';\nimport { CLIToolDefinition } from '../../lib/cli-tool-registry';\n\nexport const codeqlDatabaseAnalyzeTool: CLIToolDefinition = {\n name: 'codeql_database_analyze',\n description: 'Run queries or query suites against CodeQL databases',\n command: 'codeql',\n subcommand: 'database analyze',\n inputSchema: {\n database: z.string().describe('Path to the CodeQL database'),\n queries: z.string().describe('Queries or query suite to run'),\n output: z.string().optional().describe('Output file path'),\n format: z.enum(['csv', 'json', 'sarif-latest', 'sarifv2.1.0']).optional()\n .describe('Output format for results'),\n 'download-location': z.string().optional()\n .describe('Location to download missing dependencies'),\n threads: z.number().optional().describe('Number of threads to use'),\n ram: z.number().optional().describe('Amount of RAM to use (MB)'),\n timeout: z.number().optional().describe('Timeout in seconds'),\n verbose: z.boolean().optional().describe('Enable verbose output'),\n additionalArgs: z.array(z.string()).optional().describe('Additional command-line arguments')\n },\n examples: [\n 'codeql database analyze mydb queries.qls --format=sarif-latest --output=results.sarif',\n 'codeql database analyze mydb codeql/java-queries --format=csv'\n ]\n};", "/**\n * CodeQL database create tool\n */\n\nimport { z } from 'zod';\nimport { CLIToolDefinition, createDatabaseResultProcessor } from '../../lib/cli-tool-registry';\n\nexport const codeqlDatabaseCreateTool: CLIToolDefinition = {\n name: 'codeql_database_create',\n description: 'Create a CodeQL database from source code',\n command: 'codeql',\n subcommand: 'database create',\n inputSchema: {\n database: z.string().describe('Database path/name to create'),\n language: z.string().optional().describe('Programming language(s) to extract'),\n 'source-root': z.string().optional().describe('Root directory of source code'),\n command: z.string().optional().describe('Build command for compiled languages'),\n 'build-mode': z.enum(['none', 'autobuild', 'manual']).optional()\n .describe('Build mode: none (interpreted langs), autobuild, or manual'),\n threads: z.number().optional().describe('Number of threads to use'),\n ram: z.number().optional().describe('Amount of RAM to use (MB)'),\n verbose: z.boolean().optional().describe('Enable verbose output'),\n overwrite: z.boolean().optional().describe('Overwrite existing database if it exists'),\n 'no-cleanup': z.boolean().optional().describe('Skip database cleanup after finalization'),\n additionalArgs: z.array(z.string()).optional().describe('Additional command-line arguments')\n },\n examples: [\n 'codeql database create --language=java --source-root=/path/to/project mydb',\n 'codeql database create --language=cpp --command=\"make all\" mydb',\n 'codeql database create --language=python,javascript mydb'\n ],\n resultProcessor: createDatabaseResultProcessor()\n};", "/**\n * CodeQL find class position tool\n * \n * Inspired by JordyZomer/codeql-mcp repository:\n * - https://github.com/JordyZomer/codeql-mcp/blob/main/server.py\n * - https://github.com/JordyZomer/codeql-mcp/blob/main/codeqlclient.py\n */\n\nimport { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport { z } from 'zod';\nimport { readFile } from 'fs/promises';\nimport { logger } from '../../utils/logger';\n\nexport interface ClassPosition {\n start_line: number;\n start_col: number;\n end_line: number;\n end_col: number;\n}\n\n/**\n * Find the 1-based position of a class name identifier in a QL file.\n * Returns: { start_line, start_col, end_line, end_col }\n */\nexport async function findClassPosition(filepath: string, className: string): Promise {\n try {\n const content = await readFile(filepath, 'utf-8');\n const lines = content.split('\\n');\n\n for (let i = 0; i < lines.length; i++) {\n const line = lines[i];\n // Match class definition with the specific class name\n const classNameRegex = new RegExp(`\\\\bclass\\\\s+(${className.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&')})\\\\b`);\n const match = classNameRegex.exec(line);\n \n if (match) {\n const start_line = i + 1; // 1-based line numbering\n // The class name is in capture group 1\n const classNameStart = match.index + match[0].indexOf(match[1]);\n const start_col = classNameStart + 1; // 1-based column numbering\n const end_col = start_col + className.length - 1; // end_col is inclusive\n \n return {\n start_line,\n start_col,\n end_line: start_line,\n end_col\n };\n }\n }\n\n throw new Error(`Class name '${className}' not found in file: ${filepath}`);\n } catch (error) {\n if (error instanceof Error && error.message.includes('not found in file')) {\n throw error;\n }\n throw new Error(`Failed to read or parse file ${filepath}: ${error instanceof Error ? error.message : 'Unknown error'}`);\n }\n}\n\n/**\n * Register the find class position tool with the MCP server\n */\nexport function registerFindClassPositionTool(server: McpServer): void {\n server.tool(\n 'find_class_position',\n 'Finds startline, startcol, endline endcol of a class for quickeval',\n {\n file: z.string().describe('Path to the .ql file to search'),\n name: z.string().describe('Name of the class to find'),\n },\n async ({ file, name }) => {\n try {\n const position = await findClassPosition(file, name);\n return {\n content: [{ type: 'text', text: JSON.stringify(position, null, 2) }],\n };\n } catch (error) {\n logger.error('Error finding class position:', error);\n return {\n content: [\n {\n type: 'text',\n text: `Error: ${error instanceof Error ? error.message : 'Unknown error'}`,\n },\n ],\n isError: true,\n };\n }\n }\n );\n}", "/**\n * CodeQL find predicate position tool\n * \n * Inspired by JordyZomer/codeql-mcp repository:\n * - https://github.com/JordyZomer/codeql-mcp/blob/main/server.py\n * - https://github.com/JordyZomer/codeql-mcp/blob/main/codeqlclient.py\n */\n\nimport { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport { z } from 'zod';\nimport { readFile } from 'fs/promises';\nimport { logger } from '../../utils/logger';\n\nexport interface PredicatePosition {\n start_line: number;\n start_col: number;\n end_line: number;\n end_col: number;\n}\n\n/**\n * Find the 1-based position of a predicate name in a QL file.\n * Supports: \n * - predicate name(...) - predicates with no return type\n * - Type name(...) - predicates with return type (e.g., string foo())\n * - name(...) (inside class) - member predicates\n * Returns: { start_line, start_col, end_line, end_col }\n */\nexport async function findPredicatePosition(filepath: string, predicateName: string): Promise {\n try {\n const content = await readFile(filepath, 'utf-8');\n const lines = content.split('\\n');\n const escapedName = predicateName.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&');\n\n for (let i = 0; i < lines.length; i++) {\n const line = lines[i];\n \n // Match predicate definition with the specific predicate name\n // Pattern 1: predicate name(...)\n const predicateKeywordRegex = new RegExp(`\\\\bpredicate\\\\s+(${escapedName})\\\\s*\\\\(`);\n let match = predicateKeywordRegex.exec(line);\n \n // Pattern 2: Type name(...) - predicates with return type\n // Matches: string foo(), int bar(), MyClass baz(), etc.\n // Must start at beginning of line (with optional whitespace) or after certain keywords\n if (!match) {\n const returnTypeRegex = new RegExp(`(?:^|\\\\s)(?:abstract\\\\s+)?(?:cached\\\\s+)?(?:private\\\\s+)?(?:deprecated\\\\s+)?(?:\\\\w+)\\\\s+(${escapedName})\\\\s*\\\\(`);\n match = returnTypeRegex.exec(line);\n }\n \n if (match) {\n const start_line = i + 1; // 1-based line numbering\n // The predicate name is in capture group 1\n const predicateNameStart = match.index + match[0].indexOf(match[1]);\n const start_col = predicateNameStart + 1; // 1-based column numbering\n const end_col = start_col + predicateName.length - 1; // end_col is inclusive\n \n return {\n start_line,\n start_col,\n end_line: start_line,\n end_col\n };\n }\n }\n\n throw new Error(`Predicate name '${predicateName}' not found in file: ${filepath}`);\n } catch (error) {\n if (error instanceof Error && error.message.includes('not found in file')) {\n throw error;\n }\n throw new Error(`Failed to read or parse file ${filepath}: ${error instanceof Error ? error.message : 'Unknown error'}`);\n }\n}\n\n/**\n * Register the find predicate position tool with the MCP server\n */\nexport function registerFindPredicatePositionTool(server: McpServer): void {\n server.tool(\n 'find_predicate_position',\n 'Finds startline, startcol, endline endcol of a predicate for quickeval',\n {\n file: z.string().describe('Path to the .ql file to search'),\n name: z.string().describe('Name of the predicate to find'),\n },\n async ({ file, name }) => {\n try {\n const position = await findPredicatePosition(file, name);\n return {\n content: [{ type: 'text', text: JSON.stringify(position, null, 2) }],\n };\n } catch (error) {\n logger.error('Error finding predicate position:', error);\n return {\n content: [\n {\n type: 'text',\n text: `Error: ${error instanceof Error ? error.message : 'Unknown error'}`,\n },\n ],\n isError: true,\n };\n }\n }\n );\n}", "/**\n * CodeQL find query files tool\n * Discovers and tracks all files related to a CodeQL query\n */\n\nimport { z } from 'zod';\nimport { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport { findCodeQLQueryFiles } from '../../lib/query-file-finder';\nimport { logger } from '../../utils/logger';\n\n/**\n * Register the find_codeql_query_files tool\n */\nexport function registerFindCodeQLQueryFilesTool(server: McpServer): void {\n server.tool(\n 'find_codeql_query_files',\n 'Find and track all files and directories related to a CodeQL query, including resolved metadata',\n {\n queryPath: z.string().describe('Path to the CodeQL query file (.ql)'),\n language: z.string().optional().describe('Programming language (optional, will be inferred if not provided)'),\n resolveMetadata: z.boolean().optional().describe('Whether to resolve query metadata (default: true)')\n },\n async ({ queryPath, language, resolveMetadata }) => {\n try {\n const result = await findCodeQLQueryFiles(\n queryPath,\n language,\n resolveMetadata !== false // Default to true if not specified\n );\n\n return {\n content: [{ type: 'text', text: JSON.stringify(result, null, 2) }]\n };\n } catch (error) {\n logger.error('Error finding CodeQL query files:', error);\n return {\n content: [\n {\n type: 'text',\n text: `Error: ${error instanceof Error ? error.message : 'Unknown error'}`\n }\n ],\n isError: true\n };\n }\n }\n );\n}\n", "/**\n * CodeQL query file finder utilities\n * Handles discovery and tracking of query-related files and directories\n */\n\nimport * as fs from 'fs';\nimport * as path from 'path';\nimport * as yaml from 'js-yaml';\nimport { QueryFileInfo, QueryFilesResult } from '../types/codeql';\nimport { resolveQueryMetadata } from './metadata-resolver';\n\n// Supported CodeQL languages and their file extensions (alphabetically ordered)\nconst LANGUAGE_EXTENSIONS: Record = {\n actions: 'yml',\n cpp: 'cpp',\n csharp: 'cs',\n go: 'go',\n java: 'java',\n javascript: 'js',\n python: 'py',\n ruby: 'rb',\n swift: 'swift',\n typescript: 'ts'\n};\n\nconst KNOWN_LANGUAGES = Object.keys(LANGUAGE_EXTENSIONS);\n\n/**\n * Get the file extension for test code based on language\n */\nfunction getLanguageExtension(language: string): string {\n return LANGUAGE_EXTENSIONS[language.toLowerCase()] || 'txt';\n}\n\n/**\n * Infer the language from the query file's directory structure\n */\nfunction inferLanguageFromPath(queryPath: string): string {\n const parts = queryPath.split(path.sep);\n\n for (const part of parts) {\n if (KNOWN_LANGUAGES.includes(part.toLowerCase())) {\n return part.toLowerCase();\n }\n }\n\n // Default fallback\n return 'unknown';\n}\n\n/**\n * Find the nearest qlpack.yml or codeql-pack.yml file by walking up the directory tree\n */\nfunction findNearestQlpack(startPath: string): string | null {\n let currentPath = startPath;\n const root = path.parse(currentPath).root;\n\n while (currentPath !== root) {\n // Check for codeql-pack.yml first (newer format), then qlpack.yml\n for (const packFile of ['codeql-pack.yml', 'qlpack.yml']) {\n const packPath = path.join(currentPath, packFile);\n if (fs.existsSync(packPath) && fs.statSync(packPath).isFile()) {\n return packPath;\n }\n }\n currentPath = path.dirname(currentPath);\n }\n\n return null;\n}\n\n/**\n * Read and parse qlpack.yml file\n */\nfunction readQlpackMetadata(qlpackPath: string): Record | null {\n try {\n const content = fs.readFileSync(qlpackPath, 'utf-8');\n const parsed = yaml.load(content) as Record;\n return parsed;\n } catch (_error) {\n // If we can't parse it, return null rather than failing\n return null;\n }\n}\n\n/**\n * Check if a file exists and return QueryFileInfo\n */\nfunction checkFile(filePath: string): QueryFileInfo {\n try {\n const exists = fs.existsSync(filePath) && fs.statSync(filePath).isFile();\n return {\n exists,\n path: filePath // Always return path, whether it exists or not\n };\n } catch {\n return {\n exists: false,\n path: filePath // Return the path even on error\n };\n }\n}\n\n/**\n * Check if a directory exists and return QueryFileInfo\n */\nfunction checkDirectory(dirPath: string): QueryFileInfo {\n try {\n const exists = fs.existsSync(dirPath) && fs.statSync(dirPath).isDirectory();\n return {\n exists,\n path: dirPath // Always return path, whether it exists or not\n };\n } catch {\n return {\n exists: false,\n path: dirPath // Return the path even on error\n };\n }\n}\n\n/**\n * Find all test code files in the test directory\n */\nfunction findTestCodeFiles(testDir: string, queryName: string, language: string): string[] {\n if (!fs.existsSync(testDir)) {\n return [];\n }\n\n try {\n const files = fs.readdirSync(testDir);\n const languageExt = getLanguageExtension(language);\n const testFiles: string[] = [];\n\n // Look for files matching the query name or other test code files\n const allValidExtensions = [...new Set([...Object.values(LANGUAGE_EXTENSIONS), 'yaml'])]; // Include yaml as alias for yml\n\n for (const file of files) {\n const filePath = path.join(testDir, file);\n const stat = fs.statSync(filePath);\n\n if (stat.isFile()) {\n // Include the primary test file matching query name\n if (file === `${queryName}.${languageExt}`) {\n testFiles.push(filePath);\n }\n // Include other code files (but not .qlref, .expected, .actual files)\n else if (!file.endsWith('.qlref') && !file.endsWith('.expected') && !file.endsWith('.actual')) {\n const ext = path.extname(file).slice(1);\n if (ext === languageExt || allValidExtensions.includes(ext)) {\n testFiles.push(filePath);\n }\n }\n }\n }\n\n return testFiles;\n } catch {\n return [];\n }\n}\n\n/**\n * Find CodeQL query files and directories based on a query file path\n * Optionally resolves metadata if the query file exists\n */\nexport async function findCodeQLQueryFiles(\n queryFilePath: string,\n language?: string,\n resolveMetadata: boolean = true\n): Promise {\n // Resolve absolute path\n const absoluteQueryPath = path.resolve(queryFilePath);\n\n // Extract query name and directory\n const queryName = path.basename(absoluteQueryPath, '.ql');\n const queryDir = path.dirname(absoluteQueryPath);\n\n // Infer language if not provided\n const detectedLanguage = language || inferLanguageFromPath(absoluteQueryPath);\n\n // Check query file itself\n const queryPath = checkFile(absoluteQueryPath);\n const queryDirectory = checkDirectory(queryDir);\n\n // Check for documentation files\n const mdPath = path.join(queryDir, `${queryName}.md`);\n const qhelpPath = path.join(queryDir, `${queryName}.qhelp`);\n const mdInfo = checkFile(mdPath);\n const qhelpInfo = checkFile(qhelpPath);\n\n const documentationPath: QueryFileInfo = mdInfo.exists ? mdInfo : (qhelpInfo.exists ? qhelpInfo : {\n exists: false,\n path: mdPath // Suggest .md as the default\n });\n\n // Check for specification file\n const qspecPath = path.join(queryDir, `${queryName}.qspec`);\n const specificationPath = checkFile(qspecPath);\n\n // Determine test directory\n // Pattern: if query is in .../src/QueryName/, test should be in .../test/QueryName/\n let testDir: string;\n if (queryDir.includes(`${path.sep}src${path.sep}`)) {\n // Find the last occurrence of /src/ and replace it with /test/\n const parts = queryDir.split(path.sep);\n const srcIndex = parts.lastIndexOf('src');\n if (srcIndex !== -1) {\n parts[srcIndex] = 'test';\n testDir = parts.join(path.sep);\n } else {\n // Fallback in case split didn't find it\n testDir = path.join(path.dirname(queryDir), 'test', queryName);\n }\n } else {\n // Fallback: if not in src directory, construct test dir based on parent\n testDir = path.join(path.dirname(queryDir), 'test', queryName);\n }\n const testDirectory = checkDirectory(testDir);\n\n // Check for .qlref file\n const qlrefPath = path.join(testDir, `${queryName}.qlref`);\n const qlrefInfo = checkFile(qlrefPath);\n\n // Find test code files\n const testCodePaths = findTestCodeFiles(testDir, queryName, detectedLanguage);\n\n // Check for expected results\n const expectedPath = path.join(testDir, `${queryName}.expected`);\n const expectedResultsPath = checkFile(expectedPath);\n\n // Check for actual results\n const actualPath = path.join(testDir, `${queryName}.actual`);\n const actualResultsPath = checkFile(actualPath);\n\n // Check for test database\n const testprojPath = path.join(testDir, `${queryName}.testproj`);\n const testDatabasePath = checkDirectory(testprojPath);\n\n // Determine missing files\n const missingFiles: string[] = [];\n if (!queryPath.exists) missingFiles.push(queryPath.path);\n if (!documentationPath.exists) missingFiles.push(documentationPath.path);\n if (!specificationPath.exists) missingFiles.push(specificationPath.path);\n if (!testDirectory.exists) missingFiles.push(testDirectory.path);\n if (!qlrefInfo.exists) missingFiles.push(qlrefInfo.path);\n if (testCodePaths.length === 0) missingFiles.push(path.join(testDir, `${queryName}.${getLanguageExtension(detectedLanguage)}`));\n if (!expectedResultsPath.exists) missingFiles.push(expectedResultsPath.path);\n\n const allFilesExist = missingFiles.length === 0;\n\n // Resolve metadata if requested and query file exists\n let metadata: { [key: string]: string | string[] } | undefined;\n if (resolveMetadata && queryPath.exists) {\n const resolvedMetadata = await resolveQueryMetadata(absoluteQueryPath);\n if (resolvedMetadata) {\n metadata = resolvedMetadata;\n }\n }\n\n // Resolve pack metadata and directories by finding the nearest qlpack.yml files\n let packMetadata: Record | undefined;\n const queryPackPath = findNearestQlpack(queryDir);\n const queryPackDir = queryPackPath ? path.dirname(queryPackPath) : queryDir;\n if (queryPackPath) {\n const parsed = readQlpackMetadata(queryPackPath);\n if (parsed) {\n packMetadata = parsed;\n }\n }\n\n // Find pack directory for test files\n const testPackPath = findNearestQlpack(testDir);\n const testPackDir = testPackPath ? path.dirname(testPackPath) : testDir;\n\n return {\n queryName,\n language: detectedLanguage,\n\n allFilesExist,\n\n files: {\n query: {\n dir: queryDirectory.path,\n doc: path.basename(documentationPath.path),\n packDir: queryPackDir,\n query: path.basename(queryPath.path),\n spec: path.basename(specificationPath.path)\n },\n test: {\n actual: path.basename(actualResultsPath.path),\n dir: testDirectory.path,\n expected: path.basename(expectedResultsPath.path),\n packDir: testPackDir,\n qlref: path.basename(qlrefInfo.path),\n testCode: testCodePaths,\n testDatabaseDir: testDatabasePath.path\n }\n },\n\n metadata,\n\n missingFiles,\n\n packMetadata,\n\n status: {\n actualResultsExist: actualResultsPath.exists,\n documentationExists: documentationPath.exists,\n expectedResultsExist: expectedResultsPath.exists,\n hasTestCode: testCodePaths.length > 0,\n qlrefExists: qlrefInfo.exists,\n queryExists: queryPath.exists,\n specificationExists: specificationPath.exists,\n testDatabaseDirExists: testDatabasePath.exists,\n testDirectoryExists: testDirectory.exists\n }\n };\n}\n", "\n/*! js-yaml 4.1.1 https://github.com/nodeca/js-yaml @license MIT */\nfunction isNothing(subject) {\n return (typeof subject === 'undefined') || (subject === null);\n}\n\n\nfunction isObject(subject) {\n return (typeof subject === 'object') && (subject !== null);\n}\n\n\nfunction toArray(sequence) {\n if (Array.isArray(sequence)) return sequence;\n else if (isNothing(sequence)) return [];\n\n return [ sequence ];\n}\n\n\nfunction extend(target, source) {\n var index, length, key, sourceKeys;\n\n if (source) {\n sourceKeys = Object.keys(source);\n\n for (index = 0, length = sourceKeys.length; index < length; index += 1) {\n key = sourceKeys[index];\n target[key] = source[key];\n }\n }\n\n return target;\n}\n\n\nfunction repeat(string, count) {\n var result = '', cycle;\n\n for (cycle = 0; cycle < count; cycle += 1) {\n result += string;\n }\n\n return result;\n}\n\n\nfunction isNegativeZero(number) {\n return (number === 0) && (Number.NEGATIVE_INFINITY === 1 / number);\n}\n\n\nvar isNothing_1 = isNothing;\nvar isObject_1 = isObject;\nvar toArray_1 = toArray;\nvar repeat_1 = repeat;\nvar isNegativeZero_1 = isNegativeZero;\nvar extend_1 = extend;\n\nvar common = {\n\tisNothing: isNothing_1,\n\tisObject: isObject_1,\n\ttoArray: toArray_1,\n\trepeat: repeat_1,\n\tisNegativeZero: isNegativeZero_1,\n\textend: extend_1\n};\n\n// YAML error class. http://stackoverflow.com/questions/8458984\n\n\nfunction formatError(exception, compact) {\n var where = '', message = exception.reason || '(unknown reason)';\n\n if (!exception.mark) return message;\n\n if (exception.mark.name) {\n where += 'in \"' + exception.mark.name + '\" ';\n }\n\n where += '(' + (exception.mark.line + 1) + ':' + (exception.mark.column + 1) + ')';\n\n if (!compact && exception.mark.snippet) {\n where += '\\n\\n' + exception.mark.snippet;\n }\n\n return message + ' ' + where;\n}\n\n\nfunction YAMLException$1(reason, mark) {\n // Super constructor\n Error.call(this);\n\n this.name = 'YAMLException';\n this.reason = reason;\n this.mark = mark;\n this.message = formatError(this, false);\n\n // Include stack trace in error object\n if (Error.captureStackTrace) {\n // Chrome and NodeJS\n Error.captureStackTrace(this, this.constructor);\n } else {\n // FF, IE 10+ and Safari 6+. Fallback for others\n this.stack = (new Error()).stack || '';\n }\n}\n\n\n// Inherit from Error\nYAMLException$1.prototype = Object.create(Error.prototype);\nYAMLException$1.prototype.constructor = YAMLException$1;\n\n\nYAMLException$1.prototype.toString = function toString(compact) {\n return this.name + ': ' + formatError(this, compact);\n};\n\n\nvar exception = YAMLException$1;\n\n// get snippet for a single line, respecting maxLength\nfunction getLine(buffer, lineStart, lineEnd, position, maxLineLength) {\n var head = '';\n var tail = '';\n var maxHalfLength = Math.floor(maxLineLength / 2) - 1;\n\n if (position - lineStart > maxHalfLength) {\n head = ' ... ';\n lineStart = position - maxHalfLength + head.length;\n }\n\n if (lineEnd - position > maxHalfLength) {\n tail = ' ...';\n lineEnd = position + maxHalfLength - tail.length;\n }\n\n return {\n str: head + buffer.slice(lineStart, lineEnd).replace(/\\t/g, '\u2192') + tail,\n pos: position - lineStart + head.length // relative position\n };\n}\n\n\nfunction padStart(string, max) {\n return common.repeat(' ', max - string.length) + string;\n}\n\n\nfunction makeSnippet(mark, options) {\n options = Object.create(options || null);\n\n if (!mark.buffer) return null;\n\n if (!options.maxLength) options.maxLength = 79;\n if (typeof options.indent !== 'number') options.indent = 1;\n if (typeof options.linesBefore !== 'number') options.linesBefore = 3;\n if (typeof options.linesAfter !== 'number') options.linesAfter = 2;\n\n var re = /\\r?\\n|\\r|\\0/g;\n var lineStarts = [ 0 ];\n var lineEnds = [];\n var match;\n var foundLineNo = -1;\n\n while ((match = re.exec(mark.buffer))) {\n lineEnds.push(match.index);\n lineStarts.push(match.index + match[0].length);\n\n if (mark.position <= match.index && foundLineNo < 0) {\n foundLineNo = lineStarts.length - 2;\n }\n }\n\n if (foundLineNo < 0) foundLineNo = lineStarts.length - 1;\n\n var result = '', i, line;\n var lineNoLength = Math.min(mark.line + options.linesAfter, lineEnds.length).toString().length;\n var maxLineLength = options.maxLength - (options.indent + lineNoLength + 3);\n\n for (i = 1; i <= options.linesBefore; i++) {\n if (foundLineNo - i < 0) break;\n line = getLine(\n mark.buffer,\n lineStarts[foundLineNo - i],\n lineEnds[foundLineNo - i],\n mark.position - (lineStarts[foundLineNo] - lineStarts[foundLineNo - i]),\n maxLineLength\n );\n result = common.repeat(' ', options.indent) + padStart((mark.line - i + 1).toString(), lineNoLength) +\n ' | ' + line.str + '\\n' + result;\n }\n\n line = getLine(mark.buffer, lineStarts[foundLineNo], lineEnds[foundLineNo], mark.position, maxLineLength);\n result += common.repeat(' ', options.indent) + padStart((mark.line + 1).toString(), lineNoLength) +\n ' | ' + line.str + '\\n';\n result += common.repeat('-', options.indent + lineNoLength + 3 + line.pos) + '^' + '\\n';\n\n for (i = 1; i <= options.linesAfter; i++) {\n if (foundLineNo + i >= lineEnds.length) break;\n line = getLine(\n mark.buffer,\n lineStarts[foundLineNo + i],\n lineEnds[foundLineNo + i],\n mark.position - (lineStarts[foundLineNo] - lineStarts[foundLineNo + i]),\n maxLineLength\n );\n result += common.repeat(' ', options.indent) + padStart((mark.line + i + 1).toString(), lineNoLength) +\n ' | ' + line.str + '\\n';\n }\n\n return result.replace(/\\n$/, '');\n}\n\n\nvar snippet = makeSnippet;\n\nvar TYPE_CONSTRUCTOR_OPTIONS = [\n 'kind',\n 'multi',\n 'resolve',\n 'construct',\n 'instanceOf',\n 'predicate',\n 'represent',\n 'representName',\n 'defaultStyle',\n 'styleAliases'\n];\n\nvar YAML_NODE_KINDS = [\n 'scalar',\n 'sequence',\n 'mapping'\n];\n\nfunction compileStyleAliases(map) {\n var result = {};\n\n if (map !== null) {\n Object.keys(map).forEach(function (style) {\n map[style].forEach(function (alias) {\n result[String(alias)] = style;\n });\n });\n }\n\n return result;\n}\n\nfunction Type$1(tag, options) {\n options = options || {};\n\n Object.keys(options).forEach(function (name) {\n if (TYPE_CONSTRUCTOR_OPTIONS.indexOf(name) === -1) {\n throw new exception('Unknown option \"' + name + '\" is met in definition of \"' + tag + '\" YAML type.');\n }\n });\n\n // TODO: Add tag format check.\n this.options = options; // keep original options in case user wants to extend this type later\n this.tag = tag;\n this.kind = options['kind'] || null;\n this.resolve = options['resolve'] || function () { return true; };\n this.construct = options['construct'] || function (data) { return data; };\n this.instanceOf = options['instanceOf'] || null;\n this.predicate = options['predicate'] || null;\n this.represent = options['represent'] || null;\n this.representName = options['representName'] || null;\n this.defaultStyle = options['defaultStyle'] || null;\n this.multi = options['multi'] || false;\n this.styleAliases = compileStyleAliases(options['styleAliases'] || null);\n\n if (YAML_NODE_KINDS.indexOf(this.kind) === -1) {\n throw new exception('Unknown kind \"' + this.kind + '\" is specified for \"' + tag + '\" YAML type.');\n }\n}\n\nvar type = Type$1;\n\n/*eslint-disable max-len*/\n\n\n\n\n\nfunction compileList(schema, name) {\n var result = [];\n\n schema[name].forEach(function (currentType) {\n var newIndex = result.length;\n\n result.forEach(function (previousType, previousIndex) {\n if (previousType.tag === currentType.tag &&\n previousType.kind === currentType.kind &&\n previousType.multi === currentType.multi) {\n\n newIndex = previousIndex;\n }\n });\n\n result[newIndex] = currentType;\n });\n\n return result;\n}\n\n\nfunction compileMap(/* lists... */) {\n var result = {\n scalar: {},\n sequence: {},\n mapping: {},\n fallback: {},\n multi: {\n scalar: [],\n sequence: [],\n mapping: [],\n fallback: []\n }\n }, index, length;\n\n function collectType(type) {\n if (type.multi) {\n result.multi[type.kind].push(type);\n result.multi['fallback'].push(type);\n } else {\n result[type.kind][type.tag] = result['fallback'][type.tag] = type;\n }\n }\n\n for (index = 0, length = arguments.length; index < length; index += 1) {\n arguments[index].forEach(collectType);\n }\n return result;\n}\n\n\nfunction Schema$1(definition) {\n return this.extend(definition);\n}\n\n\nSchema$1.prototype.extend = function extend(definition) {\n var implicit = [];\n var explicit = [];\n\n if (definition instanceof type) {\n // Schema.extend(type)\n explicit.push(definition);\n\n } else if (Array.isArray(definition)) {\n // Schema.extend([ type1, type2, ... ])\n explicit = explicit.concat(definition);\n\n } else if (definition && (Array.isArray(definition.implicit) || Array.isArray(definition.explicit))) {\n // Schema.extend({ explicit: [ type1, type2, ... ], implicit: [ type1, type2, ... ] })\n if (definition.implicit) implicit = implicit.concat(definition.implicit);\n if (definition.explicit) explicit = explicit.concat(definition.explicit);\n\n } else {\n throw new exception('Schema.extend argument should be a Type, [ Type ], ' +\n 'or a schema definition ({ implicit: [...], explicit: [...] })');\n }\n\n implicit.forEach(function (type$1) {\n if (!(type$1 instanceof type)) {\n throw new exception('Specified list of YAML types (or a single Type object) contains a non-Type object.');\n }\n\n if (type$1.loadKind && type$1.loadKind !== 'scalar') {\n throw new exception('There is a non-scalar type in the implicit list of a schema. Implicit resolving of such types is not supported.');\n }\n\n if (type$1.multi) {\n throw new exception('There is a multi type in the implicit list of a schema. Multi tags can only be listed as explicit.');\n }\n });\n\n explicit.forEach(function (type$1) {\n if (!(type$1 instanceof type)) {\n throw new exception('Specified list of YAML types (or a single Type object) contains a non-Type object.');\n }\n });\n\n var result = Object.create(Schema$1.prototype);\n\n result.implicit = (this.implicit || []).concat(implicit);\n result.explicit = (this.explicit || []).concat(explicit);\n\n result.compiledImplicit = compileList(result, 'implicit');\n result.compiledExplicit = compileList(result, 'explicit');\n result.compiledTypeMap = compileMap(result.compiledImplicit, result.compiledExplicit);\n\n return result;\n};\n\n\nvar schema = Schema$1;\n\nvar str = new type('tag:yaml.org,2002:str', {\n kind: 'scalar',\n construct: function (data) { return data !== null ? data : ''; }\n});\n\nvar seq = new type('tag:yaml.org,2002:seq', {\n kind: 'sequence',\n construct: function (data) { return data !== null ? data : []; }\n});\n\nvar map = new type('tag:yaml.org,2002:map', {\n kind: 'mapping',\n construct: function (data) { return data !== null ? data : {}; }\n});\n\nvar failsafe = new schema({\n explicit: [\n str,\n seq,\n map\n ]\n});\n\nfunction resolveYamlNull(data) {\n if (data === null) return true;\n\n var max = data.length;\n\n return (max === 1 && data === '~') ||\n (max === 4 && (data === 'null' || data === 'Null' || data === 'NULL'));\n}\n\nfunction constructYamlNull() {\n return null;\n}\n\nfunction isNull(object) {\n return object === null;\n}\n\nvar _null = new type('tag:yaml.org,2002:null', {\n kind: 'scalar',\n resolve: resolveYamlNull,\n construct: constructYamlNull,\n predicate: isNull,\n represent: {\n canonical: function () { return '~'; },\n lowercase: function () { return 'null'; },\n uppercase: function () { return 'NULL'; },\n camelcase: function () { return 'Null'; },\n empty: function () { return ''; }\n },\n defaultStyle: 'lowercase'\n});\n\nfunction resolveYamlBoolean(data) {\n if (data === null) return false;\n\n var max = data.length;\n\n return (max === 4 && (data === 'true' || data === 'True' || data === 'TRUE')) ||\n (max === 5 && (data === 'false' || data === 'False' || data === 'FALSE'));\n}\n\nfunction constructYamlBoolean(data) {\n return data === 'true' ||\n data === 'True' ||\n data === 'TRUE';\n}\n\nfunction isBoolean(object) {\n return Object.prototype.toString.call(object) === '[object Boolean]';\n}\n\nvar bool = new type('tag:yaml.org,2002:bool', {\n kind: 'scalar',\n resolve: resolveYamlBoolean,\n construct: constructYamlBoolean,\n predicate: isBoolean,\n represent: {\n lowercase: function (object) { return object ? 'true' : 'false'; },\n uppercase: function (object) { return object ? 'TRUE' : 'FALSE'; },\n camelcase: function (object) { return object ? 'True' : 'False'; }\n },\n defaultStyle: 'lowercase'\n});\n\nfunction isHexCode(c) {\n return ((0x30/* 0 */ <= c) && (c <= 0x39/* 9 */)) ||\n ((0x41/* A */ <= c) && (c <= 0x46/* F */)) ||\n ((0x61/* a */ <= c) && (c <= 0x66/* f */));\n}\n\nfunction isOctCode(c) {\n return ((0x30/* 0 */ <= c) && (c <= 0x37/* 7 */));\n}\n\nfunction isDecCode(c) {\n return ((0x30/* 0 */ <= c) && (c <= 0x39/* 9 */));\n}\n\nfunction resolveYamlInteger(data) {\n if (data === null) return false;\n\n var max = data.length,\n index = 0,\n hasDigits = false,\n ch;\n\n if (!max) return false;\n\n ch = data[index];\n\n // sign\n if (ch === '-' || ch === '+') {\n ch = data[++index];\n }\n\n if (ch === '0') {\n // 0\n if (index + 1 === max) return true;\n ch = data[++index];\n\n // base 2, base 8, base 16\n\n if (ch === 'b') {\n // base 2\n index++;\n\n for (; index < max; index++) {\n ch = data[index];\n if (ch === '_') continue;\n if (ch !== '0' && ch !== '1') return false;\n hasDigits = true;\n }\n return hasDigits && ch !== '_';\n }\n\n\n if (ch === 'x') {\n // base 16\n index++;\n\n for (; index < max; index++) {\n ch = data[index];\n if (ch === '_') continue;\n if (!isHexCode(data.charCodeAt(index))) return false;\n hasDigits = true;\n }\n return hasDigits && ch !== '_';\n }\n\n\n if (ch === 'o') {\n // base 8\n index++;\n\n for (; index < max; index++) {\n ch = data[index];\n if (ch === '_') continue;\n if (!isOctCode(data.charCodeAt(index))) return false;\n hasDigits = true;\n }\n return hasDigits && ch !== '_';\n }\n }\n\n // base 10 (except 0)\n\n // value should not start with `_`;\n if (ch === '_') return false;\n\n for (; index < max; index++) {\n ch = data[index];\n if (ch === '_') continue;\n if (!isDecCode(data.charCodeAt(index))) {\n return false;\n }\n hasDigits = true;\n }\n\n // Should have digits and should not end with `_`\n if (!hasDigits || ch === '_') return false;\n\n return true;\n}\n\nfunction constructYamlInteger(data) {\n var value = data, sign = 1, ch;\n\n if (value.indexOf('_') !== -1) {\n value = value.replace(/_/g, '');\n }\n\n ch = value[0];\n\n if (ch === '-' || ch === '+') {\n if (ch === '-') sign = -1;\n value = value.slice(1);\n ch = value[0];\n }\n\n if (value === '0') return 0;\n\n if (ch === '0') {\n if (value[1] === 'b') return sign * parseInt(value.slice(2), 2);\n if (value[1] === 'x') return sign * parseInt(value.slice(2), 16);\n if (value[1] === 'o') return sign * parseInt(value.slice(2), 8);\n }\n\n return sign * parseInt(value, 10);\n}\n\nfunction isInteger(object) {\n return (Object.prototype.toString.call(object)) === '[object Number]' &&\n (object % 1 === 0 && !common.isNegativeZero(object));\n}\n\nvar int = new type('tag:yaml.org,2002:int', {\n kind: 'scalar',\n resolve: resolveYamlInteger,\n construct: constructYamlInteger,\n predicate: isInteger,\n represent: {\n binary: function (obj) { return obj >= 0 ? '0b' + obj.toString(2) : '-0b' + obj.toString(2).slice(1); },\n octal: function (obj) { return obj >= 0 ? '0o' + obj.toString(8) : '-0o' + obj.toString(8).slice(1); },\n decimal: function (obj) { return obj.toString(10); },\n /* eslint-disable max-len */\n hexadecimal: function (obj) { return obj >= 0 ? '0x' + obj.toString(16).toUpperCase() : '-0x' + obj.toString(16).toUpperCase().slice(1); }\n },\n defaultStyle: 'decimal',\n styleAliases: {\n binary: [ 2, 'bin' ],\n octal: [ 8, 'oct' ],\n decimal: [ 10, 'dec' ],\n hexadecimal: [ 16, 'hex' ]\n }\n});\n\nvar YAML_FLOAT_PATTERN = new RegExp(\n // 2.5e4, 2.5 and integers\n '^(?:[-+]?(?:[0-9][0-9_]*)(?:\\\\.[0-9_]*)?(?:[eE][-+]?[0-9]+)?' +\n // .2e4, .2\n // special case, seems not from spec\n '|\\\\.[0-9_]+(?:[eE][-+]?[0-9]+)?' +\n // .inf\n '|[-+]?\\\\.(?:inf|Inf|INF)' +\n // .nan\n '|\\\\.(?:nan|NaN|NAN))$');\n\nfunction resolveYamlFloat(data) {\n if (data === null) return false;\n\n if (!YAML_FLOAT_PATTERN.test(data) ||\n // Quick hack to not allow integers end with `_`\n // Probably should update regexp & check speed\n data[data.length - 1] === '_') {\n return false;\n }\n\n return true;\n}\n\nfunction constructYamlFloat(data) {\n var value, sign;\n\n value = data.replace(/_/g, '').toLowerCase();\n sign = value[0] === '-' ? -1 : 1;\n\n if ('+-'.indexOf(value[0]) >= 0) {\n value = value.slice(1);\n }\n\n if (value === '.inf') {\n return (sign === 1) ? Number.POSITIVE_INFINITY : Number.NEGATIVE_INFINITY;\n\n } else if (value === '.nan') {\n return NaN;\n }\n return sign * parseFloat(value, 10);\n}\n\n\nvar SCIENTIFIC_WITHOUT_DOT = /^[-+]?[0-9]+e/;\n\nfunction representYamlFloat(object, style) {\n var res;\n\n if (isNaN(object)) {\n switch (style) {\n case 'lowercase': return '.nan';\n case 'uppercase': return '.NAN';\n case 'camelcase': return '.NaN';\n }\n } else if (Number.POSITIVE_INFINITY === object) {\n switch (style) {\n case 'lowercase': return '.inf';\n case 'uppercase': return '.INF';\n case 'camelcase': return '.Inf';\n }\n } else if (Number.NEGATIVE_INFINITY === object) {\n switch (style) {\n case 'lowercase': return '-.inf';\n case 'uppercase': return '-.INF';\n case 'camelcase': return '-.Inf';\n }\n } else if (common.isNegativeZero(object)) {\n return '-0.0';\n }\n\n res = object.toString(10);\n\n // JS stringifier can build scientific format without dots: 5e-100,\n // while YAML requres dot: 5.e-100. Fix it with simple hack\n\n return SCIENTIFIC_WITHOUT_DOT.test(res) ? res.replace('e', '.e') : res;\n}\n\nfunction isFloat(object) {\n return (Object.prototype.toString.call(object) === '[object Number]') &&\n (object % 1 !== 0 || common.isNegativeZero(object));\n}\n\nvar float = new type('tag:yaml.org,2002:float', {\n kind: 'scalar',\n resolve: resolveYamlFloat,\n construct: constructYamlFloat,\n predicate: isFloat,\n represent: representYamlFloat,\n defaultStyle: 'lowercase'\n});\n\nvar json = failsafe.extend({\n implicit: [\n _null,\n bool,\n int,\n float\n ]\n});\n\nvar core = json;\n\nvar YAML_DATE_REGEXP = new RegExp(\n '^([0-9][0-9][0-9][0-9])' + // [1] year\n '-([0-9][0-9])' + // [2] month\n '-([0-9][0-9])$'); // [3] day\n\nvar YAML_TIMESTAMP_REGEXP = new RegExp(\n '^([0-9][0-9][0-9][0-9])' + // [1] year\n '-([0-9][0-9]?)' + // [2] month\n '-([0-9][0-9]?)' + // [3] day\n '(?:[Tt]|[ \\\\t]+)' + // ...\n '([0-9][0-9]?)' + // [4] hour\n ':([0-9][0-9])' + // [5] minute\n ':([0-9][0-9])' + // [6] second\n '(?:\\\\.([0-9]*))?' + // [7] fraction\n '(?:[ \\\\t]*(Z|([-+])([0-9][0-9]?)' + // [8] tz [9] tz_sign [10] tz_hour\n '(?::([0-9][0-9]))?))?$'); // [11] tz_minute\n\nfunction resolveYamlTimestamp(data) {\n if (data === null) return false;\n if (YAML_DATE_REGEXP.exec(data) !== null) return true;\n if (YAML_TIMESTAMP_REGEXP.exec(data) !== null) return true;\n return false;\n}\n\nfunction constructYamlTimestamp(data) {\n var match, year, month, day, hour, minute, second, fraction = 0,\n delta = null, tz_hour, tz_minute, date;\n\n match = YAML_DATE_REGEXP.exec(data);\n if (match === null) match = YAML_TIMESTAMP_REGEXP.exec(data);\n\n if (match === null) throw new Error('Date resolve error');\n\n // match: [1] year [2] month [3] day\n\n year = +(match[1]);\n month = +(match[2]) - 1; // JS month starts with 0\n day = +(match[3]);\n\n if (!match[4]) { // no hour\n return new Date(Date.UTC(year, month, day));\n }\n\n // match: [4] hour [5] minute [6] second [7] fraction\n\n hour = +(match[4]);\n minute = +(match[5]);\n second = +(match[6]);\n\n if (match[7]) {\n fraction = match[7].slice(0, 3);\n while (fraction.length < 3) { // milli-seconds\n fraction += '0';\n }\n fraction = +fraction;\n }\n\n // match: [8] tz [9] tz_sign [10] tz_hour [11] tz_minute\n\n if (match[9]) {\n tz_hour = +(match[10]);\n tz_minute = +(match[11] || 0);\n delta = (tz_hour * 60 + tz_minute) * 60000; // delta in mili-seconds\n if (match[9] === '-') delta = -delta;\n }\n\n date = new Date(Date.UTC(year, month, day, hour, minute, second, fraction));\n\n if (delta) date.setTime(date.getTime() - delta);\n\n return date;\n}\n\nfunction representYamlTimestamp(object /*, style*/) {\n return object.toISOString();\n}\n\nvar timestamp = new type('tag:yaml.org,2002:timestamp', {\n kind: 'scalar',\n resolve: resolveYamlTimestamp,\n construct: constructYamlTimestamp,\n instanceOf: Date,\n represent: representYamlTimestamp\n});\n\nfunction resolveYamlMerge(data) {\n return data === '<<' || data === null;\n}\n\nvar merge = new type('tag:yaml.org,2002:merge', {\n kind: 'scalar',\n resolve: resolveYamlMerge\n});\n\n/*eslint-disable no-bitwise*/\n\n\n\n\n\n// [ 64, 65, 66 ] -> [ padding, CR, LF ]\nvar BASE64_MAP = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=\\n\\r';\n\n\nfunction resolveYamlBinary(data) {\n if (data === null) return false;\n\n var code, idx, bitlen = 0, max = data.length, map = BASE64_MAP;\n\n // Convert one by one.\n for (idx = 0; idx < max; idx++) {\n code = map.indexOf(data.charAt(idx));\n\n // Skip CR/LF\n if (code > 64) continue;\n\n // Fail on illegal characters\n if (code < 0) return false;\n\n bitlen += 6;\n }\n\n // If there are any bits left, source was corrupted\n return (bitlen % 8) === 0;\n}\n\nfunction constructYamlBinary(data) {\n var idx, tailbits,\n input = data.replace(/[\\r\\n=]/g, ''), // remove CR/LF & padding to simplify scan\n max = input.length,\n map = BASE64_MAP,\n bits = 0,\n result = [];\n\n // Collect by 6*4 bits (3 bytes)\n\n for (idx = 0; idx < max; idx++) {\n if ((idx % 4 === 0) && idx) {\n result.push((bits >> 16) & 0xFF);\n result.push((bits >> 8) & 0xFF);\n result.push(bits & 0xFF);\n }\n\n bits = (bits << 6) | map.indexOf(input.charAt(idx));\n }\n\n // Dump tail\n\n tailbits = (max % 4) * 6;\n\n if (tailbits === 0) {\n result.push((bits >> 16) & 0xFF);\n result.push((bits >> 8) & 0xFF);\n result.push(bits & 0xFF);\n } else if (tailbits === 18) {\n result.push((bits >> 10) & 0xFF);\n result.push((bits >> 2) & 0xFF);\n } else if (tailbits === 12) {\n result.push((bits >> 4) & 0xFF);\n }\n\n return new Uint8Array(result);\n}\n\nfunction representYamlBinary(object /*, style*/) {\n var result = '', bits = 0, idx, tail,\n max = object.length,\n map = BASE64_MAP;\n\n // Convert every three bytes to 4 ASCII characters.\n\n for (idx = 0; idx < max; idx++) {\n if ((idx % 3 === 0) && idx) {\n result += map[(bits >> 18) & 0x3F];\n result += map[(bits >> 12) & 0x3F];\n result += map[(bits >> 6) & 0x3F];\n result += map[bits & 0x3F];\n }\n\n bits = (bits << 8) + object[idx];\n }\n\n // Dump tail\n\n tail = max % 3;\n\n if (tail === 0) {\n result += map[(bits >> 18) & 0x3F];\n result += map[(bits >> 12) & 0x3F];\n result += map[(bits >> 6) & 0x3F];\n result += map[bits & 0x3F];\n } else if (tail === 2) {\n result += map[(bits >> 10) & 0x3F];\n result += map[(bits >> 4) & 0x3F];\n result += map[(bits << 2) & 0x3F];\n result += map[64];\n } else if (tail === 1) {\n result += map[(bits >> 2) & 0x3F];\n result += map[(bits << 4) & 0x3F];\n result += map[64];\n result += map[64];\n }\n\n return result;\n}\n\nfunction isBinary(obj) {\n return Object.prototype.toString.call(obj) === '[object Uint8Array]';\n}\n\nvar binary = new type('tag:yaml.org,2002:binary', {\n kind: 'scalar',\n resolve: resolveYamlBinary,\n construct: constructYamlBinary,\n predicate: isBinary,\n represent: representYamlBinary\n});\n\nvar _hasOwnProperty$3 = Object.prototype.hasOwnProperty;\nvar _toString$2 = Object.prototype.toString;\n\nfunction resolveYamlOmap(data) {\n if (data === null) return true;\n\n var objectKeys = [], index, length, pair, pairKey, pairHasKey,\n object = data;\n\n for (index = 0, length = object.length; index < length; index += 1) {\n pair = object[index];\n pairHasKey = false;\n\n if (_toString$2.call(pair) !== '[object Object]') return false;\n\n for (pairKey in pair) {\n if (_hasOwnProperty$3.call(pair, pairKey)) {\n if (!pairHasKey) pairHasKey = true;\n else return false;\n }\n }\n\n if (!pairHasKey) return false;\n\n if (objectKeys.indexOf(pairKey) === -1) objectKeys.push(pairKey);\n else return false;\n }\n\n return true;\n}\n\nfunction constructYamlOmap(data) {\n return data !== null ? data : [];\n}\n\nvar omap = new type('tag:yaml.org,2002:omap', {\n kind: 'sequence',\n resolve: resolveYamlOmap,\n construct: constructYamlOmap\n});\n\nvar _toString$1 = Object.prototype.toString;\n\nfunction resolveYamlPairs(data) {\n if (data === null) return true;\n\n var index, length, pair, keys, result,\n object = data;\n\n result = new Array(object.length);\n\n for (index = 0, length = object.length; index < length; index += 1) {\n pair = object[index];\n\n if (_toString$1.call(pair) !== '[object Object]') return false;\n\n keys = Object.keys(pair);\n\n if (keys.length !== 1) return false;\n\n result[index] = [ keys[0], pair[keys[0]] ];\n }\n\n return true;\n}\n\nfunction constructYamlPairs(data) {\n if (data === null) return [];\n\n var index, length, pair, keys, result,\n object = data;\n\n result = new Array(object.length);\n\n for (index = 0, length = object.length; index < length; index += 1) {\n pair = object[index];\n\n keys = Object.keys(pair);\n\n result[index] = [ keys[0], pair[keys[0]] ];\n }\n\n return result;\n}\n\nvar pairs = new type('tag:yaml.org,2002:pairs', {\n kind: 'sequence',\n resolve: resolveYamlPairs,\n construct: constructYamlPairs\n});\n\nvar _hasOwnProperty$2 = Object.prototype.hasOwnProperty;\n\nfunction resolveYamlSet(data) {\n if (data === null) return true;\n\n var key, object = data;\n\n for (key in object) {\n if (_hasOwnProperty$2.call(object, key)) {\n if (object[key] !== null) return false;\n }\n }\n\n return true;\n}\n\nfunction constructYamlSet(data) {\n return data !== null ? data : {};\n}\n\nvar set = new type('tag:yaml.org,2002:set', {\n kind: 'mapping',\n resolve: resolveYamlSet,\n construct: constructYamlSet\n});\n\nvar _default = core.extend({\n implicit: [\n timestamp,\n merge\n ],\n explicit: [\n binary,\n omap,\n pairs,\n set\n ]\n});\n\n/*eslint-disable max-len,no-use-before-define*/\n\n\n\n\n\n\n\nvar _hasOwnProperty$1 = Object.prototype.hasOwnProperty;\n\n\nvar CONTEXT_FLOW_IN = 1;\nvar CONTEXT_FLOW_OUT = 2;\nvar CONTEXT_BLOCK_IN = 3;\nvar CONTEXT_BLOCK_OUT = 4;\n\n\nvar CHOMPING_CLIP = 1;\nvar CHOMPING_STRIP = 2;\nvar CHOMPING_KEEP = 3;\n\n\nvar PATTERN_NON_PRINTABLE = /[\\x00-\\x08\\x0B\\x0C\\x0E-\\x1F\\x7F-\\x84\\x86-\\x9F\\uFFFE\\uFFFF]|[\\uD800-\\uDBFF](?![\\uDC00-\\uDFFF])|(?:[^\\uD800-\\uDBFF]|^)[\\uDC00-\\uDFFF]/;\nvar PATTERN_NON_ASCII_LINE_BREAKS = /[\\x85\\u2028\\u2029]/;\nvar PATTERN_FLOW_INDICATORS = /[,\\[\\]\\{\\}]/;\nvar PATTERN_TAG_HANDLE = /^(?:!|!!|![a-z\\-]+!)$/i;\nvar PATTERN_TAG_URI = /^(?:!|[^,\\[\\]\\{\\}])(?:%[0-9a-f]{2}|[0-9a-z\\-#;\\/\\?:@&=\\+\\$,_\\.!~\\*'\\(\\)\\[\\]])*$/i;\n\n\nfunction _class(obj) { return Object.prototype.toString.call(obj); }\n\nfunction is_EOL(c) {\n return (c === 0x0A/* LF */) || (c === 0x0D/* CR */);\n}\n\nfunction is_WHITE_SPACE(c) {\n return (c === 0x09/* Tab */) || (c === 0x20/* Space */);\n}\n\nfunction is_WS_OR_EOL(c) {\n return (c === 0x09/* Tab */) ||\n (c === 0x20/* Space */) ||\n (c === 0x0A/* LF */) ||\n (c === 0x0D/* CR */);\n}\n\nfunction is_FLOW_INDICATOR(c) {\n return c === 0x2C/* , */ ||\n c === 0x5B/* [ */ ||\n c === 0x5D/* ] */ ||\n c === 0x7B/* { */ ||\n c === 0x7D/* } */;\n}\n\nfunction fromHexCode(c) {\n var lc;\n\n if ((0x30/* 0 */ <= c) && (c <= 0x39/* 9 */)) {\n return c - 0x30;\n }\n\n /*eslint-disable no-bitwise*/\n lc = c | 0x20;\n\n if ((0x61/* a */ <= lc) && (lc <= 0x66/* f */)) {\n return lc - 0x61 + 10;\n }\n\n return -1;\n}\n\nfunction escapedHexLen(c) {\n if (c === 0x78/* x */) { return 2; }\n if (c === 0x75/* u */) { return 4; }\n if (c === 0x55/* U */) { return 8; }\n return 0;\n}\n\nfunction fromDecimalCode(c) {\n if ((0x30/* 0 */ <= c) && (c <= 0x39/* 9 */)) {\n return c - 0x30;\n }\n\n return -1;\n}\n\nfunction simpleEscapeSequence(c) {\n /* eslint-disable indent */\n return (c === 0x30/* 0 */) ? '\\x00' :\n (c === 0x61/* a */) ? '\\x07' :\n (c === 0x62/* b */) ? '\\x08' :\n (c === 0x74/* t */) ? '\\x09' :\n (c === 0x09/* Tab */) ? '\\x09' :\n (c === 0x6E/* n */) ? '\\x0A' :\n (c === 0x76/* v */) ? '\\x0B' :\n (c === 0x66/* f */) ? '\\x0C' :\n (c === 0x72/* r */) ? '\\x0D' :\n (c === 0x65/* e */) ? '\\x1B' :\n (c === 0x20/* Space */) ? ' ' :\n (c === 0x22/* \" */) ? '\\x22' :\n (c === 0x2F/* / */) ? '/' :\n (c === 0x5C/* \\ */) ? '\\x5C' :\n (c === 0x4E/* N */) ? '\\x85' :\n (c === 0x5F/* _ */) ? '\\xA0' :\n (c === 0x4C/* L */) ? '\\u2028' :\n (c === 0x50/* P */) ? '\\u2029' : '';\n}\n\nfunction charFromCodepoint(c) {\n if (c <= 0xFFFF) {\n return String.fromCharCode(c);\n }\n // Encode UTF-16 surrogate pair\n // https://en.wikipedia.org/wiki/UTF-16#Code_points_U.2B010000_to_U.2B10FFFF\n return String.fromCharCode(\n ((c - 0x010000) >> 10) + 0xD800,\n ((c - 0x010000) & 0x03FF) + 0xDC00\n );\n}\n\n// set a property of a literal object, while protecting against prototype pollution,\n// see https://github.com/nodeca/js-yaml/issues/164 for more details\nfunction setProperty(object, key, value) {\n // used for this specific key only because Object.defineProperty is slow\n if (key === '__proto__') {\n Object.defineProperty(object, key, {\n configurable: true,\n enumerable: true,\n writable: true,\n value: value\n });\n } else {\n object[key] = value;\n }\n}\n\nvar simpleEscapeCheck = new Array(256); // integer, for fast access\nvar simpleEscapeMap = new Array(256);\nfor (var i = 0; i < 256; i++) {\n simpleEscapeCheck[i] = simpleEscapeSequence(i) ? 1 : 0;\n simpleEscapeMap[i] = simpleEscapeSequence(i);\n}\n\n\nfunction State$1(input, options) {\n this.input = input;\n\n this.filename = options['filename'] || null;\n this.schema = options['schema'] || _default;\n this.onWarning = options['onWarning'] || null;\n // (Hidden) Remove? makes the loader to expect YAML 1.1 documents\n // if such documents have no explicit %YAML directive\n this.legacy = options['legacy'] || false;\n\n this.json = options['json'] || false;\n this.listener = options['listener'] || null;\n\n this.implicitTypes = this.schema.compiledImplicit;\n this.typeMap = this.schema.compiledTypeMap;\n\n this.length = input.length;\n this.position = 0;\n this.line = 0;\n this.lineStart = 0;\n this.lineIndent = 0;\n\n // position of first leading tab in the current line,\n // used to make sure there are no tabs in the indentation\n this.firstTabInLine = -1;\n\n this.documents = [];\n\n /*\n this.version;\n this.checkLineBreaks;\n this.tagMap;\n this.anchorMap;\n this.tag;\n this.anchor;\n this.kind;\n this.result;*/\n\n}\n\n\nfunction generateError(state, message) {\n var mark = {\n name: state.filename,\n buffer: state.input.slice(0, -1), // omit trailing \\0\n position: state.position,\n line: state.line,\n column: state.position - state.lineStart\n };\n\n mark.snippet = snippet(mark);\n\n return new exception(message, mark);\n}\n\nfunction throwError(state, message) {\n throw generateError(state, message);\n}\n\nfunction throwWarning(state, message) {\n if (state.onWarning) {\n state.onWarning.call(null, generateError(state, message));\n }\n}\n\n\nvar directiveHandlers = {\n\n YAML: function handleYamlDirective(state, name, args) {\n\n var match, major, minor;\n\n if (state.version !== null) {\n throwError(state, 'duplication of %YAML directive');\n }\n\n if (args.length !== 1) {\n throwError(state, 'YAML directive accepts exactly one argument');\n }\n\n match = /^([0-9]+)\\.([0-9]+)$/.exec(args[0]);\n\n if (match === null) {\n throwError(state, 'ill-formed argument of the YAML directive');\n }\n\n major = parseInt(match[1], 10);\n minor = parseInt(match[2], 10);\n\n if (major !== 1) {\n throwError(state, 'unacceptable YAML version of the document');\n }\n\n state.version = args[0];\n state.checkLineBreaks = (minor < 2);\n\n if (minor !== 1 && minor !== 2) {\n throwWarning(state, 'unsupported YAML version of the document');\n }\n },\n\n TAG: function handleTagDirective(state, name, args) {\n\n var handle, prefix;\n\n if (args.length !== 2) {\n throwError(state, 'TAG directive accepts exactly two arguments');\n }\n\n handle = args[0];\n prefix = args[1];\n\n if (!PATTERN_TAG_HANDLE.test(handle)) {\n throwError(state, 'ill-formed tag handle (first argument) of the TAG directive');\n }\n\n if (_hasOwnProperty$1.call(state.tagMap, handle)) {\n throwError(state, 'there is a previously declared suffix for \"' + handle + '\" tag handle');\n }\n\n if (!PATTERN_TAG_URI.test(prefix)) {\n throwError(state, 'ill-formed tag prefix (second argument) of the TAG directive');\n }\n\n try {\n prefix = decodeURIComponent(prefix);\n } catch (err) {\n throwError(state, 'tag prefix is malformed: ' + prefix);\n }\n\n state.tagMap[handle] = prefix;\n }\n};\n\n\nfunction captureSegment(state, start, end, checkJson) {\n var _position, _length, _character, _result;\n\n if (start < end) {\n _result = state.input.slice(start, end);\n\n if (checkJson) {\n for (_position = 0, _length = _result.length; _position < _length; _position += 1) {\n _character = _result.charCodeAt(_position);\n if (!(_character === 0x09 ||\n (0x20 <= _character && _character <= 0x10FFFF))) {\n throwError(state, 'expected valid JSON character');\n }\n }\n } else if (PATTERN_NON_PRINTABLE.test(_result)) {\n throwError(state, 'the stream contains non-printable characters');\n }\n\n state.result += _result;\n }\n}\n\nfunction mergeMappings(state, destination, source, overridableKeys) {\n var sourceKeys, key, index, quantity;\n\n if (!common.isObject(source)) {\n throwError(state, 'cannot merge mappings; the provided source object is unacceptable');\n }\n\n sourceKeys = Object.keys(source);\n\n for (index = 0, quantity = sourceKeys.length; index < quantity; index += 1) {\n key = sourceKeys[index];\n\n if (!_hasOwnProperty$1.call(destination, key)) {\n setProperty(destination, key, source[key]);\n overridableKeys[key] = true;\n }\n }\n}\n\nfunction storeMappingPair(state, _result, overridableKeys, keyTag, keyNode, valueNode,\n startLine, startLineStart, startPos) {\n\n var index, quantity;\n\n // The output is a plain object here, so keys can only be strings.\n // We need to convert keyNode to a string, but doing so can hang the process\n // (deeply nested arrays that explode exponentially using aliases).\n if (Array.isArray(keyNode)) {\n keyNode = Array.prototype.slice.call(keyNode);\n\n for (index = 0, quantity = keyNode.length; index < quantity; index += 1) {\n if (Array.isArray(keyNode[index])) {\n throwError(state, 'nested arrays are not supported inside keys');\n }\n\n if (typeof keyNode === 'object' && _class(keyNode[index]) === '[object Object]') {\n keyNode[index] = '[object Object]';\n }\n }\n }\n\n // Avoid code execution in load() via toString property\n // (still use its own toString for arrays, timestamps,\n // and whatever user schema extensions happen to have @@toStringTag)\n if (typeof keyNode === 'object' && _class(keyNode) === '[object Object]') {\n keyNode = '[object Object]';\n }\n\n\n keyNode = String(keyNode);\n\n if (_result === null) {\n _result = {};\n }\n\n if (keyTag === 'tag:yaml.org,2002:merge') {\n if (Array.isArray(valueNode)) {\n for (index = 0, quantity = valueNode.length; index < quantity; index += 1) {\n mergeMappings(state, _result, valueNode[index], overridableKeys);\n }\n } else {\n mergeMappings(state, _result, valueNode, overridableKeys);\n }\n } else {\n if (!state.json &&\n !_hasOwnProperty$1.call(overridableKeys, keyNode) &&\n _hasOwnProperty$1.call(_result, keyNode)) {\n state.line = startLine || state.line;\n state.lineStart = startLineStart || state.lineStart;\n state.position = startPos || state.position;\n throwError(state, 'duplicated mapping key');\n }\n\n setProperty(_result, keyNode, valueNode);\n delete overridableKeys[keyNode];\n }\n\n return _result;\n}\n\nfunction readLineBreak(state) {\n var ch;\n\n ch = state.input.charCodeAt(state.position);\n\n if (ch === 0x0A/* LF */) {\n state.position++;\n } else if (ch === 0x0D/* CR */) {\n state.position++;\n if (state.input.charCodeAt(state.position) === 0x0A/* LF */) {\n state.position++;\n }\n } else {\n throwError(state, 'a line break is expected');\n }\n\n state.line += 1;\n state.lineStart = state.position;\n state.firstTabInLine = -1;\n}\n\nfunction skipSeparationSpace(state, allowComments, checkIndent) {\n var lineBreaks = 0,\n ch = state.input.charCodeAt(state.position);\n\n while (ch !== 0) {\n while (is_WHITE_SPACE(ch)) {\n if (ch === 0x09/* Tab */ && state.firstTabInLine === -1) {\n state.firstTabInLine = state.position;\n }\n ch = state.input.charCodeAt(++state.position);\n }\n\n if (allowComments && ch === 0x23/* # */) {\n do {\n ch = state.input.charCodeAt(++state.position);\n } while (ch !== 0x0A/* LF */ && ch !== 0x0D/* CR */ && ch !== 0);\n }\n\n if (is_EOL(ch)) {\n readLineBreak(state);\n\n ch = state.input.charCodeAt(state.position);\n lineBreaks++;\n state.lineIndent = 0;\n\n while (ch === 0x20/* Space */) {\n state.lineIndent++;\n ch = state.input.charCodeAt(++state.position);\n }\n } else {\n break;\n }\n }\n\n if (checkIndent !== -1 && lineBreaks !== 0 && state.lineIndent < checkIndent) {\n throwWarning(state, 'deficient indentation');\n }\n\n return lineBreaks;\n}\n\nfunction testDocumentSeparator(state) {\n var _position = state.position,\n ch;\n\n ch = state.input.charCodeAt(_position);\n\n // Condition state.position === state.lineStart is tested\n // in parent on each call, for efficiency. No needs to test here again.\n if ((ch === 0x2D/* - */ || ch === 0x2E/* . */) &&\n ch === state.input.charCodeAt(_position + 1) &&\n ch === state.input.charCodeAt(_position + 2)) {\n\n _position += 3;\n\n ch = state.input.charCodeAt(_position);\n\n if (ch === 0 || is_WS_OR_EOL(ch)) {\n return true;\n }\n }\n\n return false;\n}\n\nfunction writeFoldedLines(state, count) {\n if (count === 1) {\n state.result += ' ';\n } else if (count > 1) {\n state.result += common.repeat('\\n', count - 1);\n }\n}\n\n\nfunction readPlainScalar(state, nodeIndent, withinFlowCollection) {\n var preceding,\n following,\n captureStart,\n captureEnd,\n hasPendingContent,\n _line,\n _lineStart,\n _lineIndent,\n _kind = state.kind,\n _result = state.result,\n ch;\n\n ch = state.input.charCodeAt(state.position);\n\n if (is_WS_OR_EOL(ch) ||\n is_FLOW_INDICATOR(ch) ||\n ch === 0x23/* # */ ||\n ch === 0x26/* & */ ||\n ch === 0x2A/* * */ ||\n ch === 0x21/* ! */ ||\n ch === 0x7C/* | */ ||\n ch === 0x3E/* > */ ||\n ch === 0x27/* ' */ ||\n ch === 0x22/* \" */ ||\n ch === 0x25/* % */ ||\n ch === 0x40/* @ */ ||\n ch === 0x60/* ` */) {\n return false;\n }\n\n if (ch === 0x3F/* ? */ || ch === 0x2D/* - */) {\n following = state.input.charCodeAt(state.position + 1);\n\n if (is_WS_OR_EOL(following) ||\n withinFlowCollection && is_FLOW_INDICATOR(following)) {\n return false;\n }\n }\n\n state.kind = 'scalar';\n state.result = '';\n captureStart = captureEnd = state.position;\n hasPendingContent = false;\n\n while (ch !== 0) {\n if (ch === 0x3A/* : */) {\n following = state.input.charCodeAt(state.position + 1);\n\n if (is_WS_OR_EOL(following) ||\n withinFlowCollection && is_FLOW_INDICATOR(following)) {\n break;\n }\n\n } else if (ch === 0x23/* # */) {\n preceding = state.input.charCodeAt(state.position - 1);\n\n if (is_WS_OR_EOL(preceding)) {\n break;\n }\n\n } else if ((state.position === state.lineStart && testDocumentSeparator(state)) ||\n withinFlowCollection && is_FLOW_INDICATOR(ch)) {\n break;\n\n } else if (is_EOL(ch)) {\n _line = state.line;\n _lineStart = state.lineStart;\n _lineIndent = state.lineIndent;\n skipSeparationSpace(state, false, -1);\n\n if (state.lineIndent >= nodeIndent) {\n hasPendingContent = true;\n ch = state.input.charCodeAt(state.position);\n continue;\n } else {\n state.position = captureEnd;\n state.line = _line;\n state.lineStart = _lineStart;\n state.lineIndent = _lineIndent;\n break;\n }\n }\n\n if (hasPendingContent) {\n captureSegment(state, captureStart, captureEnd, false);\n writeFoldedLines(state, state.line - _line);\n captureStart = captureEnd = state.position;\n hasPendingContent = false;\n }\n\n if (!is_WHITE_SPACE(ch)) {\n captureEnd = state.position + 1;\n }\n\n ch = state.input.charCodeAt(++state.position);\n }\n\n captureSegment(state, captureStart, captureEnd, false);\n\n if (state.result) {\n return true;\n }\n\n state.kind = _kind;\n state.result = _result;\n return false;\n}\n\nfunction readSingleQuotedScalar(state, nodeIndent) {\n var ch,\n captureStart, captureEnd;\n\n ch = state.input.charCodeAt(state.position);\n\n if (ch !== 0x27/* ' */) {\n return false;\n }\n\n state.kind = 'scalar';\n state.result = '';\n state.position++;\n captureStart = captureEnd = state.position;\n\n while ((ch = state.input.charCodeAt(state.position)) !== 0) {\n if (ch === 0x27/* ' */) {\n captureSegment(state, captureStart, state.position, true);\n ch = state.input.charCodeAt(++state.position);\n\n if (ch === 0x27/* ' */) {\n captureStart = state.position;\n state.position++;\n captureEnd = state.position;\n } else {\n return true;\n }\n\n } else if (is_EOL(ch)) {\n captureSegment(state, captureStart, captureEnd, true);\n writeFoldedLines(state, skipSeparationSpace(state, false, nodeIndent));\n captureStart = captureEnd = state.position;\n\n } else if (state.position === state.lineStart && testDocumentSeparator(state)) {\n throwError(state, 'unexpected end of the document within a single quoted scalar');\n\n } else {\n state.position++;\n captureEnd = state.position;\n }\n }\n\n throwError(state, 'unexpected end of the stream within a single quoted scalar');\n}\n\nfunction readDoubleQuotedScalar(state, nodeIndent) {\n var captureStart,\n captureEnd,\n hexLength,\n hexResult,\n tmp,\n ch;\n\n ch = state.input.charCodeAt(state.position);\n\n if (ch !== 0x22/* \" */) {\n return false;\n }\n\n state.kind = 'scalar';\n state.result = '';\n state.position++;\n captureStart = captureEnd = state.position;\n\n while ((ch = state.input.charCodeAt(state.position)) !== 0) {\n if (ch === 0x22/* \" */) {\n captureSegment(state, captureStart, state.position, true);\n state.position++;\n return true;\n\n } else if (ch === 0x5C/* \\ */) {\n captureSegment(state, captureStart, state.position, true);\n ch = state.input.charCodeAt(++state.position);\n\n if (is_EOL(ch)) {\n skipSeparationSpace(state, false, nodeIndent);\n\n // TODO: rework to inline fn with no type cast?\n } else if (ch < 256 && simpleEscapeCheck[ch]) {\n state.result += simpleEscapeMap[ch];\n state.position++;\n\n } else if ((tmp = escapedHexLen(ch)) > 0) {\n hexLength = tmp;\n hexResult = 0;\n\n for (; hexLength > 0; hexLength--) {\n ch = state.input.charCodeAt(++state.position);\n\n if ((tmp = fromHexCode(ch)) >= 0) {\n hexResult = (hexResult << 4) + tmp;\n\n } else {\n throwError(state, 'expected hexadecimal character');\n }\n }\n\n state.result += charFromCodepoint(hexResult);\n\n state.position++;\n\n } else {\n throwError(state, 'unknown escape sequence');\n }\n\n captureStart = captureEnd = state.position;\n\n } else if (is_EOL(ch)) {\n captureSegment(state, captureStart, captureEnd, true);\n writeFoldedLines(state, skipSeparationSpace(state, false, nodeIndent));\n captureStart = captureEnd = state.position;\n\n } else if (state.position === state.lineStart && testDocumentSeparator(state)) {\n throwError(state, 'unexpected end of the document within a double quoted scalar');\n\n } else {\n state.position++;\n captureEnd = state.position;\n }\n }\n\n throwError(state, 'unexpected end of the stream within a double quoted scalar');\n}\n\nfunction readFlowCollection(state, nodeIndent) {\n var readNext = true,\n _line,\n _lineStart,\n _pos,\n _tag = state.tag,\n _result,\n _anchor = state.anchor,\n following,\n terminator,\n isPair,\n isExplicitPair,\n isMapping,\n overridableKeys = Object.create(null),\n keyNode,\n keyTag,\n valueNode,\n ch;\n\n ch = state.input.charCodeAt(state.position);\n\n if (ch === 0x5B/* [ */) {\n terminator = 0x5D;/* ] */\n isMapping = false;\n _result = [];\n } else if (ch === 0x7B/* { */) {\n terminator = 0x7D;/* } */\n isMapping = true;\n _result = {};\n } else {\n return false;\n }\n\n if (state.anchor !== null) {\n state.anchorMap[state.anchor] = _result;\n }\n\n ch = state.input.charCodeAt(++state.position);\n\n while (ch !== 0) {\n skipSeparationSpace(state, true, nodeIndent);\n\n ch = state.input.charCodeAt(state.position);\n\n if (ch === terminator) {\n state.position++;\n state.tag = _tag;\n state.anchor = _anchor;\n state.kind = isMapping ? 'mapping' : 'sequence';\n state.result = _result;\n return true;\n } else if (!readNext) {\n throwError(state, 'missed comma between flow collection entries');\n } else if (ch === 0x2C/* , */) {\n // \"flow collection entries can never be completely empty\", as per YAML 1.2, section 7.4\n throwError(state, \"expected the node content, but found ','\");\n }\n\n keyTag = keyNode = valueNode = null;\n isPair = isExplicitPair = false;\n\n if (ch === 0x3F/* ? */) {\n following = state.input.charCodeAt(state.position + 1);\n\n if (is_WS_OR_EOL(following)) {\n isPair = isExplicitPair = true;\n state.position++;\n skipSeparationSpace(state, true, nodeIndent);\n }\n }\n\n _line = state.line; // Save the current line.\n _lineStart = state.lineStart;\n _pos = state.position;\n composeNode(state, nodeIndent, CONTEXT_FLOW_IN, false, true);\n keyTag = state.tag;\n keyNode = state.result;\n skipSeparationSpace(state, true, nodeIndent);\n\n ch = state.input.charCodeAt(state.position);\n\n if ((isExplicitPair || state.line === _line) && ch === 0x3A/* : */) {\n isPair = true;\n ch = state.input.charCodeAt(++state.position);\n skipSeparationSpace(state, true, nodeIndent);\n composeNode(state, nodeIndent, CONTEXT_FLOW_IN, false, true);\n valueNode = state.result;\n }\n\n if (isMapping) {\n storeMappingPair(state, _result, overridableKeys, keyTag, keyNode, valueNode, _line, _lineStart, _pos);\n } else if (isPair) {\n _result.push(storeMappingPair(state, null, overridableKeys, keyTag, keyNode, valueNode, _line, _lineStart, _pos));\n } else {\n _result.push(keyNode);\n }\n\n skipSeparationSpace(state, true, nodeIndent);\n\n ch = state.input.charCodeAt(state.position);\n\n if (ch === 0x2C/* , */) {\n readNext = true;\n ch = state.input.charCodeAt(++state.position);\n } else {\n readNext = false;\n }\n }\n\n throwError(state, 'unexpected end of the stream within a flow collection');\n}\n\nfunction readBlockScalar(state, nodeIndent) {\n var captureStart,\n folding,\n chomping = CHOMPING_CLIP,\n didReadContent = false,\n detectedIndent = false,\n textIndent = nodeIndent,\n emptyLines = 0,\n atMoreIndented = false,\n tmp,\n ch;\n\n ch = state.input.charCodeAt(state.position);\n\n if (ch === 0x7C/* | */) {\n folding = false;\n } else if (ch === 0x3E/* > */) {\n folding = true;\n } else {\n return false;\n }\n\n state.kind = 'scalar';\n state.result = '';\n\n while (ch !== 0) {\n ch = state.input.charCodeAt(++state.position);\n\n if (ch === 0x2B/* + */ || ch === 0x2D/* - */) {\n if (CHOMPING_CLIP === chomping) {\n chomping = (ch === 0x2B/* + */) ? CHOMPING_KEEP : CHOMPING_STRIP;\n } else {\n throwError(state, 'repeat of a chomping mode identifier');\n }\n\n } else if ((tmp = fromDecimalCode(ch)) >= 0) {\n if (tmp === 0) {\n throwError(state, 'bad explicit indentation width of a block scalar; it cannot be less than one');\n } else if (!detectedIndent) {\n textIndent = nodeIndent + tmp - 1;\n detectedIndent = true;\n } else {\n throwError(state, 'repeat of an indentation width identifier');\n }\n\n } else {\n break;\n }\n }\n\n if (is_WHITE_SPACE(ch)) {\n do { ch = state.input.charCodeAt(++state.position); }\n while (is_WHITE_SPACE(ch));\n\n if (ch === 0x23/* # */) {\n do { ch = state.input.charCodeAt(++state.position); }\n while (!is_EOL(ch) && (ch !== 0));\n }\n }\n\n while (ch !== 0) {\n readLineBreak(state);\n state.lineIndent = 0;\n\n ch = state.input.charCodeAt(state.position);\n\n while ((!detectedIndent || state.lineIndent < textIndent) &&\n (ch === 0x20/* Space */)) {\n state.lineIndent++;\n ch = state.input.charCodeAt(++state.position);\n }\n\n if (!detectedIndent && state.lineIndent > textIndent) {\n textIndent = state.lineIndent;\n }\n\n if (is_EOL(ch)) {\n emptyLines++;\n continue;\n }\n\n // End of the scalar.\n if (state.lineIndent < textIndent) {\n\n // Perform the chomping.\n if (chomping === CHOMPING_KEEP) {\n state.result += common.repeat('\\n', didReadContent ? 1 + emptyLines : emptyLines);\n } else if (chomping === CHOMPING_CLIP) {\n if (didReadContent) { // i.e. only if the scalar is not empty.\n state.result += '\\n';\n }\n }\n\n // Break this `while` cycle and go to the funciton's epilogue.\n break;\n }\n\n // Folded style: use fancy rules to handle line breaks.\n if (folding) {\n\n // Lines starting with white space characters (more-indented lines) are not folded.\n if (is_WHITE_SPACE(ch)) {\n atMoreIndented = true;\n // except for the first content line (cf. Example 8.1)\n state.result += common.repeat('\\n', didReadContent ? 1 + emptyLines : emptyLines);\n\n // End of more-indented block.\n } else if (atMoreIndented) {\n atMoreIndented = false;\n state.result += common.repeat('\\n', emptyLines + 1);\n\n // Just one line break - perceive as the same line.\n } else if (emptyLines === 0) {\n if (didReadContent) { // i.e. only if we have already read some scalar content.\n state.result += ' ';\n }\n\n // Several line breaks - perceive as different lines.\n } else {\n state.result += common.repeat('\\n', emptyLines);\n }\n\n // Literal style: just add exact number of line breaks between content lines.\n } else {\n // Keep all line breaks except the header line break.\n state.result += common.repeat('\\n', didReadContent ? 1 + emptyLines : emptyLines);\n }\n\n didReadContent = true;\n detectedIndent = true;\n emptyLines = 0;\n captureStart = state.position;\n\n while (!is_EOL(ch) && (ch !== 0)) {\n ch = state.input.charCodeAt(++state.position);\n }\n\n captureSegment(state, captureStart, state.position, false);\n }\n\n return true;\n}\n\nfunction readBlockSequence(state, nodeIndent) {\n var _line,\n _tag = state.tag,\n _anchor = state.anchor,\n _result = [],\n following,\n detected = false,\n ch;\n\n // there is a leading tab before this token, so it can't be a block sequence/mapping;\n // it can still be flow sequence/mapping or a scalar\n if (state.firstTabInLine !== -1) return false;\n\n if (state.anchor !== null) {\n state.anchorMap[state.anchor] = _result;\n }\n\n ch = state.input.charCodeAt(state.position);\n\n while (ch !== 0) {\n if (state.firstTabInLine !== -1) {\n state.position = state.firstTabInLine;\n throwError(state, 'tab characters must not be used in indentation');\n }\n\n if (ch !== 0x2D/* - */) {\n break;\n }\n\n following = state.input.charCodeAt(state.position + 1);\n\n if (!is_WS_OR_EOL(following)) {\n break;\n }\n\n detected = true;\n state.position++;\n\n if (skipSeparationSpace(state, true, -1)) {\n if (state.lineIndent <= nodeIndent) {\n _result.push(null);\n ch = state.input.charCodeAt(state.position);\n continue;\n }\n }\n\n _line = state.line;\n composeNode(state, nodeIndent, CONTEXT_BLOCK_IN, false, true);\n _result.push(state.result);\n skipSeparationSpace(state, true, -1);\n\n ch = state.input.charCodeAt(state.position);\n\n if ((state.line === _line || state.lineIndent > nodeIndent) && (ch !== 0)) {\n throwError(state, 'bad indentation of a sequence entry');\n } else if (state.lineIndent < nodeIndent) {\n break;\n }\n }\n\n if (detected) {\n state.tag = _tag;\n state.anchor = _anchor;\n state.kind = 'sequence';\n state.result = _result;\n return true;\n }\n return false;\n}\n\nfunction readBlockMapping(state, nodeIndent, flowIndent) {\n var following,\n allowCompact,\n _line,\n _keyLine,\n _keyLineStart,\n _keyPos,\n _tag = state.tag,\n _anchor = state.anchor,\n _result = {},\n overridableKeys = Object.create(null),\n keyTag = null,\n keyNode = null,\n valueNode = null,\n atExplicitKey = false,\n detected = false,\n ch;\n\n // there is a leading tab before this token, so it can't be a block sequence/mapping;\n // it can still be flow sequence/mapping or a scalar\n if (state.firstTabInLine !== -1) return false;\n\n if (state.anchor !== null) {\n state.anchorMap[state.anchor] = _result;\n }\n\n ch = state.input.charCodeAt(state.position);\n\n while (ch !== 0) {\n if (!atExplicitKey && state.firstTabInLine !== -1) {\n state.position = state.firstTabInLine;\n throwError(state, 'tab characters must not be used in indentation');\n }\n\n following = state.input.charCodeAt(state.position + 1);\n _line = state.line; // Save the current line.\n\n //\n // Explicit notation case. There are two separate blocks:\n // first for the key (denoted by \"?\") and second for the value (denoted by \":\")\n //\n if ((ch === 0x3F/* ? */ || ch === 0x3A/* : */) && is_WS_OR_EOL(following)) {\n\n if (ch === 0x3F/* ? */) {\n if (atExplicitKey) {\n storeMappingPair(state, _result, overridableKeys, keyTag, keyNode, null, _keyLine, _keyLineStart, _keyPos);\n keyTag = keyNode = valueNode = null;\n }\n\n detected = true;\n atExplicitKey = true;\n allowCompact = true;\n\n } else if (atExplicitKey) {\n // i.e. 0x3A/* : */ === character after the explicit key.\n atExplicitKey = false;\n allowCompact = true;\n\n } else {\n throwError(state, 'incomplete explicit mapping pair; a key node is missed; or followed by a non-tabulated empty line');\n }\n\n state.position += 1;\n ch = following;\n\n //\n // Implicit notation case. Flow-style node as the key first, then \":\", and the value.\n //\n } else {\n _keyLine = state.line;\n _keyLineStart = state.lineStart;\n _keyPos = state.position;\n\n if (!composeNode(state, flowIndent, CONTEXT_FLOW_OUT, false, true)) {\n // Neither implicit nor explicit notation.\n // Reading is done. Go to the epilogue.\n break;\n }\n\n if (state.line === _line) {\n ch = state.input.charCodeAt(state.position);\n\n while (is_WHITE_SPACE(ch)) {\n ch = state.input.charCodeAt(++state.position);\n }\n\n if (ch === 0x3A/* : */) {\n ch = state.input.charCodeAt(++state.position);\n\n if (!is_WS_OR_EOL(ch)) {\n throwError(state, 'a whitespace character is expected after the key-value separator within a block mapping');\n }\n\n if (atExplicitKey) {\n storeMappingPair(state, _result, overridableKeys, keyTag, keyNode, null, _keyLine, _keyLineStart, _keyPos);\n keyTag = keyNode = valueNode = null;\n }\n\n detected = true;\n atExplicitKey = false;\n allowCompact = false;\n keyTag = state.tag;\n keyNode = state.result;\n\n } else if (detected) {\n throwError(state, 'can not read an implicit mapping pair; a colon is missed');\n\n } else {\n state.tag = _tag;\n state.anchor = _anchor;\n return true; // Keep the result of `composeNode`.\n }\n\n } else if (detected) {\n throwError(state, 'can not read a block mapping entry; a multiline key may not be an implicit key');\n\n } else {\n state.tag = _tag;\n state.anchor = _anchor;\n return true; // Keep the result of `composeNode`.\n }\n }\n\n //\n // Common reading code for both explicit and implicit notations.\n //\n if (state.line === _line || state.lineIndent > nodeIndent) {\n if (atExplicitKey) {\n _keyLine = state.line;\n _keyLineStart = state.lineStart;\n _keyPos = state.position;\n }\n\n if (composeNode(state, nodeIndent, CONTEXT_BLOCK_OUT, true, allowCompact)) {\n if (atExplicitKey) {\n keyNode = state.result;\n } else {\n valueNode = state.result;\n }\n }\n\n if (!atExplicitKey) {\n storeMappingPair(state, _result, overridableKeys, keyTag, keyNode, valueNode, _keyLine, _keyLineStart, _keyPos);\n keyTag = keyNode = valueNode = null;\n }\n\n skipSeparationSpace(state, true, -1);\n ch = state.input.charCodeAt(state.position);\n }\n\n if ((state.line === _line || state.lineIndent > nodeIndent) && (ch !== 0)) {\n throwError(state, 'bad indentation of a mapping entry');\n } else if (state.lineIndent < nodeIndent) {\n break;\n }\n }\n\n //\n // Epilogue.\n //\n\n // Special case: last mapping's node contains only the key in explicit notation.\n if (atExplicitKey) {\n storeMappingPair(state, _result, overridableKeys, keyTag, keyNode, null, _keyLine, _keyLineStart, _keyPos);\n }\n\n // Expose the resulting mapping.\n if (detected) {\n state.tag = _tag;\n state.anchor = _anchor;\n state.kind = 'mapping';\n state.result = _result;\n }\n\n return detected;\n}\n\nfunction readTagProperty(state) {\n var _position,\n isVerbatim = false,\n isNamed = false,\n tagHandle,\n tagName,\n ch;\n\n ch = state.input.charCodeAt(state.position);\n\n if (ch !== 0x21/* ! */) return false;\n\n if (state.tag !== null) {\n throwError(state, 'duplication of a tag property');\n }\n\n ch = state.input.charCodeAt(++state.position);\n\n if (ch === 0x3C/* < */) {\n isVerbatim = true;\n ch = state.input.charCodeAt(++state.position);\n\n } else if (ch === 0x21/* ! */) {\n isNamed = true;\n tagHandle = '!!';\n ch = state.input.charCodeAt(++state.position);\n\n } else {\n tagHandle = '!';\n }\n\n _position = state.position;\n\n if (isVerbatim) {\n do { ch = state.input.charCodeAt(++state.position); }\n while (ch !== 0 && ch !== 0x3E/* > */);\n\n if (state.position < state.length) {\n tagName = state.input.slice(_position, state.position);\n ch = state.input.charCodeAt(++state.position);\n } else {\n throwError(state, 'unexpected end of the stream within a verbatim tag');\n }\n } else {\n while (ch !== 0 && !is_WS_OR_EOL(ch)) {\n\n if (ch === 0x21/* ! */) {\n if (!isNamed) {\n tagHandle = state.input.slice(_position - 1, state.position + 1);\n\n if (!PATTERN_TAG_HANDLE.test(tagHandle)) {\n throwError(state, 'named tag handle cannot contain such characters');\n }\n\n isNamed = true;\n _position = state.position + 1;\n } else {\n throwError(state, 'tag suffix cannot contain exclamation marks');\n }\n }\n\n ch = state.input.charCodeAt(++state.position);\n }\n\n tagName = state.input.slice(_position, state.position);\n\n if (PATTERN_FLOW_INDICATORS.test(tagName)) {\n throwError(state, 'tag suffix cannot contain flow indicator characters');\n }\n }\n\n if (tagName && !PATTERN_TAG_URI.test(tagName)) {\n throwError(state, 'tag name cannot contain such characters: ' + tagName);\n }\n\n try {\n tagName = decodeURIComponent(tagName);\n } catch (err) {\n throwError(state, 'tag name is malformed: ' + tagName);\n }\n\n if (isVerbatim) {\n state.tag = tagName;\n\n } else if (_hasOwnProperty$1.call(state.tagMap, tagHandle)) {\n state.tag = state.tagMap[tagHandle] + tagName;\n\n } else if (tagHandle === '!') {\n state.tag = '!' + tagName;\n\n } else if (tagHandle === '!!') {\n state.tag = 'tag:yaml.org,2002:' + tagName;\n\n } else {\n throwError(state, 'undeclared tag handle \"' + tagHandle + '\"');\n }\n\n return true;\n}\n\nfunction readAnchorProperty(state) {\n var _position,\n ch;\n\n ch = state.input.charCodeAt(state.position);\n\n if (ch !== 0x26/* & */) return false;\n\n if (state.anchor !== null) {\n throwError(state, 'duplication of an anchor property');\n }\n\n ch = state.input.charCodeAt(++state.position);\n _position = state.position;\n\n while (ch !== 0 && !is_WS_OR_EOL(ch) && !is_FLOW_INDICATOR(ch)) {\n ch = state.input.charCodeAt(++state.position);\n }\n\n if (state.position === _position) {\n throwError(state, 'name of an anchor node must contain at least one character');\n }\n\n state.anchor = state.input.slice(_position, state.position);\n return true;\n}\n\nfunction readAlias(state) {\n var _position, alias,\n ch;\n\n ch = state.input.charCodeAt(state.position);\n\n if (ch !== 0x2A/* * */) return false;\n\n ch = state.input.charCodeAt(++state.position);\n _position = state.position;\n\n while (ch !== 0 && !is_WS_OR_EOL(ch) && !is_FLOW_INDICATOR(ch)) {\n ch = state.input.charCodeAt(++state.position);\n }\n\n if (state.position === _position) {\n throwError(state, 'name of an alias node must contain at least one character');\n }\n\n alias = state.input.slice(_position, state.position);\n\n if (!_hasOwnProperty$1.call(state.anchorMap, alias)) {\n throwError(state, 'unidentified alias \"' + alias + '\"');\n }\n\n state.result = state.anchorMap[alias];\n skipSeparationSpace(state, true, -1);\n return true;\n}\n\nfunction composeNode(state, parentIndent, nodeContext, allowToSeek, allowCompact) {\n var allowBlockStyles,\n allowBlockScalars,\n allowBlockCollections,\n indentStatus = 1, // 1: this>parent, 0: this=parent, -1: this parentIndent) {\n indentStatus = 1;\n } else if (state.lineIndent === parentIndent) {\n indentStatus = 0;\n } else if (state.lineIndent < parentIndent) {\n indentStatus = -1;\n }\n }\n }\n\n if (indentStatus === 1) {\n while (readTagProperty(state) || readAnchorProperty(state)) {\n if (skipSeparationSpace(state, true, -1)) {\n atNewLine = true;\n allowBlockCollections = allowBlockStyles;\n\n if (state.lineIndent > parentIndent) {\n indentStatus = 1;\n } else if (state.lineIndent === parentIndent) {\n indentStatus = 0;\n } else if (state.lineIndent < parentIndent) {\n indentStatus = -1;\n }\n } else {\n allowBlockCollections = false;\n }\n }\n }\n\n if (allowBlockCollections) {\n allowBlockCollections = atNewLine || allowCompact;\n }\n\n if (indentStatus === 1 || CONTEXT_BLOCK_OUT === nodeContext) {\n if (CONTEXT_FLOW_IN === nodeContext || CONTEXT_FLOW_OUT === nodeContext) {\n flowIndent = parentIndent;\n } else {\n flowIndent = parentIndent + 1;\n }\n\n blockIndent = state.position - state.lineStart;\n\n if (indentStatus === 1) {\n if (allowBlockCollections &&\n (readBlockSequence(state, blockIndent) ||\n readBlockMapping(state, blockIndent, flowIndent)) ||\n readFlowCollection(state, flowIndent)) {\n hasContent = true;\n } else {\n if ((allowBlockScalars && readBlockScalar(state, flowIndent)) ||\n readSingleQuotedScalar(state, flowIndent) ||\n readDoubleQuotedScalar(state, flowIndent)) {\n hasContent = true;\n\n } else if (readAlias(state)) {\n hasContent = true;\n\n if (state.tag !== null || state.anchor !== null) {\n throwError(state, 'alias node should not have any properties');\n }\n\n } else if (readPlainScalar(state, flowIndent, CONTEXT_FLOW_IN === nodeContext)) {\n hasContent = true;\n\n if (state.tag === null) {\n state.tag = '?';\n }\n }\n\n if (state.anchor !== null) {\n state.anchorMap[state.anchor] = state.result;\n }\n }\n } else if (indentStatus === 0) {\n // Special case: block sequences are allowed to have same indentation level as the parent.\n // http://www.yaml.org/spec/1.2/spec.html#id2799784\n hasContent = allowBlockCollections && readBlockSequence(state, blockIndent);\n }\n }\n\n if (state.tag === null) {\n if (state.anchor !== null) {\n state.anchorMap[state.anchor] = state.result;\n }\n\n } else if (state.tag === '?') {\n // Implicit resolving is not allowed for non-scalar types, and '?'\n // non-specific tag is only automatically assigned to plain scalars.\n //\n // We only need to check kind conformity in case user explicitly assigns '?'\n // tag, for example like this: \"! [0]\"\n //\n if (state.result !== null && state.kind !== 'scalar') {\n throwError(state, 'unacceptable node kind for ! tag; it should be \"scalar\", not \"' + state.kind + '\"');\n }\n\n for (typeIndex = 0, typeQuantity = state.implicitTypes.length; typeIndex < typeQuantity; typeIndex += 1) {\n type = state.implicitTypes[typeIndex];\n\n if (type.resolve(state.result)) { // `state.result` updated in resolver if matched\n state.result = type.construct(state.result);\n state.tag = type.tag;\n if (state.anchor !== null) {\n state.anchorMap[state.anchor] = state.result;\n }\n break;\n }\n }\n } else if (state.tag !== '!') {\n if (_hasOwnProperty$1.call(state.typeMap[state.kind || 'fallback'], state.tag)) {\n type = state.typeMap[state.kind || 'fallback'][state.tag];\n } else {\n // looking for multi type\n type = null;\n typeList = state.typeMap.multi[state.kind || 'fallback'];\n\n for (typeIndex = 0, typeQuantity = typeList.length; typeIndex < typeQuantity; typeIndex += 1) {\n if (state.tag.slice(0, typeList[typeIndex].tag.length) === typeList[typeIndex].tag) {\n type = typeList[typeIndex];\n break;\n }\n }\n }\n\n if (!type) {\n throwError(state, 'unknown tag !<' + state.tag + '>');\n }\n\n if (state.result !== null && type.kind !== state.kind) {\n throwError(state, 'unacceptable node kind for !<' + state.tag + '> tag; it should be \"' + type.kind + '\", not \"' + state.kind + '\"');\n }\n\n if (!type.resolve(state.result, state.tag)) { // `state.result` updated in resolver if matched\n throwError(state, 'cannot resolve a node with !<' + state.tag + '> explicit tag');\n } else {\n state.result = type.construct(state.result, state.tag);\n if (state.anchor !== null) {\n state.anchorMap[state.anchor] = state.result;\n }\n }\n }\n\n if (state.listener !== null) {\n state.listener('close', state);\n }\n return state.tag !== null || state.anchor !== null || hasContent;\n}\n\nfunction readDocument(state) {\n var documentStart = state.position,\n _position,\n directiveName,\n directiveArgs,\n hasDirectives = false,\n ch;\n\n state.version = null;\n state.checkLineBreaks = state.legacy;\n state.tagMap = Object.create(null);\n state.anchorMap = Object.create(null);\n\n while ((ch = state.input.charCodeAt(state.position)) !== 0) {\n skipSeparationSpace(state, true, -1);\n\n ch = state.input.charCodeAt(state.position);\n\n if (state.lineIndent > 0 || ch !== 0x25/* % */) {\n break;\n }\n\n hasDirectives = true;\n ch = state.input.charCodeAt(++state.position);\n _position = state.position;\n\n while (ch !== 0 && !is_WS_OR_EOL(ch)) {\n ch = state.input.charCodeAt(++state.position);\n }\n\n directiveName = state.input.slice(_position, state.position);\n directiveArgs = [];\n\n if (directiveName.length < 1) {\n throwError(state, 'directive name must not be less than one character in length');\n }\n\n while (ch !== 0) {\n while (is_WHITE_SPACE(ch)) {\n ch = state.input.charCodeAt(++state.position);\n }\n\n if (ch === 0x23/* # */) {\n do { ch = state.input.charCodeAt(++state.position); }\n while (ch !== 0 && !is_EOL(ch));\n break;\n }\n\n if (is_EOL(ch)) break;\n\n _position = state.position;\n\n while (ch !== 0 && !is_WS_OR_EOL(ch)) {\n ch = state.input.charCodeAt(++state.position);\n }\n\n directiveArgs.push(state.input.slice(_position, state.position));\n }\n\n if (ch !== 0) readLineBreak(state);\n\n if (_hasOwnProperty$1.call(directiveHandlers, directiveName)) {\n directiveHandlers[directiveName](state, directiveName, directiveArgs);\n } else {\n throwWarning(state, 'unknown document directive \"' + directiveName + '\"');\n }\n }\n\n skipSeparationSpace(state, true, -1);\n\n if (state.lineIndent === 0 &&\n state.input.charCodeAt(state.position) === 0x2D/* - */ &&\n state.input.charCodeAt(state.position + 1) === 0x2D/* - */ &&\n state.input.charCodeAt(state.position + 2) === 0x2D/* - */) {\n state.position += 3;\n skipSeparationSpace(state, true, -1);\n\n } else if (hasDirectives) {\n throwError(state, 'directives end mark is expected');\n }\n\n composeNode(state, state.lineIndent - 1, CONTEXT_BLOCK_OUT, false, true);\n skipSeparationSpace(state, true, -1);\n\n if (state.checkLineBreaks &&\n PATTERN_NON_ASCII_LINE_BREAKS.test(state.input.slice(documentStart, state.position))) {\n throwWarning(state, 'non-ASCII line breaks are interpreted as content');\n }\n\n state.documents.push(state.result);\n\n if (state.position === state.lineStart && testDocumentSeparator(state)) {\n\n if (state.input.charCodeAt(state.position) === 0x2E/* . */) {\n state.position += 3;\n skipSeparationSpace(state, true, -1);\n }\n return;\n }\n\n if (state.position < (state.length - 1)) {\n throwError(state, 'end of the stream or a document separator is expected');\n } else {\n return;\n }\n}\n\n\nfunction loadDocuments(input, options) {\n input = String(input);\n options = options || {};\n\n if (input.length !== 0) {\n\n // Add tailing `\\n` if not exists\n if (input.charCodeAt(input.length - 1) !== 0x0A/* LF */ &&\n input.charCodeAt(input.length - 1) !== 0x0D/* CR */) {\n input += '\\n';\n }\n\n // Strip BOM\n if (input.charCodeAt(0) === 0xFEFF) {\n input = input.slice(1);\n }\n }\n\n var state = new State$1(input, options);\n\n var nullpos = input.indexOf('\\0');\n\n if (nullpos !== -1) {\n state.position = nullpos;\n throwError(state, 'null byte is not allowed in input');\n }\n\n // Use 0 as string terminator. That significantly simplifies bounds check.\n state.input += '\\0';\n\n while (state.input.charCodeAt(state.position) === 0x20/* Space */) {\n state.lineIndent += 1;\n state.position += 1;\n }\n\n while (state.position < (state.length - 1)) {\n readDocument(state);\n }\n\n return state.documents;\n}\n\n\nfunction loadAll$1(input, iterator, options) {\n if (iterator !== null && typeof iterator === 'object' && typeof options === 'undefined') {\n options = iterator;\n iterator = null;\n }\n\n var documents = loadDocuments(input, options);\n\n if (typeof iterator !== 'function') {\n return documents;\n }\n\n for (var index = 0, length = documents.length; index < length; index += 1) {\n iterator(documents[index]);\n }\n}\n\n\nfunction load$1(input, options) {\n var documents = loadDocuments(input, options);\n\n if (documents.length === 0) {\n /*eslint-disable no-undefined*/\n return undefined;\n } else if (documents.length === 1) {\n return documents[0];\n }\n throw new exception('expected a single document in the stream, but found more');\n}\n\n\nvar loadAll_1 = loadAll$1;\nvar load_1 = load$1;\n\nvar loader = {\n\tloadAll: loadAll_1,\n\tload: load_1\n};\n\n/*eslint-disable no-use-before-define*/\n\n\n\n\n\nvar _toString = Object.prototype.toString;\nvar _hasOwnProperty = Object.prototype.hasOwnProperty;\n\nvar CHAR_BOM = 0xFEFF;\nvar CHAR_TAB = 0x09; /* Tab */\nvar CHAR_LINE_FEED = 0x0A; /* LF */\nvar CHAR_CARRIAGE_RETURN = 0x0D; /* CR */\nvar CHAR_SPACE = 0x20; /* Space */\nvar CHAR_EXCLAMATION = 0x21; /* ! */\nvar CHAR_DOUBLE_QUOTE = 0x22; /* \" */\nvar CHAR_SHARP = 0x23; /* # */\nvar CHAR_PERCENT = 0x25; /* % */\nvar CHAR_AMPERSAND = 0x26; /* & */\nvar CHAR_SINGLE_QUOTE = 0x27; /* ' */\nvar CHAR_ASTERISK = 0x2A; /* * */\nvar CHAR_COMMA = 0x2C; /* , */\nvar CHAR_MINUS = 0x2D; /* - */\nvar CHAR_COLON = 0x3A; /* : */\nvar CHAR_EQUALS = 0x3D; /* = */\nvar CHAR_GREATER_THAN = 0x3E; /* > */\nvar CHAR_QUESTION = 0x3F; /* ? */\nvar CHAR_COMMERCIAL_AT = 0x40; /* @ */\nvar CHAR_LEFT_SQUARE_BRACKET = 0x5B; /* [ */\nvar CHAR_RIGHT_SQUARE_BRACKET = 0x5D; /* ] */\nvar CHAR_GRAVE_ACCENT = 0x60; /* ` */\nvar CHAR_LEFT_CURLY_BRACKET = 0x7B; /* { */\nvar CHAR_VERTICAL_LINE = 0x7C; /* | */\nvar CHAR_RIGHT_CURLY_BRACKET = 0x7D; /* } */\n\nvar ESCAPE_SEQUENCES = {};\n\nESCAPE_SEQUENCES[0x00] = '\\\\0';\nESCAPE_SEQUENCES[0x07] = '\\\\a';\nESCAPE_SEQUENCES[0x08] = '\\\\b';\nESCAPE_SEQUENCES[0x09] = '\\\\t';\nESCAPE_SEQUENCES[0x0A] = '\\\\n';\nESCAPE_SEQUENCES[0x0B] = '\\\\v';\nESCAPE_SEQUENCES[0x0C] = '\\\\f';\nESCAPE_SEQUENCES[0x0D] = '\\\\r';\nESCAPE_SEQUENCES[0x1B] = '\\\\e';\nESCAPE_SEQUENCES[0x22] = '\\\\\"';\nESCAPE_SEQUENCES[0x5C] = '\\\\\\\\';\nESCAPE_SEQUENCES[0x85] = '\\\\N';\nESCAPE_SEQUENCES[0xA0] = '\\\\_';\nESCAPE_SEQUENCES[0x2028] = '\\\\L';\nESCAPE_SEQUENCES[0x2029] = '\\\\P';\n\nvar DEPRECATED_BOOLEANS_SYNTAX = [\n 'y', 'Y', 'yes', 'Yes', 'YES', 'on', 'On', 'ON',\n 'n', 'N', 'no', 'No', 'NO', 'off', 'Off', 'OFF'\n];\n\nvar DEPRECATED_BASE60_SYNTAX = /^[-+]?[0-9_]+(?::[0-9_]+)+(?:\\.[0-9_]*)?$/;\n\nfunction compileStyleMap(schema, map) {\n var result, keys, index, length, tag, style, type;\n\n if (map === null) return {};\n\n result = {};\n keys = Object.keys(map);\n\n for (index = 0, length = keys.length; index < length; index += 1) {\n tag = keys[index];\n style = String(map[tag]);\n\n if (tag.slice(0, 2) === '!!') {\n tag = 'tag:yaml.org,2002:' + tag.slice(2);\n }\n type = schema.compiledTypeMap['fallback'][tag];\n\n if (type && _hasOwnProperty.call(type.styleAliases, style)) {\n style = type.styleAliases[style];\n }\n\n result[tag] = style;\n }\n\n return result;\n}\n\nfunction encodeHex(character) {\n var string, handle, length;\n\n string = character.toString(16).toUpperCase();\n\n if (character <= 0xFF) {\n handle = 'x';\n length = 2;\n } else if (character <= 0xFFFF) {\n handle = 'u';\n length = 4;\n } else if (character <= 0xFFFFFFFF) {\n handle = 'U';\n length = 8;\n } else {\n throw new exception('code point within a string may not be greater than 0xFFFFFFFF');\n }\n\n return '\\\\' + handle + common.repeat('0', length - string.length) + string;\n}\n\n\nvar QUOTING_TYPE_SINGLE = 1,\n QUOTING_TYPE_DOUBLE = 2;\n\nfunction State(options) {\n this.schema = options['schema'] || _default;\n this.indent = Math.max(1, (options['indent'] || 2));\n this.noArrayIndent = options['noArrayIndent'] || false;\n this.skipInvalid = options['skipInvalid'] || false;\n this.flowLevel = (common.isNothing(options['flowLevel']) ? -1 : options['flowLevel']);\n this.styleMap = compileStyleMap(this.schema, options['styles'] || null);\n this.sortKeys = options['sortKeys'] || false;\n this.lineWidth = options['lineWidth'] || 80;\n this.noRefs = options['noRefs'] || false;\n this.noCompatMode = options['noCompatMode'] || false;\n this.condenseFlow = options['condenseFlow'] || false;\n this.quotingType = options['quotingType'] === '\"' ? QUOTING_TYPE_DOUBLE : QUOTING_TYPE_SINGLE;\n this.forceQuotes = options['forceQuotes'] || false;\n this.replacer = typeof options['replacer'] === 'function' ? options['replacer'] : null;\n\n this.implicitTypes = this.schema.compiledImplicit;\n this.explicitTypes = this.schema.compiledExplicit;\n\n this.tag = null;\n this.result = '';\n\n this.duplicates = [];\n this.usedDuplicates = null;\n}\n\n// Indents every line in a string. Empty lines (\\n only) are not indented.\nfunction indentString(string, spaces) {\n var ind = common.repeat(' ', spaces),\n position = 0,\n next = -1,\n result = '',\n line,\n length = string.length;\n\n while (position < length) {\n next = string.indexOf('\\n', position);\n if (next === -1) {\n line = string.slice(position);\n position = length;\n } else {\n line = string.slice(position, next + 1);\n position = next + 1;\n }\n\n if (line.length && line !== '\\n') result += ind;\n\n result += line;\n }\n\n return result;\n}\n\nfunction generateNextLine(state, level) {\n return '\\n' + common.repeat(' ', state.indent * level);\n}\n\nfunction testImplicitResolving(state, str) {\n var index, length, type;\n\n for (index = 0, length = state.implicitTypes.length; index < length; index += 1) {\n type = state.implicitTypes[index];\n\n if (type.resolve(str)) {\n return true;\n }\n }\n\n return false;\n}\n\n// [33] s-white ::= s-space | s-tab\nfunction isWhitespace(c) {\n return c === CHAR_SPACE || c === CHAR_TAB;\n}\n\n// Returns true if the character can be printed without escaping.\n// From YAML 1.2: \"any allowed characters known to be non-printable\n// should also be escaped. [However,] This isn\u2019t mandatory\"\n// Derived from nb-char - \\t - #x85 - #xA0 - #x2028 - #x2029.\nfunction isPrintable(c) {\n return (0x00020 <= c && c <= 0x00007E)\n || ((0x000A1 <= c && c <= 0x00D7FF) && c !== 0x2028 && c !== 0x2029)\n || ((0x0E000 <= c && c <= 0x00FFFD) && c !== CHAR_BOM)\n || (0x10000 <= c && c <= 0x10FFFF);\n}\n\n// [34] ns-char ::= nb-char - s-white\n// [27] nb-char ::= c-printable - b-char - c-byte-order-mark\n// [26] b-char ::= b-line-feed | b-carriage-return\n// Including s-white (for some reason, examples doesn't match specs in this aspect)\n// ns-char ::= c-printable - b-line-feed - b-carriage-return - c-byte-order-mark\nfunction isNsCharOrWhitespace(c) {\n return isPrintable(c)\n && c !== CHAR_BOM\n // - b-char\n && c !== CHAR_CARRIAGE_RETURN\n && c !== CHAR_LINE_FEED;\n}\n\n// [127] ns-plain-safe(c) ::= c = flow-out \u21D2 ns-plain-safe-out\n// c = flow-in \u21D2 ns-plain-safe-in\n// c = block-key \u21D2 ns-plain-safe-out\n// c = flow-key \u21D2 ns-plain-safe-in\n// [128] ns-plain-safe-out ::= ns-char\n// [129] ns-plain-safe-in ::= ns-char - c-flow-indicator\n// [130] ns-plain-char(c) ::= ( ns-plain-safe(c) - \u201C:\u201D - \u201C#\u201D )\n// | ( /* An ns-char preceding */ \u201C#\u201D )\n// | ( \u201C:\u201D /* Followed by an ns-plain-safe(c) */ )\nfunction isPlainSafe(c, prev, inblock) {\n var cIsNsCharOrWhitespace = isNsCharOrWhitespace(c);\n var cIsNsChar = cIsNsCharOrWhitespace && !isWhitespace(c);\n return (\n // ns-plain-safe\n inblock ? // c = flow-in\n cIsNsCharOrWhitespace\n : cIsNsCharOrWhitespace\n // - c-flow-indicator\n && c !== CHAR_COMMA\n && c !== CHAR_LEFT_SQUARE_BRACKET\n && c !== CHAR_RIGHT_SQUARE_BRACKET\n && c !== CHAR_LEFT_CURLY_BRACKET\n && c !== CHAR_RIGHT_CURLY_BRACKET\n )\n // ns-plain-char\n && c !== CHAR_SHARP // false on '#'\n && !(prev === CHAR_COLON && !cIsNsChar) // false on ': '\n || (isNsCharOrWhitespace(prev) && !isWhitespace(prev) && c === CHAR_SHARP) // change to true on '[^ ]#'\n || (prev === CHAR_COLON && cIsNsChar); // change to true on ':[^ ]'\n}\n\n// Simplified test for values allowed as the first character in plain style.\nfunction isPlainSafeFirst(c) {\n // Uses a subset of ns-char - c-indicator\n // where ns-char = nb-char - s-white.\n // No support of ( ( \u201C?\u201D | \u201C:\u201D | \u201C-\u201D ) /* Followed by an ns-plain-safe(c)) */ ) part\n return isPrintable(c) && c !== CHAR_BOM\n && !isWhitespace(c) // - s-white\n // - (c-indicator ::=\n // \u201C-\u201D | \u201C?\u201D | \u201C:\u201D | \u201C,\u201D | \u201C[\u201D | \u201C]\u201D | \u201C{\u201D | \u201C}\u201D\n && c !== CHAR_MINUS\n && c !== CHAR_QUESTION\n && c !== CHAR_COLON\n && c !== CHAR_COMMA\n && c !== CHAR_LEFT_SQUARE_BRACKET\n && c !== CHAR_RIGHT_SQUARE_BRACKET\n && c !== CHAR_LEFT_CURLY_BRACKET\n && c !== CHAR_RIGHT_CURLY_BRACKET\n // | \u201C#\u201D | \u201C&\u201D | \u201C*\u201D | \u201C!\u201D | \u201C|\u201D | \u201C=\u201D | \u201C>\u201D | \u201C'\u201D | \u201C\"\u201D\n && c !== CHAR_SHARP\n && c !== CHAR_AMPERSAND\n && c !== CHAR_ASTERISK\n && c !== CHAR_EXCLAMATION\n && c !== CHAR_VERTICAL_LINE\n && c !== CHAR_EQUALS\n && c !== CHAR_GREATER_THAN\n && c !== CHAR_SINGLE_QUOTE\n && c !== CHAR_DOUBLE_QUOTE\n // | \u201C%\u201D | \u201C@\u201D | \u201C`\u201D)\n && c !== CHAR_PERCENT\n && c !== CHAR_COMMERCIAL_AT\n && c !== CHAR_GRAVE_ACCENT;\n}\n\n// Simplified test for values allowed as the last character in plain style.\nfunction isPlainSafeLast(c) {\n // just not whitespace or colon, it will be checked to be plain character later\n return !isWhitespace(c) && c !== CHAR_COLON;\n}\n\n// Same as 'string'.codePointAt(pos), but works in older browsers.\nfunction codePointAt(string, pos) {\n var first = string.charCodeAt(pos), second;\n if (first >= 0xD800 && first <= 0xDBFF && pos + 1 < string.length) {\n second = string.charCodeAt(pos + 1);\n if (second >= 0xDC00 && second <= 0xDFFF) {\n // https://mathiasbynens.be/notes/javascript-encoding#surrogate-formulae\n return (first - 0xD800) * 0x400 + second - 0xDC00 + 0x10000;\n }\n }\n return first;\n}\n\n// Determines whether block indentation indicator is required.\nfunction needIndentIndicator(string) {\n var leadingSpaceRe = /^\\n* /;\n return leadingSpaceRe.test(string);\n}\n\nvar STYLE_PLAIN = 1,\n STYLE_SINGLE = 2,\n STYLE_LITERAL = 3,\n STYLE_FOLDED = 4,\n STYLE_DOUBLE = 5;\n\n// Determines which scalar styles are possible and returns the preferred style.\n// lineWidth = -1 => no limit.\n// Pre-conditions: str.length > 0.\n// Post-conditions:\n// STYLE_PLAIN or STYLE_SINGLE => no \\n are in the string.\n// STYLE_LITERAL => no lines are suitable for folding (or lineWidth is -1).\n// STYLE_FOLDED => a line > lineWidth and can be folded (and lineWidth != -1).\nfunction chooseScalarStyle(string, singleLineOnly, indentPerLevel, lineWidth,\n testAmbiguousType, quotingType, forceQuotes, inblock) {\n\n var i;\n var char = 0;\n var prevChar = null;\n var hasLineBreak = false;\n var hasFoldableLine = false; // only checked if shouldTrackWidth\n var shouldTrackWidth = lineWidth !== -1;\n var previousLineBreak = -1; // count the first line correctly\n var plain = isPlainSafeFirst(codePointAt(string, 0))\n && isPlainSafeLast(codePointAt(string, string.length - 1));\n\n if (singleLineOnly || forceQuotes) {\n // Case: no block styles.\n // Check for disallowed characters to rule out plain and single.\n for (i = 0; i < string.length; char >= 0x10000 ? i += 2 : i++) {\n char = codePointAt(string, i);\n if (!isPrintable(char)) {\n return STYLE_DOUBLE;\n }\n plain = plain && isPlainSafe(char, prevChar, inblock);\n prevChar = char;\n }\n } else {\n // Case: block styles permitted.\n for (i = 0; i < string.length; char >= 0x10000 ? i += 2 : i++) {\n char = codePointAt(string, i);\n if (char === CHAR_LINE_FEED) {\n hasLineBreak = true;\n // Check if any line can be folded.\n if (shouldTrackWidth) {\n hasFoldableLine = hasFoldableLine ||\n // Foldable line = too long, and not more-indented.\n (i - previousLineBreak - 1 > lineWidth &&\n string[previousLineBreak + 1] !== ' ');\n previousLineBreak = i;\n }\n } else if (!isPrintable(char)) {\n return STYLE_DOUBLE;\n }\n plain = plain && isPlainSafe(char, prevChar, inblock);\n prevChar = char;\n }\n // in case the end is missing a \\n\n hasFoldableLine = hasFoldableLine || (shouldTrackWidth &&\n (i - previousLineBreak - 1 > lineWidth &&\n string[previousLineBreak + 1] !== ' '));\n }\n // Although every style can represent \\n without escaping, prefer block styles\n // for multiline, since they're more readable and they don't add empty lines.\n // Also prefer folding a super-long line.\n if (!hasLineBreak && !hasFoldableLine) {\n // Strings interpretable as another type have to be quoted;\n // e.g. the string 'true' vs. the boolean true.\n if (plain && !forceQuotes && !testAmbiguousType(string)) {\n return STYLE_PLAIN;\n }\n return quotingType === QUOTING_TYPE_DOUBLE ? STYLE_DOUBLE : STYLE_SINGLE;\n }\n // Edge case: block indentation indicator can only have one digit.\n if (indentPerLevel > 9 && needIndentIndicator(string)) {\n return STYLE_DOUBLE;\n }\n // At this point we know block styles are valid.\n // Prefer literal style unless we want to fold.\n if (!forceQuotes) {\n return hasFoldableLine ? STYLE_FOLDED : STYLE_LITERAL;\n }\n return quotingType === QUOTING_TYPE_DOUBLE ? STYLE_DOUBLE : STYLE_SINGLE;\n}\n\n// Note: line breaking/folding is implemented for only the folded style.\n// NB. We drop the last trailing newline (if any) of a returned block scalar\n// since the dumper adds its own newline. This always works:\n// \u2022 No ending newline => unaffected; already using strip \"-\" chomping.\n// \u2022 Ending newline => removed then restored.\n// Importantly, this keeps the \"+\" chomp indicator from gaining an extra line.\nfunction writeScalar(state, string, level, iskey, inblock) {\n state.dump = (function () {\n if (string.length === 0) {\n return state.quotingType === QUOTING_TYPE_DOUBLE ? '\"\"' : \"''\";\n }\n if (!state.noCompatMode) {\n if (DEPRECATED_BOOLEANS_SYNTAX.indexOf(string) !== -1 || DEPRECATED_BASE60_SYNTAX.test(string)) {\n return state.quotingType === QUOTING_TYPE_DOUBLE ? ('\"' + string + '\"') : (\"'\" + string + \"'\");\n }\n }\n\n var indent = state.indent * Math.max(1, level); // no 0-indent scalars\n // As indentation gets deeper, let the width decrease monotonically\n // to the lower bound min(state.lineWidth, 40).\n // Note that this implies\n // state.lineWidth \u2264 40 + state.indent: width is fixed at the lower bound.\n // state.lineWidth > 40 + state.indent: width decreases until the lower bound.\n // This behaves better than a constant minimum width which disallows narrower options,\n // or an indent threshold which causes the width to suddenly increase.\n var lineWidth = state.lineWidth === -1\n ? -1 : Math.max(Math.min(state.lineWidth, 40), state.lineWidth - indent);\n\n // Without knowing if keys are implicit/explicit, assume implicit for safety.\n var singleLineOnly = iskey\n // No block styles in flow mode.\n || (state.flowLevel > -1 && level >= state.flowLevel);\n function testAmbiguity(string) {\n return testImplicitResolving(state, string);\n }\n\n switch (chooseScalarStyle(string, singleLineOnly, state.indent, lineWidth,\n testAmbiguity, state.quotingType, state.forceQuotes && !iskey, inblock)) {\n\n case STYLE_PLAIN:\n return string;\n case STYLE_SINGLE:\n return \"'\" + string.replace(/'/g, \"''\") + \"'\";\n case STYLE_LITERAL:\n return '|' + blockHeader(string, state.indent)\n + dropEndingNewline(indentString(string, indent));\n case STYLE_FOLDED:\n return '>' + blockHeader(string, state.indent)\n + dropEndingNewline(indentString(foldString(string, lineWidth), indent));\n case STYLE_DOUBLE:\n return '\"' + escapeString(string) + '\"';\n default:\n throw new exception('impossible error: invalid scalar style');\n }\n }());\n}\n\n// Pre-conditions: string is valid for a block scalar, 1 <= indentPerLevel <= 9.\nfunction blockHeader(string, indentPerLevel) {\n var indentIndicator = needIndentIndicator(string) ? String(indentPerLevel) : '';\n\n // note the special case: the string '\\n' counts as a \"trailing\" empty line.\n var clip = string[string.length - 1] === '\\n';\n var keep = clip && (string[string.length - 2] === '\\n' || string === '\\n');\n var chomp = keep ? '+' : (clip ? '' : '-');\n\n return indentIndicator + chomp + '\\n';\n}\n\n// (See the note for writeScalar.)\nfunction dropEndingNewline(string) {\n return string[string.length - 1] === '\\n' ? string.slice(0, -1) : string;\n}\n\n// Note: a long line without a suitable break point will exceed the width limit.\n// Pre-conditions: every char in str isPrintable, str.length > 0, width > 0.\nfunction foldString(string, width) {\n // In folded style, $k$ consecutive newlines output as $k+1$ newlines\u2014\n // unless they're before or after a more-indented line, or at the very\n // beginning or end, in which case $k$ maps to $k$.\n // Therefore, parse each chunk as newline(s) followed by a content line.\n var lineRe = /(\\n+)([^\\n]*)/g;\n\n // first line (possibly an empty line)\n var result = (function () {\n var nextLF = string.indexOf('\\n');\n nextLF = nextLF !== -1 ? nextLF : string.length;\n lineRe.lastIndex = nextLF;\n return foldLine(string.slice(0, nextLF), width);\n }());\n // If we haven't reached the first content line yet, don't add an extra \\n.\n var prevMoreIndented = string[0] === '\\n' || string[0] === ' ';\n var moreIndented;\n\n // rest of the lines\n var match;\n while ((match = lineRe.exec(string))) {\n var prefix = match[1], line = match[2];\n moreIndented = (line[0] === ' ');\n result += prefix\n + (!prevMoreIndented && !moreIndented && line !== ''\n ? '\\n' : '')\n + foldLine(line, width);\n prevMoreIndented = moreIndented;\n }\n\n return result;\n}\n\n// Greedy line breaking.\n// Picks the longest line under the limit each time,\n// otherwise settles for the shortest line over the limit.\n// NB. More-indented lines *cannot* be folded, as that would add an extra \\n.\nfunction foldLine(line, width) {\n if (line === '' || line[0] === ' ') return line;\n\n // Since a more-indented line adds a \\n, breaks can't be followed by a space.\n var breakRe = / [^ ]/g; // note: the match index will always be <= length-2.\n var match;\n // start is an inclusive index. end, curr, and next are exclusive.\n var start = 0, end, curr = 0, next = 0;\n var result = '';\n\n // Invariants: 0 <= start <= length-1.\n // 0 <= curr <= next <= max(0, length-2). curr - start <= width.\n // Inside the loop:\n // A match implies length >= 2, so curr and next are <= length-2.\n while ((match = breakRe.exec(line))) {\n next = match.index;\n // maintain invariant: curr - start <= width\n if (next - start > width) {\n end = (curr > start) ? curr : next; // derive end <= length-2\n result += '\\n' + line.slice(start, end);\n // skip the space that was output as \\n\n start = end + 1; // derive start <= length-1\n }\n curr = next;\n }\n\n // By the invariants, start <= length-1, so there is something left over.\n // It is either the whole string or a part starting from non-whitespace.\n result += '\\n';\n // Insert a break if the remainder is too long and there is a break available.\n if (line.length - start > width && curr > start) {\n result += line.slice(start, curr) + '\\n' + line.slice(curr + 1);\n } else {\n result += line.slice(start);\n }\n\n return result.slice(1); // drop extra \\n joiner\n}\n\n// Escapes a double-quoted string.\nfunction escapeString(string) {\n var result = '';\n var char = 0;\n var escapeSeq;\n\n for (var i = 0; i < string.length; char >= 0x10000 ? i += 2 : i++) {\n char = codePointAt(string, i);\n escapeSeq = ESCAPE_SEQUENCES[char];\n\n if (!escapeSeq && isPrintable(char)) {\n result += string[i];\n if (char >= 0x10000) result += string[i + 1];\n } else {\n result += escapeSeq || encodeHex(char);\n }\n }\n\n return result;\n}\n\nfunction writeFlowSequence(state, level, object) {\n var _result = '',\n _tag = state.tag,\n index,\n length,\n value;\n\n for (index = 0, length = object.length; index < length; index += 1) {\n value = object[index];\n\n if (state.replacer) {\n value = state.replacer.call(object, String(index), value);\n }\n\n // Write only valid elements, put null instead of invalid elements.\n if (writeNode(state, level, value, false, false) ||\n (typeof value === 'undefined' &&\n writeNode(state, level, null, false, false))) {\n\n if (_result !== '') _result += ',' + (!state.condenseFlow ? ' ' : '');\n _result += state.dump;\n }\n }\n\n state.tag = _tag;\n state.dump = '[' + _result + ']';\n}\n\nfunction writeBlockSequence(state, level, object, compact) {\n var _result = '',\n _tag = state.tag,\n index,\n length,\n value;\n\n for (index = 0, length = object.length; index < length; index += 1) {\n value = object[index];\n\n if (state.replacer) {\n value = state.replacer.call(object, String(index), value);\n }\n\n // Write only valid elements, put null instead of invalid elements.\n if (writeNode(state, level + 1, value, true, true, false, true) ||\n (typeof value === 'undefined' &&\n writeNode(state, level + 1, null, true, true, false, true))) {\n\n if (!compact || _result !== '') {\n _result += generateNextLine(state, level);\n }\n\n if (state.dump && CHAR_LINE_FEED === state.dump.charCodeAt(0)) {\n _result += '-';\n } else {\n _result += '- ';\n }\n\n _result += state.dump;\n }\n }\n\n state.tag = _tag;\n state.dump = _result || '[]'; // Empty sequence if no valid values.\n}\n\nfunction writeFlowMapping(state, level, object) {\n var _result = '',\n _tag = state.tag,\n objectKeyList = Object.keys(object),\n index,\n length,\n objectKey,\n objectValue,\n pairBuffer;\n\n for (index = 0, length = objectKeyList.length; index < length; index += 1) {\n\n pairBuffer = '';\n if (_result !== '') pairBuffer += ', ';\n\n if (state.condenseFlow) pairBuffer += '\"';\n\n objectKey = objectKeyList[index];\n objectValue = object[objectKey];\n\n if (state.replacer) {\n objectValue = state.replacer.call(object, objectKey, objectValue);\n }\n\n if (!writeNode(state, level, objectKey, false, false)) {\n continue; // Skip this pair because of invalid key;\n }\n\n if (state.dump.length > 1024) pairBuffer += '? ';\n\n pairBuffer += state.dump + (state.condenseFlow ? '\"' : '') + ':' + (state.condenseFlow ? '' : ' ');\n\n if (!writeNode(state, level, objectValue, false, false)) {\n continue; // Skip this pair because of invalid value.\n }\n\n pairBuffer += state.dump;\n\n // Both key and value are valid.\n _result += pairBuffer;\n }\n\n state.tag = _tag;\n state.dump = '{' + _result + '}';\n}\n\nfunction writeBlockMapping(state, level, object, compact) {\n var _result = '',\n _tag = state.tag,\n objectKeyList = Object.keys(object),\n index,\n length,\n objectKey,\n objectValue,\n explicitPair,\n pairBuffer;\n\n // Allow sorting keys so that the output file is deterministic\n if (state.sortKeys === true) {\n // Default sorting\n objectKeyList.sort();\n } else if (typeof state.sortKeys === 'function') {\n // Custom sort function\n objectKeyList.sort(state.sortKeys);\n } else if (state.sortKeys) {\n // Something is wrong\n throw new exception('sortKeys must be a boolean or a function');\n }\n\n for (index = 0, length = objectKeyList.length; index < length; index += 1) {\n pairBuffer = '';\n\n if (!compact || _result !== '') {\n pairBuffer += generateNextLine(state, level);\n }\n\n objectKey = objectKeyList[index];\n objectValue = object[objectKey];\n\n if (state.replacer) {\n objectValue = state.replacer.call(object, objectKey, objectValue);\n }\n\n if (!writeNode(state, level + 1, objectKey, true, true, true)) {\n continue; // Skip this pair because of invalid key.\n }\n\n explicitPair = (state.tag !== null && state.tag !== '?') ||\n (state.dump && state.dump.length > 1024);\n\n if (explicitPair) {\n if (state.dump && CHAR_LINE_FEED === state.dump.charCodeAt(0)) {\n pairBuffer += '?';\n } else {\n pairBuffer += '? ';\n }\n }\n\n pairBuffer += state.dump;\n\n if (explicitPair) {\n pairBuffer += generateNextLine(state, level);\n }\n\n if (!writeNode(state, level + 1, objectValue, true, explicitPair)) {\n continue; // Skip this pair because of invalid value.\n }\n\n if (state.dump && CHAR_LINE_FEED === state.dump.charCodeAt(0)) {\n pairBuffer += ':';\n } else {\n pairBuffer += ': ';\n }\n\n pairBuffer += state.dump;\n\n // Both key and value are valid.\n _result += pairBuffer;\n }\n\n state.tag = _tag;\n state.dump = _result || '{}'; // Empty mapping if no valid pairs.\n}\n\nfunction detectType(state, object, explicit) {\n var _result, typeList, index, length, type, style;\n\n typeList = explicit ? state.explicitTypes : state.implicitTypes;\n\n for (index = 0, length = typeList.length; index < length; index += 1) {\n type = typeList[index];\n\n if ((type.instanceOf || type.predicate) &&\n (!type.instanceOf || ((typeof object === 'object') && (object instanceof type.instanceOf))) &&\n (!type.predicate || type.predicate(object))) {\n\n if (explicit) {\n if (type.multi && type.representName) {\n state.tag = type.representName(object);\n } else {\n state.tag = type.tag;\n }\n } else {\n state.tag = '?';\n }\n\n if (type.represent) {\n style = state.styleMap[type.tag] || type.defaultStyle;\n\n if (_toString.call(type.represent) === '[object Function]') {\n _result = type.represent(object, style);\n } else if (_hasOwnProperty.call(type.represent, style)) {\n _result = type.represent[style](object, style);\n } else {\n throw new exception('!<' + type.tag + '> tag resolver accepts not \"' + style + '\" style');\n }\n\n state.dump = _result;\n }\n\n return true;\n }\n }\n\n return false;\n}\n\n// Serializes `object` and writes it to global `result`.\n// Returns true on success, or false on invalid object.\n//\nfunction writeNode(state, level, object, block, compact, iskey, isblockseq) {\n state.tag = null;\n state.dump = object;\n\n if (!detectType(state, object, false)) {\n detectType(state, object, true);\n }\n\n var type = _toString.call(state.dump);\n var inblock = block;\n var tagStr;\n\n if (block) {\n block = (state.flowLevel < 0 || state.flowLevel > level);\n }\n\n var objectOrArray = type === '[object Object]' || type === '[object Array]',\n duplicateIndex,\n duplicate;\n\n if (objectOrArray) {\n duplicateIndex = state.duplicates.indexOf(object);\n duplicate = duplicateIndex !== -1;\n }\n\n if ((state.tag !== null && state.tag !== '?') || duplicate || (state.indent !== 2 && level > 0)) {\n compact = false;\n }\n\n if (duplicate && state.usedDuplicates[duplicateIndex]) {\n state.dump = '*ref_' + duplicateIndex;\n } else {\n if (objectOrArray && duplicate && !state.usedDuplicates[duplicateIndex]) {\n state.usedDuplicates[duplicateIndex] = true;\n }\n if (type === '[object Object]') {\n if (block && (Object.keys(state.dump).length !== 0)) {\n writeBlockMapping(state, level, state.dump, compact);\n if (duplicate) {\n state.dump = '&ref_' + duplicateIndex + state.dump;\n }\n } else {\n writeFlowMapping(state, level, state.dump);\n if (duplicate) {\n state.dump = '&ref_' + duplicateIndex + ' ' + state.dump;\n }\n }\n } else if (type === '[object Array]') {\n if (block && (state.dump.length !== 0)) {\n if (state.noArrayIndent && !isblockseq && level > 0) {\n writeBlockSequence(state, level - 1, state.dump, compact);\n } else {\n writeBlockSequence(state, level, state.dump, compact);\n }\n if (duplicate) {\n state.dump = '&ref_' + duplicateIndex + state.dump;\n }\n } else {\n writeFlowSequence(state, level, state.dump);\n if (duplicate) {\n state.dump = '&ref_' + duplicateIndex + ' ' + state.dump;\n }\n }\n } else if (type === '[object String]') {\n if (state.tag !== '?') {\n writeScalar(state, state.dump, level, iskey, inblock);\n }\n } else if (type === '[object Undefined]') {\n return false;\n } else {\n if (state.skipInvalid) return false;\n throw new exception('unacceptable kind of an object to dump ' + type);\n }\n\n if (state.tag !== null && state.tag !== '?') {\n // Need to encode all characters except those allowed by the spec:\n //\n // [35] ns-dec-digit ::= [#x30-#x39] /* 0-9 */\n // [36] ns-hex-digit ::= ns-dec-digit\n // | [#x41-#x46] /* A-F */ | [#x61-#x66] /* a-f */\n // [37] ns-ascii-letter ::= [#x41-#x5A] /* A-Z */ | [#x61-#x7A] /* a-z */\n // [38] ns-word-char ::= ns-dec-digit | ns-ascii-letter | \u201C-\u201D\n // [39] ns-uri-char ::= \u201C%\u201D ns-hex-digit ns-hex-digit | ns-word-char | \u201C#\u201D\n // | \u201C;\u201D | \u201C/\u201D | \u201C?\u201D | \u201C:\u201D | \u201C@\u201D | \u201C&\u201D | \u201C=\u201D | \u201C+\u201D | \u201C$\u201D | \u201C,\u201D\n // | \u201C_\u201D | \u201C.\u201D | \u201C!\u201D | \u201C~\u201D | \u201C*\u201D | \u201C'\u201D | \u201C(\u201D | \u201C)\u201D | \u201C[\u201D | \u201C]\u201D\n //\n // Also need to encode '!' because it has special meaning (end of tag prefix).\n //\n tagStr = encodeURI(\n state.tag[0] === '!' ? state.tag.slice(1) : state.tag\n ).replace(/!/g, '%21');\n\n if (state.tag[0] === '!') {\n tagStr = '!' + tagStr;\n } else if (tagStr.slice(0, 18) === 'tag:yaml.org,2002:') {\n tagStr = '!!' + tagStr.slice(18);\n } else {\n tagStr = '!<' + tagStr + '>';\n }\n\n state.dump = tagStr + ' ' + state.dump;\n }\n }\n\n return true;\n}\n\nfunction getDuplicateReferences(object, state) {\n var objects = [],\n duplicatesIndexes = [],\n index,\n length;\n\n inspectNode(object, objects, duplicatesIndexes);\n\n for (index = 0, length = duplicatesIndexes.length; index < length; index += 1) {\n state.duplicates.push(objects[duplicatesIndexes[index]]);\n }\n state.usedDuplicates = new Array(length);\n}\n\nfunction inspectNode(object, objects, duplicatesIndexes) {\n var objectKeyList,\n index,\n length;\n\n if (object !== null && typeof object === 'object') {\n index = objects.indexOf(object);\n if (index !== -1) {\n if (duplicatesIndexes.indexOf(index) === -1) {\n duplicatesIndexes.push(index);\n }\n } else {\n objects.push(object);\n\n if (Array.isArray(object)) {\n for (index = 0, length = object.length; index < length; index += 1) {\n inspectNode(object[index], objects, duplicatesIndexes);\n }\n } else {\n objectKeyList = Object.keys(object);\n\n for (index = 0, length = objectKeyList.length; index < length; index += 1) {\n inspectNode(object[objectKeyList[index]], objects, duplicatesIndexes);\n }\n }\n }\n }\n}\n\nfunction dump$1(input, options) {\n options = options || {};\n\n var state = new State(options);\n\n if (!state.noRefs) getDuplicateReferences(input, state);\n\n var value = input;\n\n if (state.replacer) {\n value = state.replacer.call({ '': value }, '', value);\n }\n\n if (writeNode(state, 0, value, true, true)) return state.dump + '\\n';\n\n return '';\n}\n\nvar dump_1 = dump$1;\n\nvar dumper = {\n\tdump: dump_1\n};\n\nfunction renamed(from, to) {\n return function () {\n throw new Error('Function yaml.' + from + ' is removed in js-yaml 4. ' +\n 'Use yaml.' + to + ' instead, which is now safe by default.');\n };\n}\n\n\nvar Type = type;\nvar Schema = schema;\nvar FAILSAFE_SCHEMA = failsafe;\nvar JSON_SCHEMA = json;\nvar CORE_SCHEMA = core;\nvar DEFAULT_SCHEMA = _default;\nvar load = loader.load;\nvar loadAll = loader.loadAll;\nvar dump = dumper.dump;\nvar YAMLException = exception;\n\n// Re-export all types in case user wants to create custom schema\nvar types = {\n binary: binary,\n float: float,\n map: map,\n null: _null,\n pairs: pairs,\n set: set,\n timestamp: timestamp,\n bool: bool,\n int: int,\n merge: merge,\n omap: omap,\n seq: seq,\n str: str\n};\n\n// Removed functions from JS-YAML 3.0.x\nvar safeLoad = renamed('safeLoad', 'load');\nvar safeLoadAll = renamed('safeLoadAll', 'loadAll');\nvar safeDump = renamed('safeDump', 'dump');\n\nvar jsYaml = {\n\tType: Type,\n\tSchema: Schema,\n\tFAILSAFE_SCHEMA: FAILSAFE_SCHEMA,\n\tJSON_SCHEMA: JSON_SCHEMA,\n\tCORE_SCHEMA: CORE_SCHEMA,\n\tDEFAULT_SCHEMA: DEFAULT_SCHEMA,\n\tload: load,\n\tloadAll: loadAll,\n\tdump: dump,\n\tYAMLException: YAMLException,\n\ttypes: types,\n\tsafeLoad: safeLoad,\n\tsafeLoadAll: safeLoadAll,\n\tsafeDump: safeDump\n};\n\nexport { CORE_SCHEMA, DEFAULT_SCHEMA, FAILSAFE_SCHEMA, JSON_SCHEMA, Schema, Type, YAMLException, jsYaml as default, dump, load, loadAll, safeDump, safeLoad, safeLoadAll, types };\n", "/**\n * CodeQL metadata resolver utilities\n * Handles resolution of query metadata using the CodeQL CLI\n */\n\nimport { executeCodeQLCommand } from './cli-executor';\nimport { logger } from '../utils/logger';\n\n/**\n * Query metadata structure returned by codeql resolve metadata\n */\nexport interface QueryMetadata {\n [key: string]: string | string[];\n}\n\n/**\n * Resolve metadata for a CodeQL query file\n * @param queryPath - Absolute or relative path to the .ql query file\n * @returns Parsed metadata object or null if resolution fails\n */\nexport async function resolveQueryMetadata(queryPath: string): Promise {\n try {\n logger.info(`Resolving metadata for query: ${queryPath}`);\n\n const result = await executeCodeQLCommand(\n 'resolve metadata',\n { format: 'json' },\n [queryPath]\n );\n\n if (!result.success) {\n logger.error(`Failed to resolve metadata for ${queryPath}:`, result.stderr || result.error);\n return null;\n }\n\n // Parse the JSON output\n try {\n const metadata = JSON.parse(result.stdout);\n return metadata;\n } catch (parseError) {\n logger.error(`Failed to parse metadata JSON for ${queryPath}:`, parseError);\n return null;\n }\n } catch (error) {\n logger.error(`Error resolving metadata for ${queryPath}:`, error);\n return null;\n }\n}\n", "/**\n * CodeQL generate log-summary tool\n */\n\nimport { z } from 'zod';\nimport { CLIToolDefinition, createCodeQLSchemas, defaultCLIResultProcessor } from '../../lib/cli-tool-registry';\n\nexport const codeqlGenerateLogSummaryTool: CLIToolDefinition = {\n name: 'codeql_generate_log-summary',\n description: 'Create a summary of a structured JSON evaluator event log file',\n command: 'codeql',\n subcommand: 'generate log-summary',\n inputSchema: {\n inputLog: z.string().describe('Path to the evaluator log file to summarize'),\n outputFile: z.string().optional().describe('Path to write the summary (optional, defaults to stdout)'),\n format: z.enum(['text', 'predicates', 'overall']).optional()\n .describe('Output format: text (human-readable), predicates (JSON), or overall (stats)'),\n 'minify-output': z.boolean().optional().describe('Minify JSON output'),\n utc: z.boolean().optional().describe('Force UTC timestamps'),\n 'deduplicate-stage-summaries': z.boolean().optional().describe('Deduplicate stage summaries'),\n verbose: createCodeQLSchemas.verbose(),\n additionalArgs: createCodeQLSchemas.additionalArgs()\n },\n examples: [\n 'codeql generate log-summary --format=text -- evaluator-log.json.txt summary.txt',\n 'codeql generate log-summary --format=predicates --minify-output -- evaluator-log.json.txt',\n 'codeql generate log-summary --format=overall -- evaluator-log.json.txt overall-stats.json'\n ],\n resultProcessor: defaultCLIResultProcessor\n};", "/**\n * CodeQL generate query-help tool\n */\n\nimport { z } from 'zod';\nimport { CLIToolDefinition, createCodeQLSchemas, defaultCLIResultProcessor } from '../../lib/cli-tool-registry';\n\nexport const codeqlGenerateQueryHelpTool: CLIToolDefinition = {\n name: 'codeql_generate_query-help',\n description: 'Generate query help documentation from QLDoc comments',\n command: 'codeql',\n subcommand: 'generate query-help',\n inputSchema: {\n query: z.string().describe('Path to the query file to generate help for'),\n outputFile: z.string().optional().describe('Path to write the help documentation'),\n format: z.enum(['markdown', 'text', 'html']).optional()\n .describe('Output format for the help documentation'),\n verbose: createCodeQLSchemas.verbose(),\n additionalArgs: createCodeQLSchemas.additionalArgs()\n },\n examples: [\n 'codeql generate query-help -- MyQuery.ql',\n 'codeql generate query-help --format=markdown -- MyQuery.ql help.md',\n 'codeql generate query-help --format=html -- MyQuery.ql help.html'\n ],\n resultProcessor: defaultCLIResultProcessor\n};", "/**\n * list_codeql_databases tool\n *\n * Discovers CodeQL databases in configured base directories.\n * Scans each directory in `CODEQL_DATABASES_BASE_DIRS` for subdirectories\n * containing `codeql-database.yml`, extracts metadata (language, CLI version,\n * creation time), and returns the list.\n */\n\nimport { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport { existsSync, readdirSync, readFileSync, statSync } from 'fs';\nimport { join } from 'path';\nimport { z } from 'zod';\nimport { getDatabaseBaseDirs } from '../../lib/discovery-config';\nimport { logger } from '../../utils/logger';\n\nexport interface DatabaseInfo {\n cliVersion?: string;\n creationTime?: string;\n language?: string;\n name: string;\n path: string;\n}\n\n/**\n * Parse `codeql-database.yml` to extract metadata.\n * Uses simple line-based parsing to avoid a YAML dependency.\n */\nfunction parseDatabaseYml(ymlPath: string): Partial {\n try {\n const content = readFileSync(ymlPath, 'utf-8');\n const info: Partial = {};\n\n for (const line of content.split('\\n')) {\n const trimmed = line.trim();\n const colonIdx = trimmed.indexOf(':');\n if (colonIdx === -1) continue;\n\n const key = trimmed.substring(0, colonIdx).trim();\n const value = trimmed.substring(colonIdx + 1).trim().replace(/^[\"']|[\"']$/g, '');\n\n switch (key) {\n case 'primaryLanguage':\n info.language = value;\n break;\n case 'cliVersion':\n info.cliVersion = value;\n break;\n case 'creationTime':\n info.creationTime = value;\n break;\n }\n }\n\n return info;\n } catch {\n return {};\n }\n}\n\n/**\n * Discover CodeQL databases in the given base directories.\n *\n * @param baseDirs - Directories to scan for database subdirectories\n * @param language - Optional language filter\n * @returns List of discovered databases with metadata\n */\nexport async function discoverDatabases(\n baseDirs: string[],\n language?: string,\n): Promise {\n const databases: DatabaseInfo[] = [];\n\n for (const baseDir of baseDirs) {\n if (!existsSync(baseDir)) {\n continue;\n }\n\n let entries: string[];\n try {\n entries = readdirSync(baseDir);\n } catch {\n continue;\n }\n\n for (const entry of entries) {\n const entryPath = join(baseDir, entry);\n\n // Skip non-directories\n try {\n if (!statSync(entryPath).isDirectory()) {\n continue;\n }\n } catch {\n continue;\n }\n\n // Check for codeql-database.yml\n const ymlPath = join(entryPath, 'codeql-database.yml');\n if (!existsSync(ymlPath)) {\n continue;\n }\n\n const metadata = parseDatabaseYml(ymlPath);\n\n // Apply language filter\n if (language && metadata.language !== language) {\n continue;\n }\n\n databases.push({\n cliVersion: metadata.cliVersion,\n creationTime: metadata.creationTime,\n language: metadata.language,\n name: entry,\n path: entryPath,\n });\n }\n }\n\n return databases;\n}\n\n/**\n * Register the list_codeql_databases tool with the MCP server.\n */\nexport function registerListDatabasesTool(server: McpServer): void {\n server.tool(\n 'list_codeql_databases',\n 'List CodeQL databases discovered in configured base directories (set via CODEQL_DATABASES_BASE_DIRS env var). Returns path, language, CLI version, and creation time for each database.',\n {\n language: z\n .string()\n .optional()\n .describe('Filter databases by language (e.g., \"javascript\", \"python\")'),\n },\n async ({ language }) => {\n try {\n const baseDirs = getDatabaseBaseDirs();\n\n if (baseDirs.length === 0) {\n return {\n content: [\n {\n type: 'text' as const,\n text: 'No database base directories configured. Set the CODEQL_DATABASES_BASE_DIRS environment variable to a colon-separated list of directories to search.',\n },\n ],\n };\n }\n\n const databases = await discoverDatabases(baseDirs, language);\n\n if (databases.length === 0) {\n const filterMsg = language ? ` for language \"${language}\"` : '';\n return {\n content: [\n {\n type: 'text' as const,\n text: `No CodeQL databases found${filterMsg} in: ${baseDirs.join(', ')}`,\n },\n ],\n };\n }\n\n const lines = [\n `Found ${databases.length} CodeQL database(s):`,\n '',\n ...databases.map((db) => {\n const parts = [` ${db.name}`];\n parts.push(` Path: ${db.path}`);\n if (db.language) parts.push(` Language: ${db.language}`);\n if (db.cliVersion) parts.push(` CLI Version: ${db.cliVersion}`);\n if (db.creationTime) parts.push(` Created: ${db.creationTime}`);\n return parts.join('\\n');\n }),\n ];\n\n return {\n content: [{ type: 'text' as const, text: lines.join('\\n') }],\n };\n } catch (error) {\n logger.error('Error listing databases:', error);\n return {\n content: [\n {\n type: 'text' as const,\n text: `Error: ${error instanceof Error ? error.message : 'Unknown error'}`,\n },\n ],\n isError: true,\n };\n }\n },\n );\n}\n", "/**\n * Discovery configuration for locating CodeQL databases and query run results.\n *\n * Reads colon-separated directory lists from environment variables:\n * - `CODEQL_DATABASES_BASE_DIRS` \u2014 directories to search for CodeQL databases\n * - `CODEQL_QUERY_RUN_RESULTS_DIRS` \u2014 directories containing per-run query result subdirectories\n *\n * The VS Code extension sets these automatically from vscode-codeql storage paths.\n * CLI users can set them manually.\n */\n\n/**\n * Parse a colon-separated list of directories from an environment variable.\n */\nfunction parsePathList(envValue: string | undefined): string[] {\n if (!envValue) {\n return [];\n }\n return envValue\n .split(':')\n .map((p) => p.trim())\n .filter((p) => p.length > 0);\n}\n\n/**\n * Get the list of base directories to search for CodeQL databases.\n *\n * Each directory is expected to contain one or more CodeQL database directories\n * (each with a `codeql-database.yml` file).\n *\n * Set via `CODEQL_DATABASES_BASE_DIRS` (colon-separated).\n */\nexport function getDatabaseBaseDirs(): string[] {\n return parsePathList(process.env.CODEQL_DATABASES_BASE_DIRS);\n}\n\n/**\n * Get the list of directories containing per-run query result subdirectories.\n *\n * Each directory is expected to contain subdirectories named like\n * `.ql-/`, each holding artifacts such as\n * `evaluator-log.jsonl`, `results.bqrs`, and `results-interpreted.sarif`.\n *\n * Set via `CODEQL_QUERY_RUN_RESULTS_DIRS` (colon-separated).\n */\nexport function getQueryRunResultsDirs(): string[] {\n return parsePathList(process.env.CODEQL_QUERY_RUN_RESULTS_DIRS);\n}\n", "/**\n * list_query_run_results tool\n *\n * Discovers per-query-run result directories in configured search paths.\n * Scans each directory in `CODEQL_QUERY_RUN_RESULTS_DIRS` for subdirectories\n * matching the `.ql-` naming convention used by vscode-codeql.\n * Reports which artifacts (evaluator logs, BQRS, SARIF) are present in each run.\n */\n\nimport { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport { existsSync, readdirSync, readFileSync, statSync } from 'fs';\nimport { join } from 'path';\nimport { z } from 'zod';\nimport { getQueryRunResultsDirs } from '../../lib/discovery-config';\nimport { logger } from '../../utils/logger';\n\nexport interface QueryRunResult {\n hasBqrs: boolean;\n hasEvaluatorLog: boolean;\n hasSarif: boolean;\n path: string;\n queryName: string;\n runId: string;\n timestamp?: string;\n}\n\n/**\n * Pattern matching vscode-codeql query run directory names: `.ql-`\n */\nconst QUERY_RUN_DIR_PATTERN = /^(.+\\.ql)-(.+)$/;\n\n/**\n * Discover query run result directories in the given search paths.\n *\n * @param resultsDirs - Directories to scan for per-run subdirectories\n * @param queryName - Optional query name filter (e.g., \"UI5Xss.ql\")\n * @returns List of discovered query run results with artifact inventory\n */\nexport async function discoverQueryRunResults(\n resultsDirs: string[],\n queryName?: string,\n): Promise {\n const results: QueryRunResult[] = [];\n\n for (const dir of resultsDirs) {\n if (!existsSync(dir)) {\n continue;\n }\n\n let entries: string[];\n try {\n entries = readdirSync(dir);\n } catch {\n continue;\n }\n\n for (const entry of entries) {\n const entryPath = join(dir, entry);\n\n // Skip non-directories\n try {\n if (!statSync(entryPath).isDirectory()) {\n continue;\n }\n } catch {\n continue;\n }\n\n // Match the naming pattern\n const match = QUERY_RUN_DIR_PATTERN.exec(entry);\n if (!match) {\n continue;\n }\n\n const [, name, runId] = match;\n\n // Apply query name filter\n if (queryName && name !== queryName) {\n continue;\n }\n\n // Check which artifacts are present\n const hasEvaluatorLog = existsSync(join(entryPath, 'evaluator-log.jsonl'));\n const hasBqrs = existsSync(join(entryPath, 'results.bqrs'));\n const hasSarif = existsSync(join(entryPath, 'results-interpreted.sarif'));\n\n // Read timestamp if available\n let timestamp: string | undefined;\n const timestampPath = join(entryPath, 'timestamp');\n if (existsSync(timestampPath)) {\n try {\n timestamp = readFileSync(timestampPath, 'utf-8').trim();\n } catch {\n // Ignore read errors\n }\n }\n\n results.push({\n hasBqrs,\n hasEvaluatorLog,\n hasSarif,\n path: entryPath,\n queryName: name,\n runId,\n timestamp,\n });\n }\n }\n\n return results;\n}\n\n/**\n * Register the list_query_run_results tool with the MCP server.\n */\nexport function registerListQueryRunResultsTool(server: McpServer): void {\n server.tool(\n 'list_query_run_results',\n 'List discovered query run result directories (set via CODEQL_QUERY_RUN_RESULTS_DIRS env var). Returns path, query name, timestamp, and available artifacts for each run.',\n {\n queryName: z\n .string()\n .optional()\n .describe('Filter results by query name (e.g., \"UI5Xss.ql\")'),\n },\n async ({ queryName }) => {\n try {\n const resultsDirs = getQueryRunResultsDirs();\n\n if (resultsDirs.length === 0) {\n return {\n content: [\n {\n type: 'text' as const,\n text: 'No query run results directories configured. Set the CODEQL_QUERY_RUN_RESULTS_DIRS environment variable to a colon-separated list of directories to search.',\n },\n ],\n };\n }\n\n const runs = await discoverQueryRunResults(resultsDirs, queryName);\n\n if (runs.length === 0) {\n const filterMsg = queryName ? ` for query \"${queryName}\"` : '';\n return {\n content: [\n {\n type: 'text' as const,\n text: `No query run results found${filterMsg} in: ${resultsDirs.join(', ')}`,\n },\n ],\n };\n }\n\n const lines = [\n `Found ${runs.length} query run result(s):`,\n '',\n ...runs.map((run) => {\n const artifacts: string[] = [];\n if (run.hasEvaluatorLog) artifacts.push('evaluator-log');\n if (run.hasBqrs) artifacts.push('bqrs');\n if (run.hasSarif) artifacts.push('sarif');\n const parts = [` ${run.queryName} (${run.runId})`];\n parts.push(` Path: ${run.path}`);\n if (run.timestamp) parts.push(` Timestamp: ${run.timestamp}`);\n parts.push(` Artifacts: ${artifacts.length > 0 ? artifacts.join(', ') : 'none'}`);\n return parts.join('\\n');\n }),\n ];\n\n return {\n content: [{ type: 'text' as const, text: lines.join('\\n') }],\n };\n } catch (error) {\n logger.error('Error listing query run results:', error);\n return {\n content: [\n {\n type: 'text' as const,\n text: `Error: ${error instanceof Error ? error.message : 'Unknown error'}`,\n },\n ],\n isError: true,\n };\n }\n },\n );\n}\n", "/**\n * CodeQL pack install tool\n */\n\nimport { z } from 'zod';\nimport { CLIToolDefinition, createCodeQLSchemas } from '../../lib/cli-tool-registry';\n\nexport const codeqlPackInstallTool: CLIToolDefinition = {\n name: 'codeql_pack_install',\n description: 'Install CodeQL pack dependencies',\n command: 'codeql',\n subcommand: 'pack install',\n inputSchema: {\n packDir: z.string().optional().describe('Directory containing qlpack.yml (default: current)'),\n force: z.boolean().optional().describe('Force reinstall of dependencies'),\n 'no-strict-mode': z.boolean().optional()\n .describe('Allow non-strict dependency resolution'),\n verbose: createCodeQLSchemas.verbose(),\n additionalArgs: createCodeQLSchemas.additionalArgs()\n },\n examples: [\n 'codeql pack install',\n 'codeql pack install --force /path/to/pack',\n 'codeql pack install --no-strict-mode'\n ]\n};", "/**\n * CodeQL pack ls tool\n */\n\nimport { z } from 'zod';\nimport { CLIToolDefinition, createCodeQLSchemas, defaultCLIResultProcessor } from '../../lib/cli-tool-registry';\n\nexport const codeqlPackLsTool: CLIToolDefinition = {\n name: 'codeql_pack_ls',\n description: 'List CodeQL packs under some local directory path',\n command: 'codeql',\n subcommand: 'pack ls',\n inputSchema: {\n dir: z.string().optional().describe('The root directory of the package or workspace, defaults to the current working directory'),\n format: z.enum(['text', 'json']).optional()\n .describe('Output format: text (default) or json'),\n groups: z.string().optional()\n .describe('List of CodeQL pack groups to include or exclude'),\n verbose: createCodeQLSchemas.verbose(),\n additionalArgs: createCodeQLSchemas.additionalArgs()\n },\n examples: [\n 'codeql pack ls -- .',\n 'codeql pack ls --format=json -- /path/to/pack-directory',\n 'codeql pack ls --format=json --groups=queries,tests -- .'\n ],\n resultProcessor: defaultCLIResultProcessor\n};", "/**\n * CodeQL query profiling tool\n */\n\nimport { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport { z } from 'zod';\nimport { executeCodeQLCommand } from '../../lib/cli-executor';\nimport { logger } from '../../utils/logger';\nimport { writeFileSync, readFileSync, existsSync } from 'fs';\nimport { join, dirname, basename } from 'path';\nimport { mkdirSync } from 'fs';\n\ninterface EvaluatorLogEvent {\n time: string;\n type: string;\n eventId: number;\n nanoTime: number;\n [key: string]: unknown;\n}\n\ninterface PipelineNode {\n eventId: number;\n name: string;\n position?: string;\n type?: string;\n startTime: number;\n endTime: number;\n duration: number;\n resultSize?: number;\n tupleCount?: number;\n dependencies: string[];\n dependencyEventIds: number[];\n}\n\ninterface ProfileData {\n queryName: string;\n totalDuration: number;\n totalEvents: number;\n pipelines: PipelineNode[];\n}\n\n/**\n * Parse evaluator log and create profile data\n */\nfunction parseEvaluatorLog(logPath: string): ProfileData {\n const logContent = readFileSync(logPath, 'utf-8');\n \n // Split by empty lines to get each JSON object (handles both JSONL and pretty-printed JSON)\n const jsonObjects = logContent.split('\\n\\n').filter((s) => s.trim());\n const events: EvaluatorLogEvent[] = jsonObjects\n .map((obj) => {\n try {\n return JSON.parse(obj);\n } catch (_error) {\n logger.warn(`Failed to parse evaluator log object: ${obj.substring(0, 100)}...`);\n return null;\n }\n })\n .filter((event): event is EvaluatorLogEvent => event !== null);\n\n // Map to track pipeline nodes by their start event ID\n const pipelineMap = new Map>();\n // Map to track dependency event IDs by predicate name\n const predicateNameToEventId = new Map();\n \n let queryName = '';\n let queryStartTime = 0;\n let queryEndTime = 0;\n\n for (const event of events) {\n switch (event.type) {\n case 'QUERY_STARTED':\n queryName = (event.queryName as string) || '';\n queryStartTime = event.nanoTime;\n break;\n\n case 'QUERY_COMPLETED':\n queryEndTime = event.nanoTime;\n break;\n\n case 'PREDICATE_STARTED': {\n const predicateName = event.predicateName as string;\n const position = event.position as string | undefined;\n const predicateType = event.predicateType as string | undefined;\n const dependencies = event.dependencies as Record | undefined;\n \n // Track this predicate's event ID by name for dependency resolution\n predicateNameToEventId.set(predicateName, event.eventId);\n \n // Get dependency event IDs\n const dependencyEventIds: number[] = [];\n const dependencyNames: string[] = [];\n if (dependencies) {\n for (const depName of Object.keys(dependencies)) {\n dependencyNames.push(depName);\n const depEventId = predicateNameToEventId.get(depName);\n if (depEventId !== undefined) {\n dependencyEventIds.push(depEventId);\n }\n }\n }\n\n pipelineMap.set(event.eventId, {\n eventId: event.eventId,\n name: predicateName,\n position,\n type: predicateType,\n startTime: event.nanoTime,\n dependencies: dependencyNames,\n dependencyEventIds,\n });\n break;\n }\n\n case 'PREDICATE_COMPLETED': {\n const startEventId = event.startEvent as number;\n const pipelineInfo = pipelineMap.get(startEventId);\n if (pipelineInfo) {\n const startEvent = events.find((e) => e.eventId === startEventId);\n if (startEvent) {\n const duration = (event.nanoTime - startEvent.nanoTime) / 1_000_000; // Convert to ms\n pipelineInfo.endTime = event.nanoTime;\n pipelineInfo.duration = duration;\n pipelineInfo.resultSize = event.resultSize as number | undefined;\n pipelineInfo.tupleCount = event.tupleCount as number | undefined;\n }\n }\n break;\n }\n }\n }\n\n // Convert to array and maintain original evaluation order (by eventId)\n const pipelines: PipelineNode[] = Array.from(pipelineMap.values())\n .filter((p): p is PipelineNode => p.duration !== undefined)\n .sort((a, b) => a.eventId - b.eventId);\n\n const totalDuration = queryEndTime > 0 ? (queryEndTime - queryStartTime) / 1_000_000 : 0;\n\n return {\n queryName,\n totalDuration,\n totalEvents: events.length,\n pipelines,\n };\n}\n\n/**\n * Format profile data as JSON\n */\nfunction formatAsJson(profile: ProfileData): string {\n return JSON.stringify(profile, null, 2);\n}\n\n/**\n * Format profile data as Mermaid diagram\n * Creates a graph showing the query evaluation pipelines in order of execution\n * with dependencies as edges, annotated with duration and result sizes\n */\nfunction formatAsMermaid(profile: ProfileData): string {\n const lines: string[] = [];\n\n lines.push('```mermaid');\n lines.push('graph TD');\n lines.push('');\n \n // Add query root node\n lines.push(` QUERY[\"${basename(profile.queryName)}
Total: ${profile.totalDuration.toFixed(2)}ms\"]`);\n lines.push('');\n \n // Create nodes for each pipeline in evaluation order (already sorted by eventId)\n profile.pipelines.forEach((pipeline) => {\n const nodeId = `P${pipeline.eventId}`;\n const duration = pipeline.duration.toFixed(2);\n const resultSize = pipeline.resultSize !== undefined ? pipeline.resultSize : '?';\n // Sanitize predicate name for Mermaid\n const name = pipeline.name.replace(/[<>]/g, '').substring(0, 40);\n lines.push(` ${nodeId}[\"${name}
${duration}ms | ${resultSize} results\"]`);\n });\n \n lines.push('');\n \n // Add edges from QUERY to root pipelines (those with no dependencies)\n const rootPipelines = profile.pipelines.filter((p) => p.dependencies.length === 0);\n \n rootPipelines.forEach((pipeline) => {\n lines.push(` QUERY --> P${pipeline.eventId}`);\n });\n \n lines.push('');\n \n // Add edges between pipelines based on dependencies (using eventIds to preserve links)\n profile.pipelines.forEach((pipeline) => {\n pipeline.dependencyEventIds.forEach((depEventId) => {\n const duration = pipeline.duration.toFixed(2);\n lines.push(` P${depEventId} -->|\"${duration}ms\"| P${pipeline.eventId}`);\n });\n });\n \n lines.push('');\n lines.push(' classDef default fill:#e1f5ff,stroke:#333,stroke-width:2px');\n lines.push(' classDef query fill:#ffe1e1,stroke:#333,stroke-width:3px');\n lines.push(' class QUERY query');\n lines.push('```');\n\n return lines.join('\\n');\n}\n\n/**\n * Register the profile_codeql_query tool\n */\nexport function registerProfileCodeQLQueryTool(server: McpServer): void {\n server.tool(\n 'profile_codeql_query',\n 'Profile the performance of a CodeQL query run against a specific database by analyzing the evaluator log JSON file',\n {\n query: z.string().describe('Path to the .ql query file'),\n database: z.string().describe('Path to the CodeQL database directory'),\n evaluatorLog: z\n .string()\n .optional()\n .describe(\n 'Path to an existing structured JSON log (e.g., evaluator-log.jsonl) file. If not provided, the tool will run the query to generate one.'\n ),\n outputDir: z\n .string()\n .optional()\n .describe('Directory to write profiling data files (defaults to same directory as evaluator log)'),\n },\n async (params) => {\n try {\n const { query, database, evaluatorLog, outputDir } = params;\n let logPath = evaluatorLog;\n let bqrsPath: string | undefined;\n let sarifPath: string | undefined;\n\n // If evaluator log not provided, run the query to generate one\n if (!logPath) {\n logger.info('No evaluator log provided, running query to generate one');\n\n // Determine output directory\n const defaultOutputDir = outputDir || join(dirname(query as string), 'profile-output');\n mkdirSync(defaultOutputDir, { recursive: true });\n\n logPath = join(defaultOutputDir, 'evaluator-log.jsonl');\n bqrsPath = join(defaultOutputDir, 'query-results.bqrs');\n sarifPath = join(defaultOutputDir, 'query-results.sarif');\n\n // Run query with evaluator logging and tuple counting\n const queryResult = await executeCodeQLCommand(\n 'query run',\n {\n database: database as string,\n output: bqrsPath,\n 'evaluator-log': logPath,\n 'tuple-counting': true,\n 'evaluator-log-level': 5,\n },\n [query as string]\n );\n\n if (!queryResult.success) {\n return {\n content: [\n {\n type: 'text' as const,\n text: `Failed to run query: ${queryResult.stderr || queryResult.error}`,\n },\n ],\n isError: true,\n };\n }\n\n // Generate SARIF interpretation\n if (existsSync(bqrsPath)) {\n try {\n const sarifResult = await executeCodeQLCommand(\n 'bqrs interpret',\n { format: 'sarif-latest', output: sarifPath },\n [bqrsPath]\n );\n\n if (sarifResult.success) {\n logger.info(`Generated SARIF interpretation at ${sarifPath}`);\n }\n } catch (error) {\n logger.warn(`Failed to generate SARIF interpretation: ${error}`);\n }\n }\n }\n\n // Verify evaluator log exists\n if (!existsSync(logPath)) {\n return {\n content: [\n {\n type: 'text' as const,\n text: `Evaluator log not found at: ${logPath}`,\n },\n ],\n isError: true,\n };\n }\n\n // Parse the evaluator log\n logger.info(`Parsing evaluator log from: ${logPath}`);\n const profile = parseEvaluatorLog(logPath);\n\n // Determine output directory for profile\n const profileOutputDir = outputDir || dirname(logPath);\n mkdirSync(profileOutputDir, { recursive: true });\n\n // Write profile JSON file\n const jsonPath = join(profileOutputDir, 'query-evaluation-profile.json');\n const jsonContent = formatAsJson(profile);\n writeFileSync(jsonPath, jsonContent);\n logger.info(`Profile JSON written to: ${jsonPath}`);\n\n // Write profile Mermaid diagram file\n const mdPath = join(profileOutputDir, 'query-evaluation-profile.md');\n const mdContent = formatAsMermaid(profile);\n writeFileSync(mdPath, mdContent);\n logger.info(`Profile Mermaid diagram written to: ${mdPath}`);\n\n // Build response message\n const outputFiles: string[] = [\n `Profile JSON: ${jsonPath}`,\n `Profile Mermaid: ${mdPath}`,\n `Evaluator Log: ${logPath}`,\n ];\n\n if (bqrsPath) {\n outputFiles.push(`Query Results (BQRS): ${bqrsPath}`);\n }\n\n if (sarifPath && existsSync(sarifPath)) {\n outputFiles.push(`Query Results (SARIF): ${sarifPath}`);\n }\n\n const responseText = [\n 'Query profiling completed successfully!',\n '',\n 'Output Files:',\n ...outputFiles.map((f) => ` - ${f}`),\n '',\n 'Profile Summary:',\n ` - Query: ${basename(profile.queryName)}`,\n ` - Total Duration: ${profile.totalDuration.toFixed(2)} ms`,\n ` - Total Pipelines: ${profile.pipelines.length}`,\n ` - Total Events: ${profile.totalEvents}`,\n '',\n 'First 5 Pipeline Nodes (in evaluation order):',\n ...profile.pipelines.slice(0, 5).map((p, idx) => {\n return ` ${idx + 1}. ${p.name} (${p.duration.toFixed(2)} ms, ${p.resultSize || '?'} results)`;\n }),\n ].join('\\n');\n\n return {\n content: [\n {\n type: 'text' as const,\n text: responseText,\n },\n ],\n };\n } catch (error) {\n logger.error('Error profiling CodeQL query:', error);\n\n return {\n content: [\n {\n type: 'text' as const,\n text: `Failed to profile query: ${error instanceof Error ? error.message : String(error)}`,\n },\n ],\n isError: true,\n };\n }\n }\n );\n}\n", "/**\n * CodeQL query compile tool\n */\n\nimport { z } from 'zod';\nimport { CLIToolDefinition } from '../../lib/cli-tool-registry';\n\nexport const codeqlQueryCompileTool: CLIToolDefinition = {\n name: 'codeql_query_compile',\n description: 'Compile and validate CodeQL queries',\n command: 'codeql',\n subcommand: 'query compile',\n inputSchema: {\n query: z.string().describe('Path to the CodeQL query file (.ql)'),\n database: z.string().optional().describe('Path to the CodeQL database'),\n library: z.string().optional().describe('Path to query library'),\n output: z.string().optional().describe('Output file path'),\n warnings: z.enum(['hide', 'show', 'error']).optional()\n .describe('How to handle compilation warnings'),\n verbose: z.boolean().optional().describe('Enable verbose output'),\n additionalArgs: z.array(z.string()).optional().describe('Additional command-line arguments')\n },\n examples: [\n 'codeql query compile --database=/path/to/db MyQuery.ql',\n 'codeql query compile --library=/path/to/lib --output=compiled.qlo MyQuery.ql'\n ]\n};", "/**\n * CodeQL query format tool\n */\n\nimport { z } from 'zod';\nimport { CLIToolDefinition, createCodeQLSchemas, defaultCLIResultProcessor, CLIExecutionResult } from '../../lib/cli-tool-registry';\n\n/**\n * Custom result processor for codeql query format tool\n * Exit code 1 with --check-only means \"file would change\" - this is success for format checking\n */\nfunction formatResultProcessor(result: CLIExecutionResult, params: Record): string {\n const isCheckOnly = params['check-only'];\n const hasFormatChanges = result.exitCode === 1;\n \n if (isCheckOnly && hasFormatChanges) {\n // Mark as success for the CLI tool registry since detecting format changes is the intended behavior\n result.success = true;\n return result.stdout || result.stderr || 'File would change by autoformatting.';\n }\n \n return defaultCLIResultProcessor(result, params);\n}\n\nexport const codeqlQueryFormatTool: CLIToolDefinition = {\n name: 'codeql_query_format',\n description: 'Automatically format CodeQL source code files',\n command: 'codeql',\n subcommand: 'query format',\n inputSchema: {\n files: z.array(z.string()).describe('One or more .ql or .qll source files to format'),\n output: z.string().optional().describe('Write formatted code to this file instead of stdout'),\n 'in-place': z.boolean().optional().describe('Overwrite each input file with formatted version'),\n 'check-only': z.boolean().optional().describe('Check formatting without writing output'),\n backup: z.string().optional().describe('Backup extension when overwriting existing files'),\n 'no-syntax-errors': z.boolean().optional().describe('Ignore syntax errors and pretend file is formatted'),\n verbose: createCodeQLSchemas.verbose(),\n additionalArgs: createCodeQLSchemas.additionalArgs()\n },\n examples: [\n 'codeql query format -i -- ExampleQuery.ql',\n 'codeql query format --in-place -- queries/*.ql',\n 'codeql query format --check-only -- queries/*.ql'\n ],\n resultProcessor: formatResultProcessor\n};", "/**\n * CodeQL query run tool\n */\n\nimport { z } from 'zod';\nimport { CLIToolDefinition, createCodeQLSchemas } from '../../lib/cli-tool-registry';\n\nexport const codeqlQueryRunTool: CLIToolDefinition = {\n name: 'codeql_query_run',\n description: 'Execute a CodeQL query against a database. Use either \"query\" parameter for direct file path OR \"queryName\" + \"queryLanguage\" for pre-defined tool queries.',\n command: 'codeql',\n subcommand: 'query run',\n inputSchema: {\n query: z.string().optional().describe('Path to the CodeQL query file (.ql) - cannot be used with queryName'),\n queryName: z.string().optional().describe('Name of pre-defined query to run (e.g., \"PrintAST\", \"CallGraphFrom\", \"CallGraphTo\") - requires queryLanguage'),\n queryLanguage: z.string().optional().describe('Programming language for tools queries (e.g., \"javascript\", \"java\", \"python\") - required when using queryName'),\n queryPack: z.string().optional().describe('Query pack path (defaults to server/ql//tools/src/ for tool queries)'),\n sourceFiles: z.string().optional().describe('Comma-separated list of source file paths for PrintAST queries (e.g., \"src/main.js,src/utils.js\" or just \"main.js\")'),\n sourceFunction: z.string().optional().describe('Comma-separated list of source function names for CallGraphFrom queries (e.g., \"main,processData\")'),\n targetFunction: z.string().optional().describe('Comma-separated list of target function names for CallGraphTo queries (e.g., \"helper,validateInput\")'),\n database: createCodeQLSchemas.database(),\n output: createCodeQLSchemas.output(),\n external: z.array(z.string()).optional()\n .describe('External predicate data: predicate=file.csv'),\n timeout: createCodeQLSchemas.timeout(),\n logDir: z.string().optional()\n .describe('Custom directory for query execution logs (overrides CODEQL_QUERY_LOG_DIR environment variable). If not provided, uses CODEQL_QUERY_LOG_DIR or defaults to .tmp/query-logs/'),\n 'evaluator-log': z.string().optional().describe('Path to save evaluator log (deprecated: use logDir instead)'),\n 'evaluator-log-minify': z.boolean().optional()\n .describe('Minimize evaluator log for smaller size'),\n 'evaluator-log-level': z.number().min(1).max(5).optional()\n .describe('Evaluator log verbosity level (1-5, default 5)'),\n 'tuple-counting': z.boolean().optional()\n .describe('Display tuple counts for each evaluation step in evaluator logs'),\n format: z.enum(['sarif-latest', 'sarifv2.1.0', 'csv', 'graphtext', 'dgml', 'dot']).optional()\n .describe('Output format for query results via codeql bqrs interpret. Defaults to sarif-latest for @kind problem/path-problem queries, graphtext for @kind graph queries. Graph formats (graphtext, dgml, dot) only work with @kind graph queries.'),\n interpretedOutput: z.string().optional()\n .describe('Output file for interpreted results (e.g., results.sarif, results.txt). If not provided, defaults based on format: .sarif for SARIF, .txt for graphtext/csv, .dgml for dgml, .dot for dot'),\n evaluationFunction: z.string().optional()\n .describe('[DEPRECATED - use format parameter instead] Built-in function for query results evaluation (e.g., \"mermaid-graph\", \"json-decode\", \"csv-decode\") or path to custom evaluation script'),\n evaluationOutput: z.string().optional()\n .describe('[DEPRECATED - use interpretedOutput parameter instead] Output file for evaluation results'),\n verbose: createCodeQLSchemas.verbose(),\n additionalArgs: createCodeQLSchemas.additionalArgs()\n },\n examples: [\n 'codeql query run --database=mydb --output=results.bqrs MyQuery.ql',\n 'codeql query run --database=mydb --query-name=PrintAST --query-language=javascript --source-files=src/index.js --output=results.bqrs --format=graphtext --interpreted-output=results.txt',\n 'codeql query run --database=mydb --external=data=input.csv --output=results.bqrs MyQuery.ql --format=sarif-latest --interpreted-output=results.sarif',\n 'codeql query run --database=mydb --evaluator-log=eval.log --tuple-counting --evaluator-log-level=5 --output=results.bqrs MyQuery.ql',\n 'codeql query run --database=mydb --query-name=PrintAST --query-language=javascript --source-files=\"main.js,utils.js\" --format=graphtext',\n 'codeql query run --database=mydb --log-dir=/custom/log/path --tuple-counting --output=results.bqrs MyQuery.ql'\n ]\n};", "/**\n * CodeQL quick evaluate tool\n * \n * Inspired by JordyZomer/codeql-mcp repository:\n * - https://github.com/JordyZomer/codeql-mcp/blob/main/server.py\n * - https://github.com/JordyZomer/codeql-mcp/blob/main/codeqlclient.py\n */\n\nimport { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport { z } from 'zod';\nimport { join, resolve } from 'path';\nimport { findClassPosition } from './find-class-position';\nimport { findPredicatePosition } from './find-predicate-position';\nimport { logger } from '../../utils/logger';\nimport { getProjectTmpDir } from '../../utils/temp-dir';\n\nexport interface QuickEvaluateParams {\n file: string;\n db: string;\n symbol: string;\n output_path?: string;\n}\n\n/**\n * Quick evaluate either a class or a predicate in a CodeQL query.\n * This allows debugging a select portion of QL code without running the whole query.\n */\nexport async function quickEvaluate({\n file,\n db: _db,\n symbol,\n output_path\n}: QuickEvaluateParams): Promise {\n try {\n // Try to find as a class first, then as a predicate\n try {\n await findClassPosition(file, symbol);\n } catch {\n try {\n await findPredicatePosition(file, symbol);\n } catch {\n throw new Error(`Symbol '${symbol}' not found as class or predicate in file: ${file}`);\n }\n }\n \n const resolvedOutput = resolve(output_path || join(getProjectTmpDir('quickeval'), 'quickeval.bqrs'));\n \n // For now, return the resolved output path\n // In a full implementation, this would use the CodeQL CLI or query server\n // to perform the actual quick evaluation with the position parameters\n return resolvedOutput;\n } catch (error) {\n throw new Error(`CodeQL evaluation failed: ${error instanceof Error ? error.message : 'Unknown error'}`);\n }\n}\n\n/**\n * Register the quick evaluate tool with the MCP server\n */\nexport function registerQuickEvaluateTool(server: McpServer): void {\n server.tool(\n 'quick_evaluate',\n 'Quick evaluate either a class or a predicate in a CodeQL query for debugging',\n {\n file: z.string().describe('Path to the .ql file containing the symbol'),\n db: z.string().describe('Path to the CodeQL database'),\n symbol: z.string().describe('Name of the class or predicate to evaluate'),\n output_path: z.string().optional().describe('Output path for results (defaults to project-local .tmp/quickeval/)'),\n },\n async ({ file, db, symbol, output_path }) => {\n try {\n const result = await quickEvaluate({ file, db, symbol, output_path });\n return {\n content: [{ type: 'text', text: result }],\n };\n } catch (error) {\n logger.error('Error in quick evaluate:', error);\n return {\n content: [\n {\n type: 'text',\n text: `Error: ${error instanceof Error ? error.message : 'Unknown error'}`,\n },\n ],\n isError: true,\n };\n }\n }\n );\n}", "/**\n * CodeQL register database tool\n * \n * Inspired by JordyZomer/codeql-mcp repository:\n * - https://github.com/JordyZomer/codeql-mcp/blob/main/server.py\n * - https://github.com/JordyZomer/codeql-mcp/blob/main/codeqlclient.py\n */\n\nimport { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport { z } from 'zod';\nimport { access, constants } from 'fs/promises';\nimport { resolve } from 'path';\nimport { logger } from '../../utils/logger';\n\nexport interface DatabaseRegistration {\n uri: string;\n content: {\n sourceArchiveZip: string;\n dbDir: string;\n };\n}\n\n/**\n * Register a CodeQL database given a local path to the database directory.\n * Validates that the database exists and has required structure.\n * Supports both full databases (with src.zip) and test databases (with src/ folder).\n */\nexport async function registerDatabase(dbPath: string): Promise {\n try {\n const resolvedPath = resolve(dbPath);\n \n // Check if database directory exists\n await access(resolvedPath, constants.F_OK);\n \n // Check for codeql-database.yml (required for all CodeQL databases)\n const dbYmlPath = resolve(resolvedPath, 'codeql-database.yml');\n await access(dbYmlPath, constants.F_OK);\n \n // Check if src.zip exists (for full databases) OR src/ directory exists (for test databases)\n const srcZipPath = resolve(resolvedPath, 'src.zip');\n const srcDirPath = resolve(resolvedPath, 'src');\n \n let hasSrcZip = false;\n let hasSrcDir = false;\n \n try {\n await access(srcZipPath, constants.F_OK);\n hasSrcZip = true;\n } catch {\n // src.zip not found, check for src/ directory\n }\n \n if (!hasSrcZip) {\n try {\n await access(srcDirPath, constants.F_OK);\n hasSrcDir = true;\n } catch {\n // src directory not found either\n }\n }\n \n if (!hasSrcZip && !hasSrcDir) {\n throw new Error(`Missing required source archive (src.zip) or source directory (src/) in: ${dbPath}`);\n }\n \n // For now, we just validate and return success message\n // In a full implementation, this would register with a query server\n const sourceType = hasSrcZip ? 'src.zip' : 'src/';\n return `Database registered: ${dbPath} (source: ${sourceType})`;\n } catch (error) {\n if (error instanceof Error) {\n const errorCode = (error as { code?: string }).code;\n if (errorCode === 'ENOENT') {\n if (error.message.includes('codeql-database.yml')) {\n throw new Error(`Missing required codeql-database.yml in: ${dbPath}`);\n }\n throw new Error(`Database path does not exist: ${dbPath}`);\n }\n if (errorCode === 'EACCES') {\n throw new Error(`Database path does not exist: ${dbPath}`);\n }\n }\n throw new Error(`Failed to register database: ${error instanceof Error ? error.message : 'Unknown error'}`);\n }\n}\n\n/**\n * Register the register database tool with the MCP server\n */\nexport function registerRegisterDatabaseTool(server: McpServer): void {\n server.tool(\n 'register_database',\n 'Register a CodeQL database given a local path to the database directory',\n {\n db_path: z.string().describe('Path to the CodeQL database directory'),\n },\n async ({ db_path }) => {\n try {\n const result = await registerDatabase(db_path);\n return {\n content: [{ type: 'text', text: result }],\n };\n } catch (error) {\n logger.error('Error registering database:', error);\n return {\n content: [\n {\n type: 'text',\n text: `Error: ${error instanceof Error ? error.message : 'Unknown error'}`,\n },\n ],\n isError: true,\n };\n }\n }\n );\n}", "/**\n * CodeQL resolve database tool\n */\n\nimport { z } from 'zod';\nimport { CLIToolDefinition, createCodeQLSchemas, defaultCLIResultProcessor } from '../../lib/cli-tool-registry';\n\nexport const codeqlResolveDatabaseTool: CLIToolDefinition = {\n name: 'codeql_resolve_database',\n description: 'Resolve database path and validate database structure',\n command: 'codeql',\n subcommand: 'resolve database',\n inputSchema: {\n database: z.string().describe('Database path to resolve'),\n format: z.enum(['text', 'json', 'betterjson']).optional()\n .describe('Output format for database information'),\n verbose: createCodeQLSchemas.verbose(),\n additionalArgs: createCodeQLSchemas.additionalArgs()\n },\n examples: [\n 'codeql resolve database -- /path/to/database',\n 'codeql resolve database --format=json -- my-database',\n 'codeql resolve database --format=betterjson -- database-dir'\n ],\n resultProcessor: defaultCLIResultProcessor\n};", "/**\n * CodeQL resolve languages tool\n */\n\nimport { z } from 'zod';\nimport { CLIToolDefinition, defaultCLIResultProcessor } from '../../lib/cli-tool-registry';\n\nexport const codeqlResolveLanguagesTool: CLIToolDefinition = {\n name: 'codeql_resolve_languages',\n description: 'List installed CodeQL extractor packs',\n command: 'codeql',\n subcommand: 'resolve languages',\n inputSchema: {\n format: z.enum(['text', 'json', 'betterjson']).optional()\n .describe('Output format for language information'),\n verbose: z.boolean().optional().describe('Enable verbose output'),\n additionalArgs: z.array(z.string()).optional().describe('Additional command-line arguments')\n },\n examples: [\n 'codeql resolve languages --format=text',\n 'codeql resolve languages --format=json',\n 'codeql resolve languages --format=betterjson'\n ],\n resultProcessor: defaultCLIResultProcessor\n};", "/**\n * CodeQL resolve library-path tool\n */\n\nimport { z } from 'zod';\nimport { CLIToolDefinition, defaultCLIResultProcessor } from '../../lib/cli-tool-registry';\n\nexport const codeqlResolveLibraryPathTool: CLIToolDefinition = {\n name: 'codeql_resolve_library-path',\n description: 'Resolve library path for CodeQL queries and libraries',\n command: 'codeql',\n subcommand: 'resolve library-path',\n inputSchema: {\n language: z.string().optional().describe('Programming language to resolve library path for'),\n format: z.enum(['text', 'json', 'betterjson']).optional()\n .describe('Output format for library path information'),\n verbose: z.boolean().optional().describe('Enable verbose output'),\n additionalArgs: z.array(z.string()).optional().describe('Additional command-line arguments')\n },\n examples: [\n 'codeql resolve library-path --language=java',\n 'codeql resolve library-path --format=json --language=python',\n 'codeql resolve library-path --format=betterjson'\n ],\n resultProcessor: defaultCLIResultProcessor\n};", "/**\n * CodeQL resolve metadata tool\n */\n\nimport { z } from 'zod';\nimport { CLIToolDefinition, defaultCLIResultProcessor } from '../../lib/cli-tool-registry';\n\nexport const codeqlResolveMetadataTool: CLIToolDefinition = {\n name: 'codeql_resolve_metadata',\n description: 'Resolve and return the key-value metadata pairs from a CodeQL query source file.',\n command: 'codeql',\n subcommand: 'resolve metadata',\n inputSchema: {\n query: z.string().describe('Query file to resolve metadata for'),\n format: z.enum(['json']).optional()\n .describe('Output format for metadata information (always JSON, optional for future compatibility)'),\n verbose: z.boolean().optional().describe('Enable verbose output'),\n additionalArgs: z.array(z.string()).optional().describe('Additional command-line arguments')\n },\n examples: [\n 'codeql resolve metadata -- relative-path/2/MyQuery.ql',\n 'codeql resolve metadata --format=json -- /absolute-plus/relative-path/2/MyQuery.ql'\n ],\n resultProcessor: defaultCLIResultProcessor\n};", "/**\n * CodeQL resolve qlref tool\n */\n\nimport { z } from 'zod';\nimport { CLIToolDefinition, createCodeQLSchemas, defaultCLIResultProcessor } from '../../lib/cli-tool-registry';\n\nexport const codeqlResolveQlrefTool: CLIToolDefinition = {\n name: 'codeql_resolve_qlref',\n description: 'Resolve qlref files to their corresponding query files',\n command: 'codeql',\n subcommand: 'resolve qlref',\n inputSchema: {\n qlref: z.string().describe('Path to the .qlref file to resolve'),\n format: z.enum(['text', 'json', 'betterjson']).optional()\n .describe('Output format for qlref resolution'),\n verbose: createCodeQLSchemas.verbose(),\n additionalArgs: createCodeQLSchemas.additionalArgs()\n },\n examples: [\n 'codeql resolve qlref -- test/MyQuery.qlref',\n 'codeql resolve qlref --format=json -- test/MyQuery.qlref',\n 'codeql resolve qlref --format=betterjson -- test/MyQuery.qlref'\n ],\n resultProcessor: defaultCLIResultProcessor\n};", "/**\n * CodeQL resolve queries tool\n */\n\nimport { z } from 'zod';\nimport { CLIToolDefinition, createCodeQLSchemas, CLIExecutionResult } from '../../lib/cli-tool-registry';\n\n/**\n * Result processor that only returns stdout for JSON formats\n * This prevents warnings/info from stderr from corrupting JSON output\n */\nconst jsonOnlyResultProcessor = (\n result: CLIExecutionResult,\n params: Record\n): string => {\n if (!result.success) {\n return `Command failed (exit code ${result.exitCode || 'unknown'}):\\n${result.error || result.stderr}`;\n }\n\n // For JSON formats (including bylanguage), only return stdout to avoid mixing warnings with JSON\n if (params.format === 'json' || params.format === 'betterjson' || params.format === 'bylanguage') {\n return result.stdout || '[]';\n }\n\n // For text format, include warnings\n let output = '';\n\n if (result.stdout) {\n output += result.stdout;\n }\n\n if (result.stderr) {\n if (output) {\n output += '\\n\\nWarnings/Info:\\n';\n }\n output += result.stderr;\n }\n\n if (!output) {\n output = 'Command executed successfully (no output)';\n }\n\n return output;\n};\n\nexport const codeqlResolveQueriesTool: CLIToolDefinition = {\n name: 'codeql_resolve_queries',\n description: 'List available CodeQL queries found on the local filesystem',\n command: 'codeql',\n subcommand: 'resolve queries',\n inputSchema: {\n directory: z.string().optional().describe('Directory to search for queries'),\n language: z.string().optional().describe('Filter queries by programming language'),\n format: z.enum(['text', 'json', 'betterjson', 'bylanguage']).optional()\n .describe('Output format for query list'),\n 'additional-packs': z.union([z.string(), z.array(z.string())]).optional()\n .describe('Additional pack directories to search for CodeQL packs'),\n verbose: createCodeQLSchemas.verbose(),\n additionalArgs: createCodeQLSchemas.additionalArgs()\n },\n examples: [\n 'codeql resolve queries',\n 'codeql resolve queries --language=java --format=json',\n 'codeql resolve queries --format=betterjson -- /path/to/queries',\n 'codeql resolve queries --additional-packs=/path/to/packs codeql/java-queries'\n ],\n resultProcessor: jsonOnlyResultProcessor\n};", "/**\n * CodeQL resolve tests tool\n */\n\nimport { z } from 'zod';\nimport { CLIToolDefinition, createCodeQLSchemas, defaultCLIResultProcessor } from '../../lib/cli-tool-registry';\n\nexport const codeqlResolveTestsTool: CLIToolDefinition = {\n name: 'codeql_resolve_tests',\n description: 'Resolve the local filesystem paths of unit tests and/or queries under some base directory',\n command: 'codeql',\n subcommand: 'resolve tests',\n inputSchema: {\n tests: z.array(z.string()).optional().describe('One or more tests (.ql, .qlref files, or test directories)'),\n format: z.enum(['text', 'json']).optional()\n .describe('Output format for test list'),\n verbose: createCodeQLSchemas.verbose(),\n additionalArgs: createCodeQLSchemas.additionalArgs()\n },\n examples: [\n 'codeql resolve tests',\n 'codeql resolve tests --format=json -- test-directory',\n 'codeql resolve tests --format=json -- test1.ql test2.ql'\n ],\n resultProcessor: defaultCLIResultProcessor\n};", "/**\n * CodeQL test accept tool\n */\n\nimport { z } from 'zod';\nimport { CLIToolDefinition, createCodeQLSchemas, defaultCLIResultProcessor } from '../../lib/cli-tool-registry';\n\nexport const codeqlTestAcceptTool: CLIToolDefinition = {\n name: 'codeql_test_accept',\n description: 'Accept new test results as the expected baseline',\n command: 'codeql',\n subcommand: 'test accept',\n inputSchema: {\n tests: z.array(z.string()).describe('One or more tests (.ql, .qlref files, or test directories)'),\n verbose: createCodeQLSchemas.verbose(),\n additionalArgs: createCodeQLSchemas.additionalArgs()\n },\n examples: [\n 'codeql test accept -- languages/java/test/MyQuery/MyQuery.qlref',\n 'codeql test accept -- languages/java/test/MyQuery/',\n 'codeql test accept -- languages/java/src/MyQuery/MyQuery.ql'\n ],\n resultProcessor: defaultCLIResultProcessor\n};", "/**\n * CodeQL test extract tool\n */\n\nimport { z } from 'zod';\nimport { CLIToolDefinition, createCodeQLSchemas, defaultCLIResultProcessor } from '../../lib/cli-tool-registry';\n\nexport const codeqlTestExtractTool: CLIToolDefinition = {\n name: 'codeql_test_extract',\n description: 'Extract test databases for CodeQL query tests',\n command: 'codeql',\n subcommand: 'test extract',\n inputSchema: {\n tests: z.array(z.string()).describe('One or more test directories or files'),\n language: z.string().optional().describe('Programming language for extraction'),\n threads: createCodeQLSchemas.threads(),\n ram: createCodeQLSchemas.ram(),\n verbose: createCodeQLSchemas.verbose(),\n additionalArgs: createCodeQLSchemas.additionalArgs()\n },\n examples: [\n 'codeql test extract -- languages/java/test/MyQuery/',\n 'codeql test extract --language=java --threads=4 -- test-directory',\n 'codeql test extract --threads=2 --ram=2048 -- multiple/test/directories'\n ],\n resultProcessor: defaultCLIResultProcessor\n};", "/**\n * CodeQL test run tool\n */\n\nimport { CLIToolDefinition, createCodeQLSchemas } from '../../lib/cli-tool-registry';\nimport { z } from 'zod';\n\nexport const codeqlTestRunTool: CLIToolDefinition = {\n name: 'codeql_test_run',\n description: 'Run CodeQL query tests',\n command: 'codeql',\n subcommand: 'test run',\n inputSchema: {\n tests: z.array(z.string()).describe('One or more tests (.ql, .qlref files, or test directories)'),\n 'show-extractor-output': z.boolean().optional()\n .describe('Show output from extractors during test execution'),\n 'keep-databases': z.boolean().optional()\n .describe('Keep test databases after running tests'),\n 'learn': z.boolean().optional()\n .describe('Accept current output as expected for failing tests'),\n logDir: z.string().optional()\n .describe('Custom directory for test execution logs (overrides CODEQL_QUERY_LOG_DIR environment variable). If not provided, uses CODEQL_QUERY_LOG_DIR or defaults to .tmp/query-logs/'),\n threads: createCodeQLSchemas.threads(),\n ram: createCodeQLSchemas.ram(),\n verbose: createCodeQLSchemas.verbose(),\n additionalArgs: createCodeQLSchemas.additionalArgs()\n },\n examples: [\n 'codeql test run /path/to/tests',\n 'codeql test run --learn /path/to/failing/tests',\n 'codeql test run --threads=4 --keep-databases /path/to/tests',\n 'codeql test run --log-dir=/custom/log/path /path/to/tests'\n ]\n};", "/**\n * CodeQL tools registration for MCP server\n * Includes both high-level helpers and CLI command wrappers\n */\n\nimport { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport { z } from 'zod';\nimport { validateCodeQLSyntax } from '../lib/validation';\nimport { createCodeQLQuery } from '../lib/query-scaffolding';\nimport { registerCLITool } from '../lib/cli-tool-registry';\nimport {\n codeqlBqrsDecodeTool,\n codeqlBqrsInfoTool,\n codeqlBqrsInterpretTool,\n codeqlDatabaseAnalyzeTool,\n codeqlDatabaseCreateTool,\n codeqlGenerateLogSummaryTool,\n codeqlGenerateQueryHelpTool,\n codeqlPackInstallTool,\n codeqlPackLsTool,\n codeqlQueryCompileTool,\n codeqlQueryFormatTool,\n codeqlQueryRunTool,\n codeqlResolveDatabaseTool,\n codeqlResolveLanguagesTool,\n codeqlResolveLibraryPathTool,\n codeqlResolveMetadataTool,\n codeqlResolveQlrefTool,\n codeqlResolveQueriesTool,\n codeqlResolveTestsTool,\n codeqlTestAcceptTool,\n codeqlTestExtractTool,\n codeqlTestRunTool,\n registerFindClassPositionTool,\n registerFindCodeQLQueryFilesTool,\n registerFindPredicatePositionTool,\n registerListDatabasesTool,\n registerListQueryRunResultsTool,\n registerProfileCodeQLQueryTool,\n registerQuickEvaluateTool,\n registerRegisterDatabaseTool\n} from './codeql';\nimport { logger } from '../utils/logger';\n\n/**\n * Register all CodeQL tools with the MCP server\n */\nexport function registerCodeQLTools(server: McpServer): void {\n // Register high-level helper tools\n \n // Tool: Validate CodeQL Query (heuristic-based)\n server.tool(\n 'validate_codeql_query',\n 'Quick heuristic validation for CodeQL query structure - checks for common patterns like from/where/select clauses and metadata presence. Does NOT compile the query. For authoritative validation with actual compilation, use codeql_lsp_diagnostics instead.',\n {\n query: z.string().describe('The CodeQL query to validate'),\n language: z.string().optional().describe('Target programming language'),\n },\n async ({ query, language }) => {\n try {\n const validation = validateCodeQLSyntax(query, language);\n return {\n content: [{ type: 'text', text: JSON.stringify(validation, null, 2) }],\n };\n } catch (error) {\n logger.error('Error validating CodeQL query:', error);\n return {\n content: [\n {\n type: 'text',\n text: `Error: ${error instanceof Error ? error.message : 'Unknown error'}`,\n },\n ],\n isError: true,\n };\n }\n }\n );\n\n // Tool: Create CodeQL Query\n server.tool(\n 'create_codeql_query',\n 'Create directory structure and files for a new CodeQL query with tests',\n {\n basePath: z.string().describe('Base path where src/ and test/ directories will be created'),\n queryName: z.string().describe('Name of the query (e.g., MySecurityQuery)'),\n language: z.string().describe('Target programming language (e.g., javascript, python, java)'),\n description: z.string().optional().describe('Description of what the query does'),\n queryId: z.string().optional().describe('Custom query ID (defaults to language/example/queryname)'),\n },\n async ({ basePath, queryName, language, description, queryId }) => {\n try {\n const result = createCodeQLQuery({\n basePath,\n queryName,\n language,\n description,\n queryId\n });\n \n const summary = {\n success: true,\n queryPath: result.queryPath,\n testPath: result.testPath,\n qlrefPath: result.qlrefPath,\n testCodePath: result.testCodePath,\n filesCreated: result.filesCreated,\n nextSteps: [\n 'Review and customize the generated query in: ' + result.queryPath,\n 'Add test cases to: ' + result.testCodePath,\n 'Run codeql_pack_install to install dependencies',\n 'Run codeql_test_extract to create test database',\n 'Run codeql_test_run to execute tests'\n ]\n };\n \n return {\n content: [{ type: 'text', text: JSON.stringify(summary, null, 2) }],\n };\n } catch (error) {\n logger.error('Error creating CodeQL query:', error);\n return {\n content: [\n {\n type: 'text',\n text: `Error: ${error instanceof Error ? error.message : 'Unknown error'}`,\n },\n ],\n isError: true,\n };\n }\n }\n );\n\n // Register CLI tools (alphabetically by tool name)\n registerCLITool(server, codeqlBqrsDecodeTool);\n registerCLITool(server, codeqlBqrsInfoTool);\n registerCLITool(server, codeqlBqrsInterpretTool);\n registerCLITool(server, codeqlDatabaseAnalyzeTool);\n registerCLITool(server, codeqlDatabaseCreateTool);\n registerCLITool(server, codeqlGenerateLogSummaryTool);\n registerCLITool(server, codeqlGenerateQueryHelpTool);\n registerCLITool(server, codeqlPackInstallTool);\n registerCLITool(server, codeqlPackLsTool);\n registerCLITool(server, codeqlQueryCompileTool);\n registerCLITool(server, codeqlQueryFormatTool);\n registerCLITool(server, codeqlQueryRunTool);\n registerCLITool(server, codeqlResolveDatabaseTool);\n registerCLITool(server, codeqlResolveLanguagesTool);\n registerCLITool(server, codeqlResolveLibraryPathTool);\n registerCLITool(server, codeqlResolveMetadataTool);\n registerCLITool(server, codeqlResolveQlrefTool);\n registerCLITool(server, codeqlResolveQueriesTool);\n registerCLITool(server, codeqlResolveTestsTool);\n registerCLITool(server, codeqlTestAcceptTool);\n registerCLITool(server, codeqlTestExtractTool);\n registerCLITool(server, codeqlTestRunTool);\n\n // Register new MCP tools (inspired by JordyZomer/codeql-mcp repository)\n registerFindClassPositionTool(server);\n registerFindCodeQLQueryFilesTool(server);\n registerFindPredicatePositionTool(server);\n registerListDatabasesTool(server);\n registerListQueryRunResultsTool(server);\n registerProfileCodeQLQueryTool(server);\n registerQuickEvaluateTool(server);\n registerRegisterDatabaseTool(server);\n}\n", "/**\n * CodeQL query validation utilities\n */\n\nimport { resolve, normalize, isAbsolute, relative } from 'path';\n\nexport interface CodeQLValidationResult {\n isValid: boolean;\n errors: string[];\n warnings: string[];\n suggestions: string[];\n}\n\n/**\n * Validates CodeQL query syntax and structure\n */\nexport function validateCodeQLSyntax(query: string, _language?: string): CodeQLValidationResult {\n const validation: CodeQLValidationResult = {\n isValid: true,\n errors: [],\n warnings: [],\n suggestions: [],\n };\n\n if (!query.trim()) {\n validation.isValid = false;\n validation.errors.push('Query cannot be empty');\n return validation;\n }\n\n if (!query.includes('from') && !query.includes('select')) {\n validation.warnings.push('Query should typically include \"from\" and \"select\" clauses');\n }\n\n if (!query.includes('@name') && !query.includes('@description')) {\n validation.suggestions.push('Consider adding @name and @description metadata');\n }\n\n return validation;\n}\n\n/**\n * Validates a file path to prevent path traversal attacks\n * @param filePath - The file path to validate\n * @param workspaceRoot - Optional workspace root directory. If not provided, allows any absolute path but still blocks traversal attempts\n * @returns The validated absolute path\n * @throws Error if the path contains path traversal sequences\n */\nexport function validateFilePath(filePath: string, workspaceRoot?: string): string {\n // Normalize the path to resolve any . or .. segments\n const normalizedPath = normalize(filePath);\n \n // Check for path traversal attempts in the normalized path\n // This blocks paths like \"../../../etc/passwd\" even after normalization\n if (normalizedPath.includes('..')) {\n throw new Error(`Invalid file path: path traversal detected in \"${filePath}\"`);\n }\n \n // Resolve to absolute path\n const absolutePath = isAbsolute(normalizedPath) \n ? normalizedPath \n : resolve(workspaceRoot || process.cwd(), normalizedPath);\n \n // If workspace root is specified, ensure the resolved path is within it\n if (workspaceRoot) {\n const relativePath = relative(workspaceRoot, absolutePath);\n \n // If relative path starts with .. or is absolute, it's outside workspace\n if (relativePath.startsWith('..') || isAbsolute(relativePath)) {\n throw new Error(`Invalid file path: \"${filePath}\" is outside the workspace root`);\n }\n }\n \n return absolutePath;\n}", "/**\n * CodeQL query scaffolding utilities\n * Handles creation of query directory structure and files\n */\n\nimport * as fs from 'fs';\nimport * as path from 'path';\n\nexport interface QueryScaffoldingOptions {\n basePath: string;\n queryName: string;\n language: string;\n description?: string;\n queryId?: string;\n}\n\nexport interface QueryScaffoldingResult {\n queryPath: string;\n testPath: string;\n qlrefPath: string;\n testCodePath: string;\n filesCreated: string[];\n}\n\n/**\n * Get the file extension for test code based on language\n */\nfunction getLanguageExtension(language: string): string {\n const extensions: Record = {\n javascript: 'js',\n typescript: 'ts',\n python: 'py',\n java: 'java',\n csharp: 'cs',\n cpp: 'cpp',\n go: 'go',\n ruby: 'rb',\n actions: 'yml'\n };\n return extensions[language.toLowerCase()] || 'txt';\n}\n\n/**\n * Generate query template content\n */\nfunction generateQueryTemplate(\n queryName: string,\n language: string,\n description?: string,\n queryId?: string\n): string {\n const desc = description || `${queryName} query`;\n const id = queryId || `${language}/example/${queryName.toLowerCase()}`;\n \n return `/**\n * @id ${id}\n * @name ${queryName}\n * @description ${desc}\n * @kind problem\n * @precision medium\n * @problem.severity warning\n */\n\nimport ${language}\n\n// TODO: Implement query logic\nfrom File f\nwhere f.getBaseName() = \"${queryName}.${getLanguageExtension(language)}\"\nselect f, \"TODO: Add query logic\"\n`;\n}\n\n/**\n * Create the directory structure and files for a new CodeQL query\n */\nexport function createCodeQLQuery(options: QueryScaffoldingOptions): QueryScaffoldingResult {\n const { basePath, queryName, language, description, queryId } = options;\n \n // Resolve absolute paths\n const absoluteBasePath = path.resolve(basePath);\n \n // Define paths with intermediate directory\n const srcDir = path.join(absoluteBasePath, 'src', queryName);\n const testDir = path.join(absoluteBasePath, 'test', queryName);\n \n const queryPath = path.join(srcDir, `${queryName}.ql`);\n const qlrefPath = path.join(testDir, `${queryName}.qlref`);\n const testCodePath = path.join(testDir, `${queryName}.${getLanguageExtension(language)}`);\n \n const filesCreated: string[] = [];\n \n try {\n // Create directories (recursive: true is a no-op if they already exist)\n fs.mkdirSync(srcDir, { recursive: true });\n fs.mkdirSync(testDir, { recursive: true });\n \n // Create files atomically using 'wx' flag (exclusive create) to avoid\n // TOCTOU race between existsSync check and writeFileSync (CWE-367).\n // The 'wx' flag fails with EEXIST if the file already exists.\n try {\n const queryContent = generateQueryTemplate(queryName, language, description, queryId);\n fs.writeFileSync(queryPath, queryContent, { encoding: 'utf8', flag: 'wx' });\n filesCreated.push(queryPath);\n } catch (e: unknown) {\n const err = e as { code?: string };\n if (err.code !== 'EEXIST') throw e;\n }\n \n try {\n const qlrefContent = `${queryName}/${queryName}.ql\\n`;\n fs.writeFileSync(qlrefPath, qlrefContent, { encoding: 'utf8', flag: 'wx' });\n filesCreated.push(qlrefPath);\n } catch (e: unknown) {\n const err = e as { code?: string };\n if (err.code !== 'EEXIST') throw e;\n }\n \n try {\n const testCodeContent = `// Test code for ${queryName}\\n// TODO: Add test cases\\n`;\n fs.writeFileSync(testCodePath, testCodeContent, { encoding: 'utf8', flag: 'wx' });\n filesCreated.push(testCodePath);\n } catch (e: unknown) {\n const err = e as { code?: string };\n if (err.code !== 'EEXIST') throw e;\n }\n \n return {\n queryPath,\n testPath: testDir,\n qlrefPath,\n testCodePath,\n filesCreated\n };\n } catch (error) {\n throw new Error(`Failed to create query scaffolding: ${error instanceof Error ? error.message : 'Unknown error'}`);\n }\n}\n", "/**\n * CodeQL learning resources utilities\n */\n\nimport { readFileSync } from 'fs';\nimport { join, dirname } from 'path';\nimport { fileURLToPath } from 'url';\n\nconst __filename = fileURLToPath(import.meta.url);\nconst __dirname = dirname(__filename);\n\n/**\n * Get the getting started guide content\n */\nexport function getGettingStartedGuide(): string {\n try {\n return readFileSync(join(__dirname, '../resources/getting-started.md'), 'utf-8');\n } catch {\n return 'Getting started guide not available';\n }\n}\n\n/**\n * Get the query basics guide content\n */\nexport function getQueryBasicsGuide(): string {\n try {\n return readFileSync(join(__dirname, '../resources/query-basics.md'), 'utf-8');\n } catch {\n return 'Query basics guide not available';\n }\n}\n\n/**\n * Get the security templates content\n */\nexport function getSecurityTemplates(): string {\n try {\n return readFileSync(join(__dirname, '../resources/security-templates.md'), 'utf-8');\n } catch {\n return 'Security templates not available';\n }\n}\n\n/**\n * Get the performance patterns content\n */\nexport function getPerformancePatterns(): string {\n try {\n return readFileSync(join(__dirname, '../resources/performance-patterns.md'), 'utf-8');\n } catch {\n return 'Performance patterns not available';\n }\n}", "/**\n * CodeQL resources registration for MCP server\n */\n\nimport { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport {\n getGettingStartedGuide,\n getQueryBasicsGuide,\n getSecurityTemplates,\n getPerformancePatterns,\n} from '../lib/resources';\n\n/**\n * Register all CodeQL resources with the MCP server\n */\nexport function registerCodeQLResources(server: McpServer): void {\n // Getting Started Guide\n server.resource(\n 'CodeQL Getting Started',\n 'codeql://learning/getting-started',\n {\n description: 'Comprehensive introduction to CodeQL for beginners',\n mimeType: 'text/markdown',\n },\n async () => {\n return {\n contents: [\n {\n uri: 'codeql://learning/getting-started',\n mimeType: 'text/markdown',\n text: getGettingStartedGuide(),\n },\n ],\n };\n }\n );\n\n // Query Basics Guide\n server.resource(\n 'CodeQL Query Basics',\n 'codeql://learning/query-basics',\n {\n description: 'Learn the fundamentals of writing CodeQL queries',\n mimeType: 'text/markdown',\n },\n async () => {\n return {\n contents: [\n {\n uri: 'codeql://learning/query-basics',\n mimeType: 'text/markdown',\n text: getQueryBasicsGuide(),\n },\n ],\n };\n }\n );\n\n // Security Templates\n server.resource(\n 'CodeQL Security Templates',\n 'codeql://templates/security',\n {\n description: 'Ready-to-use security query templates',\n mimeType: 'text/markdown',\n },\n async () => {\n return {\n contents: [\n {\n uri: 'codeql://templates/security',\n mimeType: 'text/markdown',\n text: getSecurityTemplates(),\n },\n ],\n };\n }\n );\n\n // Performance Patterns\n server.resource(\n 'CodeQL Performance Patterns',\n 'codeql://patterns/performance',\n {\n description: 'Best practices for writing efficient CodeQL queries',\n mimeType: 'text/markdown',\n },\n async () => {\n return {\n contents: [\n {\n uri: 'codeql://patterns/performance',\n mimeType: 'text/markdown',\n text: getPerformancePatterns(),\n },\n ],\n };\n }\n );\n}\n", "/**\n * CodeQL LSP Diagnostics tool for MCP server.\n *\n * Provides real-time QL code validation through LSP communication.\n * Renamed from `codeql_language_server_eval` to `codeql_lsp_diagnostics`\n * for consistency with the `codeql_lsp_*` tool naming convention.\n */\n\nimport { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport { z } from 'zod';\nimport { Diagnostic, LanguageServerOptions } from '../../lib/language-server';\nimport { logger } from '../../utils/logger';\nimport { getProjectTmpDir } from '../../utils/temp-dir';\nimport { join } from 'path';\nimport { pathToFileURL } from 'url';\nimport { getInitializedLanguageServer } from './lsp-server-helper';\n\nexport interface LspDiagnosticsParams {\n qlCode: string;\n serverOptions?: LanguageServerOptions;\n workspaceUri?: string;\n}\n\nexport interface LspDiagnosticsResult {\n diagnostics: Diagnostic[];\n formattedOutput: string;\n isValid: boolean;\n summary: {\n errorCount: number;\n hintCount: number;\n infoCount: number;\n warningCount: number;\n };\n}\n\n/**\n * Format diagnostics for human-readable output.\n */\nfunction formatDiagnostics(diagnostics: Diagnostic[]): string {\n if (diagnostics.length === 0) {\n return '\u2705 No issues found in QL code';\n }\n\n const lines: string[] = [];\n lines.push(`Found ${diagnostics.length} issue(s):\\n`);\n\n diagnostics.forEach((diagnostic, index) => {\n const severityIcon = getSeverityIcon(diagnostic.severity);\n const severityName = getSeverityName(diagnostic.severity);\n const location = `Line ${diagnostic.range.start.line + 1}, Column ${diagnostic.range.start.character + 1}`;\n\n lines.push(`${index + 1}. ${severityIcon} ${severityName} at ${location}`);\n lines.push(` ${diagnostic.message}`);\n if (diagnostic.source) {\n lines.push(` Source: ${diagnostic.source}`);\n }\n if (diagnostic.code) {\n lines.push(` Code: ${diagnostic.code}`);\n }\n lines.push('');\n });\n\n return lines.join('\\n');\n}\n\nfunction getSeverityIcon(severity: number): string {\n switch (severity) {\n case 1: return '\u274C'; // Error\n case 2: return '\u26A0\uFE0F'; // Warning\n case 3: return '\u2139\uFE0F'; // Information\n case 4: return '\uD83D\uDCA1'; // Hint\n default: return '\u2753';\n }\n}\n\nfunction getSeverityName(severity: number): string {\n switch (severity) {\n case 1: return 'Error';\n case 2: return 'Warning';\n case 3: return 'Information';\n case 4: return 'Hint';\n default: return 'Unknown';\n }\n}\n\n/**\n * Evaluate QL code using the CodeQL Language Server and return diagnostics.\n */\nexport async function lspDiagnostics({\n qlCode,\n workspaceUri,\n serverOptions = {}\n}: LspDiagnosticsParams): Promise {\n try {\n logger.info('Evaluating QL code via Language Server...');\n\n const languageServer = await getInitializedLanguageServer({\n serverOptions,\n workspaceUri,\n });\n\n // Generate unique URI for this evaluation\n const evalUri = pathToFileURL(join(getProjectTmpDir('lsp-eval'), `eval_${Date.now()}.ql`)).href;\n\n const diagnostics = await languageServer.evaluateQL(qlCode, evalUri);\n\n // Count diagnostics by severity\n const summary = {\n errorCount: diagnostics.filter(d => d.severity === 1).length,\n hintCount: diagnostics.filter(d => d.severity === 4).length,\n infoCount: diagnostics.filter(d => d.severity === 3).length,\n warningCount: diagnostics.filter(d => d.severity === 2).length,\n };\n\n const isValid = summary.errorCount === 0;\n const formattedOutput = formatDiagnostics(diagnostics);\n\n logger.info(`QL evaluation complete. Valid: ${isValid}, Issues: ${diagnostics.length}`);\n\n return {\n diagnostics,\n formattedOutput,\n isValid,\n summary,\n };\n\n } catch (error) {\n logger.error('Error evaluating QL code:', error);\n throw new Error(`QL evaluation failed: ${error instanceof Error ? error.message : 'Unknown error'}`);\n }\n}\n\n/**\n * Shutdown the language server via the server manager.\n */\nexport async function shutdownDiagnosticsServer(): Promise {\n const { getServerManager } = await import('../../lib/server-manager');\n const manager = getServerManager();\n await manager.shutdownServer('language');\n}\n\n/**\n * Register the codeql_lsp_diagnostics tool with the MCP server.\n */\nexport function registerLspDiagnosticsTool(server: McpServer): void {\n server.tool(\n 'codeql_lsp_diagnostics',\n 'Authoritative syntax and semantic validation of CodeQL (QL) code via the CodeQL Language Server. Compiles the query and provides real-time diagnostics with precise error locations. Use this for accurate validation; for quick heuristic checks without compilation, use validate_codeql_query instead. Note: inline ql_code is evaluated as a virtual document and cannot resolve pack imports (e.g. `import javascript`). For validating queries with imports, use codeql_query_compile on the actual file instead.',\n {\n log_level: z.enum(['OFF', 'ERROR', 'WARN', 'INFO', 'DEBUG', 'TRACE', 'ALL']).optional().describe('Language server log level'),\n ql_code: z.string().describe('The CodeQL (QL) code to evaluate for syntax and semantic errors'),\n search_path: z.string().optional().describe('Optional search path for CodeQL libraries'),\n workspace_uri: z.string().optional().describe('Optional workspace URI for context (defaults to ./ql directory)'),\n },\n async ({ ql_code, workspace_uri, search_path, log_level }) => {\n try {\n const serverOptions: LanguageServerOptions = {};\n\n if (search_path) {\n serverOptions.searchPath = search_path;\n }\n if (log_level) {\n serverOptions.loglevel = log_level;\n }\n\n const result = await lspDiagnostics({\n qlCode: ql_code,\n serverOptions,\n workspaceUri: workspace_uri,\n });\n\n // Return structured result\n const responseContent = {\n diagnostics: result.diagnostics.map(d => ({\n code: d.code,\n column: d.range.start.character + 1, // Convert to 1-based column numbers\n line: d.range.start.line + 1, // Convert to 1-based line numbers\n message: d.message,\n severity: getSeverityName(d.severity),\n source: d.source,\n })),\n formattedOutput: result.formattedOutput,\n isValid: result.isValid,\n summary: result.summary,\n };\n\n return {\n content: [\n {\n text: JSON.stringify(responseContent, null, 2),\n type: 'text',\n }\n ],\n };\n\n } catch (error) {\n logger.error('Error in codeql_lsp_diagnostics tool:', error);\n return {\n content: [\n {\n text: `Error: ${error instanceof Error ? error.message : 'Unknown error'}`,\n type: 'text',\n },\n ],\n isError: true,\n };\n }\n }\n );\n\n // NOTE: Cleanup is handled centrally by shutdownServerManager() in\n // codeql-development-mcp-server.ts (setupGracefulShutdown). Registering\n // additional process.on('SIGINT'/'SIGTERM') handlers here would\n // accumulate on repeated calls and is unnecessary.\n}\n", "/**\n * Shared helper for obtaining a running, initialized CodeQL Language Server.\n *\n * Both `lsp-diagnostics.ts` and `lsp-handlers.ts` need to:\n * 1. Build a `LanguageServerConfig` with sensible defaults\n * 2. Obtain a server instance from the `CodeQLServerManager`\n * 3. Resolve a workspace URI (relative \u2192 absolute \u2192 `file://`)\n * 4. Initialize the server with the resolved workspace\n *\n * Centralizing this logic avoids duplication and ensures consistent\n * default behaviour across all LSP tools.\n */\n\nimport { isAbsolute, resolve } from 'path';\nimport { pathToFileURL } from 'url';\n\nimport { CodeQLLanguageServer, LanguageServerOptions } from '../../lib/language-server';\nimport { LanguageServerConfig } from '../../lib/server-config';\nimport { getServerManager } from '../../lib/server-manager';\nimport { logger } from '../../utils/logger';\n\n/**\n * Options accepted by {@link getInitializedLanguageServer}.\n */\nexport interface InitializedServerOptions {\n /** Language-server-level options (loglevel, searchPath, etc.). */\n serverOptions?: LanguageServerOptions;\n /** Workspace URI \u2014 may be a `file://` URI, absolute path, or relative path. */\n workspaceUri?: string;\n}\n\n/**\n * Return a running, initialized `CodeQLLanguageServer`.\n *\n * - Resolves `searchPath` to the bundled `ql` directory when not provided.\n * - Converts relative / bare-directory `workspaceUri` paths to `file://` URIs\n * resolved against `getUserWorkspaceDir()` (respects `CODEQL_MCP_WORKSPACE`).\n * - Falls back to the bundled `ql` directory when no workspace is given.\n * - Delegates lifecycle management to the global `CodeQLServerManager`.\n */\nexport async function getInitializedLanguageServer(\n opts: InitializedServerOptions = {},\n): Promise {\n const { packageRootDir: pkgRoot, getUserWorkspaceDir } = await import('../../utils/package-paths');\n const options = opts.serverOptions ?? {};\n\n const config: LanguageServerConfig = {\n checkErrors: 'ON_CHANGE',\n loglevel: options.loglevel ?? 'WARN',\n searchPath: options.searchPath ?? resolve(pkgRoot, 'ql'),\n synchronous: options.synchronous,\n verbosity: options.verbosity,\n };\n\n const manager = getServerManager();\n const server = await manager.getLanguageServer(config);\n\n // Normalize workspace URI: convert relative / bare directory paths to\n // file:// URIs against getUserWorkspaceDir() (respects CODEQL_MCP_WORKSPACE).\n let effectiveUri = opts.workspaceUri;\n if (effectiveUri && !effectiveUri.startsWith('file://')) {\n const absWorkspace = isAbsolute(effectiveUri)\n ? effectiveUri\n : resolve(getUserWorkspaceDir(), effectiveUri);\n effectiveUri = pathToFileURL(absWorkspace).href;\n }\n effectiveUri = effectiveUri ?? pathToFileURL(resolve(pkgRoot, 'ql')).href;\n\n await server.initialize(effectiveUri);\n logger.debug(`Language server initialized with workspace: ${effectiveUri}`);\n\n return server;\n}\n", "/**\n * CodeQL LSP tool handlers.\n *\n * Bridges MCP tool invocations to LSP requests on the CodeQL Language Server.\n * Each handler acquires a language server via the CodeQLServerManager,\n * opens the requested document, sends the LSP request, and returns the result.\n */\n\nimport { readFile } from 'fs/promises';\nimport { isAbsolute, resolve } from 'path';\nimport { pathToFileURL } from 'url';\n\nimport {\n CompletionItem,\n LSPLocation,\n TextDocumentPositionParams,\n} from '../../lib/language-server';\nimport { logger } from '../../utils/logger';\nimport { getUserWorkspaceDir } from '../../utils/package-paths';\nimport { getInitializedLanguageServer } from './lsp-server-helper';\n\n/**\n * Common parameters for LSP tool invocations.\n */\nexport interface LSPToolParams {\n /** 0-based character offset within the line. */\n character: number;\n /** Optional override for the file content (if not reading from disk). */\n fileContent?: string;\n /**\n * Path to the QL file. May be absolute or relative.\n * Relative paths are resolved against `getUserWorkspaceDir()`\n * (respects the `CODEQL_MCP_WORKSPACE` environment variable).\n */\n filePath: string;\n /** 0-based line number in the document. */\n line: number;\n /** Optional search path for CodeQL libraries. */\n searchPath?: string;\n /** Optional workspace URI for context. */\n workspaceUri?: string;\n}\n\n/**\n * Get a running, initialized language server for the given parameters.\n */\nasync function getInitializedServer(params: LSPToolParams) {\n return getInitializedLanguageServer({\n serverOptions: { searchPath: params.searchPath },\n workspaceUri: params.workspaceUri,\n });\n}\n\n/**\n * Resolve the file path to an absolute path and file:// URI.\n */\nfunction prepareDocumentPosition(\n params: LSPToolParams,\n): { absPath: string; docUri: string } {\n // Resolve relative paths against getUserWorkspaceDir() so that\n // CODEQL_MCP_WORKSPACE is respected and behaviour is consistent across tools.\n const absPath = isAbsolute(params.filePath)\n ? params.filePath\n : resolve(getUserWorkspaceDir(), params.filePath);\n const docUri = pathToFileURL(absPath).href;\n\n return { absPath, docUri };\n}\n\n/**\n * Read file content and open the document in the language server.\n */\nasync function openDocumentForPosition(\n server: Awaited>,\n params: LSPToolParams,\n absPath: string,\n docUri: string,\n): Promise {\n // Read file content from disk or use provided content\n let text: string;\n if (params.fileContent) {\n text = params.fileContent;\n } else {\n try {\n text = await readFile(absPath, 'utf-8');\n } catch (error) {\n throw new Error(`Cannot read file: ${absPath}: ${error instanceof Error ? error.message : error}`);\n }\n }\n\n // Open the document so the language server knows about it\n server.openDocument(docUri, text);\n\n return {\n position: { character: params.character, line: params.line },\n textDocument: { uri: docUri },\n };\n}\n\n/**\n * Get code completions at a position.\n */\nexport async function lspCompletion(params: LSPToolParams): Promise {\n logger.info(`LSP completion at ${params.filePath}:${params.line}:${params.character}`);\n const server = await getInitializedServer(params);\n const { absPath, docUri } = prepareDocumentPosition(params);\n const positionParams = await openDocumentForPosition(server, params, absPath, docUri);\n\n try {\n return await server.getCompletions(positionParams);\n } finally {\n server.closeDocument(docUri);\n }\n}\n\n/**\n * Go to definition of a symbol at a position.\n */\nexport async function lspDefinition(params: LSPToolParams): Promise {\n logger.info(`LSP definition at ${params.filePath}:${params.line}:${params.character}`);\n const server = await getInitializedServer(params);\n const { absPath, docUri } = prepareDocumentPosition(params);\n const positionParams = await openDocumentForPosition(server, params, absPath, docUri);\n\n try {\n return await server.getDefinition(positionParams);\n } finally {\n server.closeDocument(docUri);\n }\n}\n\n/**\n * Find all references to a symbol at a position.\n */\nexport async function lspReferences(params: LSPToolParams): Promise {\n logger.info(`LSP references at ${params.filePath}:${params.line}:${params.character}`);\n const server = await getInitializedServer(params);\n const { absPath, docUri } = prepareDocumentPosition(params);\n const positionParams = await openDocumentForPosition(server, params, absPath, docUri);\n\n try {\n return await server.getReferences({\n ...positionParams,\n context: { includeDeclaration: true },\n });\n } finally {\n server.closeDocument(docUri);\n }\n}\n", "/**\n * CodeQL LSP MCP tool definitions.\n *\n * Registers four LSP-based tools:\n * - codeql_lsp_completion \u2013 code completions at cursor position\n * - codeql_lsp_definition \u2013 go to definition\n * - codeql_lsp_diagnostics \u2013 QL code validation via LSP diagnostics\n * - codeql_lsp_references \u2013 find all references\n */\n\nimport { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport { z } from 'zod';\nimport { registerLspDiagnosticsTool } from './lsp-diagnostics';\nimport {\n lspCompletion,\n lspDefinition,\n lspReferences,\n} from './lsp-handlers';\nimport { logger } from '../../utils/logger';\n\n/**\n * Shared Zod schema for the common LSP tool parameters.\n */\nconst lspParamsSchema = {\n character: z.number().int().min(0).describe('0-based character offset within the line'),\n file_content: z.string().optional().describe('Optional file content override (reads from disk if omitted)'),\n file_path: z.string().describe('Path to the CodeQL (.ql/.qll) file. Relative paths are resolved against the user workspace directory (see CODEQL_MCP_WORKSPACE).'),\n line: z.number().int().min(0).describe('0-based line number in the document'),\n search_path: z.string().optional().describe('Optional search path for CodeQL libraries'),\n workspace_uri: z.string().optional().describe('Optional workspace URI for context (defaults to ./ql directory)'),\n};\n\n/**\n * Helper to build the handler params from the raw MCP tool input.\n */\nfunction toHandlerParams(input: {\n character: number;\n file_content?: string;\n file_path: string;\n line: number;\n search_path?: string;\n workspace_uri?: string;\n}) {\n return {\n character: input.character,\n fileContent: input.file_content,\n filePath: input.file_path,\n line: input.line,\n searchPath: input.search_path,\n workspaceUri: input.workspace_uri,\n };\n}\n\n/**\n * Register all LSP-based tools with the MCP server.\n */\nexport function registerLSPTools(server: McpServer): void {\n // --- codeql_lsp_diagnostics (relocated from codeql_language_server_eval) ---\n registerLspDiagnosticsTool(server);\n\n // --- codeql_lsp_completion ---\n server.tool(\n 'codeql_lsp_completion',\n 'Get code completions at a cursor position in a CodeQL file. Returns completion items with labels, documentation, and insert text. The file must be a .ql or .qll file. IMPORTANT: Set workspace_uri to the pack or workspace root directory for dependency resolution; without it, completions for imported libraries will be empty.',\n lspParamsSchema,\n async (input) => {\n try {\n const items = await lspCompletion(toHandlerParams(input));\n return {\n content: [{\n text: JSON.stringify({\n completionCount: items.length,\n items: items.map((item) => ({\n detail: item.detail,\n documentation: item.documentation,\n insertText: item.insertText,\n kind: item.kind,\n label: item.label,\n })),\n }, null, 2),\n type: 'text' as const,\n }],\n };\n } catch (error) {\n logger.error('codeql_lsp_completion error:', error);\n return {\n content: [{ text: `Error: ${error instanceof Error ? error.message : 'Unknown error'}`, type: 'text' as const }],\n isError: true,\n };\n }\n },\n );\n\n // --- codeql_lsp_definition ---\n server.tool(\n 'codeql_lsp_definition',\n 'Go to the definition of a CodeQL symbol at a given position. Returns one or more file locations where the symbol is defined. Set workspace_uri to the pack root for dependency resolution.',\n lspParamsSchema,\n async (input) => {\n try {\n const locations = await lspDefinition(toHandlerParams(input));\n return {\n content: [{\n text: JSON.stringify({\n definitionCount: locations.length,\n locations: locations.map((loc) => ({\n endCharacter: loc.range.end.character,\n endLine: loc.range.end.line + 1,\n startCharacter: loc.range.start.character,\n startLine: loc.range.start.line + 1,\n uri: loc.uri,\n })),\n }, null, 2),\n type: 'text' as const,\n }],\n };\n } catch (error) {\n logger.error('codeql_lsp_definition error:', error);\n return {\n content: [{ text: `Error: ${error instanceof Error ? error.message : 'Unknown error'}`, type: 'text' as const }],\n isError: true,\n };\n }\n },\n );\n\n // --- codeql_lsp_references ---\n server.tool(\n 'codeql_lsp_references',\n 'Find all references to a CodeQL symbol at a given position. Returns file locations of all usages, including the declaration. Set workspace_uri to the pack root for dependency resolution.',\n lspParamsSchema,\n async (input) => {\n try {\n const locations = await lspReferences(toHandlerParams(input));\n return {\n content: [{\n text: JSON.stringify({\n locations: locations.map((loc) => ({\n endCharacter: loc.range.end.character,\n endLine: loc.range.end.line + 1,\n startCharacter: loc.range.start.character,\n startLine: loc.range.start.line + 1,\n uri: loc.uri,\n })),\n referenceCount: locations.length,\n }, null, 2),\n type: 'text' as const,\n }],\n };\n } catch (error) {\n logger.error('codeql_lsp_references error:', error);\n return {\n content: [{ text: `Error: ${error instanceof Error ? error.message : 'Unknown error'}`, type: 'text' as const }],\n isError: true,\n };\n }\n },\n );\n}\n", "/**\n * Language-specific resources implementation\n * Dynamically loads and serves language-specific AST references and security patterns\n */\n\nimport { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport { readFileSync, existsSync } from 'fs';\nimport { join } from 'path';\nimport { LANGUAGE_RESOURCES } from '../types/language-types';\nimport { workspaceRootDir } from '../utils/package-paths';\nimport { logger } from '../utils/logger';\n\n/**\n * Get the base path for ql resources.\n * Uses the workspace root (monorepo root or package root) so that\n * resource files are found regardless of the server's process.cwd().\n */\nfunction getQLBasePath(): string {\n return workspaceRootDir;\n}\n\n/**\n * Load content from a resource file\n */\nfunction loadResourceContent(relativePath: string): string | null {\n try {\n const fullPath = join(getQLBasePath(), relativePath);\n \n if (!existsSync(fullPath)) {\n logger.warn(`Resource file not found: ${fullPath}`);\n return null;\n }\n \n return readFileSync(fullPath, 'utf-8');\n } catch (error) {\n logger.error(`Error loading resource file ${relativePath}:`, error);\n return null;\n }\n}\n\n/**\n * Register language-specific AST resources\n */\nexport function registerLanguageASTResources(server: McpServer): void {\n for (const langResource of LANGUAGE_RESOURCES) {\n if (!langResource.astFile) continue;\n \n const resourceUri = `codeql://languages/${langResource.language}/ast`;\n \n server.resource(\n `${langResource.language.toUpperCase()} AST Reference`,\n resourceUri,\n {\n description: `CodeQL AST class reference for ${langResource.language} programs`,\n mimeType: 'text/markdown'\n },\n async () => {\n const content = loadResourceContent(langResource.astFile!);\n \n if (!content) {\n return {\n contents: [{\n uri: resourceUri,\n mimeType: 'text/markdown',\n text: `# ${langResource.language.toUpperCase()} AST Reference\\n\\nResource file not found or could not be loaded.`\n }]\n };\n }\n \n return {\n contents: [{\n uri: resourceUri,\n mimeType: 'text/markdown',\n text: content\n }]\n };\n }\n );\n }\n}\n\n/**\n * Register language-specific security pattern resources\n */\nexport function registerLanguageSecurityResources(server: McpServer): void {\n for (const langResource of LANGUAGE_RESOURCES) {\n if (!langResource.securityFile) continue;\n \n const resourceUri = `codeql://languages/${langResource.language}/security`;\n \n server.resource(\n `${langResource.language.toUpperCase()} Security Patterns`,\n resourceUri,\n {\n description: `CodeQL security query patterns and framework modeling for ${langResource.language}`,\n mimeType: 'text/markdown'\n },\n async () => {\n const content = loadResourceContent(langResource.securityFile!);\n \n if (!content) {\n return {\n contents: [{\n uri: resourceUri,\n mimeType: 'text/markdown',\n text: `# ${langResource.language.toUpperCase()} Security Patterns\\n\\nResource file not found or could not be loaded.`\n }]\n };\n }\n \n return {\n contents: [{\n uri: resourceUri,\n mimeType: 'text/markdown',\n text: content\n }]\n };\n }\n );\n }\n}\n\n/**\n * Register additional language-specific resources (like Go's dataflow patterns)\n */\nexport function registerLanguageAdditionalResources(server: McpServer): void {\n for (const langResource of LANGUAGE_RESOURCES) {\n if (!langResource.additionalFiles) continue;\n \n for (const [resourceType, filePath] of Object.entries(langResource.additionalFiles)) {\n const resourceUri = `codeql://languages/${langResource.language}/${resourceType}`;\n \n server.resource(\n `${langResource.language.toUpperCase()} ${resourceType.replace('-', ' ').replace(/\\b\\w/g, l => l.toUpperCase())}`,\n resourceUri,\n {\n description: `CodeQL ${resourceType.replace('-', ' ')} guide for ${langResource.language}`,\n mimeType: 'text/markdown'\n },\n async () => {\n const content = loadResourceContent(filePath);\n \n if (!content) {\n return {\n contents: [{\n uri: resourceUri,\n mimeType: 'text/markdown',\n text: `# ${langResource.language.toUpperCase()} ${resourceType.replace('-', ' ').replace(/\\b\\w/g, l => l.toUpperCase())}\\n\\nResource file not found or could not be loaded.`\n }]\n };\n }\n \n return {\n contents: [{\n uri: resourceUri,\n mimeType: 'text/markdown',\n text: content\n }]\n };\n }\n );\n }\n }\n}\n\n/**\n * Register all language-specific resources\n */\nexport function registerLanguageResources(server: McpServer): void {\n logger.info('Registering language-specific resources...');\n \n // Register AST references for all languages\n registerLanguageASTResources(server);\n \n // Register security patterns for languages that have them\n registerLanguageSecurityResources(server);\n \n // Register additional resources (like Go's dataflow patterns)\n registerLanguageAdditionalResources(server);\n \n logger.info(`Registered resources for ${LANGUAGE_RESOURCES.length} languages`);\n}", "/**\n * Type definitions and constants for language-specific resources\n */\n\n// Language mappings to resource files\nexport interface LanguageResource {\n language: string;\n astFile?: string;\n securityFile?: string;\n additionalFiles?: Record;\n}\n\nexport const LANGUAGE_RESOURCES: LanguageResource[] = [\n {\n language: 'actions',\n astFile: 'ql/languages/actions/tools/dev/actions_ast.prompt.md'\n },\n {\n language: 'cpp',\n astFile: 'ql/languages/cpp/tools/dev/cpp_ast.prompt.md',\n securityFile: 'ql/languages/cpp/tools/dev/cpp_security_query_guide.prompt.md'\n },\n {\n language: 'csharp',\n astFile: 'ql/languages/csharp/tools/dev/csharp_ast.prompt.md',\n securityFile: 'ql/languages/csharp/tools/dev/csharp_security_query_guide.prompt.md'\n },\n {\n language: 'go',\n astFile: 'ql/languages/go/tools/dev/go_ast.prompt.md',\n securityFile: 'ql/languages/go/tools/dev/go_security_query_guide.prompt.md',\n additionalFiles: {\n 'dataflow': 'ql/languages/go/tools/dev/go_dataflow.prompt.md',\n 'library-modeling': 'ql/languages/go/tools/dev/go_library_modeling.prompt.md',\n 'basic-queries': 'ql/languages/go/tools/dev/go_basic_queries.prompt.md'\n }\n },\n {\n language: 'java',\n astFile: 'ql/languages/java/tools/dev/java_ast.prompt.md'\n },\n {\n language: 'javascript',\n astFile: 'ql/languages/javascript/tools/dev/javascript_ast.prompt.md',\n securityFile: 'ql/languages/javascript/tools/dev/javascript_security_query_guide.prompt.md'\n },\n {\n language: 'python',\n astFile: 'ql/languages/python/tools/dev/python_ast.prompt.md',\n securityFile: 'ql/languages/python/tools/dev/python_security_query_guide.prompt.md'\n },\n {\n language: 'ql',\n astFile: 'ql/languages/ql/tools/dev/ql_ast.prompt.md'\n },\n {\n language: 'ruby',\n astFile: 'ql/languages/ruby/tools/dev/ruby_ast.prompt.md'\n }\n];", "/**\n * MCP Server workflow prompts for CodeQL development\n *\n * All prompt content is loaded from .prompt.md files in this directory.\n * This file only handles prompt registration and parameter processing.\n */\n\nimport { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport { z } from 'zod';\nimport { basename } from 'path';\nimport { loadPromptTemplate, processPromptTemplate } from './prompt-loader';\nimport { logger } from '../utils/logger';\n\n/** Supported CodeQL languages for tools queries */\nexport const SUPPORTED_LANGUAGES = [\n 'actions',\n 'cpp',\n 'csharp',\n 'go',\n 'java',\n 'javascript',\n 'python',\n 'ruby',\n 'swift'\n] as const;\n\n// \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n// Exported parameter schemas for each workflow prompt.\n//\n// Extracting the schemas makes it easy to unit-test required vs optional\n// validation independently of the MCP server registration.\n//\n// **Convention for VS Code UX consistency**:\n// Every prompt MUST expose at least one parameter \u2013 even if all parameters\n// are optional \u2013 so that VS Code always displays the parameter input dialog\n// and allows the user to customize the prompt before Copilot Chat processes\n// it. The `description` field on each Zod schema member doubles as the\n// placeholder text shown in the VS Code input box.\n// \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n/**\n * Schema for test_driven_development prompt parameters.\n *\n * - `language` is **required** \u2013 the TDD workflow is language-specific.\n * - `queryName` is optional \u2013 defaults to '[QueryName]' if omitted.\n */\nexport const testDrivenDevelopmentSchema = z.object({\n language: z\n .enum(SUPPORTED_LANGUAGES)\n .describe('Programming language for the query'),\n queryName: z\n .string()\n .optional()\n .describe('Name of the query to develop'),\n});\n\n/**\n * Schema for tools_query_workflow prompt parameters.\n *\n * - `language` and `database` are **required**.\n * - `sourceFiles`, `sourceFunction`, `targetFunction` are optional context.\n */\nexport const toolsQueryWorkflowSchema = z.object({\n database: z\n .string()\n .describe('Path to the CodeQL database'),\n language: z\n .enum(SUPPORTED_LANGUAGES)\n .describe('Programming language for the tools queries'),\n sourceFiles: z\n .string()\n .optional()\n .describe('Comma-separated source file names for PrintAST (e.g., \"main.js,utils.js\")'),\n sourceFunction: z\n .string()\n .optional()\n .describe('Function name for PrintCFG or CallGraphFrom (e.g., \"processData\")'),\n targetFunction: z\n .string()\n .optional()\n .describe('Function name for CallGraphTo (e.g., \"validate\")'),\n});\n\n/**\n * Schema for workshop_creation_workflow prompt parameters.\n * Uses z.coerce.number() for numStages to handle string inputs from VSCode slash commands.\n *\n * - `queryPath` and `language` are **required**.\n * - `workshopName` and `numStages` are optional.\n */\nexport const workshopCreationWorkflowSchema = z.object({\n queryPath: z\n .string()\n .describe('Path to the production-grade CodeQL query (.ql or .qlref)'),\n language: z\n .enum(SUPPORTED_LANGUAGES)\n .describe('Programming language of the query'),\n workshopName: z\n .string()\n .optional()\n .describe('Name for the workshop directory'),\n numStages: z\n .coerce.number()\n .optional()\n .describe('Number of incremental stages (default: 4-8)'),\n});\n\n/**\n * Schema for ql_tdd_basic prompt parameters.\n *\n * All parameters are optional \u2013 but at least one should be present so the\n * VS Code quick-pick dialog appears.\n */\nexport const qlTddBasicSchema = z.object({\n language: z\n .enum(SUPPORTED_LANGUAGES)\n .optional()\n .describe('Programming language for the query (optional)'),\n queryName: z\n .string()\n .optional()\n .describe('Name of the query to develop'),\n});\n\n/**\n * Schema for ql_tdd_advanced prompt parameters.\n *\n * All parameters are optional.\n */\nexport const qlTddAdvancedSchema = z.object({\n database: z\n .string()\n .optional()\n .describe('Path to the CodeQL database for analysis'),\n language: z\n .enum(SUPPORTED_LANGUAGES)\n .optional()\n .describe('Programming language for the query (optional)'),\n queryName: z\n .string()\n .optional()\n .describe('Name of the query to develop'),\n});\n\n/**\n * Schema for sarif_rank_false_positives / sarif_rank_true_positives.\n *\n * Both parameters are optional.\n */\nexport const sarifRankSchema = z.object({\n queryId: z\n .string()\n .optional()\n .describe('CodeQL query/rule identifier'),\n sarifPath: z\n .string()\n .optional()\n .describe('Path to the SARIF file to analyze'),\n});\n\n/**\n * Schema for explain_codeql_query prompt parameters.\n *\n * - `queryPath` and `language` are **required**.\n * - `databasePath` is optional.\n */\nexport const explainCodeqlQuerySchema = z.object({\n databasePath: z\n .string()\n .optional()\n .describe('Optional path to a real CodeQL database for profiling'),\n language: z\n .enum(SUPPORTED_LANGUAGES)\n .describe('Programming language of the query'),\n queryPath: z\n .string()\n .describe('Path to the CodeQL query file (.ql or .qlref)'),\n});\n\n/**\n * Schema for document_codeql_query prompt parameters.\n *\n * - `queryPath` and `language` are **required**.\n */\nexport const documentCodeqlQuerySchema = z.object({\n language: z\n .enum(SUPPORTED_LANGUAGES)\n .describe('Programming language of the query'),\n queryPath: z\n .string()\n .describe('Path to the CodeQL query file (.ql or .qlref)'),\n});\n\n/**\n * Schema for ql_lsp_iterative_development prompt parameters.\n *\n * All parameters are optional.\n */\nexport const qlLspIterativeDevelopmentSchema = z.object({\n language: z\n .enum(SUPPORTED_LANGUAGES)\n .optional()\n .describe('Programming language for the query'),\n queryPath: z\n .string()\n .optional()\n .describe('Path to the query file being developed'),\n workspaceUri: z\n .string()\n .optional()\n .describe('Workspace URI for LSP dependency resolution'),\n});\n\n// \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n// Prompt names (exported for testing)\n// \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n/** Names of every workflow prompt registered with the MCP server. */\nexport const WORKFLOW_PROMPT_NAMES = [\n 'document_codeql_query',\n 'explain_codeql_query',\n 'ql_lsp_iterative_development',\n 'ql_tdd_advanced',\n 'ql_tdd_basic',\n 'sarif_rank_false_positives',\n 'sarif_rank_true_positives',\n 'test_driven_development',\n 'tools_query_workflow',\n 'workshop_creation_workflow',\n] as const;\n\n/**\n * Register MCP workflow prompts\n *\n * Each prompt loads its content from a corresponding .prompt.md file\n * and processes any parameter substitutions.\n *\n * **UX note**: Every prompt schema is passed to `server.prompt()` so that\n * VS Code always displays the parameter-input quick-pick before the prompt\n * is sent to Copilot Chat. This lets users review and customise the values.\n */\nexport function registerWorkflowPrompts(server: McpServer): void {\n // Test-Driven Development Prompt\n server.prompt(\n 'test_driven_development',\n 'Test-driven development workflow for CodeQL queries using MCP tools',\n testDrivenDevelopmentSchema.shape,\n async ({ language, queryName }) => {\n const template = loadPromptTemplate('ql-tdd-basic.prompt.md');\n const content = processPromptTemplate(template, {\n language,\n queryName: queryName || '[QueryName]'\n });\n\n return {\n messages: [\n {\n role: 'user',\n content: {\n type: 'text',\n text: `## Context\\n\\n- **Language**: ${language}\\n${queryName ? `- **Query Name**: ${queryName}\\n` : ''}\\n${content}`\n }\n }\n ]\n };\n }\n );\n\n // Tools Query Workflow Prompt\n server.prompt(\n 'tools_query_workflow',\n 'Guide for using built-in tools queries (PrintAST, PrintCFG, CallGraphFrom, CallGraphTo) to understand code structure',\n toolsQueryWorkflowSchema.shape,\n async ({\n language,\n database,\n sourceFiles,\n sourceFunction,\n targetFunction\n }) => {\n const template = loadPromptTemplate('tools-query-workflow.prompt.md');\n const content = processPromptTemplate(template, {\n language,\n database\n });\n\n const contextSection = buildToolsQueryContext(\n language,\n database,\n sourceFiles,\n sourceFunction,\n targetFunction\n );\n\n return {\n messages: [\n {\n role: 'user',\n content: {\n type: 'text',\n text: contextSection + content\n }\n }\n ]\n };\n }\n );\n\n // Workshop Creation Workflow Prompt\n server.prompt(\n 'workshop_creation_workflow',\n 'Guide for creating CodeQL query development workshops from production-grade queries',\n workshopCreationWorkflowSchema.shape,\n async ({ queryPath, language, workshopName, numStages }) => {\n const template = loadPromptTemplate('workshop-creation-workflow.prompt.md');\n\n // Derive workshop name from query path if not provided\n const derivedName =\n workshopName ||\n basename(queryPath)\n .replace(/\\.(ql|qlref)$/, '')\n .toLowerCase()\n .replace(/[^a-z0-9]+/g, '-') ||\n 'codeql-workshop';\n\n const contextSection = buildWorkshopContext(\n queryPath,\n language,\n derivedName,\n numStages\n );\n\n return {\n messages: [\n {\n role: 'user',\n content: {\n type: 'text',\n text: contextSection + template\n }\n }\n ]\n };\n }\n );\n\n // TDD Basic Prompt - Test-Driven Development Checklist\n server.prompt(\n 'ql_tdd_basic',\n 'Test-driven CodeQL query development checklist - write tests first, implement query, iterate until tests pass',\n qlTddBasicSchema.shape,\n async ({ language, queryName }) => {\n const template = loadPromptTemplate('ql-tdd-basic.prompt.md');\n\n let contextSection = '## Your Development Context\\n\\n';\n if (language) {\n contextSection += `- **Language**: ${language}\\n`;\n }\n if (queryName) {\n contextSection += `- **Query Name**: ${queryName}\\n`;\n }\n if (language || queryName) {\n contextSection += '\\n';\n }\n\n return {\n messages: [\n {\n role: 'user',\n content: {\n type: 'text',\n text: contextSection + template\n }\n }\n ]\n };\n }\n );\n\n // TDD Advanced Prompt - Advanced Techniques with AST/CFG/CallGraph\n server.prompt(\n 'ql_tdd_advanced',\n 'Advanced test-driven CodeQL development with AST visualization, control flow, and call graph analysis',\n qlTddAdvancedSchema.shape,\n async ({ language, queryName, database }) => {\n const template = loadPromptTemplate('ql-tdd-advanced.prompt.md');\n\n let contextSection = '## Your Development Context\\n\\n';\n if (language) {\n contextSection += `- **Language**: ${language}\\n`;\n }\n if (queryName) {\n contextSection += `- **Query Name**: ${queryName}\\n`;\n }\n if (database) {\n contextSection += `- **Database**: ${database}\\n`;\n }\n if (language || queryName || database) {\n contextSection += '\\n';\n }\n\n return {\n messages: [\n {\n role: 'user',\n content: {\n type: 'text',\n text: contextSection + template\n }\n }\n ]\n };\n }\n );\n\n // SARIF Rank False Positives Prompt\n server.prompt(\n 'sarif_rank_false_positives',\n 'Analyze SARIF results to identify likely false positives in CodeQL query results',\n sarifRankSchema.shape,\n async ({ queryId, sarifPath }) => {\n const template = loadPromptTemplate('sarif-rank-false-positives.prompt.md');\n\n let contextSection = '## Analysis Context\\n\\n';\n if (queryId) {\n contextSection += `- **Query ID**: ${queryId}\\n`;\n }\n if (sarifPath) {\n contextSection += `- **SARIF File**: ${sarifPath}\\n`;\n }\n if (queryId || sarifPath) {\n contextSection += '\\n';\n }\n\n return {\n messages: [\n {\n role: 'user',\n content: {\n type: 'text',\n text: contextSection + template\n }\n }\n ]\n };\n }\n );\n\n // SARIF Rank True Positives Prompt\n server.prompt(\n 'sarif_rank_true_positives',\n 'Analyze SARIF results to identify likely true positives in CodeQL query results',\n sarifRankSchema.shape,\n async ({ queryId, sarifPath }) => {\n const template = loadPromptTemplate('sarif-rank-true-positives.prompt.md');\n\n let contextSection = '## Analysis Context\\n\\n';\n if (queryId) {\n contextSection += `- **Query ID**: ${queryId}\\n`;\n }\n if (sarifPath) {\n contextSection += `- **SARIF File**: ${sarifPath}\\n`;\n }\n if (queryId || sarifPath) {\n contextSection += '\\n';\n }\n\n return {\n messages: [\n {\n role: 'user',\n content: {\n type: 'text',\n text: contextSection + template\n }\n }\n ]\n };\n }\n );\n\n // Explain CodeQL Query Prompt (for workshop learning content)\n server.prompt(\n 'explain_codeql_query',\n 'Generate detailed explanation of a CodeQL query for workshop learning content - uses MCP tools to gather context and produces both verbal explanations and mermaid evaluation diagrams',\n explainCodeqlQuerySchema.shape,\n async ({ queryPath, language, databasePath }) => {\n const template = loadPromptTemplate('explain-codeql-query.prompt.md');\n\n let contextSection = '## Query to Explain\\n\\n';\n contextSection += `- **Query Path**: ${queryPath}\\n`;\n contextSection += `- **Language**: ${language}\\n`;\n if (databasePath) {\n contextSection += `- **Database Path**: ${databasePath}\\n`;\n }\n contextSection += '\\n';\n\n return {\n messages: [\n {\n role: 'user',\n content: {\n type: 'text',\n text: contextSection + template\n }\n }\n ]\n };\n }\n );\n\n // Document CodeQL Query Prompt\n server.prompt(\n 'document_codeql_query',\n 'Create or update documentation for a CodeQL query - generates standardized markdown documentation as a sibling file to the query',\n documentCodeqlQuerySchema.shape,\n async ({ queryPath, language }) => {\n const template = loadPromptTemplate('document-codeql-query.prompt.md');\n\n const contextSection = `## Query to Document\n\n- **Query Path**: ${queryPath}\n- **Language**: ${language}\n\n`;\n\n return {\n messages: [\n {\n role: 'user',\n content: {\n type: 'text',\n text: contextSection + template\n }\n }\n ]\n };\n }\n );\n\n // LSP-powered Iterative Development Prompt\n server.prompt(\n 'ql_lsp_iterative_development',\n 'Iterative CodeQL query development using LSP tools for completion, navigation, and validation',\n qlLspIterativeDevelopmentSchema.shape,\n async ({ language, queryPath, workspaceUri }) => {\n const template = loadPromptTemplate('ql-lsp-iterative-development.prompt.md');\n\n let contextSection = '## Your Development Context\\n\\n';\n if (language) {\n contextSection += `- **Language**: ${language}\\n`;\n }\n if (queryPath) {\n contextSection += `- **Query Path**: ${queryPath}\\n`;\n }\n if (workspaceUri) {\n contextSection += `- **Workspace URI**: ${workspaceUri}\\n`;\n }\n if (language || queryPath || workspaceUri) {\n contextSection += '\\n';\n }\n\n return {\n messages: [\n {\n role: 'user',\n content: {\n type: 'text',\n text: contextSection + template,\n },\n },\n ],\n };\n }\n );\n\n logger.info(`Registered ${WORKFLOW_PROMPT_NAMES.length} workflow prompts`);\n}\n\n/**\n * Build context section for tools query workflow\n */\nexport function buildToolsQueryContext(\n language: string,\n database: string,\n sourceFiles?: string,\n sourceFunction?: string,\n targetFunction?: string\n): string {\n const lines = [\n '## Your Context',\n '',\n `- **Language**: ${language}`,\n `- **Database**: ${database}`\n ];\n\n if (sourceFiles) {\n lines.push(`- **Source Files**: ${sourceFiles}`);\n }\n if (sourceFunction) {\n lines.push(`- **Source Function**: ${sourceFunction}`);\n }\n if (targetFunction) {\n lines.push(`- **Target Function**: ${targetFunction}`);\n }\n\n lines.push('', '## Recommended Next Steps', '');\n\n if (sourceFiles) {\n lines.push(\n `1. Run \\`codeql_query_run\\` with queryName=\"PrintAST\", sourceFiles=\"${sourceFiles}\"`\n );\n } else {\n lines.push('1. Identify source files to analyze with PrintAST');\n }\n\n if (sourceFunction) {\n lines.push(\n `2. Run \\`codeql_query_run\\` with queryName=\"PrintCFG\" or \"CallGraphFrom\", sourceFunction=\"${sourceFunction}\"`\n );\n } else {\n lines.push(\n '2. Identify key functions for CFG or call graph analysis'\n );\n }\n\n if (targetFunction) {\n lines.push(\n `3. Run \\`codeql_query_run\\` with queryName=\"CallGraphTo\", targetFunction=\"${targetFunction}\"`\n );\n } else {\n lines.push('3. Identify target functions to find callers');\n }\n\n lines.push('', '');\n return lines.join('\\n');\n}\n\n/**\n * Build context section for workshop creation workflow\n */\nexport function buildWorkshopContext(\n queryPath: string,\n language: string,\n workshopName: string,\n numStages?: number\n): string {\n return `## Your Workshop Context\n\n- **Target Query**: ${queryPath}\n- **Language**: ${language}\n- **Workshop Name**: ${workshopName}\n- **Suggested Stages**: ${numStages || '4-8 (auto-detect based on query complexity)'}\n\n## Immediate Actions\n\n1. **Locate query files**: Use \\`find_codeql_query_files\\` with queryPath=\"${queryPath}\"\n2. **Understand query for learning content**: Use the \\`explain_codeql_query\\` prompt with queryPath=\"${queryPath}\" and language=\"${language}\"\n3. **Document each workshop stage**: Use the \\`document_codeql_query\\` prompt to create/update documentation for each solution query\n4. **Verify tests pass**: Use \\`codeql_test_run\\` on existing tests\n5. **Run tools queries**: Generate AST/CFG understanding for workshop materials\n\n`;\n}\n", "/**\n * Utility functions for loading prompt template files\n */\n\nimport { readFileSync } from 'fs';\nimport { join, dirname } from 'path';\nimport { fileURLToPath } from 'url';\n\nconst __filename = fileURLToPath(import.meta.url);\nconst __dirname = dirname(__filename);\n\n/**\n * Load a prompt template from a .prompt.md file\n */\nexport function loadPromptTemplate(promptFileName: string): string {\n try {\n const promptPath = join(__dirname, promptFileName);\n return readFileSync(promptPath, 'utf-8');\n } catch (error) {\n return `Prompt template '${promptFileName}' not available: ${error instanceof Error ? error.message : 'Unknown error'}`;\n }\n}\n\n/**\n * Process prompt template by replacing placeholders with actual values\n */\nexport function processPromptTemplate(template: string, variables: Record): string {\n let processed = template;\n \n // Replace variables in the format {{variable}} or {variable}\n for (const [key, value] of Object.entries(variables)) {\n const patterns = [\n new RegExp(`\\\\{\\\\{${key}\\\\}\\\\}`, 'g'),\n new RegExp(`\\\\{${key}\\\\}`, 'g')\n ];\n \n for (const pattern of patterns) {\n processed = processed.replace(pattern, value);\n }\n }\n \n return processed;\n}", "/**\n * Monitoring Tools - MCP tool implementations for session management and reporting\n * Provides the MCP Tool APIs specified in the monitoring specification\n */\n\nimport { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport { z } from 'zod';\nimport { randomUUID } from 'crypto';\nimport { sessionDataManager } from '../lib/session-data-manager';\nimport {\n QueryDevelopmentSession,\n SessionFilter,\n QualityScoreRecord,\n ComparisonReport,\n AggregateReport,\n ExportResult,\n FunctionalTestResult,\n} from '../types/monitoring';\nimport { logger } from '../utils/logger';\n\n/**\n * Register all monitoring and reporting tools with the MCP server\n * Note: These tools are opt-in and disabled by default for end-users.\n * Set enableMonitoringTools: true in monitoring config to enable them.\n */\nexport function registerMonitoringTools(server: McpServer): void {\n const config = sessionDataManager.getConfig();\n \n // Check if monitoring tools are enabled (opt-in, disabled by default)\n if (!config.enableMonitoringTools) {\n logger.info('Monitoring tools are disabled (opt-in). Set enableMonitoringTools: true to enable session_* tools.');\n return;\n }\n\n // Session Management Tools - session_start removed per feedback (auto-creation instead)\n registerSessionEndTool(server);\n registerSessionGetTool(server);\n registerSessionListTool(server);\n registerSessionUpdateStateTool(server);\n\n // Session Analytics Tools\n registerSessionGetCallHistoryTool(server);\n registerSessionGetTestHistoryTool(server);\n registerSessionGetScoreHistoryTool(server);\n registerSessionCalculateCurrentScoreTool(server);\n\n // Batch Operations Tools\n registerSessionsCompareTool(server);\n registerSessionsAggregateTool(server);\n registerSessionsExportTool(server);\n\n // Note: Functional Testing Support Tools are internal only, not exposed as MCP tools\n\n logger.info('Registered monitoring and reporting tools');\n}\n\n/**\n * Session Management Tools\n */\n\n// session_start tool removed - sessions are now auto-created when needed\n// Sessions are automatically created when MCP tools are called with queryPath\n// If explicit session creation is needed, provide sessionId=null and it will auto-create\n\nfunction registerSessionEndTool(server: McpServer): void {\n server.tool(\n 'session_end',\n 'End a query development session with final status',\n {\n sessionId: z.string().describe('ID of the session to end'),\n status: z.enum(['completed', 'failed', 'abandoned']).describe('Final status of the session'),\n },\n async ({ sessionId, status }) => {\n try {\n const session = await sessionDataManager.endSession(sessionId, status);\n \n if (!session) {\n return {\n content: [\n {\n type: 'text',\n text: `Session not found: ${sessionId}`,\n },\n ],\n isError: true,\n };\n }\n\n return {\n content: [\n {\n type: 'text',\n text: JSON.stringify(session, null, 2),\n },\n ],\n };\n } catch (error) {\n logger.error('Error ending session:', error);\n return {\n content: [\n {\n type: 'text',\n text: `Error ending session: ${error instanceof Error ? error.message : 'Unknown error'}`,\n },\n ],\n isError: true,\n };\n }\n }\n );\n}\n\nfunction registerSessionGetTool(server: McpServer): void {\n server.tool(\n 'session_get',\n 'Get complete details of a specific query development session',\n {\n sessionId: z.string().describe('ID of the session to retrieve'),\n },\n async ({ sessionId }) => {\n try {\n const session = await sessionDataManager.getSession(sessionId);\n \n if (!session) {\n return {\n content: [\n {\n type: 'text',\n text: `Session not found: ${sessionId}`,\n },\n ],\n isError: true,\n };\n }\n\n return {\n content: [\n {\n type: 'text',\n text: JSON.stringify(session, null, 2),\n },\n ],\n };\n } catch (error) {\n logger.error('Error getting session:', error);\n return {\n content: [\n {\n type: 'text',\n text: `Error getting session: ${error instanceof Error ? error.message : 'Unknown error'}`,\n },\n ],\n isError: true,\n };\n }\n }\n );\n}\n\nfunction registerSessionListTool(server: McpServer): void {\n server.tool(\n 'session_list',\n 'List query development sessions with optional filtering',\n {\n queryPath: z.string().optional().describe('Filter by query path (partial match)'),\n status: z.string().optional().describe('Filter by session status'),\n dateRange: z.array(z.string()).length(2).optional().describe('Filter by date range [start, end] (ISO timestamps)'),\n language: z.string().optional().describe('Filter by programming language'),\n queryType: z.string().optional().describe('Filter by query type'),\n },\n async ({ queryPath, status, dateRange, language, queryType }) => {\n try {\n const filters: SessionFilter = {};\n if (queryPath) filters.queryPath = queryPath;\n if (status) filters.status = status;\n if (dateRange) filters.dateRange = [dateRange[0], dateRange[1]];\n if (language) filters.language = language;\n if (queryType) filters.queryType = queryType;\n\n const sessions = await sessionDataManager.listSessions(\n Object.keys(filters).length > 0 ? filters : undefined\n );\n\n const sessionList = {\n totalSessions: sessions.length,\n sessions: sessions.map(s => ({\n sessionId: s.sessionId,\n queryPath: s.queryPath,\n language: s.language,\n status: s.status,\n startTime: s.startTime,\n endTime: s.endTime,\n mcpCallsCount: s.mcpCalls.length,\n testExecutionsCount: s.testExecutions.length,\n currentScore: s.qualityScores.length > 0 \n ? s.qualityScores[s.qualityScores.length - 1].overallScore \n : null,\n })),\n };\n\n return {\n content: [\n {\n type: 'text',\n text: JSON.stringify(sessionList, null, 2),\n },\n ],\n recommendations: generateListRecommendations(sessions),\n };\n } catch (error) {\n logger.error('Error listing sessions:', error);\n return {\n content: [\n {\n type: 'text',\n text: `Error listing sessions: ${error instanceof Error ? error.message : 'Unknown error'}`,\n },\n ],\n isError: true,\n };\n }\n }\n );\n}\n\nfunction registerSessionUpdateStateTool(server: McpServer): void {\n server.tool(\n 'session_update_state',\n 'Update the current state of a query development session',\n {\n sessionId: z.string().describe('ID of the session to update'),\n filesPresent: z.array(z.string()).optional().describe('List of files present in the query development'),\n compilationStatus: z.enum(['unknown', 'success', 'failed']).optional().describe('Current compilation status'),\n testStatus: z.enum(['unknown', 'passing', 'failing', 'no_tests']).optional().describe('Current test status'),\n documentationStatus: z.enum(['unknown', 'present', 'missing', 'incomplete']).optional().describe('Documentation status'),\n },\n async ({ sessionId, filesPresent, compilationStatus, testStatus, documentationStatus }) => {\n try {\n const stateUpdate: Record = {};\n if (filesPresent !== undefined) stateUpdate.filesPresent = filesPresent;\n if (compilationStatus !== undefined) stateUpdate.compilationStatus = compilationStatus;\n if (testStatus !== undefined) stateUpdate.testStatus = testStatus;\n if (documentationStatus !== undefined) stateUpdate.documentationStatus = documentationStatus;\n\n const session = await sessionDataManager.updateSessionState(sessionId, stateUpdate);\n \n if (!session) {\n return {\n content: [\n {\n type: 'text',\n text: `Session not found: ${sessionId}`,\n },\n ],\n isError: true,\n };\n }\n\n return {\n content: [\n {\n type: 'text',\n text: JSON.stringify(session, null, 2),\n },\n ],\n recommendations: generateRecommendations(session, 'session_update_state'),\n };\n } catch (error) {\n logger.error('Error updating session state:', error);\n return {\n content: [\n {\n type: 'text',\n text: `Error updating session state: ${error instanceof Error ? error.message : 'Unknown error'}`,\n },\n ],\n isError: true,\n };\n }\n }\n );\n}\n\n/**\n * Session Analytics Tools\n */\n\nfunction registerSessionGetCallHistoryTool(server: McpServer): void {\n server.tool(\n 'session_get_call_history',\n 'Get MCP call history for a specific session',\n {\n sessionId: z.string().describe('ID of the session'),\n limit: z.number().optional().describe('Maximum number of calls to return (most recent first)'),\n },\n async ({ sessionId, limit }) => {\n try {\n const session = await sessionDataManager.getSession(sessionId);\n \n if (!session) {\n return {\n content: [\n {\n type: 'text',\n text: `Session not found: ${sessionId}`,\n },\n ],\n isError: true,\n };\n }\n\n let calls = [...session.mcpCalls].reverse(); // Most recent first\n if (limit && limit > 0) {\n calls = calls.slice(0, limit);\n }\n\n return {\n content: [\n {\n type: 'text',\n text: JSON.stringify({\n sessionId,\n totalCalls: session.mcpCalls.length,\n callHistory: calls,\n }, null, 2),\n },\n ],\n };\n } catch (error) {\n logger.error('Error getting call history:', error);\n return {\n content: [\n {\n type: 'text',\n text: `Error getting call history: ${error instanceof Error ? error.message : 'Unknown error'}`,\n },\n ],\n isError: true,\n };\n }\n }\n );\n}\n\nfunction registerSessionGetTestHistoryTool(server: McpServer): void {\n server.tool(\n 'session_get_test_history',\n 'Get test execution history for a specific session',\n {\n sessionId: z.string().describe('ID of the session'),\n limit: z.number().optional().describe('Maximum number of test executions to return (most recent first)'),\n },\n async ({ sessionId, limit }) => {\n try {\n const session = await sessionDataManager.getSession(sessionId);\n \n if (!session) {\n return {\n content: [\n {\n type: 'text',\n text: `Session not found: ${sessionId}`,\n },\n ],\n isError: true,\n };\n }\n\n let tests = [...session.testExecutions].reverse(); // Most recent first\n if (limit && limit > 0) {\n tests = tests.slice(0, limit);\n }\n\n return {\n content: [\n {\n type: 'text',\n text: JSON.stringify({\n sessionId,\n totalTests: session.testExecutions.length,\n testHistory: tests,\n }, null, 2),\n },\n ],\n };\n } catch (error) {\n logger.error('Error getting test history:', error);\n return {\n content: [\n {\n type: 'text',\n text: `Error getting test history: ${error instanceof Error ? error.message : 'Unknown error'}`,\n },\n ],\n isError: true,\n };\n }\n }\n );\n}\n\nfunction registerSessionGetScoreHistoryTool(server: McpServer): void {\n server.tool(\n 'session_get_score_history',\n 'Get quality score history for a specific session',\n {\n sessionId: z.string().describe('ID of the session'),\n limit: z.number().optional().describe('Maximum number of scores to return (most recent first)'),\n },\n async ({ sessionId, limit }) => {\n try {\n const session = await sessionDataManager.getSession(sessionId);\n \n if (!session) {\n return {\n content: [\n {\n type: 'text',\n text: `Session not found: ${sessionId}`,\n },\n ],\n isError: true,\n };\n }\n\n let scores = [...session.qualityScores].reverse(); // Most recent first\n if (limit && limit > 0) {\n scores = scores.slice(0, limit);\n }\n\n return {\n content: [\n {\n type: 'text',\n text: JSON.stringify({\n sessionId,\n totalScores: session.qualityScores.length,\n scoreHistory: scores,\n }, null, 2),\n },\n ],\n };\n } catch (error) {\n logger.error('Error getting score history:', error);\n return {\n content: [\n {\n type: 'text',\n text: `Error getting score history: ${error instanceof Error ? error.message : 'Unknown error'}`,\n },\n ],\n isError: true,\n };\n }\n }\n );\n}\n\nfunction registerSessionCalculateCurrentScoreTool(server: McpServer): void {\n server.tool(\n 'session_calculate_current_score',\n 'Calculate current quality score for a session based on its state',\n {\n sessionId: z.string().describe('ID of the session'),\n },\n async ({ sessionId }) => {\n try {\n const session = await sessionDataManager.getSession(sessionId);\n \n if (!session) {\n return {\n content: [\n {\n type: 'text',\n text: `Session not found: ${sessionId}`,\n },\n ],\n isError: true,\n };\n }\n\n // Calculate quality score based on current state\n const scoreRecord = calculateQualityScore(session);\n \n // Add the score to the session\n await sessionDataManager.addQualityScore(sessionId, scoreRecord);\n \n // Get updated session with new score\n const updatedSession = await sessionDataManager.getSession(sessionId);\n\n return {\n content: [\n {\n type: 'text',\n text: JSON.stringify(scoreRecord, null, 2),\n },\n ],\n recommendations: generateRecommendations(updatedSession, 'session_calculate_current_score'),\n };\n } catch (error) {\n logger.error('Error calculating current score:', error);\n return {\n content: [\n {\n type: 'text',\n text: `Error calculating current score: ${error instanceof Error ? error.message : 'Unknown error'}`,\n },\n ],\n isError: true,\n };\n }\n }\n );\n}\n\n/**\n * Batch Operations Tools\n */\n\nfunction registerSessionsCompareTool(server: McpServer): void {\n server.tool(\n 'sessions_compare',\n 'Compare multiple query development sessions across specified dimensions',\n {\n sessionIds: z.array(z.string()).describe('Array of session IDs to compare'),\n dimensions: z.array(z.string()).optional().describe('Specific dimensions to compare (default: all)'),\n },\n async ({ sessionIds, dimensions }) => {\n try {\n const sessions = await Promise.all(\n sessionIds.map(id => sessionDataManager.getSession(id))\n );\n\n const validSessions = sessions.filter(s => s !== null) as QueryDevelopmentSession[];\n \n if (validSessions.length === 0) {\n return {\n content: [\n {\n type: 'text',\n text: 'No valid sessions found for comparison',\n },\n ],\n isError: true,\n };\n }\n\n const comparison = await compareSessions(validSessions, dimensions);\n\n return {\n content: [\n {\n type: 'text',\n text: JSON.stringify(comparison, null, 2),\n },\n ],\n };\n } catch (error) {\n logger.error('Error comparing sessions:', error);\n return {\n content: [\n {\n type: 'text',\n text: `Error comparing sessions: ${error instanceof Error ? error.message : 'Unknown error'}`,\n },\n ],\n isError: true,\n };\n }\n }\n );\n}\n\nfunction registerSessionsAggregateTool(server: McpServer): void {\n server.tool(\n 'sessions_aggregate',\n 'Generate aggregate insights from multiple sessions based on filters',\n {\n queryPath: z.string().optional().describe('Filter by query path (partial match)'),\n status: z.string().optional().describe('Filter by session status'),\n dateRange: z.array(z.string()).length(2).optional().describe('Filter by date range [start, end] (ISO timestamps)'),\n language: z.string().optional().describe('Filter by programming language'),\n queryType: z.string().optional().describe('Filter by query type'),\n },\n async ({ queryPath, status, dateRange, language, queryType }) => {\n try {\n const filters: SessionFilter = {};\n if (queryPath) filters.queryPath = queryPath;\n if (status) filters.status = status;\n if (dateRange) filters.dateRange = [dateRange[0], dateRange[1]];\n if (language) filters.language = language;\n if (queryType) filters.queryType = queryType;\n\n const sessions = await sessionDataManager.listSessions(\n Object.keys(filters).length > 0 ? filters : undefined\n );\n\n const aggregate = await aggregateSessions(sessions, filters);\n\n return {\n content: [\n {\n type: 'text',\n text: JSON.stringify(aggregate, null, 2),\n },\n ],\n };\n } catch (error) {\n logger.error('Error aggregating sessions:', error);\n return {\n content: [\n {\n type: 'text',\n text: `Error aggregating sessions: ${error instanceof Error ? error.message : 'Unknown error'}`,\n },\n ],\n isError: true,\n };\n }\n }\n );\n}\n\nfunction registerSessionsExportTool(server: McpServer): void {\n server.tool(\n 'sessions_export',\n 'Export session data in specified format for external analysis',\n {\n sessionIds: z.array(z.string()).describe('Array of session IDs to export'),\n format: z.enum(['json', 'html', 'markdown']).optional().default('json').describe('Export format'),\n },\n async ({ sessionIds, format = 'json' }) => {\n try {\n const sessions = await Promise.all(\n sessionIds.map(id => sessionDataManager.getSession(id))\n );\n\n const validSessions = sessions.filter(s => s !== null) as QueryDevelopmentSession[];\n \n if (validSessions.length === 0) {\n return {\n content: [\n {\n type: 'text',\n text: 'No valid sessions found for export',\n },\n ],\n isError: true,\n };\n }\n\n const exportResult = await exportSessions(validSessions, format);\n\n return {\n content: [\n {\n type: 'text',\n text: JSON.stringify(exportResult, null, 2),\n },\n ],\n };\n } catch (error) {\n logger.error('Error exporting sessions:', error);\n return {\n content: [\n {\n type: 'text',\n text: `Error exporting sessions: ${error instanceof Error ? error.message : 'Unknown error'}`,\n },\n ],\n isError: true,\n };\n }\n }\n );\n}\n\n/**\n * Helper Functions\n */\n\n/**\n * Calculate quality score for a session based on current state and history\n */\nfunction calculateQualityScore(session: QueryDevelopmentSession): QualityScoreRecord {\n const timestamp = new Date().toISOString();\n \n // Calculate syntactic correctness (25%)\n const syntacticCorrectness = session.currentState.compilationStatus === 'success' ? 100 :\n session.currentState.compilationStatus === 'failed' ? 0 : 50;\n\n // Calculate test coverage and results (30%)\n const testCoverageResults = session.currentState.testStatus === 'passing' ? 100 :\n session.currentState.testStatus === 'failing' ? 25 :\n session.currentState.testStatus === 'no_tests' ? 0 : 50;\n\n // Calculate documentation quality (20%)\n const documentationQuality = session.currentState.documentationStatus === 'present' ? 100 :\n session.currentState.documentationStatus === 'incomplete' ? 60 :\n session.currentState.documentationStatus === 'missing' ? 0 : 50;\n\n // Calculate functional correctness (25%) - based on successful test runs\n const successfulTests = session.testExecutions.filter(t => t.success && t.type === 'test_run').length;\n const totalTests = session.testExecutions.filter(t => t.type === 'test_run').length;\n const functionalCorrectness = totalTests > 0 ? (successfulTests / totalTests) * 100 : 50;\n\n // Calculate overall score\n const overallScore = Math.round(\n (syntacticCorrectness * 0.25) +\n (testCoverageResults * 0.30) +\n (documentationQuality * 0.20) +\n (functionalCorrectness * 0.25)\n );\n\n // Determine grade\n const grade = overallScore >= 90 ? 'A' :\n overallScore >= 80 ? 'B' :\n overallScore >= 70 ? 'C' :\n overallScore >= 60 ? 'D' : 'F';\n\n // Generate recommendations\n const recommendations: string[] = [];\n if (syntacticCorrectness < 100) {\n recommendations.push('Fix compilation errors to improve syntactic correctness');\n }\n if (testCoverageResults < 70) {\n recommendations.push('Add comprehensive tests and ensure they pass');\n }\n if (documentationQuality < 80) {\n recommendations.push('Add or improve query documentation with examples');\n }\n if (functionalCorrectness < 80) {\n recommendations.push('Improve test pass rate and verify query logic');\n }\n\n return {\n scoreId: randomUUID(),\n timestamp,\n overallScore,\n dimensions: {\n syntacticCorrectness,\n testCoverageResults,\n documentationQuality,\n functionalCorrectness,\n },\n grade,\n recommendations,\n };\n}\n\n/**\n * Compare multiple sessions\n */\nasync function compareSessions(\n sessions: QueryDevelopmentSession[],\n dimensions?: string[]\n): Promise {\n const timestamp = new Date().toISOString();\n const sessionIds = sessions.map(s => s.sessionId);\n \n const results: Record = {\n sessionCount: sessions.length,\n sessionOverview: sessions.map(s => ({\n sessionId: s.sessionId,\n queryPath: s.queryPath,\n status: s.status,\n mcpCallsCount: s.mcpCalls.length,\n duration: s.endTime ? \n new Date(s.endTime).getTime() - new Date(s.startTime).getTime() : \n new Date().getTime() - new Date(s.startTime).getTime(),\n currentScore: s.qualityScores.length > 0 ? \n s.qualityScores[s.qualityScores.length - 1].overallScore : null,\n })),\n };\n\n if (!dimensions || dimensions.includes('quality')) {\n const qualityScores = sessions.map(s => \n s.qualityScores.length > 0 ? s.qualityScores[s.qualityScores.length - 1] : null\n );\n results.qualityComparison = {\n averageScore: qualityScores\n .filter(q => q !== null)\n .reduce((sum, q) => sum + q!.overallScore, 0) / qualityScores.filter(q => q !== null).length,\n scoreRange: {\n min: Math.min(...qualityScores.filter(q => q !== null).map(q => q!.overallScore)),\n max: Math.max(...qualityScores.filter(q => q !== null).map(q => q!.overallScore)),\n },\n };\n }\n\n if (!dimensions || dimensions.includes('activity')) {\n results.activityComparison = {\n totalMCPCalls: sessions.reduce((sum, s) => sum + s.mcpCalls.length, 0),\n averageCallsPerSession: sessions.reduce((sum, s) => sum + s.mcpCalls.length, 0) / sessions.length,\n mostActiveTool: getMostUsedTool(sessions),\n };\n }\n\n return {\n sessionIds,\n dimensions: dimensions || ['all'],\n timestamp,\n results,\n };\n}\n\n/**\n * Aggregate insights from multiple sessions\n */\nasync function aggregateSessions(\n sessions: QueryDevelopmentSession[],\n filters: SessionFilter\n): Promise {\n const timestamp = new Date().toISOString();\n \n const completedSessions = sessions.filter(s => s.status === 'completed');\n const successRate = sessions.length > 0 ? completedSessions.length / sessions.length : 0;\n \n const qualityScores = sessions\n .map(s => s.qualityScores.length > 0 ? s.qualityScores[s.qualityScores.length - 1].overallScore : null)\n .filter(score => score !== null) as number[];\n \n const averageQualityScore = qualityScores.length > 0 ? \n qualityScores.reduce((sum, score) => sum + score, 0) / qualityScores.length : 0;\n\n const commonPatterns = identifyCommonPatterns(sessions);\n const recommendations = generateAggregateRecommendations(sessions);\n\n return {\n filters,\n timestamp,\n totalSessions: sessions.length,\n successRate,\n averageQualityScore,\n commonPatterns,\n recommendations,\n };\n}\n\n/**\n * Export sessions in specified format\n */\nasync function exportSessions(\n sessions: QueryDevelopmentSession[],\n format: 'json' | 'html' | 'markdown'\n): Promise {\n const timestamp = new Date().toISOString();\n const filename = `session-export-${timestamp.replace(/[:.]/g, '-')}.${format}`;\n \n let content: string;\n \n switch (format) {\n case 'json':\n content = JSON.stringify(sessions, null, 2);\n break;\n case 'html':\n content = generateHTMLReport(sessions);\n break;\n case 'markdown':\n content = generateMarkdownReport(sessions);\n break;\n }\n\n return {\n format,\n filename,\n content,\n timestamp,\n };\n}\n\n/**\n * Utility functions\n */\n\nfunction getMostUsedTool(sessions: QueryDevelopmentSession[]): string {\n const toolCounts: Record = {};\n \n sessions.forEach(session => {\n session.mcpCalls.forEach(call => {\n toolCounts[call.toolName] = (toolCounts[call.toolName] || 0) + 1;\n });\n });\n\n return Object.entries(toolCounts)\n .sort(([, a], [, b]) => b - a)[0]?.[0] || 'none';\n}\n\nfunction identifyCommonPatterns(sessions: QueryDevelopmentSession[]): string[] {\n const patterns: string[] = [];\n \n const commonTools = getMostUsedTool(sessions);\n if (commonTools && commonTools !== 'none') {\n patterns.push(`Most commonly used tool: ${commonTools}`);\n }\n\n const completionRate = sessions.filter(s => s.status === 'completed').length / sessions.length;\n if (completionRate > 0.8) {\n patterns.push('High completion rate indicates effective workflow');\n } else if (completionRate < 0.5) {\n patterns.push('Low completion rate suggests workflow issues');\n }\n\n return patterns;\n}\n\nfunction generateAggregateRecommendations(sessions: QueryDevelopmentSession[]): string[] {\n const recommendations: string[] = [];\n \n const failedSessions = sessions.filter(s => s.status === 'failed');\n if (failedSessions.length > sessions.length * 0.3) {\n recommendations.push('High failure rate - consider improving error handling and guidance');\n }\n\n const averageCallsPerSession = sessions.reduce((sum, s) => sum + s.mcpCalls.length, 0) / sessions.length;\n if (averageCallsPerSession > 20) {\n recommendations.push('High number of MCP calls per session - consider workflow optimization');\n }\n\n return recommendations;\n}\n\nfunction generateHTMLReport(sessions: QueryDevelopmentSession[]): string {\n const html = `\n\n\n\n Session Export Report\n \n\n\n

Query Development Sessions Report

\n

Generated: ${new Date().toISOString()}

\n

Total Sessions: ${sessions.length}

\n \n ${sessions.map(session => `\n
\n

Session: ${session.sessionId}

\n

Query Path: ${session.queryPath}

\n

Status: ${session.status}

\n

Language: ${session.language}

\n

Start Time: ${session.startTime}

\n

MCP Calls: ${session.mcpCalls.length}

\n

Test Executions: ${session.testExecutions.length}

\n

Quality Scores: ${session.qualityScores.length}

\n
\n `).join('')}\n\n`;\n \n return html;\n}\n\nfunction generateMarkdownReport(sessions: QueryDevelopmentSession[]): string {\n const md = `# Query Development Sessions Report\n\nGenerated: ${new Date().toISOString()}\nTotal Sessions: ${sessions.length}\n\n## Session Summary\n\n| Session ID | Query Path | Status | Language | MCP Calls | Test Executions |\n|------------|-----------|--------|----------|-----------|-----------------|\n${sessions.map(session => \n `| ${session.sessionId} | ${session.queryPath} | ${session.status} | ${session.language} | ${session.mcpCalls.length} | ${session.testExecutions.length} |`\n).join('\\n')}\n\n## Detailed Sessions\n\n${sessions.map(session => `\n### Session: ${session.sessionId}\n\n- **Query Path:** ${session.queryPath}\n- **Status:** ${session.status}\n- **Language:** ${session.language}\n- **Start Time:** ${session.startTime}\n- **End Time:** ${session.endTime || 'N/A'}\n- **MCP Calls:** ${session.mcpCalls.length}\n- **Test Executions:** ${session.testExecutions.length}\n- **Quality Scores:** ${session.qualityScores.length}\n\n${session.recommendations.length > 0 ? `\n**Current Recommendations:**\n${session.recommendations.map(rec => `- ${rec}`).join('\\n')}\n` : ''}\n`).join('\\n')}`;\n\n return md;\n}\n\nfunction _calculateAverageDuration(sessions: QueryDevelopmentSession[]): number {\n const completedSessions = sessions.filter(s => s.endTime);\n if (completedSessions.length === 0) return 0;\n\n const totalDuration = completedSessions.reduce((sum, session) => {\n return sum + (new Date(session.endTime!).getTime() - new Date(session.startTime).getTime());\n }, 0);\n\n return totalDuration / completedSessions.length;\n}\n\nfunction _identifyFailureReasons(results: FunctionalTestResult[]): string[] {\n const failedResults = results.filter(r => !r.passed);\n const reasons: Record = {};\n\n failedResults.forEach(result => {\n Object.entries(result.criteria).forEach(([criterion, passed]) => {\n if (!passed) {\n reasons[criterion] = (reasons[criterion] || 0) + 1;\n }\n });\n });\n\n return Object.entries(reasons)\n .sort(([, a], [, b]) => b - a)\n .map(([reason, count]) => `${reason}: ${count} sessions`);\n}\n\n/**\n * Generate recommendations for MCP tool responses\n * Returns a map of MCP primitive paths to recommendation reasons\n */\nfunction generateRecommendations(\n session: QueryDevelopmentSession | null,\n currentTool: string\n): Record {\n if (!session) {\n return {};\n }\n\n const recommendations: Record = {};\n\n // Session state-based recommendations\n if (session.currentState.compilationStatus === 'failed') {\n recommendations['codeql_query_format'] = 'Format query to fix potential syntax issues';\n recommendations['codeql_query_compile'] = 'Recompile after fixing syntax errors';\n } else if (session.currentState.compilationStatus === 'success') {\n if (session.currentState.testStatus === 'unknown' || session.currentState.testStatus === 'no_tests') {\n recommendations['codeql_test_run'] = 'Run tests to validate query functionality';\n } else if (session.currentState.testStatus === 'failing') {\n recommendations['session_get_test_history'] = 'Review test failures to identify issues';\n recommendations['codeql_query_compile'] = 'Verify query logic matches test expectations';\n } else if (session.currentState.testStatus === 'passing') {\n recommendations['session_calculate_current_score'] = 'Calculate quality score for completed query';\n }\n }\n\n // Tool-specific follow-up recommendations\n switch (currentTool) {\n case 'session_get':\n if (session.mcpCalls.length === 0) {\n recommendations['codeql_query_compile'] = 'Start development by compiling the query';\n }\n break;\n case 'session_end':\n if (session.status === 'completed') {\n recommendations['sessions_export'] = 'Export session data for analysis';\n }\n break;\n case 'session_calculate_current_score': {\n const latestScore = session.qualityScores[session.qualityScores.length - 1];\n if (latestScore && latestScore.overallScore < 80) {\n if (latestScore.dimensions.syntacticCorrectness < 100) {\n recommendations['codeql_query_format'] = 'Improve syntax and formatting';\n }\n if (latestScore.dimensions.testCoverageResults < 70) {\n recommendations['codeql_test_run'] = 'Improve test coverage and results';\n }\n }\n break;\n }\n case 'session_update_state':\n // Recommend next logical step based on updated state\n if (session.currentState.compilationStatus === 'success' && session.currentState.testStatus === 'unknown') {\n recommendations['codeql_test_run'] = 'Run tests now that compilation is successful';\n }\n break;\n }\n\n return recommendations;\n}\n\n/**\n * Generate recommendations for session list results\n */\nfunction generateListRecommendations(sessions: QueryDevelopmentSession[]): Record {\n const recommendations: Record = {};\n\n const activeSessions = sessions.filter(s => s.status === 'active');\n const completedSessions = sessions.filter(s => s.status === 'completed');\n\n if (activeSessions.length > 0) {\n recommendations['session_get'] = `Review details of ${activeSessions.length} active session(s)`;\n }\n\n if (completedSessions.length > 1) {\n recommendations['sessions_compare'] = 'Compare completed sessions to identify patterns';\n recommendations['sessions_aggregate'] = 'Generate aggregate insights from multiple sessions';\n }\n\n if (sessions.length > 5) {\n recommendations['sessions_export'] = 'Export session data for comprehensive analysis';\n }\n\n return recommendations;\n}", "function checkArgs(adapter, defaultData) {\n if (adapter === undefined)\n throw new Error('lowdb: missing adapter');\n if (defaultData === undefined)\n throw new Error('lowdb: missing default data');\n}\nexport class Low {\n adapter;\n data;\n constructor(adapter, defaultData) {\n checkArgs(adapter, defaultData);\n this.adapter = adapter;\n this.data = defaultData;\n }\n async read() {\n const data = await this.adapter.read();\n if (data)\n this.data = data;\n }\n async write() {\n if (this.data)\n await this.adapter.write(this.data);\n }\n async update(fn) {\n fn(this.data);\n await this.write();\n }\n}\nexport class LowSync {\n adapter;\n data;\n constructor(adapter, defaultData) {\n checkArgs(adapter, defaultData);\n this.adapter = adapter;\n this.data = defaultData;\n }\n read() {\n const data = this.adapter.read();\n if (data)\n this.data = data;\n }\n write() {\n if (this.data)\n this.adapter.write(this.data);\n }\n update(fn) {\n fn(this.data);\n this.write();\n }\n}\n", "import { readFileSync, renameSync, writeFileSync } from 'node:fs';\nimport { readFile } from 'node:fs/promises';\nimport path from 'node:path';\nimport { Writer } from 'steno';\nexport class TextFile {\n #filename;\n #writer;\n constructor(filename) {\n this.#filename = filename;\n this.#writer = new Writer(filename);\n }\n async read() {\n let data;\n try {\n data = await readFile(this.#filename, 'utf-8');\n }\n catch (e) {\n if (e.code === 'ENOENT') {\n return null;\n }\n throw e;\n }\n return data;\n }\n write(str) {\n return this.#writer.write(str);\n }\n}\nexport class TextFileSync {\n #tempFilename;\n #filename;\n constructor(filename) {\n this.#filename = filename;\n const f = filename.toString();\n this.#tempFilename = path.join(path.dirname(f), `.${path.basename(f)}.tmp`);\n }\n read() {\n let data;\n try {\n data = readFileSync(this.#filename, 'utf-8');\n }\n catch (e) {\n if (e.code === 'ENOENT') {\n return null;\n }\n throw e;\n }\n return data;\n }\n write(str) {\n writeFileSync(this.#tempFilename, str);\n renameSync(this.#tempFilename, this.#filename);\n }\n}\n", "import { TextFile, TextFileSync } from './TextFile.js';\nexport class DataFile {\n #adapter;\n #parse;\n #stringify;\n constructor(filename, { parse, stringify, }) {\n this.#adapter = new TextFile(filename);\n this.#parse = parse;\n this.#stringify = stringify;\n }\n async read() {\n const data = await this.#adapter.read();\n if (data === null) {\n return null;\n }\n else {\n return this.#parse(data);\n }\n }\n write(obj) {\n return this.#adapter.write(this.#stringify(obj));\n }\n}\nexport class DataFileSync {\n #adapter;\n #parse;\n #stringify;\n constructor(filename, { parse, stringify, }) {\n this.#adapter = new TextFileSync(filename);\n this.#parse = parse;\n this.#stringify = stringify;\n }\n read() {\n const data = this.#adapter.read();\n if (data === null) {\n return null;\n }\n else {\n return this.#parse(data);\n }\n }\n write(obj) {\n this.#adapter.write(this.#stringify(obj));\n }\n}\n", "import { DataFile, DataFileSync } from './DataFile.js';\nexport class JSONFile extends DataFile {\n constructor(filename) {\n super(filename, {\n parse: JSON.parse,\n stringify: (data) => JSON.stringify(data, null, 2),\n });\n }\n}\nexport class JSONFileSync extends DataFileSync {\n constructor(filename) {\n super(filename, {\n parse: JSON.parse,\n stringify: (data) => JSON.stringify(data, null, 2),\n });\n }\n}\n", "/**\n * Session Data Management\n * Provides unified JSON storage and session lifecycle management using lowdb\n */\n\nimport { Low } from 'lowdb';\nimport { JSONFileSync } from 'lowdb/node';\nimport { mkdirSync, writeFileSync } from 'fs';\nimport { join } from 'path';\nimport { randomUUID } from 'crypto';\nimport { getProjectTmpBase } from '../utils/temp-dir';\nimport {\n QueryDevelopmentSession,\n QueryState,\n MCPCallRecord,\n TestExecutionRecord,\n QualityScoreRecord,\n SessionFilter,\n MonitoringConfig,\n MonitoringConfigSchema,\n} from '../types/monitoring';\nimport { logger } from '../utils/logger';\n\n/**\n * Database schema for lowdb - sessions only\n */\ninterface SessionDatabase {\n sessions: QueryDevelopmentSession[];\n}\n\n/**\n * Session Data Manager - handles all session persistence and lifecycle\n */\nexport class SessionDataManager {\n private db: Low;\n private config: MonitoringConfig;\n private storageDir: string;\n\n constructor(configOverrides: Partial = {}) {\n this.config = MonitoringConfigSchema.parse({\n ...MonitoringConfigSchema.parse({}),\n ...configOverrides,\n });\n\n this.storageDir = this.config.storageLocation;\n this.ensureStorageDirectory();\n\n const adapter = new JSONFileSync(join(this.storageDir, 'sessions.json'));\n this.db = new Low(adapter, {\n sessions: [],\n });\n\n this.initializeDatabase();\n }\n\n /**\n * Initialize the database and ensure it's properly set up\n */\n async initialize(): Promise {\n await this.initializeDatabase();\n }\n\n /**\n * Initialize the database and ensure it's properly set up\n */\n private async initializeDatabase(): Promise {\n try {\n await this.db.read();\n \n logger.info(`Session data manager initialized with ${this.db.data.sessions.length} sessions`);\n } catch (error) {\n logger.error('Failed to initialize session database:', error);\n throw error;\n }\n }\n\n /**\n * Ensure storage directory structure exists\n */\n private ensureStorageDirectory(): void {\n try {\n // mkdirSync with recursive: true is a no-op if directories already exist\n mkdirSync(this.storageDir, { recursive: true });\n\n // Create subdirectories\n const subdirs = ['sessions-archive', 'exports'];\n for (const subdir of subdirs) {\n mkdirSync(join(this.storageDir, subdir), { recursive: true });\n }\n\n // Use 'wx' flag (exclusive create) to atomically create config only\n // if it doesn't exist, avoiding TOCTOU race (CWE-367).\n const configPath = join(this.storageDir, 'config.json');\n try {\n writeFileSync(configPath, JSON.stringify(this.config, null, 2), { flag: 'wx' });\n } catch (e: unknown) {\n const err = e as { code?: string };\n if (err.code !== 'EEXIST') throw e;\n }\n\n logger.debug(`Storage directory initialized: ${this.storageDir}`);\n } catch (error) {\n logger.error('Failed to create storage directory:', error);\n throw error;\n }\n }\n\n /**\n * Start a new query development session\n */\n async startSession(\n queryPath: string,\n language?: string,\n queryType?: string,\n description?: string\n ): Promise {\n const sessionId = randomUUID();\n const startTime = new Date().toISOString();\n\n const session: QueryDevelopmentSession = {\n sessionId,\n queryPath,\n language: language || 'unknown',\n queryType,\n description,\n startTime,\n status: 'active',\n mcpCalls: [],\n testExecutions: [],\n qualityScores: [],\n currentState: {\n filesPresent: [],\n compilationStatus: 'unknown',\n testStatus: 'unknown',\n documentationStatus: 'unknown',\n lastActivity: startTime,\n },\n recommendations: [],\n };\n\n await this.db.read();\n this.db.data.sessions.push(session);\n await this.db.write();\n\n logger.info(`Started new session: ${sessionId} for query: ${queryPath}`);\n return sessionId;\n }\n\n /**\n * End a session with final status\n */\n async endSession(\n sessionId: string,\n status: 'completed' | 'failed' | 'abandoned'\n ): Promise {\n await this.db.read();\n \n const session = this.db.data.sessions.find(s => s.sessionId === sessionId);\n if (!session) {\n logger.warn(`Session not found: ${sessionId}`);\n return null;\n }\n\n session.status = status;\n session.endTime = new Date().toISOString();\n session.currentState.lastActivity = session.endTime;\n\n await this.db.write();\n\n // Archive completed session if enabled\n if (this.config.archiveCompletedSessions && status === 'completed') {\n await this.archiveSession(sessionId);\n }\n\n logger.info(`Ended session: ${sessionId} with status: ${status}`);\n return session;\n }\n\n /**\n * Get a specific session by ID\n */\n async getSession(sessionId: string): Promise {\n await this.db.read();\n const session = this.db.data.sessions.find(s => s.sessionId === sessionId);\n return session || null;\n }\n\n /**\n * List sessions with optional filtering\n */\n async listSessions(filters?: SessionFilter): Promise {\n await this.db.read();\n let sessions = [...this.db.data.sessions];\n\n if (filters) {\n if (filters.queryPath) {\n sessions = sessions.filter(s => s.queryPath.includes(filters.queryPath!));\n }\n if (filters.status) {\n sessions = sessions.filter(s => s.status === filters.status);\n }\n if (filters.language) {\n sessions = sessions.filter(s => s.language === filters.language);\n }\n if (filters.queryType) {\n sessions = sessions.filter(s => s.queryType === filters.queryType);\n }\n if (filters.dateRange) {\n const [start, end] = filters.dateRange;\n sessions = sessions.filter(s => \n s.startTime >= start && s.startTime <= end\n );\n }\n }\n\n return sessions;\n }\n\n /**\n * Update session state\n */\n async updateSessionState(\n sessionId: string,\n stateUpdate: Partial\n ): Promise {\n await this.db.read();\n \n const session = this.db.data.sessions.find(s => s.sessionId === sessionId);\n if (!session) {\n logger.warn(`Session not found: ${sessionId}`);\n return null;\n }\n\n session.currentState = {\n ...session.currentState,\n ...stateUpdate,\n lastActivity: new Date().toISOString(),\n };\n\n await this.db.write();\n return session;\n }\n\n /**\n * Add MCP call record to session\n */\n async addMCPCall(sessionId: string, callRecord: MCPCallRecord): Promise {\n await this.db.read();\n \n const session = this.db.data.sessions.find(s => s.sessionId === sessionId);\n if (!session) {\n logger.warn(`Session not found for MCP call: ${sessionId}`);\n return;\n }\n\n session.mcpCalls.push(callRecord);\n session.currentState.lastActivity = callRecord.timestamp;\n\n // Update next suggested tool if provided\n if (callRecord.nextSuggestedTool) {\n session.nextSuggestedTool = callRecord.nextSuggestedTool;\n }\n\n await this.db.write();\n }\n\n /**\n * Add test execution record to session\n */\n async addTestExecution(sessionId: string, testRecord: TestExecutionRecord): Promise {\n await this.db.read();\n \n const session = this.db.data.sessions.find(s => s.sessionId === sessionId);\n if (!session) {\n logger.warn(`Session not found for test execution: ${sessionId}`);\n return;\n }\n\n session.testExecutions.push(testRecord);\n session.currentState.lastActivity = testRecord.timestamp;\n\n // Update compilation/test status based on execution\n if (testRecord.type === 'compilation') {\n session.currentState.compilationStatus = testRecord.success ? 'success' : 'failed';\n } else if (testRecord.type === 'test_run') {\n session.currentState.testStatus = testRecord.success ? 'passing' : 'failing';\n }\n\n await this.db.write();\n }\n\n /**\n * Add quality score record to session\n */\n async addQualityScore(sessionId: string, scoreRecord: QualityScoreRecord): Promise {\n await this.db.read();\n \n const session = this.db.data.sessions.find(s => s.sessionId === sessionId);\n if (!session) {\n logger.warn(`Session not found for quality score: ${sessionId}`);\n return;\n }\n\n session.qualityScores.push(scoreRecord);\n session.currentState.lastActivity = scoreRecord.timestamp;\n session.recommendations = scoreRecord.recommendations;\n\n await this.db.write();\n }\n\n /**\n * Archive a completed session to monthly file\n */\n private async archiveSession(sessionId: string): Promise {\n try {\n const session = await this.getSession(sessionId);\n if (!session) return;\n\n const date = new Date(session.endTime || session.startTime);\n const monthDir = `${date.getFullYear()}-${String(date.getMonth() + 1).padStart(2, '0')}`;\n const archiveDir = join(this.storageDir, 'sessions-archive', monthDir);\n\n mkdirSync(archiveDir, { recursive: true });\n\n const archiveFile = join(archiveDir, `${sessionId}.json`);\n writeFileSync(archiveFile, JSON.stringify(session, null, 2));\n\n // Remove from active sessions\n await this.db.read();\n this.db.data.sessions = this.db.data.sessions.filter(s => s.sessionId !== sessionId);\n await this.db.write();\n\n logger.info(`Archived session: ${sessionId} to ${archiveFile}`);\n } catch (error) {\n logger.error(`Failed to archive session ${sessionId}:`, error);\n }\n }\n\n /**\n * Get active sessions for a specific query path\n */\n async getActiveSessionsForQuery(queryPath: string): Promise {\n await this.db.read();\n return this.db.data.sessions.filter(s => \n s.queryPath === queryPath && s.status === 'active'\n );\n }\n\n /**\n * Clean up old sessions based on retention policy\n */\n async cleanupOldSessions(): Promise {\n const cutoffDate = new Date();\n cutoffDate.setDate(cutoffDate.getDate() - this.config.retentionDays);\n const cutoffTimestamp = cutoffDate.toISOString();\n\n await this.db.read();\n const sessionsToRemove = this.db.data.sessions.filter(s => \n s.endTime && s.endTime < cutoffTimestamp\n );\n\n if (sessionsToRemove.length > 0) {\n this.db.data.sessions = this.db.data.sessions.filter(s => \n !s.endTime || s.endTime >= cutoffTimestamp\n );\n await this.db.write();\n\n logger.info(`Cleaned up ${sessionsToRemove.length} old sessions`);\n }\n }\n\n /**\n * Get configuration\n */\n getConfig(): MonitoringConfig {\n return this.config;\n }\n\n /**\n * Update configuration\n */\n async updateConfig(configUpdate: Partial): Promise {\n this.config = MonitoringConfigSchema.parse({\n ...this.config,\n ...configUpdate,\n });\n\n // Update config.json file only\n const configPath = join(this.storageDir, 'config.json');\n writeFileSync(configPath, JSON.stringify(this.config, null, 2));\n\n logger.info('Updated monitoring configuration');\n }\n}\n\n/**\n * Parse boolean environment variable\n */\nfunction parseBoolEnv(envVar: string | undefined, defaultValue: boolean): boolean {\n if (envVar === undefined) return defaultValue;\n return envVar.toLowerCase() === 'true' || envVar === '1';\n}\n\n// Export singleton instance with environment variable support\nexport const sessionDataManager = new SessionDataManager({\n storageLocation: process.env.MONITORING_STORAGE_LOCATION || join(getProjectTmpBase(), '.ql-mcp-tracking'),\n enableMonitoringTools: parseBoolEnv(process.env.ENABLE_MONITORING_TOOLS, false),\n});", "import { z } from 'zod';\n\n/**\n * Monitoring and Reporting types for CodeQL Development MCP Server\n * Based on the specification in docs/mcp-server-monitoring-and-reporting.md\n */\n\n/**\n * MCP Call Record - captures individual MCP tool calls\n */\nexport const MCPCallRecordSchema = z.object({\n callId: z.string(),\n timestamp: z.string(), // ISO timestamp\n toolName: z.string(),\n parameters: z.record(z.any()),\n result: z.any(),\n success: z.boolean(),\n duration: z.number(), // milliseconds\n nextSuggestedTool: z.string().optional(),\n});\n\nexport type MCPCallRecord = z.infer;\n\n/**\n * Test Execution Record - captures query compilation and test runs\n */\nexport const TestExecutionRecordSchema = z.object({\n executionId: z.string(),\n timestamp: z.string(),\n type: z.enum(['compilation', 'test_run', 'database_build']),\n success: z.boolean(),\n details: z.record(z.any()),\n metrics: z.object({\n passRate: z.number().optional(),\n coverage: z.number().optional(),\n performance: z.number().optional(),\n }).optional(),\n});\n\nexport type TestExecutionRecord = z.infer;\n\n/**\n * Quality Score Record - multi-dimensional quality assessment\n */\nexport const QualityScoreRecordSchema = z.object({\n scoreId: z.string(),\n timestamp: z.string(),\n overallScore: z.number().min(0).max(100), // 0-100\n dimensions: z.object({\n syntacticCorrectness: z.number().min(0).max(100),\n testCoverageResults: z.number().min(0).max(100),\n documentationQuality: z.number().min(0).max(100),\n functionalCorrectness: z.number().min(0).max(100),\n }),\n grade: z.enum(['A', 'B', 'C', 'D', 'F']),\n recommendations: z.array(z.string()),\n});\n\nexport type QualityScoreRecord = z.infer;\n\n/**\n * Query State - current state of the query development\n */\nexport const QueryStateSchema = z.object({\n filesPresent: z.array(z.string()),\n compilationStatus: z.enum(['unknown', 'success', 'failed']),\n testStatus: z.enum(['unknown', 'passing', 'failing', 'no_tests']),\n documentationStatus: z.enum(['unknown', 'present', 'missing', 'incomplete']),\n lastActivity: z.string(), // ISO timestamp\n});\n\nexport type QueryState = z.infer;\n\n/**\n * Query Development Session - main data structure for tracking\n */\nexport const QueryDevelopmentSessionSchema = z.object({\n // Session Metadata\n sessionId: z.string(),\n queryPath: z.string(),\n language: z.string(),\n queryType: z.string().optional(),\n description: z.string().optional(),\n startTime: z.string(), // ISO timestamp\n endTime: z.string().optional(), // ISO timestamp\n status: z.enum(['active', 'completed', 'failed', 'abandoned']),\n\n // MCP Call History\n mcpCalls: z.array(MCPCallRecordSchema),\n\n // Test Execution Records\n testExecutions: z.array(TestExecutionRecordSchema),\n\n // Quality Metrics\n qualityScores: z.array(QualityScoreRecordSchema),\n\n // Development State\n currentState: QueryStateSchema,\n recommendations: z.array(z.string()),\n nextSuggestedTool: z.string().optional(),\n});\n\nexport type QueryDevelopmentSession = z.infer;\n\n/**\n * Session Filter for listing and searching\n */\nexport const SessionFilterSchema = z.object({\n queryPath: z.string().optional(),\n status: z.string().optional(),\n dateRange: z.tuple([z.string(), z.string()]).optional(),\n language: z.string().optional(),\n queryType: z.string().optional(),\n});\n\nexport type SessionFilter = z.infer;\n\n/**\n * Comparison Report for analyzing multiple sessions\n */\nexport const ComparisonReportSchema = z.object({\n sessionIds: z.array(z.string()),\n dimensions: z.array(z.string()),\n timestamp: z.string(),\n results: z.record(z.any()),\n});\n\nexport type ComparisonReport = z.infer;\n\n/**\n * Aggregate Report for batch analysis\n */\nexport const AggregateReportSchema = z.object({\n filters: SessionFilterSchema,\n timestamp: z.string(),\n totalSessions: z.number(),\n successRate: z.number(),\n averageQualityScore: z.number(),\n commonPatterns: z.array(z.string()),\n recommendations: z.array(z.string()),\n});\n\nexport type AggregateReport = z.infer;\n\n/**\n * Export Result for data export operations\n */\nexport const ExportResultSchema = z.object({\n format: z.enum(['json', 'html', 'markdown']),\n filename: z.string(),\n content: z.string(),\n timestamp: z.string(),\n});\n\nexport type ExportResult = z.infer;\n\n/**\n * Functional Test Result for automated testing\n */\nexport const FunctionalTestResultSchema = z.object({\n sessionId: z.string(),\n queryPath: z.string(),\n passed: z.boolean(),\n criteria: z.record(z.any()),\n details: z.record(z.any()),\n timestamp: z.string(),\n});\n\nexport type FunctionalTestResult = z.infer;\n\n/**\n * Test Report for comprehensive test analysis\n */\nexport const TestReportSchema = z.object({\n sessionIds: z.array(z.string()),\n criteria: z.record(z.any()),\n timestamp: z.string(),\n overallPassRate: z.number(),\n results: z.array(FunctionalTestResultSchema),\n summary: z.record(z.any()),\n});\n\nexport type TestReport = z.infer;\n\n/**\n * Monitoring Configuration\n */\nexport const MonitoringConfigSchema = z.object({\n storageLocation: z.string().default('.ql-mcp-tracking/'),\n autoTrackSessions: z.boolean().default(true),\n retentionDays: z.number().default(90),\n includeCallParameters: z.boolean().default(true),\n includeCallResults: z.boolean().default(true),\n maxActiveSessionsPerQuery: z.number().default(3),\n scoringFrequency: z.enum(['per_call', 'periodic', 'manual']).default('per_call'),\n archiveCompletedSessions: z.boolean().default(true),\n enableRecommendations: z.boolean().default(true),\n enableMonitoringTools: z.boolean().default(false), // Opt-in: session_* tools disabled by default for end-users\n});\n\nexport type MonitoringConfig = z.infer;"], - "mappings": "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", - "names": ["type", "resolve", "setTimeout", "resolve", "setTimeout", "clearTimeout", "join", "resolve", "spawn", "delimiter", "EventEmitter", "clearTimeout", "setTimeout", "resolve", "spawn", "delimiter", "EventEmitter", "clearTimeout", "setTimeout", "resolve", "mkdirSync", "join", "type", "packageRootDir", "resolve", "existsSync", "delimiter", "dirname", "isAbsolute", "binary", "getServerManager", "resolve", "pathToFileURL", "z", "readFileSync", "dirname", "isAbsolute", "mkdirSync", "mkdirSync", "existsSync", "join", "resolve", "timestamp", "writeFileSync", "existsSync", "mkdirSync", "basename", "dirname", "isAbsolute", "join", "resolve", "logger", "executeCodeQLCommand", "basename", "mkdirSync", "dirname", "z", "z", "z", "z", "z", "z", "z", "z", "z", "z", "readFile", "z", "exception", "map", "schema", "type", "extend", "str", "string", "z", "z", "z", "z", "z", "existsSync", "readdirSync", "readFileSync", "statSync", "join", "z", "readFileSync", "existsSync", "readdirSync", "join", "statSync", "z", "existsSync", "readdirSync", "readFileSync", "statSync", "join", "z", "existsSync", "readdirSync", "join", "statSync", "timestamp", "readFileSync", "z", "z", "z", "z", "z", "z", "writeFileSync", "readFileSync", "existsSync", "join", "dirname", "basename", "mkdirSync", "z", "z", "z", "z", "z", "z", "join", "resolve", "resolve", "join", "z", "z", "resolve", "z", "z", "z", "z", "z", "z", "z", "z", "z", "z", "z", "z", "z", "z", "z", "z", "z", "z", "z", "z", "fs", "path", "getLanguageExtension", "z", "readFileSync", "join", "dirname", "fileURLToPath", "__filename", "__dirname", "z", "join", "pathToFileURL", "isAbsolute", "resolve", "pathToFileURL", "getUserWorkspaceDir", "pathToFileURL", "join", "z", "readFile", "isAbsolute", "resolve", "pathToFileURL", "isAbsolute", "resolve", "pathToFileURL", "readFile", "z", "z", "readFileSync", "existsSync", "join", "join", "existsSync", "readFileSync", "z", "basename", "readFileSync", "join", "dirname", "fileURLToPath", "__filename", "__dirname", "z", "basename", "z", "randomUUID", "readFileSync", "writeFileSync", "path", "path", "readFileSync", "str", "writeFileSync", "parse", "mkdirSync", "writeFileSync", "join", "randomUUID", "z", "join", "mkdirSync", "writeFileSync", "randomUUID", "z", "timestamp", "randomUUID", "resolve", "pathToFileURL"] + "sources": ["../src/utils/logger.ts", "../src/lib/server-config.ts", "../src/utils/package-paths.ts", "../src/utils/temp-dir.ts", "../src/utils/process-ready.ts", "../src/lib/language-server.ts", "../src/lib/query-server.ts", "../src/lib/cli-server.ts", "../src/lib/server-manager.ts", "../src/lib/cli-executor.ts", "../src/codeql-development-mcp-server.ts", "../src/tools/codeql/bqrs-decode.ts", "../src/lib/cli-tool-registry.ts", "../src/lib/query-results-evaluator.ts", "../src/lib/log-directory-manager.ts", "../src/tools/codeql/bqrs-info.ts", "../src/tools/codeql/bqrs-interpret.ts", "../src/tools/codeql/database-analyze.ts", "../src/tools/codeql/database-create.ts", "../src/tools/codeql/find-class-position.ts", "../src/tools/codeql/find-predicate-position.ts", "../src/tools/codeql/find-query-files.ts", "../src/lib/query-file-finder.ts", "../../node_modules/js-yaml/dist/js-yaml.mjs", "../src/lib/metadata-resolver.ts", "../src/tools/codeql/generate-log-summary.ts", "../src/tools/codeql/generate-query-help.ts", "../src/tools/codeql/list-databases.ts", "../src/lib/discovery-config.ts", "../src/tools/codeql/list-mrva-run-results.ts", "../src/tools/codeql/list-query-run-results.ts", "../src/tools/codeql/pack-install.ts", "../src/tools/codeql/pack-ls.ts", "../src/tools/codeql/profile-codeql-query-from-logs.ts", "../src/lib/evaluator-log-parser.ts", "../src/tools/codeql/profile-codeql-query.ts", "../src/tools/codeql/query-compile.ts", "../src/tools/codeql/query-format.ts", "../src/tools/codeql/query-run.ts", "../src/tools/codeql/quick-evaluate.ts", "../src/tools/codeql/register-database.ts", "../src/tools/codeql/resolve-database.ts", "../src/tools/codeql/resolve-languages.ts", "../src/tools/codeql/resolve-library-path.ts", "../src/tools/codeql/resolve-metadata.ts", "../src/tools/codeql/resolve-qlref.ts", "../src/tools/codeql/resolve-queries.ts", "../src/tools/codeql/resolve-tests.ts", "../src/tools/codeql/test-accept.ts", "../src/tools/codeql/test-extract.ts", "../src/tools/codeql/test-run.ts", "../src/tools/codeql-tools.ts", "../src/lib/validation.ts", "../src/lib/query-scaffolding.ts", "../src/lib/resources.ts", "../src/tools/codeql-resources.ts", "../src/tools/lsp/lsp-diagnostics.ts", "../src/tools/lsp/lsp-server-helper.ts", "../src/tools/lsp/lsp-handlers.ts", "../src/tools/lsp/lsp-tools.ts", "../src/resources/language-resources.ts", "../src/types/language-types.ts", "../src/prompts/workflow-prompts.ts", "../src/prompts/prompt-loader.ts", "../src/tools/monitoring-tools.ts", "../../node_modules/lowdb/lib/core/Low.js", "../../node_modules/lowdb/lib/adapters/node/TextFile.js", "../../node_modules/lowdb/lib/adapters/node/DataFile.js", "../../node_modules/lowdb/lib/adapters/node/JSONFile.js", "../src/lib/session-data-manager.ts", "../src/types/monitoring.ts"], + "sourcesContent": ["/**\n * Simple logger utility.\n *\n * All log output is written to stderr. In stdio transport mode, stdout is\n * reserved exclusively for the MCP JSON-RPC protocol \u2014 any non-protocol\n * bytes on stdout would corrupt the message stream.\n */\nexport const logger = {\n info: (message: string, ...args: unknown[]) => {\n console.error(`[INFO] ${new Date().toISOString()} ${message}`, ...args);\n },\n error: (message: string, ...args: unknown[]) => {\n console.error(`[ERROR] ${new Date().toISOString()} ${message}`, ...args);\n },\n warn: (message: string, ...args: unknown[]) => {\n console.error(`[WARN] ${new Date().toISOString()} ${message}`, ...args);\n },\n debug: (message: string, ...args: unknown[]) => {\n if (process.env.DEBUG) {\n console.error(`[DEBUG] ${new Date().toISOString()} ${message}`, ...args);\n }\n },\n};\n", "/**\n * Configuration types for CodeQL background server processes.\n *\n * CodeQL provides three background server types:\n * 1. language-server \u2013 LSP-based QL validation (JSON-RPC over stdio)\n * 2. query-server2 \u2013 Query evaluation (custom protocol over stdio)\n * 3. cli-server \u2013 JVM reuse for CLI commands (custom protocol over stdio)\n *\n * Each server type has its own configuration options, but they share common\n * settings like searchPath and commonCaches.\n */\n\nimport { createHash } from 'crypto';\n\n/**\n * Server types supported by CodeQL.\n */\nexport type CodeQLServerType = 'cli' | 'language' | 'query';\n\n/**\n * Common configuration shared across all server types.\n */\nexport interface BaseServerConfig {\n /** Path to QL packs (like `codeql query compile --search-path`). */\n searchPath?: string;\n /** Location for cached data (compilation plans, downloaded packs). */\n commonCaches?: string;\n /** Directory for detailed logs. */\n logdir?: string;\n}\n\n/**\n * Configuration for the CodeQL Language Server.\n */\nexport interface LanguageServerConfig extends BaseServerConfig {\n /** Error checking mode. Default: ON_CHANGE */\n checkErrors?: 'EXPLICIT' | 'ON_CHANGE';\n /** Log level for the language server. */\n loglevel?: 'ALL' | 'DEBUG' | 'ERROR' | 'INFO' | 'OFF' | 'TRACE' | 'WARN';\n /** Single-threaded execution. */\n synchronous?: boolean;\n /** Verbosity level for progress. */\n verbosity?: 'errors' | 'progress' | 'progress+' | 'progress++' | 'progress+++' | 'warnings';\n}\n\n/**\n * Configuration for the CodeQL Query Server (query-server2).\n */\nexport interface QueryServerConfig extends BaseServerConfig {\n /** Thread count. 0 = one per core, -N = leave N cores free. */\n threads?: number;\n /** Query evaluation timeout in seconds. */\n timeout?: number;\n /** Maximum disk cache size in MB for intermediate results. */\n maxDiskCache?: number;\n /** Path for structured evaluator performance logs. */\n evaluatorLog?: string;\n /** Include tuple counts in evaluation logs. */\n tupleCounting?: boolean;\n /** Enable debug mode. */\n debug?: boolean;\n}\n\n/**\n * Configuration for the CodeQL CLI Server.\n */\nexport interface CLIServerConfig extends BaseServerConfig {\n // cli-server has fewer options \u2014 just commonCaches and logdir.\n}\n\n/**\n * Union of all server configurations (discriminated by usage context).\n */\nexport type ServerConfig = CLIServerConfig | LanguageServerConfig | QueryServerConfig;\n\n/**\n * Compute a deterministic hash for a server configuration.\n * Used to detect configuration changes that require a server restart.\n *\n * @param type - The server type.\n * @param config - The server configuration.\n * @returns A hex-encoded SHA-256 hash of the canonical JSON representation.\n */\nexport function computeConfigHash(type: CodeQLServerType, config: ServerConfig): string {\n // Deep-sort all keys to ensure deterministic serialization regardless of\n // property insertion order.\n const sortKeys = (_key: string, value: unknown): unknown => {\n if (value && typeof value === 'object' && !Array.isArray(value)) {\n const sorted: Record = {};\n for (const k of Object.keys(value as Record).sort()) {\n sorted[k] = (value as Record)[k];\n }\n return sorted;\n }\n return value;\n };\n const canonical = JSON.stringify({ config, type }, sortKeys);\n return createHash('sha256').update(canonical).digest('hex');\n}\n\n/**\n * Build command-line arguments for a language server from its configuration.\n */\nexport function buildLanguageServerArgs(config: LanguageServerConfig): string[] {\n const args: string[] = [\n 'execute', 'language-server',\n `--check-errors=${config.checkErrors ?? 'ON_CHANGE'}`,\n ];\n\n if (config.searchPath) {\n args.push(`--search-path=${config.searchPath}`);\n }\n if (config.commonCaches) {\n args.push(`--common-caches=${config.commonCaches}`);\n }\n if (config.logdir) {\n args.push(`--logdir=${config.logdir}`);\n }\n if (config.loglevel) {\n args.push(`--loglevel=${config.loglevel}`);\n }\n if (config.synchronous) {\n args.push('--synchronous');\n }\n if (config.verbosity) {\n args.push(`--verbosity=${config.verbosity}`);\n }\n\n return args;\n}\n\n/**\n * Build command-line arguments for a query server from its configuration.\n */\nexport function buildQueryServerArgs(config: QueryServerConfig): string[] {\n const args: string[] = [\n 'execute', 'query-server2',\n ];\n\n if (config.searchPath) {\n args.push(`--search-path=${config.searchPath}`);\n }\n if (config.commonCaches) {\n args.push(`--common-caches=${config.commonCaches}`);\n }\n if (config.logdir) {\n args.push(`--logdir=${config.logdir}`);\n }\n if (config.threads !== undefined) {\n args.push(`--threads=${config.threads}`);\n }\n if (config.timeout !== undefined) {\n args.push(`--timeout=${config.timeout}`);\n }\n if (config.maxDiskCache !== undefined) {\n args.push(`--max-disk-cache=${config.maxDiskCache}`);\n }\n if (config.evaluatorLog) {\n args.push(`--evaluator-log=${config.evaluatorLog}`);\n }\n if (config.debug) {\n args.push('--debug');\n args.push('--tuple-counting');\n } else if (config.tupleCounting) {\n args.push('--tuple-counting');\n }\n\n return args;\n}\n\n/**\n * Build command-line arguments for a CLI server from its configuration.\n */\nexport function buildCLIServerArgs(config: CLIServerConfig): string[] {\n const args: string[] = [\n 'execute', 'cli-server',\n ];\n\n if (config.commonCaches) {\n args.push(`--common-caches=${config.commonCaches}`);\n }\n if (config.logdir) {\n args.push(`--logdir=${config.logdir}`);\n }\n\n return args;\n}\n", "/**\n * Utilities for resolving filesystem paths relative to the server package root.\n *\n * The server can run from three different directory layouts:\n *\n * 1. **Source** (dev): `server/src/lib/` \u2192 packageRoot = `server/`\n * 2. **Bundle in monorepo** (dev/CI): `server/dist/` \u2192 packageRoot = `server/`\n * 3. **Bundle via npm** (production): `/dist/` \u2192 packageRoot = `/`\n *\n * In all three cases, the bundled QL tool query packs live at\n * `/ql//tools/src/`.\n *\n * The \"workspace root\" (monorepo root) is one level above packageRoot when\n * running from the monorepo checkout, and the packageRoot itself when running\n * from an npm install (no parent monorepo).\n */\n\nimport { dirname, resolve } from 'path';\nimport { existsSync, readFileSync } from 'fs';\nimport { fileURLToPath } from 'url';\n\nconst __filename = fileURLToPath(import.meta.url);\nconst __dirname = dirname(__filename);\n\n/**\n * Detect whether the current __dirname looks like source code (`src/lib` or\n * `src/utils`) vs a bundled flat output directory (`dist/`).\n *\n * Uses a tail-of-path check so that unrelated `/src/` segments earlier in the\n * install path (e.g. `~/src/project/node_modules/.../dist`) don't cause a\n * false positive.\n */\nfunction isRunningFromSource(dir: string): boolean {\n const normalized = dir.replace(/\\\\/g, '/');\n return /\\/src(\\/[^/]+)?$/.test(normalized);\n}\n\n/**\n * Get the server package root directory.\n *\n * - From source (`server/src/utils/`): up 2 levels \u2192 `server/`\n * - From bundle (`server/dist/` or `/dist/`): up 1 level \u2192 package root\n */\nexport function getPackageRootDir(currentDir: string = __dirname): string {\n return isRunningFromSource(currentDir)\n ? resolve(currentDir, '..', '..') // src/utils \u2192 server/\n : resolve(currentDir, '..'); // dist/ \u2192 package root\n}\n\n/**\n * Get the workspace root directory (monorepo root when applicable).\n *\n * If a `package.json` with `workspaces` exists one level above the package\n * root, we're in a monorepo and that parent is the workspace root. Otherwise,\n * the packageRoot itself is the workspace root (npm install scenario).\n */\nexport function getWorkspaceRootDir(packageRoot?: string): string {\n const pkgRoot = packageRoot ?? getPackageRootDir();\n const parentDir = resolve(pkgRoot, '..');\n\n // In the monorepo, the parent directory contains a package.json with workspaces\n try {\n const parentPkgPath = resolve(parentDir, 'package.json');\n if (existsSync(parentPkgPath)) {\n const parentPkg = JSON.parse(readFileSync(parentPkgPath, 'utf8'));\n if (parentPkg.workspaces) {\n return parentDir;\n }\n }\n } catch {\n // Not in a monorepo \u2014 fall through\n }\n\n return pkgRoot;\n}\n\n/**\n * Resolve the path to a tool query pack's source directory.\n *\n * @param language - CodeQL language identifier (e.g., \"javascript\", \"cpp\")\n * @param packageRoot - Override the package root (for testing)\n * @returns Absolute path to `ql//tools/src/`\n */\nexport function resolveToolQueryPackPath(language: string, packageRoot?: string): string {\n const pkgRoot = packageRoot ?? getPackageRootDir();\n return resolve(pkgRoot, 'ql', language, 'tools', 'src');\n}\n\n/**\n * Read the package version from the nearest package.json.\n *\n * Cached at first call so the file is read at most once per process.\n */\nlet _cachedVersion: string | undefined;\nexport function getPackageVersion(): string {\n if (_cachedVersion !== undefined) return _cachedVersion;\n try {\n const pkgPath = resolve(getPackageRootDir(), 'package.json');\n const pkg = JSON.parse(readFileSync(pkgPath, 'utf8'));\n _cachedVersion = pkg.version ?? '0.0.0';\n } catch {\n _cachedVersion = '0.0.0';\n }\n return _cachedVersion as string;\n}\n\n/**\n * Get the effective workspace directory for resolving user-supplied relative\n * paths (test directories, database paths, pack dirs, etc.).\n *\n * In a monorepo checkout the workspace root is the monorepo parent. In an\n * npm-installed layout, `workspaceRootDir` falls back to `packageRootDir`\n * which may be read-only and is not the user's project. In that case we\n * fall back to `process.cwd()` so that relative paths resolve against the\n * directory the user actually invoked the server from.\n *\n * Override with `CODEQL_MCP_WORKSPACE` for deterministic behavior.\n */\nexport function getUserWorkspaceDir(): string {\n if (process.env.CODEQL_MCP_WORKSPACE) {\n return process.env.CODEQL_MCP_WORKSPACE;\n }\n // When workspaceRootDir === packageRootDir we are NOT in a monorepo\n // (npm-installed), so fall back to process.cwd().\n if (workspaceRootDir === packageRootDir) {\n return process.cwd();\n }\n return workspaceRootDir;\n}\n\n// Pre-computed values for use throughout the server\nexport const packageRootDir = getPackageRootDir();\nexport const workspaceRootDir = getWorkspaceRootDir(packageRootDir);\n", "/**\n * Secure project-local temporary directory utilities.\n *\n * All temporary files are created under `/.tmp/` which is\n * `.gitignore`d. This avoids writing to the OS temp directory\n * (`os.tmpdir()` / `/tmp`), which is world-readable and triggers\n * CWE-377 / CWE-378 (js/insecure-temporary-file).\n */\n\nimport { mkdirSync, mkdtempSync } from 'fs';\nimport { isAbsolute, join, resolve } from 'path';\nimport { getPackageRootDir } from './package-paths';\n\n/**\n * Base directory for all project-local temporary data.\n *\n * Resolution order:\n * 1. `CODEQL_MCP_TMP_DIR` environment variable \u2014 for read-only package root\n * scenarios (e.g., npm global installs where the package directory is not\n * writable). Relative paths are resolved against process.cwd().\n * 2. `/.tmp` \u2014 default; excluded from version control.\n */\nconst PROJECT_TMP_BASE = process.env.CODEQL_MCP_TMP_DIR\n ? (isAbsolute(process.env.CODEQL_MCP_TMP_DIR) \n ? process.env.CODEQL_MCP_TMP_DIR \n : resolve(process.cwd(), process.env.CODEQL_MCP_TMP_DIR))\n : join(getPackageRootDir(), '.tmp');\n\n/**\n * Return the project-local `.tmp` base directory, creating it if needed.\n */\nexport function getProjectTmpBase(): string {\n mkdirSync(PROJECT_TMP_BASE, { recursive: true });\n return PROJECT_TMP_BASE;\n}\n\n/**\n * Create a unique temporary directory under the project `.tmp` root.\n *\n * Works identically to `fs.mkdtempSync(os.tmpdir(), prefix)` but is\n * scoped to the repository.\n *\n * @param prefix - Directory name prefix (e.g. `'codeql-external-'`).\n * @returns Absolute path to the newly created directory.\n */\nexport function createProjectTempDir(prefix: string): string {\n const base = getProjectTmpBase();\n return mkdtempSync(join(base, prefix));\n}\n\n/**\n * Return a deterministic subdirectory under `.tmp/`, creating it\n * if it does not already exist.\n *\n * Useful for well-known scratch areas such as `query-logs` or `quickeval`.\n *\n * @param name - Subdirectory name (e.g. `'query-logs'`).\n * @returns Absolute path to the subdirectory.\n */\nexport function getProjectTmpDir(name: string): string {\n const dir = join(getProjectTmpBase(), name);\n mkdirSync(dir, { recursive: true });\n return dir;\n}\n", "/**\n * Utility for waiting until a spawned child process is ready.\n *\n * CodeQL background servers (cli-server, query-server2, language-server) run\n * on the JVM and emit stderr log output once the JVM has initialised. Rather\n * than sleeping for a hard-coded duration \u2014 which is fragile on both fast and\n * slow machines \u2014 this helper resolves as soon as the first stderr output\n * arrives (indicating the JVM is alive), or when the maximum timeout expires.\n * It also rejects immediately if the process exits or errors before becoming\n * ready, giving callers a clear error instead of a silent hang.\n */\n\nimport { ChildProcess } from 'child_process';\nimport { clearTimeout, setTimeout } from 'timers';\nimport { logger } from './logger';\n\n/** Default maximum wait for a CodeQL server to become ready (30 s). */\nconst DEFAULT_READY_TIMEOUT_MS = 30_000;\n\n/**\n * Options for {@link waitForProcessReady}.\n */\nexport interface ProcessReadyOptions {\n /**\n * Maximum time in milliseconds to wait for the process to emit its first\n * stderr output. If the timeout is reached without a signal the promise\n * still resolves (best-effort) so the caller can attempt communication.\n *\n * Default: 30 000 ms.\n */\n timeoutMs?: number;\n}\n\n/**\n * Wait until a child process signals readiness.\n *\n * \"Ready\" is defined as any of:\n * 1. The process emits data on **stderr** (JVM startup log line).\n * 2. The process emits data on **stdout** (initial protocol message).\n * 3. The maximum timeout elapses (best-effort resolve).\n *\n * The promise **rejects** if the process emits an `error` event or exits\n * before any of the above conditions are met.\n *\n * @param child - The spawned child process.\n * @param name - A human-readable label for log messages.\n * @param opts - Optional configuration.\n */\nexport function waitForProcessReady(\n child: ChildProcess,\n name: string,\n opts?: ProcessReadyOptions,\n): Promise {\n const timeoutMs = opts?.timeoutMs ?? DEFAULT_READY_TIMEOUT_MS;\n\n return new Promise((resolve, reject) => {\n let settled = false;\n\n const cleanup = () => {\n settled = true;\n child.stderr?.removeListener('data', onStderr);\n child.stdout?.removeListener('data', onStdout);\n child.removeListener('error', onError);\n child.removeListener('exit', onExit);\n clearTimeout(timer);\n };\n\n const onStderr = () => {\n if (settled) return;\n logger.debug(`${name}: ready (stderr output detected)`);\n cleanup();\n resolve();\n };\n\n const onStdout = () => {\n if (settled) return;\n logger.debug(`${name}: ready (stdout output detected)`);\n cleanup();\n resolve();\n };\n\n const onError = (error: Error) => {\n if (settled) return;\n cleanup();\n reject(new Error(`${name} failed to start: ${error.message}`));\n };\n\n const onExit = (code: number | null) => {\n if (settled) return;\n cleanup();\n reject(new Error(`${name} exited before becoming ready (code: ${code})`));\n };\n\n const timer = setTimeout(() => {\n if (settled) return;\n logger.warn(`${name}: readiness timeout (${timeoutMs} ms) \u2014 proceeding anyway`);\n cleanup();\n resolve(); // best-effort: let the caller attempt communication\n }, timeoutMs);\n\n child.stderr?.on('data', onStderr);\n child.stdout?.on('data', onStdout);\n child.on('error', onError);\n child.on('exit', onExit);\n\n // If the process was dead before we even attached listeners, reject now\n if (child.killed || child.exitCode !== null) {\n cleanup();\n reject(new Error(`${name} is not running (exitCode: ${child.exitCode})`));\n }\n });\n}\n", "/**\n * CodeQL Language Server manager for LSP communication\n * Manages the lifecycle and communication with the CodeQL language server process\n */\n\nimport { spawn, ChildProcess } from 'child_process';\nimport { EventEmitter } from 'events';\nimport { setTimeout, clearTimeout } from 'timers';\nimport { pathToFileURL } from 'url';\nimport { delimiter, join } from 'path';\nimport { logger } from '../utils/logger';\nimport { getPackageVersion } from '../utils/package-paths';\nimport { getProjectTmpDir } from '../utils/temp-dir';\nimport { getResolvedCodeQLDir } from './cli-executor';\nimport { waitForProcessReady } from '../utils/process-ready';\n\nexport interface LSPMessage {\n jsonrpc: '2.0';\n id?: number | string;\n method: string;\n params?: unknown;\n result?: unknown;\n error?: {\n code: number;\n message: string;\n data?: unknown;\n };\n}\n\nexport interface Diagnostic {\n range: {\n start: { line: number; character: number };\n end: { line: number; character: number };\n };\n severity: number; // 1=Error, 2=Warning, 3=Information, 4=Hint\n source?: string;\n message: string;\n code?: string | number;\n}\n\nexport interface PublishDiagnosticsParams {\n uri: string;\n diagnostics: Diagnostic[];\n}\n\nexport interface LanguageServerOptions {\n searchPath?: string;\n logdir?: string;\n loglevel?: 'ALL' | 'DEBUG' | 'ERROR' | 'INFO' | 'OFF' | 'TRACE' | 'WARN';\n synchronous?: boolean;\n verbosity?: 'errors' | 'progress' | 'progress+' | 'progress++' | 'progress+++' | 'warnings';\n}\n\n/**\n * Position in a text document (0-based line and character).\n */\nexport interface LSPPosition {\n character: number;\n line: number;\n}\n\n/**\n * A range in a text document.\n */\nexport interface LSPRange {\n end: LSPPosition;\n start: LSPPosition;\n}\n\n/**\n * A location in a resource (file URI + range).\n */\nexport interface LSPLocation {\n range: LSPRange;\n uri: string;\n}\n\n/**\n * Identifies a text document by its URI.\n */\nexport interface TextDocumentIdentifier {\n uri: string;\n}\n\n/**\n * A text document position (document + position within it).\n */\nexport interface TextDocumentPositionParams {\n position: LSPPosition;\n textDocument: TextDocumentIdentifier;\n}\n\n/**\n * A completion item returned by the language server.\n */\nexport interface CompletionItem {\n detail?: string;\n documentation?: string | { kind: string; value: string };\n insertText?: string;\n kind?: number;\n label: string;\n sortText?: string;\n}\n\nexport class CodeQLLanguageServer extends EventEmitter {\n private server: ChildProcess | null = null;\n private messageId = 1;\n private pendingResponses = new Map void; reject: (_error: Error) => void }>();\n private isInitialized = false;\n private currentWorkspaceUri: string | undefined;\n private messageBuffer = '';\n\n constructor(private _options: LanguageServerOptions = {}) {\n super();\n }\n\n async start(): Promise {\n if (this.server) {\n throw new Error('Language server is already running');\n }\n\n logger.info('Starting CodeQL Language Server...');\n\n const args = [\n 'execute', 'language-server',\n '--check-errors=ON_CHANGE'\n ];\n\n // Add optional arguments\n if (this._options.searchPath) {\n args.push(`--search-path=${this._options.searchPath}`);\n }\n if (this._options.logdir) {\n args.push(`--logdir=${this._options.logdir}`);\n }\n if (this._options.loglevel) {\n args.push(`--loglevel=${this._options.loglevel}`);\n }\n if (this._options.synchronous) {\n args.push('--synchronous');\n }\n if (this._options.verbosity) {\n args.push(`--verbosity=${this._options.verbosity}`);\n }\n\n // Build environment with CODEQL_PATH directory prepended to PATH\n // (mirrors the approach in cli-executor.ts getSafeEnvironment).\n const spawnEnv = { ...process.env };\n const codeqlDir = getResolvedCodeQLDir();\n if (codeqlDir && spawnEnv.PATH) {\n spawnEnv.PATH = `${codeqlDir}${delimiter}${spawnEnv.PATH}`;\n } else if (codeqlDir) {\n spawnEnv.PATH = codeqlDir;\n }\n\n this.server = spawn('codeql', args, {\n stdio: ['pipe', 'pipe', 'pipe'],\n env: spawnEnv\n });\n\n this.server.stderr?.on('data', (data) => {\n logger.debug('CodeQL LS stderr:', data.toString());\n });\n\n this.server.stdout?.on('data', (data) => {\n this.handleStdout(data);\n });\n\n this.server.on('error', (error) => {\n logger.error('CodeQL Language Server error:', error);\n this.emit('error', error);\n });\n\n this.server.on('exit', (code) => {\n logger.info('CodeQL Language Server exited with code:', code);\n this.server = null;\n this.isInitialized = false;\n this.emit('exit', code);\n });\n\n // Wait for the JVM to initialise (resolves on first stderr/stdout output)\n await waitForProcessReady(this.server, 'CodeQL Language Server');\n }\n\n private handleStdout(data: Buffer): void {\n this.messageBuffer += data.toString();\n \n let headerEnd = this.messageBuffer.indexOf('\\r\\n\\r\\n');\n while (headerEnd !== -1) {\n const header = this.messageBuffer.substring(0, headerEnd);\n const contentLengthMatch = header.match(/Content-Length: (\\d+)/);\n \n if (contentLengthMatch) {\n const contentLength = parseInt(contentLengthMatch[1]);\n const messageStart = headerEnd + 4;\n const messageEnd = messageStart + contentLength;\n \n if (this.messageBuffer.length >= messageEnd) {\n const messageContent = this.messageBuffer.substring(messageStart, messageEnd);\n this.messageBuffer = this.messageBuffer.substring(messageEnd);\n \n try {\n const message: LSPMessage = JSON.parse(messageContent);\n this.handleMessage(message);\n } catch (error) {\n logger.error('Failed to parse LSP message:', error, messageContent);\n }\n \n headerEnd = this.messageBuffer.indexOf('\\r\\n\\r\\n');\n } else {\n break;\n }\n } else {\n logger.error('Invalid LSP header:', header);\n this.messageBuffer = '';\n break;\n }\n }\n }\n\n private handleMessage(message: LSPMessage): void {\n logger.debug('Received LSP message:', message);\n\n // Handle responses to our requests\n if (message.id !== undefined && this.pendingResponses.has(Number(message.id))) {\n const pending = this.pendingResponses.get(Number(message.id))!;\n this.pendingResponses.delete(Number(message.id));\n \n if (message.error) {\n pending.reject(new Error(`LSP Error: ${message.error.message}`));\n } else {\n pending.resolve(message.result);\n }\n return;\n }\n\n // Handle notifications from server\n if (message.method === 'textDocument/publishDiagnostics') {\n this.emit('diagnostics', message.params as PublishDiagnosticsParams);\n }\n }\n\n private sendMessage(message: LSPMessage): void {\n if (!this.server?.stdin) {\n throw new Error('Language server is not running');\n }\n\n const messageStr = JSON.stringify(message);\n const contentLength = Buffer.byteLength(messageStr, 'utf8');\n const header = `Content-Length: ${contentLength}\\r\\n\\r\\n`;\n const fullMessage = header + messageStr;\n\n logger.debug('Sending LSP message:', fullMessage);\n this.server.stdin.write(fullMessage);\n }\n\n private sendRequest(method: string, params?: unknown): Promise {\n const id = this.messageId++;\n const message: LSPMessage = {\n jsonrpc: '2.0',\n id,\n method,\n params\n };\n\n return new Promise((resolve, reject) => {\n // Wrap resolve/reject to clear the timer when the promise settles.\n const timer = setTimeout(() => {\n if (this.pendingResponses.has(id)) {\n this.pendingResponses.delete(id);\n reject(new Error(`LSP request timeout for method: ${method}`));\n }\n }, 60_000); // 60 second timeout (Windows CI cold JVM can exceed 30s)\n\n this.pendingResponses.set(id, {\n reject: (err: Error) => { clearTimeout(timer); reject(err); },\n resolve: (val: unknown) => { clearTimeout(timer); resolve(val); },\n });\n this.sendMessage(message);\n });\n }\n\n private sendNotification(method: string, params?: unknown): void {\n const message: LSPMessage = {\n jsonrpc: '2.0',\n method,\n params\n };\n this.sendMessage(message);\n }\n\n /**\n * Initialize the language server with an optional workspace URI.\n *\n * If the server is already initialized with a different workspace, a\n * `workspace/didChangeWorkspaceFolders` notification is sent to update\n * the workspace context instead of requiring a full restart.\n */\n async initialize(workspaceUri?: string): Promise {\n if (this.isInitialized) {\n // If workspace changed, notify the server\n if (workspaceUri && workspaceUri !== this.currentWorkspaceUri) {\n await this.updateWorkspace(workspaceUri);\n }\n return;\n }\n\n logger.info('Initializing CodeQL Language Server...');\n\n const initParams = {\n processId: process.pid,\n clientInfo: {\n name: 'codeql-development-mcp-server',\n version: getPackageVersion()\n },\n capabilities: {\n textDocument: {\n completion: { completionItem: { snippetSupport: false } },\n definition: {},\n publishDiagnostics: {},\n references: {},\n synchronization: {\n didClose: true,\n didChange: true,\n didOpen: true,\n },\n },\n workspace: {\n workspaceFolders: true,\n },\n }\n };\n\n if (workspaceUri) {\n (initParams as unknown as { workspaceFolders: unknown[] }).workspaceFolders = [{\n uri: workspaceUri,\n name: 'codeql-workspace'\n }];\n }\n\n await this.sendRequest('initialize', initParams);\n this.sendNotification('initialized', {});\n\n this.currentWorkspaceUri = workspaceUri;\n this.isInitialized = true;\n logger.info('CodeQL Language Server initialized successfully');\n }\n\n /**\n * Update the workspace folders on a running, initialized server.\n */\n private async updateWorkspace(newUri: string): Promise {\n logger.info(`Updating workspace from ${this.currentWorkspaceUri} to ${newUri}`);\n\n const removed = this.currentWorkspaceUri\n ? [{ uri: this.currentWorkspaceUri, name: 'codeql-workspace' }]\n : [];\n\n this.sendNotification('workspace/didChangeWorkspaceFolders', {\n event: {\n added: [{ uri: newUri, name: 'codeql-workspace' }],\n removed,\n },\n });\n\n this.currentWorkspaceUri = newUri;\n }\n\n /**\n * Get the current workspace URI.\n */\n getWorkspaceUri(): string | undefined {\n return this.currentWorkspaceUri;\n }\n\n async evaluateQL(qlCode: string, uri?: string): Promise {\n if (!this.isInitialized) {\n throw new Error('Language server is not initialized');\n }\n\n // Default to a project-local virtual URI rather than /tmp\n const documentUri = uri || pathToFileURL(join(getProjectTmpDir('lsp-eval'), 'eval.ql')).href;\n\n return new Promise((resolve, reject) => {\n let diagnosticsReceived = false;\n const timeout = setTimeout(() => {\n if (!diagnosticsReceived) {\n this.removeListener('diagnostics', diagnosticsHandler);\n reject(new Error('Timeout waiting for diagnostics'));\n }\n }, 90_000); // 90s \u2014 first call triggers JVM start + compilation; Windows CI is slow\n\n // Listen for diagnostics\n const diagnosticsHandler = (params: PublishDiagnosticsParams) => {\n if (params.uri === documentUri) {\n diagnosticsReceived = true;\n clearTimeout(timeout);\n this.removeListener('diagnostics', diagnosticsHandler);\n\n // Close the document\n this.sendNotification('textDocument/didClose', {\n textDocument: { uri: documentUri }\n });\n\n resolve(params.diagnostics);\n }\n };\n\n this.on('diagnostics', diagnosticsHandler);\n\n // Open the document with the QL code\n this.sendNotification('textDocument/didOpen', {\n textDocument: {\n uri: documentUri,\n languageId: 'ql',\n version: 1,\n text: qlCode\n }\n });\n });\n }\n\n // ---- LSP feature methods (issue #1) ----\n\n /**\n * Get code completions at a position in a document.\n */\n async getCompletions(params: TextDocumentPositionParams): Promise {\n if (!this.isInitialized) {\n throw new Error('Language server is not initialized');\n }\n if (!this.isRunning()) {\n throw new Error('Language server process is not running');\n }\n const result = await this.sendRequest('textDocument/completion', params);\n // The result may be a CompletionList or CompletionItem[]\n if (result && typeof result === 'object' && 'items' in (result as object)) {\n return (result as { items: CompletionItem[] }).items;\n }\n return (result as CompletionItem[]) || [];\n }\n\n /**\n * Find the definition(s) of a symbol at a position.\n */\n async getDefinition(params: TextDocumentPositionParams): Promise {\n if (!this.isInitialized) {\n throw new Error('Language server is not initialized');\n }\n if (!this.isRunning()) {\n throw new Error('Language server process is not running');\n }\n const result = await this.sendRequest('textDocument/definition', params);\n return this.normalizeLocations(result);\n }\n\n /**\n * Find all references to a symbol at a position.\n */\n async getReferences(params: TextDocumentPositionParams & { context?: { includeDeclaration: boolean } }): Promise {\n if (!this.isInitialized) {\n throw new Error('Language server is not initialized');\n }\n if (!this.isRunning()) {\n throw new Error('Language server process is not running');\n }\n const result = await this.sendRequest('textDocument/references', {\n ...params,\n context: params.context ?? { includeDeclaration: true },\n });\n return this.normalizeLocations(result);\n }\n\n /**\n * Open a text document in the language server.\n * The document must be opened before requesting completions, definitions, etc.\n */\n openDocument(uri: string, text: string, languageId = 'ql', version = 1): void {\n if (!this.isInitialized) {\n throw new Error('Language server is not initialized');\n }\n this.sendNotification('textDocument/didOpen', {\n textDocument: { uri, languageId, version, text },\n });\n }\n\n /**\n * Close a text document in the language server.\n */\n closeDocument(uri: string): void {\n if (!this.isInitialized) {\n throw new Error('Language server is not initialized');\n }\n this.sendNotification('textDocument/didClose', {\n textDocument: { uri },\n });\n }\n\n /**\n * Normalize a definition/references/implementation result to Location[].\n * The LSP spec allows Location | Location[] | LocationLink[].\n */\n private normalizeLocations(result: unknown): LSPLocation[] {\n if (!result) return [];\n if (Array.isArray(result)) {\n return result.map((item) => {\n // LocationLink has targetUri/targetRange\n if ('targetUri' in item) {\n return { uri: item.targetUri, range: item.targetRange } as LSPLocation;\n }\n return item as LSPLocation;\n });\n }\n // Single Location\n if (typeof result === 'object' && 'uri' in (result as object)) {\n return [result as LSPLocation];\n }\n return [];\n }\n\n async shutdown(): Promise {\n if (!this.server) {\n return;\n }\n\n logger.info('Shutting down CodeQL Language Server...');\n\n try {\n await this.sendRequest('shutdown', {});\n if (this.server) {\n this.sendNotification('exit', {});\n }\n } catch (error) {\n logger.warn('Error during graceful shutdown:', error);\n }\n\n // Force kill if needed\n await new Promise((resolve) => {\n const timer = setTimeout(() => {\n if (this.server) {\n this.server.kill('SIGTERM');\n }\n resolve();\n }, 1000);\n\n if (this.server) {\n this.server.once('exit', () => {\n clearTimeout(timer);\n this.server = null;\n resolve();\n });\n } else {\n clearTimeout(timer);\n resolve();\n }\n });\n\n this.isInitialized = false;\n }\n\n isRunning(): boolean {\n return this.server !== null && !this.server.killed;\n }\n}", "/**\n * CodeQL Query Server (query-server2) client.\n *\n * Manages a long-lived `codeql execute query-server2` process that evaluates\n * queries using a custom JSON-RPC protocol over stdio. Reusing the server\n * avoids repeated JVM startup for each query evaluation.\n *\n * Protocol: The query-server2 uses JSON-RPC with Content-Length headers\n * (same framing as LSP) over stdin/stdout.\n */\n\nimport { ChildProcess, spawn } from 'child_process';\nimport { delimiter } from 'path';\nimport { EventEmitter } from 'events';\nimport { clearTimeout, setTimeout } from 'timers';\nimport { buildQueryServerArgs, QueryServerConfig } from './server-config';\nimport { getResolvedCodeQLDir } from './cli-executor';\nimport { logger } from '../utils/logger';\nimport { waitForProcessReady } from '../utils/process-ready';\n\n/**\n * A pending request awaiting a response from the query server.\n */\ninterface PendingRequest {\n reject: (_error: Error) => void;\n resolve: (_value: unknown) => void;\n}\n\n/**\n * Client for the CodeQL query-server2 process.\n *\n * Spawns `codeql execute query-server2` and communicates over stdin/stdout\n * using JSON-RPC with Content-Length framing.\n */\nexport class CodeQLQueryServer extends EventEmitter {\n private messageBuffer = '';\n private messageId = 1;\n private pendingRequests = new Map();\n private process: ChildProcess | null = null;\n private readonly config: QueryServerConfig;\n\n constructor(config: QueryServerConfig) {\n super();\n this.config = config;\n }\n\n /**\n * Start the query-server2 process.\n */\n async start(): Promise {\n if (this.process) {\n throw new Error('Query server is already running');\n }\n\n logger.info('Starting CodeQL Query Server (query-server2)...');\n\n const args = buildQueryServerArgs(this.config);\n\n // Build environment with CODEQL_PATH directory prepended to PATH\n const spawnEnv = { ...process.env };\n const codeqlDir = getResolvedCodeQLDir();\n if (codeqlDir && spawnEnv.PATH) {\n spawnEnv.PATH = `${codeqlDir}${delimiter}${spawnEnv.PATH}`;\n } else if (codeqlDir) {\n spawnEnv.PATH = codeqlDir;\n }\n\n this.process = spawn('codeql', args, {\n stdio: ['pipe', 'pipe', 'pipe'],\n env: spawnEnv,\n });\n\n this.process.stderr?.on('data', (data: Buffer) => {\n logger.debug('QueryServer2 stderr:', data.toString());\n });\n\n this.process.stdout?.on('data', (data: Buffer) => {\n this.handleStdout(data);\n });\n\n this.process.on('error', (error: Error) => {\n logger.error('Query server process error:', error);\n this.emit('error', error);\n });\n\n this.process.on('exit', (code: number | null) => {\n logger.info(`Query server exited with code: ${code}`);\n this.rejectAllPending(new Error(`Query server exited with code: ${code}`));\n this.process = null;\n this.emit('exit', code);\n });\n\n // Wait for the JVM to initialise (resolves on first stderr/stdout output)\n await waitForProcessReady(this.process, 'CodeQL Query Server');\n logger.info('CodeQL Query Server started');\n }\n\n /**\n * Send a request to the query server and await the response.\n *\n * @param method - The JSON-RPC method name.\n * @param params - The method parameters.\n * @param timeoutMs - Request timeout in milliseconds (default: 300000 = 5 min).\n * @returns The result from the server.\n */\n sendRequest(method: string, params?: unknown, timeoutMs = 300_000): Promise {\n const id = this.messageId++;\n const message = {\n id,\n jsonrpc: '2.0' as const,\n method,\n params,\n };\n\n return new Promise((resolve, reject) => {\n this.pendingRequests.set(id, { reject, resolve });\n\n try {\n this.sendRaw(message);\n } catch (error) {\n // Clean up immediately \u2014 sendRaw() failed so no response will arrive.\n this.pendingRequests.delete(id);\n reject(error instanceof Error ? error : new Error(String(error)));\n return;\n }\n\n const timer = setTimeout(() => {\n if (this.pendingRequests.has(id)) {\n this.pendingRequests.delete(id);\n reject(new Error(`Query server request timeout for method: ${method}`));\n }\n }, timeoutMs);\n\n // Clear the timeout when the promise settles\n const originalResolve = resolve;\n const originalReject = reject;\n const wrapped = {\n reject: (err: Error) => { clearTimeout(timer); originalReject(err); },\n resolve: (val: unknown) => { clearTimeout(timer); originalResolve(val); },\n };\n this.pendingRequests.set(id, wrapped);\n });\n }\n\n /**\n * Gracefully shut down the query server.\n */\n async shutdown(): Promise {\n if (!this.process) {\n return;\n }\n\n logger.info('Shutting down CodeQL Query Server...');\n\n try {\n await this.sendRequest('shutdown', {}, 5000);\n } catch (error) {\n logger.warn('Error during query server graceful shutdown:', error);\n }\n\n // Force kill if process lingers\n await new Promise((resolve) => {\n const timer = setTimeout(() => {\n if (this.process) {\n this.process.kill('SIGTERM');\n this.process = null;\n }\n resolve();\n }, 2000);\n\n if (this.process) {\n this.process.once('exit', () => {\n clearTimeout(timer);\n this.process = null;\n resolve();\n });\n } else {\n clearTimeout(timer);\n resolve();\n }\n });\n }\n\n /**\n * Whether the query server process is running.\n */\n isRunning(): boolean {\n return this.process !== null && !this.process.killed;\n }\n\n // ---- private helpers ----\n\n private handleStdout(data: Buffer): void {\n this.messageBuffer += data.toString();\n\n let headerEnd = this.messageBuffer.indexOf('\\r\\n\\r\\n');\n while (headerEnd !== -1) {\n const header = this.messageBuffer.substring(0, headerEnd);\n const contentLengthMatch = header.match(/Content-Length: (\\d+)/);\n\n if (contentLengthMatch) {\n const contentLength = parseInt(contentLengthMatch[1]);\n const messageStart = headerEnd + 4;\n const messageEnd = messageStart + contentLength;\n\n if (this.messageBuffer.length >= messageEnd) {\n const messageContent = this.messageBuffer.substring(messageStart, messageEnd);\n this.messageBuffer = this.messageBuffer.substring(messageEnd);\n\n try {\n const message = JSON.parse(messageContent);\n this.handleMessage(message);\n } catch (error) {\n logger.error('Failed to parse query server message:', error);\n }\n\n headerEnd = this.messageBuffer.indexOf('\\r\\n\\r\\n');\n } else {\n break;\n }\n } else {\n logger.error('Invalid query server header:', header);\n this.messageBuffer = '';\n break;\n }\n }\n }\n\n private handleMessage(message: { error?: { message: string }; id?: number; method?: string; params?: unknown; result?: unknown }): void {\n logger.debug('QueryServer2 message:', message);\n\n // Handle responses\n if (message.id !== undefined && this.pendingRequests.has(Number(message.id))) {\n const pending = this.pendingRequests.get(Number(message.id))!;\n this.pendingRequests.delete(Number(message.id));\n\n if (message.error) {\n pending.reject(new Error(`Query server error: ${message.error.message}`));\n } else {\n pending.resolve(message.result);\n }\n return;\n }\n\n // Handle notifications (progress, etc.)\n if (message.method) {\n this.emit('notification', { method: message.method, params: message.params });\n }\n }\n\n private rejectAllPending(error: Error): void {\n for (const [id, pending] of this.pendingRequests) {\n pending.reject(error);\n this.pendingRequests.delete(id);\n }\n }\n\n private sendRaw(message: object): void {\n if (!this.process?.stdin) {\n throw new Error('Query server is not running');\n }\n\n const body = JSON.stringify(message);\n const contentLength = Buffer.byteLength(body, 'utf8');\n const frame = `Content-Length: ${contentLength}\\r\\n\\r\\n${body}`;\n this.process.stdin.write(frame);\n }\n}\n", "/**\n * CodeQL CLI Server client.\n *\n * Manages a long-lived `codeql execute cli-server` process that executes CLI\n * commands without repeated JVM startup overhead. Commands are serialized as\n * JSON arrays followed by a NUL byte, and responses are NUL-terminated JSON.\n *\n * Inspired by the `CodeQLCliServer` class in github/vscode-codeql.\n */\n\nimport { ChildProcess, spawn } from 'child_process';\nimport { delimiter } from 'path';\nimport { EventEmitter } from 'events';\nimport { clearTimeout, setTimeout } from 'timers';\nimport { buildCLIServerArgs, CLIServerConfig } from './server-config';\nimport { getResolvedCodeQLDir } from './cli-executor';\nimport { logger } from '../utils/logger';\nimport { waitForProcessReady } from '../utils/process-ready';\n\n/**\n * A queued command waiting to be sent to the CLI server.\n */\ninterface QueuedCommand {\n args: string[];\n reject: (_error: Error) => void;\n resolve: (_value: string) => void;\n}\n\n/**\n * Client for the CodeQL CLI Server process.\n *\n * The cli-server uses a simple NUL-delimited protocol:\n * - **Request**: JSON array of command arguments, followed by a NUL byte.\n * - **Response**: command stdout, terminated by a NUL byte on stdout.\n * stderr is forwarded as-is.\n */\nexport class CodeQLCLIServer extends EventEmitter {\n private commandInProgress = false;\n private commandQueue: Array<() => void> = [];\n private readonly config: CLIServerConfig;\n private currentReject: ((_error: Error) => void) | null = null;\n private currentResolve: ((_value: string) => void) | null = null;\n private nullBuffer = Buffer.alloc(1);\n private process: ChildProcess | null = null;\n private stdoutBuffer = '';\n\n constructor(config: CLIServerConfig) {\n super();\n this.config = config;\n }\n\n /**\n * Start the cli-server process.\n */\n async start(): Promise {\n if (this.process) {\n throw new Error('CLI server is already running');\n }\n\n logger.info('Starting CodeQL CLI Server...');\n\n const args = buildCLIServerArgs(this.config);\n\n const spawnEnv = { ...process.env };\n const codeqlDir = getResolvedCodeQLDir();\n if (codeqlDir && spawnEnv.PATH) {\n spawnEnv.PATH = `${codeqlDir}${delimiter}${spawnEnv.PATH}`;\n } else if (codeqlDir) {\n spawnEnv.PATH = codeqlDir;\n }\n\n this.process = spawn('codeql', args, {\n stdio: ['pipe', 'pipe', 'pipe'],\n env: spawnEnv,\n });\n\n this.process.stdout?.on('data', (data: Buffer) => {\n this.handleStdout(data);\n });\n\n this.process.stderr?.on('data', (data: Buffer) => {\n logger.debug('CLIServer stderr:', data.toString());\n });\n\n this.process.on('error', (error: Error) => {\n logger.error('CLI server process error:', error);\n if (this.currentReject) {\n this.currentReject(error);\n this.currentReject = null;\n this.currentResolve = null;\n }\n this.emit('error', error);\n });\n\n this.process.on('exit', (code: number | null) => {\n logger.info(`CLI server exited with code: ${code}`);\n if (this.currentReject) {\n this.currentReject(new Error(`CLI server exited unexpectedly with code: ${code}`));\n this.currentReject = null;\n this.currentResolve = null;\n }\n this.process = null;\n this.emit('exit', code);\n });\n\n // Wait for the JVM to initialise (resolves on first stderr/stdout output)\n await waitForProcessReady(this.process, 'CodeQL CLI Server');\n logger.info('CodeQL CLI Server started');\n }\n\n /**\n * Run a CodeQL CLI command through the persistent server.\n *\n * Commands are serialized and queued; only one command runs at a time.\n *\n * @param args - The full command arguments (e.g. `['resolve', 'qlpacks']`).\n * @returns The stdout output from the command.\n */\n runCommand(args: string[]): Promise {\n return new Promise((resolve, reject) => {\n const execute = () => {\n this.executeCommand({ args, reject, resolve });\n };\n\n if (this.commandInProgress) {\n this.commandQueue.push(execute);\n } else {\n execute();\n }\n });\n }\n\n /**\n * Gracefully shut down the CLI server.\n */\n async shutdown(): Promise {\n if (!this.process) {\n return;\n }\n\n logger.info('Shutting down CodeQL CLI Server...');\n\n try {\n // Send shutdown command\n this.process.stdin?.write(JSON.stringify(['shutdown']), 'utf8');\n this.process.stdin?.write(this.nullBuffer);\n } catch (error) {\n logger.warn('Error during CLI server shutdown request:', error);\n }\n\n // Give it a moment, then force kill\n await new Promise((resolve) => {\n const timer = setTimeout(() => {\n if (this.process) {\n this.process.kill('SIGTERM');\n this.process = null;\n }\n resolve();\n }, 2000);\n\n if (this.process) {\n this.process.once('exit', () => {\n clearTimeout(timer);\n this.process = null;\n resolve();\n });\n } else {\n clearTimeout(timer);\n resolve();\n }\n });\n\n this.commandInProgress = false;\n this.commandQueue = [];\n logger.info('CodeQL CLI Server stopped');\n }\n\n /**\n * Whether the CLI server process is running.\n */\n isRunning(): boolean {\n return this.process !== null && !this.process.killed;\n }\n\n // ---- private helpers ----\n\n private executeCommand(cmd: QueuedCommand): void {\n if (!this.process?.stdin) {\n cmd.reject(new Error('CLI server is not running'));\n return;\n }\n\n this.commandInProgress = true;\n this.currentResolve = cmd.resolve;\n this.currentReject = cmd.reject;\n\n try {\n this.process.stdin.write(JSON.stringify(cmd.args), 'utf8');\n this.process.stdin.write(this.nullBuffer);\n } catch (error) {\n this.commandInProgress = false;\n this.currentResolve = null;\n this.currentReject = null;\n cmd.reject(error instanceof Error ? error : new Error(String(error)));\n this.runNext();\n }\n }\n\n private handleStdout(data: Buffer): void {\n this.stdoutBuffer += data.toString();\n\n // Process all NUL-delimited responses in the buffer\n let nulIndex = this.stdoutBuffer.indexOf('\\0');\n while (nulIndex !== -1) {\n const result = this.stdoutBuffer.substring(0, nulIndex);\n this.stdoutBuffer = this.stdoutBuffer.substring(nulIndex + 1);\n\n if (this.currentResolve) {\n this.currentResolve(result);\n this.currentResolve = null;\n this.currentReject = null;\n }\n\n this.commandInProgress = false;\n this.runNext();\n\n nulIndex = this.stdoutBuffer.indexOf('\\0');\n }\n }\n\n private runNext(): void {\n const next = this.commandQueue.shift();\n if (next) {\n next();\n }\n }\n}\n", "/**\n * CodeQL Server Manager\n *\n * Manages the lifecycle of CodeQL background server processes:\n * - language-server (LSP-based QL validation)\n * - query-server2 (query evaluation)\n * - cli-server (JVM reuse for CLI commands)\n *\n * Servers are keyed by a hash of their configuration. When a caller requests\n * a server with a different configuration, the old server is shut down and a\n * new one is started. Session-specific cache directories provide isolation.\n */\n\nimport { mkdirSync } from 'fs';\nimport { join } from 'path';\nimport { randomUUID } from 'crypto';\nimport {\n CLIServerConfig,\n CodeQLServerType,\n computeConfigHash,\n LanguageServerConfig,\n QueryServerConfig,\n ServerConfig,\n} from './server-config';\nimport { CodeQLLanguageServer } from './language-server';\nimport { CodeQLQueryServer } from './query-server';\nimport { CodeQLCLIServer } from './cli-server';\nimport { getProjectTmpDir } from '../utils/temp-dir';\nimport { logger } from '../utils/logger';\n\n/**\n * Entry in the managed servers map.\n */\ninterface ManagedServer {\n configHash: string;\n server: CodeQLCLIServer | CodeQLLanguageServer | CodeQLQueryServer;\n sessionId: string;\n type: CodeQLServerType;\n}\n\n/**\n * Options for creating a session-specific cache layout.\n */\nexport interface SessionCacheOptions {\n /** Override the session ID (defaults to a random UUID). */\n sessionId?: string;\n}\n\n/**\n * Manages CodeQL background server processes with config-aware caching.\n *\n * Callers should use `getLanguageServer()`, `getQueryServer()`, or\n * `getCLIServer()` to obtain a running server. If the requested\n * configuration differs from the currently running server of that type, the\n * old server is stopped and replaced.\n */\nexport class CodeQLServerManager {\n /** Keyed by `CodeQLServerType` \u2014 at most one per type at a time. */\n private servers = new Map();\n\n /** In-flight `getOrRestart` promises, keyed by server type, to serialize concurrent calls. */\n private pendingStarts = new Map>();\n\n /** The session ID used for cache isolation. */\n private sessionId: string;\n\n /** Root directory for session-specific caches. */\n private sessionCacheDir: string;\n\n constructor(options?: SessionCacheOptions) {\n this.sessionId = options?.sessionId ?? randomUUID();\n this.sessionCacheDir = join(\n getProjectTmpDir('codeql-cache'),\n this.sessionId,\n );\n // Pre-create the cache directory tree\n for (const subdir of ['compilation-cache', 'logs', 'query-cache']) {\n mkdirSync(join(this.sessionCacheDir, subdir), { recursive: true });\n }\n logger.info(`CodeQLServerManager initialized (session: ${this.sessionId})`);\n }\n\n // ---- Public API ----\n\n /**\n * Get the current session ID.\n */\n getSessionId(): string {\n return this.sessionId;\n }\n\n /**\n * Get the session-specific cache directory.\n */\n getCacheDir(): string {\n return this.sessionCacheDir;\n }\n\n /**\n * Return the session-specific log directory.\n */\n getLogDir(): string {\n return join(this.sessionCacheDir, 'logs');\n }\n\n /**\n * Get or create a Language Server with the given configuration.\n *\n * If a language server is already running with the same config it is reused.\n * If the config has changed the old server is shut down first.\n */\n async getLanguageServer(config: LanguageServerConfig): Promise {\n const enriched = this.enrichConfig(config) as LanguageServerConfig;\n return this.getOrRestart('language', enriched, () => {\n // Convert LanguageServerConfig to the LanguageServerOptions the existing class expects\n return new CodeQLLanguageServer({\n loglevel: enriched.loglevel,\n logdir: enriched.logdir,\n searchPath: enriched.searchPath,\n synchronous: enriched.synchronous,\n verbosity: enriched.verbosity,\n });\n }) as Promise;\n }\n\n /**\n * Get or create a Query Server with the given configuration.\n */\n async getQueryServer(config: QueryServerConfig): Promise {\n const enriched = this.enrichConfig(config) as QueryServerConfig;\n return this.getOrRestart('query', enriched, () => {\n return new CodeQLQueryServer(enriched);\n }) as Promise;\n }\n\n /**\n * Get or create a CLI Server with the given configuration.\n */\n async getCLIServer(config: CLIServerConfig): Promise {\n const enriched = this.enrichConfig(config) as CLIServerConfig;\n return this.getOrRestart('cli', enriched, () => {\n return new CodeQLCLIServer(enriched);\n }) as Promise;\n }\n\n /**\n * Shut down a specific server type.\n */\n async shutdownServer(type: CodeQLServerType): Promise {\n const managed = this.servers.get(type);\n if (!managed) return;\n\n logger.info(`Shutting down ${type} server (session: ${managed.sessionId})`);\n await this.stopServer(managed);\n this.servers.delete(type);\n }\n\n /**\n * Shut down all managed servers.\n */\n async shutdownAll(): Promise {\n logger.info(`Shutting down all servers for session: ${this.sessionId}`);\n const shutdownPromises = Array.from(this.servers.entries()).map(\n async ([type, managed]) => {\n try {\n await this.stopServer(managed);\n } catch (error) {\n logger.error(`Error shutting down ${type} server:`, error);\n }\n },\n );\n await Promise.all(shutdownPromises);\n this.servers.clear();\n logger.info('All servers shut down');\n }\n\n /**\n * Check whether a server of the given type is currently running.\n */\n isRunning(type: CodeQLServerType): boolean {\n const managed = this.servers.get(type);\n if (!managed) return false;\n return managed.server.isRunning();\n }\n\n /**\n * Get status information for all managed servers.\n */\n getStatus(): Record {\n const status: Record = {\n cli: null,\n language: null,\n query: null,\n };\n for (const [type, managed] of this.servers) {\n status[type] = {\n configHash: managed.configHash,\n running: managed.server.isRunning(),\n sessionId: managed.sessionId,\n };\n }\n return status as Record;\n }\n\n // ---- Private helpers ----\n\n /**\n * Eagerly start the language server so the JVM is warm when the first\n * LSP tool call arrives. Uses the default configuration that\n * `lsp-handlers.ts` / `lsp-diagnostics.ts` would create on the first\n * `getLanguageServer()` call. The server is stored in the managed-servers\n * map and reused by subsequent tool invocations.\n *\n * This is fire-and-forget: errors are logged but do not prevent the MCP\n * server from starting.\n */\n async warmUpLanguageServer(): Promise {\n try {\n // Lazy-import to avoid circular dependency at module level\n const { packageRootDir } = await import('../utils/package-paths');\n const { resolve } = await import('path');\n\n const config: LanguageServerConfig = {\n checkErrors: 'ON_CHANGE',\n loglevel: 'WARN',\n searchPath: resolve(packageRootDir, 'ql'),\n };\n logger.info('Warming up language server (background JVM start)...');\n await this.getLanguageServer(config);\n logger.info('Language server warm-up complete');\n } catch (error) {\n logger.warn('Language server warm-up failed (will retry on first tool call):', error);\n }\n }\n\n /**\n * Eagerly start the CLI server so the JVM is warm when the first\n * `executeCodeQLCommand()` call routes through it.\n *\n * The CLI server uses only session-scoped `commonCaches` and `logdir`,\n * both injected by `enrichConfig()`. Passing an empty config is\n * intentional \u2014 it matches what `executeCodeQLCommand()` will request.\n *\n * Fire-and-forget: errors are logged but do not block startup.\n */\n async warmUpCLIServer(): Promise {\n try {\n logger.info('Warming up CLI server (background JVM start)...');\n await this.getCLIServer({});\n logger.info('CLI server warm-up complete');\n } catch (error) {\n logger.warn('CLI server warm-up failed (will retry on first tool call):', error);\n }\n }\n\n /**\n * Enrich a config with session-specific defaults for commonCaches and logdir.\n */\n private enrichConfig(config: T): T {\n return {\n ...config,\n commonCaches: config.commonCaches ?? this.sessionCacheDir,\n logdir: config.logdir ?? this.getLogDir(),\n };\n }\n\n /**\n * Get an existing server if its config matches, otherwise stop the old\n * one and start a new server.\n *\n * Concurrent calls for the same server type are serialized via\n * `pendingStarts` to avoid spawning duplicate server processes.\n */\n private async getOrRestart(\n type: CodeQLServerType,\n config: ServerConfig,\n factory: () => CodeQLCLIServer | CodeQLLanguageServer | CodeQLQueryServer,\n ): Promise {\n // If another call is already starting a server of this type, wait for it\n // to settle (success or failure) and then re-check whether the result is\n // still usable.\n const inflight = this.pendingStarts.get(type);\n if (inflight) {\n try { await inflight; } catch { /* swallow \u2014 original caller handles the rejection */ }\n }\n\n const work = this.doGetOrRestart(type, config, factory);\n this.pendingStarts.set(type, work);\n try {\n return await work;\n } finally {\n // Ensure `work` has settled before removing the pendingStarts entry so\n // that concurrent callers waiting on the same promise see a consistent\n // map state. The try/catch avoids re-throwing a rejection that the\n // outer `try` block already handles.\n try { await work; } catch { /* already handled */ }\n if (this.pendingStarts.get(type) === work) {\n this.pendingStarts.delete(type);\n }\n }\n }\n\n /**\n * Core logic for getOrRestart, separated to allow serialization.\n */\n private async doGetOrRestart(\n type: CodeQLServerType,\n config: ServerConfig,\n factory: () => CodeQLCLIServer | CodeQLLanguageServer | CodeQLQueryServer,\n ): Promise {\n const hash = computeConfigHash(type, config);\n const existing = this.servers.get(type);\n\n // Reuse if config matches and server is still running\n if (existing && existing.configHash === hash && existing.server.isRunning()) {\n logger.debug(`Reusing existing ${type} server (hash: ${hash.substring(0, 8)})`);\n return existing.server;\n }\n\n // Config changed or server died \u2014 stop the old one\n if (existing) {\n logger.info(`${type} server config changed or dead, restarting...`);\n await this.stopServer(existing);\n this.servers.delete(type);\n }\n\n // Start a new server\n const server = factory();\n await server.start();\n\n this.servers.set(type, {\n configHash: hash,\n server,\n sessionId: this.sessionId,\n type,\n });\n\n logger.info(`${type} server started (hash: ${hash.substring(0, 8)})`);\n return server;\n }\n\n /**\n * Stop a managed server, ignoring errors.\n */\n private async stopServer(managed: ManagedServer): Promise {\n try {\n await managed.server.shutdown();\n } catch (error) {\n logger.warn(`Error stopping ${managed.type} server:`, error);\n // Best-effort \u2014 don't propagate\n }\n }\n}\n\n/**\n * Global server manager singleton.\n *\n * Initialized lazily by `getServerManager()`. The MCP server entry point\n * should call `initServerManager()` at startup and `shutdownServerManager()`\n * at graceful shutdown.\n */\nlet globalServerManager: CodeQLServerManager | null = null;\n\n/**\n * Initialize the global server manager (idempotent).\n */\nexport function initServerManager(options?: SessionCacheOptions): CodeQLServerManager {\n if (!globalServerManager) {\n globalServerManager = new CodeQLServerManager(options);\n }\n return globalServerManager;\n}\n\n/**\n * Get the global server manager, creating it if needed.\n */\nexport function getServerManager(): CodeQLServerManager {\n if (!globalServerManager) {\n globalServerManager = new CodeQLServerManager();\n }\n return globalServerManager;\n}\n\n/**\n * Shut down the global server manager and all its servers.\n */\nexport async function shutdownServerManager(): Promise {\n if (globalServerManager) {\n await globalServerManager.shutdownAll();\n globalServerManager = null;\n }\n}\n\n/**\n * Reset the global server manager (for testing only).\n */\nexport function resetServerManager(): void {\n globalServerManager = null;\n}\n", "/**\n * Generic CLI command execution utilities for CodeQL and QLT commands\n */\n\nimport { execFile } from 'child_process';\nimport { existsSync } from 'fs';\nimport { basename, delimiter, dirname, isAbsolute } from 'path';\nimport { promisify } from 'util';\nimport { logger } from '../utils/logger';\n\nconst execFileAsync = promisify(execFile);\n\nexport interface CLIExecutionResult {\n stdout: string;\n stderr: string;\n success: boolean;\n error?: string;\n exitCode?: number;\n}\n\nexport interface CLIExecutionOptions {\n command: string;\n args: string[];\n cwd?: string;\n timeout?: number;\n env?: Record;\n}\n\n// Whitelist of allowed commands to prevent arbitrary command execution\nconst ALLOWED_COMMANDS = new Set([\n 'codeql',\n 'git',\n 'node',\n 'npm',\n 'qlt',\n 'which'\n]);\n\n// Additional commands allowed in test environments\nlet testCommands: Set | null = null;\n\n// Whitelist of safe environment variables to pass to child processes\n// This prevents potentially malicious environment variables from being passed through\nconst SAFE_ENV_VARS = [\n 'HOME', // User home directory\n 'LANG', // Locale setting\n 'LC_ALL', // Locale setting\n 'LC_CTYPE', // Locale setting\n 'PATH', // Required to find executables\n 'SHELL', // User's shell (Unix)\n 'TEMP', // Temporary directory (Windows)\n 'TERM', // Terminal type (Unix)\n 'TMP', // Temporary directory (Windows)\n 'TMPDIR', // Temporary directory (Unix)\n 'USER', // Current user (Unix)\n 'USERNAME', // Current user (Windows)\n] as const;\n\n// Whitelist of safe environment variable prefixes\n// These are needed for CodeQL and Node.js functionality\nconst SAFE_ENV_PREFIXES = [\n 'CODEQL_', // CodeQL-specific variables\n 'NODE_', // Node.js-specific variables (for npm, etc.)\n] as const;\n\n// Pattern for dangerous control characters in CLI arguments\n// Rejected characters:\n// \\x01-\\x08: SOH through BS (start of heading, text, null control chars, backspace)\n// \\x0B: Vertical tab - rarely used legitimately, can cause display issues\n// \\x0C: Form feed - can cause unexpected page breaks in output\n// \\x0E-\\x1F: SO through US (shift out/in, device controls, separators)\n// Allowed characters:\n// \\x00: Null byte - handled separately for clearer error messaging\n// \\x09: Horizontal tab - commonly used in file paths and arguments\n// \\x0A: Newline (LF) - may appear in multi-line arguments\n// \\x0D: Carriage return (CR) - may appear with newlines on Windows\n// eslint-disable-next-line no-control-regex\nconst DANGEROUS_CONTROL_CHARS = /[\\x01-\\x08\\x0B\\x0C\\x0E-\\x1F]/;\n\n/**\n * Enable test-specific commands for testing purposes\n * This should only be called in test environments\n */\nexport function enableTestCommands(): void {\n testCommands = new Set([\n 'cat',\n 'echo',\n 'ls',\n 'sh',\n 'sleep'\n ]);\n}\n\n/**\n * Disable test-specific commands\n */\nexport function disableTestCommands(): void {\n testCommands = null;\n}\n\n/**\n * Check if a command is allowed\n */\nfunction isCommandAllowed(command: string): boolean {\n return ALLOWED_COMMANDS.has(command) || (testCommands !== null && testCommands.has(command));\n}\n\n// Resolved CodeQL binary directory from CODEQL_PATH.\n// When set, this directory is prepended to PATH for all child processes\n// so that `execFile('codeql', ...)` finds the correct binary via execvp().\n// Using PATH lookup (rather than an absolute path) is essential because\n// execvp() handles shell-script shebangs correctly, whereas passing an\n// absolute path to execFile() can fail with ENOENT for shell scripts.\nlet resolvedCodeQLDir: string | null = null;\n\n// Cached result from resolveCodeQLBinary(). `undefined` means not yet resolved.\nlet resolvedBinaryResult: string | undefined;\n\n/**\n * Resolve the CodeQL CLI binary path.\n *\n * Resolution order:\n * 1. `CODEQL_PATH` environment variable \u2014 must point to an existing file whose\n * basename is `codeql` (or `codeql.exe` / `codeql.cmd` on Windows).\n * The parent directory is prepended to PATH for child processes.\n * 2. Falls back to the bare `codeql` command (resolved via PATH at exec time).\n *\n * The resolved value is cached for the lifetime of the process. Call this once\n * at startup; subsequent calls are a no-op and return the cached value.\n */\nexport function resolveCodeQLBinary(): string {\n // Short-circuit if already resolved\n if (resolvedBinaryResult !== undefined) {\n return resolvedBinaryResult;\n }\n\n const envPath = process.env.CODEQL_PATH;\n\n if (!envPath) {\n resolvedCodeQLDir = null;\n resolvedBinaryResult = 'codeql';\n return resolvedBinaryResult;\n }\n\n // Validate the path points to a plausible CodeQL binary\n const base = basename(envPath).toLowerCase();\n const validBaseNames = ['codeql', 'codeql.exe', 'codeql.cmd'];\n if (!validBaseNames.includes(base)) {\n throw new Error(\n `CODEQL_PATH must point to a CodeQL CLI binary (expected basename: codeql), got: ${base}`\n );\n }\n\n // Require an absolute path to avoid ambiguity\n if (!isAbsolute(envPath)) {\n throw new Error(\n `CODEQL_PATH must be an absolute path, got: ${envPath}`\n );\n }\n\n // Verify the file exists\n if (!existsSync(envPath)) {\n throw new Error(\n `CODEQL_PATH points to a file that does not exist: ${envPath}`\n );\n }\n\n resolvedCodeQLDir = dirname(envPath);\n resolvedBinaryResult = 'codeql';\n logger.info(`CodeQL CLI resolved via CODEQL_PATH: ${envPath} (dir: ${resolvedCodeQLDir})`);\n return resolvedBinaryResult;\n}\n\n/**\n * Get the currently resolved CodeQL binary directory, or null if using PATH.\n */\nexport function getResolvedCodeQLDir(): string | null {\n return resolvedCodeQLDir;\n}\n\n/**\n * Reset the resolved CodeQL binary to the default (for testing only).\n */\nexport function resetResolvedCodeQLBinary(): void {\n resolvedCodeQLDir = null;\n resolvedBinaryResult = undefined;\n}\n\n/**\n * Validate that the resolved CodeQL binary is actually callable.\n *\n * Runs `codeql version --format=terse` and verifies the process exits\n * successfully. This catches the case where `CODEQL_PATH` is unset and\n * `codeql` is not on PATH \u2014 the server would otherwise start normally\n * but every tool invocation would fail.\n *\n * @returns The version string reported by the CodeQL CLI.\n * @throws Error if the binary is not reachable or returns a non-zero exit code.\n */\nexport async function validateCodeQLBinaryReachable(): Promise {\n const binary = resolvedBinaryResult ?? 'codeql';\n const env = { ...process.env };\n if (resolvedCodeQLDir) {\n env.PATH = resolvedCodeQLDir + delimiter + (env.PATH || '');\n }\n\n try {\n const { stdout } = await execFileAsync(binary, ['version', '--format=terse'], {\n env,\n timeout: 15_000,\n });\n return stdout.trim();\n } catch (err: unknown) {\n const message = err instanceof Error ? err.message : String(err);\n throw new Error(\n `CodeQL CLI is not reachable (binary: ${binary}). ` +\n `Ensure codeql is on PATH or set the CODEQL_PATH environment variable ` +\n `to the absolute path of the CodeQL CLI binary. Details: ${message}`\n );\n }\n}\n\n/**\n * Sanitize a CLI argument to prevent potential issues with special characters.\n * \n * While execFile() does not spawn a shell (preventing shell injection), we still\n * validate arguments to:\n * 1. Reject null bytes that could truncate strings in C-based commands\n * 2. Reject control characters that could cause unexpected behavior\n * 3. Provide defense-in-depth against potential issues\n * \n * @param arg - The argument to sanitize\n * @returns The sanitized argument\n * @throws Error if the argument contains dangerous characters\n */\nexport function sanitizeCLIArgument(arg: string): string {\n // Reject null bytes - these can truncate strings in C-based commands\n // Error message intentionally excludes argument content to avoid logging potentially sensitive data\n if (arg.includes('\\0')) {\n throw new Error(`CLI argument contains null byte: argument rejected for security`);\n }\n \n // Reject control characters using the module-level constant pattern\n if (DANGEROUS_CONTROL_CHARS.test(arg)) {\n // Error message intentionally excludes argument content to avoid logging potentially sensitive data\n throw new Error(`CLI argument contains control characters: argument rejected for security`);\n }\n \n return arg;\n}\n\n/**\n * Sanitize an array of CLI arguments\n * @param args - The arguments to sanitize\n * @returns The sanitized arguments\n * @throws Error if any argument contains dangerous characters\n */\nexport function sanitizeCLIArguments(args: string[]): string[] {\n return args.map(sanitizeCLIArgument);\n}\n\n/**\n * Filter environment variables to only include safe ones\n * This prevents potentially malicious environment variables from being passed to child processes\n */\nfunction getSafeEnvironment(additionalEnv?: Record): Record {\n const safeEnv: Record = {};\n \n // Copy whitelisted environment variables from process.env\n for (const key of SAFE_ENV_VARS) {\n if (process.env[key] !== undefined) {\n safeEnv[key] = process.env[key]!;\n }\n }\n \n // Copy environment variables with whitelisted prefixes\n for (const [key, value] of Object.entries(process.env)) {\n if (value !== undefined && SAFE_ENV_PREFIXES.some(prefix => key.startsWith(prefix))) {\n safeEnv[key] = value;\n }\n }\n \n // When CODEQL_PATH was set, prepend the resolved directory to PATH so that\n // `execFile('codeql', ...)` finds the user-specified binary via execvp().\n // This approach (PATH manipulation + bare command name) is essential because\n // execvp() handles shell-script shebangs correctly, whereas passing an\n // absolute path to execFile() fails with ENOENT for shell-script launchers.\n if (resolvedCodeQLDir && safeEnv.PATH) {\n safeEnv.PATH = `${resolvedCodeQLDir}${delimiter}${safeEnv.PATH}`;\n } else if (resolvedCodeQLDir) {\n safeEnv.PATH = resolvedCodeQLDir;\n }\n \n // Merge with explicitly provided environment variables\n // These are trusted as they come from the application code, not external sources\n if (additionalEnv) {\n Object.assign(safeEnv, additionalEnv);\n }\n \n return safeEnv;\n}\n\n/**\n * Execute a CLI command and return the result.\n * \n * Security: This function uses execFile() instead of exec() to avoid shell interpretation.\n * Arguments are passed directly to the executable as an array, preventing shell injection.\n * Additional security measures include:\n * - Command whitelist validation\n * - Shell metacharacter detection in command names\n * - CLI argument sanitization (null bytes, control characters)\n * - Environment variable filtering\n */\nexport async function executeCLICommand(options: CLIExecutionOptions): Promise {\n try {\n const { command, args, cwd, timeout = 300000, env } = options; // 5 minute default timeout\n \n // Validate command is in the whitelist to prevent arbitrary command execution\n if (!isCommandAllowed(command)) {\n throw new Error(`Command not allowed: ${command}. Only whitelisted commands can be executed.`);\n }\n \n // Validate command to ensure it doesn't contain shell metacharacters\n if (command.includes(';') || command.includes('|') || command.includes('&') || \n command.includes('$') || command.includes('`') || command.includes('\\n') ||\n command.includes('\\r')) {\n throw new Error(`Invalid command: contains shell metacharacters: ${command}`);\n }\n \n // Sanitize CLI arguments to prevent issues with special characters\n // This provides defense-in-depth even though execFile() doesn't use a shell\n const sanitizedArgs = sanitizeCLIArguments(args);\n \n logger.info(`Executing CLI command: ${command}`, { args: sanitizedArgs, cwd, timeout });\n \n const execOptions = {\n cwd,\n timeout,\n env: getSafeEnvironment(env),\n };\n \n // execFile() is used instead of exec() to avoid shell interpretation\n // Arguments are passed as an array, not interpolated into a command string\n const { stdout, stderr } = await execFileAsync(command, sanitizedArgs, execOptions);\n\n return {\n stdout,\n stderr,\n success: true,\n exitCode: 0\n };\n\n } catch (error: unknown) {\n logger.error('CLI command execution failed:', error);\n \n const err = error as Error & { code?: number; stdout?: string; stderr?: string };\n const errorMessage = err instanceof Error ? err.message : String(error);\n const exitCode = err.code || 1;\n \n return {\n stdout: err.stdout || '',\n stderr: err.stderr || errorMessage,\n success: false,\n error: errorMessage,\n exitCode\n };\n }\n}\n\n/**\n * Build CodeQL command arguments with proper escaping\n */\nexport function buildCodeQLArgs(subcommand: string, options: Record): string[] {\n const args = [subcommand];\n \n // Single-letter parameters that should use -key=value format (with equals sign)\n // Note: CodeQL CLI uses -t=key=value format for metadata, not -t key=value\n const singleLetterParams = new Set(['t', 'o', 'v', 'q', 'h', 'J']);\n \n for (const [key, value] of Object.entries(options)) {\n if (value === undefined || value === null) {\n continue;\n }\n \n const isSingleLetter = key.length === 1 && singleLetterParams.has(key);\n \n if (typeof value === 'boolean') {\n if (value) {\n args.push(isSingleLetter ? `-${key}` : `--${key}`);\n }\n } else if (Array.isArray(value)) {\n // Handle array values (e.g., multiple -t flags for metadata)\n for (const item of value) {\n if (isSingleLetter) {\n // For single-letter params like -t, use -key=value format\n args.push(`-${key}=${String(item)}`);\n } else {\n // For long params, use --key=value format\n args.push(`--${key}=${String(item)}`);\n }\n }\n } else {\n // Handle string, number, and other values\n if (isSingleLetter) {\n // For single-letter params, use -key=value format\n args.push(`-${key}=${String(value)}`);\n } else {\n args.push(`--${key}=${String(value)}`);\n }\n }\n }\n \n return args;\n}\n\n/**\n * Build QLT command arguments with proper escaping\n */\nexport function buildQLTArgs(subcommand: string, options: Record): string[] {\n const args = [subcommand];\n \n for (const [key, value] of Object.entries(options)) {\n if (value === undefined || value === null) {\n continue;\n }\n \n if (typeof value === 'boolean') {\n if (value) {\n args.push(`--${key}`);\n }\n } else if (Array.isArray(value)) {\n // Handle array values\n for (const item of value) {\n args.push(`--${key}`, String(item));\n }\n } else {\n // Handle string, number, and other values\n args.push(`--${key}`, String(value));\n }\n }\n \n return args;\n}\n\n/**\n * CodeQL subcommands that MUST run as fresh processes.\n *\n * These cannot use the cli-server because they:\n * - Spawn extractors or other long-running child processes (database create, test extract)\n * - Produce multi-event NUL-delimited streams (test run)\n * - Are compound orchestration commands (database analyze)\n *\n * Everything else is routed through the persistent cli-server JVM for\n * sub-second execution instead of 2-5 s JVM cold-start per invocation.\n */\nconst FRESH_PROCESS_SUBCOMMANDS = new Set([\n 'database analyze',\n 'database create',\n 'test extract',\n 'test run',\n]);\n\n/**\n * Execute a CodeQL command.\n *\n * By default, commands are routed through the persistent `codeql execute\n * cli-server` process managed by {@link CodeQLServerManager}, eliminating\n * repeated JVM startup overhead (~2-5 s savings per call).\n *\n * Commands listed in {@link FRESH_PROCESS_SUBCOMMANDS} (e.g. `database create`,\n * `test run`) are always executed as fresh processes because they either spawn\n * child extractors, produce streaming output, or require a dedicated working\n * directory.\n *\n * If the cli-server is not available (e.g. during early startup before\n * `initServerManager()` is called), the function falls back transparently to\n * a fresh process.\n */\nexport async function executeCodeQLCommand(\n subcommand: string,\n options: Record,\n additionalArgs: string[] = [],\n cwd?: string\n): Promise {\n const args = buildCodeQLArgs(subcommand, options);\n args.push(...additionalArgs);\n\n // Determine whether this subcommand can use the persistent cli-server.\n // Commands that need a specific CWD also must use a fresh process because\n // the cli-server's CWD is fixed at startup.\n const canUseCLIServer = !FRESH_PROCESS_SUBCOMMANDS.has(subcommand) && !cwd;\n\n if (canUseCLIServer) {\n try {\n // Lazy-import to avoid circular dependency at module level.\n // Use getServerManager() (not initServerManager()) \u2014 if the manager\n // hasn't been initialized yet (e.g. during tests or early startup),\n // this creates one, but we only attempt to *use* the cli-server if\n // it is already running (warmed up at MCP server startup). We never\n // block on starting a new cli-server here \u2014 that would add JVM\n // startup latency to the first fresh-process-fallback call.\n const { getServerManager } = await import('./server-manager');\n const manager = getServerManager();\n\n if (manager.isRunning('cli')) {\n const cliServer = await manager.getCLIServer({});\n const sanitizedArgs = sanitizeCLIArguments(args);\n\n logger.info(`Executing CodeQL command via cli-server: ${subcommand}`, { args: sanitizedArgs });\n\n const stdout = await cliServer.runCommand(sanitizedArgs);\n\n return {\n stdout,\n stderr: '',\n success: true,\n exitCode: 0,\n };\n } else {\n logger.debug(`cli-server not yet running for \"${subcommand}\", using fresh process`);\n }\n } catch (error) {\n // If the cli-server call fails, check whether it's a command-level\n // error (the CLI returned non-zero) or a transport/startup error.\n // For transport errors we fall back to a fresh process; for command\n // errors we return the failure directly.\n const message = error instanceof Error ? error.message : String(error);\n\n // Transport-level errors that warrant a fallback:\n if (message.includes('CLI server is not running') ||\n message.includes('CLI server exited') ||\n message.includes('failed to start')) {\n logger.warn(`cli-server unavailable for \"${subcommand}\", falling back to fresh process: ${message}`);\n // Fall through to fresh-process execution below\n } else {\n // Command-level error \u2014 return it as a failed result\n logger.error(`cli-server command failed for \"${subcommand}\": ${message}`);\n return {\n stdout: '',\n stderr: message,\n success: false,\n error: message,\n exitCode: 1,\n };\n }\n }\n }\n\n // Fresh-process execution (for FRESH_PROCESS_SUBCOMMANDS, CWD-specific\n // calls, or as a fallback when the cli-server is unavailable).\n // Use 0 (no timeout) because CodeQL operations such as query evaluation,\n // database analysis, profiling, and test runs are inherently long-running\n // and should not be killed by a process timeout.\n return executeCLICommand({\n command: 'codeql',\n args,\n cwd,\n timeout: 0\n });\n}\n\n/**\n * Execute a QLT command\n */\nexport async function executeQLTCommand(\n subcommand: string, \n options: Record, \n additionalArgs: string[] = []\n): Promise {\n const args = buildQLTArgs(subcommand, options);\n args.push(...additionalArgs);\n \n return executeCLICommand({\n command: 'qlt',\n args\n });\n}\n\n/**\n * Get help text for a CLI command\n */\nexport async function getCommandHelp(command: string, subcommand?: string): Promise {\n const args = subcommand ? [subcommand, '--help'] : ['--help'];\n \n const result = await executeCLICommand({\n command,\n args\n });\n \n return result.stdout || result.stderr || 'No help available';\n}\n\n/**\n * Validate that a command exists on the system.\n */\nexport async function validateCommandExists(command: string): Promise {\n try {\n const result = await executeCLICommand({\n command: 'which',\n args: [command]\n });\n return result.success;\n } catch {\n return false;\n }\n}", "/**\n * CodeQL Development MCP McpServer\n * Main entry point for the server\n */\n\nimport { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';\nimport { StreamableHTTPServerTransport } from '@modelcontextprotocol/sdk/server/streamableHttp.js';\nimport express from 'express';\nimport cors from 'cors';\nimport dotenv from 'dotenv';\nimport { realpathSync } from 'fs';\nimport { resolve } from 'path';\nimport { pathToFileURL } from 'url';\nimport { registerCodeQLTools, registerCodeQLResources } from './tools';\nimport { registerLSPTools } from './tools/lsp';\nimport { registerLanguageResources } from './resources/language-resources';\nimport { registerWorkflowPrompts } from './prompts/workflow-prompts';\nimport { registerMonitoringTools } from './tools/monitoring-tools';\nimport { sessionDataManager } from './lib/session-data-manager';\nimport { resolveCodeQLBinary, validateCodeQLBinaryReachable } from './lib/cli-executor';\nimport { initServerManager, shutdownServerManager } from './lib/server-manager';\nimport { packageRootDir } from './utils/package-paths';\nimport { logger } from './utils/logger';\n\n// Load environment variables from a .env file co-located with the package root.\n// Uses the package directory (not CWD) so that npm-installed users don't\n// accidentally inherit a .env from their project.\n// Set DOTENV_CONFIG_QUIET to suppress the dotenv banner that would otherwise\n// leak to stdout and corrupt the MCP stdio JSON-RPC channel.\ndotenv.config({ path: resolve(packageRootDir, '.env'), quiet: true });\n\nconst PACKAGE_NAME = 'codeql-development-mcp-server';\nconst VERSION = '2.24.1';\n\n/**\n * Start the MCP server\n */\nexport async function startServer(mode: 'stdio' | 'http' = 'stdio'): Promise {\n logger.info(`Starting CodeQL Development MCP McpServer v${VERSION} in ${mode} mode`);\n\n // Resolve the CodeQL CLI binary path (honors CODEQL_PATH env var).\n // This must happen before any tool registration so that all CodeQL commands\n // use the user-specified binary.\n const codeqlBinary = resolveCodeQLBinary();\n logger.info(`CodeQL CLI binary: ${codeqlBinary}`);\n\n // Validate that the resolved binary is actually callable. This catches\n // misconfigurations early (e.g. codeql not on PATH and CODEQL_PATH unset)\n // instead of failing silently and producing confusing tool-level errors.\n const codeqlVersion = await validateCodeQLBinaryReachable();\n logger.info(`CodeQL CLI version: ${codeqlVersion}`);\n\n const server = new McpServer({\n name: PACKAGE_NAME,\n version: VERSION,\n });\n\n // Register CodeQL tools (legacy high-level helpers)\n registerCodeQLTools(server);\n\n // Register LSP-based tools (diagnostics, completion, definition, references)\n registerLSPTools(server);\n\n // Register CodeQL resources (static guides)\n registerCodeQLResources(server);\n\n // Register language-specific resources (AST references, security patterns)\n registerLanguageResources(server);\n\n // Register high-level workflow prompts (complete development workflows)\n registerWorkflowPrompts(server);\n\n // Register monitoring and reporting tools\n registerMonitoringTools(server);\n\n // Initialize session data manager\n await sessionDataManager.initialize();\n\n // Initialize the CodeQL background server manager and eagerly start the\n // language server and CLI server JVMs so they are warm when the first tool\n // calls arrive. This avoids 2-60 s cold-start penalties per JVM.\n const manager = initServerManager();\n Promise.all([\n manager.warmUpLanguageServer(),\n manager.warmUpCLIServer(),\n ]).catch(() => { /* individual errors logged inside each warm-up method */ });\n\n if (mode === 'stdio') {\n const transport = new StdioServerTransport();\n await server.connect(transport);\n logger.info('McpServer started successfully on STDIO transport');\n } else {\n // HTTP mode\n const app = express();\n app.use(cors());\n app.use(express.json());\n\n const transport = new StreamableHTTPServerTransport({\n sessionIdGenerator: () => Math.random().toString(36).substring(7),\n });\n await server.connect(transport);\n\n app.all('/mcp', (req, res) => {\n transport.handleRequest(req, res, req.body).catch((err) => {\n logger.error('Error handling MCP request:', err);\n if (!res.headersSent) {\n res.status(500).json({ error: 'Internal McpServer Error' });\n }\n });\n });\n\n app.get('/', (_req, res) => {\n res.json({\n name: PACKAGE_NAME,\n version: VERSION,\n description: 'CodeQL Development MCP McpServer',\n status: 'running',\n });\n });\n\n const host = process.env.HTTP_HOST || 'localhost';\n const port = Number(process.env.HTTP_PORT || process.env.PORT) || 3000;\n \n // Return a promise that keeps the process alive\n return new Promise((resolve, reject) => {\n const httpServer = app.listen(port, host, () => {\n logger.info(`HTTP server listening on http://${host}:${port}/mcp`);\n resolve();\n });\n \n httpServer.on('error', (error) => {\n logger.error('HTTP server error:', error);\n reject(error);\n });\n });\n }\n\n setupGracefulShutdown(server);\n return server;\n}\n\n/**\n * Set up graceful shutdown handling\n */\nfunction setupGracefulShutdown(server: McpServer): void {\n const shutdown = async () => {\n logger.info('Shutting down server...');\n try {\n // Shut down all CodeQL background servers first\n await shutdownServerManager();\n await server.close();\n logger.info('McpServer closed gracefully');\n process.exit(0);\n } catch (error) {\n logger.error('Error during shutdown:', error);\n process.exit(1);\n }\n };\n\n process.on('SIGINT', shutdown);\n process.on('SIGTERM', shutdown);\n}\n\n/**\n * Main function to start the server\n */\nasync function main(): Promise {\n try {\n const transportMode = (process.env.TRANSPORT_MODE || 'stdio').toLowerCase();\n const mode: 'stdio' | 'http' = transportMode === 'http' ? 'http' : 'stdio';\n await startServer(mode);\n } catch (error) {\n logger.error('Failed to start server:', error);\n process.exit(1);\n }\n}\n\n// Start the server if this file is run directly.\n// Use realpathSync to resolve npm/npx symlinks so the guard works for both\n// direct invocation and globally-installed npm bin entries.\nconst scriptPath = process.argv[1] ? realpathSync(resolve(process.argv[1])) : undefined;\nif (scriptPath && import.meta.url === pathToFileURL(scriptPath).href) {\n main();\n}\n", "/**\n * CodeQL BQRS decode tool\n */\n\nimport { z } from 'zod';\nimport { CLIToolDefinition, createCodeQLSchemas, createBQRSResultProcessor } from '../../lib/cli-tool-registry';\n\nexport const codeqlBqrsDecodeTool: CLIToolDefinition = {\n name: 'codeql_bqrs_decode',\n description: 'Decode BQRS result files to human-readable formats',\n command: 'codeql',\n subcommand: 'bqrs decode',\n inputSchema: {\n files: z.array(z.string()).describe('BQRS file(s) to decode'),\n output: createCodeQLSchemas.output(),\n format: z.enum(['csv', 'json']).optional().describe('Output format'),\n 'max-paths': z.number().optional().describe('Maximum number of paths to output'),\n 'start-at': z.number().optional().describe('Start output at result number'),\n 'max-results': z.number().optional().describe('Maximum number of results'),\n verbose: createCodeQLSchemas.verbose(),\n additionalArgs: createCodeQLSchemas.additionalArgs()\n },\n examples: [\n 'codeql bqrs decode --format=csv --output=results.csv results.bqrs',\n 'codeql bqrs decode --format=json --max-results=100 results.bqrs'\n ],\n resultProcessor: createBQRSResultProcessor()\n};", "/**\n * Generic tool registry for creating MCP tools from CLI command definitions\n */\n\nimport { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport { z } from 'zod';\nimport { executeCodeQLCommand, executeQLTCommand, CLIExecutionResult } from './cli-executor';\nimport { logger } from '../utils/logger';\nimport { evaluateQueryResults, QueryEvaluationResult, extractQueryMetadata } from './query-results-evaluator';\nimport { getOrCreateLogDirectory } from './log-directory-manager';\nimport { getUserWorkspaceDir, packageRootDir, resolveToolQueryPackPath } from '../utils/package-paths';\nimport { writeFileSync, rmSync, existsSync, mkdirSync } from 'fs';\nimport { basename, dirname, isAbsolute, join, resolve } from 'path';\nimport { createProjectTempDir } from '../utils/temp-dir';\n\nexport type { CLIExecutionResult } from './cli-executor';\n\nexport interface CLIToolDefinition {\n name: string;\n description: string;\n command: 'codeql' | 'qlt';\n subcommand: string;\n inputSchema: Record;\n examples?: string[];\n resultProcessor?: (_result: CLIExecutionResult, _params: Record) => string;\n}\n\n/**\n * Default result processor that formats CLI output appropriately\n */\nexport const defaultCLIResultProcessor = (\n result: CLIExecutionResult, \n _params: Record\n): string => {\n if (!result.success) {\n return `Command failed (exit code ${result.exitCode || 'unknown'}):\\n${result.error || result.stderr}`;\n }\n \n let output = '';\n \n if (result.stdout) {\n output += result.stdout;\n }\n \n if (result.stderr) {\n if (output) {\n output += '\\n\\nWarnings/Info:\\n';\n }\n output += result.stderr;\n }\n \n if (!output) {\n output = 'Command executed successfully (no output)';\n }\n \n return output;\n};\n\n/**\n * Register a CLI tool with the MCP server\n */\nexport function registerCLITool(server: McpServer, definition: CLIToolDefinition): void {\n const {\n name,\n description,\n command,\n subcommand,\n inputSchema,\n resultProcessor = defaultCLIResultProcessor\n } = definition;\n\n server.tool(\n name,\n description,\n inputSchema,\n async (params: Record) => {\n // Track temporary directories for cleanup\n const tempDirsToCleanup: string[] = [];\n \n try {\n logger.info(`Executing CLI tool: ${name}`, { command, subcommand, params });\n\n // Separate positional arguments from named options\n // Extract tool-specific parameters that should not be passed to CLI\n // Note: format is extracted for tools that use it internally but not on CLI\n // For codeql_bqrs_interpret, codeql_bqrs_decode, codeql_generate_query-help, and codeql_database_analyze, format should be passed to CLI\n const formatShouldBePassedToCLI = name === 'codeql_bqrs_interpret' || name === 'codeql_bqrs_decode' || name === 'codeql_generate_query-help' || name === 'codeql_database_analyze';\n \n const extractedParams = formatShouldBePassedToCLI\n ? {\n _positional: params._positional || [],\n files: params.files,\n file: params.file,\n dir: params.dir,\n packDir: params.packDir,\n tests: params.tests,\n query: params.query,\n queryName: params.queryName,\n queryLanguage: params.queryLanguage,\n queryPack: params.queryPack,\n sourceFiles: params.sourceFiles,\n sourceFunction: params.sourceFunction,\n targetFunction: params.targetFunction,\n interpretedOutput: params.interpretedOutput,\n evaluationFunction: params.evaluationFunction,\n evaluationOutput: params.evaluationOutput,\n directory: params.directory,\n logDir: params.logDir,\n qlref: params.qlref\n }\n : {\n _positional: params._positional || [],\n files: params.files,\n file: params.file,\n dir: params.dir,\n packDir: params.packDir,\n tests: params.tests,\n query: params.query,\n queryName: params.queryName,\n queryLanguage: params.queryLanguage,\n queryPack: params.queryPack, \n sourceFiles: params.sourceFiles,\n sourceFunction: params.sourceFunction,\n targetFunction: params.targetFunction,\n format: params.format,\n interpretedOutput: params.interpretedOutput,\n evaluationFunction: params.evaluationFunction,\n evaluationOutput: params.evaluationOutput,\n directory: params.directory,\n logDir: params.logDir,\n qlref: params.qlref\n };\n\n const {\n _positional = [],\n files,\n file,\n dir,\n packDir,\n tests,\n query,\n queryName,\n queryLanguage: _queryLanguage,\n queryPack: _queryPack,\n sourceFiles,\n sourceFunction,\n targetFunction,\n format: _format,\n interpretedOutput: _interpretedOutput,\n evaluationFunction: _evaluationFunction,\n evaluationOutput: _evaluationOutput,\n directory,\n logDir: customLogDir,\n qlref,\n } = extractedParams;\n\n // Get remaining options (everything not extracted above)\n const options = {...params};\n Object.keys(extractedParams).forEach(key => delete options[key]);\n let positionalArgs = Array.isArray(_positional) ? _positional as string[] : [_positional as string];\n\n // Handle files parameter as positional arguments for certain tools\n if (files && Array.isArray(files)) {\n positionalArgs = [...positionalArgs, ...files as string[]];\n }\n\n // Handle file parameter as positional argument for BQRS tools\n if (file && name.startsWith('codeql_bqrs_')) {\n positionalArgs = [...positionalArgs, file as string];\n }\n\n // Handle qlref parameter as positional argument for resolve qlref tool\n if (qlref && name === 'codeql_resolve_qlref') {\n positionalArgs = [...positionalArgs, qlref as string];\n }\n\n // Handle database parameter as positional argument for resolve database tool\n if (options.database && name === 'codeql_resolve_database') {\n positionalArgs = [...positionalArgs, options.database as string];\n delete options.database;\n }\n\n // Handle database parameter as positional argument for database create tool\n if (options.database && name === 'codeql_database_create') {\n positionalArgs = [...positionalArgs, options.database as string];\n delete options.database;\n }\n\n // Handle database and queries parameters as positional arguments for database analyze tool\n if (name === 'codeql_database_analyze') {\n if (options.database) {\n positionalArgs = [...positionalArgs, options.database as string];\n delete options.database;\n }\n if (options.queries) {\n positionalArgs = [...positionalArgs, options.queries as string];\n delete options.queries;\n }\n }\n\n // Handle query parameter as positional argument for generate query-help tool\n if (query && name === 'codeql_generate_query-help') {\n positionalArgs = [...positionalArgs, query as string];\n }\n\n // Handle dir parameter as positional argument for pack tools\n if (dir && (name === 'codeql_pack_ls')) {\n positionalArgs = [...positionalArgs, dir as string];\n }\n \n // Handle tool-specific parameters using switch pattern for better maintainability\n switch (name) {\n case 'codeql_test_accept':\n case 'codeql_test_extract':\n case 'codeql_test_run':\n case 'codeql_resolve_tests':\n // Handle tests parameter as positional arguments for test tools.\n // Resolve relative paths against the user's effective workspace\n // directory. In monorepo layouts this is the repo root; in npm-\n // installed layouts it falls back to process.cwd().\n if (tests && Array.isArray(tests)) {\n const userDir = getUserWorkspaceDir();\n positionalArgs = [...positionalArgs, ...(tests as string[]).map(\n t => isAbsolute(t) ? t : resolve(userDir, t)\n )];\n }\n break;\n \n case 'codeql_query_run': {\n // Resolve database path to absolute path if it's relative\n if (options.database && typeof options.database === 'string' && !isAbsolute(options.database)) {\n options.database = resolve(getUserWorkspaceDir(), options.database);\n logger.info(`Resolved database path to: ${options.database}`);\n }\n \n // Implement query resolution logic with enhanced results processing\n const resolvedQuery = await resolveQueryPath(params, logger);\n if (resolvedQuery) {\n positionalArgs = [...positionalArgs, resolvedQuery];\n } else if (query) {\n positionalArgs = [...positionalArgs, query as string];\n }\n \n // Handle external predicates for tool queries\n if (queryName === 'PrintAST' && sourceFiles) {\n // Create a CSV file with the source file paths for the external predicate\n // The external predicate expects a CSV file with one column containing file paths\n const filePaths = (sourceFiles as string).split(',').map((f: string) => f.trim());\n let tempDir: string;\n let csvPath: string;\n try {\n tempDir = createProjectTempDir('codeql-external-');\n tempDirsToCleanup.push(tempDir); // Track for cleanup\n csvPath = join(tempDir, 'selectedSourceFiles.csv');\n\n // Create CSV content\n const csvContent = filePaths.join('\\n') + '\\n';\n\n writeFileSync(csvPath, csvContent, 'utf8');\n } catch (err) {\n logger.error(`Failed to create external predicate CSV for PrintAST query at path ${csvPath || '[unknown]'}: ${err instanceof Error ? err.message : String(err)}`);\n throw err;\n }\n \n // Add the external predicate with the CSV file path\n const currentExternal = options.external || [];\n const externalArray = Array.isArray(currentExternal) ? currentExternal : [currentExternal];\n externalArray.push(`selectedSourceFiles=${csvPath}`);\n options.external = externalArray;\n \n logger.info(`Created external predicate CSV at ${csvPath} for files: ${filePaths.join(', ')}`);\n }\n \n // Handle external predicates for CallGraphFrom queries\n if (queryName === 'CallGraphFrom' && sourceFunction) {\n const functionNames = (sourceFunction as string).split(',').map((f: string) => f.trim());\n let tempDir: string;\n let csvPath: string;\n try {\n tempDir = createProjectTempDir('codeql-external-');\n tempDirsToCleanup.push(tempDir);\n csvPath = join(tempDir, 'sourceFunction.csv');\n\n // Create CSV content\n const csvContent = functionNames.join('\\n') + '\\n';\n\n writeFileSync(csvPath, csvContent, 'utf8');\n } catch (err) {\n logger.error(`Failed to create external predicate CSV for CallGraphFrom query at path ${csvPath || '[unknown]'}: ${err instanceof Error ? err.message : String(err)}`);\n throw err;\n }\n \n // Add the external predicate with the CSV file path\n const currentExternal = options.external || [];\n const externalArray = Array.isArray(currentExternal) ? currentExternal : [currentExternal];\n externalArray.push(`sourceFunction=${csvPath}`);\n options.external = externalArray;\n \n logger.info(`Created external predicate CSV at ${csvPath} for functions: ${functionNames.join(', ')}`);\n }\n \n // Handle external predicates for CallGraphTo queries\n if (queryName === 'CallGraphTo' && targetFunction) {\n const functionNames = (targetFunction as string).split(',').map((f: string) => f.trim());\n let tempDir: string;\n let csvPath: string;\n try {\n tempDir = createProjectTempDir('codeql-external-');\n tempDirsToCleanup.push(tempDir);\n csvPath = join(tempDir, 'targetFunction.csv');\n\n // Create CSV content\n const csvContent = functionNames.join('\\n') + '\\n';\n\n writeFileSync(csvPath, csvContent, 'utf8');\n } catch (err) {\n logger.error(`Failed to create external predicate CSV for CallGraphTo query at path ${csvPath || '[unknown]'}: ${err instanceof Error ? err.message : String(err)}`);\n throw err;\n }\n \n // Add the external predicate with the CSV file path\n const currentExternal = options.external || [];\n const externalArray = Array.isArray(currentExternal) ? currentExternal : [currentExternal];\n externalArray.push(`targetFunction=${csvPath}`);\n options.external = externalArray;\n \n logger.info(`Created external predicate CSV at ${csvPath} for functions: ${functionNames.join(', ')}`);\n }\n break;\n }\n \n case 'codeql_query_compile':\n case 'codeql_resolve_metadata':\n // Handle query parameter as positional argument for query compilation and metadata tools\n if (query) {\n positionalArgs = [...positionalArgs, query as string];\n }\n break;\n \n case 'codeql_resolve_queries':\n // Handle directory parameter as positional argument\n if (directory) {\n positionalArgs = [...positionalArgs, directory as string];\n }\n break;\n \n default:\n // No special parameter handling needed for other tools\n break;\n }\n\n // Set up logging directory for query/test/analyze runs\n let queryLogDir: string | undefined;\n if (name === 'codeql_query_run' || name === 'codeql_test_run' || name === 'codeql_database_analyze') {\n queryLogDir = getOrCreateLogDirectory(customLogDir as string | undefined);\n logger.info(`Using log directory for ${name}: ${queryLogDir}`);\n\n // Create timestamp file to track when query/test run started\n const timestampPath = join(queryLogDir, 'timestamp');\n writeFileSync(timestampPath, Date.now().toString(), 'utf8');\n\n // Set the --logdir option for CodeQL CLI\n options.logdir = queryLogDir;\n\n // Set verbosity to progress+ to generate detailed query.log/test.log\n if (!options.verbosity) {\n options.verbosity = 'progress+';\n }\n\n // Set evaluator-log if not explicitly provided\n if (!options['evaluator-log']) {\n options['evaluator-log'] = join(queryLogDir, 'evaluator-log.jsonl');\n }\n\n // Enable --tuple-counting by default for evaluator logging\n if (options['tuple-counting'] === undefined) {\n options['tuple-counting'] = true;\n }\n\n // For query run, also handle default output\n if (name === 'codeql_query_run') {\n // If output was not explicitly provided, set it to the log directory\n if (!options.output) {\n options.output = join(queryLogDir, 'results.bqrs');\n }\n }\n }\n\n let result: CLIExecutionResult;\n \n if (command === 'codeql') {\n // For pack commands, set the working directory to where qlpack.yml is located.\n // Resolve to absolute path since the MCP server's cwd may differ from\n // the workspace root (especially when launched by VS Code).\n let cwd: string | undefined;\n if ((name === 'codeql_pack_install' || name === 'codeql_pack_ls') && (dir || packDir)) {\n const rawCwd = (dir || packDir) as string;\n // Resolve relative paths against the user's effective workspace\n // directory rather than a potentially read-only package root.\n cwd = isAbsolute(rawCwd) ? rawCwd : resolve(getUserWorkspaceDir(), rawCwd);\n }\n \n // Add --additional-packs for commands that need to access local test packs.\n // Only set the default examples path when it actually exists on disk\n // (it may be absent in npm-installed layouts where ql/javascript/examples/\n // is not included in the published package).\n const defaultExamplesPath = resolve(packageRootDir, 'ql', 'javascript', 'examples');\n const additionalPacksPath = process.env.CODEQL_ADDITIONAL_PACKS\n || (existsSync(defaultExamplesPath) ? defaultExamplesPath : undefined);\n if (additionalPacksPath && (name === 'codeql_test_run' || name === 'codeql_query_run' || name === 'codeql_query_compile' || name === 'codeql_database_analyze')) {\n options['additional-packs'] = additionalPacksPath;\n }\n \n // Keep test databases for codeql_test_run to allow subsequent query runs\n if (name === 'codeql_test_run') {\n options['keep-databases'] = true;\n }\n \n result = await executeCodeQLCommand(subcommand, options, positionalArgs, cwd);\n } else if (command === 'qlt') {\n result = await executeQLTCommand(subcommand, options, positionalArgs);\n } else {\n throw new Error(`Unsupported command: ${command}`);\n }\n\n // Post-execution processing for codeql_query_run\n if (name === 'codeql_query_run' && result.success && queryLogDir) {\n // Generate SARIF interpretation if results.bqrs exists\n const bqrsPath = options.output as string;\n const sarifPath = join(queryLogDir, 'results.sarif');\n\n if (existsSync(bqrsPath)) {\n try {\n const sarifResult = await executeCodeQLCommand(\n 'bqrs interpret',\n { format: 'sarif-latest', output: sarifPath },\n [bqrsPath]\n );\n\n if (sarifResult.success) {\n logger.info(`Generated SARIF interpretation at ${sarifPath}`);\n }\n } catch (error) {\n logger.warn(`Failed to generate SARIF interpretation: ${error}`);\n }\n }\n\n // Process evaluation results\n result = await processQueryRunResults(result, params, logger);\n }\n\n // Post-execution: generate evaluator log summary for query run / database analyze\n if ((name === 'codeql_query_run' || name === 'codeql_database_analyze') && result.success && queryLogDir) {\n const evalLogPath = options['evaluator-log'] as string | undefined;\n if (evalLogPath && existsSync(evalLogPath)) {\n try {\n const summaryPath = evalLogPath.replace(/\\.jsonl$/, '.summary.jsonl');\n // codeql generate log-summary takes positional args: []\n const summaryResult = await executeCodeQLCommand(\n 'generate log-summary',\n { format: 'predicates' },\n [evalLogPath, summaryPath]\n );\n\n if (summaryResult.success) {\n logger.info(`Generated evaluator log summary at ${summaryPath}`);\n }\n } catch (error) {\n logger.warn(`Failed to generate evaluator log summary: ${error}`);\n }\n }\n }\n\n // Process the result\n const processedResult = resultProcessor(result, params);\n\n return {\n content: [{\n type: 'text' as const,\n text: processedResult\n }],\n isError: !result.success\n };\n\n } catch (error) {\n logger.error(`Error in CLI tool ${name}:`, error);\n \n return {\n content: [{\n type: 'text' as const,\n text: `Failed to execute CLI tool: ${error instanceof Error ? error.message : String(error)}`\n }],\n isError: true\n };\n } finally {\n // Clean up temporary directories\n for (const tempDir of tempDirsToCleanup) {\n try {\n rmSync(tempDir, { recursive: true, force: true });\n logger.info(`Cleaned up temporary directory: ${tempDir}`);\n } catch (cleanupError) {\n logger.error(`Failed to clean up temporary directory ${tempDir}:`, cleanupError);\n }\n }\n }\n }\n );\n}\n\n/**\n * Helper function to create common CodeQL input schemas\n */\nexport const createCodeQLSchemas = {\n database: () => z.string().describe('Path to the CodeQL database'),\n \n query: () => z.string().describe('Path to the CodeQL query file (.ql)'),\n \n output: () => z.string().optional().describe('Output file path'),\n \n outputFormat: () => z.enum(['csv', 'json', 'bqrs', 'sarif-latest', 'sarifv2.1.0']).optional()\n .describe('Output format for results'),\n \n language: () => z.string().optional().describe('Programming language'),\n \n threads: () => z.number().optional().describe('Number of threads to use'),\n \n ram: () => z.number().optional().describe('Amount of RAM to use (MB)'),\n \n timeout: () => z.number().optional().describe('Timeout in seconds'),\n \n verbose: () => z.boolean().optional().describe('Enable verbose output'),\n \n additionalArgs: () => z.array(z.string()).optional().describe('Additional command-line arguments'),\n \n positionalArgs: () => z.array(z.string()).optional().describe('Positional arguments')\n .transform((val) => ({ _positional: val }))\n};\n\n/**\n * Helper function to create common QLT input schemas\n */\nexport const createQLTSchemas = {\n language: () => z.string().describe('Programming language'),\n \n output: () => z.string().optional().describe('Output directory or file path'),\n \n template: () => z.string().optional().describe('Template to use'),\n \n name: () => z.string().optional().describe('Name for generated query'),\n \n description: () => z.string().optional().describe('Description for generated query'),\n \n verbose: () => z.boolean().optional().describe('Enable verbose output'),\n \n force: () => z.boolean().optional().describe('Force overwrite existing files'),\n \n additionalArgs: () => z.array(z.string()).optional().describe('Additional command-line arguments')\n};\n\n/**\n * Create a result processor that formats BQRS output specially\n */\nexport const createBQRSResultProcessor = () => (\n result: CLIExecutionResult, \n params: Record\n): string => {\n if (!result.success) {\n return defaultCLIResultProcessor(result, params);\n }\n \n // For BQRS commands, provide more context about the output\n let output = result.stdout;\n \n if (params.output) {\n output += `\\n\\nResults saved to: ${params.output}`;\n }\n \n if (result.stderr) {\n output += `\\n\\nAdditional information:\\n${result.stderr}`;\n }\n \n return output;\n};\n\n/**\n * Create a result processor that formats database creation output\n */\nexport const createDatabaseResultProcessor = () => (\n result: CLIExecutionResult, \n params: Record\n): string => {\n if (!result.success) {\n return defaultCLIResultProcessor(result, params);\n }\n \n let output = 'Database creation completed successfully';\n \n if (params.database || params._positional) {\n const dbPath = params.database || (Array.isArray(params._positional) ? params._positional[0] : params._positional);\n output += `\\n\\nDatabase location: ${dbPath}`;\n }\n \n if (result.stdout) {\n output += `\\n\\nOutput:\\n${result.stdout}`;\n }\n \n if (result.stderr) {\n output += `\\n\\nAdditional information:\\n${result.stderr}`;\n }\n \n return output;\n};\n\n/**\n * Resolve query path for codeql_query_run tool\n * If queryName and queryLanguage are provided, resolve using codeql resolve queries\n */\nasync function resolveQueryPath(\n params: Record, \n logger: { info: (_message: string, ..._args: unknown[]) => void; error: (_message: string, ..._args: unknown[]) => void }\n): Promise {\n const { queryName, queryLanguage, queryPack, query } = params;\n \n // Validate parameter usage - queryName and query are mutually exclusive\n if (queryName && query) {\n logger.error('Cannot use both \"query\" and \"queryName\" parameters simultaneously. Use either \"query\" for direct file path OR \"queryName\" + \"queryLanguage\" for tool queries.');\n throw new Error('Cannot use both \"query\" and \"queryName\" parameters simultaneously. Use either \"query\" for direct file path OR \"queryName\" + \"queryLanguage\" for tool queries.');\n }\n \n // If no queryName provided, fall back to direct query parameter\n if (!queryName) {\n return query as string || null;\n }\n \n // If queryName provided but no language, we can't resolve\n if (!queryLanguage) {\n logger.error('queryLanguage is required when using queryName parameter. Supported languages: actions, cpp, csharp, go, java, javascript, python, ruby, swift');\n throw new Error('queryLanguage is required when using queryName parameter. Supported languages: actions, cpp, csharp, go, java, javascript, python, ruby, swift');\n }\n \n try {\n // Determine the query pack path - use absolute path to ensure it works regardless of cwd\n const defaultPackPath = resolveToolQueryPackPath(queryLanguage as string);\n const packPath = queryPack as string || defaultPackPath;\n \n logger.info(`Resolving query: ${queryName} for language: ${queryLanguage} in pack: ${packPath}`);\n \n // Execute codeql resolve queries to get available queries\n const { executeCodeQLCommand } = await import('./cli-executor');\n const resolveResult = await executeCodeQLCommand(\n 'resolve queries',\n { format: 'json' },\n [packPath]\n );\n \n if (!resolveResult.success) {\n logger.error('Failed to resolve queries:', resolveResult.stderr || resolveResult.error);\n throw new Error(`Failed to resolve queries: ${resolveResult.stderr || resolveResult.error}`);\n }\n \n // Parse the JSON output to find matching queries\n let resolvedQueries: string[];\n try {\n resolvedQueries = JSON.parse(resolveResult.stdout);\n } catch (parseError) {\n logger.error('Failed to parse resolve queries output:', parseError);\n throw new Error('Failed to parse resolve queries output');\n }\n \n // Find the query that matches the requested name exactly\n const matchingQuery = resolvedQueries.find(queryPath => {\n const fileName = basename(queryPath);\n // Match exact query name: \"PrintAST\" should match \"PrintAST.ql\" only\n return fileName === `${queryName}.ql`;\n });\n\n if (!matchingQuery) {\n logger.error(`Query \"${queryName}.ql\" not found in pack \"${packPath}\". Available queries:`, resolvedQueries.map(q => basename(q)));\n throw new Error(`Query \"${queryName}.ql\" not found in pack \"${packPath}\"`);\n }\n \n logger.info(`Resolved query \"${queryName}\" to: ${matchingQuery}`);\n return matchingQuery;\n \n } catch (error) {\n logger.error('Error resolving query path:', error);\n throw error;\n }\n}\n\n/**\n * Interpret BQRS file using codeql bqrs interpret\n */\nasync function interpretBQRSFile(\n bqrsPath: string,\n queryPath: string,\n format: string,\n outputPath: string,\n logger: { info: (_message: string, ..._args: unknown[]) => void; error: (_message: string, ..._args: unknown[]) => void }\n): Promise {\n try {\n // Extract query metadata to get id and kind\n const metadata = await extractQueryMetadata(queryPath);\n \n // Validate required metadata fields\n const missingFields = [];\n if (!metadata.id) missingFields.push('id');\n if (!metadata.kind) missingFields.push('kind');\n \n if (missingFields.length > 0) {\n return {\n success: false,\n exitCode: 1,\n stdout: '',\n stderr: '',\n error: `Query metadata is incomplete. Missing required field(s): ${missingFields.join(', ')}. Ensure the query file contains @id and @kind metadata.`\n };\n }\n \n // Sanitize metadata values to prevent command injection\n const sanitizedKind = (metadata.kind || '').replace(/[^a-zA-Z0-9_-]/g, '');\n const sanitizedId = (metadata.id || '').replace(/[^a-zA-Z0-9_/:-]/g, '');\n \n // Validate format for query kind\n const graphFormats = ['graphtext', 'dgml', 'dot'];\n if (graphFormats.includes(format) && metadata.kind !== 'graph') {\n return {\n success: false,\n exitCode: 1,\n stdout: '',\n stderr: '',\n error: `Format '${format}' is only compatible with @kind graph queries, but this query has @kind ${metadata.kind}`\n };\n }\n \n // Ensure output directory exists\n mkdirSync(dirname(outputPath), { recursive: true });\n \n // Build the codeql bqrs interpret command\n const params: Record = {\n format: format,\n output: outputPath,\n t: [`kind=${sanitizedKind}`, `id=${sanitizedId}`]\n };\n \n logger.info(`Interpreting BQRS file ${bqrsPath} with format ${format} to ${outputPath}`);\n \n // Execute codeql bqrs interpret\n const result = await executeCodeQLCommand(\n 'bqrs interpret',\n params,\n [bqrsPath]\n );\n \n return result;\n } catch (error) {\n return {\n success: false,\n exitCode: 1,\n stdout: '',\n stderr: '',\n error: `Failed to interpret BQRS file: ${error}`\n };\n }\n}\n\n/**\n * Get default output extension based on format\n */\nfunction getDefaultExtension(format: string): string {\n switch (format) {\n case 'sarif-latest':\n case 'sarifv2.1.0':\n return '.sarif';\n case 'csv':\n return '.csv';\n case 'graphtext':\n return '.txt';\n case 'dgml':\n return '.dgml';\n case 'dot':\n return '.dot';\n default:\n return '.txt';\n }\n}\n\n/**\n * Process query run results with optional interpretation or evaluation\n */\nasync function processQueryRunResults(\n result: CLIExecutionResult,\n params: Record,\n logger: { info: (_message: string, ..._args: unknown[]) => void; error: (_message: string, ..._args: unknown[]) => void }\n): Promise {\n try {\n const { format, interpretedOutput, evaluationFunction, evaluationOutput, output, query, queryName, queryLanguage } = params;\n \n // If no format or evaluationFunction specified, return as-is\n if (!format && !evaluationFunction) {\n return result;\n }\n \n // Ensure output (bqrs file) was generated\n if (!output) {\n return result;\n }\n \n const bqrsPath = output as string;\n \n // Determine the query path for metadata extraction\n let queryPath: string | null = null;\n \n if (query) {\n queryPath = query as string;\n } else if (queryName && queryLanguage) {\n // Try to resolve the query path again for evaluation\n queryPath = await resolveQueryPath(params, logger);\n }\n \n if (!queryPath) {\n logger.error('Cannot determine query path for interpretation/evaluation');\n return {\n ...result,\n stdout: result.stdout + '\\n\\nWarning: Query interpretation skipped - could not determine query path'\n };\n }\n \n // Handle new format parameter (preferred approach)\n if (format) {\n const outputFormat = format as string;\n \n // Determine output path\n let outputFilePath = interpretedOutput as string | undefined;\n if (!outputFilePath) {\n const ext = getDefaultExtension(outputFormat);\n outputFilePath = bqrsPath.replace('.bqrs', ext);\n }\n \n logger.info(`Interpreting query results from ${bqrsPath} with format: ${outputFormat}`);\n \n // Interpret the BQRS file\n const interpretResult = await interpretBQRSFile(\n bqrsPath,\n queryPath,\n outputFormat,\n outputFilePath,\n logger\n );\n \n if (interpretResult.success) {\n let enhancedOutput = result.stdout;\n enhancedOutput += `\\n\\nQuery results interpreted successfully with format: ${outputFormat}`;\n enhancedOutput += `\\nInterpreted output saved to: ${outputFilePath}`;\n \n return {\n ...result,\n stdout: enhancedOutput\n };\n } else {\n logger.error('Query interpretation failed:', interpretResult.error);\n return {\n ...result,\n stdout: result.stdout + `\\n\\nWarning: Query interpretation failed - ${interpretResult.error || interpretResult.stderr}`\n };\n }\n }\n \n // Handle legacy evaluationFunction parameter (deprecated)\n if (evaluationFunction) {\n logger.info(`Using deprecated evaluationFunction parameter. Consider using format parameter instead.`);\n logger.info(`Evaluating query results from ${bqrsPath} using function: ${evaluationFunction}`);\n \n // Perform the evaluation\n const evaluationResult: QueryEvaluationResult = await evaluateQueryResults(\n bqrsPath,\n queryPath,\n evaluationFunction as string,\n evaluationOutput as string | undefined\n );\n \n if (evaluationResult.success) {\n // Append evaluation results to the command output\n let enhancedOutput = result.stdout;\n \n if (evaluationResult.outputPath) {\n enhancedOutput += `\\n\\nQuery evaluation completed successfully.`;\n enhancedOutput += `\\nEvaluation output saved to: ${evaluationResult.outputPath}`;\n }\n \n if (evaluationResult.content) {\n enhancedOutput += `\\n\\n=== Query Results Evaluation ===\\n`;\n enhancedOutput += evaluationResult.content;\n }\n \n return {\n ...result,\n stdout: enhancedOutput\n };\n } else {\n // Evaluation failed, but don't fail the whole operation\n logger.error('Query evaluation failed:', evaluationResult.error);\n return {\n ...result,\n stdout: result.stdout + `\\n\\nWarning: Query evaluation failed - ${evaluationResult.error}`\n };\n }\n }\n \n return result;\n } catch (error) {\n logger.error('Error in query results processing:', error);\n return {\n ...result,\n stdout: result.stdout + `\\n\\nWarning: Query processing error - ${error}`\n };\n }\n}", "/**\n * Query results evaluation functions for processing .bqrs files\n */\n\nimport { executeCodeQLCommand } from './cli-executor';\nimport { logger } from '../utils/logger';\nimport { writeFileSync, readFileSync } from 'fs';\nimport { dirname, isAbsolute } from 'path';\nimport { mkdirSync } from 'fs';\n\nexport interface QueryEvaluationResult {\n success: boolean;\n outputPath?: string;\n content?: string;\n error?: string;\n}\n\nexport interface QueryMetadata {\n kind?: string;\n name?: string;\n description?: string;\n id?: string;\n tags?: string[];\n}\n\n/**\n * Built-in evaluation functions\n */\nexport const BUILT_IN_EVALUATORS = {\n 'json-decode': 'JSON format decoder for query results',\n 'csv-decode': 'CSV format decoder for query results', \n 'mermaid-graph': 'Mermaid diagram generator for @kind graph queries (like PrintAST)',\n} as const;\n\nexport type BuiltInEvaluator = keyof typeof BUILT_IN_EVALUATORS;\n\n/**\n * Extract metadata from a CodeQL query file\n */\nexport async function extractQueryMetadata(queryPath: string): Promise {\n try {\n const queryContent = readFileSync(queryPath, 'utf-8');\n const metadata: QueryMetadata = {};\n \n // Extract metadata from comments using regex patterns\n const kindMatch = queryContent.match(/@kind\\s+([^\\s]+)/);\n if (kindMatch) metadata.kind = kindMatch[1];\n \n const nameMatch = queryContent.match(/@name\\s+(.+)/);\n if (nameMatch) metadata.name = nameMatch[1].trim();\n \n const descMatch = queryContent.match(/@description\\s+(.+)/);\n if (descMatch) metadata.description = descMatch[1].trim();\n \n const idMatch = queryContent.match(/@id\\s+(.+)/);\n if (idMatch) metadata.id = idMatch[1].trim();\n \n const tagsMatch = queryContent.match(/@tags\\s+(.+)/);\n if (tagsMatch) {\n metadata.tags = tagsMatch[1].split(/\\s+/).filter(t => t.length > 0);\n }\n \n return metadata;\n } catch (error) {\n logger.error('Failed to extract query metadata:', error);\n return {};\n }\n}\n\n/**\n * JSON decoder - converts .bqrs to JSON format\n */\nexport async function evaluateWithJsonDecoder(\n bqrsPath: string, \n outputPath?: string\n): Promise {\n try {\n const result = await executeCodeQLCommand(\n 'bqrs decode',\n { format: 'json' },\n [bqrsPath]\n );\n \n if (!result.success) {\n return {\n success: false,\n error: `Failed to decode BQRS file: ${result.stderr || result.error}`\n };\n }\n \n const defaultOutputPath = outputPath || bqrsPath.replace('.bqrs', '.json');\n \n // Ensure output directory exists\n mkdirSync(dirname(defaultOutputPath), { recursive: true });\n \n // Write JSON results\n writeFileSync(defaultOutputPath, result.stdout);\n \n return {\n success: true,\n outputPath: defaultOutputPath,\n content: result.stdout\n };\n } catch (error) {\n return {\n success: false,\n error: `JSON evaluation failed: ${error}`\n };\n }\n}\n\n/**\n * CSV decoder - converts .bqrs to CSV format\n */\nexport async function evaluateWithCsvDecoder(\n bqrsPath: string,\n outputPath?: string\n): Promise {\n try {\n const result = await executeCodeQLCommand(\n 'bqrs decode',\n { format: 'csv' },\n [bqrsPath]\n );\n \n if (!result.success) {\n return {\n success: false,\n error: `Failed to decode BQRS file: ${result.stderr || result.error}`\n };\n }\n \n const defaultOutputPath = outputPath || bqrsPath.replace('.bqrs', '.csv');\n \n // Ensure output directory exists\n mkdirSync(dirname(defaultOutputPath), { recursive: true });\n \n // Write CSV results\n writeFileSync(defaultOutputPath, result.stdout);\n \n return {\n success: true,\n outputPath: defaultOutputPath,\n content: result.stdout\n };\n } catch (error) {\n return {\n success: false,\n error: `CSV evaluation failed: ${error}`\n };\n }\n}\n\n/**\n * Mermaid graph generator - converts @kind graph query results to mermaid diagrams\n */\nexport async function evaluateWithMermaidGraph(\n bqrsPath: string,\n queryPath: string,\n outputPath?: string\n): Promise {\n try {\n // First extract query metadata to confirm this is a graph query\n const metadata = await extractQueryMetadata(queryPath);\n \n if (metadata.kind !== 'graph') {\n logger.error(`Query is not a graph query (kind: ${metadata.kind}), mermaid-graph evaluation is only for @kind graph queries`);\n return {\n success: false,\n error: `Query is not a graph query (kind: ${metadata.kind}), mermaid-graph evaluation is only for @kind graph queries`\n };\n }\n \n // Decode the BQRS file to JSON first\n const jsonResult = await executeCodeQLCommand(\n 'bqrs decode',\n { format: 'json' },\n [bqrsPath]\n );\n \n if (!jsonResult.success) {\n return {\n success: false,\n error: `Failed to decode BQRS file: ${jsonResult.stderr || jsonResult.error}`\n };\n }\n \n // Parse the JSON results\n let queryResults;\n try {\n queryResults = JSON.parse(jsonResult.stdout);\n } catch (parseError) {\n return {\n success: false,\n error: `Failed to parse query results JSON: ${parseError}`\n };\n }\n \n // Generate mermaid diagram from graph results\n const mermaidContent = generateMermaidFromGraphResults(queryResults, metadata);\n \n const defaultOutputPath = outputPath || bqrsPath.replace('.bqrs', '.md');\n \n // Ensure output directory exists\n mkdirSync(dirname(defaultOutputPath), { recursive: true });\n \n // Write markdown file with mermaid diagram\n writeFileSync(defaultOutputPath, mermaidContent);\n \n return {\n success: true,\n outputPath: defaultOutputPath,\n content: mermaidContent\n };\n } catch (error) {\n return {\n success: false,\n error: `Mermaid graph evaluation failed: ${error}`\n };\n }\n}\n\n/**\n * Generate mermaid diagram from CodeQL graph query results\n */\nfunction generateMermaidFromGraphResults(queryResults: unknown, metadata: QueryMetadata): string {\n const queryName = sanitizeMarkdown(metadata.name || 'CodeQL Query Results');\n const queryDesc = sanitizeMarkdown(metadata.description || 'Graph visualization of CodeQL query results');\n \n let mermaidContent = `# ${queryName}\\n\\n${queryDesc}\\n\\n`;\n \n // Handle different result structures that CodeQL graph queries can produce\n if (!queryResults || typeof queryResults !== 'object') {\n mermaidContent += '```mermaid\\ngraph TD\\n A[No Results]\\n```\\n';\n return mermaidContent;\n }\n \n // Check if results have the expected structure for graph queries\n const tuples = queryResults.tuples || queryResults;\n \n if (!Array.isArray(tuples) || tuples.length === 0) {\n mermaidContent += '```mermaid\\ngraph TD\\n A[No Graph Data]\\n```\\n';\n return mermaidContent;\n }\n \n mermaidContent += '```mermaid\\ngraph TD\\n';\n \n // Track nodes and edges to avoid duplicates\n const nodes = new Set();\n const edges = new Set();\n \n // Process each tuple in the results\n tuples.forEach((tuple: unknown, index: number) => {\n if (Array.isArray(tuple) && tuple.length >= 2) {\n // Extract source and target from tuple\n const source = sanitizeNodeId(tuple[0]?.toString() || `node_${index}_0`);\n const target = sanitizeNodeId(tuple[1]?.toString() || `node_${index}_1`);\n const label = tuple[2]?.toString() || '';\n \n // Add nodes\n nodes.add(source);\n nodes.add(target);\n \n // Add edge\n const edgeId = `${source}_${target}`;\n if (!edges.has(edgeId)) {\n if (label) {\n mermaidContent += ` ${source} -->|${sanitizeLabel(label)}| ${target}\\n`;\n } else {\n mermaidContent += ` ${source} --> ${target}\\n`;\n }\n edges.add(edgeId);\n }\n } else if (typeof tuple === 'object' && tuple !== null) {\n // Handle object-based results\n const source = sanitizeNodeId(tuple.source?.toString() || tuple.from?.toString() || `node_${index}_src`);\n const target = sanitizeNodeId(tuple.target?.toString() || tuple.to?.toString() || `node_${index}_tgt`);\n const label = tuple.label?.toString() || tuple.relation?.toString() || '';\n \n nodes.add(source);\n nodes.add(target);\n \n const edgeId = `${source}_${target}`;\n if (!edges.has(edgeId)) {\n if (label) {\n mermaidContent += ` ${source} -->|${sanitizeLabel(label)}| ${target}\\n`;\n } else {\n mermaidContent += ` ${source} --> ${target}\\n`;\n }\n edges.add(edgeId);\n }\n }\n });\n \n // If no edges were created, create a simple diagram showing the first few nodes\n if (edges.size === 0 && nodes.size > 0) {\n const nodeArray = Array.from(nodes).slice(0, 10); // Limit to avoid clutter\n nodeArray.forEach((node, index) => {\n if (index === 0) {\n mermaidContent += ` ${node}[${sanitizeLabel(node)}]\\n`;\n } else {\n mermaidContent += ` ${nodeArray[0]} --> ${node}\\n`;\n }\n });\n }\n \n mermaidContent += '```\\n\\n';\n \n // Add statistics\n mermaidContent += `## Query Statistics\\n\\n`;\n mermaidContent += `- Total nodes: ${nodes.size}\\n`;\n mermaidContent += `- Total edges: ${edges.size}\\n`;\n mermaidContent += `- Total tuples processed: ${tuples.length}\\n`;\n \n return mermaidContent;\n}\n\n/**\n * Sanitize node IDs for mermaid compatibility\n */\nfunction sanitizeNodeId(id: string): string {\n return id\n .replace(/[^a-zA-Z0-9_]/g, '_')\n .replace(/^(\\d)/, 'n$1') // Prefix with 'n' if starts with number\n .substring(0, 50); // Limit length\n}\n\n/**\n * Sanitize labels for mermaid compatibility\n */\nfunction sanitizeLabel(label: string): string {\n return label\n .replace(/[|\"`<>\\n\\r\\t]/g, '') // Remove problematic characters including backticks, newlines, angle brackets\n .replace(/\\s+/g, ' ') // Normalize whitespace\n .trim()\n .substring(0, 30); // Limit length for readability\n}\n\n/**\n * Sanitize markdown content to prevent injection\n */\nfunction sanitizeMarkdown(content: string): string {\n return content\n .replace(/[<>\"`]/g, '') // Remove potentially dangerous characters\n .replace(/\\n/g, ' ') // Convert newlines to spaces\n .replace(/\\s+/g, ' ') // Normalize whitespace\n .trim()\n .substring(0, 100); // Limit length\n}\n\n/**\n * Main evaluation function that determines which evaluator to use\n */\nexport async function evaluateQueryResults(\n bqrsPath: string,\n queryPath: string,\n evaluationFunction?: string,\n outputPath?: string\n): Promise {\n try {\n // If no evaluation function specified, default to json-decode\n const evalFunc = evaluationFunction || 'json-decode';\n \n logger.info(`Evaluating query results with function: ${evalFunc}`);\n \n // Handle built-in evaluation functions\n switch (evalFunc) {\n case 'json-decode':\n return await evaluateWithJsonDecoder(bqrsPath, outputPath);\n \n case 'csv-decode':\n return await evaluateWithCsvDecoder(bqrsPath, outputPath);\n \n case 'mermaid-graph':\n return await evaluateWithMermaidGraph(bqrsPath, queryPath, outputPath);\n \n default:\n // Check if it's a path to a custom evaluation script\n if (isAbsolute(evalFunc)) {\n return await evaluateWithCustomScript(bqrsPath, queryPath, evalFunc, outputPath);\n } else {\n return {\n success: false,\n error: `Unknown evaluation function: ${evalFunc}. Available built-in functions: ${Object.keys(BUILT_IN_EVALUATORS).join(', ')}`\n };\n }\n }\n } catch (error) {\n return {\n success: false,\n error: `Query evaluation failed: ${error}`\n };\n }\n}\n\n/**\n * Execute custom evaluation script\n */\nasync function evaluateWithCustomScript(\n _bqrsPath: string,\n _queryPath: string,\n _scriptPath: string,\n _outputPath?: string\n): Promise {\n // TODO: Implement custom script execution\n // This would need to execute the script with bqrsPath and queryPath as arguments\n // and capture the output\n return {\n success: false,\n error: 'Custom evaluation scripts are not yet implemented'\n };\n}", "/**\n * Log directory management utilities for CodeQL query and test runs\n */\n\nimport { mkdirSync, existsSync } from 'fs';\nimport { join, resolve } from 'path';\nimport { randomBytes } from 'crypto';\nimport { getProjectTmpDir } from '../utils/temp-dir';\n\n/**\n * Ensure that a given path is within a base directory.\n * Throws an error if the path is outside the base directory.\n */\nfunction ensurePathWithinBase(baseDir: string, targetPath: string): string {\n const absBase = resolve(baseDir);\n const absTarget = resolve(targetPath);\n if (!absTarget.startsWith(absBase + '/') && absTarget !== absBase) {\n throw new Error(`Provided log directory is outside the allowed base directory: ${absBase}`);\n }\n return absTarget;\n}\n\n/**\n * Get or create a unique log directory for query/test runs\n * \n * @param logDir - Optional custom log directory from parameters\n * @returns Absolute path to the log directory\n */\nexport function getOrCreateLogDirectory(logDir?: string): string {\n // Use CODEQL_QUERY_LOG_DIR env var or default base\n const baseLogDir = process.env.CODEQL_QUERY_LOG_DIR || getProjectTmpDir('query-logs');\n\n // If logDir is explicitly provided, validate it is within baseLogDir\n if (logDir) {\n const absLogDir = ensurePathWithinBase(baseLogDir, logDir);\n if (!existsSync(absLogDir)) {\n mkdirSync(absLogDir, { recursive: true });\n }\n return absLogDir;\n }\n \n // Otherwise, use baseLogDir and create a unique subdirectory\n \n // Create base directory if it doesn't exist\n if (!existsSync(baseLogDir)) {\n mkdirSync(baseLogDir, { recursive: true });\n }\n \n // Generate unique subdirectory with timestamp and random ID\n const timestamp = new Date().toISOString().replace(/[:.]/g, '-');\n const uniqueId = randomBytes(4).toString('hex');\n const uniqueLogDir = join(baseLogDir, `query-run-${timestamp}-${uniqueId}`);\n \n mkdirSync(uniqueLogDir, { recursive: true });\n \n return uniqueLogDir;\n}\n", "/**\n * CodeQL BQRS info tool\n */\n\nimport { z } from 'zod';\nimport { CLIToolDefinition, createCodeQLSchemas, createBQRSResultProcessor } from '../../lib/cli-tool-registry';\n\nexport const codeqlBqrsInfoTool: CLIToolDefinition = {\n name: 'codeql_bqrs_info',\n description: 'Get metadata and information about BQRS result files',\n command: 'codeql',\n subcommand: 'bqrs info',\n inputSchema: {\n files: z.array(z.string()).describe('BQRS file(s) to examine'),\n verbose: createCodeQLSchemas.verbose(),\n additionalArgs: createCodeQLSchemas.additionalArgs()\n },\n examples: [\n 'codeql bqrs info results.bqrs',\n 'codeql bqrs info --verbose results.bqrs'\n ],\n resultProcessor: createBQRSResultProcessor()\n};", "/**\n * CodeQL BQRS interpret tool\n */\n\nimport { z } from 'zod';\nimport { CLIToolDefinition, createCodeQLSchemas, createBQRSResultProcessor } from '../../lib/cli-tool-registry';\n\nexport const codeqlBqrsInterpretTool: CLIToolDefinition = {\n name: 'codeql_bqrs_interpret',\n description: 'Interpret BQRS result files according to query metadata and generate output in specified formats (CSV, SARIF, graph formats)',\n command: 'codeql',\n subcommand: 'bqrs interpret',\n inputSchema: {\n file: z.string().describe('The BQRS file to interpret'),\n format: z.enum(['csv', 'sarif-latest', 'sarifv2.1.0', 'graphtext', 'dgml', 'dot'])\n .describe('Output format: csv (comma-separated), sarif-latest/sarifv2.1.0 (SARIF), graphtext/dgml/dot (graph formats, only for @kind graph queries)'),\n output: createCodeQLSchemas.output(),\n t: z.array(z.string())\n .describe('Query metadata key=value pairs. At least \"kind\" and \"id\" must be specified (e.g., [\"kind=graph\", \"id=js/print-ast\"])'),\n 'max-paths': z.number().optional()\n .describe('Maximum number of paths to produce for each alert with paths (default: 4)'),\n 'sarif-add-file-contents': z.boolean().optional()\n .describe('[SARIF only] Include full file contents for all files referenced in results'),\n 'sarif-add-snippets': z.boolean().optional()\n .describe('[SARIF only] Include code snippets for each location with context'),\n 'sarif-group-rules-by-pack': z.boolean().optional()\n .describe('[SARIF only] Place rule objects under their QL pack in tool.extensions property'),\n 'sarif-multicause-markdown': z.boolean().optional()\n .describe('[SARIF only] Include multi-cause alerts as Markdown-formatted lists'),\n 'sarif-category': z.string().optional()\n .describe('[SARIF only] Category for this analysis (distinguishes multiple analyses on same code)'),\n 'csv-location-format': z.enum(['uri', 'line-column', 'offset-length']).optional()\n .describe('[CSV only] Format for locations in CSV output (default: line-column)'),\n 'dot-location-url-format': z.string().optional()\n .describe('[DOT only] Format string for file location URLs (placeholders: {path}, {start:line}, {start:column}, {end:line}, {end:column}, {offset}, {length})'),\n threads: z.number().optional()\n .describe('Number of threads for computing paths (0 = one per core, -N = leave N cores unused)'),\n 'column-kind': z.enum(['utf8', 'utf16', 'utf32', 'bytes']).optional()\n .describe('[SARIF only] Column kind for interpreting location columns'),\n 'unicode-new-lines': z.boolean().optional()\n .describe('[SARIF only] Whether unicode newlines (U+2028, U+2029) are considered as newlines'),\n verbose: createCodeQLSchemas.verbose(),\n additionalArgs: createCodeQLSchemas.additionalArgs()\n },\n examples: [\n 'codeql bqrs interpret --format=sarif-latest --output=results.sarif -t kind=problem -t id=js/sql-injection results.bqrs',\n 'codeql bqrs interpret --format=graphtext --output=ast.txt -t kind=graph -t id=js/print-ast results.bqrs',\n 'codeql bqrs interpret --format=csv --csv-location-format=line-column --output=results.csv -t kind=problem -t id=js/xss results.bqrs',\n 'codeql bqrs interpret --format=dot --output=graph.dot -t kind=graph -t id=java/call-graph results.bqrs',\n 'codeql bqrs interpret --format=sarif-latest --sarif-add-snippets --sarif-category=security --output=results.sarif -t kind=path-problem -t id=go/path-injection results.bqrs'\n ],\n resultProcessor: createBQRSResultProcessor()\n};\n", "/**\n * CodeQL database analyze tool\n */\n\nimport { z } from 'zod';\nimport { CLIToolDefinition } from '../../lib/cli-tool-registry';\n\nexport const codeqlDatabaseAnalyzeTool: CLIToolDefinition = {\n name: 'codeql_database_analyze',\n description: 'Run queries or query suites against CodeQL databases',\n command: 'codeql',\n subcommand: 'database analyze',\n inputSchema: {\n database: z.string().describe('Path to the CodeQL database'),\n queries: z.string().describe('Queries or query suite to run'),\n output: z.string().optional().describe('Output file path'),\n format: z.enum(['csv', 'json', 'sarif-latest', 'sarifv2.1.0']).optional()\n .describe('Output format for results'),\n 'download-location': z.string().optional()\n .describe('Location to download missing dependencies'),\n threads: z.number().optional().describe('Number of threads to use'),\n ram: z.number().optional().describe('Amount of RAM to use (MB)'),\n timeout: z.number().optional().describe('Timeout in seconds'),\n logDir: z.string().optional()\n .describe('Custom directory for analysis execution logs (overrides CODEQL_QUERY_LOG_DIR environment variable). If not provided, uses CODEQL_QUERY_LOG_DIR or defaults to .tmp/query-logs/'),\n 'evaluator-log': z.string().optional()\n .describe('Path to save evaluator log. If not provided and logDir is set, defaults to /evaluator-log.jsonl'),\n 'tuple-counting': z.boolean().optional()\n .describe('Display tuple counts for each evaluation step in evaluator logs'),\n 'evaluator-log-level': z.number().min(1).max(5).optional()\n .describe('Evaluator log verbosity level (1-5, default 5)'),\n verbose: z.boolean().optional().describe('Enable verbose output'),\n additionalArgs: z.array(z.string()).optional().describe('Additional command-line arguments')\n },\n examples: [\n 'codeql database analyze mydb queries.qls --format=sarif-latest --output=results.sarif',\n 'codeql database analyze mydb codeql/java-queries --format=csv',\n 'codeql database analyze mydb queries.qls --format=sarif-latest --output=results.sarif --log-dir=/path/to/logs --tuple-counting'\n ]\n};", "/**\n * CodeQL database create tool\n */\n\nimport { z } from 'zod';\nimport { CLIToolDefinition, createDatabaseResultProcessor } from '../../lib/cli-tool-registry';\n\nexport const codeqlDatabaseCreateTool: CLIToolDefinition = {\n name: 'codeql_database_create',\n description: 'Create a CodeQL database from source code',\n command: 'codeql',\n subcommand: 'database create',\n inputSchema: {\n database: z.string().describe('Database path/name to create'),\n language: z.string().optional().describe('Programming language(s) to extract'),\n 'source-root': z.string().optional().describe('Root directory of source code'),\n command: z.string().optional().describe('Build command for compiled languages'),\n 'build-mode': z.enum(['none', 'autobuild', 'manual']).optional()\n .describe('Build mode: none (interpreted langs), autobuild, or manual'),\n threads: z.number().optional().describe('Number of threads to use'),\n ram: z.number().optional().describe('Amount of RAM to use (MB)'),\n verbose: z.boolean().optional().describe('Enable verbose output'),\n overwrite: z.boolean().optional().describe('Overwrite existing database if it exists'),\n 'no-cleanup': z.boolean().optional().describe('Skip database cleanup after finalization'),\n additionalArgs: z.array(z.string()).optional().describe('Additional command-line arguments')\n },\n examples: [\n 'codeql database create --language=java --source-root=/path/to/project mydb',\n 'codeql database create --language=cpp --command=\"make all\" mydb',\n 'codeql database create --language=python,javascript mydb'\n ],\n resultProcessor: createDatabaseResultProcessor()\n};", "/**\n * CodeQL find class position tool\n * \n * Inspired by JordyZomer/codeql-mcp repository:\n * - https://github.com/JordyZomer/codeql-mcp/blob/main/server.py\n * - https://github.com/JordyZomer/codeql-mcp/blob/main/codeqlclient.py\n */\n\nimport { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport { z } from 'zod';\nimport { readFile } from 'fs/promises';\nimport { logger } from '../../utils/logger';\n\nexport interface ClassPosition {\n start_line: number;\n start_col: number;\n end_line: number;\n end_col: number;\n}\n\n/**\n * Find the 1-based position of a class name identifier in a QL file.\n * Returns: { start_line, start_col, end_line, end_col }\n */\nexport async function findClassPosition(filepath: string, className: string): Promise {\n try {\n const content = await readFile(filepath, 'utf-8');\n const lines = content.split('\\n');\n\n for (let i = 0; i < lines.length; i++) {\n const line = lines[i];\n // Match class definition with the specific class name\n const classNameRegex = new RegExp(`\\\\bclass\\\\s+(${className.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&')})\\\\b`);\n const match = classNameRegex.exec(line);\n \n if (match) {\n const start_line = i + 1; // 1-based line numbering\n // The class name is in capture group 1\n const classNameStart = match.index + match[0].indexOf(match[1]);\n const start_col = classNameStart + 1; // 1-based column numbering\n const end_col = start_col + className.length - 1; // end_col is inclusive\n \n return {\n start_line,\n start_col,\n end_line: start_line,\n end_col\n };\n }\n }\n\n throw new Error(`Class name '${className}' not found in file: ${filepath}`);\n } catch (error) {\n if (error instanceof Error && error.message.includes('not found in file')) {\n throw error;\n }\n throw new Error(`Failed to read or parse file ${filepath}: ${error instanceof Error ? error.message : 'Unknown error'}`);\n }\n}\n\n/**\n * Register the find class position tool with the MCP server\n */\nexport function registerFindClassPositionTool(server: McpServer): void {\n server.tool(\n 'find_class_position',\n 'Finds startline, startcol, endline endcol of a class for quickeval',\n {\n file: z.string().describe('Path to the .ql file to search'),\n name: z.string().describe('Name of the class to find'),\n },\n async ({ file, name }) => {\n try {\n const position = await findClassPosition(file, name);\n return {\n content: [{ type: 'text', text: JSON.stringify(position, null, 2) }],\n };\n } catch (error) {\n logger.error('Error finding class position:', error);\n return {\n content: [\n {\n type: 'text',\n text: `Error: ${error instanceof Error ? error.message : 'Unknown error'}`,\n },\n ],\n isError: true,\n };\n }\n }\n );\n}", "/**\n * CodeQL find predicate position tool\n * \n * Inspired by JordyZomer/codeql-mcp repository:\n * - https://github.com/JordyZomer/codeql-mcp/blob/main/server.py\n * - https://github.com/JordyZomer/codeql-mcp/blob/main/codeqlclient.py\n */\n\nimport { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport { z } from 'zod';\nimport { readFile } from 'fs/promises';\nimport { logger } from '../../utils/logger';\n\nexport interface PredicatePosition {\n start_line: number;\n start_col: number;\n end_line: number;\n end_col: number;\n}\n\n/**\n * Find the 1-based position of a predicate name in a QL file.\n * Supports: \n * - predicate name(...) - predicates with no return type\n * - Type name(...) - predicates with return type (e.g., string foo())\n * - name(...) (inside class) - member predicates\n * Returns: { start_line, start_col, end_line, end_col }\n */\nexport async function findPredicatePosition(filepath: string, predicateName: string): Promise {\n try {\n const content = await readFile(filepath, 'utf-8');\n const lines = content.split('\\n');\n const escapedName = predicateName.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&');\n\n for (let i = 0; i < lines.length; i++) {\n const line = lines[i];\n \n // Match predicate definition with the specific predicate name\n // Pattern 1: predicate name(...)\n const predicateKeywordRegex = new RegExp(`\\\\bpredicate\\\\s+(${escapedName})\\\\s*\\\\(`);\n let match = predicateKeywordRegex.exec(line);\n \n // Pattern 2: Type name(...) - predicates with return type\n // Matches: string foo(), int bar(), MyClass baz(), etc.\n // Must start at beginning of line (with optional whitespace) or after certain keywords\n if (!match) {\n const returnTypeRegex = new RegExp(`(?:^|\\\\s)(?:abstract\\\\s+)?(?:cached\\\\s+)?(?:private\\\\s+)?(?:deprecated\\\\s+)?(?:\\\\w+)\\\\s+(${escapedName})\\\\s*\\\\(`);\n match = returnTypeRegex.exec(line);\n }\n \n if (match) {\n const start_line = i + 1; // 1-based line numbering\n // The predicate name is in capture group 1\n const predicateNameStart = match.index + match[0].indexOf(match[1]);\n const start_col = predicateNameStart + 1; // 1-based column numbering\n const end_col = start_col + predicateName.length - 1; // end_col is inclusive\n \n return {\n start_line,\n start_col,\n end_line: start_line,\n end_col\n };\n }\n }\n\n throw new Error(`Predicate name '${predicateName}' not found in file: ${filepath}`);\n } catch (error) {\n if (error instanceof Error && error.message.includes('not found in file')) {\n throw error;\n }\n throw new Error(`Failed to read or parse file ${filepath}: ${error instanceof Error ? error.message : 'Unknown error'}`);\n }\n}\n\n/**\n * Register the find predicate position tool with the MCP server\n */\nexport function registerFindPredicatePositionTool(server: McpServer): void {\n server.tool(\n 'find_predicate_position',\n 'Finds startline, startcol, endline endcol of a predicate for quickeval',\n {\n file: z.string().describe('Path to the .ql file to search'),\n name: z.string().describe('Name of the predicate to find'),\n },\n async ({ file, name }) => {\n try {\n const position = await findPredicatePosition(file, name);\n return {\n content: [{ type: 'text', text: JSON.stringify(position, null, 2) }],\n };\n } catch (error) {\n logger.error('Error finding predicate position:', error);\n return {\n content: [\n {\n type: 'text',\n text: `Error: ${error instanceof Error ? error.message : 'Unknown error'}`,\n },\n ],\n isError: true,\n };\n }\n }\n );\n}", "/**\n * CodeQL find query files tool\n * Discovers and tracks all files related to a CodeQL query\n */\n\nimport { z } from 'zod';\nimport { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport { findCodeQLQueryFiles } from '../../lib/query-file-finder';\nimport { logger } from '../../utils/logger';\n\n/**\n * Register the find_codeql_query_files tool\n */\nexport function registerFindCodeQLQueryFilesTool(server: McpServer): void {\n server.tool(\n 'find_codeql_query_files',\n 'Find and track all files and directories related to a CodeQL query, including resolved metadata',\n {\n queryPath: z.string().describe('Path to the CodeQL query file (.ql)'),\n language: z.string().optional().describe('Programming language (optional, will be inferred if not provided)'),\n resolveMetadata: z.boolean().optional().describe('Whether to resolve query metadata (default: true)')\n },\n async ({ queryPath, language, resolveMetadata }) => {\n try {\n const result = await findCodeQLQueryFiles(\n queryPath,\n language,\n resolveMetadata !== false // Default to true if not specified\n );\n\n return {\n content: [{ type: 'text', text: JSON.stringify(result, null, 2) }]\n };\n } catch (error) {\n logger.error('Error finding CodeQL query files:', error);\n return {\n content: [\n {\n type: 'text',\n text: `Error: ${error instanceof Error ? error.message : 'Unknown error'}`\n }\n ],\n isError: true\n };\n }\n }\n );\n}\n", "/**\n * CodeQL query file finder utilities\n * Handles discovery and tracking of query-related files and directories\n */\n\nimport * as fs from 'fs';\nimport * as path from 'path';\nimport * as yaml from 'js-yaml';\nimport { QueryFileInfo, QueryFilesResult } from '../types/codeql';\nimport { resolveQueryMetadata } from './metadata-resolver';\n\n// Supported CodeQL languages and their file extensions (alphabetically ordered)\nconst LANGUAGE_EXTENSIONS: Record = {\n actions: 'yml',\n cpp: 'cpp',\n csharp: 'cs',\n go: 'go',\n java: 'java',\n javascript: 'js',\n python: 'py',\n ruby: 'rb',\n swift: 'swift',\n typescript: 'ts'\n};\n\nconst KNOWN_LANGUAGES = Object.keys(LANGUAGE_EXTENSIONS);\n\n/**\n * Get the file extension for test code based on language\n */\nfunction getLanguageExtension(language: string): string {\n return LANGUAGE_EXTENSIONS[language.toLowerCase()] || 'txt';\n}\n\n/**\n * Infer the language from the query file's directory structure\n */\nfunction inferLanguageFromPath(queryPath: string): string {\n const parts = queryPath.split(path.sep);\n\n for (const part of parts) {\n if (KNOWN_LANGUAGES.includes(part.toLowerCase())) {\n return part.toLowerCase();\n }\n }\n\n // Default fallback\n return 'unknown';\n}\n\n/**\n * Find the nearest qlpack.yml or codeql-pack.yml file by walking up the directory tree\n */\nfunction findNearestQlpack(startPath: string): string | null {\n let currentPath = startPath;\n const root = path.parse(currentPath).root;\n\n while (currentPath !== root) {\n // Check for codeql-pack.yml first (newer format), then qlpack.yml\n for (const packFile of ['codeql-pack.yml', 'qlpack.yml']) {\n const packPath = path.join(currentPath, packFile);\n if (fs.existsSync(packPath) && fs.statSync(packPath).isFile()) {\n return packPath;\n }\n }\n currentPath = path.dirname(currentPath);\n }\n\n return null;\n}\n\n/**\n * Read and parse qlpack.yml file\n */\nfunction readQlpackMetadata(qlpackPath: string): Record | null {\n try {\n const content = fs.readFileSync(qlpackPath, 'utf-8');\n const parsed = yaml.load(content) as Record;\n return parsed;\n } catch (_error) {\n // If we can't parse it, return null rather than failing\n return null;\n }\n}\n\n/**\n * Check if a file exists and return QueryFileInfo\n */\nfunction checkFile(filePath: string): QueryFileInfo {\n try {\n const exists = fs.existsSync(filePath) && fs.statSync(filePath).isFile();\n return {\n exists,\n path: filePath // Always return path, whether it exists or not\n };\n } catch {\n return {\n exists: false,\n path: filePath // Return the path even on error\n };\n }\n}\n\n/**\n * Check if a directory exists and return QueryFileInfo\n */\nfunction checkDirectory(dirPath: string): QueryFileInfo {\n try {\n const exists = fs.existsSync(dirPath) && fs.statSync(dirPath).isDirectory();\n return {\n exists,\n path: dirPath // Always return path, whether it exists or not\n };\n } catch {\n return {\n exists: false,\n path: dirPath // Return the path even on error\n };\n }\n}\n\n/**\n * Find all test code files in the test directory\n */\nfunction findTestCodeFiles(testDir: string, queryName: string, language: string): string[] {\n if (!fs.existsSync(testDir)) {\n return [];\n }\n\n try {\n const files = fs.readdirSync(testDir);\n const languageExt = getLanguageExtension(language);\n const testFiles: string[] = [];\n\n // Look for files matching the query name or other test code files\n const allValidExtensions = [...new Set([...Object.values(LANGUAGE_EXTENSIONS), 'yaml'])]; // Include yaml as alias for yml\n\n for (const file of files) {\n const filePath = path.join(testDir, file);\n const stat = fs.statSync(filePath);\n\n if (stat.isFile()) {\n // Include the primary test file matching query name\n if (file === `${queryName}.${languageExt}`) {\n testFiles.push(filePath);\n }\n // Include other code files (but not .qlref, .expected, .actual files)\n else if (!file.endsWith('.qlref') && !file.endsWith('.expected') && !file.endsWith('.actual')) {\n const ext = path.extname(file).slice(1);\n if (ext === languageExt || allValidExtensions.includes(ext)) {\n testFiles.push(filePath);\n }\n }\n }\n }\n\n return testFiles;\n } catch {\n return [];\n }\n}\n\n/**\n * Find CodeQL query files and directories based on a query file path\n * Optionally resolves metadata if the query file exists\n */\nexport async function findCodeQLQueryFiles(\n queryFilePath: string,\n language?: string,\n resolveMetadata: boolean = true\n): Promise {\n // Resolve absolute path\n const absoluteQueryPath = path.resolve(queryFilePath);\n\n // Extract query name and directory\n const queryName = path.basename(absoluteQueryPath, '.ql');\n const queryDir = path.dirname(absoluteQueryPath);\n\n // Infer language if not provided\n const detectedLanguage = language || inferLanguageFromPath(absoluteQueryPath);\n\n // Check query file itself\n const queryPath = checkFile(absoluteQueryPath);\n const queryDirectory = checkDirectory(queryDir);\n\n // Check for documentation files\n const mdPath = path.join(queryDir, `${queryName}.md`);\n const qhelpPath = path.join(queryDir, `${queryName}.qhelp`);\n const mdInfo = checkFile(mdPath);\n const qhelpInfo = checkFile(qhelpPath);\n\n const documentationPath: QueryFileInfo = mdInfo.exists ? mdInfo : (qhelpInfo.exists ? qhelpInfo : {\n exists: false,\n path: mdPath // Suggest .md as the default\n });\n\n // Check for specification file\n const qspecPath = path.join(queryDir, `${queryName}.qspec`);\n const specificationPath = checkFile(qspecPath);\n\n // Determine test directory\n // Pattern: if query is in .../src/QueryName/, test should be in .../test/QueryName/\n let testDir: string;\n if (queryDir.includes(`${path.sep}src${path.sep}`)) {\n // Find the last occurrence of /src/ and replace it with /test/\n const parts = queryDir.split(path.sep);\n const srcIndex = parts.lastIndexOf('src');\n if (srcIndex !== -1) {\n parts[srcIndex] = 'test';\n testDir = parts.join(path.sep);\n } else {\n // Fallback in case split didn't find it\n testDir = path.join(path.dirname(queryDir), 'test', queryName);\n }\n } else {\n // Fallback: if not in src directory, construct test dir based on parent\n testDir = path.join(path.dirname(queryDir), 'test', queryName);\n }\n const testDirectory = checkDirectory(testDir);\n\n // Check for .qlref file\n const qlrefPath = path.join(testDir, `${queryName}.qlref`);\n const qlrefInfo = checkFile(qlrefPath);\n\n // Find test code files\n const testCodePaths = findTestCodeFiles(testDir, queryName, detectedLanguage);\n\n // Check for expected results\n const expectedPath = path.join(testDir, `${queryName}.expected`);\n const expectedResultsPath = checkFile(expectedPath);\n\n // Check for actual results\n const actualPath = path.join(testDir, `${queryName}.actual`);\n const actualResultsPath = checkFile(actualPath);\n\n // Check for test database\n const testprojPath = path.join(testDir, `${queryName}.testproj`);\n const testDatabasePath = checkDirectory(testprojPath);\n\n // Determine missing files\n const missingFiles: string[] = [];\n if (!queryPath.exists) missingFiles.push(queryPath.path);\n if (!documentationPath.exists) missingFiles.push(documentationPath.path);\n if (!specificationPath.exists) missingFiles.push(specificationPath.path);\n if (!testDirectory.exists) missingFiles.push(testDirectory.path);\n if (!qlrefInfo.exists) missingFiles.push(qlrefInfo.path);\n if (testCodePaths.length === 0) missingFiles.push(path.join(testDir, `${queryName}.${getLanguageExtension(detectedLanguage)}`));\n if (!expectedResultsPath.exists) missingFiles.push(expectedResultsPath.path);\n\n const allFilesExist = missingFiles.length === 0;\n\n // Resolve metadata if requested and query file exists\n let metadata: { [key: string]: string | string[] } | undefined;\n if (resolveMetadata && queryPath.exists) {\n const resolvedMetadata = await resolveQueryMetadata(absoluteQueryPath);\n if (resolvedMetadata) {\n metadata = resolvedMetadata;\n }\n }\n\n // Resolve pack metadata and directories by finding the nearest qlpack.yml files\n let packMetadata: Record | undefined;\n const queryPackPath = findNearestQlpack(queryDir);\n const queryPackDir = queryPackPath ? path.dirname(queryPackPath) : queryDir;\n if (queryPackPath) {\n const parsed = readQlpackMetadata(queryPackPath);\n if (parsed) {\n packMetadata = parsed;\n }\n }\n\n // Find pack directory for test files\n const testPackPath = findNearestQlpack(testDir);\n const testPackDir = testPackPath ? path.dirname(testPackPath) : testDir;\n\n return {\n queryName,\n language: detectedLanguage,\n\n allFilesExist,\n\n files: {\n query: {\n dir: queryDirectory.path,\n doc: path.basename(documentationPath.path),\n packDir: queryPackDir,\n query: path.basename(queryPath.path),\n spec: path.basename(specificationPath.path)\n },\n test: {\n actual: path.basename(actualResultsPath.path),\n dir: testDirectory.path,\n expected: path.basename(expectedResultsPath.path),\n packDir: testPackDir,\n qlref: path.basename(qlrefInfo.path),\n testCode: testCodePaths,\n testDatabaseDir: testDatabasePath.path\n }\n },\n\n metadata,\n\n missingFiles,\n\n packMetadata,\n\n status: {\n actualResultsExist: actualResultsPath.exists,\n documentationExists: documentationPath.exists,\n expectedResultsExist: expectedResultsPath.exists,\n hasTestCode: testCodePaths.length > 0,\n qlrefExists: qlrefInfo.exists,\n queryExists: queryPath.exists,\n specificationExists: specificationPath.exists,\n testDatabaseDirExists: testDatabasePath.exists,\n testDirectoryExists: testDirectory.exists\n }\n };\n}\n", "\n/*! js-yaml 4.1.1 https://github.com/nodeca/js-yaml @license MIT */\nfunction isNothing(subject) {\n return (typeof subject === 'undefined') || (subject === null);\n}\n\n\nfunction isObject(subject) {\n return (typeof subject === 'object') && (subject !== null);\n}\n\n\nfunction toArray(sequence) {\n if (Array.isArray(sequence)) return sequence;\n else if (isNothing(sequence)) return [];\n\n return [ sequence ];\n}\n\n\nfunction extend(target, source) {\n var index, length, key, sourceKeys;\n\n if (source) {\n sourceKeys = Object.keys(source);\n\n for (index = 0, length = sourceKeys.length; index < length; index += 1) {\n key = sourceKeys[index];\n target[key] = source[key];\n }\n }\n\n return target;\n}\n\n\nfunction repeat(string, count) {\n var result = '', cycle;\n\n for (cycle = 0; cycle < count; cycle += 1) {\n result += string;\n }\n\n return result;\n}\n\n\nfunction isNegativeZero(number) {\n return (number === 0) && (Number.NEGATIVE_INFINITY === 1 / number);\n}\n\n\nvar isNothing_1 = isNothing;\nvar isObject_1 = isObject;\nvar toArray_1 = toArray;\nvar repeat_1 = repeat;\nvar isNegativeZero_1 = isNegativeZero;\nvar extend_1 = extend;\n\nvar common = {\n\tisNothing: isNothing_1,\n\tisObject: isObject_1,\n\ttoArray: toArray_1,\n\trepeat: repeat_1,\n\tisNegativeZero: isNegativeZero_1,\n\textend: extend_1\n};\n\n// YAML error class. http://stackoverflow.com/questions/8458984\n\n\nfunction formatError(exception, compact) {\n var where = '', message = exception.reason || '(unknown reason)';\n\n if (!exception.mark) return message;\n\n if (exception.mark.name) {\n where += 'in \"' + exception.mark.name + '\" ';\n }\n\n where += '(' + (exception.mark.line + 1) + ':' + (exception.mark.column + 1) + ')';\n\n if (!compact && exception.mark.snippet) {\n where += '\\n\\n' + exception.mark.snippet;\n }\n\n return message + ' ' + where;\n}\n\n\nfunction YAMLException$1(reason, mark) {\n // Super constructor\n Error.call(this);\n\n this.name = 'YAMLException';\n this.reason = reason;\n this.mark = mark;\n this.message = formatError(this, false);\n\n // Include stack trace in error object\n if (Error.captureStackTrace) {\n // Chrome and NodeJS\n Error.captureStackTrace(this, this.constructor);\n } else {\n // FF, IE 10+ and Safari 6+. Fallback for others\n this.stack = (new Error()).stack || '';\n }\n}\n\n\n// Inherit from Error\nYAMLException$1.prototype = Object.create(Error.prototype);\nYAMLException$1.prototype.constructor = YAMLException$1;\n\n\nYAMLException$1.prototype.toString = function toString(compact) {\n return this.name + ': ' + formatError(this, compact);\n};\n\n\nvar exception = YAMLException$1;\n\n// get snippet for a single line, respecting maxLength\nfunction getLine(buffer, lineStart, lineEnd, position, maxLineLength) {\n var head = '';\n var tail = '';\n var maxHalfLength = Math.floor(maxLineLength / 2) - 1;\n\n if (position - lineStart > maxHalfLength) {\n head = ' ... ';\n lineStart = position - maxHalfLength + head.length;\n }\n\n if (lineEnd - position > maxHalfLength) {\n tail = ' ...';\n lineEnd = position + maxHalfLength - tail.length;\n }\n\n return {\n str: head + buffer.slice(lineStart, lineEnd).replace(/\\t/g, '\u2192') + tail,\n pos: position - lineStart + head.length // relative position\n };\n}\n\n\nfunction padStart(string, max) {\n return common.repeat(' ', max - string.length) + string;\n}\n\n\nfunction makeSnippet(mark, options) {\n options = Object.create(options || null);\n\n if (!mark.buffer) return null;\n\n if (!options.maxLength) options.maxLength = 79;\n if (typeof options.indent !== 'number') options.indent = 1;\n if (typeof options.linesBefore !== 'number') options.linesBefore = 3;\n if (typeof options.linesAfter !== 'number') options.linesAfter = 2;\n\n var re = /\\r?\\n|\\r|\\0/g;\n var lineStarts = [ 0 ];\n var lineEnds = [];\n var match;\n var foundLineNo = -1;\n\n while ((match = re.exec(mark.buffer))) {\n lineEnds.push(match.index);\n lineStarts.push(match.index + match[0].length);\n\n if (mark.position <= match.index && foundLineNo < 0) {\n foundLineNo = lineStarts.length - 2;\n }\n }\n\n if (foundLineNo < 0) foundLineNo = lineStarts.length - 1;\n\n var result = '', i, line;\n var lineNoLength = Math.min(mark.line + options.linesAfter, lineEnds.length).toString().length;\n var maxLineLength = options.maxLength - (options.indent + lineNoLength + 3);\n\n for (i = 1; i <= options.linesBefore; i++) {\n if (foundLineNo - i < 0) break;\n line = getLine(\n mark.buffer,\n lineStarts[foundLineNo - i],\n lineEnds[foundLineNo - i],\n mark.position - (lineStarts[foundLineNo] - lineStarts[foundLineNo - i]),\n maxLineLength\n );\n result = common.repeat(' ', options.indent) + padStart((mark.line - i + 1).toString(), lineNoLength) +\n ' | ' + line.str + '\\n' + result;\n }\n\n line = getLine(mark.buffer, lineStarts[foundLineNo], lineEnds[foundLineNo], mark.position, maxLineLength);\n result += common.repeat(' ', options.indent) + padStart((mark.line + 1).toString(), lineNoLength) +\n ' | ' + line.str + '\\n';\n result += common.repeat('-', options.indent + lineNoLength + 3 + line.pos) + '^' + '\\n';\n\n for (i = 1; i <= options.linesAfter; i++) {\n if (foundLineNo + i >= lineEnds.length) break;\n line = getLine(\n mark.buffer,\n lineStarts[foundLineNo + i],\n lineEnds[foundLineNo + i],\n mark.position - (lineStarts[foundLineNo] - lineStarts[foundLineNo + i]),\n maxLineLength\n );\n result += common.repeat(' ', options.indent) + padStart((mark.line + i + 1).toString(), lineNoLength) +\n ' | ' + line.str + '\\n';\n }\n\n return result.replace(/\\n$/, '');\n}\n\n\nvar snippet = makeSnippet;\n\nvar TYPE_CONSTRUCTOR_OPTIONS = [\n 'kind',\n 'multi',\n 'resolve',\n 'construct',\n 'instanceOf',\n 'predicate',\n 'represent',\n 'representName',\n 'defaultStyle',\n 'styleAliases'\n];\n\nvar YAML_NODE_KINDS = [\n 'scalar',\n 'sequence',\n 'mapping'\n];\n\nfunction compileStyleAliases(map) {\n var result = {};\n\n if (map !== null) {\n Object.keys(map).forEach(function (style) {\n map[style].forEach(function (alias) {\n result[String(alias)] = style;\n });\n });\n }\n\n return result;\n}\n\nfunction Type$1(tag, options) {\n options = options || {};\n\n Object.keys(options).forEach(function (name) {\n if (TYPE_CONSTRUCTOR_OPTIONS.indexOf(name) === -1) {\n throw new exception('Unknown option \"' + name + '\" is met in definition of \"' + tag + '\" YAML type.');\n }\n });\n\n // TODO: Add tag format check.\n this.options = options; // keep original options in case user wants to extend this type later\n this.tag = tag;\n this.kind = options['kind'] || null;\n this.resolve = options['resolve'] || function () { return true; };\n this.construct = options['construct'] || function (data) { return data; };\n this.instanceOf = options['instanceOf'] || null;\n this.predicate = options['predicate'] || null;\n this.represent = options['represent'] || null;\n this.representName = options['representName'] || null;\n this.defaultStyle = options['defaultStyle'] || null;\n this.multi = options['multi'] || false;\n this.styleAliases = compileStyleAliases(options['styleAliases'] || null);\n\n if (YAML_NODE_KINDS.indexOf(this.kind) === -1) {\n throw new exception('Unknown kind \"' + this.kind + '\" is specified for \"' + tag + '\" YAML type.');\n }\n}\n\nvar type = Type$1;\n\n/*eslint-disable max-len*/\n\n\n\n\n\nfunction compileList(schema, name) {\n var result = [];\n\n schema[name].forEach(function (currentType) {\n var newIndex = result.length;\n\n result.forEach(function (previousType, previousIndex) {\n if (previousType.tag === currentType.tag &&\n previousType.kind === currentType.kind &&\n previousType.multi === currentType.multi) {\n\n newIndex = previousIndex;\n }\n });\n\n result[newIndex] = currentType;\n });\n\n return result;\n}\n\n\nfunction compileMap(/* lists... */) {\n var result = {\n scalar: {},\n sequence: {},\n mapping: {},\n fallback: {},\n multi: {\n scalar: [],\n sequence: [],\n mapping: [],\n fallback: []\n }\n }, index, length;\n\n function collectType(type) {\n if (type.multi) {\n result.multi[type.kind].push(type);\n result.multi['fallback'].push(type);\n } else {\n result[type.kind][type.tag] = result['fallback'][type.tag] = type;\n }\n }\n\n for (index = 0, length = arguments.length; index < length; index += 1) {\n arguments[index].forEach(collectType);\n }\n return result;\n}\n\n\nfunction Schema$1(definition) {\n return this.extend(definition);\n}\n\n\nSchema$1.prototype.extend = function extend(definition) {\n var implicit = [];\n var explicit = [];\n\n if (definition instanceof type) {\n // Schema.extend(type)\n explicit.push(definition);\n\n } else if (Array.isArray(definition)) {\n // Schema.extend([ type1, type2, ... ])\n explicit = explicit.concat(definition);\n\n } else if (definition && (Array.isArray(definition.implicit) || Array.isArray(definition.explicit))) {\n // Schema.extend({ explicit: [ type1, type2, ... ], implicit: [ type1, type2, ... ] })\n if (definition.implicit) implicit = implicit.concat(definition.implicit);\n if (definition.explicit) explicit = explicit.concat(definition.explicit);\n\n } else {\n throw new exception('Schema.extend argument should be a Type, [ Type ], ' +\n 'or a schema definition ({ implicit: [...], explicit: [...] })');\n }\n\n implicit.forEach(function (type$1) {\n if (!(type$1 instanceof type)) {\n throw new exception('Specified list of YAML types (or a single Type object) contains a non-Type object.');\n }\n\n if (type$1.loadKind && type$1.loadKind !== 'scalar') {\n throw new exception('There is a non-scalar type in the implicit list of a schema. Implicit resolving of such types is not supported.');\n }\n\n if (type$1.multi) {\n throw new exception('There is a multi type in the implicit list of a schema. Multi tags can only be listed as explicit.');\n }\n });\n\n explicit.forEach(function (type$1) {\n if (!(type$1 instanceof type)) {\n throw new exception('Specified list of YAML types (or a single Type object) contains a non-Type object.');\n }\n });\n\n var result = Object.create(Schema$1.prototype);\n\n result.implicit = (this.implicit || []).concat(implicit);\n result.explicit = (this.explicit || []).concat(explicit);\n\n result.compiledImplicit = compileList(result, 'implicit');\n result.compiledExplicit = compileList(result, 'explicit');\n result.compiledTypeMap = compileMap(result.compiledImplicit, result.compiledExplicit);\n\n return result;\n};\n\n\nvar schema = Schema$1;\n\nvar str = new type('tag:yaml.org,2002:str', {\n kind: 'scalar',\n construct: function (data) { return data !== null ? data : ''; }\n});\n\nvar seq = new type('tag:yaml.org,2002:seq', {\n kind: 'sequence',\n construct: function (data) { return data !== null ? data : []; }\n});\n\nvar map = new type('tag:yaml.org,2002:map', {\n kind: 'mapping',\n construct: function (data) { return data !== null ? data : {}; }\n});\n\nvar failsafe = new schema({\n explicit: [\n str,\n seq,\n map\n ]\n});\n\nfunction resolveYamlNull(data) {\n if (data === null) return true;\n\n var max = data.length;\n\n return (max === 1 && data === '~') ||\n (max === 4 && (data === 'null' || data === 'Null' || data === 'NULL'));\n}\n\nfunction constructYamlNull() {\n return null;\n}\n\nfunction isNull(object) {\n return object === null;\n}\n\nvar _null = new type('tag:yaml.org,2002:null', {\n kind: 'scalar',\n resolve: resolveYamlNull,\n construct: constructYamlNull,\n predicate: isNull,\n represent: {\n canonical: function () { return '~'; },\n lowercase: function () { return 'null'; },\n uppercase: function () { return 'NULL'; },\n camelcase: function () { return 'Null'; },\n empty: function () { return ''; }\n },\n defaultStyle: 'lowercase'\n});\n\nfunction resolveYamlBoolean(data) {\n if (data === null) return false;\n\n var max = data.length;\n\n return (max === 4 && (data === 'true' || data === 'True' || data === 'TRUE')) ||\n (max === 5 && (data === 'false' || data === 'False' || data === 'FALSE'));\n}\n\nfunction constructYamlBoolean(data) {\n return data === 'true' ||\n data === 'True' ||\n data === 'TRUE';\n}\n\nfunction isBoolean(object) {\n return Object.prototype.toString.call(object) === '[object Boolean]';\n}\n\nvar bool = new type('tag:yaml.org,2002:bool', {\n kind: 'scalar',\n resolve: resolveYamlBoolean,\n construct: constructYamlBoolean,\n predicate: isBoolean,\n represent: {\n lowercase: function (object) { return object ? 'true' : 'false'; },\n uppercase: function (object) { return object ? 'TRUE' : 'FALSE'; },\n camelcase: function (object) { return object ? 'True' : 'False'; }\n },\n defaultStyle: 'lowercase'\n});\n\nfunction isHexCode(c) {\n return ((0x30/* 0 */ <= c) && (c <= 0x39/* 9 */)) ||\n ((0x41/* A */ <= c) && (c <= 0x46/* F */)) ||\n ((0x61/* a */ <= c) && (c <= 0x66/* f */));\n}\n\nfunction isOctCode(c) {\n return ((0x30/* 0 */ <= c) && (c <= 0x37/* 7 */));\n}\n\nfunction isDecCode(c) {\n return ((0x30/* 0 */ <= c) && (c <= 0x39/* 9 */));\n}\n\nfunction resolveYamlInteger(data) {\n if (data === null) return false;\n\n var max = data.length,\n index = 0,\n hasDigits = false,\n ch;\n\n if (!max) return false;\n\n ch = data[index];\n\n // sign\n if (ch === '-' || ch === '+') {\n ch = data[++index];\n }\n\n if (ch === '0') {\n // 0\n if (index + 1 === max) return true;\n ch = data[++index];\n\n // base 2, base 8, base 16\n\n if (ch === 'b') {\n // base 2\n index++;\n\n for (; index < max; index++) {\n ch = data[index];\n if (ch === '_') continue;\n if (ch !== '0' && ch !== '1') return false;\n hasDigits = true;\n }\n return hasDigits && ch !== '_';\n }\n\n\n if (ch === 'x') {\n // base 16\n index++;\n\n for (; index < max; index++) {\n ch = data[index];\n if (ch === '_') continue;\n if (!isHexCode(data.charCodeAt(index))) return false;\n hasDigits = true;\n }\n return hasDigits && ch !== '_';\n }\n\n\n if (ch === 'o') {\n // base 8\n index++;\n\n for (; index < max; index++) {\n ch = data[index];\n if (ch === '_') continue;\n if (!isOctCode(data.charCodeAt(index))) return false;\n hasDigits = true;\n }\n return hasDigits && ch !== '_';\n }\n }\n\n // base 10 (except 0)\n\n // value should not start with `_`;\n if (ch === '_') return false;\n\n for (; index < max; index++) {\n ch = data[index];\n if (ch === '_') continue;\n if (!isDecCode(data.charCodeAt(index))) {\n return false;\n }\n hasDigits = true;\n }\n\n // Should have digits and should not end with `_`\n if (!hasDigits || ch === '_') return false;\n\n return true;\n}\n\nfunction constructYamlInteger(data) {\n var value = data, sign = 1, ch;\n\n if (value.indexOf('_') !== -1) {\n value = value.replace(/_/g, '');\n }\n\n ch = value[0];\n\n if (ch === '-' || ch === '+') {\n if (ch === '-') sign = -1;\n value = value.slice(1);\n ch = value[0];\n }\n\n if (value === '0') return 0;\n\n if (ch === '0') {\n if (value[1] === 'b') return sign * parseInt(value.slice(2), 2);\n if (value[1] === 'x') return sign * parseInt(value.slice(2), 16);\n if (value[1] === 'o') return sign * parseInt(value.slice(2), 8);\n }\n\n return sign * parseInt(value, 10);\n}\n\nfunction isInteger(object) {\n return (Object.prototype.toString.call(object)) === '[object Number]' &&\n (object % 1 === 0 && !common.isNegativeZero(object));\n}\n\nvar int = new type('tag:yaml.org,2002:int', {\n kind: 'scalar',\n resolve: resolveYamlInteger,\n construct: constructYamlInteger,\n predicate: isInteger,\n represent: {\n binary: function (obj) { return obj >= 0 ? '0b' + obj.toString(2) : '-0b' + obj.toString(2).slice(1); },\n octal: function (obj) { return obj >= 0 ? '0o' + obj.toString(8) : '-0o' + obj.toString(8).slice(1); },\n decimal: function (obj) { return obj.toString(10); },\n /* eslint-disable max-len */\n hexadecimal: function (obj) { return obj >= 0 ? '0x' + obj.toString(16).toUpperCase() : '-0x' + obj.toString(16).toUpperCase().slice(1); }\n },\n defaultStyle: 'decimal',\n styleAliases: {\n binary: [ 2, 'bin' ],\n octal: [ 8, 'oct' ],\n decimal: [ 10, 'dec' ],\n hexadecimal: [ 16, 'hex' ]\n }\n});\n\nvar YAML_FLOAT_PATTERN = new RegExp(\n // 2.5e4, 2.5 and integers\n '^(?:[-+]?(?:[0-9][0-9_]*)(?:\\\\.[0-9_]*)?(?:[eE][-+]?[0-9]+)?' +\n // .2e4, .2\n // special case, seems not from spec\n '|\\\\.[0-9_]+(?:[eE][-+]?[0-9]+)?' +\n // .inf\n '|[-+]?\\\\.(?:inf|Inf|INF)' +\n // .nan\n '|\\\\.(?:nan|NaN|NAN))$');\n\nfunction resolveYamlFloat(data) {\n if (data === null) return false;\n\n if (!YAML_FLOAT_PATTERN.test(data) ||\n // Quick hack to not allow integers end with `_`\n // Probably should update regexp & check speed\n data[data.length - 1] === '_') {\n return false;\n }\n\n return true;\n}\n\nfunction constructYamlFloat(data) {\n var value, sign;\n\n value = data.replace(/_/g, '').toLowerCase();\n sign = value[0] === '-' ? -1 : 1;\n\n if ('+-'.indexOf(value[0]) >= 0) {\n value = value.slice(1);\n }\n\n if (value === '.inf') {\n return (sign === 1) ? Number.POSITIVE_INFINITY : Number.NEGATIVE_INFINITY;\n\n } else if (value === '.nan') {\n return NaN;\n }\n return sign * parseFloat(value, 10);\n}\n\n\nvar SCIENTIFIC_WITHOUT_DOT = /^[-+]?[0-9]+e/;\n\nfunction representYamlFloat(object, style) {\n var res;\n\n if (isNaN(object)) {\n switch (style) {\n case 'lowercase': return '.nan';\n case 'uppercase': return '.NAN';\n case 'camelcase': return '.NaN';\n }\n } else if (Number.POSITIVE_INFINITY === object) {\n switch (style) {\n case 'lowercase': return '.inf';\n case 'uppercase': return '.INF';\n case 'camelcase': return '.Inf';\n }\n } else if (Number.NEGATIVE_INFINITY === object) {\n switch (style) {\n case 'lowercase': return '-.inf';\n case 'uppercase': return '-.INF';\n case 'camelcase': return '-.Inf';\n }\n } else if (common.isNegativeZero(object)) {\n return '-0.0';\n }\n\n res = object.toString(10);\n\n // JS stringifier can build scientific format without dots: 5e-100,\n // while YAML requres dot: 5.e-100. Fix it with simple hack\n\n return SCIENTIFIC_WITHOUT_DOT.test(res) ? res.replace('e', '.e') : res;\n}\n\nfunction isFloat(object) {\n return (Object.prototype.toString.call(object) === '[object Number]') &&\n (object % 1 !== 0 || common.isNegativeZero(object));\n}\n\nvar float = new type('tag:yaml.org,2002:float', {\n kind: 'scalar',\n resolve: resolveYamlFloat,\n construct: constructYamlFloat,\n predicate: isFloat,\n represent: representYamlFloat,\n defaultStyle: 'lowercase'\n});\n\nvar json = failsafe.extend({\n implicit: [\n _null,\n bool,\n int,\n float\n ]\n});\n\nvar core = json;\n\nvar YAML_DATE_REGEXP = new RegExp(\n '^([0-9][0-9][0-9][0-9])' + // [1] year\n '-([0-9][0-9])' + // [2] month\n '-([0-9][0-9])$'); // [3] day\n\nvar YAML_TIMESTAMP_REGEXP = new RegExp(\n '^([0-9][0-9][0-9][0-9])' + // [1] year\n '-([0-9][0-9]?)' + // [2] month\n '-([0-9][0-9]?)' + // [3] day\n '(?:[Tt]|[ \\\\t]+)' + // ...\n '([0-9][0-9]?)' + // [4] hour\n ':([0-9][0-9])' + // [5] minute\n ':([0-9][0-9])' + // [6] second\n '(?:\\\\.([0-9]*))?' + // [7] fraction\n '(?:[ \\\\t]*(Z|([-+])([0-9][0-9]?)' + // [8] tz [9] tz_sign [10] tz_hour\n '(?::([0-9][0-9]))?))?$'); // [11] tz_minute\n\nfunction resolveYamlTimestamp(data) {\n if (data === null) return false;\n if (YAML_DATE_REGEXP.exec(data) !== null) return true;\n if (YAML_TIMESTAMP_REGEXP.exec(data) !== null) return true;\n return false;\n}\n\nfunction constructYamlTimestamp(data) {\n var match, year, month, day, hour, minute, second, fraction = 0,\n delta = null, tz_hour, tz_minute, date;\n\n match = YAML_DATE_REGEXP.exec(data);\n if (match === null) match = YAML_TIMESTAMP_REGEXP.exec(data);\n\n if (match === null) throw new Error('Date resolve error');\n\n // match: [1] year [2] month [3] day\n\n year = +(match[1]);\n month = +(match[2]) - 1; // JS month starts with 0\n day = +(match[3]);\n\n if (!match[4]) { // no hour\n return new Date(Date.UTC(year, month, day));\n }\n\n // match: [4] hour [5] minute [6] second [7] fraction\n\n hour = +(match[4]);\n minute = +(match[5]);\n second = +(match[6]);\n\n if (match[7]) {\n fraction = match[7].slice(0, 3);\n while (fraction.length < 3) { // milli-seconds\n fraction += '0';\n }\n fraction = +fraction;\n }\n\n // match: [8] tz [9] tz_sign [10] tz_hour [11] tz_minute\n\n if (match[9]) {\n tz_hour = +(match[10]);\n tz_minute = +(match[11] || 0);\n delta = (tz_hour * 60 + tz_minute) * 60000; // delta in mili-seconds\n if (match[9] === '-') delta = -delta;\n }\n\n date = new Date(Date.UTC(year, month, day, hour, minute, second, fraction));\n\n if (delta) date.setTime(date.getTime() - delta);\n\n return date;\n}\n\nfunction representYamlTimestamp(object /*, style*/) {\n return object.toISOString();\n}\n\nvar timestamp = new type('tag:yaml.org,2002:timestamp', {\n kind: 'scalar',\n resolve: resolveYamlTimestamp,\n construct: constructYamlTimestamp,\n instanceOf: Date,\n represent: representYamlTimestamp\n});\n\nfunction resolveYamlMerge(data) {\n return data === '<<' || data === null;\n}\n\nvar merge = new type('tag:yaml.org,2002:merge', {\n kind: 'scalar',\n resolve: resolveYamlMerge\n});\n\n/*eslint-disable no-bitwise*/\n\n\n\n\n\n// [ 64, 65, 66 ] -> [ padding, CR, LF ]\nvar BASE64_MAP = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=\\n\\r';\n\n\nfunction resolveYamlBinary(data) {\n if (data === null) return false;\n\n var code, idx, bitlen = 0, max = data.length, map = BASE64_MAP;\n\n // Convert one by one.\n for (idx = 0; idx < max; idx++) {\n code = map.indexOf(data.charAt(idx));\n\n // Skip CR/LF\n if (code > 64) continue;\n\n // Fail on illegal characters\n if (code < 0) return false;\n\n bitlen += 6;\n }\n\n // If there are any bits left, source was corrupted\n return (bitlen % 8) === 0;\n}\n\nfunction constructYamlBinary(data) {\n var idx, tailbits,\n input = data.replace(/[\\r\\n=]/g, ''), // remove CR/LF & padding to simplify scan\n max = input.length,\n map = BASE64_MAP,\n bits = 0,\n result = [];\n\n // Collect by 6*4 bits (3 bytes)\n\n for (idx = 0; idx < max; idx++) {\n if ((idx % 4 === 0) && idx) {\n result.push((bits >> 16) & 0xFF);\n result.push((bits >> 8) & 0xFF);\n result.push(bits & 0xFF);\n }\n\n bits = (bits << 6) | map.indexOf(input.charAt(idx));\n }\n\n // Dump tail\n\n tailbits = (max % 4) * 6;\n\n if (tailbits === 0) {\n result.push((bits >> 16) & 0xFF);\n result.push((bits >> 8) & 0xFF);\n result.push(bits & 0xFF);\n } else if (tailbits === 18) {\n result.push((bits >> 10) & 0xFF);\n result.push((bits >> 2) & 0xFF);\n } else if (tailbits === 12) {\n result.push((bits >> 4) & 0xFF);\n }\n\n return new Uint8Array(result);\n}\n\nfunction representYamlBinary(object /*, style*/) {\n var result = '', bits = 0, idx, tail,\n max = object.length,\n map = BASE64_MAP;\n\n // Convert every three bytes to 4 ASCII characters.\n\n for (idx = 0; idx < max; idx++) {\n if ((idx % 3 === 0) && idx) {\n result += map[(bits >> 18) & 0x3F];\n result += map[(bits >> 12) & 0x3F];\n result += map[(bits >> 6) & 0x3F];\n result += map[bits & 0x3F];\n }\n\n bits = (bits << 8) + object[idx];\n }\n\n // Dump tail\n\n tail = max % 3;\n\n if (tail === 0) {\n result += map[(bits >> 18) & 0x3F];\n result += map[(bits >> 12) & 0x3F];\n result += map[(bits >> 6) & 0x3F];\n result += map[bits & 0x3F];\n } else if (tail === 2) {\n result += map[(bits >> 10) & 0x3F];\n result += map[(bits >> 4) & 0x3F];\n result += map[(bits << 2) & 0x3F];\n result += map[64];\n } else if (tail === 1) {\n result += map[(bits >> 2) & 0x3F];\n result += map[(bits << 4) & 0x3F];\n result += map[64];\n result += map[64];\n }\n\n return result;\n}\n\nfunction isBinary(obj) {\n return Object.prototype.toString.call(obj) === '[object Uint8Array]';\n}\n\nvar binary = new type('tag:yaml.org,2002:binary', {\n kind: 'scalar',\n resolve: resolveYamlBinary,\n construct: constructYamlBinary,\n predicate: isBinary,\n represent: representYamlBinary\n});\n\nvar _hasOwnProperty$3 = Object.prototype.hasOwnProperty;\nvar _toString$2 = Object.prototype.toString;\n\nfunction resolveYamlOmap(data) {\n if (data === null) return true;\n\n var objectKeys = [], index, length, pair, pairKey, pairHasKey,\n object = data;\n\n for (index = 0, length = object.length; index < length; index += 1) {\n pair = object[index];\n pairHasKey = false;\n\n if (_toString$2.call(pair) !== '[object Object]') return false;\n\n for (pairKey in pair) {\n if (_hasOwnProperty$3.call(pair, pairKey)) {\n if (!pairHasKey) pairHasKey = true;\n else return false;\n }\n }\n\n if (!pairHasKey) return false;\n\n if (objectKeys.indexOf(pairKey) === -1) objectKeys.push(pairKey);\n else return false;\n }\n\n return true;\n}\n\nfunction constructYamlOmap(data) {\n return data !== null ? data : [];\n}\n\nvar omap = new type('tag:yaml.org,2002:omap', {\n kind: 'sequence',\n resolve: resolveYamlOmap,\n construct: constructYamlOmap\n});\n\nvar _toString$1 = Object.prototype.toString;\n\nfunction resolveYamlPairs(data) {\n if (data === null) return true;\n\n var index, length, pair, keys, result,\n object = data;\n\n result = new Array(object.length);\n\n for (index = 0, length = object.length; index < length; index += 1) {\n pair = object[index];\n\n if (_toString$1.call(pair) !== '[object Object]') return false;\n\n keys = Object.keys(pair);\n\n if (keys.length !== 1) return false;\n\n result[index] = [ keys[0], pair[keys[0]] ];\n }\n\n return true;\n}\n\nfunction constructYamlPairs(data) {\n if (data === null) return [];\n\n var index, length, pair, keys, result,\n object = data;\n\n result = new Array(object.length);\n\n for (index = 0, length = object.length; index < length; index += 1) {\n pair = object[index];\n\n keys = Object.keys(pair);\n\n result[index] = [ keys[0], pair[keys[0]] ];\n }\n\n return result;\n}\n\nvar pairs = new type('tag:yaml.org,2002:pairs', {\n kind: 'sequence',\n resolve: resolveYamlPairs,\n construct: constructYamlPairs\n});\n\nvar _hasOwnProperty$2 = Object.prototype.hasOwnProperty;\n\nfunction resolveYamlSet(data) {\n if (data === null) return true;\n\n var key, object = data;\n\n for (key in object) {\n if (_hasOwnProperty$2.call(object, key)) {\n if (object[key] !== null) return false;\n }\n }\n\n return true;\n}\n\nfunction constructYamlSet(data) {\n return data !== null ? data : {};\n}\n\nvar set = new type('tag:yaml.org,2002:set', {\n kind: 'mapping',\n resolve: resolveYamlSet,\n construct: constructYamlSet\n});\n\nvar _default = core.extend({\n implicit: [\n timestamp,\n merge\n ],\n explicit: [\n binary,\n omap,\n pairs,\n set\n ]\n});\n\n/*eslint-disable max-len,no-use-before-define*/\n\n\n\n\n\n\n\nvar _hasOwnProperty$1 = Object.prototype.hasOwnProperty;\n\n\nvar CONTEXT_FLOW_IN = 1;\nvar CONTEXT_FLOW_OUT = 2;\nvar CONTEXT_BLOCK_IN = 3;\nvar CONTEXT_BLOCK_OUT = 4;\n\n\nvar CHOMPING_CLIP = 1;\nvar CHOMPING_STRIP = 2;\nvar CHOMPING_KEEP = 3;\n\n\nvar PATTERN_NON_PRINTABLE = /[\\x00-\\x08\\x0B\\x0C\\x0E-\\x1F\\x7F-\\x84\\x86-\\x9F\\uFFFE\\uFFFF]|[\\uD800-\\uDBFF](?![\\uDC00-\\uDFFF])|(?:[^\\uD800-\\uDBFF]|^)[\\uDC00-\\uDFFF]/;\nvar PATTERN_NON_ASCII_LINE_BREAKS = /[\\x85\\u2028\\u2029]/;\nvar PATTERN_FLOW_INDICATORS = /[,\\[\\]\\{\\}]/;\nvar PATTERN_TAG_HANDLE = /^(?:!|!!|![a-z\\-]+!)$/i;\nvar PATTERN_TAG_URI = /^(?:!|[^,\\[\\]\\{\\}])(?:%[0-9a-f]{2}|[0-9a-z\\-#;\\/\\?:@&=\\+\\$,_\\.!~\\*'\\(\\)\\[\\]])*$/i;\n\n\nfunction _class(obj) { return Object.prototype.toString.call(obj); }\n\nfunction is_EOL(c) {\n return (c === 0x0A/* LF */) || (c === 0x0D/* CR */);\n}\n\nfunction is_WHITE_SPACE(c) {\n return (c === 0x09/* Tab */) || (c === 0x20/* Space */);\n}\n\nfunction is_WS_OR_EOL(c) {\n return (c === 0x09/* Tab */) ||\n (c === 0x20/* Space */) ||\n (c === 0x0A/* LF */) ||\n (c === 0x0D/* CR */);\n}\n\nfunction is_FLOW_INDICATOR(c) {\n return c === 0x2C/* , */ ||\n c === 0x5B/* [ */ ||\n c === 0x5D/* ] */ ||\n c === 0x7B/* { */ ||\n c === 0x7D/* } */;\n}\n\nfunction fromHexCode(c) {\n var lc;\n\n if ((0x30/* 0 */ <= c) && (c <= 0x39/* 9 */)) {\n return c - 0x30;\n }\n\n /*eslint-disable no-bitwise*/\n lc = c | 0x20;\n\n if ((0x61/* a */ <= lc) && (lc <= 0x66/* f */)) {\n return lc - 0x61 + 10;\n }\n\n return -1;\n}\n\nfunction escapedHexLen(c) {\n if (c === 0x78/* x */) { return 2; }\n if (c === 0x75/* u */) { return 4; }\n if (c === 0x55/* U */) { return 8; }\n return 0;\n}\n\nfunction fromDecimalCode(c) {\n if ((0x30/* 0 */ <= c) && (c <= 0x39/* 9 */)) {\n return c - 0x30;\n }\n\n return -1;\n}\n\nfunction simpleEscapeSequence(c) {\n /* eslint-disable indent */\n return (c === 0x30/* 0 */) ? '\\x00' :\n (c === 0x61/* a */) ? '\\x07' :\n (c === 0x62/* b */) ? '\\x08' :\n (c === 0x74/* t */) ? '\\x09' :\n (c === 0x09/* Tab */) ? '\\x09' :\n (c === 0x6E/* n */) ? '\\x0A' :\n (c === 0x76/* v */) ? '\\x0B' :\n (c === 0x66/* f */) ? '\\x0C' :\n (c === 0x72/* r */) ? '\\x0D' :\n (c === 0x65/* e */) ? '\\x1B' :\n (c === 0x20/* Space */) ? ' ' :\n (c === 0x22/* \" */) ? '\\x22' :\n (c === 0x2F/* / */) ? '/' :\n (c === 0x5C/* \\ */) ? '\\x5C' :\n (c === 0x4E/* N */) ? '\\x85' :\n (c === 0x5F/* _ */) ? '\\xA0' :\n (c === 0x4C/* L */) ? '\\u2028' :\n (c === 0x50/* P */) ? '\\u2029' : '';\n}\n\nfunction charFromCodepoint(c) {\n if (c <= 0xFFFF) {\n return String.fromCharCode(c);\n }\n // Encode UTF-16 surrogate pair\n // https://en.wikipedia.org/wiki/UTF-16#Code_points_U.2B010000_to_U.2B10FFFF\n return String.fromCharCode(\n ((c - 0x010000) >> 10) + 0xD800,\n ((c - 0x010000) & 0x03FF) + 0xDC00\n );\n}\n\n// set a property of a literal object, while protecting against prototype pollution,\n// see https://github.com/nodeca/js-yaml/issues/164 for more details\nfunction setProperty(object, key, value) {\n // used for this specific key only because Object.defineProperty is slow\n if (key === '__proto__') {\n Object.defineProperty(object, key, {\n configurable: true,\n enumerable: true,\n writable: true,\n value: value\n });\n } else {\n object[key] = value;\n }\n}\n\nvar simpleEscapeCheck = new Array(256); // integer, for fast access\nvar simpleEscapeMap = new Array(256);\nfor (var i = 0; i < 256; i++) {\n simpleEscapeCheck[i] = simpleEscapeSequence(i) ? 1 : 0;\n simpleEscapeMap[i] = simpleEscapeSequence(i);\n}\n\n\nfunction State$1(input, options) {\n this.input = input;\n\n this.filename = options['filename'] || null;\n this.schema = options['schema'] || _default;\n this.onWarning = options['onWarning'] || null;\n // (Hidden) Remove? makes the loader to expect YAML 1.1 documents\n // if such documents have no explicit %YAML directive\n this.legacy = options['legacy'] || false;\n\n this.json = options['json'] || false;\n this.listener = options['listener'] || null;\n\n this.implicitTypes = this.schema.compiledImplicit;\n this.typeMap = this.schema.compiledTypeMap;\n\n this.length = input.length;\n this.position = 0;\n this.line = 0;\n this.lineStart = 0;\n this.lineIndent = 0;\n\n // position of first leading tab in the current line,\n // used to make sure there are no tabs in the indentation\n this.firstTabInLine = -1;\n\n this.documents = [];\n\n /*\n this.version;\n this.checkLineBreaks;\n this.tagMap;\n this.anchorMap;\n this.tag;\n this.anchor;\n this.kind;\n this.result;*/\n\n}\n\n\nfunction generateError(state, message) {\n var mark = {\n name: state.filename,\n buffer: state.input.slice(0, -1), // omit trailing \\0\n position: state.position,\n line: state.line,\n column: state.position - state.lineStart\n };\n\n mark.snippet = snippet(mark);\n\n return new exception(message, mark);\n}\n\nfunction throwError(state, message) {\n throw generateError(state, message);\n}\n\nfunction throwWarning(state, message) {\n if (state.onWarning) {\n state.onWarning.call(null, generateError(state, message));\n }\n}\n\n\nvar directiveHandlers = {\n\n YAML: function handleYamlDirective(state, name, args) {\n\n var match, major, minor;\n\n if (state.version !== null) {\n throwError(state, 'duplication of %YAML directive');\n }\n\n if (args.length !== 1) {\n throwError(state, 'YAML directive accepts exactly one argument');\n }\n\n match = /^([0-9]+)\\.([0-9]+)$/.exec(args[0]);\n\n if (match === null) {\n throwError(state, 'ill-formed argument of the YAML directive');\n }\n\n major = parseInt(match[1], 10);\n minor = parseInt(match[2], 10);\n\n if (major !== 1) {\n throwError(state, 'unacceptable YAML version of the document');\n }\n\n state.version = args[0];\n state.checkLineBreaks = (minor < 2);\n\n if (minor !== 1 && minor !== 2) {\n throwWarning(state, 'unsupported YAML version of the document');\n }\n },\n\n TAG: function handleTagDirective(state, name, args) {\n\n var handle, prefix;\n\n if (args.length !== 2) {\n throwError(state, 'TAG directive accepts exactly two arguments');\n }\n\n handle = args[0];\n prefix = args[1];\n\n if (!PATTERN_TAG_HANDLE.test(handle)) {\n throwError(state, 'ill-formed tag handle (first argument) of the TAG directive');\n }\n\n if (_hasOwnProperty$1.call(state.tagMap, handle)) {\n throwError(state, 'there is a previously declared suffix for \"' + handle + '\" tag handle');\n }\n\n if (!PATTERN_TAG_URI.test(prefix)) {\n throwError(state, 'ill-formed tag prefix (second argument) of the TAG directive');\n }\n\n try {\n prefix = decodeURIComponent(prefix);\n } catch (err) {\n throwError(state, 'tag prefix is malformed: ' + prefix);\n }\n\n state.tagMap[handle] = prefix;\n }\n};\n\n\nfunction captureSegment(state, start, end, checkJson) {\n var _position, _length, _character, _result;\n\n if (start < end) {\n _result = state.input.slice(start, end);\n\n if (checkJson) {\n for (_position = 0, _length = _result.length; _position < _length; _position += 1) {\n _character = _result.charCodeAt(_position);\n if (!(_character === 0x09 ||\n (0x20 <= _character && _character <= 0x10FFFF))) {\n throwError(state, 'expected valid JSON character');\n }\n }\n } else if (PATTERN_NON_PRINTABLE.test(_result)) {\n throwError(state, 'the stream contains non-printable characters');\n }\n\n state.result += _result;\n }\n}\n\nfunction mergeMappings(state, destination, source, overridableKeys) {\n var sourceKeys, key, index, quantity;\n\n if (!common.isObject(source)) {\n throwError(state, 'cannot merge mappings; the provided source object is unacceptable');\n }\n\n sourceKeys = Object.keys(source);\n\n for (index = 0, quantity = sourceKeys.length; index < quantity; index += 1) {\n key = sourceKeys[index];\n\n if (!_hasOwnProperty$1.call(destination, key)) {\n setProperty(destination, key, source[key]);\n overridableKeys[key] = true;\n }\n }\n}\n\nfunction storeMappingPair(state, _result, overridableKeys, keyTag, keyNode, valueNode,\n startLine, startLineStart, startPos) {\n\n var index, quantity;\n\n // The output is a plain object here, so keys can only be strings.\n // We need to convert keyNode to a string, but doing so can hang the process\n // (deeply nested arrays that explode exponentially using aliases).\n if (Array.isArray(keyNode)) {\n keyNode = Array.prototype.slice.call(keyNode);\n\n for (index = 0, quantity = keyNode.length; index < quantity; index += 1) {\n if (Array.isArray(keyNode[index])) {\n throwError(state, 'nested arrays are not supported inside keys');\n }\n\n if (typeof keyNode === 'object' && _class(keyNode[index]) === '[object Object]') {\n keyNode[index] = '[object Object]';\n }\n }\n }\n\n // Avoid code execution in load() via toString property\n // (still use its own toString for arrays, timestamps,\n // and whatever user schema extensions happen to have @@toStringTag)\n if (typeof keyNode === 'object' && _class(keyNode) === '[object Object]') {\n keyNode = '[object Object]';\n }\n\n\n keyNode = String(keyNode);\n\n if (_result === null) {\n _result = {};\n }\n\n if (keyTag === 'tag:yaml.org,2002:merge') {\n if (Array.isArray(valueNode)) {\n for (index = 0, quantity = valueNode.length; index < quantity; index += 1) {\n mergeMappings(state, _result, valueNode[index], overridableKeys);\n }\n } else {\n mergeMappings(state, _result, valueNode, overridableKeys);\n }\n } else {\n if (!state.json &&\n !_hasOwnProperty$1.call(overridableKeys, keyNode) &&\n _hasOwnProperty$1.call(_result, keyNode)) {\n state.line = startLine || state.line;\n state.lineStart = startLineStart || state.lineStart;\n state.position = startPos || state.position;\n throwError(state, 'duplicated mapping key');\n }\n\n setProperty(_result, keyNode, valueNode);\n delete overridableKeys[keyNode];\n }\n\n return _result;\n}\n\nfunction readLineBreak(state) {\n var ch;\n\n ch = state.input.charCodeAt(state.position);\n\n if (ch === 0x0A/* LF */) {\n state.position++;\n } else if (ch === 0x0D/* CR */) {\n state.position++;\n if (state.input.charCodeAt(state.position) === 0x0A/* LF */) {\n state.position++;\n }\n } else {\n throwError(state, 'a line break is expected');\n }\n\n state.line += 1;\n state.lineStart = state.position;\n state.firstTabInLine = -1;\n}\n\nfunction skipSeparationSpace(state, allowComments, checkIndent) {\n var lineBreaks = 0,\n ch = state.input.charCodeAt(state.position);\n\n while (ch !== 0) {\n while (is_WHITE_SPACE(ch)) {\n if (ch === 0x09/* Tab */ && state.firstTabInLine === -1) {\n state.firstTabInLine = state.position;\n }\n ch = state.input.charCodeAt(++state.position);\n }\n\n if (allowComments && ch === 0x23/* # */) {\n do {\n ch = state.input.charCodeAt(++state.position);\n } while (ch !== 0x0A/* LF */ && ch !== 0x0D/* CR */ && ch !== 0);\n }\n\n if (is_EOL(ch)) {\n readLineBreak(state);\n\n ch = state.input.charCodeAt(state.position);\n lineBreaks++;\n state.lineIndent = 0;\n\n while (ch === 0x20/* Space */) {\n state.lineIndent++;\n ch = state.input.charCodeAt(++state.position);\n }\n } else {\n break;\n }\n }\n\n if (checkIndent !== -1 && lineBreaks !== 0 && state.lineIndent < checkIndent) {\n throwWarning(state, 'deficient indentation');\n }\n\n return lineBreaks;\n}\n\nfunction testDocumentSeparator(state) {\n var _position = state.position,\n ch;\n\n ch = state.input.charCodeAt(_position);\n\n // Condition state.position === state.lineStart is tested\n // in parent on each call, for efficiency. No needs to test here again.\n if ((ch === 0x2D/* - */ || ch === 0x2E/* . */) &&\n ch === state.input.charCodeAt(_position + 1) &&\n ch === state.input.charCodeAt(_position + 2)) {\n\n _position += 3;\n\n ch = state.input.charCodeAt(_position);\n\n if (ch === 0 || is_WS_OR_EOL(ch)) {\n return true;\n }\n }\n\n return false;\n}\n\nfunction writeFoldedLines(state, count) {\n if (count === 1) {\n state.result += ' ';\n } else if (count > 1) {\n state.result += common.repeat('\\n', count - 1);\n }\n}\n\n\nfunction readPlainScalar(state, nodeIndent, withinFlowCollection) {\n var preceding,\n following,\n captureStart,\n captureEnd,\n hasPendingContent,\n _line,\n _lineStart,\n _lineIndent,\n _kind = state.kind,\n _result = state.result,\n ch;\n\n ch = state.input.charCodeAt(state.position);\n\n if (is_WS_OR_EOL(ch) ||\n is_FLOW_INDICATOR(ch) ||\n ch === 0x23/* # */ ||\n ch === 0x26/* & */ ||\n ch === 0x2A/* * */ ||\n ch === 0x21/* ! */ ||\n ch === 0x7C/* | */ ||\n ch === 0x3E/* > */ ||\n ch === 0x27/* ' */ ||\n ch === 0x22/* \" */ ||\n ch === 0x25/* % */ ||\n ch === 0x40/* @ */ ||\n ch === 0x60/* ` */) {\n return false;\n }\n\n if (ch === 0x3F/* ? */ || ch === 0x2D/* - */) {\n following = state.input.charCodeAt(state.position + 1);\n\n if (is_WS_OR_EOL(following) ||\n withinFlowCollection && is_FLOW_INDICATOR(following)) {\n return false;\n }\n }\n\n state.kind = 'scalar';\n state.result = '';\n captureStart = captureEnd = state.position;\n hasPendingContent = false;\n\n while (ch !== 0) {\n if (ch === 0x3A/* : */) {\n following = state.input.charCodeAt(state.position + 1);\n\n if (is_WS_OR_EOL(following) ||\n withinFlowCollection && is_FLOW_INDICATOR(following)) {\n break;\n }\n\n } else if (ch === 0x23/* # */) {\n preceding = state.input.charCodeAt(state.position - 1);\n\n if (is_WS_OR_EOL(preceding)) {\n break;\n }\n\n } else if ((state.position === state.lineStart && testDocumentSeparator(state)) ||\n withinFlowCollection && is_FLOW_INDICATOR(ch)) {\n break;\n\n } else if (is_EOL(ch)) {\n _line = state.line;\n _lineStart = state.lineStart;\n _lineIndent = state.lineIndent;\n skipSeparationSpace(state, false, -1);\n\n if (state.lineIndent >= nodeIndent) {\n hasPendingContent = true;\n ch = state.input.charCodeAt(state.position);\n continue;\n } else {\n state.position = captureEnd;\n state.line = _line;\n state.lineStart = _lineStart;\n state.lineIndent = _lineIndent;\n break;\n }\n }\n\n if (hasPendingContent) {\n captureSegment(state, captureStart, captureEnd, false);\n writeFoldedLines(state, state.line - _line);\n captureStart = captureEnd = state.position;\n hasPendingContent = false;\n }\n\n if (!is_WHITE_SPACE(ch)) {\n captureEnd = state.position + 1;\n }\n\n ch = state.input.charCodeAt(++state.position);\n }\n\n captureSegment(state, captureStart, captureEnd, false);\n\n if (state.result) {\n return true;\n }\n\n state.kind = _kind;\n state.result = _result;\n return false;\n}\n\nfunction readSingleQuotedScalar(state, nodeIndent) {\n var ch,\n captureStart, captureEnd;\n\n ch = state.input.charCodeAt(state.position);\n\n if (ch !== 0x27/* ' */) {\n return false;\n }\n\n state.kind = 'scalar';\n state.result = '';\n state.position++;\n captureStart = captureEnd = state.position;\n\n while ((ch = state.input.charCodeAt(state.position)) !== 0) {\n if (ch === 0x27/* ' */) {\n captureSegment(state, captureStart, state.position, true);\n ch = state.input.charCodeAt(++state.position);\n\n if (ch === 0x27/* ' */) {\n captureStart = state.position;\n state.position++;\n captureEnd = state.position;\n } else {\n return true;\n }\n\n } else if (is_EOL(ch)) {\n captureSegment(state, captureStart, captureEnd, true);\n writeFoldedLines(state, skipSeparationSpace(state, false, nodeIndent));\n captureStart = captureEnd = state.position;\n\n } else if (state.position === state.lineStart && testDocumentSeparator(state)) {\n throwError(state, 'unexpected end of the document within a single quoted scalar');\n\n } else {\n state.position++;\n captureEnd = state.position;\n }\n }\n\n throwError(state, 'unexpected end of the stream within a single quoted scalar');\n}\n\nfunction readDoubleQuotedScalar(state, nodeIndent) {\n var captureStart,\n captureEnd,\n hexLength,\n hexResult,\n tmp,\n ch;\n\n ch = state.input.charCodeAt(state.position);\n\n if (ch !== 0x22/* \" */) {\n return false;\n }\n\n state.kind = 'scalar';\n state.result = '';\n state.position++;\n captureStart = captureEnd = state.position;\n\n while ((ch = state.input.charCodeAt(state.position)) !== 0) {\n if (ch === 0x22/* \" */) {\n captureSegment(state, captureStart, state.position, true);\n state.position++;\n return true;\n\n } else if (ch === 0x5C/* \\ */) {\n captureSegment(state, captureStart, state.position, true);\n ch = state.input.charCodeAt(++state.position);\n\n if (is_EOL(ch)) {\n skipSeparationSpace(state, false, nodeIndent);\n\n // TODO: rework to inline fn with no type cast?\n } else if (ch < 256 && simpleEscapeCheck[ch]) {\n state.result += simpleEscapeMap[ch];\n state.position++;\n\n } else if ((tmp = escapedHexLen(ch)) > 0) {\n hexLength = tmp;\n hexResult = 0;\n\n for (; hexLength > 0; hexLength--) {\n ch = state.input.charCodeAt(++state.position);\n\n if ((tmp = fromHexCode(ch)) >= 0) {\n hexResult = (hexResult << 4) + tmp;\n\n } else {\n throwError(state, 'expected hexadecimal character');\n }\n }\n\n state.result += charFromCodepoint(hexResult);\n\n state.position++;\n\n } else {\n throwError(state, 'unknown escape sequence');\n }\n\n captureStart = captureEnd = state.position;\n\n } else if (is_EOL(ch)) {\n captureSegment(state, captureStart, captureEnd, true);\n writeFoldedLines(state, skipSeparationSpace(state, false, nodeIndent));\n captureStart = captureEnd = state.position;\n\n } else if (state.position === state.lineStart && testDocumentSeparator(state)) {\n throwError(state, 'unexpected end of the document within a double quoted scalar');\n\n } else {\n state.position++;\n captureEnd = state.position;\n }\n }\n\n throwError(state, 'unexpected end of the stream within a double quoted scalar');\n}\n\nfunction readFlowCollection(state, nodeIndent) {\n var readNext = true,\n _line,\n _lineStart,\n _pos,\n _tag = state.tag,\n _result,\n _anchor = state.anchor,\n following,\n terminator,\n isPair,\n isExplicitPair,\n isMapping,\n overridableKeys = Object.create(null),\n keyNode,\n keyTag,\n valueNode,\n ch;\n\n ch = state.input.charCodeAt(state.position);\n\n if (ch === 0x5B/* [ */) {\n terminator = 0x5D;/* ] */\n isMapping = false;\n _result = [];\n } else if (ch === 0x7B/* { */) {\n terminator = 0x7D;/* } */\n isMapping = true;\n _result = {};\n } else {\n return false;\n }\n\n if (state.anchor !== null) {\n state.anchorMap[state.anchor] = _result;\n }\n\n ch = state.input.charCodeAt(++state.position);\n\n while (ch !== 0) {\n skipSeparationSpace(state, true, nodeIndent);\n\n ch = state.input.charCodeAt(state.position);\n\n if (ch === terminator) {\n state.position++;\n state.tag = _tag;\n state.anchor = _anchor;\n state.kind = isMapping ? 'mapping' : 'sequence';\n state.result = _result;\n return true;\n } else if (!readNext) {\n throwError(state, 'missed comma between flow collection entries');\n } else if (ch === 0x2C/* , */) {\n // \"flow collection entries can never be completely empty\", as per YAML 1.2, section 7.4\n throwError(state, \"expected the node content, but found ','\");\n }\n\n keyTag = keyNode = valueNode = null;\n isPair = isExplicitPair = false;\n\n if (ch === 0x3F/* ? */) {\n following = state.input.charCodeAt(state.position + 1);\n\n if (is_WS_OR_EOL(following)) {\n isPair = isExplicitPair = true;\n state.position++;\n skipSeparationSpace(state, true, nodeIndent);\n }\n }\n\n _line = state.line; // Save the current line.\n _lineStart = state.lineStart;\n _pos = state.position;\n composeNode(state, nodeIndent, CONTEXT_FLOW_IN, false, true);\n keyTag = state.tag;\n keyNode = state.result;\n skipSeparationSpace(state, true, nodeIndent);\n\n ch = state.input.charCodeAt(state.position);\n\n if ((isExplicitPair || state.line === _line) && ch === 0x3A/* : */) {\n isPair = true;\n ch = state.input.charCodeAt(++state.position);\n skipSeparationSpace(state, true, nodeIndent);\n composeNode(state, nodeIndent, CONTEXT_FLOW_IN, false, true);\n valueNode = state.result;\n }\n\n if (isMapping) {\n storeMappingPair(state, _result, overridableKeys, keyTag, keyNode, valueNode, _line, _lineStart, _pos);\n } else if (isPair) {\n _result.push(storeMappingPair(state, null, overridableKeys, keyTag, keyNode, valueNode, _line, _lineStart, _pos));\n } else {\n _result.push(keyNode);\n }\n\n skipSeparationSpace(state, true, nodeIndent);\n\n ch = state.input.charCodeAt(state.position);\n\n if (ch === 0x2C/* , */) {\n readNext = true;\n ch = state.input.charCodeAt(++state.position);\n } else {\n readNext = false;\n }\n }\n\n throwError(state, 'unexpected end of the stream within a flow collection');\n}\n\nfunction readBlockScalar(state, nodeIndent) {\n var captureStart,\n folding,\n chomping = CHOMPING_CLIP,\n didReadContent = false,\n detectedIndent = false,\n textIndent = nodeIndent,\n emptyLines = 0,\n atMoreIndented = false,\n tmp,\n ch;\n\n ch = state.input.charCodeAt(state.position);\n\n if (ch === 0x7C/* | */) {\n folding = false;\n } else if (ch === 0x3E/* > */) {\n folding = true;\n } else {\n return false;\n }\n\n state.kind = 'scalar';\n state.result = '';\n\n while (ch !== 0) {\n ch = state.input.charCodeAt(++state.position);\n\n if (ch === 0x2B/* + */ || ch === 0x2D/* - */) {\n if (CHOMPING_CLIP === chomping) {\n chomping = (ch === 0x2B/* + */) ? CHOMPING_KEEP : CHOMPING_STRIP;\n } else {\n throwError(state, 'repeat of a chomping mode identifier');\n }\n\n } else if ((tmp = fromDecimalCode(ch)) >= 0) {\n if (tmp === 0) {\n throwError(state, 'bad explicit indentation width of a block scalar; it cannot be less than one');\n } else if (!detectedIndent) {\n textIndent = nodeIndent + tmp - 1;\n detectedIndent = true;\n } else {\n throwError(state, 'repeat of an indentation width identifier');\n }\n\n } else {\n break;\n }\n }\n\n if (is_WHITE_SPACE(ch)) {\n do { ch = state.input.charCodeAt(++state.position); }\n while (is_WHITE_SPACE(ch));\n\n if (ch === 0x23/* # */) {\n do { ch = state.input.charCodeAt(++state.position); }\n while (!is_EOL(ch) && (ch !== 0));\n }\n }\n\n while (ch !== 0) {\n readLineBreak(state);\n state.lineIndent = 0;\n\n ch = state.input.charCodeAt(state.position);\n\n while ((!detectedIndent || state.lineIndent < textIndent) &&\n (ch === 0x20/* Space */)) {\n state.lineIndent++;\n ch = state.input.charCodeAt(++state.position);\n }\n\n if (!detectedIndent && state.lineIndent > textIndent) {\n textIndent = state.lineIndent;\n }\n\n if (is_EOL(ch)) {\n emptyLines++;\n continue;\n }\n\n // End of the scalar.\n if (state.lineIndent < textIndent) {\n\n // Perform the chomping.\n if (chomping === CHOMPING_KEEP) {\n state.result += common.repeat('\\n', didReadContent ? 1 + emptyLines : emptyLines);\n } else if (chomping === CHOMPING_CLIP) {\n if (didReadContent) { // i.e. only if the scalar is not empty.\n state.result += '\\n';\n }\n }\n\n // Break this `while` cycle and go to the funciton's epilogue.\n break;\n }\n\n // Folded style: use fancy rules to handle line breaks.\n if (folding) {\n\n // Lines starting with white space characters (more-indented lines) are not folded.\n if (is_WHITE_SPACE(ch)) {\n atMoreIndented = true;\n // except for the first content line (cf. Example 8.1)\n state.result += common.repeat('\\n', didReadContent ? 1 + emptyLines : emptyLines);\n\n // End of more-indented block.\n } else if (atMoreIndented) {\n atMoreIndented = false;\n state.result += common.repeat('\\n', emptyLines + 1);\n\n // Just one line break - perceive as the same line.\n } else if (emptyLines === 0) {\n if (didReadContent) { // i.e. only if we have already read some scalar content.\n state.result += ' ';\n }\n\n // Several line breaks - perceive as different lines.\n } else {\n state.result += common.repeat('\\n', emptyLines);\n }\n\n // Literal style: just add exact number of line breaks between content lines.\n } else {\n // Keep all line breaks except the header line break.\n state.result += common.repeat('\\n', didReadContent ? 1 + emptyLines : emptyLines);\n }\n\n didReadContent = true;\n detectedIndent = true;\n emptyLines = 0;\n captureStart = state.position;\n\n while (!is_EOL(ch) && (ch !== 0)) {\n ch = state.input.charCodeAt(++state.position);\n }\n\n captureSegment(state, captureStart, state.position, false);\n }\n\n return true;\n}\n\nfunction readBlockSequence(state, nodeIndent) {\n var _line,\n _tag = state.tag,\n _anchor = state.anchor,\n _result = [],\n following,\n detected = false,\n ch;\n\n // there is a leading tab before this token, so it can't be a block sequence/mapping;\n // it can still be flow sequence/mapping or a scalar\n if (state.firstTabInLine !== -1) return false;\n\n if (state.anchor !== null) {\n state.anchorMap[state.anchor] = _result;\n }\n\n ch = state.input.charCodeAt(state.position);\n\n while (ch !== 0) {\n if (state.firstTabInLine !== -1) {\n state.position = state.firstTabInLine;\n throwError(state, 'tab characters must not be used in indentation');\n }\n\n if (ch !== 0x2D/* - */) {\n break;\n }\n\n following = state.input.charCodeAt(state.position + 1);\n\n if (!is_WS_OR_EOL(following)) {\n break;\n }\n\n detected = true;\n state.position++;\n\n if (skipSeparationSpace(state, true, -1)) {\n if (state.lineIndent <= nodeIndent) {\n _result.push(null);\n ch = state.input.charCodeAt(state.position);\n continue;\n }\n }\n\n _line = state.line;\n composeNode(state, nodeIndent, CONTEXT_BLOCK_IN, false, true);\n _result.push(state.result);\n skipSeparationSpace(state, true, -1);\n\n ch = state.input.charCodeAt(state.position);\n\n if ((state.line === _line || state.lineIndent > nodeIndent) && (ch !== 0)) {\n throwError(state, 'bad indentation of a sequence entry');\n } else if (state.lineIndent < nodeIndent) {\n break;\n }\n }\n\n if (detected) {\n state.tag = _tag;\n state.anchor = _anchor;\n state.kind = 'sequence';\n state.result = _result;\n return true;\n }\n return false;\n}\n\nfunction readBlockMapping(state, nodeIndent, flowIndent) {\n var following,\n allowCompact,\n _line,\n _keyLine,\n _keyLineStart,\n _keyPos,\n _tag = state.tag,\n _anchor = state.anchor,\n _result = {},\n overridableKeys = Object.create(null),\n keyTag = null,\n keyNode = null,\n valueNode = null,\n atExplicitKey = false,\n detected = false,\n ch;\n\n // there is a leading tab before this token, so it can't be a block sequence/mapping;\n // it can still be flow sequence/mapping or a scalar\n if (state.firstTabInLine !== -1) return false;\n\n if (state.anchor !== null) {\n state.anchorMap[state.anchor] = _result;\n }\n\n ch = state.input.charCodeAt(state.position);\n\n while (ch !== 0) {\n if (!atExplicitKey && state.firstTabInLine !== -1) {\n state.position = state.firstTabInLine;\n throwError(state, 'tab characters must not be used in indentation');\n }\n\n following = state.input.charCodeAt(state.position + 1);\n _line = state.line; // Save the current line.\n\n //\n // Explicit notation case. There are two separate blocks:\n // first for the key (denoted by \"?\") and second for the value (denoted by \":\")\n //\n if ((ch === 0x3F/* ? */ || ch === 0x3A/* : */) && is_WS_OR_EOL(following)) {\n\n if (ch === 0x3F/* ? */) {\n if (atExplicitKey) {\n storeMappingPair(state, _result, overridableKeys, keyTag, keyNode, null, _keyLine, _keyLineStart, _keyPos);\n keyTag = keyNode = valueNode = null;\n }\n\n detected = true;\n atExplicitKey = true;\n allowCompact = true;\n\n } else if (atExplicitKey) {\n // i.e. 0x3A/* : */ === character after the explicit key.\n atExplicitKey = false;\n allowCompact = true;\n\n } else {\n throwError(state, 'incomplete explicit mapping pair; a key node is missed; or followed by a non-tabulated empty line');\n }\n\n state.position += 1;\n ch = following;\n\n //\n // Implicit notation case. Flow-style node as the key first, then \":\", and the value.\n //\n } else {\n _keyLine = state.line;\n _keyLineStart = state.lineStart;\n _keyPos = state.position;\n\n if (!composeNode(state, flowIndent, CONTEXT_FLOW_OUT, false, true)) {\n // Neither implicit nor explicit notation.\n // Reading is done. Go to the epilogue.\n break;\n }\n\n if (state.line === _line) {\n ch = state.input.charCodeAt(state.position);\n\n while (is_WHITE_SPACE(ch)) {\n ch = state.input.charCodeAt(++state.position);\n }\n\n if (ch === 0x3A/* : */) {\n ch = state.input.charCodeAt(++state.position);\n\n if (!is_WS_OR_EOL(ch)) {\n throwError(state, 'a whitespace character is expected after the key-value separator within a block mapping');\n }\n\n if (atExplicitKey) {\n storeMappingPair(state, _result, overridableKeys, keyTag, keyNode, null, _keyLine, _keyLineStart, _keyPos);\n keyTag = keyNode = valueNode = null;\n }\n\n detected = true;\n atExplicitKey = false;\n allowCompact = false;\n keyTag = state.tag;\n keyNode = state.result;\n\n } else if (detected) {\n throwError(state, 'can not read an implicit mapping pair; a colon is missed');\n\n } else {\n state.tag = _tag;\n state.anchor = _anchor;\n return true; // Keep the result of `composeNode`.\n }\n\n } else if (detected) {\n throwError(state, 'can not read a block mapping entry; a multiline key may not be an implicit key');\n\n } else {\n state.tag = _tag;\n state.anchor = _anchor;\n return true; // Keep the result of `composeNode`.\n }\n }\n\n //\n // Common reading code for both explicit and implicit notations.\n //\n if (state.line === _line || state.lineIndent > nodeIndent) {\n if (atExplicitKey) {\n _keyLine = state.line;\n _keyLineStart = state.lineStart;\n _keyPos = state.position;\n }\n\n if (composeNode(state, nodeIndent, CONTEXT_BLOCK_OUT, true, allowCompact)) {\n if (atExplicitKey) {\n keyNode = state.result;\n } else {\n valueNode = state.result;\n }\n }\n\n if (!atExplicitKey) {\n storeMappingPair(state, _result, overridableKeys, keyTag, keyNode, valueNode, _keyLine, _keyLineStart, _keyPos);\n keyTag = keyNode = valueNode = null;\n }\n\n skipSeparationSpace(state, true, -1);\n ch = state.input.charCodeAt(state.position);\n }\n\n if ((state.line === _line || state.lineIndent > nodeIndent) && (ch !== 0)) {\n throwError(state, 'bad indentation of a mapping entry');\n } else if (state.lineIndent < nodeIndent) {\n break;\n }\n }\n\n //\n // Epilogue.\n //\n\n // Special case: last mapping's node contains only the key in explicit notation.\n if (atExplicitKey) {\n storeMappingPair(state, _result, overridableKeys, keyTag, keyNode, null, _keyLine, _keyLineStart, _keyPos);\n }\n\n // Expose the resulting mapping.\n if (detected) {\n state.tag = _tag;\n state.anchor = _anchor;\n state.kind = 'mapping';\n state.result = _result;\n }\n\n return detected;\n}\n\nfunction readTagProperty(state) {\n var _position,\n isVerbatim = false,\n isNamed = false,\n tagHandle,\n tagName,\n ch;\n\n ch = state.input.charCodeAt(state.position);\n\n if (ch !== 0x21/* ! */) return false;\n\n if (state.tag !== null) {\n throwError(state, 'duplication of a tag property');\n }\n\n ch = state.input.charCodeAt(++state.position);\n\n if (ch === 0x3C/* < */) {\n isVerbatim = true;\n ch = state.input.charCodeAt(++state.position);\n\n } else if (ch === 0x21/* ! */) {\n isNamed = true;\n tagHandle = '!!';\n ch = state.input.charCodeAt(++state.position);\n\n } else {\n tagHandle = '!';\n }\n\n _position = state.position;\n\n if (isVerbatim) {\n do { ch = state.input.charCodeAt(++state.position); }\n while (ch !== 0 && ch !== 0x3E/* > */);\n\n if (state.position < state.length) {\n tagName = state.input.slice(_position, state.position);\n ch = state.input.charCodeAt(++state.position);\n } else {\n throwError(state, 'unexpected end of the stream within a verbatim tag');\n }\n } else {\n while (ch !== 0 && !is_WS_OR_EOL(ch)) {\n\n if (ch === 0x21/* ! */) {\n if (!isNamed) {\n tagHandle = state.input.slice(_position - 1, state.position + 1);\n\n if (!PATTERN_TAG_HANDLE.test(tagHandle)) {\n throwError(state, 'named tag handle cannot contain such characters');\n }\n\n isNamed = true;\n _position = state.position + 1;\n } else {\n throwError(state, 'tag suffix cannot contain exclamation marks');\n }\n }\n\n ch = state.input.charCodeAt(++state.position);\n }\n\n tagName = state.input.slice(_position, state.position);\n\n if (PATTERN_FLOW_INDICATORS.test(tagName)) {\n throwError(state, 'tag suffix cannot contain flow indicator characters');\n }\n }\n\n if (tagName && !PATTERN_TAG_URI.test(tagName)) {\n throwError(state, 'tag name cannot contain such characters: ' + tagName);\n }\n\n try {\n tagName = decodeURIComponent(tagName);\n } catch (err) {\n throwError(state, 'tag name is malformed: ' + tagName);\n }\n\n if (isVerbatim) {\n state.tag = tagName;\n\n } else if (_hasOwnProperty$1.call(state.tagMap, tagHandle)) {\n state.tag = state.tagMap[tagHandle] + tagName;\n\n } else if (tagHandle === '!') {\n state.tag = '!' + tagName;\n\n } else if (tagHandle === '!!') {\n state.tag = 'tag:yaml.org,2002:' + tagName;\n\n } else {\n throwError(state, 'undeclared tag handle \"' + tagHandle + '\"');\n }\n\n return true;\n}\n\nfunction readAnchorProperty(state) {\n var _position,\n ch;\n\n ch = state.input.charCodeAt(state.position);\n\n if (ch !== 0x26/* & */) return false;\n\n if (state.anchor !== null) {\n throwError(state, 'duplication of an anchor property');\n }\n\n ch = state.input.charCodeAt(++state.position);\n _position = state.position;\n\n while (ch !== 0 && !is_WS_OR_EOL(ch) && !is_FLOW_INDICATOR(ch)) {\n ch = state.input.charCodeAt(++state.position);\n }\n\n if (state.position === _position) {\n throwError(state, 'name of an anchor node must contain at least one character');\n }\n\n state.anchor = state.input.slice(_position, state.position);\n return true;\n}\n\nfunction readAlias(state) {\n var _position, alias,\n ch;\n\n ch = state.input.charCodeAt(state.position);\n\n if (ch !== 0x2A/* * */) return false;\n\n ch = state.input.charCodeAt(++state.position);\n _position = state.position;\n\n while (ch !== 0 && !is_WS_OR_EOL(ch) && !is_FLOW_INDICATOR(ch)) {\n ch = state.input.charCodeAt(++state.position);\n }\n\n if (state.position === _position) {\n throwError(state, 'name of an alias node must contain at least one character');\n }\n\n alias = state.input.slice(_position, state.position);\n\n if (!_hasOwnProperty$1.call(state.anchorMap, alias)) {\n throwError(state, 'unidentified alias \"' + alias + '\"');\n }\n\n state.result = state.anchorMap[alias];\n skipSeparationSpace(state, true, -1);\n return true;\n}\n\nfunction composeNode(state, parentIndent, nodeContext, allowToSeek, allowCompact) {\n var allowBlockStyles,\n allowBlockScalars,\n allowBlockCollections,\n indentStatus = 1, // 1: this>parent, 0: this=parent, -1: this parentIndent) {\n indentStatus = 1;\n } else if (state.lineIndent === parentIndent) {\n indentStatus = 0;\n } else if (state.lineIndent < parentIndent) {\n indentStatus = -1;\n }\n }\n }\n\n if (indentStatus === 1) {\n while (readTagProperty(state) || readAnchorProperty(state)) {\n if (skipSeparationSpace(state, true, -1)) {\n atNewLine = true;\n allowBlockCollections = allowBlockStyles;\n\n if (state.lineIndent > parentIndent) {\n indentStatus = 1;\n } else if (state.lineIndent === parentIndent) {\n indentStatus = 0;\n } else if (state.lineIndent < parentIndent) {\n indentStatus = -1;\n }\n } else {\n allowBlockCollections = false;\n }\n }\n }\n\n if (allowBlockCollections) {\n allowBlockCollections = atNewLine || allowCompact;\n }\n\n if (indentStatus === 1 || CONTEXT_BLOCK_OUT === nodeContext) {\n if (CONTEXT_FLOW_IN === nodeContext || CONTEXT_FLOW_OUT === nodeContext) {\n flowIndent = parentIndent;\n } else {\n flowIndent = parentIndent + 1;\n }\n\n blockIndent = state.position - state.lineStart;\n\n if (indentStatus === 1) {\n if (allowBlockCollections &&\n (readBlockSequence(state, blockIndent) ||\n readBlockMapping(state, blockIndent, flowIndent)) ||\n readFlowCollection(state, flowIndent)) {\n hasContent = true;\n } else {\n if ((allowBlockScalars && readBlockScalar(state, flowIndent)) ||\n readSingleQuotedScalar(state, flowIndent) ||\n readDoubleQuotedScalar(state, flowIndent)) {\n hasContent = true;\n\n } else if (readAlias(state)) {\n hasContent = true;\n\n if (state.tag !== null || state.anchor !== null) {\n throwError(state, 'alias node should not have any properties');\n }\n\n } else if (readPlainScalar(state, flowIndent, CONTEXT_FLOW_IN === nodeContext)) {\n hasContent = true;\n\n if (state.tag === null) {\n state.tag = '?';\n }\n }\n\n if (state.anchor !== null) {\n state.anchorMap[state.anchor] = state.result;\n }\n }\n } else if (indentStatus === 0) {\n // Special case: block sequences are allowed to have same indentation level as the parent.\n // http://www.yaml.org/spec/1.2/spec.html#id2799784\n hasContent = allowBlockCollections && readBlockSequence(state, blockIndent);\n }\n }\n\n if (state.tag === null) {\n if (state.anchor !== null) {\n state.anchorMap[state.anchor] = state.result;\n }\n\n } else if (state.tag === '?') {\n // Implicit resolving is not allowed for non-scalar types, and '?'\n // non-specific tag is only automatically assigned to plain scalars.\n //\n // We only need to check kind conformity in case user explicitly assigns '?'\n // tag, for example like this: \"! [0]\"\n //\n if (state.result !== null && state.kind !== 'scalar') {\n throwError(state, 'unacceptable node kind for ! tag; it should be \"scalar\", not \"' + state.kind + '\"');\n }\n\n for (typeIndex = 0, typeQuantity = state.implicitTypes.length; typeIndex < typeQuantity; typeIndex += 1) {\n type = state.implicitTypes[typeIndex];\n\n if (type.resolve(state.result)) { // `state.result` updated in resolver if matched\n state.result = type.construct(state.result);\n state.tag = type.tag;\n if (state.anchor !== null) {\n state.anchorMap[state.anchor] = state.result;\n }\n break;\n }\n }\n } else if (state.tag !== '!') {\n if (_hasOwnProperty$1.call(state.typeMap[state.kind || 'fallback'], state.tag)) {\n type = state.typeMap[state.kind || 'fallback'][state.tag];\n } else {\n // looking for multi type\n type = null;\n typeList = state.typeMap.multi[state.kind || 'fallback'];\n\n for (typeIndex = 0, typeQuantity = typeList.length; typeIndex < typeQuantity; typeIndex += 1) {\n if (state.tag.slice(0, typeList[typeIndex].tag.length) === typeList[typeIndex].tag) {\n type = typeList[typeIndex];\n break;\n }\n }\n }\n\n if (!type) {\n throwError(state, 'unknown tag !<' + state.tag + '>');\n }\n\n if (state.result !== null && type.kind !== state.kind) {\n throwError(state, 'unacceptable node kind for !<' + state.tag + '> tag; it should be \"' + type.kind + '\", not \"' + state.kind + '\"');\n }\n\n if (!type.resolve(state.result, state.tag)) { // `state.result` updated in resolver if matched\n throwError(state, 'cannot resolve a node with !<' + state.tag + '> explicit tag');\n } else {\n state.result = type.construct(state.result, state.tag);\n if (state.anchor !== null) {\n state.anchorMap[state.anchor] = state.result;\n }\n }\n }\n\n if (state.listener !== null) {\n state.listener('close', state);\n }\n return state.tag !== null || state.anchor !== null || hasContent;\n}\n\nfunction readDocument(state) {\n var documentStart = state.position,\n _position,\n directiveName,\n directiveArgs,\n hasDirectives = false,\n ch;\n\n state.version = null;\n state.checkLineBreaks = state.legacy;\n state.tagMap = Object.create(null);\n state.anchorMap = Object.create(null);\n\n while ((ch = state.input.charCodeAt(state.position)) !== 0) {\n skipSeparationSpace(state, true, -1);\n\n ch = state.input.charCodeAt(state.position);\n\n if (state.lineIndent > 0 || ch !== 0x25/* % */) {\n break;\n }\n\n hasDirectives = true;\n ch = state.input.charCodeAt(++state.position);\n _position = state.position;\n\n while (ch !== 0 && !is_WS_OR_EOL(ch)) {\n ch = state.input.charCodeAt(++state.position);\n }\n\n directiveName = state.input.slice(_position, state.position);\n directiveArgs = [];\n\n if (directiveName.length < 1) {\n throwError(state, 'directive name must not be less than one character in length');\n }\n\n while (ch !== 0) {\n while (is_WHITE_SPACE(ch)) {\n ch = state.input.charCodeAt(++state.position);\n }\n\n if (ch === 0x23/* # */) {\n do { ch = state.input.charCodeAt(++state.position); }\n while (ch !== 0 && !is_EOL(ch));\n break;\n }\n\n if (is_EOL(ch)) break;\n\n _position = state.position;\n\n while (ch !== 0 && !is_WS_OR_EOL(ch)) {\n ch = state.input.charCodeAt(++state.position);\n }\n\n directiveArgs.push(state.input.slice(_position, state.position));\n }\n\n if (ch !== 0) readLineBreak(state);\n\n if (_hasOwnProperty$1.call(directiveHandlers, directiveName)) {\n directiveHandlers[directiveName](state, directiveName, directiveArgs);\n } else {\n throwWarning(state, 'unknown document directive \"' + directiveName + '\"');\n }\n }\n\n skipSeparationSpace(state, true, -1);\n\n if (state.lineIndent === 0 &&\n state.input.charCodeAt(state.position) === 0x2D/* - */ &&\n state.input.charCodeAt(state.position + 1) === 0x2D/* - */ &&\n state.input.charCodeAt(state.position + 2) === 0x2D/* - */) {\n state.position += 3;\n skipSeparationSpace(state, true, -1);\n\n } else if (hasDirectives) {\n throwError(state, 'directives end mark is expected');\n }\n\n composeNode(state, state.lineIndent - 1, CONTEXT_BLOCK_OUT, false, true);\n skipSeparationSpace(state, true, -1);\n\n if (state.checkLineBreaks &&\n PATTERN_NON_ASCII_LINE_BREAKS.test(state.input.slice(documentStart, state.position))) {\n throwWarning(state, 'non-ASCII line breaks are interpreted as content');\n }\n\n state.documents.push(state.result);\n\n if (state.position === state.lineStart && testDocumentSeparator(state)) {\n\n if (state.input.charCodeAt(state.position) === 0x2E/* . */) {\n state.position += 3;\n skipSeparationSpace(state, true, -1);\n }\n return;\n }\n\n if (state.position < (state.length - 1)) {\n throwError(state, 'end of the stream or a document separator is expected');\n } else {\n return;\n }\n}\n\n\nfunction loadDocuments(input, options) {\n input = String(input);\n options = options || {};\n\n if (input.length !== 0) {\n\n // Add tailing `\\n` if not exists\n if (input.charCodeAt(input.length - 1) !== 0x0A/* LF */ &&\n input.charCodeAt(input.length - 1) !== 0x0D/* CR */) {\n input += '\\n';\n }\n\n // Strip BOM\n if (input.charCodeAt(0) === 0xFEFF) {\n input = input.slice(1);\n }\n }\n\n var state = new State$1(input, options);\n\n var nullpos = input.indexOf('\\0');\n\n if (nullpos !== -1) {\n state.position = nullpos;\n throwError(state, 'null byte is not allowed in input');\n }\n\n // Use 0 as string terminator. That significantly simplifies bounds check.\n state.input += '\\0';\n\n while (state.input.charCodeAt(state.position) === 0x20/* Space */) {\n state.lineIndent += 1;\n state.position += 1;\n }\n\n while (state.position < (state.length - 1)) {\n readDocument(state);\n }\n\n return state.documents;\n}\n\n\nfunction loadAll$1(input, iterator, options) {\n if (iterator !== null && typeof iterator === 'object' && typeof options === 'undefined') {\n options = iterator;\n iterator = null;\n }\n\n var documents = loadDocuments(input, options);\n\n if (typeof iterator !== 'function') {\n return documents;\n }\n\n for (var index = 0, length = documents.length; index < length; index += 1) {\n iterator(documents[index]);\n }\n}\n\n\nfunction load$1(input, options) {\n var documents = loadDocuments(input, options);\n\n if (documents.length === 0) {\n /*eslint-disable no-undefined*/\n return undefined;\n } else if (documents.length === 1) {\n return documents[0];\n }\n throw new exception('expected a single document in the stream, but found more');\n}\n\n\nvar loadAll_1 = loadAll$1;\nvar load_1 = load$1;\n\nvar loader = {\n\tloadAll: loadAll_1,\n\tload: load_1\n};\n\n/*eslint-disable no-use-before-define*/\n\n\n\n\n\nvar _toString = Object.prototype.toString;\nvar _hasOwnProperty = Object.prototype.hasOwnProperty;\n\nvar CHAR_BOM = 0xFEFF;\nvar CHAR_TAB = 0x09; /* Tab */\nvar CHAR_LINE_FEED = 0x0A; /* LF */\nvar CHAR_CARRIAGE_RETURN = 0x0D; /* CR */\nvar CHAR_SPACE = 0x20; /* Space */\nvar CHAR_EXCLAMATION = 0x21; /* ! */\nvar CHAR_DOUBLE_QUOTE = 0x22; /* \" */\nvar CHAR_SHARP = 0x23; /* # */\nvar CHAR_PERCENT = 0x25; /* % */\nvar CHAR_AMPERSAND = 0x26; /* & */\nvar CHAR_SINGLE_QUOTE = 0x27; /* ' */\nvar CHAR_ASTERISK = 0x2A; /* * */\nvar CHAR_COMMA = 0x2C; /* , */\nvar CHAR_MINUS = 0x2D; /* - */\nvar CHAR_COLON = 0x3A; /* : */\nvar CHAR_EQUALS = 0x3D; /* = */\nvar CHAR_GREATER_THAN = 0x3E; /* > */\nvar CHAR_QUESTION = 0x3F; /* ? */\nvar CHAR_COMMERCIAL_AT = 0x40; /* @ */\nvar CHAR_LEFT_SQUARE_BRACKET = 0x5B; /* [ */\nvar CHAR_RIGHT_SQUARE_BRACKET = 0x5D; /* ] */\nvar CHAR_GRAVE_ACCENT = 0x60; /* ` */\nvar CHAR_LEFT_CURLY_BRACKET = 0x7B; /* { */\nvar CHAR_VERTICAL_LINE = 0x7C; /* | */\nvar CHAR_RIGHT_CURLY_BRACKET = 0x7D; /* } */\n\nvar ESCAPE_SEQUENCES = {};\n\nESCAPE_SEQUENCES[0x00] = '\\\\0';\nESCAPE_SEQUENCES[0x07] = '\\\\a';\nESCAPE_SEQUENCES[0x08] = '\\\\b';\nESCAPE_SEQUENCES[0x09] = '\\\\t';\nESCAPE_SEQUENCES[0x0A] = '\\\\n';\nESCAPE_SEQUENCES[0x0B] = '\\\\v';\nESCAPE_SEQUENCES[0x0C] = '\\\\f';\nESCAPE_SEQUENCES[0x0D] = '\\\\r';\nESCAPE_SEQUENCES[0x1B] = '\\\\e';\nESCAPE_SEQUENCES[0x22] = '\\\\\"';\nESCAPE_SEQUENCES[0x5C] = '\\\\\\\\';\nESCAPE_SEQUENCES[0x85] = '\\\\N';\nESCAPE_SEQUENCES[0xA0] = '\\\\_';\nESCAPE_SEQUENCES[0x2028] = '\\\\L';\nESCAPE_SEQUENCES[0x2029] = '\\\\P';\n\nvar DEPRECATED_BOOLEANS_SYNTAX = [\n 'y', 'Y', 'yes', 'Yes', 'YES', 'on', 'On', 'ON',\n 'n', 'N', 'no', 'No', 'NO', 'off', 'Off', 'OFF'\n];\n\nvar DEPRECATED_BASE60_SYNTAX = /^[-+]?[0-9_]+(?::[0-9_]+)+(?:\\.[0-9_]*)?$/;\n\nfunction compileStyleMap(schema, map) {\n var result, keys, index, length, tag, style, type;\n\n if (map === null) return {};\n\n result = {};\n keys = Object.keys(map);\n\n for (index = 0, length = keys.length; index < length; index += 1) {\n tag = keys[index];\n style = String(map[tag]);\n\n if (tag.slice(0, 2) === '!!') {\n tag = 'tag:yaml.org,2002:' + tag.slice(2);\n }\n type = schema.compiledTypeMap['fallback'][tag];\n\n if (type && _hasOwnProperty.call(type.styleAliases, style)) {\n style = type.styleAliases[style];\n }\n\n result[tag] = style;\n }\n\n return result;\n}\n\nfunction encodeHex(character) {\n var string, handle, length;\n\n string = character.toString(16).toUpperCase();\n\n if (character <= 0xFF) {\n handle = 'x';\n length = 2;\n } else if (character <= 0xFFFF) {\n handle = 'u';\n length = 4;\n } else if (character <= 0xFFFFFFFF) {\n handle = 'U';\n length = 8;\n } else {\n throw new exception('code point within a string may not be greater than 0xFFFFFFFF');\n }\n\n return '\\\\' + handle + common.repeat('0', length - string.length) + string;\n}\n\n\nvar QUOTING_TYPE_SINGLE = 1,\n QUOTING_TYPE_DOUBLE = 2;\n\nfunction State(options) {\n this.schema = options['schema'] || _default;\n this.indent = Math.max(1, (options['indent'] || 2));\n this.noArrayIndent = options['noArrayIndent'] || false;\n this.skipInvalid = options['skipInvalid'] || false;\n this.flowLevel = (common.isNothing(options['flowLevel']) ? -1 : options['flowLevel']);\n this.styleMap = compileStyleMap(this.schema, options['styles'] || null);\n this.sortKeys = options['sortKeys'] || false;\n this.lineWidth = options['lineWidth'] || 80;\n this.noRefs = options['noRefs'] || false;\n this.noCompatMode = options['noCompatMode'] || false;\n this.condenseFlow = options['condenseFlow'] || false;\n this.quotingType = options['quotingType'] === '\"' ? QUOTING_TYPE_DOUBLE : QUOTING_TYPE_SINGLE;\n this.forceQuotes = options['forceQuotes'] || false;\n this.replacer = typeof options['replacer'] === 'function' ? options['replacer'] : null;\n\n this.implicitTypes = this.schema.compiledImplicit;\n this.explicitTypes = this.schema.compiledExplicit;\n\n this.tag = null;\n this.result = '';\n\n this.duplicates = [];\n this.usedDuplicates = null;\n}\n\n// Indents every line in a string. Empty lines (\\n only) are not indented.\nfunction indentString(string, spaces) {\n var ind = common.repeat(' ', spaces),\n position = 0,\n next = -1,\n result = '',\n line,\n length = string.length;\n\n while (position < length) {\n next = string.indexOf('\\n', position);\n if (next === -1) {\n line = string.slice(position);\n position = length;\n } else {\n line = string.slice(position, next + 1);\n position = next + 1;\n }\n\n if (line.length && line !== '\\n') result += ind;\n\n result += line;\n }\n\n return result;\n}\n\nfunction generateNextLine(state, level) {\n return '\\n' + common.repeat(' ', state.indent * level);\n}\n\nfunction testImplicitResolving(state, str) {\n var index, length, type;\n\n for (index = 0, length = state.implicitTypes.length; index < length; index += 1) {\n type = state.implicitTypes[index];\n\n if (type.resolve(str)) {\n return true;\n }\n }\n\n return false;\n}\n\n// [33] s-white ::= s-space | s-tab\nfunction isWhitespace(c) {\n return c === CHAR_SPACE || c === CHAR_TAB;\n}\n\n// Returns true if the character can be printed without escaping.\n// From YAML 1.2: \"any allowed characters known to be non-printable\n// should also be escaped. [However,] This isn\u2019t mandatory\"\n// Derived from nb-char - \\t - #x85 - #xA0 - #x2028 - #x2029.\nfunction isPrintable(c) {\n return (0x00020 <= c && c <= 0x00007E)\n || ((0x000A1 <= c && c <= 0x00D7FF) && c !== 0x2028 && c !== 0x2029)\n || ((0x0E000 <= c && c <= 0x00FFFD) && c !== CHAR_BOM)\n || (0x10000 <= c && c <= 0x10FFFF);\n}\n\n// [34] ns-char ::= nb-char - s-white\n// [27] nb-char ::= c-printable - b-char - c-byte-order-mark\n// [26] b-char ::= b-line-feed | b-carriage-return\n// Including s-white (for some reason, examples doesn't match specs in this aspect)\n// ns-char ::= c-printable - b-line-feed - b-carriage-return - c-byte-order-mark\nfunction isNsCharOrWhitespace(c) {\n return isPrintable(c)\n && c !== CHAR_BOM\n // - b-char\n && c !== CHAR_CARRIAGE_RETURN\n && c !== CHAR_LINE_FEED;\n}\n\n// [127] ns-plain-safe(c) ::= c = flow-out \u21D2 ns-plain-safe-out\n// c = flow-in \u21D2 ns-plain-safe-in\n// c = block-key \u21D2 ns-plain-safe-out\n// c = flow-key \u21D2 ns-plain-safe-in\n// [128] ns-plain-safe-out ::= ns-char\n// [129] ns-plain-safe-in ::= ns-char - c-flow-indicator\n// [130] ns-plain-char(c) ::= ( ns-plain-safe(c) - \u201C:\u201D - \u201C#\u201D )\n// | ( /* An ns-char preceding */ \u201C#\u201D )\n// | ( \u201C:\u201D /* Followed by an ns-plain-safe(c) */ )\nfunction isPlainSafe(c, prev, inblock) {\n var cIsNsCharOrWhitespace = isNsCharOrWhitespace(c);\n var cIsNsChar = cIsNsCharOrWhitespace && !isWhitespace(c);\n return (\n // ns-plain-safe\n inblock ? // c = flow-in\n cIsNsCharOrWhitespace\n : cIsNsCharOrWhitespace\n // - c-flow-indicator\n && c !== CHAR_COMMA\n && c !== CHAR_LEFT_SQUARE_BRACKET\n && c !== CHAR_RIGHT_SQUARE_BRACKET\n && c !== CHAR_LEFT_CURLY_BRACKET\n && c !== CHAR_RIGHT_CURLY_BRACKET\n )\n // ns-plain-char\n && c !== CHAR_SHARP // false on '#'\n && !(prev === CHAR_COLON && !cIsNsChar) // false on ': '\n || (isNsCharOrWhitespace(prev) && !isWhitespace(prev) && c === CHAR_SHARP) // change to true on '[^ ]#'\n || (prev === CHAR_COLON && cIsNsChar); // change to true on ':[^ ]'\n}\n\n// Simplified test for values allowed as the first character in plain style.\nfunction isPlainSafeFirst(c) {\n // Uses a subset of ns-char - c-indicator\n // where ns-char = nb-char - s-white.\n // No support of ( ( \u201C?\u201D | \u201C:\u201D | \u201C-\u201D ) /* Followed by an ns-plain-safe(c)) */ ) part\n return isPrintable(c) && c !== CHAR_BOM\n && !isWhitespace(c) // - s-white\n // - (c-indicator ::=\n // \u201C-\u201D | \u201C?\u201D | \u201C:\u201D | \u201C,\u201D | \u201C[\u201D | \u201C]\u201D | \u201C{\u201D | \u201C}\u201D\n && c !== CHAR_MINUS\n && c !== CHAR_QUESTION\n && c !== CHAR_COLON\n && c !== CHAR_COMMA\n && c !== CHAR_LEFT_SQUARE_BRACKET\n && c !== CHAR_RIGHT_SQUARE_BRACKET\n && c !== CHAR_LEFT_CURLY_BRACKET\n && c !== CHAR_RIGHT_CURLY_BRACKET\n // | \u201C#\u201D | \u201C&\u201D | \u201C*\u201D | \u201C!\u201D | \u201C|\u201D | \u201C=\u201D | \u201C>\u201D | \u201C'\u201D | \u201C\"\u201D\n && c !== CHAR_SHARP\n && c !== CHAR_AMPERSAND\n && c !== CHAR_ASTERISK\n && c !== CHAR_EXCLAMATION\n && c !== CHAR_VERTICAL_LINE\n && c !== CHAR_EQUALS\n && c !== CHAR_GREATER_THAN\n && c !== CHAR_SINGLE_QUOTE\n && c !== CHAR_DOUBLE_QUOTE\n // | \u201C%\u201D | \u201C@\u201D | \u201C`\u201D)\n && c !== CHAR_PERCENT\n && c !== CHAR_COMMERCIAL_AT\n && c !== CHAR_GRAVE_ACCENT;\n}\n\n// Simplified test for values allowed as the last character in plain style.\nfunction isPlainSafeLast(c) {\n // just not whitespace or colon, it will be checked to be plain character later\n return !isWhitespace(c) && c !== CHAR_COLON;\n}\n\n// Same as 'string'.codePointAt(pos), but works in older browsers.\nfunction codePointAt(string, pos) {\n var first = string.charCodeAt(pos), second;\n if (first >= 0xD800 && first <= 0xDBFF && pos + 1 < string.length) {\n second = string.charCodeAt(pos + 1);\n if (second >= 0xDC00 && second <= 0xDFFF) {\n // https://mathiasbynens.be/notes/javascript-encoding#surrogate-formulae\n return (first - 0xD800) * 0x400 + second - 0xDC00 + 0x10000;\n }\n }\n return first;\n}\n\n// Determines whether block indentation indicator is required.\nfunction needIndentIndicator(string) {\n var leadingSpaceRe = /^\\n* /;\n return leadingSpaceRe.test(string);\n}\n\nvar STYLE_PLAIN = 1,\n STYLE_SINGLE = 2,\n STYLE_LITERAL = 3,\n STYLE_FOLDED = 4,\n STYLE_DOUBLE = 5;\n\n// Determines which scalar styles are possible and returns the preferred style.\n// lineWidth = -1 => no limit.\n// Pre-conditions: str.length > 0.\n// Post-conditions:\n// STYLE_PLAIN or STYLE_SINGLE => no \\n are in the string.\n// STYLE_LITERAL => no lines are suitable for folding (or lineWidth is -1).\n// STYLE_FOLDED => a line > lineWidth and can be folded (and lineWidth != -1).\nfunction chooseScalarStyle(string, singleLineOnly, indentPerLevel, lineWidth,\n testAmbiguousType, quotingType, forceQuotes, inblock) {\n\n var i;\n var char = 0;\n var prevChar = null;\n var hasLineBreak = false;\n var hasFoldableLine = false; // only checked if shouldTrackWidth\n var shouldTrackWidth = lineWidth !== -1;\n var previousLineBreak = -1; // count the first line correctly\n var plain = isPlainSafeFirst(codePointAt(string, 0))\n && isPlainSafeLast(codePointAt(string, string.length - 1));\n\n if (singleLineOnly || forceQuotes) {\n // Case: no block styles.\n // Check for disallowed characters to rule out plain and single.\n for (i = 0; i < string.length; char >= 0x10000 ? i += 2 : i++) {\n char = codePointAt(string, i);\n if (!isPrintable(char)) {\n return STYLE_DOUBLE;\n }\n plain = plain && isPlainSafe(char, prevChar, inblock);\n prevChar = char;\n }\n } else {\n // Case: block styles permitted.\n for (i = 0; i < string.length; char >= 0x10000 ? i += 2 : i++) {\n char = codePointAt(string, i);\n if (char === CHAR_LINE_FEED) {\n hasLineBreak = true;\n // Check if any line can be folded.\n if (shouldTrackWidth) {\n hasFoldableLine = hasFoldableLine ||\n // Foldable line = too long, and not more-indented.\n (i - previousLineBreak - 1 > lineWidth &&\n string[previousLineBreak + 1] !== ' ');\n previousLineBreak = i;\n }\n } else if (!isPrintable(char)) {\n return STYLE_DOUBLE;\n }\n plain = plain && isPlainSafe(char, prevChar, inblock);\n prevChar = char;\n }\n // in case the end is missing a \\n\n hasFoldableLine = hasFoldableLine || (shouldTrackWidth &&\n (i - previousLineBreak - 1 > lineWidth &&\n string[previousLineBreak + 1] !== ' '));\n }\n // Although every style can represent \\n without escaping, prefer block styles\n // for multiline, since they're more readable and they don't add empty lines.\n // Also prefer folding a super-long line.\n if (!hasLineBreak && !hasFoldableLine) {\n // Strings interpretable as another type have to be quoted;\n // e.g. the string 'true' vs. the boolean true.\n if (plain && !forceQuotes && !testAmbiguousType(string)) {\n return STYLE_PLAIN;\n }\n return quotingType === QUOTING_TYPE_DOUBLE ? STYLE_DOUBLE : STYLE_SINGLE;\n }\n // Edge case: block indentation indicator can only have one digit.\n if (indentPerLevel > 9 && needIndentIndicator(string)) {\n return STYLE_DOUBLE;\n }\n // At this point we know block styles are valid.\n // Prefer literal style unless we want to fold.\n if (!forceQuotes) {\n return hasFoldableLine ? STYLE_FOLDED : STYLE_LITERAL;\n }\n return quotingType === QUOTING_TYPE_DOUBLE ? STYLE_DOUBLE : STYLE_SINGLE;\n}\n\n// Note: line breaking/folding is implemented for only the folded style.\n// NB. We drop the last trailing newline (if any) of a returned block scalar\n// since the dumper adds its own newline. This always works:\n// \u2022 No ending newline => unaffected; already using strip \"-\" chomping.\n// \u2022 Ending newline => removed then restored.\n// Importantly, this keeps the \"+\" chomp indicator from gaining an extra line.\nfunction writeScalar(state, string, level, iskey, inblock) {\n state.dump = (function () {\n if (string.length === 0) {\n return state.quotingType === QUOTING_TYPE_DOUBLE ? '\"\"' : \"''\";\n }\n if (!state.noCompatMode) {\n if (DEPRECATED_BOOLEANS_SYNTAX.indexOf(string) !== -1 || DEPRECATED_BASE60_SYNTAX.test(string)) {\n return state.quotingType === QUOTING_TYPE_DOUBLE ? ('\"' + string + '\"') : (\"'\" + string + \"'\");\n }\n }\n\n var indent = state.indent * Math.max(1, level); // no 0-indent scalars\n // As indentation gets deeper, let the width decrease monotonically\n // to the lower bound min(state.lineWidth, 40).\n // Note that this implies\n // state.lineWidth \u2264 40 + state.indent: width is fixed at the lower bound.\n // state.lineWidth > 40 + state.indent: width decreases until the lower bound.\n // This behaves better than a constant minimum width which disallows narrower options,\n // or an indent threshold which causes the width to suddenly increase.\n var lineWidth = state.lineWidth === -1\n ? -1 : Math.max(Math.min(state.lineWidth, 40), state.lineWidth - indent);\n\n // Without knowing if keys are implicit/explicit, assume implicit for safety.\n var singleLineOnly = iskey\n // No block styles in flow mode.\n || (state.flowLevel > -1 && level >= state.flowLevel);\n function testAmbiguity(string) {\n return testImplicitResolving(state, string);\n }\n\n switch (chooseScalarStyle(string, singleLineOnly, state.indent, lineWidth,\n testAmbiguity, state.quotingType, state.forceQuotes && !iskey, inblock)) {\n\n case STYLE_PLAIN:\n return string;\n case STYLE_SINGLE:\n return \"'\" + string.replace(/'/g, \"''\") + \"'\";\n case STYLE_LITERAL:\n return '|' + blockHeader(string, state.indent)\n + dropEndingNewline(indentString(string, indent));\n case STYLE_FOLDED:\n return '>' + blockHeader(string, state.indent)\n + dropEndingNewline(indentString(foldString(string, lineWidth), indent));\n case STYLE_DOUBLE:\n return '\"' + escapeString(string) + '\"';\n default:\n throw new exception('impossible error: invalid scalar style');\n }\n }());\n}\n\n// Pre-conditions: string is valid for a block scalar, 1 <= indentPerLevel <= 9.\nfunction blockHeader(string, indentPerLevel) {\n var indentIndicator = needIndentIndicator(string) ? String(indentPerLevel) : '';\n\n // note the special case: the string '\\n' counts as a \"trailing\" empty line.\n var clip = string[string.length - 1] === '\\n';\n var keep = clip && (string[string.length - 2] === '\\n' || string === '\\n');\n var chomp = keep ? '+' : (clip ? '' : '-');\n\n return indentIndicator + chomp + '\\n';\n}\n\n// (See the note for writeScalar.)\nfunction dropEndingNewline(string) {\n return string[string.length - 1] === '\\n' ? string.slice(0, -1) : string;\n}\n\n// Note: a long line without a suitable break point will exceed the width limit.\n// Pre-conditions: every char in str isPrintable, str.length > 0, width > 0.\nfunction foldString(string, width) {\n // In folded style, $k$ consecutive newlines output as $k+1$ newlines\u2014\n // unless they're before or after a more-indented line, or at the very\n // beginning or end, in which case $k$ maps to $k$.\n // Therefore, parse each chunk as newline(s) followed by a content line.\n var lineRe = /(\\n+)([^\\n]*)/g;\n\n // first line (possibly an empty line)\n var result = (function () {\n var nextLF = string.indexOf('\\n');\n nextLF = nextLF !== -1 ? nextLF : string.length;\n lineRe.lastIndex = nextLF;\n return foldLine(string.slice(0, nextLF), width);\n }());\n // If we haven't reached the first content line yet, don't add an extra \\n.\n var prevMoreIndented = string[0] === '\\n' || string[0] === ' ';\n var moreIndented;\n\n // rest of the lines\n var match;\n while ((match = lineRe.exec(string))) {\n var prefix = match[1], line = match[2];\n moreIndented = (line[0] === ' ');\n result += prefix\n + (!prevMoreIndented && !moreIndented && line !== ''\n ? '\\n' : '')\n + foldLine(line, width);\n prevMoreIndented = moreIndented;\n }\n\n return result;\n}\n\n// Greedy line breaking.\n// Picks the longest line under the limit each time,\n// otherwise settles for the shortest line over the limit.\n// NB. More-indented lines *cannot* be folded, as that would add an extra \\n.\nfunction foldLine(line, width) {\n if (line === '' || line[0] === ' ') return line;\n\n // Since a more-indented line adds a \\n, breaks can't be followed by a space.\n var breakRe = / [^ ]/g; // note: the match index will always be <= length-2.\n var match;\n // start is an inclusive index. end, curr, and next are exclusive.\n var start = 0, end, curr = 0, next = 0;\n var result = '';\n\n // Invariants: 0 <= start <= length-1.\n // 0 <= curr <= next <= max(0, length-2). curr - start <= width.\n // Inside the loop:\n // A match implies length >= 2, so curr and next are <= length-2.\n while ((match = breakRe.exec(line))) {\n next = match.index;\n // maintain invariant: curr - start <= width\n if (next - start > width) {\n end = (curr > start) ? curr : next; // derive end <= length-2\n result += '\\n' + line.slice(start, end);\n // skip the space that was output as \\n\n start = end + 1; // derive start <= length-1\n }\n curr = next;\n }\n\n // By the invariants, start <= length-1, so there is something left over.\n // It is either the whole string or a part starting from non-whitespace.\n result += '\\n';\n // Insert a break if the remainder is too long and there is a break available.\n if (line.length - start > width && curr > start) {\n result += line.slice(start, curr) + '\\n' + line.slice(curr + 1);\n } else {\n result += line.slice(start);\n }\n\n return result.slice(1); // drop extra \\n joiner\n}\n\n// Escapes a double-quoted string.\nfunction escapeString(string) {\n var result = '';\n var char = 0;\n var escapeSeq;\n\n for (var i = 0; i < string.length; char >= 0x10000 ? i += 2 : i++) {\n char = codePointAt(string, i);\n escapeSeq = ESCAPE_SEQUENCES[char];\n\n if (!escapeSeq && isPrintable(char)) {\n result += string[i];\n if (char >= 0x10000) result += string[i + 1];\n } else {\n result += escapeSeq || encodeHex(char);\n }\n }\n\n return result;\n}\n\nfunction writeFlowSequence(state, level, object) {\n var _result = '',\n _tag = state.tag,\n index,\n length,\n value;\n\n for (index = 0, length = object.length; index < length; index += 1) {\n value = object[index];\n\n if (state.replacer) {\n value = state.replacer.call(object, String(index), value);\n }\n\n // Write only valid elements, put null instead of invalid elements.\n if (writeNode(state, level, value, false, false) ||\n (typeof value === 'undefined' &&\n writeNode(state, level, null, false, false))) {\n\n if (_result !== '') _result += ',' + (!state.condenseFlow ? ' ' : '');\n _result += state.dump;\n }\n }\n\n state.tag = _tag;\n state.dump = '[' + _result + ']';\n}\n\nfunction writeBlockSequence(state, level, object, compact) {\n var _result = '',\n _tag = state.tag,\n index,\n length,\n value;\n\n for (index = 0, length = object.length; index < length; index += 1) {\n value = object[index];\n\n if (state.replacer) {\n value = state.replacer.call(object, String(index), value);\n }\n\n // Write only valid elements, put null instead of invalid elements.\n if (writeNode(state, level + 1, value, true, true, false, true) ||\n (typeof value === 'undefined' &&\n writeNode(state, level + 1, null, true, true, false, true))) {\n\n if (!compact || _result !== '') {\n _result += generateNextLine(state, level);\n }\n\n if (state.dump && CHAR_LINE_FEED === state.dump.charCodeAt(0)) {\n _result += '-';\n } else {\n _result += '- ';\n }\n\n _result += state.dump;\n }\n }\n\n state.tag = _tag;\n state.dump = _result || '[]'; // Empty sequence if no valid values.\n}\n\nfunction writeFlowMapping(state, level, object) {\n var _result = '',\n _tag = state.tag,\n objectKeyList = Object.keys(object),\n index,\n length,\n objectKey,\n objectValue,\n pairBuffer;\n\n for (index = 0, length = objectKeyList.length; index < length; index += 1) {\n\n pairBuffer = '';\n if (_result !== '') pairBuffer += ', ';\n\n if (state.condenseFlow) pairBuffer += '\"';\n\n objectKey = objectKeyList[index];\n objectValue = object[objectKey];\n\n if (state.replacer) {\n objectValue = state.replacer.call(object, objectKey, objectValue);\n }\n\n if (!writeNode(state, level, objectKey, false, false)) {\n continue; // Skip this pair because of invalid key;\n }\n\n if (state.dump.length > 1024) pairBuffer += '? ';\n\n pairBuffer += state.dump + (state.condenseFlow ? '\"' : '') + ':' + (state.condenseFlow ? '' : ' ');\n\n if (!writeNode(state, level, objectValue, false, false)) {\n continue; // Skip this pair because of invalid value.\n }\n\n pairBuffer += state.dump;\n\n // Both key and value are valid.\n _result += pairBuffer;\n }\n\n state.tag = _tag;\n state.dump = '{' + _result + '}';\n}\n\nfunction writeBlockMapping(state, level, object, compact) {\n var _result = '',\n _tag = state.tag,\n objectKeyList = Object.keys(object),\n index,\n length,\n objectKey,\n objectValue,\n explicitPair,\n pairBuffer;\n\n // Allow sorting keys so that the output file is deterministic\n if (state.sortKeys === true) {\n // Default sorting\n objectKeyList.sort();\n } else if (typeof state.sortKeys === 'function') {\n // Custom sort function\n objectKeyList.sort(state.sortKeys);\n } else if (state.sortKeys) {\n // Something is wrong\n throw new exception('sortKeys must be a boolean or a function');\n }\n\n for (index = 0, length = objectKeyList.length; index < length; index += 1) {\n pairBuffer = '';\n\n if (!compact || _result !== '') {\n pairBuffer += generateNextLine(state, level);\n }\n\n objectKey = objectKeyList[index];\n objectValue = object[objectKey];\n\n if (state.replacer) {\n objectValue = state.replacer.call(object, objectKey, objectValue);\n }\n\n if (!writeNode(state, level + 1, objectKey, true, true, true)) {\n continue; // Skip this pair because of invalid key.\n }\n\n explicitPair = (state.tag !== null && state.tag !== '?') ||\n (state.dump && state.dump.length > 1024);\n\n if (explicitPair) {\n if (state.dump && CHAR_LINE_FEED === state.dump.charCodeAt(0)) {\n pairBuffer += '?';\n } else {\n pairBuffer += '? ';\n }\n }\n\n pairBuffer += state.dump;\n\n if (explicitPair) {\n pairBuffer += generateNextLine(state, level);\n }\n\n if (!writeNode(state, level + 1, objectValue, true, explicitPair)) {\n continue; // Skip this pair because of invalid value.\n }\n\n if (state.dump && CHAR_LINE_FEED === state.dump.charCodeAt(0)) {\n pairBuffer += ':';\n } else {\n pairBuffer += ': ';\n }\n\n pairBuffer += state.dump;\n\n // Both key and value are valid.\n _result += pairBuffer;\n }\n\n state.tag = _tag;\n state.dump = _result || '{}'; // Empty mapping if no valid pairs.\n}\n\nfunction detectType(state, object, explicit) {\n var _result, typeList, index, length, type, style;\n\n typeList = explicit ? state.explicitTypes : state.implicitTypes;\n\n for (index = 0, length = typeList.length; index < length; index += 1) {\n type = typeList[index];\n\n if ((type.instanceOf || type.predicate) &&\n (!type.instanceOf || ((typeof object === 'object') && (object instanceof type.instanceOf))) &&\n (!type.predicate || type.predicate(object))) {\n\n if (explicit) {\n if (type.multi && type.representName) {\n state.tag = type.representName(object);\n } else {\n state.tag = type.tag;\n }\n } else {\n state.tag = '?';\n }\n\n if (type.represent) {\n style = state.styleMap[type.tag] || type.defaultStyle;\n\n if (_toString.call(type.represent) === '[object Function]') {\n _result = type.represent(object, style);\n } else if (_hasOwnProperty.call(type.represent, style)) {\n _result = type.represent[style](object, style);\n } else {\n throw new exception('!<' + type.tag + '> tag resolver accepts not \"' + style + '\" style');\n }\n\n state.dump = _result;\n }\n\n return true;\n }\n }\n\n return false;\n}\n\n// Serializes `object` and writes it to global `result`.\n// Returns true on success, or false on invalid object.\n//\nfunction writeNode(state, level, object, block, compact, iskey, isblockseq) {\n state.tag = null;\n state.dump = object;\n\n if (!detectType(state, object, false)) {\n detectType(state, object, true);\n }\n\n var type = _toString.call(state.dump);\n var inblock = block;\n var tagStr;\n\n if (block) {\n block = (state.flowLevel < 0 || state.flowLevel > level);\n }\n\n var objectOrArray = type === '[object Object]' || type === '[object Array]',\n duplicateIndex,\n duplicate;\n\n if (objectOrArray) {\n duplicateIndex = state.duplicates.indexOf(object);\n duplicate = duplicateIndex !== -1;\n }\n\n if ((state.tag !== null && state.tag !== '?') || duplicate || (state.indent !== 2 && level > 0)) {\n compact = false;\n }\n\n if (duplicate && state.usedDuplicates[duplicateIndex]) {\n state.dump = '*ref_' + duplicateIndex;\n } else {\n if (objectOrArray && duplicate && !state.usedDuplicates[duplicateIndex]) {\n state.usedDuplicates[duplicateIndex] = true;\n }\n if (type === '[object Object]') {\n if (block && (Object.keys(state.dump).length !== 0)) {\n writeBlockMapping(state, level, state.dump, compact);\n if (duplicate) {\n state.dump = '&ref_' + duplicateIndex + state.dump;\n }\n } else {\n writeFlowMapping(state, level, state.dump);\n if (duplicate) {\n state.dump = '&ref_' + duplicateIndex + ' ' + state.dump;\n }\n }\n } else if (type === '[object Array]') {\n if (block && (state.dump.length !== 0)) {\n if (state.noArrayIndent && !isblockseq && level > 0) {\n writeBlockSequence(state, level - 1, state.dump, compact);\n } else {\n writeBlockSequence(state, level, state.dump, compact);\n }\n if (duplicate) {\n state.dump = '&ref_' + duplicateIndex + state.dump;\n }\n } else {\n writeFlowSequence(state, level, state.dump);\n if (duplicate) {\n state.dump = '&ref_' + duplicateIndex + ' ' + state.dump;\n }\n }\n } else if (type === '[object String]') {\n if (state.tag !== '?') {\n writeScalar(state, state.dump, level, iskey, inblock);\n }\n } else if (type === '[object Undefined]') {\n return false;\n } else {\n if (state.skipInvalid) return false;\n throw new exception('unacceptable kind of an object to dump ' + type);\n }\n\n if (state.tag !== null && state.tag !== '?') {\n // Need to encode all characters except those allowed by the spec:\n //\n // [35] ns-dec-digit ::= [#x30-#x39] /* 0-9 */\n // [36] ns-hex-digit ::= ns-dec-digit\n // | [#x41-#x46] /* A-F */ | [#x61-#x66] /* a-f */\n // [37] ns-ascii-letter ::= [#x41-#x5A] /* A-Z */ | [#x61-#x7A] /* a-z */\n // [38] ns-word-char ::= ns-dec-digit | ns-ascii-letter | \u201C-\u201D\n // [39] ns-uri-char ::= \u201C%\u201D ns-hex-digit ns-hex-digit | ns-word-char | \u201C#\u201D\n // | \u201C;\u201D | \u201C/\u201D | \u201C?\u201D | \u201C:\u201D | \u201C@\u201D | \u201C&\u201D | \u201C=\u201D | \u201C+\u201D | \u201C$\u201D | \u201C,\u201D\n // | \u201C_\u201D | \u201C.\u201D | \u201C!\u201D | \u201C~\u201D | \u201C*\u201D | \u201C'\u201D | \u201C(\u201D | \u201C)\u201D | \u201C[\u201D | \u201C]\u201D\n //\n // Also need to encode '!' because it has special meaning (end of tag prefix).\n //\n tagStr = encodeURI(\n state.tag[0] === '!' ? state.tag.slice(1) : state.tag\n ).replace(/!/g, '%21');\n\n if (state.tag[0] === '!') {\n tagStr = '!' + tagStr;\n } else if (tagStr.slice(0, 18) === 'tag:yaml.org,2002:') {\n tagStr = '!!' + tagStr.slice(18);\n } else {\n tagStr = '!<' + tagStr + '>';\n }\n\n state.dump = tagStr + ' ' + state.dump;\n }\n }\n\n return true;\n}\n\nfunction getDuplicateReferences(object, state) {\n var objects = [],\n duplicatesIndexes = [],\n index,\n length;\n\n inspectNode(object, objects, duplicatesIndexes);\n\n for (index = 0, length = duplicatesIndexes.length; index < length; index += 1) {\n state.duplicates.push(objects[duplicatesIndexes[index]]);\n }\n state.usedDuplicates = new Array(length);\n}\n\nfunction inspectNode(object, objects, duplicatesIndexes) {\n var objectKeyList,\n index,\n length;\n\n if (object !== null && typeof object === 'object') {\n index = objects.indexOf(object);\n if (index !== -1) {\n if (duplicatesIndexes.indexOf(index) === -1) {\n duplicatesIndexes.push(index);\n }\n } else {\n objects.push(object);\n\n if (Array.isArray(object)) {\n for (index = 0, length = object.length; index < length; index += 1) {\n inspectNode(object[index], objects, duplicatesIndexes);\n }\n } else {\n objectKeyList = Object.keys(object);\n\n for (index = 0, length = objectKeyList.length; index < length; index += 1) {\n inspectNode(object[objectKeyList[index]], objects, duplicatesIndexes);\n }\n }\n }\n }\n}\n\nfunction dump$1(input, options) {\n options = options || {};\n\n var state = new State(options);\n\n if (!state.noRefs) getDuplicateReferences(input, state);\n\n var value = input;\n\n if (state.replacer) {\n value = state.replacer.call({ '': value }, '', value);\n }\n\n if (writeNode(state, 0, value, true, true)) return state.dump + '\\n';\n\n return '';\n}\n\nvar dump_1 = dump$1;\n\nvar dumper = {\n\tdump: dump_1\n};\n\nfunction renamed(from, to) {\n return function () {\n throw new Error('Function yaml.' + from + ' is removed in js-yaml 4. ' +\n 'Use yaml.' + to + ' instead, which is now safe by default.');\n };\n}\n\n\nvar Type = type;\nvar Schema = schema;\nvar FAILSAFE_SCHEMA = failsafe;\nvar JSON_SCHEMA = json;\nvar CORE_SCHEMA = core;\nvar DEFAULT_SCHEMA = _default;\nvar load = loader.load;\nvar loadAll = loader.loadAll;\nvar dump = dumper.dump;\nvar YAMLException = exception;\n\n// Re-export all types in case user wants to create custom schema\nvar types = {\n binary: binary,\n float: float,\n map: map,\n null: _null,\n pairs: pairs,\n set: set,\n timestamp: timestamp,\n bool: bool,\n int: int,\n merge: merge,\n omap: omap,\n seq: seq,\n str: str\n};\n\n// Removed functions from JS-YAML 3.0.x\nvar safeLoad = renamed('safeLoad', 'load');\nvar safeLoadAll = renamed('safeLoadAll', 'loadAll');\nvar safeDump = renamed('safeDump', 'dump');\n\nvar jsYaml = {\n\tType: Type,\n\tSchema: Schema,\n\tFAILSAFE_SCHEMA: FAILSAFE_SCHEMA,\n\tJSON_SCHEMA: JSON_SCHEMA,\n\tCORE_SCHEMA: CORE_SCHEMA,\n\tDEFAULT_SCHEMA: DEFAULT_SCHEMA,\n\tload: load,\n\tloadAll: loadAll,\n\tdump: dump,\n\tYAMLException: YAMLException,\n\ttypes: types,\n\tsafeLoad: safeLoad,\n\tsafeLoadAll: safeLoadAll,\n\tsafeDump: safeDump\n};\n\nexport { CORE_SCHEMA, DEFAULT_SCHEMA, FAILSAFE_SCHEMA, JSON_SCHEMA, Schema, Type, YAMLException, jsYaml as default, dump, load, loadAll, safeDump, safeLoad, safeLoadAll, types };\n", "/**\n * CodeQL metadata resolver utilities\n * Handles resolution of query metadata using the CodeQL CLI\n */\n\nimport { executeCodeQLCommand } from './cli-executor';\nimport { logger } from '../utils/logger';\n\n/**\n * Query metadata structure returned by codeql resolve metadata\n */\nexport interface QueryMetadata {\n [key: string]: string | string[];\n}\n\n/**\n * Resolve metadata for a CodeQL query file\n * @param queryPath - Absolute or relative path to the .ql query file\n * @returns Parsed metadata object or null if resolution fails\n */\nexport async function resolveQueryMetadata(queryPath: string): Promise {\n try {\n logger.info(`Resolving metadata for query: ${queryPath}`);\n\n const result = await executeCodeQLCommand(\n 'resolve metadata',\n { format: 'json' },\n [queryPath]\n );\n\n if (!result.success) {\n logger.error(`Failed to resolve metadata for ${queryPath}:`, result.stderr || result.error);\n return null;\n }\n\n // Parse the JSON output\n try {\n const metadata = JSON.parse(result.stdout);\n return metadata;\n } catch (parseError) {\n logger.error(`Failed to parse metadata JSON for ${queryPath}:`, parseError);\n return null;\n }\n } catch (error) {\n logger.error(`Error resolving metadata for ${queryPath}:`, error);\n return null;\n }\n}\n", "/**\n * CodeQL generate log-summary tool\n */\n\nimport { z } from 'zod';\nimport { CLIToolDefinition, createCodeQLSchemas, defaultCLIResultProcessor } from '../../lib/cli-tool-registry';\n\nexport const codeqlGenerateLogSummaryTool: CLIToolDefinition = {\n name: 'codeql_generate_log-summary',\n description: 'Create a summary of a structured JSON evaluator event log file',\n command: 'codeql',\n subcommand: 'generate log-summary',\n inputSchema: {\n inputLog: z.string().describe('Path to the evaluator log file to summarize'),\n outputFile: z.string().optional().describe('Path to write the summary (optional, defaults to stdout)'),\n format: z.enum(['text', 'predicates', 'overall']).optional()\n .describe('Output format: text (human-readable), predicates (JSON), or overall (stats)'),\n 'minify-output': z.boolean().optional().describe('Minify JSON output'),\n utc: z.boolean().optional().describe('Force UTC timestamps'),\n 'deduplicate-stage-summaries': z.boolean().optional().describe('Deduplicate stage summaries'),\n verbose: createCodeQLSchemas.verbose(),\n additionalArgs: createCodeQLSchemas.additionalArgs()\n },\n examples: [\n 'codeql generate log-summary --format=text -- evaluator-log.json.txt summary.txt',\n 'codeql generate log-summary --format=predicates --minify-output -- evaluator-log.json.txt',\n 'codeql generate log-summary --format=overall -- evaluator-log.json.txt overall-stats.json'\n ],\n resultProcessor: defaultCLIResultProcessor\n};", "/**\n * CodeQL generate query-help tool\n */\n\nimport { z } from 'zod';\nimport { CLIToolDefinition, createCodeQLSchemas, defaultCLIResultProcessor } from '../../lib/cli-tool-registry';\n\nexport const codeqlGenerateQueryHelpTool: CLIToolDefinition = {\n name: 'codeql_generate_query-help',\n description: 'Generate query help documentation from QLDoc comments',\n command: 'codeql',\n subcommand: 'generate query-help',\n inputSchema: {\n query: z.string().describe('Path to the query file to generate help for'),\n outputFile: z.string().optional().describe('Path to write the help documentation'),\n format: z.enum(['markdown', 'text', 'html']).optional()\n .describe('Output format for the help documentation'),\n verbose: createCodeQLSchemas.verbose(),\n additionalArgs: createCodeQLSchemas.additionalArgs()\n },\n examples: [\n 'codeql generate query-help -- MyQuery.ql',\n 'codeql generate query-help --format=markdown -- MyQuery.ql help.md',\n 'codeql generate query-help --format=html -- MyQuery.ql help.html'\n ],\n resultProcessor: defaultCLIResultProcessor\n};", "/**\n * list_codeql_databases tool\n *\n * Discovers CodeQL databases in configured base directories.\n * Scans each directory in `CODEQL_DATABASES_BASE_DIRS` for subdirectories\n * containing `codeql-database.yml`, extracts metadata (language, CLI version,\n * creation time), and returns the list.\n */\n\nimport { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport { existsSync, readdirSync, readFileSync, statSync } from 'fs';\nimport { join } from 'path';\nimport { z } from 'zod';\nimport { getDatabaseBaseDirs } from '../../lib/discovery-config';\nimport { logger } from '../../utils/logger';\n\nexport interface DatabaseInfo {\n cliVersion?: string;\n creationTime?: string;\n language?: string;\n name: string;\n path: string;\n}\n\n/**\n * Parse `codeql-database.yml` to extract metadata.\n * Uses simple line-based parsing to avoid a YAML dependency.\n */\nfunction parseDatabaseYml(ymlPath: string): Partial {\n try {\n const content = readFileSync(ymlPath, 'utf-8');\n const info: Partial = {};\n\n for (const line of content.split('\\n')) {\n const trimmed = line.trim();\n const colonIdx = trimmed.indexOf(':');\n if (colonIdx === -1) continue;\n\n const key = trimmed.substring(0, colonIdx).trim();\n const value = trimmed.substring(colonIdx + 1).trim().replace(/^[\"']|[\"']$/g, '');\n\n switch (key) {\n case 'primaryLanguage':\n info.language = value;\n break;\n case 'cliVersion':\n info.cliVersion = value;\n break;\n case 'creationTime':\n info.creationTime = value;\n break;\n }\n }\n\n return info;\n } catch {\n return {};\n }\n}\n\n/**\n * Discover CodeQL databases in the given base directories.\n *\n * @param baseDirs - Directories to scan for database subdirectories\n * @param language - Optional language filter\n * @returns List of discovered databases with metadata\n */\nexport async function discoverDatabases(\n baseDirs: string[],\n language?: string,\n): Promise {\n const databases: DatabaseInfo[] = [];\n\n for (const baseDir of baseDirs) {\n if (!existsSync(baseDir)) {\n continue;\n }\n\n let entries: string[];\n try {\n entries = readdirSync(baseDir);\n } catch {\n continue;\n }\n\n for (const entry of entries) {\n const entryPath = join(baseDir, entry);\n\n // Skip non-directories\n try {\n if (!statSync(entryPath).isDirectory()) {\n continue;\n }\n } catch {\n continue;\n }\n\n // Check for codeql-database.yml\n const ymlPath = join(entryPath, 'codeql-database.yml');\n if (!existsSync(ymlPath)) {\n continue;\n }\n\n const metadata = parseDatabaseYml(ymlPath);\n\n // Apply language filter\n if (language && metadata.language !== language) {\n continue;\n }\n\n databases.push({\n cliVersion: metadata.cliVersion,\n creationTime: metadata.creationTime,\n language: metadata.language,\n name: entry,\n path: entryPath,\n });\n }\n }\n\n return databases;\n}\n\n/**\n * Register the list_codeql_databases tool with the MCP server.\n */\nexport function registerListDatabasesTool(server: McpServer): void {\n server.tool(\n 'list_codeql_databases',\n 'List CodeQL databases discovered in configured base directories (set via CODEQL_DATABASES_BASE_DIRS env var). Returns path, language, CLI version, and creation time for each database.',\n {\n language: z\n .string()\n .optional()\n .describe('Filter databases by language (e.g., \"javascript\", \"python\")'),\n },\n async ({ language }) => {\n try {\n const baseDirs = getDatabaseBaseDirs();\n\n if (baseDirs.length === 0) {\n return {\n content: [\n {\n type: 'text' as const,\n text: 'No database base directories configured. Set the CODEQL_DATABASES_BASE_DIRS environment variable to a colon-separated list of directories to search.',\n },\n ],\n };\n }\n\n const databases = await discoverDatabases(baseDirs, language);\n\n if (databases.length === 0) {\n const filterMsg = language ? ` for language \"${language}\"` : '';\n return {\n content: [\n {\n type: 'text' as const,\n text: `No CodeQL databases found${filterMsg} in: ${baseDirs.join(', ')}`,\n },\n ],\n };\n }\n\n const lines = [\n `Found ${databases.length} CodeQL database(s):`,\n '',\n ...databases.map((db) => {\n const parts = [` ${db.name}`];\n parts.push(` Path: ${db.path}`);\n if (db.language) parts.push(` Language: ${db.language}`);\n if (db.cliVersion) parts.push(` CLI Version: ${db.cliVersion}`);\n if (db.creationTime) parts.push(` Created: ${db.creationTime}`);\n return parts.join('\\n');\n }),\n ];\n\n return {\n content: [{ type: 'text' as const, text: lines.join('\\n') }],\n };\n } catch (error) {\n logger.error('Error listing databases:', error);\n return {\n content: [\n {\n type: 'text' as const,\n text: `Error: ${error instanceof Error ? error.message : 'Unknown error'}`,\n },\n ],\n isError: true,\n };\n }\n },\n );\n}\n", "/**\n * Discovery configuration for locating CodeQL databases, query run results,\n * and MRVA (Multi-Repository Variant Analysis) run results.\n *\n * Reads colon-separated directory lists from environment variables:\n * - `CODEQL_DATABASES_BASE_DIRS` \u2014 directories to search for CodeQL databases\n * - `CODEQL_MRVA_RUN_RESULTS_DIRS` \u2014 directories containing MRVA run result subdirectories\n * - `CODEQL_QUERY_RUN_RESULTS_DIRS` \u2014 directories containing per-run query result subdirectories\n *\n * The VS Code extension sets these automatically from vscode-codeql storage paths.\n * CLI users can set them manually.\n */\n\n/**\n * Parse a colon-separated list of directories from an environment variable.\n */\nfunction parsePathList(envValue: string | undefined): string[] {\n if (!envValue) {\n return [];\n }\n return envValue\n .split(':')\n .map((p) => p.trim())\n .filter((p) => p.length > 0);\n}\n\n/**\n * Get the list of base directories to search for CodeQL databases.\n *\n * Each directory is expected to contain one or more CodeQL database directories\n * (each with a `codeql-database.yml` file).\n *\n * Set via `CODEQL_DATABASES_BASE_DIRS` (colon-separated).\n */\nexport function getDatabaseBaseDirs(): string[] {\n return parsePathList(process.env.CODEQL_DATABASES_BASE_DIRS);\n}\n\n/**\n * Get the list of directories containing MRVA run result subdirectories.\n *\n * Each directory is expected to contain numeric subdirectories (run IDs),\n * each holding `timestamp`, `repo_states.json`, and per-repository\n * subdirectories with `repo_task.json`, `results/results.sarif`, and\n * `results/results.bqrs`.\n *\n * Set via `CODEQL_MRVA_RUN_RESULTS_DIRS` (colon-separated).\n */\nexport function getMrvaRunResultsDirs(): string[] {\n return parsePathList(process.env.CODEQL_MRVA_RUN_RESULTS_DIRS);\n}\n\n/**\n * Get the list of directories containing per-run query result subdirectories.\n *\n * Each directory is expected to contain subdirectories named like\n * `.ql-/`, each holding artifacts such as\n * `evaluator-log.jsonl`, `results.bqrs`, and `results-interpreted.sarif`.\n *\n * Set via `CODEQL_QUERY_RUN_RESULTS_DIRS` (colon-separated).\n */\nexport function getQueryRunResultsDirs(): string[] {\n return parsePathList(process.env.CODEQL_QUERY_RUN_RESULTS_DIRS);\n}\n", "/**\n * list_mrva_run_results tool\n *\n * Discovers MRVA (Multi-Repository Variant Analysis) run result directories\n * in configured search paths.\n * Scans each directory in `CODEQL_MRVA_RUN_RESULTS_DIRS` for numeric\n * subdirectories representing variant analysis runs created by vscode-codeql.\n * Reports run ID, timestamp, repositories scanned, analysis status, and\n * available artifacts for each run.\n */\n\nimport { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport { existsSync, readdirSync, readFileSync, statSync } from 'fs';\nimport { join } from 'path';\nimport { z } from 'zod';\nimport { getMrvaRunResultsDirs } from '../../lib/discovery-config';\nimport { logger } from '../../utils/logger';\n\nexport interface MrvaRepoResult {\n analysisStatus?: string;\n fullName: string;\n hasBqrs: boolean;\n hasSarif: boolean;\n resultCount?: number;\n}\n\nexport interface MrvaRunResult {\n path: string;\n repositories: MrvaRepoResult[];\n runId: string;\n timestamp?: string;\n}\n\n/**\n * Pattern matching numeric MRVA run directory names.\n */\nconst NUMERIC_DIR_PATTERN = /^\\d+$/;\n\n/**\n * Directory names to skip when walking repository subdirectories.\n */\nconst SKIP_DIRS = new Set(['.DS_Store', 'exported-results']);\n\n/**\n * Discover MRVA run result directories in the given search paths.\n *\n * @param resultsDirs - Directories to scan for MRVA run subdirectories\n * @param runId - Optional run ID filter (e.g., \"20442\")\n * @returns List of discovered MRVA run results with repository inventory\n */\nexport async function discoverMrvaRunResults(\n resultsDirs: string[],\n runId?: string,\n): Promise {\n const results: MrvaRunResult[] = [];\n\n for (const dir of resultsDirs) {\n if (!existsSync(dir)) {\n continue;\n }\n\n let entries: string[];\n try {\n entries = readdirSync(dir);\n } catch {\n continue;\n }\n\n for (const entry of entries) {\n const entryPath = join(dir, entry);\n\n // Skip non-directories\n try {\n if (!statSync(entryPath).isDirectory()) {\n continue;\n }\n } catch {\n continue;\n }\n\n // Match numeric directory names\n if (!NUMERIC_DIR_PATTERN.test(entry)) {\n continue;\n }\n\n // Apply run ID filter\n if (runId && entry !== runId) {\n continue;\n }\n\n // Read timestamp if available\n let timestamp: string | undefined;\n const timestampPath = join(entryPath, 'timestamp');\n if (existsSync(timestampPath)) {\n try {\n timestamp = readFileSync(timestampPath, 'utf-8').trim();\n } catch {\n // Ignore read errors\n }\n }\n\n // Discover repository subdirectories\n const repositories = discoverRepoResults(entryPath);\n\n results.push({\n path: entryPath,\n repositories,\n runId: entry,\n timestamp,\n });\n }\n }\n\n return results;\n}\n\n/**\n * Walk a single MRVA run directory to discover per-repository results.\n *\n * The directory structure is `//` containing `repo_task.json`\n * and optionally `results/results.sarif` and `results/results.bqrs`.\n */\nfunction discoverRepoResults(runPath: string): MrvaRepoResult[] {\n const repos: MrvaRepoResult[] = [];\n\n let ownerEntries: string[];\n try {\n ownerEntries = readdirSync(runPath);\n } catch {\n return repos;\n }\n\n for (const ownerEntry of ownerEntries) {\n if (SKIP_DIRS.has(ownerEntry)) {\n continue;\n }\n\n // Skip non-directory entries (timestamp, repo_states.json, etc.)\n const ownerPath = join(runPath, ownerEntry);\n try {\n if (!statSync(ownerPath).isDirectory()) {\n continue;\n }\n } catch {\n continue;\n }\n\n let repoEntries: string[];\n try {\n repoEntries = readdirSync(ownerPath);\n } catch {\n continue;\n }\n\n for (const repoEntry of repoEntries) {\n const repoPath = join(ownerPath, repoEntry);\n try {\n if (!statSync(repoPath).isDirectory()) {\n continue;\n }\n } catch {\n continue;\n }\n\n const fullName = `${ownerEntry}/${repoEntry}`;\n\n // Parse repo_task.json if present\n let analysisStatus: string | undefined;\n let resultCount: number | undefined;\n const repoTaskPath = join(repoPath, 'repo_task.json');\n if (existsSync(repoTaskPath)) {\n try {\n const raw = readFileSync(repoTaskPath, 'utf-8');\n const task = JSON.parse(raw);\n if (typeof task.analysisStatus === 'string') {\n analysisStatus = task.analysisStatus;\n }\n if (typeof task.resultCount === 'number') {\n resultCount = task.resultCount;\n }\n } catch {\n // Ignore parse errors\n }\n }\n\n // Check for SARIF and BQRS artifacts\n const hasSarif = existsSync(join(repoPath, 'results', 'results.sarif'));\n const hasBqrs = existsSync(join(repoPath, 'results', 'results.bqrs'));\n\n repos.push({\n analysisStatus,\n fullName,\n hasBqrs,\n hasSarif,\n resultCount,\n });\n }\n }\n\n return repos;\n}\n\n/**\n * Register the list_mrva_run_results tool with the MCP server.\n */\nexport function registerListMrvaRunResultsTool(server: McpServer): void {\n server.tool(\n 'list_mrva_run_results',\n 'List discovered MRVA (Multi-Repository Variant Analysis) run results (set via CODEQL_MRVA_RUN_RESULTS_DIRS env var). Returns run ID, timestamp, repositories scanned, analysis status, and available artifacts for each run.',\n {\n runId: z\n .string()\n .optional()\n .describe('Filter results by run ID (e.g., \"20442\")'),\n },\n async ({ runId }) => {\n try {\n const resultsDirs = getMrvaRunResultsDirs();\n\n if (resultsDirs.length === 0) {\n return {\n content: [\n {\n type: 'text' as const,\n text: 'No MRVA run results directories configured. Set the CODEQL_MRVA_RUN_RESULTS_DIRS environment variable to a colon-separated list of directories to search.',\n },\n ],\n };\n }\n\n const runs = await discoverMrvaRunResults(resultsDirs, runId);\n\n if (runs.length === 0) {\n const filterMsg = runId ? ` for run ID \"${runId}\"` : '';\n return {\n content: [\n {\n type: 'text' as const,\n text: `No MRVA run results found${filterMsg} in: ${resultsDirs.join(', ')}`,\n },\n ],\n };\n }\n\n const lines = [\n `Found ${runs.length} MRVA run result(s):`,\n '',\n ...runs.map((run) => {\n const parts = [` Run ${run.runId}`];\n parts.push(` Path: ${run.path}`);\n if (run.timestamp) parts.push(` Timestamp: ${run.timestamp}`);\n parts.push(` Repositories: ${run.repositories.length}`);\n for (const repo of run.repositories) {\n const artifacts: string[] = [];\n if (repo.hasSarif) artifacts.push('sarif');\n if (repo.hasBqrs) artifacts.push('bqrs');\n const status = repo.analysisStatus ?? 'unknown';\n const count = repo.resultCount !== undefined ? `, ${repo.resultCount} result(s)` : '';\n parts.push(` ${repo.fullName} [${status}${count}] artifacts: ${artifacts.length > 0 ? artifacts.join(', ') : 'none'}`);\n }\n return parts.join('\\n');\n }),\n ];\n\n return {\n content: [{ type: 'text' as const, text: lines.join('\\n') }],\n };\n } catch (error) {\n logger.error('Error listing MRVA run results:', error);\n return {\n content: [\n {\n type: 'text' as const,\n text: `Error: ${error instanceof Error ? error.message : 'Unknown error'}`,\n },\n ],\n isError: true,\n };\n }\n },\n );\n}\n", "/**\n * list_query_run_results tool\n *\n * Discovers per-query-run result directories in configured search paths.\n * Scans each directory in `CODEQL_QUERY_RUN_RESULTS_DIRS` for subdirectories\n * matching the `.ql-` naming convention used by vscode-codeql.\n * Reports which artifacts (evaluator logs, BQRS, SARIF) are present in each run.\n */\n\nimport { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport { existsSync, readdirSync, readFileSync, statSync } from 'fs';\nimport { join } from 'path';\nimport { z } from 'zod';\nimport { getQueryRunResultsDirs } from '../../lib/discovery-config';\nimport { logger } from '../../utils/logger';\n\nexport interface QueryRunResult {\n hasBqrs: boolean;\n hasEvaluatorLog: boolean;\n hasSarif: boolean;\n path: string;\n queryName: string;\n runId: string;\n timestamp?: string;\n}\n\n/**\n * Pattern matching vscode-codeql query run directory names: `.ql-`\n */\nconst QUERY_RUN_DIR_PATTERN = /^(.+\\.ql)-(.+)$/;\n\n/**\n * Discover query run result directories in the given search paths.\n *\n * @param resultsDirs - Directories to scan for per-run subdirectories\n * @param queryName - Optional query name filter (e.g., \"UI5Xss.ql\")\n * @returns List of discovered query run results with artifact inventory\n */\nexport async function discoverQueryRunResults(\n resultsDirs: string[],\n queryName?: string,\n): Promise {\n const results: QueryRunResult[] = [];\n\n for (const dir of resultsDirs) {\n if (!existsSync(dir)) {\n continue;\n }\n\n let entries: string[];\n try {\n entries = readdirSync(dir);\n } catch {\n continue;\n }\n\n for (const entry of entries) {\n const entryPath = join(dir, entry);\n\n // Skip non-directories\n try {\n if (!statSync(entryPath).isDirectory()) {\n continue;\n }\n } catch {\n continue;\n }\n\n // Match the naming pattern\n const match = QUERY_RUN_DIR_PATTERN.exec(entry);\n if (!match) {\n continue;\n }\n\n const [, name, runId] = match;\n\n // Apply query name filter\n if (queryName && name !== queryName) {\n continue;\n }\n\n // Check which artifacts are present\n const hasEvaluatorLog = existsSync(join(entryPath, 'evaluator-log.jsonl'));\n const hasBqrs = existsSync(join(entryPath, 'results.bqrs'));\n const hasSarif = existsSync(join(entryPath, 'results-interpreted.sarif'));\n\n // Read timestamp if available\n let timestamp: string | undefined;\n const timestampPath = join(entryPath, 'timestamp');\n if (existsSync(timestampPath)) {\n try {\n timestamp = readFileSync(timestampPath, 'utf-8').trim();\n } catch {\n // Ignore read errors\n }\n }\n\n results.push({\n hasBqrs,\n hasEvaluatorLog,\n hasSarif,\n path: entryPath,\n queryName: name,\n runId,\n timestamp,\n });\n }\n }\n\n return results;\n}\n\n/**\n * Register the list_query_run_results tool with the MCP server.\n */\nexport function registerListQueryRunResultsTool(server: McpServer): void {\n server.tool(\n 'list_query_run_results',\n 'List discovered query run result directories (set via CODEQL_QUERY_RUN_RESULTS_DIRS env var). Returns path, query name, timestamp, and available artifacts for each run.',\n {\n queryName: z\n .string()\n .optional()\n .describe('Filter results by query name (e.g., \"UI5Xss.ql\")'),\n },\n async ({ queryName }) => {\n try {\n const resultsDirs = getQueryRunResultsDirs();\n\n if (resultsDirs.length === 0) {\n return {\n content: [\n {\n type: 'text' as const,\n text: 'No query run results directories configured. Set the CODEQL_QUERY_RUN_RESULTS_DIRS environment variable to a colon-separated list of directories to search.',\n },\n ],\n };\n }\n\n const runs = await discoverQueryRunResults(resultsDirs, queryName);\n\n if (runs.length === 0) {\n const filterMsg = queryName ? ` for query \"${queryName}\"` : '';\n return {\n content: [\n {\n type: 'text' as const,\n text: `No query run results found${filterMsg} in: ${resultsDirs.join(', ')}`,\n },\n ],\n };\n }\n\n const lines = [\n `Found ${runs.length} query run result(s):`,\n '',\n ...runs.map((run) => {\n const artifacts: string[] = [];\n if (run.hasEvaluatorLog) artifacts.push('evaluator-log');\n if (run.hasBqrs) artifacts.push('bqrs');\n if (run.hasSarif) artifacts.push('sarif');\n const parts = [` ${run.queryName} (${run.runId})`];\n parts.push(` Path: ${run.path}`);\n if (run.timestamp) parts.push(` Timestamp: ${run.timestamp}`);\n parts.push(` Artifacts: ${artifacts.length > 0 ? artifacts.join(', ') : 'none'}`);\n return parts.join('\\n');\n }),\n ];\n\n return {\n content: [{ type: 'text' as const, text: lines.join('\\n') }],\n };\n } catch (error) {\n logger.error('Error listing query run results:', error);\n return {\n content: [\n {\n type: 'text' as const,\n text: `Error: ${error instanceof Error ? error.message : 'Unknown error'}`,\n },\n ],\n isError: true,\n };\n }\n },\n );\n}\n", "/**\n * CodeQL pack install tool\n */\n\nimport { z } from 'zod';\nimport { CLIToolDefinition, createCodeQLSchemas } from '../../lib/cli-tool-registry';\n\nexport const codeqlPackInstallTool: CLIToolDefinition = {\n name: 'codeql_pack_install',\n description: 'Install CodeQL pack dependencies',\n command: 'codeql',\n subcommand: 'pack install',\n inputSchema: {\n packDir: z.string().optional().describe('Directory containing qlpack.yml (default: current)'),\n force: z.boolean().optional().describe('Force reinstall of dependencies'),\n 'no-strict-mode': z.boolean().optional()\n .describe('Allow non-strict dependency resolution'),\n verbose: createCodeQLSchemas.verbose(),\n additionalArgs: createCodeQLSchemas.additionalArgs()\n },\n examples: [\n 'codeql pack install',\n 'codeql pack install --force /path/to/pack',\n 'codeql pack install --no-strict-mode'\n ]\n};", "/**\n * CodeQL pack ls tool\n */\n\nimport { z } from 'zod';\nimport { CLIToolDefinition, createCodeQLSchemas, defaultCLIResultProcessor } from '../../lib/cli-tool-registry';\n\nexport const codeqlPackLsTool: CLIToolDefinition = {\n name: 'codeql_pack_ls',\n description: 'List CodeQL packs under some local directory path',\n command: 'codeql',\n subcommand: 'pack ls',\n inputSchema: {\n dir: z.string().optional().describe('The root directory of the package or workspace, defaults to the current working directory'),\n format: z.enum(['text', 'json']).optional()\n .describe('Output format: text (default) or json'),\n groups: z.string().optional()\n .describe('List of CodeQL pack groups to include or exclude'),\n verbose: createCodeQLSchemas.verbose(),\n additionalArgs: createCodeQLSchemas.additionalArgs()\n },\n examples: [\n 'codeql pack ls -- .',\n 'codeql pack ls --format=json -- /path/to/pack-directory',\n 'codeql pack ls --format=json --groups=queries,tests -- .'\n ],\n resultProcessor: defaultCLIResultProcessor\n};", "/**\n * MCP tool: profile_codeql_query_from_logs\n *\n * Parses CodeQL query evaluation logs into a performance profile WITHOUT\n * running the query. Works with logs from `codeql query run`,\n * `codeql database analyze`, or vscode-codeql query history.\n */\n\nimport { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport { existsSync, mkdirSync, writeFileSync } from 'fs';\nimport { basename, dirname, join } from 'path';\nimport { z } from 'zod';\nimport {\n parseEvaluatorLog,\n type PredicateProfile,\n type ProfileData,\n} from '../../lib/evaluator-log-parser';\nimport { logger } from '../../utils/logger';\n\n// ---------------------------------------------------------------------------\n// Formatting helpers\n// ---------------------------------------------------------------------------\n\n/**\n * Format the full profile data as pretty-printed JSON.\n */\nfunction formatAsJson(profile: ProfileData): string {\n return JSON.stringify(profile, null, 2);\n}\n\n/**\n * Format profile data as a Mermaid diagram.\n *\n * For single-query logs the diagram has one query root node with sub-nodes\n * for the top-N most expensive predicates. For multi-query logs each query\n * gets its own sub-graph.\n */\nfunction formatAsMermaid(profile: ProfileData, topN: number): string {\n const lines: string[] = [];\n\n lines.push('```mermaid');\n lines.push('graph TD');\n lines.push('');\n\n if (profile.queries.length <= 1) {\n // Single query layout\n const query = profile.queries[0] ?? {\n queryName: 'unknown',\n totalDurationMs: 0,\n predicates: [],\n predicateCount: 0,\n cacheHits: 0,\n };\n const qLabel = sanitizeMermaid(basename(query.queryName));\n lines.push(\n ` QUERY[\"${qLabel}
Total: ${query.totalDurationMs.toFixed(2)}ms
Predicates: ${query.predicateCount}\"]`\n );\n lines.push('');\n\n const topPredicates = getTopPredicates(query.predicates, topN);\n topPredicates.forEach((pred, idx) => {\n const nodeId = `P${idx}`;\n const name = sanitizeMermaid(pred.predicateName).substring(0, 50);\n const dur = pred.durationMs.toFixed(2);\n const size =\n pred.resultSize !== undefined ? String(pred.resultSize) : '?';\n lines.push(\n ` ${nodeId}[\"${name}
${dur}ms | ${size} results\"]`\n );\n });\n\n lines.push('');\n\n topPredicates.forEach((_pred, idx) => {\n lines.push(` QUERY --> P${idx}`);\n });\n } else {\n // Multi-query layout\n lines.push(\n ` ROOT[\"Evaluation Log
${profile.queries.length} queries\"]`\n );\n lines.push('');\n\n profile.queries.forEach((query, qIdx) => {\n const qNodeId = `Q${qIdx}`;\n const qLabel = sanitizeMermaid(basename(query.queryName));\n lines.push(\n ` ${qNodeId}[\"${qLabel}
${query.totalDurationMs.toFixed(2)}ms
Predicates: ${query.predicateCount}\"]`\n );\n lines.push(` ROOT --> ${qNodeId}`);\n\n const topPredicates = getTopPredicates(query.predicates, topN);\n topPredicates.forEach((pred, pIdx) => {\n const nodeId = `Q${qIdx}P${pIdx}`;\n const name = sanitizeMermaid(pred.predicateName).substring(0, 50);\n const dur = pred.durationMs.toFixed(2);\n const size =\n pred.resultSize !== undefined ? String(pred.resultSize) : '?';\n lines.push(\n ` ${nodeId}[\"${name}
${dur}ms | ${size} results\"]`\n );\n lines.push(` ${qNodeId} --> ${nodeId}`);\n });\n lines.push('');\n });\n }\n\n lines.push('');\n lines.push(\n ' classDef default fill:#e1f5ff,stroke:#333,stroke-width:2px'\n );\n lines.push(\n ' classDef query fill:#ffe1e1,stroke:#333,stroke-width:3px'\n );\n lines.push(' class QUERY query');\n lines.push('```');\n\n return lines.join('\\n');\n}\n\n/**\n * Sanitize a string for safe inclusion in a Mermaid node label.\n */\nfunction sanitizeMermaid(text: string): string {\n return text.replace(/[<>\"]/g, '');\n}\n\n/**\n * Return the top-N most expensive predicates sorted by descending duration.\n */\nfunction getTopPredicates(\n predicates: PredicateProfile[],\n topN: number\n): PredicateProfile[] {\n return [...predicates]\n .sort((a, b) => b.durationMs - a.durationMs)\n .slice(0, topN);\n}\n\n// ---------------------------------------------------------------------------\n// Text summary\n// ---------------------------------------------------------------------------\n\nfunction buildTextSummary(\n profile: ProfileData,\n topN: number,\n outputFiles: string[]\n): string {\n const sections: string[] = [];\n\n sections.push('Query log profiling completed successfully!');\n sections.push('');\n sections.push('Output Files:');\n for (const f of outputFiles) {\n sections.push(` - ${f}`);\n }\n\n sections.push('');\n sections.push(`Log Format: ${profile.logFormat}`);\n if (profile.codeqlVersion) {\n sections.push(`CodeQL Version: ${profile.codeqlVersion}`);\n }\n sections.push(`Total Events: ${profile.totalEvents}`);\n sections.push(`Queries: ${profile.queries.length}`);\n\n for (const query of profile.queries) {\n sections.push('');\n sections.push(`--- ${basename(query.queryName)} ---`);\n sections.push(` Total Duration: ${query.totalDurationMs.toFixed(2)} ms`);\n sections.push(` Predicates Evaluated: ${query.predicateCount}`);\n sections.push(` Cache Hits: ${query.cacheHits}`);\n\n const top = getTopPredicates(query.predicates, topN);\n if (top.length > 0) {\n sections.push(` Top ${top.length} Most Expensive Predicates:`);\n top.forEach((pred, idx) => {\n const sizeStr =\n pred.resultSize !== undefined ? `, ${pred.resultSize} results` : '';\n sections.push(\n ` ${idx + 1}. ${pred.predicateName} (${pred.durationMs.toFixed(2)} ms${sizeStr})`\n );\n });\n }\n }\n\n return sections.join('\\n');\n}\n\n// ---------------------------------------------------------------------------\n// Tool registration\n// ---------------------------------------------------------------------------\n\n/**\n * Register the `profile_codeql_query_from_logs` tool with the MCP server.\n */\nexport function registerProfileCodeQLQueryFromLogsTool(\n server: McpServer\n): void {\n server.tool(\n 'profile_codeql_query_from_logs',\n 'Parse CodeQL query evaluation logs into a performance profile without re-running the query. Works with logs from codeql query run, codeql database analyze, or vscode-codeql query history.',\n {\n evaluatorLog: z\n .string()\n .describe(\n 'Path to evaluator-log.jsonl or evaluator-log.summary.jsonl'\n ),\n outputDir: z\n .string()\n .optional()\n .describe(\n 'Directory to write profile output files (defaults to same directory as log)'\n ),\n topN: z\n .number()\n .optional()\n .describe(\n 'Number of most expensive predicates to highlight (default: 20)'\n ),\n },\n async (params) => {\n try {\n const { evaluatorLog, outputDir, topN } = params;\n const effectiveTopN = topN ?? 20;\n\n // Validate input path\n if (!existsSync(evaluatorLog)) {\n return {\n content: [\n {\n type: 'text' as const,\n text: `Evaluator log not found at: ${evaluatorLog}`,\n },\n ],\n isError: true,\n };\n }\n\n // Parse log\n logger.info(`Parsing evaluator log from: ${evaluatorLog}`);\n const profile = parseEvaluatorLog(evaluatorLog);\n\n // Determine output directory\n const profileOutputDir = outputDir ?? dirname(evaluatorLog);\n mkdirSync(profileOutputDir, { recursive: true });\n\n // Write profile JSON\n const jsonPath = join(\n profileOutputDir,\n 'query-evaluation-profile.json'\n );\n writeFileSync(jsonPath, formatAsJson(profile));\n logger.info(`Profile JSON written to: ${jsonPath}`);\n\n // Write Mermaid diagram\n const mdPath = join(\n profileOutputDir,\n 'query-evaluation-profile.md'\n );\n writeFileSync(mdPath, formatAsMermaid(profile, effectiveTopN));\n logger.info(`Profile Mermaid diagram written to: ${mdPath}`);\n\n // Build response\n const outputFilesList = [\n `Profile JSON: ${jsonPath}`,\n `Profile Mermaid: ${mdPath}`,\n `Evaluator Log: ${evaluatorLog}`,\n ];\n\n const responseText = buildTextSummary(\n profile,\n effectiveTopN,\n outputFilesList\n );\n\n return {\n content: [{ type: 'text' as const, text: responseText }],\n };\n } catch (error) {\n logger.error(\n 'Error profiling CodeQL query from logs:',\n error\n );\n return {\n content: [\n {\n type: 'text' as const,\n text: `Failed to profile query from logs: ${error instanceof Error ? error.message : String(error)}`,\n },\n ],\n isError: true,\n };\n }\n }\n );\n}\n", "/**\n * Reusable parser for CodeQL evaluator log files.\n *\n * Supports two formats:\n * - **Raw** (`evaluator-log.jsonl`): Pretty-printed JSON objects with a `type`\n * field (`LOG_HEADER`, `QUERY_STARTED`, `PREDICATE_STARTED`, etc.)\n * - **Summary** (`evaluator-log.summary.jsonl`): Pretty-printed JSON objects\n * without a `type` field; identified by `summaryLogVersion` or\n * `evaluationStrategy`.\n *\n * Both formats use pretty-printed JSON separated by `}\\n{` boundaries.\n */\n\nimport { readFileSync } from 'fs';\nimport { logger } from '../utils/logger';\n\n// ---------------------------------------------------------------------------\n// Public interfaces\n// ---------------------------------------------------------------------------\n\n/** Performance profile for a single evaluated predicate. */\nexport interface PredicateProfile {\n predicateName: string;\n position?: string;\n durationMs: number;\n resultSize?: number;\n pipelineCount?: number;\n evaluationStrategy?: string;\n dependencies: string[];\n}\n\n/** Performance profile for a single query within a log. */\nexport interface QueryProfile {\n queryName: string;\n totalDurationMs: number;\n predicateCount: number;\n predicates: PredicateProfile[];\n cacheHits: number;\n}\n\n/** Top-level result returned by all parse functions. */\nexport interface ProfileData {\n codeqlVersion?: string;\n logFormat: 'raw' | 'summary';\n queries: QueryProfile[];\n totalEvents: number;\n}\n\n// ---------------------------------------------------------------------------\n// Format detection\n// ---------------------------------------------------------------------------\n\n/**\n * Auto-detect whether the first parsed JSON object comes from a raw\n * evaluator log or a summary log.\n *\n * Raw events always contain a `type` string field.\n * Summary events never have `type`; the header carries `summaryLogVersion`.\n */\nexport function detectLogFormat(firstEvent: Record): 'raw' | 'summary' {\n if (typeof firstEvent.type === 'string') {\n return 'raw';\n }\n return 'summary';\n}\n\n// ---------------------------------------------------------------------------\n// Helpers\n// ---------------------------------------------------------------------------\n\n/**\n * Split a pretty-printed multi-JSON file into individual JSON strings.\n *\n * The log file contains multiple JSON objects that are pretty-printed,\n * separated by the pattern `}\\n\\n{` (closing brace, blank line, opening\n * brace). We split on `\\n}\\n` boundaries and reconstruct valid objects.\n */\nfunction splitJsonObjects(content: string): string[] {\n // Trim leading/trailing whitespace\n const trimmed = content.trim();\n if (trimmed.length === 0) {\n return [];\n }\n\n // Split on closing-brace + newline(s) + opening-brace boundaries.\n // We use a regex that matches `}\\n` followed by optional blank lines\n // then `{` \u2013 capturing the boundary so we can reconstruct.\n const parts = trimmed.split(/\\n\\}\\s*\\n\\s*\\{/);\n\n if (parts.length === 1) {\n // Single object or single-line \u2013 return as-is\n return [trimmed];\n }\n\n // Reconstruct: first part needs closing `}`, middle parts need both,\n // last part needs opening `{`.\n return parts.map((part, idx) => {\n if (idx === 0) {\n return part + '\\n}';\n }\n if (idx === parts.length - 1) {\n return '{\\n' + part;\n }\n return '{\\n' + part + '\\n}';\n });\n}\n\n/**\n * Parse all JSON objects from an evaluator log file.\n */\nfunction parseJsonObjects(logPath: string): Record[] {\n const content = readFileSync(logPath, 'utf-8');\n const objectStrings = splitJsonObjects(content);\n\n const results: Record[] = [];\n for (const objStr of objectStrings) {\n try {\n results.push(JSON.parse(objStr) as Record);\n } catch {\n logger.warn(\n `Failed to parse evaluator log object: ${objStr.substring(0, 120)}...`\n );\n }\n }\n return results;\n}\n\n// ---------------------------------------------------------------------------\n// Raw evaluator log parsing\n// ---------------------------------------------------------------------------\n\n/**\n * Parse a raw `evaluator-log.jsonl` file into {@link ProfileData}.\n *\n * Tracks `QUERY_STARTED`/`QUERY_COMPLETED` pairs, computes predicate\n * durations from `PREDICATE_STARTED`/`PREDICATE_COMPLETED` nanoTime\n * differences, and groups predicates by `queryCausingWork`.\n */\nexport function parseRawEvaluatorLog(logPath: string): ProfileData {\n const events = parseJsonObjects(logPath);\n\n let codeqlVersion: string | undefined;\n\n // Maps: eventId \u2192 event data for lookups\n const queryStartEvents = new Map<\n number,\n { queryName: string; nanoTime: number }\n >();\n const predicateStartEvents = new Map<\n number,\n {\n predicateName: string;\n position?: string;\n predicateType?: string;\n dependencies: string[];\n queryCausingWork?: number;\n nanoTime: number;\n pipelineCount: number;\n }\n >();\n\n // Completed predicate profiles grouped by query eventId\n const queryPredicates = new Map();\n // Query end nanoTimes keyed by query start eventId\n const queryEndNanoTimes = new Map();\n // Track cache lookups per query\n const queryCacheHits = new Map();\n // Fallback query eventId for predicates without queryCausingWork\n let firstQueryEventId: number | undefined;\n\n for (const event of events) {\n const eventType = event.type as string | undefined;\n\n switch (eventType) {\n case 'LOG_HEADER': {\n codeqlVersion = event.codeqlVersion as string | undefined;\n break;\n }\n\n case 'QUERY_STARTED': {\n const eid = event.eventId as number;\n const qName = (event.queryName as string) || 'unknown';\n queryStartEvents.set(eid, {\n queryName: qName,\n nanoTime: event.nanoTime as number,\n });\n queryPredicates.set(eid, []);\n queryCacheHits.set(eid, 0);\n if (firstQueryEventId === undefined) {\n firstQueryEventId = eid;\n }\n break;\n }\n\n case 'QUERY_COMPLETED': {\n const startEid = event.startEvent as number;\n queryEndNanoTimes.set(startEid, event.nanoTime as number);\n break;\n }\n\n case 'PREDICATE_STARTED': {\n const eid = event.eventId as number;\n const deps = event.dependencies as Record | undefined;\n predicateStartEvents.set(eid, {\n predicateName: (event.predicateName as string) || 'unknown',\n position: event.position as string | undefined,\n predicateType: event.predicateType as string | undefined,\n dependencies: deps ? Object.keys(deps) : [],\n queryCausingWork: event.queryCausingWork as number | undefined,\n nanoTime: event.nanoTime as number,\n pipelineCount: 0,\n });\n break;\n }\n\n case 'PIPELINE_COMPLETED': {\n // Count pipelines for the parent predicate\n const pipelineStartEid = event.startEvent as number;\n // Find the pipeline_started event to get predicateStartEvent\n const pipelineStartEvt = events.find(\n (e) =>\n (e.type as string) === 'PIPELINE_STARTED' &&\n (e.eventId as number) === pipelineStartEid\n );\n if (pipelineStartEvt) {\n const predEid = pipelineStartEvt.predicateStartEvent as number;\n const predStart = predicateStartEvents.get(predEid);\n if (predStart) {\n predStart.pipelineCount += 1;\n }\n }\n break;\n }\n\n case 'PREDICATE_COMPLETED': {\n const startEid = event.startEvent as number;\n const predStart = predicateStartEvents.get(startEid);\n if (predStart) {\n const durationNs =\n (event.nanoTime as number) - predStart.nanoTime;\n const durationMs = durationNs / 1_000_000;\n\n const profile: PredicateProfile = {\n predicateName: predStart.predicateName,\n position: predStart.position,\n durationMs,\n resultSize: event.resultSize as number | undefined,\n pipelineCount:\n predStart.pipelineCount > 0\n ? predStart.pipelineCount\n : undefined,\n evaluationStrategy: predStart.predicateType,\n dependencies: predStart.dependencies,\n };\n\n const qEid =\n predStart.queryCausingWork ?? firstQueryEventId;\n if (qEid !== undefined) {\n let arr = queryPredicates.get(qEid);\n if (!arr) {\n arr = [];\n queryPredicates.set(qEid, arr);\n }\n arr.push(profile);\n }\n }\n break;\n }\n\n case 'CACHE_LOOKUP': {\n // Attribute to the most recent query\n const qEid =\n (event.queryCausingWork as number | undefined) ??\n firstQueryEventId;\n if (qEid !== undefined) {\n queryCacheHits.set(qEid, (queryCacheHits.get(qEid) ?? 0) + 1);\n }\n break;\n }\n }\n }\n\n // Build QueryProfile entries\n const queries: QueryProfile[] = [];\n for (const [qEid, startInfo] of queryStartEvents) {\n const predicates = queryPredicates.get(qEid) ?? [];\n const endNano = queryEndNanoTimes.get(qEid);\n const totalDurationMs =\n endNano !== undefined\n ? (endNano - startInfo.nanoTime) / 1_000_000\n : predicates.reduce((sum, p) => sum + p.durationMs, 0);\n\n queries.push({\n queryName: startInfo.queryName,\n totalDurationMs,\n predicateCount: predicates.length,\n predicates,\n cacheHits: queryCacheHits.get(qEid) ?? 0,\n });\n }\n\n return {\n codeqlVersion,\n logFormat: 'raw',\n queries,\n totalEvents: events.length,\n };\n}\n\n// ---------------------------------------------------------------------------\n// Summary log parsing\n// ---------------------------------------------------------------------------\n\n/**\n * Parse an `evaluator-log.summary.jsonl` file into {@link ProfileData}.\n *\n * Summary events carry `millis` directly (already in ms). Predicates are\n * grouped by `queryCausingWork` which is a **string** (query name) in the\n * summary format.\n */\nexport function parseSummaryLog(logPath: string): ProfileData {\n const events = parseJsonObjects(logPath);\n\n let codeqlVersion: string | undefined;\n\n // queryCausingWork (string) \u2192 collected predicates\n const queryPredicatesMap = new Map();\n // Track total millis per query\n const queryTotalMs = new Map();\n // Track cache hits per query\n const queryCacheHits = new Map();\n\n for (const event of events) {\n // Header detection\n if (event.summaryLogVersion !== undefined) {\n codeqlVersion = event.codeqlVersion as string | undefined;\n continue;\n }\n\n const strategy = event.evaluationStrategy as string | undefined;\n\n // Skip sentinel-empty entries (no useful timing data)\n if (strategy === 'SENTINEL_EMPTY') {\n continue;\n }\n\n // Skip events without millis (non-predicate summaries)\n if (event.millis === undefined) {\n continue;\n }\n\n const predicateName =\n (event.predicateName as string) || 'unknown';\n const millis = event.millis as number;\n const queryName =\n (event.queryCausingWork as string) || 'unknown';\n\n const deps = event.dependencies as Record | undefined;\n const pipelineRuns = event.pipelineRuns as number | undefined;\n\n const profile: PredicateProfile = {\n predicateName,\n position: event.position as string | undefined,\n durationMs: millis,\n resultSize: event.resultSize as number | undefined,\n pipelineCount: pipelineRuns,\n evaluationStrategy: strategy,\n dependencies: deps ? Object.keys(deps) : [],\n };\n\n // Check if this is a cached entry\n if (event.isCached === true || strategy === 'CACHEHIT') {\n queryCacheHits.set(\n queryName,\n (queryCacheHits.get(queryName) ?? 0) + 1\n );\n }\n\n let arr = queryPredicatesMap.get(queryName);\n if (!arr) {\n arr = [];\n queryPredicatesMap.set(queryName, arr);\n }\n arr.push(profile);\n\n queryTotalMs.set(\n queryName,\n (queryTotalMs.get(queryName) ?? 0) + millis\n );\n }\n\n // Build QueryProfile entries\n const queries: QueryProfile[] = [];\n for (const [queryName, predicates] of queryPredicatesMap) {\n queries.push({\n queryName,\n totalDurationMs: queryTotalMs.get(queryName) ?? 0,\n predicateCount: predicates.length,\n predicates,\n cacheHits: queryCacheHits.get(queryName) ?? 0,\n });\n }\n\n return {\n codeqlVersion,\n logFormat: 'summary',\n queries,\n totalEvents: events.length,\n };\n}\n\n// ---------------------------------------------------------------------------\n// Auto-detect entry point\n// ---------------------------------------------------------------------------\n\n/**\n * Auto-detect the log format and parse accordingly.\n *\n * @param logPath - Absolute path to `evaluator-log.jsonl` or\n * `evaluator-log.summary.jsonl`.\n * @returns Parsed profile data.\n */\nexport function parseEvaluatorLog(logPath: string): ProfileData {\n const events = parseJsonObjects(logPath);\n\n if (events.length === 0) {\n return {\n logFormat: 'raw',\n queries: [],\n totalEvents: 0,\n };\n }\n\n const format = detectLogFormat(events[0]);\n\n if (format === 'raw') {\n return parseRawEvaluatorLog(logPath);\n }\n return parseSummaryLog(logPath);\n}\n", "/**\n * CodeQL query profiling tool\n */\n\nimport { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport { z } from 'zod';\nimport { executeCodeQLCommand } from '../../lib/cli-executor';\nimport { logger } from '../../utils/logger';\nimport { writeFileSync, readFileSync, existsSync } from 'fs';\nimport { join, dirname, basename } from 'path';\nimport { mkdirSync } from 'fs';\n\ninterface EvaluatorLogEvent {\n time: string;\n type: string;\n eventId: number;\n nanoTime: number;\n [key: string]: unknown;\n}\n\ninterface PipelineNode {\n eventId: number;\n name: string;\n position?: string;\n type?: string;\n startTime: number;\n endTime: number;\n duration: number;\n resultSize?: number;\n tupleCount?: number;\n dependencies: string[];\n dependencyEventIds: number[];\n}\n\ninterface ProfileData {\n queryName: string;\n totalDuration: number;\n totalEvents: number;\n pipelines: PipelineNode[];\n}\n\n/**\n * Parse evaluator log and create profile data\n */\nfunction parseEvaluatorLog(logPath: string): ProfileData {\n const logContent = readFileSync(logPath, 'utf-8');\n \n // Split by empty lines to get each JSON object (handles both JSONL and pretty-printed JSON)\n const jsonObjects = logContent.split('\\n\\n').filter((s) => s.trim());\n const events: EvaluatorLogEvent[] = jsonObjects\n .map((obj) => {\n try {\n return JSON.parse(obj);\n } catch (_error) {\n logger.warn(`Failed to parse evaluator log object: ${obj.substring(0, 100)}...`);\n return null;\n }\n })\n .filter((event): event is EvaluatorLogEvent => event !== null);\n\n // Map to track pipeline nodes by their start event ID\n const pipelineMap = new Map>();\n // Map to track dependency event IDs by predicate name\n const predicateNameToEventId = new Map();\n \n let queryName = '';\n let queryStartTime = 0;\n let queryEndTime = 0;\n\n for (const event of events) {\n switch (event.type) {\n case 'QUERY_STARTED':\n queryName = (event.queryName as string) || '';\n queryStartTime = event.nanoTime;\n break;\n\n case 'QUERY_COMPLETED':\n queryEndTime = event.nanoTime;\n break;\n\n case 'PREDICATE_STARTED': {\n const predicateName = event.predicateName as string;\n const position = event.position as string | undefined;\n const predicateType = event.predicateType as string | undefined;\n const dependencies = event.dependencies as Record | undefined;\n \n // Track this predicate's event ID by name for dependency resolution\n predicateNameToEventId.set(predicateName, event.eventId);\n \n // Get dependency event IDs\n const dependencyEventIds: number[] = [];\n const dependencyNames: string[] = [];\n if (dependencies) {\n for (const depName of Object.keys(dependencies)) {\n dependencyNames.push(depName);\n const depEventId = predicateNameToEventId.get(depName);\n if (depEventId !== undefined) {\n dependencyEventIds.push(depEventId);\n }\n }\n }\n\n pipelineMap.set(event.eventId, {\n eventId: event.eventId,\n name: predicateName,\n position,\n type: predicateType,\n startTime: event.nanoTime,\n dependencies: dependencyNames,\n dependencyEventIds,\n });\n break;\n }\n\n case 'PREDICATE_COMPLETED': {\n const startEventId = event.startEvent as number;\n const pipelineInfo = pipelineMap.get(startEventId);\n if (pipelineInfo) {\n const startEvent = events.find((e) => e.eventId === startEventId);\n if (startEvent) {\n const duration = (event.nanoTime - startEvent.nanoTime) / 1_000_000; // Convert to ms\n pipelineInfo.endTime = event.nanoTime;\n pipelineInfo.duration = duration;\n pipelineInfo.resultSize = event.resultSize as number | undefined;\n pipelineInfo.tupleCount = event.tupleCount as number | undefined;\n }\n }\n break;\n }\n }\n }\n\n // Convert to array and maintain original evaluation order (by eventId)\n const pipelines: PipelineNode[] = Array.from(pipelineMap.values())\n .filter((p): p is PipelineNode => p.duration !== undefined)\n .sort((a, b) => a.eventId - b.eventId);\n\n const totalDuration = queryEndTime > 0 ? (queryEndTime - queryStartTime) / 1_000_000 : 0;\n\n return {\n queryName,\n totalDuration,\n totalEvents: events.length,\n pipelines,\n };\n}\n\n/**\n * Format profile data as JSON\n */\nfunction formatAsJson(profile: ProfileData): string {\n return JSON.stringify(profile, null, 2);\n}\n\n/**\n * Format profile data as Mermaid diagram\n * Creates a graph showing the query evaluation pipelines in order of execution\n * with dependencies as edges, annotated with duration and result sizes\n */\nfunction formatAsMermaid(profile: ProfileData): string {\n const lines: string[] = [];\n\n lines.push('```mermaid');\n lines.push('graph TD');\n lines.push('');\n \n // Add query root node\n lines.push(` QUERY[\"${basename(profile.queryName)}
Total: ${profile.totalDuration.toFixed(2)}ms\"]`);\n lines.push('');\n \n // Create nodes for each pipeline in evaluation order (already sorted by eventId)\n profile.pipelines.forEach((pipeline) => {\n const nodeId = `P${pipeline.eventId}`;\n const duration = pipeline.duration.toFixed(2);\n const resultSize = pipeline.resultSize !== undefined ? pipeline.resultSize : '?';\n // Sanitize predicate name for Mermaid\n const name = pipeline.name.replace(/[<>]/g, '').substring(0, 40);\n lines.push(` ${nodeId}[\"${name}
${duration}ms | ${resultSize} results\"]`);\n });\n \n lines.push('');\n \n // Add edges from QUERY to root pipelines (those with no dependencies)\n const rootPipelines = profile.pipelines.filter((p) => p.dependencies.length === 0);\n \n rootPipelines.forEach((pipeline) => {\n lines.push(` QUERY --> P${pipeline.eventId}`);\n });\n \n lines.push('');\n \n // Add edges between pipelines based on dependencies (using eventIds to preserve links)\n profile.pipelines.forEach((pipeline) => {\n pipeline.dependencyEventIds.forEach((depEventId) => {\n const duration = pipeline.duration.toFixed(2);\n lines.push(` P${depEventId} -->|\"${duration}ms\"| P${pipeline.eventId}`);\n });\n });\n \n lines.push('');\n lines.push(' classDef default fill:#e1f5ff,stroke:#333,stroke-width:2px');\n lines.push(' classDef query fill:#ffe1e1,stroke:#333,stroke-width:3px');\n lines.push(' class QUERY query');\n lines.push('```');\n\n return lines.join('\\n');\n}\n\n/**\n * Register the profile_codeql_query tool\n */\nexport function registerProfileCodeQLQueryTool(server: McpServer): void {\n server.tool(\n 'profile_codeql_query',\n 'Profile the performance of a CodeQL query run against a specific database by analyzing the evaluator log JSON file',\n {\n query: z.string().describe('Path to the .ql query file'),\n database: z.string().describe('Path to the CodeQL database directory'),\n evaluatorLog: z\n .string()\n .optional()\n .describe(\n 'Path to an existing structured JSON log (e.g., evaluator-log.jsonl) file. If not provided, the tool will run the query to generate one.'\n ),\n outputDir: z\n .string()\n .optional()\n .describe('Directory to write profiling data files (defaults to same directory as evaluator log)'),\n },\n async (params) => {\n try {\n const { query, database, evaluatorLog, outputDir } = params;\n let logPath = evaluatorLog;\n let bqrsPath: string | undefined;\n let sarifPath: string | undefined;\n\n // If evaluator log not provided, run the query to generate one\n if (!logPath) {\n logger.info('No evaluator log provided, running query to generate one');\n\n // Determine output directory\n const defaultOutputDir = outputDir || join(dirname(query as string), 'profile-output');\n mkdirSync(defaultOutputDir, { recursive: true });\n\n logPath = join(defaultOutputDir, 'evaluator-log.jsonl');\n bqrsPath = join(defaultOutputDir, 'query-results.bqrs');\n sarifPath = join(defaultOutputDir, 'query-results.sarif');\n\n // Run query with evaluator logging and tuple counting\n const queryResult = await executeCodeQLCommand(\n 'query run',\n {\n database: database as string,\n output: bqrsPath,\n 'evaluator-log': logPath,\n 'tuple-counting': true,\n 'evaluator-log-level': 5,\n },\n [query as string]\n );\n\n if (!queryResult.success) {\n return {\n content: [\n {\n type: 'text' as const,\n text: `Failed to run query: ${queryResult.stderr || queryResult.error}`,\n },\n ],\n isError: true,\n };\n }\n\n // Generate SARIF interpretation\n if (existsSync(bqrsPath)) {\n try {\n const sarifResult = await executeCodeQLCommand(\n 'bqrs interpret',\n { format: 'sarif-latest', output: sarifPath },\n [bqrsPath]\n );\n\n if (sarifResult.success) {\n logger.info(`Generated SARIF interpretation at ${sarifPath}`);\n }\n } catch (error) {\n logger.warn(`Failed to generate SARIF interpretation: ${error}`);\n }\n }\n }\n\n // Verify evaluator log exists\n if (!existsSync(logPath)) {\n return {\n content: [\n {\n type: 'text' as const,\n text: `Evaluator log not found at: ${logPath}`,\n },\n ],\n isError: true,\n };\n }\n\n // Parse the evaluator log\n logger.info(`Parsing evaluator log from: ${logPath}`);\n const profile = parseEvaluatorLog(logPath);\n\n // Determine output directory for profile\n const profileOutputDir = outputDir || dirname(logPath);\n mkdirSync(profileOutputDir, { recursive: true });\n\n // Write profile JSON file\n const jsonPath = join(profileOutputDir, 'query-evaluation-profile.json');\n const jsonContent = formatAsJson(profile);\n writeFileSync(jsonPath, jsonContent);\n logger.info(`Profile JSON written to: ${jsonPath}`);\n\n // Write profile Mermaid diagram file\n const mdPath = join(profileOutputDir, 'query-evaluation-profile.md');\n const mdContent = formatAsMermaid(profile);\n writeFileSync(mdPath, mdContent);\n logger.info(`Profile Mermaid diagram written to: ${mdPath}`);\n\n // Build response message\n const outputFiles: string[] = [\n `Profile JSON: ${jsonPath}`,\n `Profile Mermaid: ${mdPath}`,\n `Evaluator Log: ${logPath}`,\n ];\n\n if (bqrsPath) {\n outputFiles.push(`Query Results (BQRS): ${bqrsPath}`);\n }\n\n if (sarifPath && existsSync(sarifPath)) {\n outputFiles.push(`Query Results (SARIF): ${sarifPath}`);\n }\n\n const responseText = [\n 'Query profiling completed successfully!',\n '',\n 'Output Files:',\n ...outputFiles.map((f) => ` - ${f}`),\n '',\n 'Profile Summary:',\n ` - Query: ${basename(profile.queryName)}`,\n ` - Total Duration: ${profile.totalDuration.toFixed(2)} ms`,\n ` - Total Pipelines: ${profile.pipelines.length}`,\n ` - Total Events: ${profile.totalEvents}`,\n '',\n 'First 5 Pipeline Nodes (in evaluation order):',\n ...profile.pipelines.slice(0, 5).map((p, idx) => {\n return ` ${idx + 1}. ${p.name} (${p.duration.toFixed(2)} ms, ${p.resultSize || '?'} results)`;\n }),\n ].join('\\n');\n\n return {\n content: [\n {\n type: 'text' as const,\n text: responseText,\n },\n ],\n };\n } catch (error) {\n logger.error('Error profiling CodeQL query:', error);\n\n return {\n content: [\n {\n type: 'text' as const,\n text: `Failed to profile query: ${error instanceof Error ? error.message : String(error)}`,\n },\n ],\n isError: true,\n };\n }\n }\n );\n}\n", "/**\n * CodeQL query compile tool\n */\n\nimport { z } from 'zod';\nimport { CLIToolDefinition } from '../../lib/cli-tool-registry';\n\nexport const codeqlQueryCompileTool: CLIToolDefinition = {\n name: 'codeql_query_compile',\n description: 'Compile and validate CodeQL queries',\n command: 'codeql',\n subcommand: 'query compile',\n inputSchema: {\n query: z.string().describe('Path to the CodeQL query file (.ql)'),\n database: z.string().optional().describe('Path to the CodeQL database'),\n library: z.string().optional().describe('Path to query library'),\n output: z.string().optional().describe('Output file path'),\n warnings: z.enum(['hide', 'show', 'error']).optional()\n .describe('How to handle compilation warnings'),\n verbose: z.boolean().optional().describe('Enable verbose output'),\n additionalArgs: z.array(z.string()).optional().describe('Additional command-line arguments')\n },\n examples: [\n 'codeql query compile --database=/path/to/db MyQuery.ql',\n 'codeql query compile --library=/path/to/lib --output=compiled.qlo MyQuery.ql'\n ]\n};", "/**\n * CodeQL query format tool\n */\n\nimport { z } from 'zod';\nimport { CLIToolDefinition, createCodeQLSchemas, defaultCLIResultProcessor, CLIExecutionResult } from '../../lib/cli-tool-registry';\n\n/**\n * Custom result processor for codeql query format tool\n * Exit code 1 with --check-only means \"file would change\" - this is success for format checking\n */\nfunction formatResultProcessor(result: CLIExecutionResult, params: Record): string {\n const isCheckOnly = params['check-only'];\n const hasFormatChanges = result.exitCode === 1;\n \n if (isCheckOnly && hasFormatChanges) {\n // Mark as success for the CLI tool registry since detecting format changes is the intended behavior\n result.success = true;\n return result.stdout || result.stderr || 'File would change by autoformatting.';\n }\n \n return defaultCLIResultProcessor(result, params);\n}\n\nexport const codeqlQueryFormatTool: CLIToolDefinition = {\n name: 'codeql_query_format',\n description: 'Automatically format CodeQL source code files',\n command: 'codeql',\n subcommand: 'query format',\n inputSchema: {\n files: z.array(z.string()).describe('One or more .ql or .qll source files to format'),\n output: z.string().optional().describe('Write formatted code to this file instead of stdout'),\n 'in-place': z.boolean().optional().describe('Overwrite each input file with formatted version'),\n 'check-only': z.boolean().optional().describe('Check formatting without writing output'),\n backup: z.string().optional().describe('Backup extension when overwriting existing files'),\n 'no-syntax-errors': z.boolean().optional().describe('Ignore syntax errors and pretend file is formatted'),\n verbose: createCodeQLSchemas.verbose(),\n additionalArgs: createCodeQLSchemas.additionalArgs()\n },\n examples: [\n 'codeql query format -i -- ExampleQuery.ql',\n 'codeql query format --in-place -- queries/*.ql',\n 'codeql query format --check-only -- queries/*.ql'\n ],\n resultProcessor: formatResultProcessor\n};", "/**\n * CodeQL query run tool\n */\n\nimport { z } from 'zod';\nimport { CLIToolDefinition, createCodeQLSchemas } from '../../lib/cli-tool-registry';\n\nexport const codeqlQueryRunTool: CLIToolDefinition = {\n name: 'codeql_query_run',\n description: 'Execute a CodeQL query against a database. Use either \"query\" parameter for direct file path OR \"queryName\" + \"queryLanguage\" for pre-defined tool queries.',\n command: 'codeql',\n subcommand: 'query run',\n inputSchema: {\n query: z.string().optional().describe('Path to the CodeQL query file (.ql) - cannot be used with queryName'),\n queryName: z.string().optional().describe('Name of pre-defined query to run (e.g., \"PrintAST\", \"CallGraphFrom\", \"CallGraphTo\") - requires queryLanguage'),\n queryLanguage: z.string().optional().describe('Programming language for tools queries (e.g., \"javascript\", \"java\", \"python\") - required when using queryName'),\n queryPack: z.string().optional().describe('Query pack path (defaults to server/ql//tools/src/ for tool queries)'),\n sourceFiles: z.string().optional().describe('Comma-separated list of source file paths for PrintAST queries (e.g., \"src/main.js,src/utils.js\" or just \"main.js\")'),\n sourceFunction: z.string().optional().describe('Comma-separated list of source function names for CallGraphFrom queries (e.g., \"main,processData\")'),\n targetFunction: z.string().optional().describe('Comma-separated list of target function names for CallGraphTo queries (e.g., \"helper,validateInput\")'),\n database: createCodeQLSchemas.database(),\n output: createCodeQLSchemas.output(),\n external: z.array(z.string()).optional()\n .describe('External predicate data: predicate=file.csv'),\n timeout: createCodeQLSchemas.timeout(),\n logDir: z.string().optional()\n .describe('Custom directory for query execution logs (overrides CODEQL_QUERY_LOG_DIR environment variable). If not provided, uses CODEQL_QUERY_LOG_DIR or defaults to .tmp/query-logs/'),\n 'evaluator-log': z.string().optional().describe('Path to save evaluator log (deprecated: use logDir instead)'),\n 'evaluator-log-minify': z.boolean().optional()\n .describe('Minimize evaluator log for smaller size'),\n 'evaluator-log-level': z.number().min(1).max(5).optional()\n .describe('Evaluator log verbosity level (1-5, default 5)'),\n 'tuple-counting': z.boolean().optional()\n .describe('Display tuple counts for each evaluation step in evaluator logs'),\n format: z.enum(['sarif-latest', 'sarifv2.1.0', 'csv', 'graphtext', 'dgml', 'dot']).optional()\n .describe('Output format for query results via codeql bqrs interpret. Defaults to sarif-latest for @kind problem/path-problem queries, graphtext for @kind graph queries. Graph formats (graphtext, dgml, dot) only work with @kind graph queries.'),\n interpretedOutput: z.string().optional()\n .describe('Output file for interpreted results (e.g., results.sarif, results.txt). If not provided, defaults based on format: .sarif for SARIF, .txt for graphtext/csv, .dgml for dgml, .dot for dot'),\n evaluationFunction: z.string().optional()\n .describe('[DEPRECATED - use format parameter instead] Built-in function for query results evaluation (e.g., \"mermaid-graph\", \"json-decode\", \"csv-decode\") or path to custom evaluation script'),\n evaluationOutput: z.string().optional()\n .describe('[DEPRECATED - use interpretedOutput parameter instead] Output file for evaluation results'),\n verbose: createCodeQLSchemas.verbose(),\n additionalArgs: createCodeQLSchemas.additionalArgs()\n },\n examples: [\n 'codeql query run --database=mydb --output=results.bqrs MyQuery.ql',\n 'codeql query run --database=mydb --query-name=PrintAST --query-language=javascript --source-files=src/index.js --output=results.bqrs --format=graphtext --interpreted-output=results.txt',\n 'codeql query run --database=mydb --external=data=input.csv --output=results.bqrs MyQuery.ql --format=sarif-latest --interpreted-output=results.sarif',\n 'codeql query run --database=mydb --evaluator-log=eval.log --tuple-counting --evaluator-log-level=5 --output=results.bqrs MyQuery.ql',\n 'codeql query run --database=mydb --query-name=PrintAST --query-language=javascript --source-files=\"main.js,utils.js\" --format=graphtext',\n 'codeql query run --database=mydb --log-dir=/custom/log/path --tuple-counting --output=results.bqrs MyQuery.ql'\n ]\n};", "/**\n * CodeQL quick evaluate tool\n * \n * Inspired by JordyZomer/codeql-mcp repository:\n * - https://github.com/JordyZomer/codeql-mcp/blob/main/server.py\n * - https://github.com/JordyZomer/codeql-mcp/blob/main/codeqlclient.py\n */\n\nimport { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport { z } from 'zod';\nimport { join, resolve } from 'path';\nimport { findClassPosition } from './find-class-position';\nimport { findPredicatePosition } from './find-predicate-position';\nimport { logger } from '../../utils/logger';\nimport { getProjectTmpDir } from '../../utils/temp-dir';\n\nexport interface QuickEvaluateParams {\n file: string;\n db: string;\n symbol: string;\n output_path?: string;\n}\n\n/**\n * Quick evaluate either a class or a predicate in a CodeQL query.\n * This allows debugging a select portion of QL code without running the whole query.\n */\nexport async function quickEvaluate({\n file,\n db: _db,\n symbol,\n output_path\n}: QuickEvaluateParams): Promise {\n try {\n // Try to find as a class first, then as a predicate\n try {\n await findClassPosition(file, symbol);\n } catch {\n try {\n await findPredicatePosition(file, symbol);\n } catch {\n throw new Error(`Symbol '${symbol}' not found as class or predicate in file: ${file}`);\n }\n }\n \n const resolvedOutput = resolve(output_path || join(getProjectTmpDir('quickeval'), 'quickeval.bqrs'));\n \n // For now, return the resolved output path\n // In a full implementation, this would use the CodeQL CLI or query server\n // to perform the actual quick evaluation with the position parameters\n return resolvedOutput;\n } catch (error) {\n throw new Error(`CodeQL evaluation failed: ${error instanceof Error ? error.message : 'Unknown error'}`);\n }\n}\n\n/**\n * Register the quick evaluate tool with the MCP server\n */\nexport function registerQuickEvaluateTool(server: McpServer): void {\n server.tool(\n 'quick_evaluate',\n 'Quick evaluate either a class or a predicate in a CodeQL query for debugging',\n {\n file: z.string().describe('Path to the .ql file containing the symbol'),\n db: z.string().describe('Path to the CodeQL database'),\n symbol: z.string().describe('Name of the class or predicate to evaluate'),\n output_path: z.string().optional().describe('Output path for results (defaults to project-local .tmp/quickeval/)'),\n },\n async ({ file, db, symbol, output_path }) => {\n try {\n const result = await quickEvaluate({ file, db, symbol, output_path });\n return {\n content: [{ type: 'text', text: result }],\n };\n } catch (error) {\n logger.error('Error in quick evaluate:', error);\n return {\n content: [\n {\n type: 'text',\n text: `Error: ${error instanceof Error ? error.message : 'Unknown error'}`,\n },\n ],\n isError: true,\n };\n }\n }\n );\n}", "/**\n * CodeQL register database tool\n * \n * Inspired by JordyZomer/codeql-mcp repository:\n * - https://github.com/JordyZomer/codeql-mcp/blob/main/server.py\n * - https://github.com/JordyZomer/codeql-mcp/blob/main/codeqlclient.py\n */\n\nimport { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport { z } from 'zod';\nimport { access, constants } from 'fs/promises';\nimport { resolve } from 'path';\nimport { logger } from '../../utils/logger';\n\nexport interface DatabaseRegistration {\n uri: string;\n content: {\n sourceArchiveZip: string;\n dbDir: string;\n };\n}\n\n/**\n * Register a CodeQL database given a local path to the database directory.\n * Validates that the database exists and has required structure.\n * Supports both full databases (with src.zip) and test databases (with src/ folder).\n */\nexport async function registerDatabase(dbPath: string): Promise {\n try {\n const resolvedPath = resolve(dbPath);\n \n // Check if database directory exists\n await access(resolvedPath, constants.F_OK);\n \n // Check for codeql-database.yml (required for all CodeQL databases)\n const dbYmlPath = resolve(resolvedPath, 'codeql-database.yml');\n await access(dbYmlPath, constants.F_OK);\n \n // Check if src.zip exists (for full databases) OR src/ directory exists (for test databases)\n const srcZipPath = resolve(resolvedPath, 'src.zip');\n const srcDirPath = resolve(resolvedPath, 'src');\n \n let hasSrcZip = false;\n let hasSrcDir = false;\n \n try {\n await access(srcZipPath, constants.F_OK);\n hasSrcZip = true;\n } catch {\n // src.zip not found, check for src/ directory\n }\n \n if (!hasSrcZip) {\n try {\n await access(srcDirPath, constants.F_OK);\n hasSrcDir = true;\n } catch {\n // src directory not found either\n }\n }\n \n if (!hasSrcZip && !hasSrcDir) {\n throw new Error(`Missing required source archive (src.zip) or source directory (src/) in: ${dbPath}`);\n }\n \n // For now, we just validate and return success message\n // In a full implementation, this would register with a query server\n const sourceType = hasSrcZip ? 'src.zip' : 'src/';\n return `Database registered: ${dbPath} (source: ${sourceType})`;\n } catch (error) {\n if (error instanceof Error) {\n const errorCode = (error as { code?: string }).code;\n if (errorCode === 'ENOENT') {\n if (error.message.includes('codeql-database.yml')) {\n throw new Error(`Missing required codeql-database.yml in: ${dbPath}`);\n }\n throw new Error(`Database path does not exist: ${dbPath}`);\n }\n if (errorCode === 'EACCES') {\n throw new Error(`Database path does not exist: ${dbPath}`);\n }\n }\n throw new Error(`Failed to register database: ${error instanceof Error ? error.message : 'Unknown error'}`);\n }\n}\n\n/**\n * Register the register database tool with the MCP server\n */\nexport function registerRegisterDatabaseTool(server: McpServer): void {\n server.tool(\n 'register_database',\n 'Register a CodeQL database given a local path to the database directory',\n {\n db_path: z.string().describe('Path to the CodeQL database directory'),\n },\n async ({ db_path }) => {\n try {\n const result = await registerDatabase(db_path);\n return {\n content: [{ type: 'text', text: result }],\n };\n } catch (error) {\n logger.error('Error registering database:', error);\n return {\n content: [\n {\n type: 'text',\n text: `Error: ${error instanceof Error ? error.message : 'Unknown error'}`,\n },\n ],\n isError: true,\n };\n }\n }\n );\n}", "/**\n * CodeQL resolve database tool\n */\n\nimport { z } from 'zod';\nimport { CLIToolDefinition, createCodeQLSchemas, defaultCLIResultProcessor } from '../../lib/cli-tool-registry';\n\nexport const codeqlResolveDatabaseTool: CLIToolDefinition = {\n name: 'codeql_resolve_database',\n description: 'Resolve database path and validate database structure',\n command: 'codeql',\n subcommand: 'resolve database',\n inputSchema: {\n database: z.string().describe('Database path to resolve'),\n format: z.enum(['text', 'json', 'betterjson']).optional()\n .describe('Output format for database information'),\n verbose: createCodeQLSchemas.verbose(),\n additionalArgs: createCodeQLSchemas.additionalArgs()\n },\n examples: [\n 'codeql resolve database -- /path/to/database',\n 'codeql resolve database --format=json -- my-database',\n 'codeql resolve database --format=betterjson -- database-dir'\n ],\n resultProcessor: defaultCLIResultProcessor\n};", "/**\n * CodeQL resolve languages tool\n */\n\nimport { z } from 'zod';\nimport { CLIToolDefinition, defaultCLIResultProcessor } from '../../lib/cli-tool-registry';\n\nexport const codeqlResolveLanguagesTool: CLIToolDefinition = {\n name: 'codeql_resolve_languages',\n description: 'List installed CodeQL extractor packs',\n command: 'codeql',\n subcommand: 'resolve languages',\n inputSchema: {\n format: z.enum(['text', 'json', 'betterjson']).optional()\n .describe('Output format for language information'),\n verbose: z.boolean().optional().describe('Enable verbose output'),\n additionalArgs: z.array(z.string()).optional().describe('Additional command-line arguments')\n },\n examples: [\n 'codeql resolve languages --format=text',\n 'codeql resolve languages --format=json',\n 'codeql resolve languages --format=betterjson'\n ],\n resultProcessor: defaultCLIResultProcessor\n};", "/**\n * CodeQL resolve library-path tool\n */\n\nimport { z } from 'zod';\nimport { CLIToolDefinition, defaultCLIResultProcessor } from '../../lib/cli-tool-registry';\n\nexport const codeqlResolveLibraryPathTool: CLIToolDefinition = {\n name: 'codeql_resolve_library-path',\n description: 'Resolve library path for CodeQL queries and libraries',\n command: 'codeql',\n subcommand: 'resolve library-path',\n inputSchema: {\n language: z.string().optional().describe('Programming language to resolve library path for'),\n format: z.enum(['text', 'json', 'betterjson']).optional()\n .describe('Output format for library path information'),\n verbose: z.boolean().optional().describe('Enable verbose output'),\n additionalArgs: z.array(z.string()).optional().describe('Additional command-line arguments')\n },\n examples: [\n 'codeql resolve library-path --language=java',\n 'codeql resolve library-path --format=json --language=python',\n 'codeql resolve library-path --format=betterjson'\n ],\n resultProcessor: defaultCLIResultProcessor\n};", "/**\n * CodeQL resolve metadata tool\n */\n\nimport { z } from 'zod';\nimport { CLIToolDefinition, defaultCLIResultProcessor } from '../../lib/cli-tool-registry';\n\nexport const codeqlResolveMetadataTool: CLIToolDefinition = {\n name: 'codeql_resolve_metadata',\n description: 'Resolve and return the key-value metadata pairs from a CodeQL query source file.',\n command: 'codeql',\n subcommand: 'resolve metadata',\n inputSchema: {\n query: z.string().describe('Query file to resolve metadata for'),\n format: z.enum(['json']).optional()\n .describe('Output format for metadata information (always JSON, optional for future compatibility)'),\n verbose: z.boolean().optional().describe('Enable verbose output'),\n additionalArgs: z.array(z.string()).optional().describe('Additional command-line arguments')\n },\n examples: [\n 'codeql resolve metadata -- relative-path/2/MyQuery.ql',\n 'codeql resolve metadata --format=json -- /absolute-plus/relative-path/2/MyQuery.ql'\n ],\n resultProcessor: defaultCLIResultProcessor\n};", "/**\n * CodeQL resolve qlref tool\n */\n\nimport { z } from 'zod';\nimport { CLIToolDefinition, createCodeQLSchemas, defaultCLIResultProcessor } from '../../lib/cli-tool-registry';\n\nexport const codeqlResolveQlrefTool: CLIToolDefinition = {\n name: 'codeql_resolve_qlref',\n description: 'Resolve qlref files to their corresponding query files',\n command: 'codeql',\n subcommand: 'resolve qlref',\n inputSchema: {\n qlref: z.string().describe('Path to the .qlref file to resolve'),\n format: z.enum(['text', 'json', 'betterjson']).optional()\n .describe('Output format for qlref resolution'),\n verbose: createCodeQLSchemas.verbose(),\n additionalArgs: createCodeQLSchemas.additionalArgs()\n },\n examples: [\n 'codeql resolve qlref -- test/MyQuery.qlref',\n 'codeql resolve qlref --format=json -- test/MyQuery.qlref',\n 'codeql resolve qlref --format=betterjson -- test/MyQuery.qlref'\n ],\n resultProcessor: defaultCLIResultProcessor\n};", "/**\n * CodeQL resolve queries tool\n */\n\nimport { z } from 'zod';\nimport { CLIToolDefinition, createCodeQLSchemas, CLIExecutionResult } from '../../lib/cli-tool-registry';\n\n/**\n * Result processor that only returns stdout for JSON formats\n * This prevents warnings/info from stderr from corrupting JSON output\n */\nconst jsonOnlyResultProcessor = (\n result: CLIExecutionResult,\n params: Record\n): string => {\n if (!result.success) {\n return `Command failed (exit code ${result.exitCode || 'unknown'}):\\n${result.error || result.stderr}`;\n }\n\n // For JSON formats (including bylanguage), only return stdout to avoid mixing warnings with JSON\n if (params.format === 'json' || params.format === 'betterjson' || params.format === 'bylanguage') {\n return result.stdout || '[]';\n }\n\n // For text format, include warnings\n let output = '';\n\n if (result.stdout) {\n output += result.stdout;\n }\n\n if (result.stderr) {\n if (output) {\n output += '\\n\\nWarnings/Info:\\n';\n }\n output += result.stderr;\n }\n\n if (!output) {\n output = 'Command executed successfully (no output)';\n }\n\n return output;\n};\n\nexport const codeqlResolveQueriesTool: CLIToolDefinition = {\n name: 'codeql_resolve_queries',\n description: 'List available CodeQL queries found on the local filesystem',\n command: 'codeql',\n subcommand: 'resolve queries',\n inputSchema: {\n directory: z.string().optional().describe('Directory to search for queries'),\n language: z.string().optional().describe('Filter queries by programming language'),\n format: z.enum(['text', 'json', 'betterjson', 'bylanguage']).optional()\n .describe('Output format for query list'),\n 'additional-packs': z.union([z.string(), z.array(z.string())]).optional()\n .describe('Additional pack directories to search for CodeQL packs'),\n verbose: createCodeQLSchemas.verbose(),\n additionalArgs: createCodeQLSchemas.additionalArgs()\n },\n examples: [\n 'codeql resolve queries',\n 'codeql resolve queries --language=java --format=json',\n 'codeql resolve queries --format=betterjson -- /path/to/queries',\n 'codeql resolve queries --additional-packs=/path/to/packs codeql/java-queries'\n ],\n resultProcessor: jsonOnlyResultProcessor\n};", "/**\n * CodeQL resolve tests tool\n */\n\nimport { z } from 'zod';\nimport { CLIToolDefinition, createCodeQLSchemas, defaultCLIResultProcessor } from '../../lib/cli-tool-registry';\n\nexport const codeqlResolveTestsTool: CLIToolDefinition = {\n name: 'codeql_resolve_tests',\n description: 'Resolve the local filesystem paths of unit tests and/or queries under some base directory',\n command: 'codeql',\n subcommand: 'resolve tests',\n inputSchema: {\n tests: z.array(z.string()).optional().describe('One or more tests (.ql, .qlref files, or test directories)'),\n format: z.enum(['text', 'json']).optional()\n .describe('Output format for test list'),\n verbose: createCodeQLSchemas.verbose(),\n additionalArgs: createCodeQLSchemas.additionalArgs()\n },\n examples: [\n 'codeql resolve tests',\n 'codeql resolve tests --format=json -- test-directory',\n 'codeql resolve tests --format=json -- test1.ql test2.ql'\n ],\n resultProcessor: defaultCLIResultProcessor\n};", "/**\n * CodeQL test accept tool\n */\n\nimport { z } from 'zod';\nimport { CLIToolDefinition, createCodeQLSchemas, defaultCLIResultProcessor } from '../../lib/cli-tool-registry';\n\nexport const codeqlTestAcceptTool: CLIToolDefinition = {\n name: 'codeql_test_accept',\n description: 'Accept new test results as the expected baseline',\n command: 'codeql',\n subcommand: 'test accept',\n inputSchema: {\n tests: z.array(z.string()).describe('One or more tests (.ql, .qlref files, or test directories)'),\n verbose: createCodeQLSchemas.verbose(),\n additionalArgs: createCodeQLSchemas.additionalArgs()\n },\n examples: [\n 'codeql test accept -- languages/java/test/MyQuery/MyQuery.qlref',\n 'codeql test accept -- languages/java/test/MyQuery/',\n 'codeql test accept -- languages/java/src/MyQuery/MyQuery.ql'\n ],\n resultProcessor: defaultCLIResultProcessor\n};", "/**\n * CodeQL test extract tool\n */\n\nimport { z } from 'zod';\nimport { CLIToolDefinition, createCodeQLSchemas, defaultCLIResultProcessor } from '../../lib/cli-tool-registry';\n\nexport const codeqlTestExtractTool: CLIToolDefinition = {\n name: 'codeql_test_extract',\n description: 'Extract test databases for CodeQL query tests',\n command: 'codeql',\n subcommand: 'test extract',\n inputSchema: {\n tests: z.array(z.string()).describe('One or more test directories or files'),\n language: z.string().optional().describe('Programming language for extraction'),\n threads: createCodeQLSchemas.threads(),\n ram: createCodeQLSchemas.ram(),\n verbose: createCodeQLSchemas.verbose(),\n additionalArgs: createCodeQLSchemas.additionalArgs()\n },\n examples: [\n 'codeql test extract -- languages/java/test/MyQuery/',\n 'codeql test extract --language=java --threads=4 -- test-directory',\n 'codeql test extract --threads=2 --ram=2048 -- multiple/test/directories'\n ],\n resultProcessor: defaultCLIResultProcessor\n};", "/**\n * CodeQL test run tool\n */\n\nimport { CLIToolDefinition, createCodeQLSchemas } from '../../lib/cli-tool-registry';\nimport { z } from 'zod';\n\nexport const codeqlTestRunTool: CLIToolDefinition = {\n name: 'codeql_test_run',\n description: 'Run CodeQL query tests',\n command: 'codeql',\n subcommand: 'test run',\n inputSchema: {\n tests: z.array(z.string()).describe('One or more tests (.ql, .qlref files, or test directories)'),\n 'show-extractor-output': z.boolean().optional()\n .describe('Show output from extractors during test execution'),\n 'keep-databases': z.boolean().optional()\n .describe('Keep test databases after running tests'),\n 'learn': z.boolean().optional()\n .describe('Accept current output as expected for failing tests'),\n logDir: z.string().optional()\n .describe('Custom directory for test execution logs (overrides CODEQL_QUERY_LOG_DIR environment variable). If not provided, uses CODEQL_QUERY_LOG_DIR or defaults to .tmp/query-logs/'),\n threads: createCodeQLSchemas.threads(),\n ram: createCodeQLSchemas.ram(),\n verbose: createCodeQLSchemas.verbose(),\n additionalArgs: createCodeQLSchemas.additionalArgs()\n },\n examples: [\n 'codeql test run /path/to/tests',\n 'codeql test run --learn /path/to/failing/tests',\n 'codeql test run --threads=4 --keep-databases /path/to/tests',\n 'codeql test run --log-dir=/custom/log/path /path/to/tests'\n ]\n};", "/**\n * CodeQL tools registration for MCP server\n * Includes both high-level helpers and CLI command wrappers\n */\n\nimport { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport { z } from 'zod';\nimport { validateCodeQLSyntax } from '../lib/validation';\nimport { createCodeQLQuery } from '../lib/query-scaffolding';\nimport { registerCLITool } from '../lib/cli-tool-registry';\nimport {\n codeqlBqrsDecodeTool,\n codeqlBqrsInfoTool,\n codeqlBqrsInterpretTool,\n codeqlDatabaseAnalyzeTool,\n codeqlDatabaseCreateTool,\n codeqlGenerateLogSummaryTool,\n codeqlGenerateQueryHelpTool,\n codeqlPackInstallTool,\n codeqlPackLsTool,\n codeqlQueryCompileTool,\n codeqlQueryFormatTool,\n codeqlQueryRunTool,\n codeqlResolveDatabaseTool,\n codeqlResolveLanguagesTool,\n codeqlResolveLibraryPathTool,\n codeqlResolveMetadataTool,\n codeqlResolveQlrefTool,\n codeqlResolveQueriesTool,\n codeqlResolveTestsTool,\n codeqlTestAcceptTool,\n codeqlTestExtractTool,\n codeqlTestRunTool,\n registerFindClassPositionTool,\n registerFindCodeQLQueryFilesTool,\n registerFindPredicatePositionTool,\n registerListDatabasesTool,\n registerListMrvaRunResultsTool,\n registerListQueryRunResultsTool,\n registerProfileCodeQLQueryFromLogsTool,\n registerProfileCodeQLQueryTool,\n registerQuickEvaluateTool,\n registerRegisterDatabaseTool\n} from './codeql';\nimport { logger } from '../utils/logger';\n\n/**\n * Register all CodeQL tools with the MCP server\n */\nexport function registerCodeQLTools(server: McpServer): void {\n // Register high-level helper tools\n \n // Tool: Validate CodeQL Query (heuristic-based)\n server.tool(\n 'validate_codeql_query',\n 'Quick heuristic validation for CodeQL query structure - checks for common patterns like from/where/select clauses and metadata presence. Does NOT compile the query. For authoritative validation with actual compilation, use codeql_lsp_diagnostics instead.',\n {\n query: z.string().describe('The CodeQL query to validate'),\n language: z.string().optional().describe('Target programming language'),\n },\n async ({ query, language }) => {\n try {\n const validation = validateCodeQLSyntax(query, language);\n return {\n content: [{ type: 'text', text: JSON.stringify(validation, null, 2) }],\n };\n } catch (error) {\n logger.error('Error validating CodeQL query:', error);\n return {\n content: [\n {\n type: 'text',\n text: `Error: ${error instanceof Error ? error.message : 'Unknown error'}`,\n },\n ],\n isError: true,\n };\n }\n }\n );\n\n // Tool: Create CodeQL Query\n server.tool(\n 'create_codeql_query',\n 'Create directory structure and files for a new CodeQL query with tests',\n {\n basePath: z.string().describe('Base path where src/ and test/ directories will be created'),\n queryName: z.string().describe('Name of the query (e.g., MySecurityQuery)'),\n language: z.string().describe('Target programming language (e.g., javascript, python, java)'),\n description: z.string().optional().describe('Description of what the query does'),\n queryId: z.string().optional().describe('Custom query ID (defaults to language/example/queryname)'),\n },\n async ({ basePath, queryName, language, description, queryId }) => {\n try {\n const result = createCodeQLQuery({\n basePath,\n queryName,\n language,\n description,\n queryId\n });\n \n const summary = {\n success: true,\n queryPath: result.queryPath,\n testPath: result.testPath,\n qlrefPath: result.qlrefPath,\n testCodePath: result.testCodePath,\n filesCreated: result.filesCreated,\n nextSteps: [\n 'Review and customize the generated query in: ' + result.queryPath,\n 'Add test cases to: ' + result.testCodePath,\n 'Run codeql_pack_install to install dependencies',\n 'Run codeql_test_extract to create test database',\n 'Run codeql_test_run to execute tests'\n ]\n };\n \n return {\n content: [{ type: 'text', text: JSON.stringify(summary, null, 2) }],\n };\n } catch (error) {\n logger.error('Error creating CodeQL query:', error);\n return {\n content: [\n {\n type: 'text',\n text: `Error: ${error instanceof Error ? error.message : 'Unknown error'}`,\n },\n ],\n isError: true,\n };\n }\n }\n );\n\n // Register CLI tools (alphabetically by tool name)\n registerCLITool(server, codeqlBqrsDecodeTool);\n registerCLITool(server, codeqlBqrsInfoTool);\n registerCLITool(server, codeqlBqrsInterpretTool);\n registerCLITool(server, codeqlDatabaseAnalyzeTool);\n registerCLITool(server, codeqlDatabaseCreateTool);\n registerCLITool(server, codeqlGenerateLogSummaryTool);\n registerCLITool(server, codeqlGenerateQueryHelpTool);\n registerCLITool(server, codeqlPackInstallTool);\n registerCLITool(server, codeqlPackLsTool);\n registerCLITool(server, codeqlQueryCompileTool);\n registerCLITool(server, codeqlQueryFormatTool);\n registerCLITool(server, codeqlQueryRunTool);\n registerCLITool(server, codeqlResolveDatabaseTool);\n registerCLITool(server, codeqlResolveLanguagesTool);\n registerCLITool(server, codeqlResolveLibraryPathTool);\n registerCLITool(server, codeqlResolveMetadataTool);\n registerCLITool(server, codeqlResolveQlrefTool);\n registerCLITool(server, codeqlResolveQueriesTool);\n registerCLITool(server, codeqlResolveTestsTool);\n registerCLITool(server, codeqlTestAcceptTool);\n registerCLITool(server, codeqlTestExtractTool);\n registerCLITool(server, codeqlTestRunTool);\n\n // Register new MCP tools (inspired by JordyZomer/codeql-mcp repository)\n registerFindClassPositionTool(server);\n registerFindCodeQLQueryFilesTool(server);\n registerFindPredicatePositionTool(server);\n registerListDatabasesTool(server);\n registerListMrvaRunResultsTool(server);\n registerListQueryRunResultsTool(server);\n registerProfileCodeQLQueryFromLogsTool(server);\n registerProfileCodeQLQueryTool(server);\n registerQuickEvaluateTool(server);\n registerRegisterDatabaseTool(server);\n}\n", "/**\n * CodeQL query validation utilities\n */\n\nimport { resolve, normalize, isAbsolute, relative } from 'path';\n\nexport interface CodeQLValidationResult {\n isValid: boolean;\n errors: string[];\n warnings: string[];\n suggestions: string[];\n}\n\n/**\n * Validates CodeQL query syntax and structure\n */\nexport function validateCodeQLSyntax(query: string, _language?: string): CodeQLValidationResult {\n const validation: CodeQLValidationResult = {\n isValid: true,\n errors: [],\n warnings: [],\n suggestions: [],\n };\n\n if (!query.trim()) {\n validation.isValid = false;\n validation.errors.push('Query cannot be empty');\n return validation;\n }\n\n if (!query.includes('from') && !query.includes('select')) {\n validation.warnings.push('Query should typically include \"from\" and \"select\" clauses');\n }\n\n if (!query.includes('@name') && !query.includes('@description')) {\n validation.suggestions.push('Consider adding @name and @description metadata');\n }\n\n return validation;\n}\n\n/**\n * Validates a file path to prevent path traversal attacks\n * @param filePath - The file path to validate\n * @param workspaceRoot - Optional workspace root directory. If not provided, allows any absolute path but still blocks traversal attempts\n * @returns The validated absolute path\n * @throws Error if the path contains path traversal sequences\n */\nexport function validateFilePath(filePath: string, workspaceRoot?: string): string {\n // Normalize the path to resolve any . or .. segments\n const normalizedPath = normalize(filePath);\n \n // Check for path traversal attempts in the normalized path\n // This blocks paths like \"../../../etc/passwd\" even after normalization\n if (normalizedPath.includes('..')) {\n throw new Error(`Invalid file path: path traversal detected in \"${filePath}\"`);\n }\n \n // Resolve to absolute path\n const absolutePath = isAbsolute(normalizedPath) \n ? normalizedPath \n : resolve(workspaceRoot || process.cwd(), normalizedPath);\n \n // If workspace root is specified, ensure the resolved path is within it\n if (workspaceRoot) {\n const relativePath = relative(workspaceRoot, absolutePath);\n \n // If relative path starts with .. or is absolute, it's outside workspace\n if (relativePath.startsWith('..') || isAbsolute(relativePath)) {\n throw new Error(`Invalid file path: \"${filePath}\" is outside the workspace root`);\n }\n }\n \n return absolutePath;\n}", "/**\n * CodeQL query scaffolding utilities\n * Handles creation of query directory structure and files\n */\n\nimport * as fs from 'fs';\nimport * as path from 'path';\n\nexport interface QueryScaffoldingOptions {\n basePath: string;\n queryName: string;\n language: string;\n description?: string;\n queryId?: string;\n}\n\nexport interface QueryScaffoldingResult {\n queryPath: string;\n testPath: string;\n qlrefPath: string;\n testCodePath: string;\n filesCreated: string[];\n}\n\n/**\n * Get the file extension for test code based on language\n */\nfunction getLanguageExtension(language: string): string {\n const extensions: Record = {\n javascript: 'js',\n typescript: 'ts',\n python: 'py',\n java: 'java',\n csharp: 'cs',\n cpp: 'cpp',\n go: 'go',\n ruby: 'rb',\n actions: 'yml'\n };\n return extensions[language.toLowerCase()] || 'txt';\n}\n\n/**\n * Generate query template content\n */\nfunction generateQueryTemplate(\n queryName: string,\n language: string,\n description?: string,\n queryId?: string\n): string {\n const desc = description || `${queryName} query`;\n const id = queryId || `${language}/example/${queryName.toLowerCase()}`;\n \n return `/**\n * @id ${id}\n * @name ${queryName}\n * @description ${desc}\n * @kind problem\n * @precision medium\n * @problem.severity warning\n */\n\nimport ${language}\n\n// TODO: Implement query logic\nfrom File f\nwhere f.getBaseName() = \"${queryName}.${getLanguageExtension(language)}\"\nselect f, \"TODO: Add query logic\"\n`;\n}\n\n/**\n * Create the directory structure and files for a new CodeQL query\n */\nexport function createCodeQLQuery(options: QueryScaffoldingOptions): QueryScaffoldingResult {\n const { basePath, queryName, language, description, queryId } = options;\n \n // Resolve absolute paths\n const absoluteBasePath = path.resolve(basePath);\n \n // Define paths with intermediate directory\n const srcDir = path.join(absoluteBasePath, 'src', queryName);\n const testDir = path.join(absoluteBasePath, 'test', queryName);\n \n const queryPath = path.join(srcDir, `${queryName}.ql`);\n const qlrefPath = path.join(testDir, `${queryName}.qlref`);\n const testCodePath = path.join(testDir, `${queryName}.${getLanguageExtension(language)}`);\n \n const filesCreated: string[] = [];\n \n try {\n // Create directories (recursive: true is a no-op if they already exist)\n fs.mkdirSync(srcDir, { recursive: true });\n fs.mkdirSync(testDir, { recursive: true });\n \n // Create files atomically using 'wx' flag (exclusive create) to avoid\n // TOCTOU race between existsSync check and writeFileSync (CWE-367).\n // The 'wx' flag fails with EEXIST if the file already exists.\n try {\n const queryContent = generateQueryTemplate(queryName, language, description, queryId);\n fs.writeFileSync(queryPath, queryContent, { encoding: 'utf8', flag: 'wx' });\n filesCreated.push(queryPath);\n } catch (e: unknown) {\n const err = e as { code?: string };\n if (err.code !== 'EEXIST') throw e;\n }\n \n try {\n const qlrefContent = `${queryName}/${queryName}.ql\\n`;\n fs.writeFileSync(qlrefPath, qlrefContent, { encoding: 'utf8', flag: 'wx' });\n filesCreated.push(qlrefPath);\n } catch (e: unknown) {\n const err = e as { code?: string };\n if (err.code !== 'EEXIST') throw e;\n }\n \n try {\n const testCodeContent = `// Test code for ${queryName}\\n// TODO: Add test cases\\n`;\n fs.writeFileSync(testCodePath, testCodeContent, { encoding: 'utf8', flag: 'wx' });\n filesCreated.push(testCodePath);\n } catch (e: unknown) {\n const err = e as { code?: string };\n if (err.code !== 'EEXIST') throw e;\n }\n \n return {\n queryPath,\n testPath: testDir,\n qlrefPath,\n testCodePath,\n filesCreated\n };\n } catch (error) {\n throw new Error(`Failed to create query scaffolding: ${error instanceof Error ? error.message : 'Unknown error'}`);\n }\n}\n", "/**\n * CodeQL learning resources utilities\n */\n\nimport { readFileSync } from 'fs';\nimport { join, dirname } from 'path';\nimport { fileURLToPath } from 'url';\n\nconst __filename = fileURLToPath(import.meta.url);\nconst __dirname = dirname(__filename);\n\n/**\n * Get the getting started guide content\n */\nexport function getGettingStartedGuide(): string {\n try {\n return readFileSync(join(__dirname, '../resources/getting-started.md'), 'utf-8');\n } catch {\n return 'Getting started guide not available';\n }\n}\n\n/**\n * Get the query basics guide content\n */\nexport function getQueryBasicsGuide(): string {\n try {\n return readFileSync(join(__dirname, '../resources/query-basics.md'), 'utf-8');\n } catch {\n return 'Query basics guide not available';\n }\n}\n\n/**\n * Get the security templates content\n */\nexport function getSecurityTemplates(): string {\n try {\n return readFileSync(join(__dirname, '../resources/security-templates.md'), 'utf-8');\n } catch {\n return 'Security templates not available';\n }\n}\n\n/**\n * Get the performance patterns content\n */\nexport function getPerformancePatterns(): string {\n try {\n return readFileSync(join(__dirname, '../resources/performance-patterns.md'), 'utf-8');\n } catch {\n return 'Performance patterns not available';\n }\n}", "/**\n * CodeQL resources registration for MCP server\n */\n\nimport { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport {\n getGettingStartedGuide,\n getQueryBasicsGuide,\n getSecurityTemplates,\n getPerformancePatterns,\n} from '../lib/resources';\n\n/**\n * Register all CodeQL resources with the MCP server\n */\nexport function registerCodeQLResources(server: McpServer): void {\n // Getting Started Guide\n server.resource(\n 'CodeQL Getting Started',\n 'codeql://learning/getting-started',\n {\n description: 'Comprehensive introduction to CodeQL for beginners',\n mimeType: 'text/markdown',\n },\n async () => {\n return {\n contents: [\n {\n uri: 'codeql://learning/getting-started',\n mimeType: 'text/markdown',\n text: getGettingStartedGuide(),\n },\n ],\n };\n }\n );\n\n // Query Basics Guide\n server.resource(\n 'CodeQL Query Basics',\n 'codeql://learning/query-basics',\n {\n description: 'Learn the fundamentals of writing CodeQL queries',\n mimeType: 'text/markdown',\n },\n async () => {\n return {\n contents: [\n {\n uri: 'codeql://learning/query-basics',\n mimeType: 'text/markdown',\n text: getQueryBasicsGuide(),\n },\n ],\n };\n }\n );\n\n // Security Templates\n server.resource(\n 'CodeQL Security Templates',\n 'codeql://templates/security',\n {\n description: 'Ready-to-use security query templates',\n mimeType: 'text/markdown',\n },\n async () => {\n return {\n contents: [\n {\n uri: 'codeql://templates/security',\n mimeType: 'text/markdown',\n text: getSecurityTemplates(),\n },\n ],\n };\n }\n );\n\n // Performance Patterns\n server.resource(\n 'CodeQL Performance Patterns',\n 'codeql://patterns/performance',\n {\n description: 'Best practices for writing efficient CodeQL queries',\n mimeType: 'text/markdown',\n },\n async () => {\n return {\n contents: [\n {\n uri: 'codeql://patterns/performance',\n mimeType: 'text/markdown',\n text: getPerformancePatterns(),\n },\n ],\n };\n }\n );\n}\n", "/**\n * CodeQL LSP Diagnostics tool for MCP server.\n *\n * Provides real-time QL code validation through LSP communication.\n * Renamed from `codeql_language_server_eval` to `codeql_lsp_diagnostics`\n * for consistency with the `codeql_lsp_*` tool naming convention.\n */\n\nimport { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport { z } from 'zod';\nimport { Diagnostic, LanguageServerOptions } from '../../lib/language-server';\nimport { logger } from '../../utils/logger';\nimport { getProjectTmpDir } from '../../utils/temp-dir';\nimport { join } from 'path';\nimport { pathToFileURL } from 'url';\nimport { getInitializedLanguageServer } from './lsp-server-helper';\n\nexport interface LspDiagnosticsParams {\n qlCode: string;\n serverOptions?: LanguageServerOptions;\n workspaceUri?: string;\n}\n\nexport interface LspDiagnosticsResult {\n diagnostics: Diagnostic[];\n formattedOutput: string;\n isValid: boolean;\n summary: {\n errorCount: number;\n hintCount: number;\n infoCount: number;\n warningCount: number;\n };\n}\n\n/**\n * Format diagnostics for human-readable output.\n */\nfunction formatDiagnostics(diagnostics: Diagnostic[]): string {\n if (diagnostics.length === 0) {\n return '\u2705 No issues found in QL code';\n }\n\n const lines: string[] = [];\n lines.push(`Found ${diagnostics.length} issue(s):\\n`);\n\n diagnostics.forEach((diagnostic, index) => {\n const severityIcon = getSeverityIcon(diagnostic.severity);\n const severityName = getSeverityName(diagnostic.severity);\n const location = `Line ${diagnostic.range.start.line + 1}, Column ${diagnostic.range.start.character + 1}`;\n\n lines.push(`${index + 1}. ${severityIcon} ${severityName} at ${location}`);\n lines.push(` ${diagnostic.message}`);\n if (diagnostic.source) {\n lines.push(` Source: ${diagnostic.source}`);\n }\n if (diagnostic.code) {\n lines.push(` Code: ${diagnostic.code}`);\n }\n lines.push('');\n });\n\n return lines.join('\\n');\n}\n\nfunction getSeverityIcon(severity: number): string {\n switch (severity) {\n case 1: return '\u274C'; // Error\n case 2: return '\u26A0\uFE0F'; // Warning\n case 3: return '\u2139\uFE0F'; // Information\n case 4: return '\uD83D\uDCA1'; // Hint\n default: return '\u2753';\n }\n}\n\nfunction getSeverityName(severity: number): string {\n switch (severity) {\n case 1: return 'Error';\n case 2: return 'Warning';\n case 3: return 'Information';\n case 4: return 'Hint';\n default: return 'Unknown';\n }\n}\n\n/**\n * Evaluate QL code using the CodeQL Language Server and return diagnostics.\n */\nexport async function lspDiagnostics({\n qlCode,\n workspaceUri,\n serverOptions = {}\n}: LspDiagnosticsParams): Promise {\n try {\n logger.info('Evaluating QL code via Language Server...');\n\n const languageServer = await getInitializedLanguageServer({\n serverOptions,\n workspaceUri,\n });\n\n // Generate unique URI for this evaluation\n const evalUri = pathToFileURL(join(getProjectTmpDir('lsp-eval'), `eval_${Date.now()}.ql`)).href;\n\n const diagnostics = await languageServer.evaluateQL(qlCode, evalUri);\n\n // Count diagnostics by severity\n const summary = {\n errorCount: diagnostics.filter(d => d.severity === 1).length,\n hintCount: diagnostics.filter(d => d.severity === 4).length,\n infoCount: diagnostics.filter(d => d.severity === 3).length,\n warningCount: diagnostics.filter(d => d.severity === 2).length,\n };\n\n const isValid = summary.errorCount === 0;\n const formattedOutput = formatDiagnostics(diagnostics);\n\n logger.info(`QL evaluation complete. Valid: ${isValid}, Issues: ${diagnostics.length}`);\n\n return {\n diagnostics,\n formattedOutput,\n isValid,\n summary,\n };\n\n } catch (error) {\n logger.error('Error evaluating QL code:', error);\n throw new Error(`QL evaluation failed: ${error instanceof Error ? error.message : 'Unknown error'}`);\n }\n}\n\n/**\n * Shutdown the language server via the server manager.\n */\nexport async function shutdownDiagnosticsServer(): Promise {\n const { getServerManager } = await import('../../lib/server-manager');\n const manager = getServerManager();\n await manager.shutdownServer('language');\n}\n\n/**\n * Register the codeql_lsp_diagnostics tool with the MCP server.\n */\nexport function registerLspDiagnosticsTool(server: McpServer): void {\n server.tool(\n 'codeql_lsp_diagnostics',\n 'Authoritative syntax and semantic validation of CodeQL (QL) code via the CodeQL Language Server. Compiles the query and provides real-time diagnostics with precise error locations. Use this for accurate validation; for quick heuristic checks without compilation, use validate_codeql_query instead. Note: inline ql_code is evaluated as a virtual document and cannot resolve pack imports (e.g. `import javascript`). For validating queries with imports, use codeql_query_compile on the actual file instead.',\n {\n log_level: z.enum(['OFF', 'ERROR', 'WARN', 'INFO', 'DEBUG', 'TRACE', 'ALL']).optional().describe('Language server log level'),\n ql_code: z.string().describe('The CodeQL (QL) code to evaluate for syntax and semantic errors'),\n search_path: z.string().optional().describe('Optional search path for CodeQL libraries'),\n workspace_uri: z.string().optional().describe('Optional workspace URI for context (defaults to ./ql directory)'),\n },\n async ({ ql_code, workspace_uri, search_path, log_level }) => {\n try {\n const serverOptions: LanguageServerOptions = {};\n\n if (search_path) {\n serverOptions.searchPath = search_path;\n }\n if (log_level) {\n serverOptions.loglevel = log_level;\n }\n\n const result = await lspDiagnostics({\n qlCode: ql_code,\n serverOptions,\n workspaceUri: workspace_uri,\n });\n\n // Return structured result\n const responseContent = {\n diagnostics: result.diagnostics.map(d => ({\n code: d.code,\n column: d.range.start.character + 1, // Convert to 1-based column numbers\n line: d.range.start.line + 1, // Convert to 1-based line numbers\n message: d.message,\n severity: getSeverityName(d.severity),\n source: d.source,\n })),\n formattedOutput: result.formattedOutput,\n isValid: result.isValid,\n summary: result.summary,\n };\n\n return {\n content: [\n {\n text: JSON.stringify(responseContent, null, 2),\n type: 'text',\n }\n ],\n };\n\n } catch (error) {\n logger.error('Error in codeql_lsp_diagnostics tool:', error);\n return {\n content: [\n {\n text: `Error: ${error instanceof Error ? error.message : 'Unknown error'}`,\n type: 'text',\n },\n ],\n isError: true,\n };\n }\n }\n );\n\n // NOTE: Cleanup is handled centrally by shutdownServerManager() in\n // codeql-development-mcp-server.ts (setupGracefulShutdown). Registering\n // additional process.on('SIGINT'/'SIGTERM') handlers here would\n // accumulate on repeated calls and is unnecessary.\n}\n", "/**\n * Shared helper for obtaining a running, initialized CodeQL Language Server.\n *\n * Both `lsp-diagnostics.ts` and `lsp-handlers.ts` need to:\n * 1. Build a `LanguageServerConfig` with sensible defaults\n * 2. Obtain a server instance from the `CodeQLServerManager`\n * 3. Resolve a workspace URI (relative \u2192 absolute \u2192 `file://`)\n * 4. Initialize the server with the resolved workspace\n *\n * Centralizing this logic avoids duplication and ensures consistent\n * default behaviour across all LSP tools.\n */\n\nimport { isAbsolute, resolve } from 'path';\nimport { pathToFileURL } from 'url';\n\nimport { CodeQLLanguageServer, LanguageServerOptions } from '../../lib/language-server';\nimport { LanguageServerConfig } from '../../lib/server-config';\nimport { getServerManager } from '../../lib/server-manager';\nimport { logger } from '../../utils/logger';\n\n/**\n * Options accepted by {@link getInitializedLanguageServer}.\n */\nexport interface InitializedServerOptions {\n /** Language-server-level options (loglevel, searchPath, etc.). */\n serverOptions?: LanguageServerOptions;\n /** Workspace URI \u2014 may be a `file://` URI, absolute path, or relative path. */\n workspaceUri?: string;\n}\n\n/**\n * Return a running, initialized `CodeQLLanguageServer`.\n *\n * - Resolves `searchPath` to the bundled `ql` directory when not provided.\n * - Converts relative / bare-directory `workspaceUri` paths to `file://` URIs\n * resolved against `getUserWorkspaceDir()` (respects `CODEQL_MCP_WORKSPACE`).\n * - Falls back to the bundled `ql` directory when no workspace is given.\n * - Delegates lifecycle management to the global `CodeQLServerManager`.\n */\nexport async function getInitializedLanguageServer(\n opts: InitializedServerOptions = {},\n): Promise {\n const { packageRootDir: pkgRoot, getUserWorkspaceDir } = await import('../../utils/package-paths');\n const options = opts.serverOptions ?? {};\n\n const config: LanguageServerConfig = {\n checkErrors: 'ON_CHANGE',\n loglevel: options.loglevel ?? 'WARN',\n searchPath: options.searchPath ?? resolve(pkgRoot, 'ql'),\n synchronous: options.synchronous,\n verbosity: options.verbosity,\n };\n\n const manager = getServerManager();\n const server = await manager.getLanguageServer(config);\n\n // Normalize workspace URI: convert relative / bare directory paths to\n // file:// URIs against getUserWorkspaceDir() (respects CODEQL_MCP_WORKSPACE).\n let effectiveUri = opts.workspaceUri;\n if (effectiveUri && !effectiveUri.startsWith('file://')) {\n const absWorkspace = isAbsolute(effectiveUri)\n ? effectiveUri\n : resolve(getUserWorkspaceDir(), effectiveUri);\n effectiveUri = pathToFileURL(absWorkspace).href;\n }\n effectiveUri = effectiveUri ?? pathToFileURL(resolve(pkgRoot, 'ql')).href;\n\n await server.initialize(effectiveUri);\n logger.debug(`Language server initialized with workspace: ${effectiveUri}`);\n\n return server;\n}\n", "/**\n * CodeQL LSP tool handlers.\n *\n * Bridges MCP tool invocations to LSP requests on the CodeQL Language Server.\n * Each handler acquires a language server via the CodeQLServerManager,\n * opens the requested document, sends the LSP request, and returns the result.\n */\n\nimport { readFile } from 'fs/promises';\nimport { isAbsolute, resolve } from 'path';\nimport { pathToFileURL } from 'url';\n\nimport {\n CompletionItem,\n LSPLocation,\n TextDocumentPositionParams,\n} from '../../lib/language-server';\nimport { logger } from '../../utils/logger';\nimport { getUserWorkspaceDir } from '../../utils/package-paths';\nimport { getInitializedLanguageServer } from './lsp-server-helper';\n\n/**\n * Common parameters for LSP tool invocations.\n */\nexport interface LSPToolParams {\n /** 0-based character offset within the line. */\n character: number;\n /** Optional override for the file content (if not reading from disk). */\n fileContent?: string;\n /**\n * Path to the QL file. May be absolute or relative.\n * Relative paths are resolved against `getUserWorkspaceDir()`\n * (respects the `CODEQL_MCP_WORKSPACE` environment variable).\n */\n filePath: string;\n /** 0-based line number in the document. */\n line: number;\n /** Optional search path for CodeQL libraries. */\n searchPath?: string;\n /** Optional workspace URI for context. */\n workspaceUri?: string;\n}\n\n/**\n * Get a running, initialized language server for the given parameters.\n */\nasync function getInitializedServer(params: LSPToolParams) {\n return getInitializedLanguageServer({\n serverOptions: { searchPath: params.searchPath },\n workspaceUri: params.workspaceUri,\n });\n}\n\n/**\n * Resolve the file path to an absolute path and file:// URI.\n */\nfunction prepareDocumentPosition(\n params: LSPToolParams,\n): { absPath: string; docUri: string } {\n // Resolve relative paths against getUserWorkspaceDir() so that\n // CODEQL_MCP_WORKSPACE is respected and behaviour is consistent across tools.\n const absPath = isAbsolute(params.filePath)\n ? params.filePath\n : resolve(getUserWorkspaceDir(), params.filePath);\n const docUri = pathToFileURL(absPath).href;\n\n return { absPath, docUri };\n}\n\n/**\n * Read file content and open the document in the language server.\n */\nasync function openDocumentForPosition(\n server: Awaited>,\n params: LSPToolParams,\n absPath: string,\n docUri: string,\n): Promise {\n // Read file content from disk or use provided content\n let text: string;\n if (params.fileContent) {\n text = params.fileContent;\n } else {\n try {\n text = await readFile(absPath, 'utf-8');\n } catch (error) {\n throw new Error(`Cannot read file: ${absPath}: ${error instanceof Error ? error.message : error}`);\n }\n }\n\n // Open the document so the language server knows about it\n server.openDocument(docUri, text);\n\n return {\n position: { character: params.character, line: params.line },\n textDocument: { uri: docUri },\n };\n}\n\n/**\n * Get code completions at a position.\n */\nexport async function lspCompletion(params: LSPToolParams): Promise {\n logger.info(`LSP completion at ${params.filePath}:${params.line}:${params.character}`);\n const server = await getInitializedServer(params);\n const { absPath, docUri } = prepareDocumentPosition(params);\n const positionParams = await openDocumentForPosition(server, params, absPath, docUri);\n\n try {\n return await server.getCompletions(positionParams);\n } finally {\n server.closeDocument(docUri);\n }\n}\n\n/**\n * Go to definition of a symbol at a position.\n */\nexport async function lspDefinition(params: LSPToolParams): Promise {\n logger.info(`LSP definition at ${params.filePath}:${params.line}:${params.character}`);\n const server = await getInitializedServer(params);\n const { absPath, docUri } = prepareDocumentPosition(params);\n const positionParams = await openDocumentForPosition(server, params, absPath, docUri);\n\n try {\n return await server.getDefinition(positionParams);\n } finally {\n server.closeDocument(docUri);\n }\n}\n\n/**\n * Find all references to a symbol at a position.\n */\nexport async function lspReferences(params: LSPToolParams): Promise {\n logger.info(`LSP references at ${params.filePath}:${params.line}:${params.character}`);\n const server = await getInitializedServer(params);\n const { absPath, docUri } = prepareDocumentPosition(params);\n const positionParams = await openDocumentForPosition(server, params, absPath, docUri);\n\n try {\n return await server.getReferences({\n ...positionParams,\n context: { includeDeclaration: true },\n });\n } finally {\n server.closeDocument(docUri);\n }\n}\n", "/**\n * CodeQL LSP MCP tool definitions.\n *\n * Registers four LSP-based tools:\n * - codeql_lsp_completion \u2013 code completions at cursor position\n * - codeql_lsp_definition \u2013 go to definition\n * - codeql_lsp_diagnostics \u2013 QL code validation via LSP diagnostics\n * - codeql_lsp_references \u2013 find all references\n */\n\nimport { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport { z } from 'zod';\nimport { registerLspDiagnosticsTool } from './lsp-diagnostics';\nimport {\n lspCompletion,\n lspDefinition,\n lspReferences,\n} from './lsp-handlers';\nimport { logger } from '../../utils/logger';\n\n/**\n * Shared Zod schema for the common LSP tool parameters.\n */\nconst lspParamsSchema = {\n character: z.number().int().min(0).describe('0-based character offset within the line'),\n file_content: z.string().optional().describe('Optional file content override (reads from disk if omitted)'),\n file_path: z.string().describe('Path to the CodeQL (.ql/.qll) file. Relative paths are resolved against the user workspace directory (see CODEQL_MCP_WORKSPACE).'),\n line: z.number().int().min(0).describe('0-based line number in the document'),\n search_path: z.string().optional().describe('Optional search path for CodeQL libraries'),\n workspace_uri: z.string().optional().describe('Optional workspace URI for context (defaults to ./ql directory)'),\n};\n\n/**\n * Helper to build the handler params from the raw MCP tool input.\n */\nfunction toHandlerParams(input: {\n character: number;\n file_content?: string;\n file_path: string;\n line: number;\n search_path?: string;\n workspace_uri?: string;\n}) {\n return {\n character: input.character,\n fileContent: input.file_content,\n filePath: input.file_path,\n line: input.line,\n searchPath: input.search_path,\n workspaceUri: input.workspace_uri,\n };\n}\n\n/**\n * Register all LSP-based tools with the MCP server.\n */\nexport function registerLSPTools(server: McpServer): void {\n // --- codeql_lsp_diagnostics (relocated from codeql_language_server_eval) ---\n registerLspDiagnosticsTool(server);\n\n // --- codeql_lsp_completion ---\n server.tool(\n 'codeql_lsp_completion',\n 'Get code completions at a cursor position in a CodeQL file. Returns completion items with labels, documentation, and insert text. The file must be a .ql or .qll file. IMPORTANT: Set workspace_uri to the pack or workspace root directory for dependency resolution; without it, completions for imported libraries will be empty.',\n lspParamsSchema,\n async (input) => {\n try {\n const items = await lspCompletion(toHandlerParams(input));\n return {\n content: [{\n text: JSON.stringify({\n completionCount: items.length,\n items: items.map((item) => ({\n detail: item.detail,\n documentation: item.documentation,\n insertText: item.insertText,\n kind: item.kind,\n label: item.label,\n })),\n }, null, 2),\n type: 'text' as const,\n }],\n };\n } catch (error) {\n logger.error('codeql_lsp_completion error:', error);\n return {\n content: [{ text: `Error: ${error instanceof Error ? error.message : 'Unknown error'}`, type: 'text' as const }],\n isError: true,\n };\n }\n },\n );\n\n // --- codeql_lsp_definition ---\n server.tool(\n 'codeql_lsp_definition',\n 'Go to the definition of a CodeQL symbol at a given position. Returns one or more file locations where the symbol is defined. Set workspace_uri to the pack root for dependency resolution.',\n lspParamsSchema,\n async (input) => {\n try {\n const locations = await lspDefinition(toHandlerParams(input));\n return {\n content: [{\n text: JSON.stringify({\n definitionCount: locations.length,\n locations: locations.map((loc) => ({\n endCharacter: loc.range.end.character,\n endLine: loc.range.end.line + 1,\n startCharacter: loc.range.start.character,\n startLine: loc.range.start.line + 1,\n uri: loc.uri,\n })),\n }, null, 2),\n type: 'text' as const,\n }],\n };\n } catch (error) {\n logger.error('codeql_lsp_definition error:', error);\n return {\n content: [{ text: `Error: ${error instanceof Error ? error.message : 'Unknown error'}`, type: 'text' as const }],\n isError: true,\n };\n }\n },\n );\n\n // --- codeql_lsp_references ---\n server.tool(\n 'codeql_lsp_references',\n 'Find all references to a CodeQL symbol at a given position. Returns file locations of all usages, including the declaration. Set workspace_uri to the pack root for dependency resolution.',\n lspParamsSchema,\n async (input) => {\n try {\n const locations = await lspReferences(toHandlerParams(input));\n return {\n content: [{\n text: JSON.stringify({\n locations: locations.map((loc) => ({\n endCharacter: loc.range.end.character,\n endLine: loc.range.end.line + 1,\n startCharacter: loc.range.start.character,\n startLine: loc.range.start.line + 1,\n uri: loc.uri,\n })),\n referenceCount: locations.length,\n }, null, 2),\n type: 'text' as const,\n }],\n };\n } catch (error) {\n logger.error('codeql_lsp_references error:', error);\n return {\n content: [{ text: `Error: ${error instanceof Error ? error.message : 'Unknown error'}`, type: 'text' as const }],\n isError: true,\n };\n }\n },\n );\n}\n", "/**\n * Language-specific resources implementation\n * Dynamically loads and serves language-specific AST references and security patterns\n */\n\nimport { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport { readFileSync, existsSync } from 'fs';\nimport { join } from 'path';\nimport { LANGUAGE_RESOURCES } from '../types/language-types';\nimport { workspaceRootDir } from '../utils/package-paths';\nimport { logger } from '../utils/logger';\n\n/**\n * Get the base path for ql resources.\n * Uses the workspace root (monorepo root or package root) so that\n * resource files are found regardless of the server's process.cwd().\n */\nfunction getQLBasePath(): string {\n return workspaceRootDir;\n}\n\n/**\n * Load content from a resource file\n */\nfunction loadResourceContent(relativePath: string): string | null {\n try {\n const fullPath = join(getQLBasePath(), relativePath);\n \n if (!existsSync(fullPath)) {\n logger.warn(`Resource file not found: ${fullPath}`);\n return null;\n }\n \n return readFileSync(fullPath, 'utf-8');\n } catch (error) {\n logger.error(`Error loading resource file ${relativePath}:`, error);\n return null;\n }\n}\n\n/**\n * Register language-specific AST resources\n */\nexport function registerLanguageASTResources(server: McpServer): void {\n for (const langResource of LANGUAGE_RESOURCES) {\n if (!langResource.astFile) continue;\n \n const resourceUri = `codeql://languages/${langResource.language}/ast`;\n \n server.resource(\n `${langResource.language.toUpperCase()} AST Reference`,\n resourceUri,\n {\n description: `CodeQL AST class reference for ${langResource.language} programs`,\n mimeType: 'text/markdown'\n },\n async () => {\n const content = loadResourceContent(langResource.astFile!);\n \n if (!content) {\n return {\n contents: [{\n uri: resourceUri,\n mimeType: 'text/markdown',\n text: `# ${langResource.language.toUpperCase()} AST Reference\\n\\nResource file not found or could not be loaded.`\n }]\n };\n }\n \n return {\n contents: [{\n uri: resourceUri,\n mimeType: 'text/markdown',\n text: content\n }]\n };\n }\n );\n }\n}\n\n/**\n * Register language-specific security pattern resources\n */\nexport function registerLanguageSecurityResources(server: McpServer): void {\n for (const langResource of LANGUAGE_RESOURCES) {\n if (!langResource.securityFile) continue;\n \n const resourceUri = `codeql://languages/${langResource.language}/security`;\n \n server.resource(\n `${langResource.language.toUpperCase()} Security Patterns`,\n resourceUri,\n {\n description: `CodeQL security query patterns and framework modeling for ${langResource.language}`,\n mimeType: 'text/markdown'\n },\n async () => {\n const content = loadResourceContent(langResource.securityFile!);\n \n if (!content) {\n return {\n contents: [{\n uri: resourceUri,\n mimeType: 'text/markdown',\n text: `# ${langResource.language.toUpperCase()} Security Patterns\\n\\nResource file not found or could not be loaded.`\n }]\n };\n }\n \n return {\n contents: [{\n uri: resourceUri,\n mimeType: 'text/markdown',\n text: content\n }]\n };\n }\n );\n }\n}\n\n/**\n * Register additional language-specific resources (like Go's dataflow patterns)\n */\nexport function registerLanguageAdditionalResources(server: McpServer): void {\n for (const langResource of LANGUAGE_RESOURCES) {\n if (!langResource.additionalFiles) continue;\n \n for (const [resourceType, filePath] of Object.entries(langResource.additionalFiles)) {\n const resourceUri = `codeql://languages/${langResource.language}/${resourceType}`;\n \n server.resource(\n `${langResource.language.toUpperCase()} ${resourceType.replace('-', ' ').replace(/\\b\\w/g, l => l.toUpperCase())}`,\n resourceUri,\n {\n description: `CodeQL ${resourceType.replace('-', ' ')} guide for ${langResource.language}`,\n mimeType: 'text/markdown'\n },\n async () => {\n const content = loadResourceContent(filePath);\n \n if (!content) {\n return {\n contents: [{\n uri: resourceUri,\n mimeType: 'text/markdown',\n text: `# ${langResource.language.toUpperCase()} ${resourceType.replace('-', ' ').replace(/\\b\\w/g, l => l.toUpperCase())}\\n\\nResource file not found or could not be loaded.`\n }]\n };\n }\n \n return {\n contents: [{\n uri: resourceUri,\n mimeType: 'text/markdown',\n text: content\n }]\n };\n }\n );\n }\n }\n}\n\n/**\n * Register all language-specific resources\n */\nexport function registerLanguageResources(server: McpServer): void {\n logger.info('Registering language-specific resources...');\n \n // Register AST references for all languages\n registerLanguageASTResources(server);\n \n // Register security patterns for languages that have them\n registerLanguageSecurityResources(server);\n \n // Register additional resources (like Go's dataflow patterns)\n registerLanguageAdditionalResources(server);\n \n logger.info(`Registered resources for ${LANGUAGE_RESOURCES.length} languages`);\n}", "/**\n * Type definitions and constants for language-specific resources\n */\n\n// Language mappings to resource files\nexport interface LanguageResource {\n language: string;\n astFile?: string;\n securityFile?: string;\n additionalFiles?: Record;\n}\n\nexport const LANGUAGE_RESOURCES: LanguageResource[] = [\n {\n language: 'actions',\n astFile: 'ql/languages/actions/tools/dev/actions_ast.prompt.md'\n },\n {\n language: 'cpp',\n astFile: 'ql/languages/cpp/tools/dev/cpp_ast.prompt.md',\n securityFile: 'ql/languages/cpp/tools/dev/cpp_security_query_guide.prompt.md'\n },\n {\n language: 'csharp',\n astFile: 'ql/languages/csharp/tools/dev/csharp_ast.prompt.md',\n securityFile: 'ql/languages/csharp/tools/dev/csharp_security_query_guide.prompt.md'\n },\n {\n language: 'go',\n astFile: 'ql/languages/go/tools/dev/go_ast.prompt.md',\n securityFile: 'ql/languages/go/tools/dev/go_security_query_guide.prompt.md',\n additionalFiles: {\n 'dataflow': 'ql/languages/go/tools/dev/go_dataflow.prompt.md',\n 'library-modeling': 'ql/languages/go/tools/dev/go_library_modeling.prompt.md',\n 'basic-queries': 'ql/languages/go/tools/dev/go_basic_queries.prompt.md'\n }\n },\n {\n language: 'java',\n astFile: 'ql/languages/java/tools/dev/java_ast.prompt.md'\n },\n {\n language: 'javascript',\n astFile: 'ql/languages/javascript/tools/dev/javascript_ast.prompt.md',\n securityFile: 'ql/languages/javascript/tools/dev/javascript_security_query_guide.prompt.md'\n },\n {\n language: 'python',\n astFile: 'ql/languages/python/tools/dev/python_ast.prompt.md',\n securityFile: 'ql/languages/python/tools/dev/python_security_query_guide.prompt.md'\n },\n {\n language: 'ql',\n astFile: 'ql/languages/ql/tools/dev/ql_ast.prompt.md'\n },\n {\n language: 'ruby',\n astFile: 'ql/languages/ruby/tools/dev/ruby_ast.prompt.md'\n }\n];", "/**\n * MCP Server workflow prompts for CodeQL development\n *\n * All prompt content is loaded from .prompt.md files in this directory.\n * This file only handles prompt registration and parameter processing.\n */\n\nimport { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport { z } from 'zod';\nimport { basename } from 'path';\nimport { loadPromptTemplate, processPromptTemplate } from './prompt-loader';\nimport { logger } from '../utils/logger';\n\n/** Supported CodeQL languages for tools queries */\nexport const SUPPORTED_LANGUAGES = [\n 'actions',\n 'cpp',\n 'csharp',\n 'go',\n 'java',\n 'javascript',\n 'python',\n 'ruby',\n 'swift'\n] as const;\n\n// \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n// Exported parameter schemas for each workflow prompt.\n//\n// Extracting the schemas makes it easy to unit-test required vs optional\n// validation independently of the MCP server registration.\n//\n// **Convention for VS Code UX consistency**:\n// Every prompt MUST expose at least one parameter \u2013 even if all parameters\n// are optional \u2013 so that VS Code always displays the parameter input dialog\n// and allows the user to customize the prompt before Copilot Chat processes\n// it. The `description` field on each Zod schema member doubles as the\n// placeholder text shown in the VS Code input box.\n// \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n/**\n * Schema for test_driven_development prompt parameters.\n *\n * - `language` is **required** \u2013 the TDD workflow is language-specific.\n * - `queryName` is optional \u2013 defaults to '[QueryName]' if omitted.\n */\nexport const testDrivenDevelopmentSchema = z.object({\n language: z\n .enum(SUPPORTED_LANGUAGES)\n .describe('Programming language for the query'),\n queryName: z\n .string()\n .optional()\n .describe('Name of the query to develop'),\n});\n\n/**\n * Schema for tools_query_workflow prompt parameters.\n *\n * - `language` and `database` are **required**.\n * - `sourceFiles`, `sourceFunction`, `targetFunction` are optional context.\n */\nexport const toolsQueryWorkflowSchema = z.object({\n database: z\n .string()\n .describe('Path to the CodeQL database'),\n language: z\n .enum(SUPPORTED_LANGUAGES)\n .describe('Programming language for the tools queries'),\n sourceFiles: z\n .string()\n .optional()\n .describe('Comma-separated source file names for PrintAST (e.g., \"main.js,utils.js\")'),\n sourceFunction: z\n .string()\n .optional()\n .describe('Function name for PrintCFG or CallGraphFrom (e.g., \"processData\")'),\n targetFunction: z\n .string()\n .optional()\n .describe('Function name for CallGraphTo (e.g., \"validate\")'),\n});\n\n/**\n * Schema for workshop_creation_workflow prompt parameters.\n * Uses z.coerce.number() for numStages to handle string inputs from VSCode slash commands.\n *\n * - `queryPath` and `language` are **required**.\n * - `workshopName` and `numStages` are optional.\n */\nexport const workshopCreationWorkflowSchema = z.object({\n queryPath: z\n .string()\n .describe('Path to the production-grade CodeQL query (.ql or .qlref)'),\n language: z\n .enum(SUPPORTED_LANGUAGES)\n .describe('Programming language of the query'),\n workshopName: z\n .string()\n .optional()\n .describe('Name for the workshop directory'),\n numStages: z\n .coerce.number()\n .optional()\n .describe('Number of incremental stages (default: 4-8)'),\n});\n\n/**\n * Schema for ql_tdd_basic prompt parameters.\n *\n * All parameters are optional \u2013 but at least one should be present so the\n * VS Code quick-pick dialog appears.\n */\nexport const qlTddBasicSchema = z.object({\n language: z\n .enum(SUPPORTED_LANGUAGES)\n .optional()\n .describe('Programming language for the query (optional)'),\n queryName: z\n .string()\n .optional()\n .describe('Name of the query to develop'),\n});\n\n/**\n * Schema for ql_tdd_advanced prompt parameters.\n *\n * All parameters are optional.\n */\nexport const qlTddAdvancedSchema = z.object({\n database: z\n .string()\n .optional()\n .describe('Path to the CodeQL database for analysis'),\n language: z\n .enum(SUPPORTED_LANGUAGES)\n .optional()\n .describe('Programming language for the query (optional)'),\n queryName: z\n .string()\n .optional()\n .describe('Name of the query to develop'),\n});\n\n/**\n * Schema for sarif_rank_false_positives / sarif_rank_true_positives.\n *\n * Both parameters are optional.\n */\nexport const sarifRankSchema = z.object({\n queryId: z\n .string()\n .optional()\n .describe('CodeQL query/rule identifier'),\n sarifPath: z\n .string()\n .optional()\n .describe('Path to the SARIF file to analyze'),\n});\n\n/**\n * Schema for explain_codeql_query prompt parameters.\n *\n * - `queryPath` and `language` are **required**.\n * - `databasePath` is optional.\n */\nexport const explainCodeqlQuerySchema = z.object({\n databasePath: z\n .string()\n .optional()\n .describe('Optional path to a real CodeQL database for profiling'),\n language: z\n .enum(SUPPORTED_LANGUAGES)\n .describe('Programming language of the query'),\n queryPath: z\n .string()\n .describe('Path to the CodeQL query file (.ql or .qlref)'),\n});\n\n/**\n * Schema for document_codeql_query prompt parameters.\n *\n * - `queryPath` and `language` are **required**.\n */\nexport const documentCodeqlQuerySchema = z.object({\n language: z\n .enum(SUPPORTED_LANGUAGES)\n .describe('Programming language of the query'),\n queryPath: z\n .string()\n .describe('Path to the CodeQL query file (.ql or .qlref)'),\n});\n\n/**\n * Schema for ql_lsp_iterative_development prompt parameters.\n *\n * All parameters are optional.\n */\nexport const qlLspIterativeDevelopmentSchema = z.object({\n language: z\n .enum(SUPPORTED_LANGUAGES)\n .optional()\n .describe('Programming language for the query'),\n queryPath: z\n .string()\n .optional()\n .describe('Path to the query file being developed'),\n workspaceUri: z\n .string()\n .optional()\n .describe('Workspace URI for LSP dependency resolution'),\n});\n\n// \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n// Prompt names (exported for testing)\n// \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n/** Names of every workflow prompt registered with the MCP server. */\nexport const WORKFLOW_PROMPT_NAMES = [\n 'document_codeql_query',\n 'explain_codeql_query',\n 'ql_lsp_iterative_development',\n 'ql_tdd_advanced',\n 'ql_tdd_basic',\n 'sarif_rank_false_positives',\n 'sarif_rank_true_positives',\n 'test_driven_development',\n 'tools_query_workflow',\n 'workshop_creation_workflow',\n] as const;\n\n/**\n * Register MCP workflow prompts\n *\n * Each prompt loads its content from a corresponding .prompt.md file\n * and processes any parameter substitutions.\n *\n * **UX note**: Every prompt schema is passed to `server.prompt()` so that\n * VS Code always displays the parameter-input quick-pick before the prompt\n * is sent to Copilot Chat. This lets users review and customise the values.\n */\nexport function registerWorkflowPrompts(server: McpServer): void {\n // Test-Driven Development Prompt\n server.prompt(\n 'test_driven_development',\n 'Test-driven development workflow for CodeQL queries using MCP tools',\n testDrivenDevelopmentSchema.shape,\n async ({ language, queryName }) => {\n const template = loadPromptTemplate('ql-tdd-basic.prompt.md');\n const content = processPromptTemplate(template, {\n language,\n queryName: queryName || '[QueryName]'\n });\n\n return {\n messages: [\n {\n role: 'user',\n content: {\n type: 'text',\n text: `## Context\\n\\n- **Language**: ${language}\\n${queryName ? `- **Query Name**: ${queryName}\\n` : ''}\\n${content}`\n }\n }\n ]\n };\n }\n );\n\n // Tools Query Workflow Prompt\n server.prompt(\n 'tools_query_workflow',\n 'Guide for using built-in tools queries (PrintAST, PrintCFG, CallGraphFrom, CallGraphTo) to understand code structure',\n toolsQueryWorkflowSchema.shape,\n async ({\n language,\n database,\n sourceFiles,\n sourceFunction,\n targetFunction\n }) => {\n const template = loadPromptTemplate('tools-query-workflow.prompt.md');\n const content = processPromptTemplate(template, {\n language,\n database\n });\n\n const contextSection = buildToolsQueryContext(\n language,\n database,\n sourceFiles,\n sourceFunction,\n targetFunction\n );\n\n return {\n messages: [\n {\n role: 'user',\n content: {\n type: 'text',\n text: contextSection + content\n }\n }\n ]\n };\n }\n );\n\n // Workshop Creation Workflow Prompt\n server.prompt(\n 'workshop_creation_workflow',\n 'Guide for creating CodeQL query development workshops from production-grade queries',\n workshopCreationWorkflowSchema.shape,\n async ({ queryPath, language, workshopName, numStages }) => {\n const template = loadPromptTemplate('workshop-creation-workflow.prompt.md');\n\n // Derive workshop name from query path if not provided\n const derivedName =\n workshopName ||\n basename(queryPath)\n .replace(/\\.(ql|qlref)$/, '')\n .toLowerCase()\n .replace(/[^a-z0-9]+/g, '-') ||\n 'codeql-workshop';\n\n const contextSection = buildWorkshopContext(\n queryPath,\n language,\n derivedName,\n numStages\n );\n\n return {\n messages: [\n {\n role: 'user',\n content: {\n type: 'text',\n text: contextSection + template\n }\n }\n ]\n };\n }\n );\n\n // TDD Basic Prompt - Test-Driven Development Checklist\n server.prompt(\n 'ql_tdd_basic',\n 'Test-driven CodeQL query development checklist - write tests first, implement query, iterate until tests pass',\n qlTddBasicSchema.shape,\n async ({ language, queryName }) => {\n const template = loadPromptTemplate('ql-tdd-basic.prompt.md');\n\n let contextSection = '## Your Development Context\\n\\n';\n if (language) {\n contextSection += `- **Language**: ${language}\\n`;\n }\n if (queryName) {\n contextSection += `- **Query Name**: ${queryName}\\n`;\n }\n if (language || queryName) {\n contextSection += '\\n';\n }\n\n return {\n messages: [\n {\n role: 'user',\n content: {\n type: 'text',\n text: contextSection + template\n }\n }\n ]\n };\n }\n );\n\n // TDD Advanced Prompt - Advanced Techniques with AST/CFG/CallGraph\n server.prompt(\n 'ql_tdd_advanced',\n 'Advanced test-driven CodeQL development with AST visualization, control flow, and call graph analysis',\n qlTddAdvancedSchema.shape,\n async ({ language, queryName, database }) => {\n const template = loadPromptTemplate('ql-tdd-advanced.prompt.md');\n\n let contextSection = '## Your Development Context\\n\\n';\n if (language) {\n contextSection += `- **Language**: ${language}\\n`;\n }\n if (queryName) {\n contextSection += `- **Query Name**: ${queryName}\\n`;\n }\n if (database) {\n contextSection += `- **Database**: ${database}\\n`;\n }\n if (language || queryName || database) {\n contextSection += '\\n';\n }\n\n return {\n messages: [\n {\n role: 'user',\n content: {\n type: 'text',\n text: contextSection + template\n }\n }\n ]\n };\n }\n );\n\n // SARIF Rank False Positives Prompt\n server.prompt(\n 'sarif_rank_false_positives',\n 'Analyze SARIF results to identify likely false positives in CodeQL query results',\n sarifRankSchema.shape,\n async ({ queryId, sarifPath }) => {\n const template = loadPromptTemplate('sarif-rank-false-positives.prompt.md');\n\n let contextSection = '## Analysis Context\\n\\n';\n if (queryId) {\n contextSection += `- **Query ID**: ${queryId}\\n`;\n }\n if (sarifPath) {\n contextSection += `- **SARIF File**: ${sarifPath}\\n`;\n }\n if (queryId || sarifPath) {\n contextSection += '\\n';\n }\n\n return {\n messages: [\n {\n role: 'user',\n content: {\n type: 'text',\n text: contextSection + template\n }\n }\n ]\n };\n }\n );\n\n // SARIF Rank True Positives Prompt\n server.prompt(\n 'sarif_rank_true_positives',\n 'Analyze SARIF results to identify likely true positives in CodeQL query results',\n sarifRankSchema.shape,\n async ({ queryId, sarifPath }) => {\n const template = loadPromptTemplate('sarif-rank-true-positives.prompt.md');\n\n let contextSection = '## Analysis Context\\n\\n';\n if (queryId) {\n contextSection += `- **Query ID**: ${queryId}\\n`;\n }\n if (sarifPath) {\n contextSection += `- **SARIF File**: ${sarifPath}\\n`;\n }\n if (queryId || sarifPath) {\n contextSection += '\\n';\n }\n\n return {\n messages: [\n {\n role: 'user',\n content: {\n type: 'text',\n text: contextSection + template\n }\n }\n ]\n };\n }\n );\n\n // Explain CodeQL Query Prompt (for workshop learning content)\n server.prompt(\n 'explain_codeql_query',\n 'Generate detailed explanation of a CodeQL query for workshop learning content - uses MCP tools to gather context and produces both verbal explanations and mermaid evaluation diagrams',\n explainCodeqlQuerySchema.shape,\n async ({ queryPath, language, databasePath }) => {\n const template = loadPromptTemplate('explain-codeql-query.prompt.md');\n\n let contextSection = '## Query to Explain\\n\\n';\n contextSection += `- **Query Path**: ${queryPath}\\n`;\n contextSection += `- **Language**: ${language}\\n`;\n if (databasePath) {\n contextSection += `- **Database Path**: ${databasePath}\\n`;\n }\n contextSection += '\\n';\n\n return {\n messages: [\n {\n role: 'user',\n content: {\n type: 'text',\n text: contextSection + template\n }\n }\n ]\n };\n }\n );\n\n // Document CodeQL Query Prompt\n server.prompt(\n 'document_codeql_query',\n 'Create or update documentation for a CodeQL query - generates standardized markdown documentation as a sibling file to the query',\n documentCodeqlQuerySchema.shape,\n async ({ queryPath, language }) => {\n const template = loadPromptTemplate('document-codeql-query.prompt.md');\n\n const contextSection = `## Query to Document\n\n- **Query Path**: ${queryPath}\n- **Language**: ${language}\n\n`;\n\n return {\n messages: [\n {\n role: 'user',\n content: {\n type: 'text',\n text: contextSection + template\n }\n }\n ]\n };\n }\n );\n\n // LSP-powered Iterative Development Prompt\n server.prompt(\n 'ql_lsp_iterative_development',\n 'Iterative CodeQL query development using LSP tools for completion, navigation, and validation',\n qlLspIterativeDevelopmentSchema.shape,\n async ({ language, queryPath, workspaceUri }) => {\n const template = loadPromptTemplate('ql-lsp-iterative-development.prompt.md');\n\n let contextSection = '## Your Development Context\\n\\n';\n if (language) {\n contextSection += `- **Language**: ${language}\\n`;\n }\n if (queryPath) {\n contextSection += `- **Query Path**: ${queryPath}\\n`;\n }\n if (workspaceUri) {\n contextSection += `- **Workspace URI**: ${workspaceUri}\\n`;\n }\n if (language || queryPath || workspaceUri) {\n contextSection += '\\n';\n }\n\n return {\n messages: [\n {\n role: 'user',\n content: {\n type: 'text',\n text: contextSection + template,\n },\n },\n ],\n };\n }\n );\n\n logger.info(`Registered ${WORKFLOW_PROMPT_NAMES.length} workflow prompts`);\n}\n\n/**\n * Build context section for tools query workflow\n */\nexport function buildToolsQueryContext(\n language: string,\n database: string,\n sourceFiles?: string,\n sourceFunction?: string,\n targetFunction?: string\n): string {\n const lines = [\n '## Your Context',\n '',\n `- **Language**: ${language}`,\n `- **Database**: ${database}`\n ];\n\n if (sourceFiles) {\n lines.push(`- **Source Files**: ${sourceFiles}`);\n }\n if (sourceFunction) {\n lines.push(`- **Source Function**: ${sourceFunction}`);\n }\n if (targetFunction) {\n lines.push(`- **Target Function**: ${targetFunction}`);\n }\n\n lines.push('', '## Recommended Next Steps', '');\n\n if (sourceFiles) {\n lines.push(\n `1. Run \\`codeql_query_run\\` with queryName=\"PrintAST\", sourceFiles=\"${sourceFiles}\"`\n );\n } else {\n lines.push('1. Identify source files to analyze with PrintAST');\n }\n\n if (sourceFunction) {\n lines.push(\n `2. Run \\`codeql_query_run\\` with queryName=\"PrintCFG\" or \"CallGraphFrom\", sourceFunction=\"${sourceFunction}\"`\n );\n } else {\n lines.push(\n '2. Identify key functions for CFG or call graph analysis'\n );\n }\n\n if (targetFunction) {\n lines.push(\n `3. Run \\`codeql_query_run\\` with queryName=\"CallGraphTo\", targetFunction=\"${targetFunction}\"`\n );\n } else {\n lines.push('3. Identify target functions to find callers');\n }\n\n lines.push('', '');\n return lines.join('\\n');\n}\n\n/**\n * Build context section for workshop creation workflow\n */\nexport function buildWorkshopContext(\n queryPath: string,\n language: string,\n workshopName: string,\n numStages?: number\n): string {\n return `## Your Workshop Context\n\n- **Target Query**: ${queryPath}\n- **Language**: ${language}\n- **Workshop Name**: ${workshopName}\n- **Suggested Stages**: ${numStages || '4-8 (auto-detect based on query complexity)'}\n\n## Immediate Actions\n\n1. **Locate query files**: Use \\`find_codeql_query_files\\` with queryPath=\"${queryPath}\"\n2. **Understand query for learning content**: Use the \\`explain_codeql_query\\` prompt with queryPath=\"${queryPath}\" and language=\"${language}\"\n3. **Document each workshop stage**: Use the \\`document_codeql_query\\` prompt to create/update documentation for each solution query\n4. **Verify tests pass**: Use \\`codeql_test_run\\` on existing tests\n5. **Run tools queries**: Generate AST/CFG understanding for workshop materials\n\n`;\n}\n", "/**\n * Utility functions for loading prompt template files\n */\n\nimport { readFileSync } from 'fs';\nimport { join, dirname } from 'path';\nimport { fileURLToPath } from 'url';\n\nconst __filename = fileURLToPath(import.meta.url);\nconst __dirname = dirname(__filename);\n\n/**\n * Load a prompt template from a .prompt.md file\n */\nexport function loadPromptTemplate(promptFileName: string): string {\n try {\n const promptPath = join(__dirname, promptFileName);\n return readFileSync(promptPath, 'utf-8');\n } catch (error) {\n return `Prompt template '${promptFileName}' not available: ${error instanceof Error ? error.message : 'Unknown error'}`;\n }\n}\n\n/**\n * Process prompt template by replacing placeholders with actual values\n */\nexport function processPromptTemplate(template: string, variables: Record): string {\n let processed = template;\n \n // Replace variables in the format {{variable}} or {variable}\n for (const [key, value] of Object.entries(variables)) {\n const patterns = [\n new RegExp(`\\\\{\\\\{${key}\\\\}\\\\}`, 'g'),\n new RegExp(`\\\\{${key}\\\\}`, 'g')\n ];\n \n for (const pattern of patterns) {\n processed = processed.replace(pattern, value);\n }\n }\n \n return processed;\n}", "/**\n * Monitoring Tools - MCP tool implementations for session management and reporting\n * Provides the MCP Tool APIs specified in the monitoring specification\n */\n\nimport { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport { z } from 'zod';\nimport { randomUUID } from 'crypto';\nimport { sessionDataManager } from '../lib/session-data-manager';\nimport {\n QueryDevelopmentSession,\n SessionFilter,\n QualityScoreRecord,\n ComparisonReport,\n AggregateReport,\n ExportResult,\n FunctionalTestResult,\n} from '../types/monitoring';\nimport { logger } from '../utils/logger';\n\n/**\n * Register all monitoring and reporting tools with the MCP server\n * Note: These tools are opt-in and disabled by default for end-users.\n * Set enableMonitoringTools: true in monitoring config to enable them.\n */\nexport function registerMonitoringTools(server: McpServer): void {\n const config = sessionDataManager.getConfig();\n \n // Check if monitoring tools are enabled (opt-in, disabled by default)\n if (!config.enableMonitoringTools) {\n logger.info('Monitoring tools are disabled (opt-in). Set enableMonitoringTools: true to enable session_* tools.');\n return;\n }\n\n // Session Management Tools - session_start removed per feedback (auto-creation instead)\n registerSessionEndTool(server);\n registerSessionGetTool(server);\n registerSessionListTool(server);\n registerSessionUpdateStateTool(server);\n\n // Session Analytics Tools\n registerSessionGetCallHistoryTool(server);\n registerSessionGetTestHistoryTool(server);\n registerSessionGetScoreHistoryTool(server);\n registerSessionCalculateCurrentScoreTool(server);\n\n // Batch Operations Tools\n registerSessionsCompareTool(server);\n registerSessionsAggregateTool(server);\n registerSessionsExportTool(server);\n\n // Note: Functional Testing Support Tools are internal only, not exposed as MCP tools\n\n logger.info('Registered monitoring and reporting tools');\n}\n\n/**\n * Session Management Tools\n */\n\n// session_start tool removed - sessions are now auto-created when needed\n// Sessions are automatically created when MCP tools are called with queryPath\n// If explicit session creation is needed, provide sessionId=null and it will auto-create\n\nfunction registerSessionEndTool(server: McpServer): void {\n server.tool(\n 'session_end',\n 'End a query development session with final status',\n {\n sessionId: z.string().describe('ID of the session to end'),\n status: z.enum(['completed', 'failed', 'abandoned']).describe('Final status of the session'),\n },\n async ({ sessionId, status }) => {\n try {\n const session = await sessionDataManager.endSession(sessionId, status);\n \n if (!session) {\n return {\n content: [\n {\n type: 'text',\n text: `Session not found: ${sessionId}`,\n },\n ],\n isError: true,\n };\n }\n\n return {\n content: [\n {\n type: 'text',\n text: JSON.stringify(session, null, 2),\n },\n ],\n };\n } catch (error) {\n logger.error('Error ending session:', error);\n return {\n content: [\n {\n type: 'text',\n text: `Error ending session: ${error instanceof Error ? error.message : 'Unknown error'}`,\n },\n ],\n isError: true,\n };\n }\n }\n );\n}\n\nfunction registerSessionGetTool(server: McpServer): void {\n server.tool(\n 'session_get',\n 'Get complete details of a specific query development session',\n {\n sessionId: z.string().describe('ID of the session to retrieve'),\n },\n async ({ sessionId }) => {\n try {\n const session = await sessionDataManager.getSession(sessionId);\n \n if (!session) {\n return {\n content: [\n {\n type: 'text',\n text: `Session not found: ${sessionId}`,\n },\n ],\n isError: true,\n };\n }\n\n return {\n content: [\n {\n type: 'text',\n text: JSON.stringify(session, null, 2),\n },\n ],\n };\n } catch (error) {\n logger.error('Error getting session:', error);\n return {\n content: [\n {\n type: 'text',\n text: `Error getting session: ${error instanceof Error ? error.message : 'Unknown error'}`,\n },\n ],\n isError: true,\n };\n }\n }\n );\n}\n\nfunction registerSessionListTool(server: McpServer): void {\n server.tool(\n 'session_list',\n 'List query development sessions with optional filtering',\n {\n queryPath: z.string().optional().describe('Filter by query path (partial match)'),\n status: z.string().optional().describe('Filter by session status'),\n dateRange: z.array(z.string()).length(2).optional().describe('Filter by date range [start, end] (ISO timestamps)'),\n language: z.string().optional().describe('Filter by programming language'),\n queryType: z.string().optional().describe('Filter by query type'),\n },\n async ({ queryPath, status, dateRange, language, queryType }) => {\n try {\n const filters: SessionFilter = {};\n if (queryPath) filters.queryPath = queryPath;\n if (status) filters.status = status;\n if (dateRange) filters.dateRange = [dateRange[0], dateRange[1]];\n if (language) filters.language = language;\n if (queryType) filters.queryType = queryType;\n\n const sessions = await sessionDataManager.listSessions(\n Object.keys(filters).length > 0 ? filters : undefined\n );\n\n const sessionList = {\n totalSessions: sessions.length,\n sessions: sessions.map(s => ({\n sessionId: s.sessionId,\n queryPath: s.queryPath,\n language: s.language,\n status: s.status,\n startTime: s.startTime,\n endTime: s.endTime,\n mcpCallsCount: s.mcpCalls.length,\n testExecutionsCount: s.testExecutions.length,\n currentScore: s.qualityScores.length > 0 \n ? s.qualityScores[s.qualityScores.length - 1].overallScore \n : null,\n })),\n };\n\n return {\n content: [\n {\n type: 'text',\n text: JSON.stringify(sessionList, null, 2),\n },\n ],\n recommendations: generateListRecommendations(sessions),\n };\n } catch (error) {\n logger.error('Error listing sessions:', error);\n return {\n content: [\n {\n type: 'text',\n text: `Error listing sessions: ${error instanceof Error ? error.message : 'Unknown error'}`,\n },\n ],\n isError: true,\n };\n }\n }\n );\n}\n\nfunction registerSessionUpdateStateTool(server: McpServer): void {\n server.tool(\n 'session_update_state',\n 'Update the current state of a query development session',\n {\n sessionId: z.string().describe('ID of the session to update'),\n filesPresent: z.array(z.string()).optional().describe('List of files present in the query development'),\n compilationStatus: z.enum(['unknown', 'success', 'failed']).optional().describe('Current compilation status'),\n testStatus: z.enum(['unknown', 'passing', 'failing', 'no_tests']).optional().describe('Current test status'),\n documentationStatus: z.enum(['unknown', 'present', 'missing', 'incomplete']).optional().describe('Documentation status'),\n },\n async ({ sessionId, filesPresent, compilationStatus, testStatus, documentationStatus }) => {\n try {\n const stateUpdate: Record = {};\n if (filesPresent !== undefined) stateUpdate.filesPresent = filesPresent;\n if (compilationStatus !== undefined) stateUpdate.compilationStatus = compilationStatus;\n if (testStatus !== undefined) stateUpdate.testStatus = testStatus;\n if (documentationStatus !== undefined) stateUpdate.documentationStatus = documentationStatus;\n\n const session = await sessionDataManager.updateSessionState(sessionId, stateUpdate);\n \n if (!session) {\n return {\n content: [\n {\n type: 'text',\n text: `Session not found: ${sessionId}`,\n },\n ],\n isError: true,\n };\n }\n\n return {\n content: [\n {\n type: 'text',\n text: JSON.stringify(session, null, 2),\n },\n ],\n recommendations: generateRecommendations(session, 'session_update_state'),\n };\n } catch (error) {\n logger.error('Error updating session state:', error);\n return {\n content: [\n {\n type: 'text',\n text: `Error updating session state: ${error instanceof Error ? error.message : 'Unknown error'}`,\n },\n ],\n isError: true,\n };\n }\n }\n );\n}\n\n/**\n * Session Analytics Tools\n */\n\nfunction registerSessionGetCallHistoryTool(server: McpServer): void {\n server.tool(\n 'session_get_call_history',\n 'Get MCP call history for a specific session',\n {\n sessionId: z.string().describe('ID of the session'),\n limit: z.number().optional().describe('Maximum number of calls to return (most recent first)'),\n },\n async ({ sessionId, limit }) => {\n try {\n const session = await sessionDataManager.getSession(sessionId);\n \n if (!session) {\n return {\n content: [\n {\n type: 'text',\n text: `Session not found: ${sessionId}`,\n },\n ],\n isError: true,\n };\n }\n\n let calls = [...session.mcpCalls].reverse(); // Most recent first\n if (limit && limit > 0) {\n calls = calls.slice(0, limit);\n }\n\n return {\n content: [\n {\n type: 'text',\n text: JSON.stringify({\n sessionId,\n totalCalls: session.mcpCalls.length,\n callHistory: calls,\n }, null, 2),\n },\n ],\n };\n } catch (error) {\n logger.error('Error getting call history:', error);\n return {\n content: [\n {\n type: 'text',\n text: `Error getting call history: ${error instanceof Error ? error.message : 'Unknown error'}`,\n },\n ],\n isError: true,\n };\n }\n }\n );\n}\n\nfunction registerSessionGetTestHistoryTool(server: McpServer): void {\n server.tool(\n 'session_get_test_history',\n 'Get test execution history for a specific session',\n {\n sessionId: z.string().describe('ID of the session'),\n limit: z.number().optional().describe('Maximum number of test executions to return (most recent first)'),\n },\n async ({ sessionId, limit }) => {\n try {\n const session = await sessionDataManager.getSession(sessionId);\n \n if (!session) {\n return {\n content: [\n {\n type: 'text',\n text: `Session not found: ${sessionId}`,\n },\n ],\n isError: true,\n };\n }\n\n let tests = [...session.testExecutions].reverse(); // Most recent first\n if (limit && limit > 0) {\n tests = tests.slice(0, limit);\n }\n\n return {\n content: [\n {\n type: 'text',\n text: JSON.stringify({\n sessionId,\n totalTests: session.testExecutions.length,\n testHistory: tests,\n }, null, 2),\n },\n ],\n };\n } catch (error) {\n logger.error('Error getting test history:', error);\n return {\n content: [\n {\n type: 'text',\n text: `Error getting test history: ${error instanceof Error ? error.message : 'Unknown error'}`,\n },\n ],\n isError: true,\n };\n }\n }\n );\n}\n\nfunction registerSessionGetScoreHistoryTool(server: McpServer): void {\n server.tool(\n 'session_get_score_history',\n 'Get quality score history for a specific session',\n {\n sessionId: z.string().describe('ID of the session'),\n limit: z.number().optional().describe('Maximum number of scores to return (most recent first)'),\n },\n async ({ sessionId, limit }) => {\n try {\n const session = await sessionDataManager.getSession(sessionId);\n \n if (!session) {\n return {\n content: [\n {\n type: 'text',\n text: `Session not found: ${sessionId}`,\n },\n ],\n isError: true,\n };\n }\n\n let scores = [...session.qualityScores].reverse(); // Most recent first\n if (limit && limit > 0) {\n scores = scores.slice(0, limit);\n }\n\n return {\n content: [\n {\n type: 'text',\n text: JSON.stringify({\n sessionId,\n totalScores: session.qualityScores.length,\n scoreHistory: scores,\n }, null, 2),\n },\n ],\n };\n } catch (error) {\n logger.error('Error getting score history:', error);\n return {\n content: [\n {\n type: 'text',\n text: `Error getting score history: ${error instanceof Error ? error.message : 'Unknown error'}`,\n },\n ],\n isError: true,\n };\n }\n }\n );\n}\n\nfunction registerSessionCalculateCurrentScoreTool(server: McpServer): void {\n server.tool(\n 'session_calculate_current_score',\n 'Calculate current quality score for a session based on its state',\n {\n sessionId: z.string().describe('ID of the session'),\n },\n async ({ sessionId }) => {\n try {\n const session = await sessionDataManager.getSession(sessionId);\n \n if (!session) {\n return {\n content: [\n {\n type: 'text',\n text: `Session not found: ${sessionId}`,\n },\n ],\n isError: true,\n };\n }\n\n // Calculate quality score based on current state\n const scoreRecord = calculateQualityScore(session);\n \n // Add the score to the session\n await sessionDataManager.addQualityScore(sessionId, scoreRecord);\n \n // Get updated session with new score\n const updatedSession = await sessionDataManager.getSession(sessionId);\n\n return {\n content: [\n {\n type: 'text',\n text: JSON.stringify(scoreRecord, null, 2),\n },\n ],\n recommendations: generateRecommendations(updatedSession, 'session_calculate_current_score'),\n };\n } catch (error) {\n logger.error('Error calculating current score:', error);\n return {\n content: [\n {\n type: 'text',\n text: `Error calculating current score: ${error instanceof Error ? error.message : 'Unknown error'}`,\n },\n ],\n isError: true,\n };\n }\n }\n );\n}\n\n/**\n * Batch Operations Tools\n */\n\nfunction registerSessionsCompareTool(server: McpServer): void {\n server.tool(\n 'sessions_compare',\n 'Compare multiple query development sessions across specified dimensions',\n {\n sessionIds: z.array(z.string()).describe('Array of session IDs to compare'),\n dimensions: z.array(z.string()).optional().describe('Specific dimensions to compare (default: all)'),\n },\n async ({ sessionIds, dimensions }) => {\n try {\n const sessions = await Promise.all(\n sessionIds.map(id => sessionDataManager.getSession(id))\n );\n\n const validSessions = sessions.filter(s => s !== null) as QueryDevelopmentSession[];\n \n if (validSessions.length === 0) {\n return {\n content: [\n {\n type: 'text',\n text: 'No valid sessions found for comparison',\n },\n ],\n isError: true,\n };\n }\n\n const comparison = await compareSessions(validSessions, dimensions);\n\n return {\n content: [\n {\n type: 'text',\n text: JSON.stringify(comparison, null, 2),\n },\n ],\n };\n } catch (error) {\n logger.error('Error comparing sessions:', error);\n return {\n content: [\n {\n type: 'text',\n text: `Error comparing sessions: ${error instanceof Error ? error.message : 'Unknown error'}`,\n },\n ],\n isError: true,\n };\n }\n }\n );\n}\n\nfunction registerSessionsAggregateTool(server: McpServer): void {\n server.tool(\n 'sessions_aggregate',\n 'Generate aggregate insights from multiple sessions based on filters',\n {\n queryPath: z.string().optional().describe('Filter by query path (partial match)'),\n status: z.string().optional().describe('Filter by session status'),\n dateRange: z.array(z.string()).length(2).optional().describe('Filter by date range [start, end] (ISO timestamps)'),\n language: z.string().optional().describe('Filter by programming language'),\n queryType: z.string().optional().describe('Filter by query type'),\n },\n async ({ queryPath, status, dateRange, language, queryType }) => {\n try {\n const filters: SessionFilter = {};\n if (queryPath) filters.queryPath = queryPath;\n if (status) filters.status = status;\n if (dateRange) filters.dateRange = [dateRange[0], dateRange[1]];\n if (language) filters.language = language;\n if (queryType) filters.queryType = queryType;\n\n const sessions = await sessionDataManager.listSessions(\n Object.keys(filters).length > 0 ? filters : undefined\n );\n\n const aggregate = await aggregateSessions(sessions, filters);\n\n return {\n content: [\n {\n type: 'text',\n text: JSON.stringify(aggregate, null, 2),\n },\n ],\n };\n } catch (error) {\n logger.error('Error aggregating sessions:', error);\n return {\n content: [\n {\n type: 'text',\n text: `Error aggregating sessions: ${error instanceof Error ? error.message : 'Unknown error'}`,\n },\n ],\n isError: true,\n };\n }\n }\n );\n}\n\nfunction registerSessionsExportTool(server: McpServer): void {\n server.tool(\n 'sessions_export',\n 'Export session data in specified format for external analysis',\n {\n sessionIds: z.array(z.string()).describe('Array of session IDs to export'),\n format: z.enum(['json', 'html', 'markdown']).optional().default('json').describe('Export format'),\n },\n async ({ sessionIds, format = 'json' }) => {\n try {\n const sessions = await Promise.all(\n sessionIds.map(id => sessionDataManager.getSession(id))\n );\n\n const validSessions = sessions.filter(s => s !== null) as QueryDevelopmentSession[];\n \n if (validSessions.length === 0) {\n return {\n content: [\n {\n type: 'text',\n text: 'No valid sessions found for export',\n },\n ],\n isError: true,\n };\n }\n\n const exportResult = await exportSessions(validSessions, format);\n\n return {\n content: [\n {\n type: 'text',\n text: JSON.stringify(exportResult, null, 2),\n },\n ],\n };\n } catch (error) {\n logger.error('Error exporting sessions:', error);\n return {\n content: [\n {\n type: 'text',\n text: `Error exporting sessions: ${error instanceof Error ? error.message : 'Unknown error'}`,\n },\n ],\n isError: true,\n };\n }\n }\n );\n}\n\n/**\n * Helper Functions\n */\n\n/**\n * Calculate quality score for a session based on current state and history\n */\nfunction calculateQualityScore(session: QueryDevelopmentSession): QualityScoreRecord {\n const timestamp = new Date().toISOString();\n \n // Calculate syntactic correctness (25%)\n const syntacticCorrectness = session.currentState.compilationStatus === 'success' ? 100 :\n session.currentState.compilationStatus === 'failed' ? 0 : 50;\n\n // Calculate test coverage and results (30%)\n const testCoverageResults = session.currentState.testStatus === 'passing' ? 100 :\n session.currentState.testStatus === 'failing' ? 25 :\n session.currentState.testStatus === 'no_tests' ? 0 : 50;\n\n // Calculate documentation quality (20%)\n const documentationQuality = session.currentState.documentationStatus === 'present' ? 100 :\n session.currentState.documentationStatus === 'incomplete' ? 60 :\n session.currentState.documentationStatus === 'missing' ? 0 : 50;\n\n // Calculate functional correctness (25%) - based on successful test runs\n const successfulTests = session.testExecutions.filter(t => t.success && t.type === 'test_run').length;\n const totalTests = session.testExecutions.filter(t => t.type === 'test_run').length;\n const functionalCorrectness = totalTests > 0 ? (successfulTests / totalTests) * 100 : 50;\n\n // Calculate overall score\n const overallScore = Math.round(\n (syntacticCorrectness * 0.25) +\n (testCoverageResults * 0.30) +\n (documentationQuality * 0.20) +\n (functionalCorrectness * 0.25)\n );\n\n // Determine grade\n const grade = overallScore >= 90 ? 'A' :\n overallScore >= 80 ? 'B' :\n overallScore >= 70 ? 'C' :\n overallScore >= 60 ? 'D' : 'F';\n\n // Generate recommendations\n const recommendations: string[] = [];\n if (syntacticCorrectness < 100) {\n recommendations.push('Fix compilation errors to improve syntactic correctness');\n }\n if (testCoverageResults < 70) {\n recommendations.push('Add comprehensive tests and ensure they pass');\n }\n if (documentationQuality < 80) {\n recommendations.push('Add or improve query documentation with examples');\n }\n if (functionalCorrectness < 80) {\n recommendations.push('Improve test pass rate and verify query logic');\n }\n\n return {\n scoreId: randomUUID(),\n timestamp,\n overallScore,\n dimensions: {\n syntacticCorrectness,\n testCoverageResults,\n documentationQuality,\n functionalCorrectness,\n },\n grade,\n recommendations,\n };\n}\n\n/**\n * Compare multiple sessions\n */\nasync function compareSessions(\n sessions: QueryDevelopmentSession[],\n dimensions?: string[]\n): Promise {\n const timestamp = new Date().toISOString();\n const sessionIds = sessions.map(s => s.sessionId);\n \n const results: Record = {\n sessionCount: sessions.length,\n sessionOverview: sessions.map(s => ({\n sessionId: s.sessionId,\n queryPath: s.queryPath,\n status: s.status,\n mcpCallsCount: s.mcpCalls.length,\n duration: s.endTime ? \n new Date(s.endTime).getTime() - new Date(s.startTime).getTime() : \n new Date().getTime() - new Date(s.startTime).getTime(),\n currentScore: s.qualityScores.length > 0 ? \n s.qualityScores[s.qualityScores.length - 1].overallScore : null,\n })),\n };\n\n if (!dimensions || dimensions.includes('quality')) {\n const qualityScores = sessions.map(s => \n s.qualityScores.length > 0 ? s.qualityScores[s.qualityScores.length - 1] : null\n );\n results.qualityComparison = {\n averageScore: qualityScores\n .filter(q => q !== null)\n .reduce((sum, q) => sum + q!.overallScore, 0) / qualityScores.filter(q => q !== null).length,\n scoreRange: {\n min: Math.min(...qualityScores.filter(q => q !== null).map(q => q!.overallScore)),\n max: Math.max(...qualityScores.filter(q => q !== null).map(q => q!.overallScore)),\n },\n };\n }\n\n if (!dimensions || dimensions.includes('activity')) {\n results.activityComparison = {\n totalMCPCalls: sessions.reduce((sum, s) => sum + s.mcpCalls.length, 0),\n averageCallsPerSession: sessions.reduce((sum, s) => sum + s.mcpCalls.length, 0) / sessions.length,\n mostActiveTool: getMostUsedTool(sessions),\n };\n }\n\n return {\n sessionIds,\n dimensions: dimensions || ['all'],\n timestamp,\n results,\n };\n}\n\n/**\n * Aggregate insights from multiple sessions\n */\nasync function aggregateSessions(\n sessions: QueryDevelopmentSession[],\n filters: SessionFilter\n): Promise {\n const timestamp = new Date().toISOString();\n \n const completedSessions = sessions.filter(s => s.status === 'completed');\n const successRate = sessions.length > 0 ? completedSessions.length / sessions.length : 0;\n \n const qualityScores = sessions\n .map(s => s.qualityScores.length > 0 ? s.qualityScores[s.qualityScores.length - 1].overallScore : null)\n .filter(score => score !== null) as number[];\n \n const averageQualityScore = qualityScores.length > 0 ? \n qualityScores.reduce((sum, score) => sum + score, 0) / qualityScores.length : 0;\n\n const commonPatterns = identifyCommonPatterns(sessions);\n const recommendations = generateAggregateRecommendations(sessions);\n\n return {\n filters,\n timestamp,\n totalSessions: sessions.length,\n successRate,\n averageQualityScore,\n commonPatterns,\n recommendations,\n };\n}\n\n/**\n * Export sessions in specified format\n */\nasync function exportSessions(\n sessions: QueryDevelopmentSession[],\n format: 'json' | 'html' | 'markdown'\n): Promise {\n const timestamp = new Date().toISOString();\n const filename = `session-export-${timestamp.replace(/[:.]/g, '-')}.${format}`;\n \n let content: string;\n \n switch (format) {\n case 'json':\n content = JSON.stringify(sessions, null, 2);\n break;\n case 'html':\n content = generateHTMLReport(sessions);\n break;\n case 'markdown':\n content = generateMarkdownReport(sessions);\n break;\n }\n\n return {\n format,\n filename,\n content,\n timestamp,\n };\n}\n\n/**\n * Utility functions\n */\n\nfunction getMostUsedTool(sessions: QueryDevelopmentSession[]): string {\n const toolCounts: Record = {};\n \n sessions.forEach(session => {\n session.mcpCalls.forEach(call => {\n toolCounts[call.toolName] = (toolCounts[call.toolName] || 0) + 1;\n });\n });\n\n return Object.entries(toolCounts)\n .sort(([, a], [, b]) => b - a)[0]?.[0] || 'none';\n}\n\nfunction identifyCommonPatterns(sessions: QueryDevelopmentSession[]): string[] {\n const patterns: string[] = [];\n \n const commonTools = getMostUsedTool(sessions);\n if (commonTools && commonTools !== 'none') {\n patterns.push(`Most commonly used tool: ${commonTools}`);\n }\n\n const completionRate = sessions.filter(s => s.status === 'completed').length / sessions.length;\n if (completionRate > 0.8) {\n patterns.push('High completion rate indicates effective workflow');\n } else if (completionRate < 0.5) {\n patterns.push('Low completion rate suggests workflow issues');\n }\n\n return patterns;\n}\n\nfunction generateAggregateRecommendations(sessions: QueryDevelopmentSession[]): string[] {\n const recommendations: string[] = [];\n \n const failedSessions = sessions.filter(s => s.status === 'failed');\n if (failedSessions.length > sessions.length * 0.3) {\n recommendations.push('High failure rate - consider improving error handling and guidance');\n }\n\n const averageCallsPerSession = sessions.reduce((sum, s) => sum + s.mcpCalls.length, 0) / sessions.length;\n if (averageCallsPerSession > 20) {\n recommendations.push('High number of MCP calls per session - consider workflow optimization');\n }\n\n return recommendations;\n}\n\nfunction generateHTMLReport(sessions: QueryDevelopmentSession[]): string {\n const html = `\n\n\n\n Session Export Report\n \n\n\n

Query Development Sessions Report

\n

Generated: ${new Date().toISOString()}

\n

Total Sessions: ${sessions.length}

\n \n ${sessions.map(session => `\n
\n

Session: ${session.sessionId}

\n

Query Path: ${session.queryPath}

\n

Status: ${session.status}

\n

Language: ${session.language}

\n

Start Time: ${session.startTime}

\n

MCP Calls: ${session.mcpCalls.length}

\n

Test Executions: ${session.testExecutions.length}

\n

Quality Scores: ${session.qualityScores.length}

\n
\n `).join('')}\n\n`;\n \n return html;\n}\n\nfunction generateMarkdownReport(sessions: QueryDevelopmentSession[]): string {\n const md = `# Query Development Sessions Report\n\nGenerated: ${new Date().toISOString()}\nTotal Sessions: ${sessions.length}\n\n## Session Summary\n\n| Session ID | Query Path | Status | Language | MCP Calls | Test Executions |\n|------------|-----------|--------|----------|-----------|-----------------|\n${sessions.map(session => \n `| ${session.sessionId} | ${session.queryPath} | ${session.status} | ${session.language} | ${session.mcpCalls.length} | ${session.testExecutions.length} |`\n).join('\\n')}\n\n## Detailed Sessions\n\n${sessions.map(session => `\n### Session: ${session.sessionId}\n\n- **Query Path:** ${session.queryPath}\n- **Status:** ${session.status}\n- **Language:** ${session.language}\n- **Start Time:** ${session.startTime}\n- **End Time:** ${session.endTime || 'N/A'}\n- **MCP Calls:** ${session.mcpCalls.length}\n- **Test Executions:** ${session.testExecutions.length}\n- **Quality Scores:** ${session.qualityScores.length}\n\n${session.recommendations.length > 0 ? `\n**Current Recommendations:**\n${session.recommendations.map(rec => `- ${rec}`).join('\\n')}\n` : ''}\n`).join('\\n')}`;\n\n return md;\n}\n\nfunction _calculateAverageDuration(sessions: QueryDevelopmentSession[]): number {\n const completedSessions = sessions.filter(s => s.endTime);\n if (completedSessions.length === 0) return 0;\n\n const totalDuration = completedSessions.reduce((sum, session) => {\n return sum + (new Date(session.endTime!).getTime() - new Date(session.startTime).getTime());\n }, 0);\n\n return totalDuration / completedSessions.length;\n}\n\nfunction _identifyFailureReasons(results: FunctionalTestResult[]): string[] {\n const failedResults = results.filter(r => !r.passed);\n const reasons: Record = {};\n\n failedResults.forEach(result => {\n Object.entries(result.criteria).forEach(([criterion, passed]) => {\n if (!passed) {\n reasons[criterion] = (reasons[criterion] || 0) + 1;\n }\n });\n });\n\n return Object.entries(reasons)\n .sort(([, a], [, b]) => b - a)\n .map(([reason, count]) => `${reason}: ${count} sessions`);\n}\n\n/**\n * Generate recommendations for MCP tool responses\n * Returns a map of MCP primitive paths to recommendation reasons\n */\nfunction generateRecommendations(\n session: QueryDevelopmentSession | null,\n currentTool: string\n): Record {\n if (!session) {\n return {};\n }\n\n const recommendations: Record = {};\n\n // Session state-based recommendations\n if (session.currentState.compilationStatus === 'failed') {\n recommendations['codeql_query_format'] = 'Format query to fix potential syntax issues';\n recommendations['codeql_query_compile'] = 'Recompile after fixing syntax errors';\n } else if (session.currentState.compilationStatus === 'success') {\n if (session.currentState.testStatus === 'unknown' || session.currentState.testStatus === 'no_tests') {\n recommendations['codeql_test_run'] = 'Run tests to validate query functionality';\n } else if (session.currentState.testStatus === 'failing') {\n recommendations['session_get_test_history'] = 'Review test failures to identify issues';\n recommendations['codeql_query_compile'] = 'Verify query logic matches test expectations';\n } else if (session.currentState.testStatus === 'passing') {\n recommendations['session_calculate_current_score'] = 'Calculate quality score for completed query';\n }\n }\n\n // Tool-specific follow-up recommendations\n switch (currentTool) {\n case 'session_get':\n if (session.mcpCalls.length === 0) {\n recommendations['codeql_query_compile'] = 'Start development by compiling the query';\n }\n break;\n case 'session_end':\n if (session.status === 'completed') {\n recommendations['sessions_export'] = 'Export session data for analysis';\n }\n break;\n case 'session_calculate_current_score': {\n const latestScore = session.qualityScores[session.qualityScores.length - 1];\n if (latestScore && latestScore.overallScore < 80) {\n if (latestScore.dimensions.syntacticCorrectness < 100) {\n recommendations['codeql_query_format'] = 'Improve syntax and formatting';\n }\n if (latestScore.dimensions.testCoverageResults < 70) {\n recommendations['codeql_test_run'] = 'Improve test coverage and results';\n }\n }\n break;\n }\n case 'session_update_state':\n // Recommend next logical step based on updated state\n if (session.currentState.compilationStatus === 'success' && session.currentState.testStatus === 'unknown') {\n recommendations['codeql_test_run'] = 'Run tests now that compilation is successful';\n }\n break;\n }\n\n return recommendations;\n}\n\n/**\n * Generate recommendations for session list results\n */\nfunction generateListRecommendations(sessions: QueryDevelopmentSession[]): Record {\n const recommendations: Record = {};\n\n const activeSessions = sessions.filter(s => s.status === 'active');\n const completedSessions = sessions.filter(s => s.status === 'completed');\n\n if (activeSessions.length > 0) {\n recommendations['session_get'] = `Review details of ${activeSessions.length} active session(s)`;\n }\n\n if (completedSessions.length > 1) {\n recommendations['sessions_compare'] = 'Compare completed sessions to identify patterns';\n recommendations['sessions_aggregate'] = 'Generate aggregate insights from multiple sessions';\n }\n\n if (sessions.length > 5) {\n recommendations['sessions_export'] = 'Export session data for comprehensive analysis';\n }\n\n return recommendations;\n}", "function checkArgs(adapter, defaultData) {\n if (adapter === undefined)\n throw new Error('lowdb: missing adapter');\n if (defaultData === undefined)\n throw new Error('lowdb: missing default data');\n}\nexport class Low {\n adapter;\n data;\n constructor(adapter, defaultData) {\n checkArgs(adapter, defaultData);\n this.adapter = adapter;\n this.data = defaultData;\n }\n async read() {\n const data = await this.adapter.read();\n if (data)\n this.data = data;\n }\n async write() {\n if (this.data)\n await this.adapter.write(this.data);\n }\n async update(fn) {\n fn(this.data);\n await this.write();\n }\n}\nexport class LowSync {\n adapter;\n data;\n constructor(adapter, defaultData) {\n checkArgs(adapter, defaultData);\n this.adapter = adapter;\n this.data = defaultData;\n }\n read() {\n const data = this.adapter.read();\n if (data)\n this.data = data;\n }\n write() {\n if (this.data)\n this.adapter.write(this.data);\n }\n update(fn) {\n fn(this.data);\n this.write();\n }\n}\n", "import { readFileSync, renameSync, writeFileSync } from 'node:fs';\nimport { readFile } from 'node:fs/promises';\nimport path from 'node:path';\nimport { Writer } from 'steno';\nexport class TextFile {\n #filename;\n #writer;\n constructor(filename) {\n this.#filename = filename;\n this.#writer = new Writer(filename);\n }\n async read() {\n let data;\n try {\n data = await readFile(this.#filename, 'utf-8');\n }\n catch (e) {\n if (e.code === 'ENOENT') {\n return null;\n }\n throw e;\n }\n return data;\n }\n write(str) {\n return this.#writer.write(str);\n }\n}\nexport class TextFileSync {\n #tempFilename;\n #filename;\n constructor(filename) {\n this.#filename = filename;\n const f = filename.toString();\n this.#tempFilename = path.join(path.dirname(f), `.${path.basename(f)}.tmp`);\n }\n read() {\n let data;\n try {\n data = readFileSync(this.#filename, 'utf-8');\n }\n catch (e) {\n if (e.code === 'ENOENT') {\n return null;\n }\n throw e;\n }\n return data;\n }\n write(str) {\n writeFileSync(this.#tempFilename, str);\n renameSync(this.#tempFilename, this.#filename);\n }\n}\n", "import { TextFile, TextFileSync } from './TextFile.js';\nexport class DataFile {\n #adapter;\n #parse;\n #stringify;\n constructor(filename, { parse, stringify, }) {\n this.#adapter = new TextFile(filename);\n this.#parse = parse;\n this.#stringify = stringify;\n }\n async read() {\n const data = await this.#adapter.read();\n if (data === null) {\n return null;\n }\n else {\n return this.#parse(data);\n }\n }\n write(obj) {\n return this.#adapter.write(this.#stringify(obj));\n }\n}\nexport class DataFileSync {\n #adapter;\n #parse;\n #stringify;\n constructor(filename, { parse, stringify, }) {\n this.#adapter = new TextFileSync(filename);\n this.#parse = parse;\n this.#stringify = stringify;\n }\n read() {\n const data = this.#adapter.read();\n if (data === null) {\n return null;\n }\n else {\n return this.#parse(data);\n }\n }\n write(obj) {\n this.#adapter.write(this.#stringify(obj));\n }\n}\n", "import { DataFile, DataFileSync } from './DataFile.js';\nexport class JSONFile extends DataFile {\n constructor(filename) {\n super(filename, {\n parse: JSON.parse,\n stringify: (data) => JSON.stringify(data, null, 2),\n });\n }\n}\nexport class JSONFileSync extends DataFileSync {\n constructor(filename) {\n super(filename, {\n parse: JSON.parse,\n stringify: (data) => JSON.stringify(data, null, 2),\n });\n }\n}\n", "/**\n * Session Data Management\n * Provides unified JSON storage and session lifecycle management using lowdb\n */\n\nimport { Low } from 'lowdb';\nimport { JSONFileSync } from 'lowdb/node';\nimport { mkdirSync, writeFileSync } from 'fs';\nimport { join } from 'path';\nimport { randomUUID } from 'crypto';\nimport { getProjectTmpBase } from '../utils/temp-dir';\nimport {\n QueryDevelopmentSession,\n QueryState,\n MCPCallRecord,\n TestExecutionRecord,\n QualityScoreRecord,\n SessionFilter,\n MonitoringConfig,\n MonitoringConfigSchema,\n} from '../types/monitoring';\nimport { logger } from '../utils/logger';\n\n/**\n * Database schema for lowdb - sessions only\n */\ninterface SessionDatabase {\n sessions: QueryDevelopmentSession[];\n}\n\n/**\n * Session Data Manager - handles all session persistence and lifecycle\n */\nexport class SessionDataManager {\n private db: Low;\n private config: MonitoringConfig;\n private storageDir: string;\n\n constructor(configOverrides: Partial = {}) {\n this.config = MonitoringConfigSchema.parse({\n ...MonitoringConfigSchema.parse({}),\n ...configOverrides,\n });\n\n this.storageDir = this.config.storageLocation;\n this.ensureStorageDirectory();\n\n const adapter = new JSONFileSync(join(this.storageDir, 'sessions.json'));\n this.db = new Low(adapter, {\n sessions: [],\n });\n\n this.initializeDatabase();\n }\n\n /**\n * Initialize the database and ensure it's properly set up\n */\n async initialize(): Promise {\n await this.initializeDatabase();\n }\n\n /**\n * Initialize the database and ensure it's properly set up\n */\n private async initializeDatabase(): Promise {\n try {\n await this.db.read();\n \n logger.info(`Session data manager initialized with ${this.db.data.sessions.length} sessions`);\n } catch (error) {\n logger.error('Failed to initialize session database:', error);\n throw error;\n }\n }\n\n /**\n * Ensure storage directory structure exists\n */\n private ensureStorageDirectory(): void {\n try {\n // mkdirSync with recursive: true is a no-op if directories already exist\n mkdirSync(this.storageDir, { recursive: true });\n\n // Create subdirectories\n const subdirs = ['sessions-archive', 'exports'];\n for (const subdir of subdirs) {\n mkdirSync(join(this.storageDir, subdir), { recursive: true });\n }\n\n // Use 'wx' flag (exclusive create) to atomically create config only\n // if it doesn't exist, avoiding TOCTOU race (CWE-367).\n const configPath = join(this.storageDir, 'config.json');\n try {\n writeFileSync(configPath, JSON.stringify(this.config, null, 2), { flag: 'wx' });\n } catch (e: unknown) {\n const err = e as { code?: string };\n if (err.code !== 'EEXIST') throw e;\n }\n\n logger.debug(`Storage directory initialized: ${this.storageDir}`);\n } catch (error) {\n logger.error('Failed to create storage directory:', error);\n throw error;\n }\n }\n\n /**\n * Start a new query development session\n */\n async startSession(\n queryPath: string,\n language?: string,\n queryType?: string,\n description?: string\n ): Promise {\n const sessionId = randomUUID();\n const startTime = new Date().toISOString();\n\n const session: QueryDevelopmentSession = {\n sessionId,\n queryPath,\n language: language || 'unknown',\n queryType,\n description,\n startTime,\n status: 'active',\n mcpCalls: [],\n testExecutions: [],\n qualityScores: [],\n currentState: {\n filesPresent: [],\n compilationStatus: 'unknown',\n testStatus: 'unknown',\n documentationStatus: 'unknown',\n lastActivity: startTime,\n },\n recommendations: [],\n };\n\n await this.db.read();\n this.db.data.sessions.push(session);\n await this.db.write();\n\n logger.info(`Started new session: ${sessionId} for query: ${queryPath}`);\n return sessionId;\n }\n\n /**\n * End a session with final status\n */\n async endSession(\n sessionId: string,\n status: 'completed' | 'failed' | 'abandoned'\n ): Promise {\n await this.db.read();\n \n const session = this.db.data.sessions.find(s => s.sessionId === sessionId);\n if (!session) {\n logger.warn(`Session not found: ${sessionId}`);\n return null;\n }\n\n session.status = status;\n session.endTime = new Date().toISOString();\n session.currentState.lastActivity = session.endTime;\n\n await this.db.write();\n\n // Archive completed session if enabled\n if (this.config.archiveCompletedSessions && status === 'completed') {\n await this.archiveSession(sessionId);\n }\n\n logger.info(`Ended session: ${sessionId} with status: ${status}`);\n return session;\n }\n\n /**\n * Get a specific session by ID\n */\n async getSession(sessionId: string): Promise {\n await this.db.read();\n const session = this.db.data.sessions.find(s => s.sessionId === sessionId);\n return session || null;\n }\n\n /**\n * List sessions with optional filtering\n */\n async listSessions(filters?: SessionFilter): Promise {\n await this.db.read();\n let sessions = [...this.db.data.sessions];\n\n if (filters) {\n if (filters.queryPath) {\n sessions = sessions.filter(s => s.queryPath.includes(filters.queryPath!));\n }\n if (filters.status) {\n sessions = sessions.filter(s => s.status === filters.status);\n }\n if (filters.language) {\n sessions = sessions.filter(s => s.language === filters.language);\n }\n if (filters.queryType) {\n sessions = sessions.filter(s => s.queryType === filters.queryType);\n }\n if (filters.dateRange) {\n const [start, end] = filters.dateRange;\n sessions = sessions.filter(s => \n s.startTime >= start && s.startTime <= end\n );\n }\n }\n\n return sessions;\n }\n\n /**\n * Update session state\n */\n async updateSessionState(\n sessionId: string,\n stateUpdate: Partial\n ): Promise {\n await this.db.read();\n \n const session = this.db.data.sessions.find(s => s.sessionId === sessionId);\n if (!session) {\n logger.warn(`Session not found: ${sessionId}`);\n return null;\n }\n\n session.currentState = {\n ...session.currentState,\n ...stateUpdate,\n lastActivity: new Date().toISOString(),\n };\n\n await this.db.write();\n return session;\n }\n\n /**\n * Add MCP call record to session\n */\n async addMCPCall(sessionId: string, callRecord: MCPCallRecord): Promise {\n await this.db.read();\n \n const session = this.db.data.sessions.find(s => s.sessionId === sessionId);\n if (!session) {\n logger.warn(`Session not found for MCP call: ${sessionId}`);\n return;\n }\n\n session.mcpCalls.push(callRecord);\n session.currentState.lastActivity = callRecord.timestamp;\n\n // Update next suggested tool if provided\n if (callRecord.nextSuggestedTool) {\n session.nextSuggestedTool = callRecord.nextSuggestedTool;\n }\n\n await this.db.write();\n }\n\n /**\n * Add test execution record to session\n */\n async addTestExecution(sessionId: string, testRecord: TestExecutionRecord): Promise {\n await this.db.read();\n \n const session = this.db.data.sessions.find(s => s.sessionId === sessionId);\n if (!session) {\n logger.warn(`Session not found for test execution: ${sessionId}`);\n return;\n }\n\n session.testExecutions.push(testRecord);\n session.currentState.lastActivity = testRecord.timestamp;\n\n // Update compilation/test status based on execution\n if (testRecord.type === 'compilation') {\n session.currentState.compilationStatus = testRecord.success ? 'success' : 'failed';\n } else if (testRecord.type === 'test_run') {\n session.currentState.testStatus = testRecord.success ? 'passing' : 'failing';\n }\n\n await this.db.write();\n }\n\n /**\n * Add quality score record to session\n */\n async addQualityScore(sessionId: string, scoreRecord: QualityScoreRecord): Promise {\n await this.db.read();\n \n const session = this.db.data.sessions.find(s => s.sessionId === sessionId);\n if (!session) {\n logger.warn(`Session not found for quality score: ${sessionId}`);\n return;\n }\n\n session.qualityScores.push(scoreRecord);\n session.currentState.lastActivity = scoreRecord.timestamp;\n session.recommendations = scoreRecord.recommendations;\n\n await this.db.write();\n }\n\n /**\n * Archive a completed session to monthly file\n */\n private async archiveSession(sessionId: string): Promise {\n try {\n const session = await this.getSession(sessionId);\n if (!session) return;\n\n const date = new Date(session.endTime || session.startTime);\n const monthDir = `${date.getFullYear()}-${String(date.getMonth() + 1).padStart(2, '0')}`;\n const archiveDir = join(this.storageDir, 'sessions-archive', monthDir);\n\n mkdirSync(archiveDir, { recursive: true });\n\n const archiveFile = join(archiveDir, `${sessionId}.json`);\n writeFileSync(archiveFile, JSON.stringify(session, null, 2));\n\n // Remove from active sessions\n await this.db.read();\n this.db.data.sessions = this.db.data.sessions.filter(s => s.sessionId !== sessionId);\n await this.db.write();\n\n logger.info(`Archived session: ${sessionId} to ${archiveFile}`);\n } catch (error) {\n logger.error(`Failed to archive session ${sessionId}:`, error);\n }\n }\n\n /**\n * Get active sessions for a specific query path\n */\n async getActiveSessionsForQuery(queryPath: string): Promise {\n await this.db.read();\n return this.db.data.sessions.filter(s => \n s.queryPath === queryPath && s.status === 'active'\n );\n }\n\n /**\n * Clean up old sessions based on retention policy\n */\n async cleanupOldSessions(): Promise {\n const cutoffDate = new Date();\n cutoffDate.setDate(cutoffDate.getDate() - this.config.retentionDays);\n const cutoffTimestamp = cutoffDate.toISOString();\n\n await this.db.read();\n const sessionsToRemove = this.db.data.sessions.filter(s => \n s.endTime && s.endTime < cutoffTimestamp\n );\n\n if (sessionsToRemove.length > 0) {\n this.db.data.sessions = this.db.data.sessions.filter(s => \n !s.endTime || s.endTime >= cutoffTimestamp\n );\n await this.db.write();\n\n logger.info(`Cleaned up ${sessionsToRemove.length} old sessions`);\n }\n }\n\n /**\n * Get configuration\n */\n getConfig(): MonitoringConfig {\n return this.config;\n }\n\n /**\n * Update configuration\n */\n async updateConfig(configUpdate: Partial): Promise {\n this.config = MonitoringConfigSchema.parse({\n ...this.config,\n ...configUpdate,\n });\n\n // Update config.json file only\n const configPath = join(this.storageDir, 'config.json');\n writeFileSync(configPath, JSON.stringify(this.config, null, 2));\n\n logger.info('Updated monitoring configuration');\n }\n}\n\n/**\n * Parse boolean environment variable\n */\nfunction parseBoolEnv(envVar: string | undefined, defaultValue: boolean): boolean {\n if (envVar === undefined) return defaultValue;\n return envVar.toLowerCase() === 'true' || envVar === '1';\n}\n\n// Export singleton instance with environment variable support\nexport const sessionDataManager = new SessionDataManager({\n storageLocation: process.env.MONITORING_STORAGE_LOCATION || join(getProjectTmpBase(), '.ql-mcp-tracking'),\n enableMonitoringTools: parseBoolEnv(process.env.ENABLE_MONITORING_TOOLS, false),\n});", "import { z } from 'zod';\n\n/**\n * Monitoring and Reporting types for CodeQL Development MCP Server\n * Based on the specification in docs/mcp-server-monitoring-and-reporting.md\n */\n\n/**\n * MCP Call Record - captures individual MCP tool calls\n */\nexport const MCPCallRecordSchema = z.object({\n callId: z.string(),\n timestamp: z.string(), // ISO timestamp\n toolName: z.string(),\n parameters: z.record(z.any()),\n result: z.any(),\n success: z.boolean(),\n duration: z.number(), // milliseconds\n nextSuggestedTool: z.string().optional(),\n});\n\nexport type MCPCallRecord = z.infer;\n\n/**\n * Test Execution Record - captures query compilation and test runs\n */\nexport const TestExecutionRecordSchema = z.object({\n executionId: z.string(),\n timestamp: z.string(),\n type: z.enum(['compilation', 'test_run', 'database_build']),\n success: z.boolean(),\n details: z.record(z.any()),\n metrics: z.object({\n passRate: z.number().optional(),\n coverage: z.number().optional(),\n performance: z.number().optional(),\n }).optional(),\n});\n\nexport type TestExecutionRecord = z.infer;\n\n/**\n * Quality Score Record - multi-dimensional quality assessment\n */\nexport const QualityScoreRecordSchema = z.object({\n scoreId: z.string(),\n timestamp: z.string(),\n overallScore: z.number().min(0).max(100), // 0-100\n dimensions: z.object({\n syntacticCorrectness: z.number().min(0).max(100),\n testCoverageResults: z.number().min(0).max(100),\n documentationQuality: z.number().min(0).max(100),\n functionalCorrectness: z.number().min(0).max(100),\n }),\n grade: z.enum(['A', 'B', 'C', 'D', 'F']),\n recommendations: z.array(z.string()),\n});\n\nexport type QualityScoreRecord = z.infer;\n\n/**\n * Query State - current state of the query development\n */\nexport const QueryStateSchema = z.object({\n filesPresent: z.array(z.string()),\n compilationStatus: z.enum(['unknown', 'success', 'failed']),\n testStatus: z.enum(['unknown', 'passing', 'failing', 'no_tests']),\n documentationStatus: z.enum(['unknown', 'present', 'missing', 'incomplete']),\n lastActivity: z.string(), // ISO timestamp\n});\n\nexport type QueryState = z.infer;\n\n/**\n * Query Development Session - main data structure for tracking\n */\nexport const QueryDevelopmentSessionSchema = z.object({\n // Session Metadata\n sessionId: z.string(),\n queryPath: z.string(),\n language: z.string(),\n queryType: z.string().optional(),\n description: z.string().optional(),\n startTime: z.string(), // ISO timestamp\n endTime: z.string().optional(), // ISO timestamp\n status: z.enum(['active', 'completed', 'failed', 'abandoned']),\n\n // MCP Call History\n mcpCalls: z.array(MCPCallRecordSchema),\n\n // Test Execution Records\n testExecutions: z.array(TestExecutionRecordSchema),\n\n // Quality Metrics\n qualityScores: z.array(QualityScoreRecordSchema),\n\n // Development State\n currentState: QueryStateSchema,\n recommendations: z.array(z.string()),\n nextSuggestedTool: z.string().optional(),\n});\n\nexport type QueryDevelopmentSession = z.infer;\n\n/**\n * Session Filter for listing and searching\n */\nexport const SessionFilterSchema = z.object({\n queryPath: z.string().optional(),\n status: z.string().optional(),\n dateRange: z.tuple([z.string(), z.string()]).optional(),\n language: z.string().optional(),\n queryType: z.string().optional(),\n});\n\nexport type SessionFilter = z.infer;\n\n/**\n * Comparison Report for analyzing multiple sessions\n */\nexport const ComparisonReportSchema = z.object({\n sessionIds: z.array(z.string()),\n dimensions: z.array(z.string()),\n timestamp: z.string(),\n results: z.record(z.any()),\n});\n\nexport type ComparisonReport = z.infer;\n\n/**\n * Aggregate Report for batch analysis\n */\nexport const AggregateReportSchema = z.object({\n filters: SessionFilterSchema,\n timestamp: z.string(),\n totalSessions: z.number(),\n successRate: z.number(),\n averageQualityScore: z.number(),\n commonPatterns: z.array(z.string()),\n recommendations: z.array(z.string()),\n});\n\nexport type AggregateReport = z.infer;\n\n/**\n * Export Result for data export operations\n */\nexport const ExportResultSchema = z.object({\n format: z.enum(['json', 'html', 'markdown']),\n filename: z.string(),\n content: z.string(),\n timestamp: z.string(),\n});\n\nexport type ExportResult = z.infer;\n\n/**\n * Functional Test Result for automated testing\n */\nexport const FunctionalTestResultSchema = z.object({\n sessionId: z.string(),\n queryPath: z.string(),\n passed: z.boolean(),\n criteria: z.record(z.any()),\n details: z.record(z.any()),\n timestamp: z.string(),\n});\n\nexport type FunctionalTestResult = z.infer;\n\n/**\n * Test Report for comprehensive test analysis\n */\nexport const TestReportSchema = z.object({\n sessionIds: z.array(z.string()),\n criteria: z.record(z.any()),\n timestamp: z.string(),\n overallPassRate: z.number(),\n results: z.array(FunctionalTestResultSchema),\n summary: z.record(z.any()),\n});\n\nexport type TestReport = z.infer;\n\n/**\n * Monitoring Configuration\n */\nexport const MonitoringConfigSchema = z.object({\n storageLocation: z.string().default('.ql-mcp-tracking/'),\n autoTrackSessions: z.boolean().default(true),\n retentionDays: z.number().default(90),\n includeCallParameters: z.boolean().default(true),\n includeCallResults: z.boolean().default(true),\n maxActiveSessionsPerQuery: z.number().default(3),\n scoringFrequency: z.enum(['per_call', 'periodic', 'manual']).default('per_call'),\n archiveCompletedSessions: z.boolean().default(true),\n enableRecommendations: z.boolean().default(true),\n enableMonitoringTools: z.boolean().default(false), // Opt-in: session_* tools disabled by default for end-users\n});\n\nexport type MonitoringConfig = z.infer;"], + "mappings": "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", + "names": ["type", "resolve", "setTimeout", "resolve", "setTimeout", "clearTimeout", "join", "resolve", "spawn", "delimiter", "EventEmitter", "clearTimeout", "setTimeout", "resolve", "spawn", "delimiter", "EventEmitter", "clearTimeout", "setTimeout", "resolve", "mkdirSync", "join", "type", "packageRootDir", "resolve", "existsSync", "delimiter", "dirname", "isAbsolute", "binary", "getServerManager", "resolve", "pathToFileURL", "z", "readFileSync", "dirname", "isAbsolute", "mkdirSync", "mkdirSync", "existsSync", "join", "resolve", "timestamp", "writeFileSync", "existsSync", "mkdirSync", "basename", "dirname", "isAbsolute", "join", "resolve", "logger", "executeCodeQLCommand", "basename", "mkdirSync", "dirname", "z", "z", "z", "z", "z", "z", "z", "z", "z", "z", "readFile", "z", "exception", "map", "schema", "type", "extend", "str", "string", "z", "z", "z", "z", "z", "existsSync", "readdirSync", "readFileSync", "statSync", "join", "z", "readFileSync", "existsSync", "readdirSync", "join", "statSync", "z", "existsSync", "readdirSync", "readFileSync", "statSync", "join", "z", "existsSync", "readdirSync", "join", "statSync", "timestamp", "readFileSync", "z", "existsSync", "readdirSync", "readFileSync", "statSync", "join", "z", "existsSync", "readdirSync", "join", "statSync", "timestamp", "readFileSync", "z", "z", "z", "z", "z", "existsSync", "mkdirSync", "writeFileSync", "basename", "dirname", "join", "z", "readFileSync", "basename", "z", "existsSync", "dirname", "mkdirSync", "join", "writeFileSync", "z", "writeFileSync", "readFileSync", "existsSync", "join", "dirname", "basename", "mkdirSync", "parseEvaluatorLog", "formatAsJson", "formatAsMermaid", "z", "z", "z", "z", "z", "z", "join", "resolve", "resolve", "join", "z", "z", "resolve", "z", "z", "z", "z", "z", "z", "z", "z", "z", "z", "z", "z", "z", "z", "z", "z", "z", "z", "z", "z", "fs", "path", "getLanguageExtension", "z", "readFileSync", "join", "dirname", "fileURLToPath", "__filename", "__dirname", "z", "join", "pathToFileURL", "isAbsolute", "resolve", "pathToFileURL", "getUserWorkspaceDir", "pathToFileURL", "join", "z", "readFile", "isAbsolute", "resolve", "pathToFileURL", "isAbsolute", "resolve", "pathToFileURL", "readFile", "z", "z", "readFileSync", "existsSync", "join", "join", "existsSync", "readFileSync", "z", "basename", "readFileSync", "join", "dirname", "fileURLToPath", "__filename", "__dirname", "z", "basename", "z", "randomUUID", "readFileSync", "writeFileSync", "path", "path", "readFileSync", "str", "writeFileSync", "parse", "mkdirSync", "writeFileSync", "join", "randomUUID", "z", "join", "mkdirSync", "writeFileSync", "randomUUID", "z", "timestamp", "randomUUID", "resolve", "pathToFileURL"] } diff --git a/server/src/lib/cli-tool-registry.ts b/server/src/lib/cli-tool-registry.ts index 162ab863..01570089 100644 --- a/server/src/lib/cli-tool-registry.ts +++ b/server/src/lib/cli-tool-registry.ts @@ -349,32 +349,36 @@ export function registerCLITool(server: McpServer, definition: CLIToolDefinition break; } - // Set up logging directory for query/test runs + // Set up logging directory for query/test/analyze runs let queryLogDir: string | undefined; - if (name === 'codeql_query_run' || name === 'codeql_test_run') { + if (name === 'codeql_query_run' || name === 'codeql_test_run' || name === 'codeql_database_analyze') { queryLogDir = getOrCreateLogDirectory(customLogDir as string | undefined); logger.info(`Using log directory for ${name}: ${queryLogDir}`); - + // Create timestamp file to track when query/test run started const timestampPath = join(queryLogDir, 'timestamp'); writeFileSync(timestampPath, Date.now().toString(), 'utf8'); - + // Set the --logdir option for CodeQL CLI options.logdir = queryLogDir; - + // Set verbosity to progress+ to generate detailed query.log/test.log if (!options.verbosity) { options.verbosity = 'progress+'; } - - // For query run, also handle the deprecated evaluator-log parameter and default output + + // Set evaluator-log if not explicitly provided + if (!options['evaluator-log']) { + options['evaluator-log'] = join(queryLogDir, 'evaluator-log.jsonl'); + } + + // Enable --tuple-counting by default for evaluator logging + if (options['tuple-counting'] === undefined) { + options['tuple-counting'] = true; + } + + // For query run, also handle default output if (name === 'codeql_query_run') { - // If evaluator-log was explicitly provided (deprecated), use it - // Otherwise, set it to the log directory - if (!options['evaluator-log']) { - options['evaluator-log'] = join(queryLogDir, 'evaluator-log.jsonl'); - } - // If output was not explicitly provided, set it to the log directory if (!options.output) { options.output = join(queryLogDir, 'results.bqrs'); @@ -403,7 +407,7 @@ export function registerCLITool(server: McpServer, definition: CLIToolDefinition const defaultExamplesPath = resolve(packageRootDir, 'ql', 'javascript', 'examples'); const additionalPacksPath = process.env.CODEQL_ADDITIONAL_PACKS || (existsSync(defaultExamplesPath) ? defaultExamplesPath : undefined); - if (additionalPacksPath && (name === 'codeql_test_run' || name === 'codeql_query_run' || name === 'codeql_query_compile')) { + if (additionalPacksPath && (name === 'codeql_test_run' || name === 'codeql_query_run' || name === 'codeql_query_compile' || name === 'codeql_database_analyze')) { options['additional-packs'] = additionalPacksPath; } @@ -424,7 +428,7 @@ export function registerCLITool(server: McpServer, definition: CLIToolDefinition // Generate SARIF interpretation if results.bqrs exists const bqrsPath = options.output as string; const sarifPath = join(queryLogDir, 'results.sarif'); - + if (existsSync(bqrsPath)) { try { const sarifResult = await executeCodeQLCommand( @@ -432,7 +436,7 @@ export function registerCLITool(server: McpServer, definition: CLIToolDefinition { format: 'sarif-latest', output: sarifPath }, [bqrsPath] ); - + if (sarifResult.success) { logger.info(`Generated SARIF interpretation at ${sarifPath}`); } @@ -440,11 +444,33 @@ export function registerCLITool(server: McpServer, definition: CLIToolDefinition logger.warn(`Failed to generate SARIF interpretation: ${error}`); } } - + // Process evaluation results result = await processQueryRunResults(result, params, logger); } + // Post-execution: generate evaluator log summary for query run / database analyze + if ((name === 'codeql_query_run' || name === 'codeql_database_analyze') && result.success && queryLogDir) { + const evalLogPath = options['evaluator-log'] as string | undefined; + if (evalLogPath && existsSync(evalLogPath)) { + try { + const summaryPath = evalLogPath.replace(/\.jsonl$/, '.summary.jsonl'); + // codeql generate log-summary takes positional args: [] + const summaryResult = await executeCodeQLCommand( + 'generate log-summary', + { format: 'predicates' }, + [evalLogPath, summaryPath] + ); + + if (summaryResult.success) { + logger.info(`Generated evaluator log summary at ${summaryPath}`); + } + } catch (error) { + logger.warn(`Failed to generate evaluator log summary: ${error}`); + } + } + } + // Process the result const processedResult = resultProcessor(result, params); diff --git a/server/src/lib/discovery-config.ts b/server/src/lib/discovery-config.ts index 1bd200a6..3ddbed50 100644 --- a/server/src/lib/discovery-config.ts +++ b/server/src/lib/discovery-config.ts @@ -1,8 +1,10 @@ /** - * Discovery configuration for locating CodeQL databases and query run results. + * Discovery configuration for locating CodeQL databases, query run results, + * and MRVA (Multi-Repository Variant Analysis) run results. * * Reads colon-separated directory lists from environment variables: * - `CODEQL_DATABASES_BASE_DIRS` — directories to search for CodeQL databases + * - `CODEQL_MRVA_RUN_RESULTS_DIRS` — directories containing MRVA run result subdirectories * - `CODEQL_QUERY_RUN_RESULTS_DIRS` — directories containing per-run query result subdirectories * * The VS Code extension sets these automatically from vscode-codeql storage paths. @@ -34,6 +36,20 @@ export function getDatabaseBaseDirs(): string[] { return parsePathList(process.env.CODEQL_DATABASES_BASE_DIRS); } +/** + * Get the list of directories containing MRVA run result subdirectories. + * + * Each directory is expected to contain numeric subdirectories (run IDs), + * each holding `timestamp`, `repo_states.json`, and per-repository + * subdirectories with `repo_task.json`, `results/results.sarif`, and + * `results/results.bqrs`. + * + * Set via `CODEQL_MRVA_RUN_RESULTS_DIRS` (colon-separated). + */ +export function getMrvaRunResultsDirs(): string[] { + return parsePathList(process.env.CODEQL_MRVA_RUN_RESULTS_DIRS); +} + /** * Get the list of directories containing per-run query result subdirectories. * diff --git a/server/src/lib/evaluator-log-parser.ts b/server/src/lib/evaluator-log-parser.ts new file mode 100644 index 00000000..3c4be45e --- /dev/null +++ b/server/src/lib/evaluator-log-parser.ts @@ -0,0 +1,440 @@ +/** + * Reusable parser for CodeQL evaluator log files. + * + * Supports two formats: + * - **Raw** (`evaluator-log.jsonl`): Pretty-printed JSON objects with a `type` + * field (`LOG_HEADER`, `QUERY_STARTED`, `PREDICATE_STARTED`, etc.) + * - **Summary** (`evaluator-log.summary.jsonl`): Pretty-printed JSON objects + * without a `type` field; identified by `summaryLogVersion` or + * `evaluationStrategy`. + * + * Both formats use pretty-printed JSON separated by `}\n{` boundaries. + */ + +import { readFileSync } from 'fs'; +import { logger } from '../utils/logger'; + +// --------------------------------------------------------------------------- +// Public interfaces +// --------------------------------------------------------------------------- + +/** Performance profile for a single evaluated predicate. */ +export interface PredicateProfile { + predicateName: string; + position?: string; + durationMs: number; + resultSize?: number; + pipelineCount?: number; + evaluationStrategy?: string; + dependencies: string[]; +} + +/** Performance profile for a single query within a log. */ +export interface QueryProfile { + queryName: string; + totalDurationMs: number; + predicateCount: number; + predicates: PredicateProfile[]; + cacheHits: number; +} + +/** Top-level result returned by all parse functions. */ +export interface ProfileData { + codeqlVersion?: string; + logFormat: 'raw' | 'summary'; + queries: QueryProfile[]; + totalEvents: number; +} + +// --------------------------------------------------------------------------- +// Format detection +// --------------------------------------------------------------------------- + +/** + * Auto-detect whether the first parsed JSON object comes from a raw + * evaluator log or a summary log. + * + * Raw events always contain a `type` string field. + * Summary events never have `type`; the header carries `summaryLogVersion`. + */ +export function detectLogFormat(firstEvent: Record): 'raw' | 'summary' { + if (typeof firstEvent.type === 'string') { + return 'raw'; + } + return 'summary'; +} + +// --------------------------------------------------------------------------- +// Helpers +// --------------------------------------------------------------------------- + +/** + * Split a pretty-printed multi-JSON file into individual JSON strings. + * + * The log file contains multiple JSON objects that are pretty-printed, + * separated by the pattern `}\n\n{` (closing brace, blank line, opening + * brace). We split on `\n}\n` boundaries and reconstruct valid objects. + */ +function splitJsonObjects(content: string): string[] { + // Trim leading/trailing whitespace + const trimmed = content.trim(); + if (trimmed.length === 0) { + return []; + } + + // Split on closing-brace + newline(s) + opening-brace boundaries. + // We use a regex that matches `}\n` followed by optional blank lines + // then `{` – capturing the boundary so we can reconstruct. + const parts = trimmed.split(/\n\}\s*\n\s*\{/); + + if (parts.length === 1) { + // Single object or single-line – return as-is + return [trimmed]; + } + + // Reconstruct: first part needs closing `}`, middle parts need both, + // last part needs opening `{`. + return parts.map((part, idx) => { + if (idx === 0) { + return part + '\n}'; + } + if (idx === parts.length - 1) { + return '{\n' + part; + } + return '{\n' + part + '\n}'; + }); +} + +/** + * Parse all JSON objects from an evaluator log file. + */ +function parseJsonObjects(logPath: string): Record[] { + const content = readFileSync(logPath, 'utf-8'); + const objectStrings = splitJsonObjects(content); + + const results: Record[] = []; + for (const objStr of objectStrings) { + try { + results.push(JSON.parse(objStr) as Record); + } catch { + logger.warn( + `Failed to parse evaluator log object: ${objStr.substring(0, 120)}...` + ); + } + } + return results; +} + +// --------------------------------------------------------------------------- +// Raw evaluator log parsing +// --------------------------------------------------------------------------- + +/** + * Parse a raw `evaluator-log.jsonl` file into {@link ProfileData}. + * + * Tracks `QUERY_STARTED`/`QUERY_COMPLETED` pairs, computes predicate + * durations from `PREDICATE_STARTED`/`PREDICATE_COMPLETED` nanoTime + * differences, and groups predicates by `queryCausingWork`. + */ +export function parseRawEvaluatorLog(logPath: string): ProfileData { + const events = parseJsonObjects(logPath); + + let codeqlVersion: string | undefined; + + // Maps: eventId → event data for lookups + const queryStartEvents = new Map< + number, + { queryName: string; nanoTime: number } + >(); + const predicateStartEvents = new Map< + number, + { + predicateName: string; + position?: string; + predicateType?: string; + dependencies: string[]; + queryCausingWork?: number; + nanoTime: number; + pipelineCount: number; + } + >(); + + // Completed predicate profiles grouped by query eventId + const queryPredicates = new Map(); + // Query end nanoTimes keyed by query start eventId + const queryEndNanoTimes = new Map(); + // Track cache lookups per query + const queryCacheHits = new Map(); + // Fallback query eventId for predicates without queryCausingWork + let firstQueryEventId: number | undefined; + + for (const event of events) { + const eventType = event.type as string | undefined; + + switch (eventType) { + case 'LOG_HEADER': { + codeqlVersion = event.codeqlVersion as string | undefined; + break; + } + + case 'QUERY_STARTED': { + const eid = event.eventId as number; + const qName = (event.queryName as string) || 'unknown'; + queryStartEvents.set(eid, { + queryName: qName, + nanoTime: event.nanoTime as number, + }); + queryPredicates.set(eid, []); + queryCacheHits.set(eid, 0); + if (firstQueryEventId === undefined) { + firstQueryEventId = eid; + } + break; + } + + case 'QUERY_COMPLETED': { + const startEid = event.startEvent as number; + queryEndNanoTimes.set(startEid, event.nanoTime as number); + break; + } + + case 'PREDICATE_STARTED': { + const eid = event.eventId as number; + const deps = event.dependencies as Record | undefined; + predicateStartEvents.set(eid, { + predicateName: (event.predicateName as string) || 'unknown', + position: event.position as string | undefined, + predicateType: event.predicateType as string | undefined, + dependencies: deps ? Object.keys(deps) : [], + queryCausingWork: event.queryCausingWork as number | undefined, + nanoTime: event.nanoTime as number, + pipelineCount: 0, + }); + break; + } + + case 'PIPELINE_COMPLETED': { + // Count pipelines for the parent predicate + const pipelineStartEid = event.startEvent as number; + // Find the pipeline_started event to get predicateStartEvent + const pipelineStartEvt = events.find( + (e) => + (e.type as string) === 'PIPELINE_STARTED' && + (e.eventId as number) === pipelineStartEid + ); + if (pipelineStartEvt) { + const predEid = pipelineStartEvt.predicateStartEvent as number; + const predStart = predicateStartEvents.get(predEid); + if (predStart) { + predStart.pipelineCount += 1; + } + } + break; + } + + case 'PREDICATE_COMPLETED': { + const startEid = event.startEvent as number; + const predStart = predicateStartEvents.get(startEid); + if (predStart) { + const durationNs = + (event.nanoTime as number) - predStart.nanoTime; + const durationMs = durationNs / 1_000_000; + + const profile: PredicateProfile = { + predicateName: predStart.predicateName, + position: predStart.position, + durationMs, + resultSize: event.resultSize as number | undefined, + pipelineCount: + predStart.pipelineCount > 0 + ? predStart.pipelineCount + : undefined, + evaluationStrategy: predStart.predicateType, + dependencies: predStart.dependencies, + }; + + const qEid = + predStart.queryCausingWork ?? firstQueryEventId; + if (qEid !== undefined) { + let arr = queryPredicates.get(qEid); + if (!arr) { + arr = []; + queryPredicates.set(qEid, arr); + } + arr.push(profile); + } + } + break; + } + + case 'CACHE_LOOKUP': { + // Attribute to the most recent query + const qEid = + (event.queryCausingWork as number | undefined) ?? + firstQueryEventId; + if (qEid !== undefined) { + queryCacheHits.set(qEid, (queryCacheHits.get(qEid) ?? 0) + 1); + } + break; + } + } + } + + // Build QueryProfile entries + const queries: QueryProfile[] = []; + for (const [qEid, startInfo] of queryStartEvents) { + const predicates = queryPredicates.get(qEid) ?? []; + const endNano = queryEndNanoTimes.get(qEid); + const totalDurationMs = + endNano !== undefined + ? (endNano - startInfo.nanoTime) / 1_000_000 + : predicates.reduce((sum, p) => sum + p.durationMs, 0); + + queries.push({ + queryName: startInfo.queryName, + totalDurationMs, + predicateCount: predicates.length, + predicates, + cacheHits: queryCacheHits.get(qEid) ?? 0, + }); + } + + return { + codeqlVersion, + logFormat: 'raw', + queries, + totalEvents: events.length, + }; +} + +// --------------------------------------------------------------------------- +// Summary log parsing +// --------------------------------------------------------------------------- + +/** + * Parse an `evaluator-log.summary.jsonl` file into {@link ProfileData}. + * + * Summary events carry `millis` directly (already in ms). Predicates are + * grouped by `queryCausingWork` which is a **string** (query name) in the + * summary format. + */ +export function parseSummaryLog(logPath: string): ProfileData { + const events = parseJsonObjects(logPath); + + let codeqlVersion: string | undefined; + + // queryCausingWork (string) → collected predicates + const queryPredicatesMap = new Map(); + // Track total millis per query + const queryTotalMs = new Map(); + // Track cache hits per query + const queryCacheHits = new Map(); + + for (const event of events) { + // Header detection + if (event.summaryLogVersion !== undefined) { + codeqlVersion = event.codeqlVersion as string | undefined; + continue; + } + + const strategy = event.evaluationStrategy as string | undefined; + + // Skip sentinel-empty entries (no useful timing data) + if (strategy === 'SENTINEL_EMPTY') { + continue; + } + + // Skip events without millis (non-predicate summaries) + if (event.millis === undefined) { + continue; + } + + const predicateName = + (event.predicateName as string) || 'unknown'; + const millis = event.millis as number; + const queryName = + (event.queryCausingWork as string) || 'unknown'; + + const deps = event.dependencies as Record | undefined; + const pipelineRuns = event.pipelineRuns as number | undefined; + + const profile: PredicateProfile = { + predicateName, + position: event.position as string | undefined, + durationMs: millis, + resultSize: event.resultSize as number | undefined, + pipelineCount: pipelineRuns, + evaluationStrategy: strategy, + dependencies: deps ? Object.keys(deps) : [], + }; + + // Check if this is a cached entry + if (event.isCached === true || strategy === 'CACHEHIT') { + queryCacheHits.set( + queryName, + (queryCacheHits.get(queryName) ?? 0) + 1 + ); + } + + let arr = queryPredicatesMap.get(queryName); + if (!arr) { + arr = []; + queryPredicatesMap.set(queryName, arr); + } + arr.push(profile); + + queryTotalMs.set( + queryName, + (queryTotalMs.get(queryName) ?? 0) + millis + ); + } + + // Build QueryProfile entries + const queries: QueryProfile[] = []; + for (const [queryName, predicates] of queryPredicatesMap) { + queries.push({ + queryName, + totalDurationMs: queryTotalMs.get(queryName) ?? 0, + predicateCount: predicates.length, + predicates, + cacheHits: queryCacheHits.get(queryName) ?? 0, + }); + } + + return { + codeqlVersion, + logFormat: 'summary', + queries, + totalEvents: events.length, + }; +} + +// --------------------------------------------------------------------------- +// Auto-detect entry point +// --------------------------------------------------------------------------- + +/** + * Auto-detect the log format and parse accordingly. + * + * @param logPath - Absolute path to `evaluator-log.jsonl` or + * `evaluator-log.summary.jsonl`. + * @returns Parsed profile data. + */ +export function parseEvaluatorLog(logPath: string): ProfileData { + const events = parseJsonObjects(logPath); + + if (events.length === 0) { + return { + logFormat: 'raw', + queries: [], + totalEvents: 0, + }; + } + + const format = detectLogFormat(events[0]); + + if (format === 'raw') { + return parseRawEvaluatorLog(logPath); + } + return parseSummaryLog(logPath); +} diff --git a/server/src/tools/codeql-tools.ts b/server/src/tools/codeql-tools.ts index f2ca05db..8c05f769 100644 --- a/server/src/tools/codeql-tools.ts +++ b/server/src/tools/codeql-tools.ts @@ -35,7 +35,9 @@ import { registerFindCodeQLQueryFilesTool, registerFindPredicatePositionTool, registerListDatabasesTool, + registerListMrvaRunResultsTool, registerListQueryRunResultsTool, + registerProfileCodeQLQueryFromLogsTool, registerProfileCodeQLQueryTool, registerQuickEvaluateTool, registerRegisterDatabaseTool @@ -161,7 +163,9 @@ export function registerCodeQLTools(server: McpServer): void { registerFindCodeQLQueryFilesTool(server); registerFindPredicatePositionTool(server); registerListDatabasesTool(server); + registerListMrvaRunResultsTool(server); registerListQueryRunResultsTool(server); + registerProfileCodeQLQueryFromLogsTool(server); registerProfileCodeQLQueryTool(server); registerQuickEvaluateTool(server); registerRegisterDatabaseTool(server); diff --git a/server/src/tools/codeql/database-analyze.ts b/server/src/tools/codeql/database-analyze.ts index cfd8706b..4c2d5fa7 100644 --- a/server/src/tools/codeql/database-analyze.ts +++ b/server/src/tools/codeql/database-analyze.ts @@ -21,11 +21,20 @@ export const codeqlDatabaseAnalyzeTool: CLIToolDefinition = { threads: z.number().optional().describe('Number of threads to use'), ram: z.number().optional().describe('Amount of RAM to use (MB)'), timeout: z.number().optional().describe('Timeout in seconds'), + logDir: z.string().optional() + .describe('Custom directory for analysis execution logs (overrides CODEQL_QUERY_LOG_DIR environment variable). If not provided, uses CODEQL_QUERY_LOG_DIR or defaults to .tmp/query-logs/'), + 'evaluator-log': z.string().optional() + .describe('Path to save evaluator log. If not provided and logDir is set, defaults to /evaluator-log.jsonl'), + 'tuple-counting': z.boolean().optional() + .describe('Display tuple counts for each evaluation step in evaluator logs'), + 'evaluator-log-level': z.number().min(1).max(5).optional() + .describe('Evaluator log verbosity level (1-5, default 5)'), verbose: z.boolean().optional().describe('Enable verbose output'), additionalArgs: z.array(z.string()).optional().describe('Additional command-line arguments') }, examples: [ 'codeql database analyze mydb queries.qls --format=sarif-latest --output=results.sarif', - 'codeql database analyze mydb codeql/java-queries --format=csv' + 'codeql database analyze mydb codeql/java-queries --format=csv', + 'codeql database analyze mydb queries.qls --format=sarif-latest --output=results.sarif --log-dir=/path/to/logs --tuple-counting' ] }; \ No newline at end of file diff --git a/server/src/tools/codeql/index.ts b/server/src/tools/codeql/index.ts index c550f248..68ed3b14 100644 --- a/server/src/tools/codeql/index.ts +++ b/server/src/tools/codeql/index.ts @@ -14,9 +14,11 @@ export { codeqlGenerateLogSummaryTool } from './generate-log-summary'; export { codeqlGenerateQueryHelpTool } from './generate-query-help'; // codeql_lsp_diagnostics has moved to server/src/tools/lsp/lsp-diagnostics.ts export { registerListDatabasesTool } from './list-databases'; +export { registerListMrvaRunResultsTool } from './list-mrva-run-results'; export { registerListQueryRunResultsTool } from './list-query-run-results'; export { codeqlPackInstallTool } from './pack-install'; export { codeqlPackLsTool } from './pack-ls'; +export { registerProfileCodeQLQueryFromLogsTool } from './profile-codeql-query-from-logs'; export { registerProfileCodeQLQueryTool } from './profile-codeql-query'; export { codeqlQueryCompileTool } from './query-compile'; export { codeqlQueryFormatTool } from './query-format'; diff --git a/server/src/tools/codeql/list-mrva-run-results.ts b/server/src/tools/codeql/list-mrva-run-results.ts new file mode 100644 index 00000000..45fa8642 --- /dev/null +++ b/server/src/tools/codeql/list-mrva-run-results.ts @@ -0,0 +1,282 @@ +/** + * list_mrva_run_results tool + * + * Discovers MRVA (Multi-Repository Variant Analysis) run result directories + * in configured search paths. + * Scans each directory in `CODEQL_MRVA_RUN_RESULTS_DIRS` for numeric + * subdirectories representing variant analysis runs created by vscode-codeql. + * Reports run ID, timestamp, repositories scanned, analysis status, and + * available artifacts for each run. + */ + +import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js'; +import { existsSync, readdirSync, readFileSync, statSync } from 'fs'; +import { join } from 'path'; +import { z } from 'zod'; +import { getMrvaRunResultsDirs } from '../../lib/discovery-config'; +import { logger } from '../../utils/logger'; + +export interface MrvaRepoResult { + analysisStatus?: string; + fullName: string; + hasBqrs: boolean; + hasSarif: boolean; + resultCount?: number; +} + +export interface MrvaRunResult { + path: string; + repositories: MrvaRepoResult[]; + runId: string; + timestamp?: string; +} + +/** + * Pattern matching numeric MRVA run directory names. + */ +const NUMERIC_DIR_PATTERN = /^\d+$/; + +/** + * Directory names to skip when walking repository subdirectories. + */ +const SKIP_DIRS = new Set(['.DS_Store', 'exported-results']); + +/** + * Discover MRVA run result directories in the given search paths. + * + * @param resultsDirs - Directories to scan for MRVA run subdirectories + * @param runId - Optional run ID filter (e.g., "20442") + * @returns List of discovered MRVA run results with repository inventory + */ +export async function discoverMrvaRunResults( + resultsDirs: string[], + runId?: string, +): Promise { + const results: MrvaRunResult[] = []; + + for (const dir of resultsDirs) { + if (!existsSync(dir)) { + continue; + } + + let entries: string[]; + try { + entries = readdirSync(dir); + } catch { + continue; + } + + for (const entry of entries) { + const entryPath = join(dir, entry); + + // Skip non-directories + try { + if (!statSync(entryPath).isDirectory()) { + continue; + } + } catch { + continue; + } + + // Match numeric directory names + if (!NUMERIC_DIR_PATTERN.test(entry)) { + continue; + } + + // Apply run ID filter + if (runId && entry !== runId) { + continue; + } + + // Read timestamp if available + let timestamp: string | undefined; + const timestampPath = join(entryPath, 'timestamp'); + if (existsSync(timestampPath)) { + try { + timestamp = readFileSync(timestampPath, 'utf-8').trim(); + } catch { + // Ignore read errors + } + } + + // Discover repository subdirectories + const repositories = discoverRepoResults(entryPath); + + results.push({ + path: entryPath, + repositories, + runId: entry, + timestamp, + }); + } + } + + return results; +} + +/** + * Walk a single MRVA run directory to discover per-repository results. + * + * The directory structure is `//` containing `repo_task.json` + * and optionally `results/results.sarif` and `results/results.bqrs`. + */ +function discoverRepoResults(runPath: string): MrvaRepoResult[] { + const repos: MrvaRepoResult[] = []; + + let ownerEntries: string[]; + try { + ownerEntries = readdirSync(runPath); + } catch { + return repos; + } + + for (const ownerEntry of ownerEntries) { + if (SKIP_DIRS.has(ownerEntry)) { + continue; + } + + // Skip non-directory entries (timestamp, repo_states.json, etc.) + const ownerPath = join(runPath, ownerEntry); + try { + if (!statSync(ownerPath).isDirectory()) { + continue; + } + } catch { + continue; + } + + let repoEntries: string[]; + try { + repoEntries = readdirSync(ownerPath); + } catch { + continue; + } + + for (const repoEntry of repoEntries) { + const repoPath = join(ownerPath, repoEntry); + try { + if (!statSync(repoPath).isDirectory()) { + continue; + } + } catch { + continue; + } + + const fullName = `${ownerEntry}/${repoEntry}`; + + // Parse repo_task.json if present + let analysisStatus: string | undefined; + let resultCount: number | undefined; + const repoTaskPath = join(repoPath, 'repo_task.json'); + if (existsSync(repoTaskPath)) { + try { + const raw = readFileSync(repoTaskPath, 'utf-8'); + const task = JSON.parse(raw); + if (typeof task.analysisStatus === 'string') { + analysisStatus = task.analysisStatus; + } + if (typeof task.resultCount === 'number') { + resultCount = task.resultCount; + } + } catch { + // Ignore parse errors + } + } + + // Check for SARIF and BQRS artifacts + const hasSarif = existsSync(join(repoPath, 'results', 'results.sarif')); + const hasBqrs = existsSync(join(repoPath, 'results', 'results.bqrs')); + + repos.push({ + analysisStatus, + fullName, + hasBqrs, + hasSarif, + resultCount, + }); + } + } + + return repos; +} + +/** + * Register the list_mrva_run_results tool with the MCP server. + */ +export function registerListMrvaRunResultsTool(server: McpServer): void { + server.tool( + 'list_mrva_run_results', + 'List discovered MRVA (Multi-Repository Variant Analysis) run results (set via CODEQL_MRVA_RUN_RESULTS_DIRS env var). Returns run ID, timestamp, repositories scanned, analysis status, and available artifacts for each run.', + { + runId: z + .string() + .optional() + .describe('Filter results by run ID (e.g., "20442")'), + }, + async ({ runId }) => { + try { + const resultsDirs = getMrvaRunResultsDirs(); + + if (resultsDirs.length === 0) { + return { + content: [ + { + type: 'text' as const, + text: 'No MRVA run results directories configured. Set the CODEQL_MRVA_RUN_RESULTS_DIRS environment variable to a colon-separated list of directories to search.', + }, + ], + }; + } + + const runs = await discoverMrvaRunResults(resultsDirs, runId); + + if (runs.length === 0) { + const filterMsg = runId ? ` for run ID "${runId}"` : ''; + return { + content: [ + { + type: 'text' as const, + text: `No MRVA run results found${filterMsg} in: ${resultsDirs.join(', ')}`, + }, + ], + }; + } + + const lines = [ + `Found ${runs.length} MRVA run result(s):`, + '', + ...runs.map((run) => { + const parts = [` Run ${run.runId}`]; + parts.push(` Path: ${run.path}`); + if (run.timestamp) parts.push(` Timestamp: ${run.timestamp}`); + parts.push(` Repositories: ${run.repositories.length}`); + for (const repo of run.repositories) { + const artifacts: string[] = []; + if (repo.hasSarif) artifacts.push('sarif'); + if (repo.hasBqrs) artifacts.push('bqrs'); + const status = repo.analysisStatus ?? 'unknown'; + const count = repo.resultCount !== undefined ? `, ${repo.resultCount} result(s)` : ''; + parts.push(` ${repo.fullName} [${status}${count}] artifacts: ${artifacts.length > 0 ? artifacts.join(', ') : 'none'}`); + } + return parts.join('\n'); + }), + ]; + + return { + content: [{ type: 'text' as const, text: lines.join('\n') }], + }; + } catch (error) { + logger.error('Error listing MRVA run results:', error); + return { + content: [ + { + type: 'text' as const, + text: `Error: ${error instanceof Error ? error.message : 'Unknown error'}`, + }, + ], + isError: true, + }; + } + }, + ); +} diff --git a/server/src/tools/codeql/profile-codeql-query-from-logs.ts b/server/src/tools/codeql/profile-codeql-query-from-logs.ts new file mode 100644 index 00000000..d0895d59 --- /dev/null +++ b/server/src/tools/codeql/profile-codeql-query-from-logs.ts @@ -0,0 +1,296 @@ +/** + * MCP tool: profile_codeql_query_from_logs + * + * Parses CodeQL query evaluation logs into a performance profile WITHOUT + * running the query. Works with logs from `codeql query run`, + * `codeql database analyze`, or vscode-codeql query history. + */ + +import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js'; +import { existsSync, mkdirSync, writeFileSync } from 'fs'; +import { basename, dirname, join } from 'path'; +import { z } from 'zod'; +import { + parseEvaluatorLog, + type PredicateProfile, + type ProfileData, +} from '../../lib/evaluator-log-parser'; +import { logger } from '../../utils/logger'; + +// --------------------------------------------------------------------------- +// Formatting helpers +// --------------------------------------------------------------------------- + +/** + * Format the full profile data as pretty-printed JSON. + */ +function formatAsJson(profile: ProfileData): string { + return JSON.stringify(profile, null, 2); +} + +/** + * Format profile data as a Mermaid diagram. + * + * For single-query logs the diagram has one query root node with sub-nodes + * for the top-N most expensive predicates. For multi-query logs each query + * gets its own sub-graph. + */ +function formatAsMermaid(profile: ProfileData, topN: number): string { + const lines: string[] = []; + + lines.push('```mermaid'); + lines.push('graph TD'); + lines.push(''); + + if (profile.queries.length <= 1) { + // Single query layout + const query = profile.queries[0] ?? { + queryName: 'unknown', + totalDurationMs: 0, + predicates: [], + predicateCount: 0, + cacheHits: 0, + }; + const qLabel = sanitizeMermaid(basename(query.queryName)); + lines.push( + ` QUERY["${qLabel}
Total: ${query.totalDurationMs.toFixed(2)}ms
Predicates: ${query.predicateCount}"]` + ); + lines.push(''); + + const topPredicates = getTopPredicates(query.predicates, topN); + topPredicates.forEach((pred, idx) => { + const nodeId = `P${idx}`; + const name = sanitizeMermaid(pred.predicateName).substring(0, 50); + const dur = pred.durationMs.toFixed(2); + const size = + pred.resultSize !== undefined ? String(pred.resultSize) : '?'; + lines.push( + ` ${nodeId}["${name}
${dur}ms | ${size} results"]` + ); + }); + + lines.push(''); + + topPredicates.forEach((_pred, idx) => { + lines.push(` QUERY --> P${idx}`); + }); + } else { + // Multi-query layout + lines.push( + ` ROOT["Evaluation Log
${profile.queries.length} queries"]` + ); + lines.push(''); + + profile.queries.forEach((query, qIdx) => { + const qNodeId = `Q${qIdx}`; + const qLabel = sanitizeMermaid(basename(query.queryName)); + lines.push( + ` ${qNodeId}["${qLabel}
${query.totalDurationMs.toFixed(2)}ms
Predicates: ${query.predicateCount}"]` + ); + lines.push(` ROOT --> ${qNodeId}`); + + const topPredicates = getTopPredicates(query.predicates, topN); + topPredicates.forEach((pred, pIdx) => { + const nodeId = `Q${qIdx}P${pIdx}`; + const name = sanitizeMermaid(pred.predicateName).substring(0, 50); + const dur = pred.durationMs.toFixed(2); + const size = + pred.resultSize !== undefined ? String(pred.resultSize) : '?'; + lines.push( + ` ${nodeId}["${name}
${dur}ms | ${size} results"]` + ); + lines.push(` ${qNodeId} --> ${nodeId}`); + }); + lines.push(''); + }); + } + + lines.push(''); + lines.push( + ' classDef default fill:#e1f5ff,stroke:#333,stroke-width:2px' + ); + lines.push( + ' classDef query fill:#ffe1e1,stroke:#333,stroke-width:3px' + ); + lines.push(' class QUERY query'); + lines.push('```'); + + return lines.join('\n'); +} + +/** + * Sanitize a string for safe inclusion in a Mermaid node label. + */ +function sanitizeMermaid(text: string): string { + return text.replace(/[<>"]/g, ''); +} + +/** + * Return the top-N most expensive predicates sorted by descending duration. + */ +function getTopPredicates( + predicates: PredicateProfile[], + topN: number +): PredicateProfile[] { + return [...predicates] + .sort((a, b) => b.durationMs - a.durationMs) + .slice(0, topN); +} + +// --------------------------------------------------------------------------- +// Text summary +// --------------------------------------------------------------------------- + +function buildTextSummary( + profile: ProfileData, + topN: number, + outputFiles: string[] +): string { + const sections: string[] = []; + + sections.push('Query log profiling completed successfully!'); + sections.push(''); + sections.push('Output Files:'); + for (const f of outputFiles) { + sections.push(` - ${f}`); + } + + sections.push(''); + sections.push(`Log Format: ${profile.logFormat}`); + if (profile.codeqlVersion) { + sections.push(`CodeQL Version: ${profile.codeqlVersion}`); + } + sections.push(`Total Events: ${profile.totalEvents}`); + sections.push(`Queries: ${profile.queries.length}`); + + for (const query of profile.queries) { + sections.push(''); + sections.push(`--- ${basename(query.queryName)} ---`); + sections.push(` Total Duration: ${query.totalDurationMs.toFixed(2)} ms`); + sections.push(` Predicates Evaluated: ${query.predicateCount}`); + sections.push(` Cache Hits: ${query.cacheHits}`); + + const top = getTopPredicates(query.predicates, topN); + if (top.length > 0) { + sections.push(` Top ${top.length} Most Expensive Predicates:`); + top.forEach((pred, idx) => { + const sizeStr = + pred.resultSize !== undefined ? `, ${pred.resultSize} results` : ''; + sections.push( + ` ${idx + 1}. ${pred.predicateName} (${pred.durationMs.toFixed(2)} ms${sizeStr})` + ); + }); + } + } + + return sections.join('\n'); +} + +// --------------------------------------------------------------------------- +// Tool registration +// --------------------------------------------------------------------------- + +/** + * Register the `profile_codeql_query_from_logs` tool with the MCP server. + */ +export function registerProfileCodeQLQueryFromLogsTool( + server: McpServer +): void { + server.tool( + 'profile_codeql_query_from_logs', + 'Parse CodeQL query evaluation logs into a performance profile without re-running the query. Works with logs from codeql query run, codeql database analyze, or vscode-codeql query history.', + { + evaluatorLog: z + .string() + .describe( + 'Path to evaluator-log.jsonl or evaluator-log.summary.jsonl' + ), + outputDir: z + .string() + .optional() + .describe( + 'Directory to write profile output files (defaults to same directory as log)' + ), + topN: z + .number() + .optional() + .describe( + 'Number of most expensive predicates to highlight (default: 20)' + ), + }, + async (params) => { + try { + const { evaluatorLog, outputDir, topN } = params; + const effectiveTopN = topN ?? 20; + + // Validate input path + if (!existsSync(evaluatorLog)) { + return { + content: [ + { + type: 'text' as const, + text: `Evaluator log not found at: ${evaluatorLog}`, + }, + ], + isError: true, + }; + } + + // Parse log + logger.info(`Parsing evaluator log from: ${evaluatorLog}`); + const profile = parseEvaluatorLog(evaluatorLog); + + // Determine output directory + const profileOutputDir = outputDir ?? dirname(evaluatorLog); + mkdirSync(profileOutputDir, { recursive: true }); + + // Write profile JSON + const jsonPath = join( + profileOutputDir, + 'query-evaluation-profile.json' + ); + writeFileSync(jsonPath, formatAsJson(profile)); + logger.info(`Profile JSON written to: ${jsonPath}`); + + // Write Mermaid diagram + const mdPath = join( + profileOutputDir, + 'query-evaluation-profile.md' + ); + writeFileSync(mdPath, formatAsMermaid(profile, effectiveTopN)); + logger.info(`Profile Mermaid diagram written to: ${mdPath}`); + + // Build response + const outputFilesList = [ + `Profile JSON: ${jsonPath}`, + `Profile Mermaid: ${mdPath}`, + `Evaluator Log: ${evaluatorLog}`, + ]; + + const responseText = buildTextSummary( + profile, + effectiveTopN, + outputFilesList + ); + + return { + content: [{ type: 'text' as const, text: responseText }], + }; + } catch (error) { + logger.error( + 'Error profiling CodeQL query from logs:', + error + ); + return { + content: [ + { + type: 'text' as const, + text: `Failed to profile query from logs: ${error instanceof Error ? error.message : String(error)}`, + }, + ], + isError: true, + }; + } + } + ); +} diff --git a/server/test/src/lib/discovery-config.test.ts b/server/test/src/lib/discovery-config.test.ts index 2ae087bc..4b4b9e13 100644 --- a/server/test/src/lib/discovery-config.test.ts +++ b/server/test/src/lib/discovery-config.test.ts @@ -6,6 +6,7 @@ import { afterEach, beforeEach, describe, expect, it } from 'vitest'; import { getDatabaseBaseDirs, + getMrvaRunResultsDirs, getQueryRunResultsDirs, } from '../../../src/lib/discovery-config'; @@ -52,6 +53,38 @@ describe('Discovery Configuration', () => { }); }); + describe('getMrvaRunResultsDirs', () => { + it('should return empty array when env var is not set', () => { + delete process.env.CODEQL_MRVA_RUN_RESULTS_DIRS; + expect(getMrvaRunResultsDirs()).toEqual([]); + }); + + it('should return empty array when env var is empty string', () => { + process.env.CODEQL_MRVA_RUN_RESULTS_DIRS = ''; + expect(getMrvaRunResultsDirs()).toEqual([]); + }); + + it('should parse single directory', () => { + process.env.CODEQL_MRVA_RUN_RESULTS_DIRS = '/path/to/variant-analyses'; + expect(getMrvaRunResultsDirs()).toEqual(['/path/to/variant-analyses']); + }); + + it('should parse colon-separated directories', () => { + process.env.CODEQL_MRVA_RUN_RESULTS_DIRS = '/global/mrva:/workspace/mrva'; + expect(getMrvaRunResultsDirs()).toEqual(['/global/mrva', '/workspace/mrva']); + }); + + it('should trim whitespace from paths', () => { + process.env.CODEQL_MRVA_RUN_RESULTS_DIRS = ' /path/one : /path/two '; + expect(getMrvaRunResultsDirs()).toEqual(['/path/one', '/path/two']); + }); + + it('should filter out empty segments from consecutive colons', () => { + process.env.CODEQL_MRVA_RUN_RESULTS_DIRS = '/path/one::/path/two'; + expect(getMrvaRunResultsDirs()).toEqual(['/path/one', '/path/two']); + }); + }); + describe('getQueryRunResultsDirs', () => { it('should return empty array when env var is not set', () => { delete process.env.CODEQL_QUERY_RUN_RESULTS_DIRS; diff --git a/server/test/src/lib/evaluator-log-parser.test.ts b/server/test/src/lib/evaluator-log-parser.test.ts new file mode 100644 index 00000000..8c03bbad --- /dev/null +++ b/server/test/src/lib/evaluator-log-parser.test.ts @@ -0,0 +1,660 @@ +/** + * Tests for the evaluator log parser library. + */ + +import { afterEach, describe, expect, it } from 'vitest'; +import { join } from 'path'; +import { mkdirSync, writeFileSync } from 'fs'; +import { + createTestTempDir, + cleanupTestTempDir, +} from '../../utils/temp-dir'; +import { + detectLogFormat, + parseEvaluatorLog, + parseRawEvaluatorLog, + parseSummaryLog, +} from '../../../src/lib/evaluator-log-parser'; + +// --------------------------------------------------------------------------- +// Synthetic log data helpers +// --------------------------------------------------------------------------- + +function singleQueryRawLog(): string { + const events = [ + { + time: '2026-02-17T00:00:00Z', + type: 'LOG_HEADER', + eventId: 1, + nanoTime: 100000000, + codeqlVersion: '2.24.1', + logVersion: '0.5.0', + }, + { + time: '2026-02-17T00:00:01Z', + type: 'QUERY_STARTED', + eventId: 2, + nanoTime: 200000000, + queryName: 'TestQuery.ql', + }, + { + time: '2026-02-17T00:00:02Z', + type: 'PREDICATE_STARTED', + eventId: 3, + nanoTime: 300000000, + raHash: 'abc123', + predicateName: 'TestPredicate#1', + predicateType: 'COMPUTED', + position: 'TestQuery.ql:5:1:10:1', + dependencies: {}, + queryCausingWork: 2, + }, + { + time: '2026-02-17T00:00:02Z', + type: 'PIPELINE_STARTED', + eventId: 4, + nanoTime: 300100000, + predicateStartEvent: 3, + raReference: 'pipeline', + }, + { + time: '2026-02-17T00:00:02Z', + type: 'PIPELINE_COMPLETED', + eventId: 5, + nanoTime: 350000000, + startEvent: 4, + resultSize: 100, + }, + { + time: '2026-02-17T00:00:02Z', + type: 'PREDICATE_COMPLETED', + eventId: 6, + nanoTime: 350100000, + startEvent: 3, + resultSize: 100, + }, + { + time: '2026-02-17T00:00:03Z', + type: 'PREDICATE_STARTED', + eventId: 7, + nanoTime: 360000000, + raHash: 'def456', + predicateName: 'TestPredicate#2', + predicateType: 'COMPUTED', + position: 'TestQuery.ql:12:1:18:1', + dependencies: { 'TestPredicate#1': 'abc123' }, + queryCausingWork: 2, + }, + { + time: '2026-02-17T00:00:03Z', + type: 'PREDICATE_COMPLETED', + eventId: 8, + nanoTime: 380000000, + startEvent: 7, + resultSize: 50, + }, + { + time: '2026-02-17T00:00:03Z', + type: 'QUERY_COMPLETED', + eventId: 9, + nanoTime: 400000000, + startEvent: 2, + terminationType: 'NORMAL', + }, + { + time: '2026-02-17T00:00:04Z', + type: 'LOG_FOOTER', + eventId: 10, + nanoTime: 500000000, + }, + ]; + return events.map((e) => JSON.stringify(e, null, 2)).join('\n\n'); +} + +function multiQueryRawLog(): string { + const events = [ + { + time: '2026-02-17T00:00:00Z', + type: 'LOG_HEADER', + eventId: 1, + nanoTime: 100000000, + codeqlVersion: '2.24.1', + logVersion: '0.5.0', + }, + // Query A + { + time: '2026-02-17T00:00:01Z', + type: 'QUERY_STARTED', + eventId: 10, + nanoTime: 200000000, + queryName: 'QueryA.ql', + }, + { + time: '2026-02-17T00:00:02Z', + type: 'PREDICATE_STARTED', + eventId: 11, + nanoTime: 300000000, + raHash: 'aaa111', + predicateName: 'PredicateA#1', + predicateType: 'COMPUTED', + dependencies: {}, + queryCausingWork: 10, + }, + { + time: '2026-02-17T00:00:02Z', + type: 'PREDICATE_COMPLETED', + eventId: 12, + nanoTime: 310000000, + startEvent: 11, + resultSize: 200, + }, + { + time: '2026-02-17T00:00:03Z', + type: 'QUERY_COMPLETED', + eventId: 13, + nanoTime: 350000000, + startEvent: 10, + terminationType: 'NORMAL', + }, + // Query B + { + time: '2026-02-17T00:00:04Z', + type: 'QUERY_STARTED', + eventId: 20, + nanoTime: 400000000, + queryName: 'QueryB.ql', + }, + { + time: '2026-02-17T00:00:05Z', + type: 'PREDICATE_STARTED', + eventId: 21, + nanoTime: 500000000, + raHash: 'bbb222', + predicateName: 'PredicateB#1', + predicateType: 'COMPUTED', + dependencies: {}, + queryCausingWork: 20, + }, + { + time: '2026-02-17T00:00:05Z', + type: 'PREDICATE_COMPLETED', + eventId: 22, + nanoTime: 550000000, + startEvent: 21, + resultSize: 300, + }, + { + time: '2026-02-17T00:00:05Z', + type: 'PREDICATE_STARTED', + eventId: 23, + nanoTime: 560000000, + raHash: 'bbb333', + predicateName: 'PredicateB#2', + predicateType: 'COMPUTED', + dependencies: { 'PredicateB#1': 'bbb222' }, + queryCausingWork: 20, + }, + { + time: '2026-02-17T00:00:06Z', + type: 'PREDICATE_COMPLETED', + eventId: 24, + nanoTime: 600000000, + startEvent: 23, + resultSize: 75, + }, + { + time: '2026-02-17T00:00:07Z', + type: 'QUERY_COMPLETED', + eventId: 25, + nanoTime: 650000000, + startEvent: 20, + terminationType: 'NORMAL', + }, + { + time: '2026-02-17T00:00:08Z', + type: 'LOG_FOOTER', + eventId: 30, + nanoTime: 700000000, + }, + ]; + return events.map((e) => JSON.stringify(e, null, 2)).join('\n\n'); +} + +function summaryLog(): string { + const events = [ + { + summaryLogVersion: '0.4.0', + codeqlVersion: '2.24.1', + startTime: '2026-02-17T00:00:00Z', + }, + { + completionTime: '2026-02-17T00:00:01Z', + raHash: 'sent1', + predicateName: 'SentinelPred', + appearsAs: { SentinelPred: { 'TestQuery.ql': [1] } }, + evaluationStrategy: 'SENTINEL_EMPTY', + sentinelRaHash: 'sss', + }, + { + completionTime: '2026-02-17T00:00:02Z', + raHash: 'abc123', + predicateName: 'TestPredicate#1', + appearsAs: { 'TestPredicate#1': { 'TestQuery.ql': [5] } }, + evaluationStrategy: 'COMPUTED', + dependencies: { dep1: 'dep1hash' }, + millis: 50, + pipelineRuns: 1, + position: 'TestQuery.ql:5:1:10:1', + queryCausingWork: 'TestQuery.ql', + ra: 'some RA text', + resultSize: 100, + }, + { + completionTime: '2026-02-17T00:00:03Z', + raHash: 'def456', + predicateName: 'TestPredicate#2', + appearsAs: { 'TestPredicate#2': { 'TestQuery.ql': [12] } }, + evaluationStrategy: 'COMPUTED', + dependencies: { 'TestPredicate#1': 'abc123' }, + millis: 120, + pipelineRuns: 2, + position: 'TestQuery.ql:12:1:18:1', + queryCausingWork: 'TestQuery.ql', + ra: 'more RA text', + resultSize: 50, + }, + ]; + return events.map((e) => JSON.stringify(e, null, 2)).join('\n\n'); +} + +function multiQuerySummaryLog(): string { + const events = [ + { + summaryLogVersion: '0.4.0', + codeqlVersion: '2.24.1', + startTime: '2026-02-17T00:00:00Z', + }, + { + completionTime: '2026-02-17T00:00:02Z', + raHash: 'aaa111', + predicateName: 'PredicateA#1', + evaluationStrategy: 'COMPUTED', + dependencies: {}, + millis: 30, + pipelineRuns: 1, + queryCausingWork: 'QueryA.ql', + resultSize: 200, + }, + { + completionTime: '2026-02-17T00:00:03Z', + raHash: 'bbb222', + predicateName: 'PredicateB#1', + evaluationStrategy: 'COMPUTED', + dependencies: {}, + millis: 75, + pipelineRuns: 1, + queryCausingWork: 'QueryB.ql', + resultSize: 300, + }, + { + completionTime: '2026-02-17T00:00:04Z', + raHash: 'bbb333', + predicateName: 'PredicateB#2', + evaluationStrategy: 'COMPUTED', + dependencies: { 'PredicateB#1': 'bbb222' }, + millis: 45, + pipelineRuns: 1, + queryCausingWork: 'QueryB.ql', + resultSize: 75, + }, + ]; + return events.map((e) => JSON.stringify(e, null, 2)).join('\n\n'); +} + +// --------------------------------------------------------------------------- +// Tests +// --------------------------------------------------------------------------- + +describe('Evaluator Log Parser', () => { + let tempDir: string; + + afterEach(() => { + if (tempDir) { + cleanupTestTempDir(tempDir); + } + }); + + function writeTempLog(filename: string, content: string): string { + tempDir = createTestTempDir('eval-log-parser-'); + mkdirSync(tempDir, { recursive: true }); + const logPath = join(tempDir, filename); + writeFileSync(logPath, content); + return logPath; + } + + // ----------------------------------------------------------------------- + // detectLogFormat + // ----------------------------------------------------------------------- + + describe('detectLogFormat', () => { + it('should detect raw format when event has a type field', () => { + const event = { type: 'LOG_HEADER', eventId: 1, nanoTime: 100 }; + expect(detectLogFormat(event)).toBe('raw'); + }); + + it('should detect summary format when event has no type field', () => { + const event = { + summaryLogVersion: '0.4.0', + codeqlVersion: '2.24.1', + }; + expect(detectLogFormat(event)).toBe('summary'); + }); + + it('should detect summary format for predicate summary events', () => { + const event = { + completionTime: '2026-02-17T00:00:02Z', + raHash: 'abc', + predicateName: 'Foo', + evaluationStrategy: 'COMPUTED', + millis: 50, + }; + expect(detectLogFormat(event)).toBe('summary'); + }); + }); + + // ----------------------------------------------------------------------- + // parseRawEvaluatorLog — single query + // ----------------------------------------------------------------------- + + describe('parseRawEvaluatorLog — single query', () => { + it('should parse codeqlVersion from LOG_HEADER', () => { + const logPath = writeTempLog('evaluator-log.jsonl', singleQueryRawLog()); + const result = parseRawEvaluatorLog(logPath); + + expect(result.codeqlVersion).toBe('2.24.1'); + }); + + it('should set logFormat to raw', () => { + const logPath = writeTempLog('evaluator-log.jsonl', singleQueryRawLog()); + const result = parseRawEvaluatorLog(logPath); + + expect(result.logFormat).toBe('raw'); + }); + + it('should produce exactly one QueryProfile', () => { + const logPath = writeTempLog('evaluator-log.jsonl', singleQueryRawLog()); + const result = parseRawEvaluatorLog(logPath); + + expect(result.queries).toHaveLength(1); + expect(result.queries[0].queryName).toBe('TestQuery.ql'); + }); + + it('should compute query total duration from QUERY_STARTED/COMPLETED nanoTimes', () => { + const logPath = writeTempLog('evaluator-log.jsonl', singleQueryRawLog()); + const result = parseRawEvaluatorLog(logPath); + + // nanoTime: 200000000 → 400000000 = 200ms + expect(result.queries[0].totalDurationMs).toBe(200); + }); + + it('should collect all predicates for the query', () => { + const logPath = writeTempLog('evaluator-log.jsonl', singleQueryRawLog()); + const result = parseRawEvaluatorLog(logPath); + + expect(result.queries[0].predicateCount).toBe(2); + expect(result.queries[0].predicates).toHaveLength(2); + }); + + it('should compute predicate duration from nanoTime diffs', () => { + const logPath = writeTempLog('evaluator-log.jsonl', singleQueryRawLog()); + const result = parseRawEvaluatorLog(logPath); + + const pred1 = result.queries[0].predicates.find( + (p) => p.predicateName === 'TestPredicate#1' + ); + // nanoTime: 300000000 → 350100000 = 50.1ms + expect(pred1).toBeDefined(); + expect(pred1!.durationMs).toBeCloseTo(50.1, 1); + }); + + it('should capture resultSize for completed predicates', () => { + const logPath = writeTempLog('evaluator-log.jsonl', singleQueryRawLog()); + const result = parseRawEvaluatorLog(logPath); + + const pred1 = result.queries[0].predicates.find( + (p) => p.predicateName === 'TestPredicate#1' + ); + expect(pred1!.resultSize).toBe(100); + }); + + it('should capture pipeline count for predicates', () => { + const logPath = writeTempLog('evaluator-log.jsonl', singleQueryRawLog()); + const result = parseRawEvaluatorLog(logPath); + + const pred1 = result.queries[0].predicates.find( + (p) => p.predicateName === 'TestPredicate#1' + ); + expect(pred1!.pipelineCount).toBe(1); + }); + + it('should capture dependencies for predicates', () => { + const logPath = writeTempLog('evaluator-log.jsonl', singleQueryRawLog()); + const result = parseRawEvaluatorLog(logPath); + + const pred2 = result.queries[0].predicates.find( + (p) => p.predicateName === 'TestPredicate#2' + ); + expect(pred2!.dependencies).toContain('TestPredicate#1'); + }); + + it('should report totalEvents', () => { + const logPath = writeTempLog('evaluator-log.jsonl', singleQueryRawLog()); + const result = parseRawEvaluatorLog(logPath); + + expect(result.totalEvents).toBe(10); + }); + }); + + // ----------------------------------------------------------------------- + // parseRawEvaluatorLog — multi query + // ----------------------------------------------------------------------- + + describe('parseRawEvaluatorLog — multi query', () => { + it('should produce two QueryProfiles', () => { + const logPath = writeTempLog('evaluator-log.jsonl', multiQueryRawLog()); + const result = parseRawEvaluatorLog(logPath); + + expect(result.queries).toHaveLength(2); + }); + + it('should name queries correctly', () => { + const logPath = writeTempLog('evaluator-log.jsonl', multiQueryRawLog()); + const result = parseRawEvaluatorLog(logPath); + + expect(result.queries[0].queryName).toBe('QueryA.ql'); + expect(result.queries[1].queryName).toBe('QueryB.ql'); + }); + + it('should group predicates by queryCausingWork', () => { + const logPath = writeTempLog('evaluator-log.jsonl', multiQueryRawLog()); + const result = parseRawEvaluatorLog(logPath); + + expect(result.queries[0].predicateCount).toBe(1); + expect(result.queries[0].predicates[0].predicateName).toBe( + 'PredicateA#1' + ); + + expect(result.queries[1].predicateCount).toBe(2); + const names = result.queries[1].predicates.map( + (p) => p.predicateName + ); + expect(names).toContain('PredicateB#1'); + expect(names).toContain('PredicateB#2'); + }); + + it('should compute per-query total durations', () => { + const logPath = writeTempLog('evaluator-log.jsonl', multiQueryRawLog()); + const result = parseRawEvaluatorLog(logPath); + + // QueryA: 200000000 → 350000000 = 150ms + expect(result.queries[0].totalDurationMs).toBe(150); + // QueryB: 400000000 → 650000000 = 250ms + expect(result.queries[1].totalDurationMs).toBe(250); + }); + }); + + // ----------------------------------------------------------------------- + // parseSummaryLog + // ----------------------------------------------------------------------- + + describe('parseSummaryLog', () => { + it('should parse codeqlVersion from header', () => { + const logPath = writeTempLog( + 'evaluator-log.summary.jsonl', + summaryLog() + ); + const result = parseSummaryLog(logPath); + + expect(result.codeqlVersion).toBe('2.24.1'); + }); + + it('should set logFormat to summary', () => { + const logPath = writeTempLog( + 'evaluator-log.summary.jsonl', + summaryLog() + ); + const result = parseSummaryLog(logPath); + + expect(result.logFormat).toBe('summary'); + }); + + it('should skip SENTINEL_EMPTY entries', () => { + const logPath = writeTempLog( + 'evaluator-log.summary.jsonl', + summaryLog() + ); + const result = parseSummaryLog(logPath); + + const allNames = result.queries.flatMap((q) => + q.predicates.map((p) => p.predicateName) + ); + expect(allNames).not.toContain('SentinelPred'); + }); + + it('should produce one QueryProfile for single-query summary', () => { + const logPath = writeTempLog( + 'evaluator-log.summary.jsonl', + summaryLog() + ); + const result = parseSummaryLog(logPath); + + expect(result.queries).toHaveLength(1); + expect(result.queries[0].queryName).toBe('TestQuery.ql'); + }); + + it('should use millis field directly for duration', () => { + const logPath = writeTempLog( + 'evaluator-log.summary.jsonl', + summaryLog() + ); + const result = parseSummaryLog(logPath); + + const pred1 = result.queries[0].predicates.find( + (p) => p.predicateName === 'TestPredicate#1' + ); + expect(pred1!.durationMs).toBe(50); + }); + + it('should capture pipelineRuns', () => { + const logPath = writeTempLog( + 'evaluator-log.summary.jsonl', + summaryLog() + ); + const result = parseSummaryLog(logPath); + + const pred2 = result.queries[0].predicates.find( + (p) => p.predicateName === 'TestPredicate#2' + ); + expect(pred2!.pipelineCount).toBe(2); + }); + + it('should sum millis for total query duration', () => { + const logPath = writeTempLog( + 'evaluator-log.summary.jsonl', + summaryLog() + ); + const result = parseSummaryLog(logPath); + + // 50 + 120 = 170ms + expect(result.queries[0].totalDurationMs).toBe(170); + }); + + it('should group predicates by queryCausingWork in multi-query summary', () => { + const logPath = writeTempLog( + 'evaluator-log.summary.jsonl', + multiQuerySummaryLog() + ); + const result = parseSummaryLog(logPath); + + expect(result.queries).toHaveLength(2); + + const queryA = result.queries.find( + (q) => q.queryName === 'QueryA.ql' + ); + const queryB = result.queries.find( + (q) => q.queryName === 'QueryB.ql' + ); + + expect(queryA).toBeDefined(); + expect(queryA!.predicateCount).toBe(1); + + expect(queryB).toBeDefined(); + expect(queryB!.predicateCount).toBe(2); + }); + }); + + // ----------------------------------------------------------------------- + // parseEvaluatorLog — auto-detection + // ----------------------------------------------------------------------- + + describe('parseEvaluatorLog — auto-detection', () => { + it('should auto-detect and parse raw log', () => { + const logPath = writeTempLog('evaluator-log.jsonl', singleQueryRawLog()); + const result = parseEvaluatorLog(logPath); + + expect(result.logFormat).toBe('raw'); + expect(result.queries).toHaveLength(1); + }); + + it('should auto-detect and parse summary log', () => { + const logPath = writeTempLog( + 'evaluator-log.summary.jsonl', + summaryLog() + ); + const result = parseEvaluatorLog(logPath); + + expect(result.logFormat).toBe('summary'); + expect(result.queries).toHaveLength(1); + }); + + it('should return empty profile for empty log file', () => { + const logPath = writeTempLog('empty.jsonl', ''); + const result = parseEvaluatorLog(logPath); + + expect(result.queries).toHaveLength(0); + expect(result.totalEvents).toBe(0); + }); + + it('should handle malformed log content gracefully', () => { + const logPath = writeTempLog( + 'bad.jsonl', + 'not valid json\n\nalso not json' + ); + const result = parseEvaluatorLog(logPath); + + // Should not throw; returns empty profile + expect(result.queries).toHaveLength(0); + expect(result.totalEvents).toBe(0); + }); + }); +}); diff --git a/server/test/src/tools/codeql-tools.test.ts b/server/test/src/tools/codeql-tools.test.ts index 990360a9..03d9c3f2 100644 --- a/server/test/src/tools/codeql-tools.test.ts +++ b/server/test/src/tools/codeql-tools.test.ts @@ -32,6 +32,7 @@ describe('registerCodeQLTools', () => { expect(toolNames).toContain('find_class_position'); expect(toolNames).toContain('find_predicate_position'); expect(toolNames).toContain('list_codeql_databases'); + expect(toolNames).toContain('list_mrva_run_results'); expect(toolNames).toContain('list_query_run_results'); expect(toolNames).toContain('quick_evaluate'); expect(toolNames).toContain('register_database'); @@ -41,9 +42,9 @@ describe('registerCodeQLTools', () => { // rank_sarif_results has been removed in favor of SARIF prompts expect(toolNames).not.toContain('rank_sarif_results'); - // Total tools registered: 2 high-level helpers + 8 specialized tools + 22 CLI tools = 32 + // Total tools registered: 2 high-level helpers + 10 specialized tools + 22 CLI tools = 34 // (codeql_lsp_diagnostics moved to registerLSPTools in tools/lsp/) - expect(mockServer.tool).toHaveBeenCalledTimes(32); + expect(mockServer.tool).toHaveBeenCalledTimes(34); }); it('should register validate_codeql_query with correct parameters', () => { diff --git a/server/test/src/tools/codeql/list-mrva-run-results.test.ts b/server/test/src/tools/codeql/list-mrva-run-results.test.ts new file mode 100644 index 00000000..220b5bbc --- /dev/null +++ b/server/test/src/tools/codeql/list-mrva-run-results.test.ts @@ -0,0 +1,241 @@ +/** + * Tests for list_mrva_run_results tool + */ + +import { afterEach, beforeEach, describe, expect, it } from 'vitest'; +import { mkdirSync, writeFileSync } from 'fs'; +import { join } from 'path'; +import { createTestTempDir, cleanupTestTempDir } from '../../../utils/temp-dir'; +import { + discoverMrvaRunResults, + MrvaRunResult, +} from '../../../../src/tools/codeql/list-mrva-run-results'; + +describe('list_mrva_run_results', () => { + let testDir: string; + + beforeEach(() => { + testDir = createTestTempDir('list-mrva-run-results'); + }); + + afterEach(() => { + cleanupTestTempDir(testDir); + }); + + describe('discoverMrvaRunResults', () => { + it('should return empty array when no result dirs are provided', async () => { + const result = await discoverMrvaRunResults([]); + expect(result).toEqual([]); + }); + + it('should return empty array when result dir does not exist', async () => { + const result = await discoverMrvaRunResults([join(testDir, 'nonexistent')]); + expect(result).toEqual([]); + }); + + it('should discover a single run with repository results', async () => { + // Arrange: create a fake MRVA run directory + const runDir = join(testDir, '20442'); + const repoDir = join(runDir, 'arduino', 'Arduino'); + const resultsDir = join(repoDir, 'results'); + mkdirSync(resultsDir, { recursive: true }); + writeFileSync(join(runDir, 'timestamp'), '2026-02-17T15:00:00Z'); + writeFileSync( + join(runDir, 'repo_states.json'), + JSON.stringify({ '919161': { repositoryId: 919161, downloadStatus: 'succeeded' } }), + ); + writeFileSync( + join(repoDir, 'repo_task.json'), + JSON.stringify({ + repository: { id: 919161, fullName: 'arduino/Arduino', private: false }, + analysisStatus: 'succeeded', + resultCount: 1, + artifactSizeInBytes: 14311, + }), + ); + writeFileSync(join(resultsDir, 'results.sarif'), '{}'); + writeFileSync(join(resultsDir, 'results.bqrs'), ''); + + // Act + const result = await discoverMrvaRunResults([testDir]); + + // Assert + expect(result).toHaveLength(1); + expect(result[0].runId).toBe('20442'); + expect(result[0].timestamp).toBe('2026-02-17T15:00:00Z'); + expect(result[0].repositories).toHaveLength(1); + expect(result[0].repositories[0].fullName).toBe('arduino/Arduino'); + expect(result[0].repositories[0].analysisStatus).toBe('succeeded'); + expect(result[0].repositories[0].resultCount).toBe(1); + expect(result[0].repositories[0].hasSarif).toBe(true); + expect(result[0].repositories[0].hasBqrs).toBe(true); + }); + + it('should discover multiple runs across multiple dirs', async () => { + // Arrange + const dir1 = join(testDir, 'dir1'); + const dir2 = join(testDir, 'dir2'); + const run1 = join(dir1, '10001'); + const run2 = join(dir2, '10002'); + mkdirSync(run1, { recursive: true }); + mkdirSync(run2, { recursive: true }); + writeFileSync(join(run1, 'timestamp'), 'ts1'); + writeFileSync(join(run2, 'timestamp'), 'ts2'); + + // Act + const result = await discoverMrvaRunResults([dir1, dir2]); + + // Assert + expect(result).toHaveLength(2); + }); + + it('should filter by run ID', async () => { + // Arrange + for (const id of ['20438', '20440', '20442']) { + const runDir = join(testDir, id); + mkdirSync(runDir, { recursive: true }); + writeFileSync(join(runDir, 'timestamp'), `ts-${id}`); + } + + // Act + const result = await discoverMrvaRunResults([testDir], '20440'); + + // Assert + expect(result).toHaveLength(1); + expect(result[0].runId).toBe('20440'); + }); + + it('should skip non-numeric directories', async () => { + // Arrange + const notARun = join(testDir, 'exported-results'); + mkdirSync(notARun, { recursive: true }); + const alsoNotARun = join(testDir, 'some-text-dir'); + mkdirSync(alsoNotARun, { recursive: true }); + const realRun = join(testDir, '99999'); + mkdirSync(realRun, { recursive: true }); + writeFileSync(join(realRun, 'timestamp'), 'ts'); + + // Act + const result = await discoverMrvaRunResults([testDir]); + + // Assert + expect(result).toHaveLength(1); + expect(result[0].runId).toBe('99999'); + }); + + it('should handle missing timestamp file gracefully', async () => { + // Arrange + const runDir = join(testDir, '12345'); + mkdirSync(runDir, { recursive: true }); + // No timestamp file + + // Act + const result = await discoverMrvaRunResults([testDir]); + + // Assert + expect(result).toHaveLength(1); + expect(result[0].timestamp).toBeUndefined(); + }); + + it('should handle missing repo_task.json gracefully', async () => { + // Arrange: repo directory without repo_task.json + const runDir = join(testDir, '55555'); + const repoDir = join(runDir, 'owner', 'repo'); + mkdirSync(repoDir, { recursive: true }); + + // Act + const result = await discoverMrvaRunResults([testDir]); + + // Assert + expect(result).toHaveLength(1); + expect(result[0].repositories).toHaveLength(1); + expect(result[0].repositories[0].fullName).toBe('owner/repo'); + expect(result[0].repositories[0].analysisStatus).toBeUndefined(); + expect(result[0].repositories[0].resultCount).toBeUndefined(); + expect(result[0].repositories[0].hasSarif).toBe(false); + expect(result[0].repositories[0].hasBqrs).toBe(false); + }); + + it('should skip exported-results and .DS_Store directories', async () => { + // Arrange + const runDir = join(testDir, '77777'); + mkdirSync(join(runDir, 'exported-results'), { recursive: true }); + mkdirSync(join(runDir, '.DS_Store'), { recursive: true }); + const repoDir = join(runDir, 'owner', 'repo'); + mkdirSync(repoDir, { recursive: true }); + + // Act + const result = await discoverMrvaRunResults([testDir]); + + // Assert + expect(result).toHaveLength(1); + expect(result[0].repositories).toHaveLength(1); + expect(result[0].repositories[0].fullName).toBe('owner/repo'); + }); + + it('should discover multiple repositories in a single run', async () => { + // Arrange + const runDir = join(testDir, '30000'); + mkdirSync(runDir, { recursive: true }); + writeFileSync(join(runDir, 'timestamp'), '2026-02-17T10:00:00Z'); + + for (const [owner, repo, status, count] of [ + ['arduino', 'Arduino', 'succeeded', 5], + ['google', 'guava', 'succeeded', 2], + ['facebook', 'react', 'failed', 0], + ] as const) { + const repoDir = join(runDir, owner, repo); + const resultsDir = join(repoDir, 'results'); + mkdirSync(resultsDir, { recursive: true }); + writeFileSync( + join(repoDir, 'repo_task.json'), + JSON.stringify({ analysisStatus: status, resultCount: count }), + ); + if (status === 'succeeded') { + writeFileSync(join(resultsDir, 'results.sarif'), '{}'); + writeFileSync(join(resultsDir, 'results.bqrs'), ''); + } + } + + // Act + const result = await discoverMrvaRunResults([testDir]); + + // Assert + expect(result).toHaveLength(1); + expect(result[0].repositories).toHaveLength(3); + + const arduino = result[0].repositories.find( + (r: MrvaRunResult['repositories'][0]) => r.fullName === 'arduino/Arduino', + ); + expect(arduino).toBeDefined(); + expect(arduino!.analysisStatus).toBe('succeeded'); + expect(arduino!.resultCount).toBe(5); + expect(arduino!.hasSarif).toBe(true); + expect(arduino!.hasBqrs).toBe(true); + + const react = result[0].repositories.find( + (r: MrvaRunResult['repositories'][0]) => r.fullName === 'facebook/react', + ); + expect(react).toBeDefined(); + expect(react!.analysisStatus).toBe('failed'); + expect(react!.resultCount).toBe(0); + expect(react!.hasSarif).toBe(false); + expect(react!.hasBqrs).toBe(false); + }); + + it('should handle run directory with no repositories', async () => { + // Arrange: numeric directory with only files (no owner/repo subdirs) + const runDir = join(testDir, '20438'); + mkdirSync(runDir, { recursive: true }); + writeFileSync(join(runDir, 'timestamp'), '2026-01-01T00:00:00Z'); + + // Act + const result = await discoverMrvaRunResults([testDir]); + + // Assert + expect(result).toHaveLength(1); + expect(result[0].runId).toBe('20438'); + expect(result[0].repositories).toHaveLength(0); + }); + }); +}); diff --git a/server/test/src/tools/codeql/profile-codeql-query-from-logs.test.ts b/server/test/src/tools/codeql/profile-codeql-query-from-logs.test.ts new file mode 100644 index 00000000..adaa5a5a --- /dev/null +++ b/server/test/src/tools/codeql/profile-codeql-query-from-logs.test.ts @@ -0,0 +1,380 @@ +/** + * Tests for the profile_codeql_query_from_logs MCP tool. + */ + +import { afterEach, describe, expect, it, vi } from 'vitest'; +import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js'; +import { existsSync, mkdirSync, readFileSync, writeFileSync } from 'fs'; +import { join } from 'path'; +import { + createTestTempDir, + cleanupTestTempDir, +} from '../../../utils/temp-dir'; +import { registerProfileCodeQLQueryFromLogsTool } from '../../../../src/tools/codeql/profile-codeql-query-from-logs'; + +// --------------------------------------------------------------------------- +// Synthetic log helpers (minimal) +// --------------------------------------------------------------------------- + +function minimalRawLog(): string { + const events = [ + { + time: '2026-02-17T00:00:00Z', + type: 'LOG_HEADER', + eventId: 1, + nanoTime: 100000000, + codeqlVersion: '2.24.1', + logVersion: '0.5.0', + }, + { + time: '2026-02-17T00:00:01Z', + type: 'QUERY_STARTED', + eventId: 2, + nanoTime: 200000000, + queryName: 'TestQuery.ql', + }, + { + time: '2026-02-17T00:00:02Z', + type: 'PREDICATE_STARTED', + eventId: 3, + nanoTime: 300000000, + raHash: 'abc123', + predicateName: 'ExpensivePred', + predicateType: 'COMPUTED', + dependencies: {}, + queryCausingWork: 2, + }, + { + time: '2026-02-17T00:00:02Z', + type: 'PREDICATE_COMPLETED', + eventId: 4, + nanoTime: 350000000, + startEvent: 3, + resultSize: 42, + }, + { + time: '2026-02-17T00:00:03Z', + type: 'QUERY_COMPLETED', + eventId: 5, + nanoTime: 400000000, + startEvent: 2, + terminationType: 'NORMAL', + }, + { + time: '2026-02-17T00:00:04Z', + type: 'LOG_FOOTER', + eventId: 6, + nanoTime: 500000000, + }, + ]; + return events.map((e) => JSON.stringify(e, null, 2)).join('\n\n'); +} + +function minimalSummaryLog(): string { + const events = [ + { + summaryLogVersion: '0.4.0', + codeqlVersion: '2.24.1', + startTime: '2026-02-17T00:00:00Z', + }, + { + completionTime: '2026-02-17T00:00:02Z', + raHash: 'abc123', + predicateName: 'ExpensivePred', + evaluationStrategy: 'COMPUTED', + dependencies: {}, + millis: 50, + pipelineRuns: 1, + queryCausingWork: 'TestQuery.ql', + resultSize: 42, + }, + ]; + return events.map((e) => JSON.stringify(e, null, 2)).join('\n\n'); +} + +// --------------------------------------------------------------------------- +// Helper to extract the handler registered via server.tool() +// --------------------------------------------------------------------------- + +// eslint-disable-next-line no-unused-vars +type ToolHandler = (params: Record) => Promise<{ + content: { type: string; text: string }[]; + isError?: boolean; +}>; + +function getRegisteredHandler( + _mockServer: McpServer +): ToolHandler { + return (_mockServer.tool as ReturnType).mock + .calls[0][3] as ToolHandler; +} + +// --------------------------------------------------------------------------- +// Tests +// --------------------------------------------------------------------------- + +describe('Profile CodeQL Query From Logs Tool', () => { + let tempDir: string; + + afterEach(() => { + if (tempDir) { + cleanupTestTempDir(tempDir); + } + }); + + // ----------------------------------------------------------------------- + // Registration + // ----------------------------------------------------------------------- + + describe('registerProfileCodeQLQueryFromLogsTool', () => { + it('should register the tool with the expected name and schema', () => { + const mockServer = { + tool: vi.fn(), + } as unknown as McpServer; + + registerProfileCodeQLQueryFromLogsTool(mockServer); + + expect(mockServer.tool).toHaveBeenCalledOnce(); + expect(mockServer.tool).toHaveBeenCalledWith( + 'profile_codeql_query_from_logs', + expect.any(String), + expect.objectContaining({ + evaluatorLog: expect.any(Object), + outputDir: expect.any(Object), + topN: expect.any(Object), + }), + expect.any(Function) + ); + }); + }); + + // ----------------------------------------------------------------------- + // Error cases + // ----------------------------------------------------------------------- + + describe('error handling', () => { + it('should return error when evaluator log does not exist', async () => { + const mockServer = { + tool: vi.fn(), + } as unknown as McpServer; + registerProfileCodeQLQueryFromLogsTool(mockServer); + const handler = getRegisteredHandler(mockServer); + + const result = await handler({ + evaluatorLog: '/nonexistent/evaluator-log.jsonl', + }); + + expect(result.isError).toBe(true); + expect(result.content[0].text).toContain('Evaluator log not found'); + }); + }); + + // ----------------------------------------------------------------------- + // Raw log processing + // ----------------------------------------------------------------------- + + describe('raw evaluator log processing', () => { + it('should produce output files and a text summary', async () => { + tempDir = createTestTempDir('profile-from-logs-raw-'); + mkdirSync(tempDir, { recursive: true }); + + const logPath = join(tempDir, 'evaluator-log.jsonl'); + writeFileSync(logPath, minimalRawLog()); + + const outputDir = join(tempDir, 'output'); + + const mockServer = { + tool: vi.fn(), + } as unknown as McpServer; + registerProfileCodeQLQueryFromLogsTool(mockServer); + const handler = getRegisteredHandler(mockServer); + + const result = await handler({ + evaluatorLog: logPath, + outputDir, + topN: 5, + }); + + expect(result.isError).toBeUndefined(); + + // Output files created + expect( + existsSync(join(outputDir, 'query-evaluation-profile.json')) + ).toBe(true); + expect( + existsSync(join(outputDir, 'query-evaluation-profile.md')) + ).toBe(true); + + // Text summary content + const text = result.content[0].text; + expect(text).toContain('Query log profiling completed successfully'); + expect(text).toContain('TestQuery.ql'); + expect(text).toContain('ExpensivePred'); + }); + + it('should write valid JSON profile', async () => { + tempDir = createTestTempDir('profile-json-'); + mkdirSync(tempDir, { recursive: true }); + + const logPath = join(tempDir, 'evaluator-log.jsonl'); + writeFileSync(logPath, minimalRawLog()); + + const outputDir = join(tempDir, 'output'); + + const mockServer = { + tool: vi.fn(), + } as unknown as McpServer; + registerProfileCodeQLQueryFromLogsTool(mockServer); + const handler = getRegisteredHandler(mockServer); + await handler({ evaluatorLog: logPath, outputDir }); + + const jsonContent = readFileSync( + join(outputDir, 'query-evaluation-profile.json'), + 'utf-8' + ); + const profile = JSON.parse(jsonContent); + + expect(profile.logFormat).toBe('raw'); + expect(profile.queries).toHaveLength(1); + expect(profile.queries[0].queryName).toBe('TestQuery.ql'); + }); + + it('should write a Mermaid diagram file', async () => { + tempDir = createTestTempDir('profile-mermaid-'); + mkdirSync(tempDir, { recursive: true }); + + const logPath = join(tempDir, 'evaluator-log.jsonl'); + writeFileSync(logPath, minimalRawLog()); + + const outputDir = join(tempDir, 'output'); + + const mockServer = { + tool: vi.fn(), + } as unknown as McpServer; + registerProfileCodeQLQueryFromLogsTool(mockServer); + const handler = getRegisteredHandler(mockServer); + await handler({ evaluatorLog: logPath, outputDir }); + + const mdContent = readFileSync( + join(outputDir, 'query-evaluation-profile.md'), + 'utf-8' + ); + expect(mdContent).toContain('```mermaid'); + expect(mdContent).toContain('graph TD'); + expect(mdContent).toContain('TestQuery.ql'); + }); + }); + + // ----------------------------------------------------------------------- + // Summary log processing + // ----------------------------------------------------------------------- + + describe('summary log processing', () => { + it('should produce output files from a summary log', async () => { + tempDir = createTestTempDir('profile-from-logs-summary-'); + mkdirSync(tempDir, { recursive: true }); + + const logPath = join(tempDir, 'evaluator-log.summary.jsonl'); + writeFileSync(logPath, minimalSummaryLog()); + + const outputDir = join(tempDir, 'output'); + + const mockServer = { + tool: vi.fn(), + } as unknown as McpServer; + registerProfileCodeQLQueryFromLogsTool(mockServer); + const handler = getRegisteredHandler(mockServer); + + const result = await handler({ + evaluatorLog: logPath, + outputDir, + }); + + expect(result.isError).toBeUndefined(); + expect( + existsSync(join(outputDir, 'query-evaluation-profile.json')) + ).toBe(true); + + const text = result.content[0].text; + expect(text).toContain('TestQuery.ql'); + expect(text).toContain('ExpensivePred'); + }); + + it('should report summary log format in the JSON profile', async () => { + tempDir = createTestTempDir('profile-summary-format-'); + mkdirSync(tempDir, { recursive: true }); + + const logPath = join(tempDir, 'evaluator-log.summary.jsonl'); + writeFileSync(logPath, minimalSummaryLog()); + + const outputDir = join(tempDir, 'output'); + + const mockServer = { + tool: vi.fn(), + } as unknown as McpServer; + registerProfileCodeQLQueryFromLogsTool(mockServer); + const handler = getRegisteredHandler(mockServer); + await handler({ evaluatorLog: logPath, outputDir }); + + const jsonContent = readFileSync( + join(outputDir, 'query-evaluation-profile.json'), + 'utf-8' + ); + const profile = JSON.parse(jsonContent); + + expect(profile.logFormat).toBe('summary'); + }); + }); + + // ----------------------------------------------------------------------- + // Defaults + // ----------------------------------------------------------------------- + + describe('default behaviour', () => { + it('should default outputDir to the log directory', async () => { + tempDir = createTestTempDir('profile-default-dir-'); + mkdirSync(tempDir, { recursive: true }); + + const logPath = join(tempDir, 'evaluator-log.jsonl'); + writeFileSync(logPath, minimalRawLog()); + + const mockServer = { + tool: vi.fn(), + } as unknown as McpServer; + registerProfileCodeQLQueryFromLogsTool(mockServer); + const handler = getRegisteredHandler(mockServer); + + await handler({ evaluatorLog: logPath }); + + // Output files should appear next to the log + expect( + existsSync(join(tempDir, 'query-evaluation-profile.json')) + ).toBe(true); + expect( + existsSync(join(tempDir, 'query-evaluation-profile.md')) + ).toBe(true); + }); + + it('should default topN to 20', async () => { + tempDir = createTestTempDir('profile-default-topn-'); + mkdirSync(tempDir, { recursive: true }); + + const logPath = join(tempDir, 'evaluator-log.jsonl'); + writeFileSync(logPath, minimalRawLog()); + + const mockServer = { + tool: vi.fn(), + } as unknown as McpServer; + registerProfileCodeQLQueryFromLogsTool(mockServer); + const handler = getRegisteredHandler(mockServer); + + const result = await handler({ evaluatorLog: logPath }); + + // Should succeed without error (topN default applied internally) + expect(result.isError).toBeUndefined(); + expect(result.content[0].text).toContain( + 'Query log profiling completed successfully' + ); + }); + }); +}); From 583bad45461d4149dbffd0793ca91fb492fef1fb Mon Sep 17 00:00:00 2001 From: Nathan Randall Date: Wed, 18 Feb 2026 06:37:01 -0700 Subject: [PATCH 03/14] fixes for broken tools, integrations tests, & docs Fixes found by stress-testing MCP tools against real CodeQL databases: - bqrs_decode: replace non-existent --max-results/--max-paths with correct --rows option; add --result-set, --entities, --sort-direction, --no-titles - bqrs_info: add --format (text/json), --paginate-rows, --paginate-result-set; fix format passthrough in cli-tool-registry (formatShouldBePassedToCLI) - list_query_run_results: add language/queryPath filters; extract metadata from query.log (queryPath, databasePath, language); add fallback language detection from semmlecode..dbscheme and codeql/-all/ paths - database_analyze: add --rerun parameter; auto-create output parent directory to prevent NoSuchFileException after long-running evaluations - query_run: fix SARIF generation to use interpretBQRSFile with proper -t metadata instead of bare bqrs interpret; fix output filename to results-interpreted.sarif - `docs/**/*.md`: update project docs to reflect ^ improvements to tools. Unit tests: 873 passed (44 files, +23 new tests) Integration tests: 5 new test cases covering each fix --- .../decode_with_result_set/README.md | 17 + .../after/monitoring-state.json | 14 + .../before/monitoring-state.json | 3 + .../before/results.bqrs | Bin 0 -> 16152 bytes .../decode_with_result_set/test-config.json | 9 + .../codeql_bqrs_info/json_format/README.md | 9 + .../json_format/after/monitoring-state.json | 14 + .../json_format/before/monitoring-state.json | 3 + .../json_format/before/results.bqrs | Bin 0 -> 16152 bytes .../json_format/test-config.json | 7 + .../analyze_with_output_subdir/README.md | 21 ++ .../after/monitoring-state.json | 14 + .../before/monitoring-state.json | 10 + .../filter_by_language/README.md | 12 + .../after/monitoring-state.json | 14 + .../before/monitoring-state.json | 3 + .../filter_by_language/test-config.json | 6 + .../filter_by_query_name/README.md | 10 + .../after/monitoring-state.json | 14 + .../before/monitoring-state.json | 3 + .../filter_by_query_name/test-config.json | 6 + docs/getting-started.md | 15 +- docs/ql-mcp/tools.md | 10 +- docs/vscode/IMPLEMENTATION.md | 312 ----------------- docs/vscode/extension.md | 2 + server/dist/codeql-development-mcp-server.js | 161 +++++++-- .../dist/codeql-development-mcp-server.js.map | 4 +- server/src/lib/cli-tool-registry.ts | 33 +- server/src/tools/codeql/bqrs-decode.ts | 38 ++- server/src/tools/codeql/bqrs-info.ts | 20 +- server/src/tools/codeql/database-analyze.ts | 10 +- server/src/tools/codeql/list-databases.ts | 2 +- .../tools/codeql/list-query-run-results.ts | 199 ++++++++++- server/src/tools/codeql/query-run.ts | 5 +- .../test/src/tools/codeql/bqrs-decode.test.ts | 75 +++++ .../test/src/tools/codeql/bqrs-info.test.ts | 46 +++ .../codeql/list-query-run-results.test.ts | 316 +++++++++++++++++- 37 files changed, 1055 insertions(+), 382 deletions(-) create mode 100644 client/integration-tests/primitives/tools/codeql_bqrs_decode/decode_with_result_set/README.md create mode 100644 client/integration-tests/primitives/tools/codeql_bqrs_decode/decode_with_result_set/after/monitoring-state.json create mode 100644 client/integration-tests/primitives/tools/codeql_bqrs_decode/decode_with_result_set/before/monitoring-state.json create mode 100644 client/integration-tests/primitives/tools/codeql_bqrs_decode/decode_with_result_set/before/results.bqrs create mode 100644 client/integration-tests/primitives/tools/codeql_bqrs_decode/decode_with_result_set/test-config.json create mode 100644 client/integration-tests/primitives/tools/codeql_bqrs_info/json_format/README.md create mode 100644 client/integration-tests/primitives/tools/codeql_bqrs_info/json_format/after/monitoring-state.json create mode 100644 client/integration-tests/primitives/tools/codeql_bqrs_info/json_format/before/monitoring-state.json create mode 100644 client/integration-tests/primitives/tools/codeql_bqrs_info/json_format/before/results.bqrs create mode 100644 client/integration-tests/primitives/tools/codeql_bqrs_info/json_format/test-config.json create mode 100644 client/integration-tests/primitives/tools/codeql_database_analyze/analyze_with_output_subdir/README.md create mode 100644 client/integration-tests/primitives/tools/codeql_database_analyze/analyze_with_output_subdir/after/monitoring-state.json create mode 100644 client/integration-tests/primitives/tools/codeql_database_analyze/analyze_with_output_subdir/before/monitoring-state.json create mode 100644 client/integration-tests/primitives/tools/list_query_run_results/filter_by_language/README.md create mode 100644 client/integration-tests/primitives/tools/list_query_run_results/filter_by_language/after/monitoring-state.json create mode 100644 client/integration-tests/primitives/tools/list_query_run_results/filter_by_language/before/monitoring-state.json create mode 100644 client/integration-tests/primitives/tools/list_query_run_results/filter_by_language/test-config.json create mode 100644 client/integration-tests/primitives/tools/list_query_run_results/filter_by_query_name/README.md create mode 100644 client/integration-tests/primitives/tools/list_query_run_results/filter_by_query_name/after/monitoring-state.json create mode 100644 client/integration-tests/primitives/tools/list_query_run_results/filter_by_query_name/before/monitoring-state.json create mode 100644 client/integration-tests/primitives/tools/list_query_run_results/filter_by_query_name/test-config.json delete mode 100644 docs/vscode/IMPLEMENTATION.md create mode 100644 server/test/src/tools/codeql/bqrs-decode.test.ts create mode 100644 server/test/src/tools/codeql/bqrs-info.test.ts diff --git a/client/integration-tests/primitives/tools/codeql_bqrs_decode/decode_with_result_set/README.md b/client/integration-tests/primitives/tools/codeql_bqrs_decode/decode_with_result_set/README.md new file mode 100644 index 00000000..d35baac8 --- /dev/null +++ b/client/integration-tests/primitives/tools/codeql_bqrs_decode/decode_with_result_set/README.md @@ -0,0 +1,17 @@ +# `codeql_bqrs_decode` - decode_with_result_set + +## Purpose + +Tests the `codeql_bqrs_decode` tool with the `result-set` parameter to decode +a specific result set from a BQRS file. This test exercises the `--result-set`, +`--format`, and `--no-titles` CLI options which were previously untested, +allowing non-existent options like `--max-results` to go undetected. + +## Inputs + +- `before/results.bqrs` — BQRS file with a `#select` result set (1 row, 2 columns). +- `test-config.json` — Specifies `result-set`, `format`, and `no-titles` arguments. + +## Outputs + +- Tool returns decoded CSV output for the `#select` result set without column headers. diff --git a/client/integration-tests/primitives/tools/codeql_bqrs_decode/decode_with_result_set/after/monitoring-state.json b/client/integration-tests/primitives/tools/codeql_bqrs_decode/decode_with_result_set/after/monitoring-state.json new file mode 100644 index 00000000..792a6ea2 --- /dev/null +++ b/client/integration-tests/primitives/tools/codeql_bqrs_decode/decode_with_result_set/after/monitoring-state.json @@ -0,0 +1,14 @@ +{ + "sessions": [ + { + "id": "integration_test_session", + "calls": [ + { + "tool": "codeql_bqrs_decode", + "timestamp": "2025-09-25T16:06:00.000Z", + "status": "success" + } + ] + } + ] +} diff --git a/client/integration-tests/primitives/tools/codeql_bqrs_decode/decode_with_result_set/before/monitoring-state.json b/client/integration-tests/primitives/tools/codeql_bqrs_decode/decode_with_result_set/before/monitoring-state.json new file mode 100644 index 00000000..f56218ab --- /dev/null +++ b/client/integration-tests/primitives/tools/codeql_bqrs_decode/decode_with_result_set/before/monitoring-state.json @@ -0,0 +1,3 @@ +{ + "sessions": [] +} diff --git a/client/integration-tests/primitives/tools/codeql_bqrs_decode/decode_with_result_set/before/results.bqrs b/client/integration-tests/primitives/tools/codeql_bqrs_decode/decode_with_result_set/before/results.bqrs new file mode 100644 index 0000000000000000000000000000000000000000..6c7d29394f36f39aeddf4eec79a1d731be340cf8 GIT binary patch literal 16152 zcmds8-EQN!6`tg(m^bJh0pBH%W!dpB(2I6v+wNk!JG*JGiXxyT+SWurwkS`MqHoal z1^NPgxIRK}dMHsmRE9~&IEsT}fQ&84NBq9?osSeLo}T>Y^zSGBpExVHAJLL}QND*S z{_o<_U&rNUzx2aAV!OnP*cX=M+mvOcmxfypuKEHOhDi)Z{5UJwx}as8XI{y8$$ehJ zx6uDgzfc|)@wW8EasQiJnr;*J)1DP~LHk?(Gym7gDo)tK_uo#F7K8fVN7-^BU=TqH z5p5-_e4j<|x2TTok}Glkirtn44NJmmxMU~r_J4WuiymhQ3(J$!(-n(PPTui%@BVS} z@6&(&_nqf??~8r5cu%UUW5&ft;)y?GOT+605xm!gdtVXm)r5OUxW|jIH>!SKumrO4 zrKbH8EjJ7DSR!^w>sPhpD9p>MFxygiFMsgIA3y#mJ_EZf6OH@? z5`^3S`7dx#$g!5EsW|QAk&F8p(!&d3=N#QXDnOB2A94qCA=;y@4@F?ThYbY1p6igJWf>-88>$O9yE( z-{%$bn7lP zp-s6UjT#6MRw(>WTEA!|9E>ye!#-VtkuS)ve>G7}6TXw|(@Z-#Z%)>u8u4?%3|L(? z$kaxQwL>+RKOZJGUWbWC5#~_c%m!vKJjWm=q-QGLt6^1lgsurwT8{t))rd8~JX?XC zp9g0ucM$38#GYZu7r=YNJsw@ViZ?Jp#bY)|Cjb;_Gyt8Rsemtl^ES@8GfJ#5Eul{0 z#Rvw3D$kwc!vfOv8cY?I=i&<1>(*Xj(|IEKJ3)-tKD`Rr1G zcEx#N#MxNKn|kgp;&E^>1w7nr`GzIQXXiohST*6zyKG4_ zSTcf{XU8d`v8f}$KF~Im=+?$ms(^>564vKnZVDb@Sf7^#ETgz0o|wdo?YBjYycrRz zfUk-ehdTQBZ=xEb$yj@|v4I?jxs(8n%?KJ}9)_B;G)$EcbBlF=1c;n4{aNXu^~aIKw&hFknt&@Lkgau zfH^k%{~5g50p_O6BOx}KuM7bDLu37`h#jULdUANbz=xG@_^V9Lh8d^{HMTR-qQZ4ZOA3qGX`Zcf-*EsC4A23Pfhiueq~L6-vTybU4A~_O zf`Vx2Ov21GC>W|?i`|%AbPvdzSqduTF-btZ>cfQLKs8PqCrs1}0(L8gqbblZ!Sy4v z7__LzBtlhYYmIGYT(lVB#a1OT7Q+Sg4h+y>T4%$c$D{#0P}c*znxcFSogo-F@-QC& z55WL6XCy)k+a(j6?-EyYn2)jT$ioQj&PonK49K&Q0}RO3v z${5YD2v87MEjCOHrvX&P6V9kY9+w70dyfW8KGJ}kSUAP+FDHo1!huQ`j(- z#+*g4QAd5glC-)mW&{(n*(#OT2MZ5XK2DyGU&cvq*xtLOosyiX&4EL) zDXD4qYi|w|ZH3Kdq6G(RFnVZDpdP*BEoS;I+ZWnlYu;V^qC0EFj@n8O_jc9Z-%)GY PO)K}?8h6q@wu|Y^zSGBpExVHAJLL}QND*S z{_o<_U&rNUzx2aAV!OnP*cX=M+mvOcmxfypuKEHOhDi)Z{5UJwx}as8XI{y8$$ehJ zx6uDgzfc|)@wW8EasQiJnr;*J)1DP~LHk?(Gym7gDo)tK_uo#F7K8fVN7-^BU=TqH z5p5-_e4j<|x2TTok}Glkirtn44NJmmxMU~r_J4WuiymhQ3(J$!(-n(PPTui%@BVS} z@6&(&_nqf??~8r5cu%UUW5&ft;)y?GOT+605xm!gdtVXm)r5OUxW|jIH>!SKumrO4 zrKbH8EjJ7DSR!^w>sPhpD9p>MFxygiFMsgIA3y#mJ_EZf6OH@? z5`^3S`7dx#$g!5EsW|QAk&F8p(!&d3=N#QXDnOB2A94qCA=;y@4@F?ThYbY1p6igJWf>-88>$O9yE( z-{%$bn7lP zp-s6UjT#6MRw(>WTEA!|9E>ye!#-VtkuS)ve>G7}6TXw|(@Z-#Z%)>u8u4?%3|L(? z$kaxQwL>+RKOZJGUWbWC5#~_c%m!vKJjWm=q-QGLt6^1lgsurwT8{t))rd8~JX?XC zp9g0ucM$38#GYZu7r=YNJsw@ViZ?Jp#bY)|Cjb;_Gyt8Rsemtl^ES@8GfJ#5Eul{0 z#Rvw3D$kwc!vfOv8cY?I=i&<1>(*Xj(|IEKJ3)-tKD`Rr1G zcEx#N#MxNKn|kgp;&E^>1w7nr`GzIQXXiohST*6zyKG4_ zSTcf{XU8d`v8f}$KF~Im=+?$ms(^>564vKnZVDb@Sf7^#ETgz0o|wdo?YBjYycrRz zfUk-ehdTQBZ=xEb$yj@|v4I?jxs(8n%?KJ}9)_B;G)$EcbBlF=1c;n4{aNXu^~aIKw&hFknt&@Lkgau zfH^k%{~5g50p_O6BOx}KuM7bDLu37`h#jULdUANbz=xG@_^V9Lh8d^{HMTR-qQZ4ZOA3qGX`Zcf-*EsC4A23Pfhiueq~L6-vTybU4A~_O zf`Vx2Ov21GC>W|?i`|%AbPvdzSqduTF-btZ>cfQLKs8PqCrs1}0(L8gqbblZ!Sy4v z7__LzBtlhYYmIGYT(lVB#a1OT7Q+Sg4h+y>T4%$c$D{#0P}c*znxcFSogo-F@-QC& z55WL6XCy)k+a(j6?-EyYn2)jT$ioQj&PonK49K&Q0}RO3v z${5YD2v87MEjCOHrvX&P6V9kY9+w70dyfW8KGJ}kSUAP+FDHo1!huQ`j(- z#+*g4QAd5glC-)mW&{(n*(#OT2MZ5XK2DyGU&cvq*xtLOosyiX&4EL) zDXD4qYi|w|ZH3Kdq6G(RFnVZDpdP*BEoS;I+ZWnlYu;V^qC0EFj@n8O_jc9Z-%)GY PO)K}?8h6q@wu|/` segment or `semmlecode..dbscheme` +filename pattern. diff --git a/client/integration-tests/primitives/tools/list_query_run_results/filter_by_language/after/monitoring-state.json b/client/integration-tests/primitives/tools/list_query_run_results/filter_by_language/after/monitoring-state.json new file mode 100644 index 00000000..e1bec348 --- /dev/null +++ b/client/integration-tests/primitives/tools/list_query_run_results/filter_by_language/after/monitoring-state.json @@ -0,0 +1,14 @@ +{ + "sessions": [ + { + "id": "integration_test_session", + "calls": [ + { + "tool": "list_query_run_results", + "timestamp": "2025-09-25T16:06:00.000Z", + "status": "success" + } + ] + } + ] +} diff --git a/client/integration-tests/primitives/tools/list_query_run_results/filter_by_language/before/monitoring-state.json b/client/integration-tests/primitives/tools/list_query_run_results/filter_by_language/before/monitoring-state.json new file mode 100644 index 00000000..f56218ab --- /dev/null +++ b/client/integration-tests/primitives/tools/list_query_run_results/filter_by_language/before/monitoring-state.json @@ -0,0 +1,3 @@ +{ + "sessions": [] +} diff --git a/client/integration-tests/primitives/tools/list_query_run_results/filter_by_language/test-config.json b/client/integration-tests/primitives/tools/list_query_run_results/filter_by_language/test-config.json new file mode 100644 index 00000000..489ea1b2 --- /dev/null +++ b/client/integration-tests/primitives/tools/list_query_run_results/filter_by_language/test-config.json @@ -0,0 +1,6 @@ +{ + "toolName": "list_query_run_results", + "arguments": { + "language": "javascript" + } +} diff --git a/client/integration-tests/primitives/tools/list_query_run_results/filter_by_query_name/README.md b/client/integration-tests/primitives/tools/list_query_run_results/filter_by_query_name/README.md new file mode 100644 index 00000000..32f0c037 --- /dev/null +++ b/client/integration-tests/primitives/tools/list_query_run_results/filter_by_query_name/README.md @@ -0,0 +1,10 @@ +# `list_query_run_results` - filter_by_query_name + +## Purpose + +Tests the `list_query_run_results` tool with the `queryName` filter parameter. +When `CODEQL_QUERY_RUN_RESULTS_DIRS` is not set, the tool should return a +helpful message regardless of the filter value. + +This test validates that the `queryName` parameter is accepted by the tool +schema without causing a validation error. diff --git a/client/integration-tests/primitives/tools/list_query_run_results/filter_by_query_name/after/monitoring-state.json b/client/integration-tests/primitives/tools/list_query_run_results/filter_by_query_name/after/monitoring-state.json new file mode 100644 index 00000000..e1bec348 --- /dev/null +++ b/client/integration-tests/primitives/tools/list_query_run_results/filter_by_query_name/after/monitoring-state.json @@ -0,0 +1,14 @@ +{ + "sessions": [ + { + "id": "integration_test_session", + "calls": [ + { + "tool": "list_query_run_results", + "timestamp": "2025-09-25T16:06:00.000Z", + "status": "success" + } + ] + } + ] +} diff --git a/client/integration-tests/primitives/tools/list_query_run_results/filter_by_query_name/before/monitoring-state.json b/client/integration-tests/primitives/tools/list_query_run_results/filter_by_query_name/before/monitoring-state.json new file mode 100644 index 00000000..f56218ab --- /dev/null +++ b/client/integration-tests/primitives/tools/list_query_run_results/filter_by_query_name/before/monitoring-state.json @@ -0,0 +1,3 @@ +{ + "sessions": [] +} diff --git a/client/integration-tests/primitives/tools/list_query_run_results/filter_by_query_name/test-config.json b/client/integration-tests/primitives/tools/list_query_run_results/filter_by_query_name/test-config.json new file mode 100644 index 00000000..2f25eb49 --- /dev/null +++ b/client/integration-tests/primitives/tools/list_query_run_results/filter_by_query_name/test-config.json @@ -0,0 +1,6 @@ +{ + "toolName": "list_query_run_results", + "arguments": { + "queryName": "LogInjection.ql" + } +} diff --git a/docs/getting-started.md b/docs/getting-started.md index f866a2e3..000a110e 100644 --- a/docs/getting-started.md +++ b/docs/getting-started.md @@ -87,12 +87,15 @@ Add to your `mcp.json` file: ## Environment Variables -| Variable | Description | Default | -| ---------------- | -------------------------------------- | -------- | -| `CODEQL_PATH` | Absolute path to the CodeQL CLI binary | `codeql` | -| `TRANSPORT_MODE` | `stdio` or `http` | `stdio` | -| `HTTP_PORT` | HTTP port | `3000` | -| `DEBUG` | Enable debug logging | `false` | +| Variable | Description | Default | +| ------------------------------- | -------------------------------------------------------------------------- | -------- | +| `CODEQL_PATH` | Absolute path to the CodeQL CLI binary | `codeql` | +| `TRANSPORT_MODE` | `stdio` or `http` | `stdio` | +| `HTTP_PORT` | HTTP port | `3000` | +| `DEBUG` | Enable debug logging | `false` | +| `CODEQL_DATABASES_BASE_DIRS` | Colon-separated directories to search for CodeQL databases | — | +| `CODEQL_QUERY_RUN_RESULTS_DIRS` | Colon-separated directories containing per-run query result subdirectories | — | +| `CODEQL_MRVA_RUN_RESULTS_DIRS` | Colon-separated directories containing MRVA run result subdirectories | — | ## Verification diff --git a/docs/ql-mcp/tools.md b/docs/ql-mcp/tools.md index c04a9f0e..68056fa8 100644 --- a/docs/ql-mcp/tools.md +++ b/docs/ql-mcp/tools.md @@ -12,10 +12,10 @@ The server exposes **38 default tools** and **11 opt-in monitoring tools**. Defa | Tool | Description | | ----------------------------- | ---------------------------------------------------------------------------------------------------------------------------- | -| `codeql_bqrs_decode` | Decode BQRS result files to human-readable formats | -| `codeql_bqrs_info` | Get metadata and information about BQRS result files | +| `codeql_bqrs_decode` | Decode BQRS result files to human-readable formats (text, csv, json). Supports `--result-set`, `--rows` for pagination | +| `codeql_bqrs_info` | Get metadata about BQRS result files: result sets, column types, row counts. Supports `--format=json` and pagination offsets | | `codeql_bqrs_interpret` | Interpret BQRS result files according to query metadata and generate output in specified formats (CSV, SARIF, graph formats) | -| `codeql_database_analyze` | Run queries or query suites against CodeQL databases | +| `codeql_database_analyze` | Run queries or query suites against CodeQL databases. Produces evaluator logs, BQRS, and SARIF output | | `codeql_database_create` | Create a CodeQL database from source code | | `codeql_generate_log-summary` | Create a summary of a structured JSON evaluator event log file | | `codeql_generate_query-help` | Generate query help documentation from QLDoc comments | @@ -52,9 +52,9 @@ The server exposes **38 default tools** and **11 opt-in monitoring tools**. Defa | `find_class_position` | Find the start/end line and column of a class for quick evaluation | | `find_codeql_query_files` | Find and track all files and directories related to a CodeQL query, including resolved metadata | | `find_predicate_position` | Find the start/end line and column of a predicate for quick evaluation | -| `list_codeql_databases` | List CodeQL databases discovered in configured base directories (`CODEQL_DATABASES_BASE_DIRS`) | +| `list_codeql_databases` | List CodeQL databases discovered in configured base directories (`CODEQL_DATABASES_BASE_DIRS`). Filter by language | | `list_mrva_run_results` | List MRVA (Multi-Repository Variant Analysis) run results with per-repo details (`CODEQL_MRVA_RUN_RESULTS_DIRS`) | -| `list_query_run_results` | List discovered query run result directories with artifact inventory (`CODEQL_QUERY_RUN_RESULTS_DIRS`) | +| `list_query_run_results` | List query run result directories with artifact inventory. Filter by `queryName`, `language`, or `queryPath` | | `profile_codeql_query` | Profile the performance of a CodeQL query run against a specific database by analyzing the evaluator log JSON file | | `profile_codeql_query_from_logs` | Parse existing CodeQL evaluator logs into a performance profile without re-running the query | | `quick_evaluate` | Quick evaluate either a class or a predicate in a CodeQL query for debugging | diff --git a/docs/vscode/IMPLEMENTATION.md b/docs/vscode/IMPLEMENTATION.md deleted file mode 100644 index 8d1887cc..00000000 --- a/docs/vscode/IMPLEMENTATION.md +++ /dev/null @@ -1,312 +0,0 @@ -# VS Code Extension — Implementation Tracker - -> Tracks the implementation and testing of new features that integrate the -> `codeql-development-mcp-server` with the `github.vscode-codeql` extension. - -## Branch - -`dd/vscode-extension/1` (base: `main`) - -## Completed on Branch - -The initial commit (`9ea4b14`) adds: - -- **VS Code extension** (`extensions/vscode/`) — registers the MCP server, - discovers the CodeQL CLI, installs tool query packs, and bridges the - vscode-codeql extension (database/query-results watchers). -- **Server: `list_codeql_databases` tool** — discovers databases from - `CODEQL_DATABASES_BASE_DIRS`. -- **Server: `list_query_run_results` tool** — discovers query run result - directories from `CODEQL_QUERY_RUN_RESULTS_DIRS`. -- **Server: `discovery-config` module** — parses colon-separated env var - directory lists. -- Docs: `docs/vscode/extension.md`, updated `docs/ql-mcp/tools.md`. - ---- - -## TODO 1: `list_mrva_run_results` Tool - -**Status:** Not started - -### Purpose - -List available MRVA (Multi-Repository Variant Analysis) run results stored by -the vscode-codeql extension. - -### Directory Structure (observed) - -``` -~/Library/Application Support/Code/User/globalStorage/github.vscode-codeql/variant-analyses/ -├── 20438/ -│ └── timestamp -├── 20439/ -│ └── timestamp -├── 20440/ -│ ├── repo_states.json -│ └── timestamp -├── 20442/ -│ ├── repo_states.json -│ ├── timestamp -│ ├── arduino/Arduino/ -│ │ ├── repo_task.json # VariantAnalysisRepositoryTask -│ │ ├── results.zip -│ │ └── results/ -│ │ ├── results.sarif -│ │ └── results.bqrs -│ └── exported-results/ -│ └── results_/ -│ ├── _summary.md -│ └── -.md -``` - -### `repo_task.json` Schema - -```json -{ - "repository": { "id": 919161, "fullName": "arduino/Arduino", "private": false }, - "analysisStatus": "succeeded", - "resultCount": 1, - "artifactSizeInBytes": 14311, - "databaseCommitSha": "a0df6e0...", - "sourceLocationPrefix": "/home/runner/work/Arduino/Arduino", - "artifactUrl": "https://..." -} -``` - -### `repo_states.json` Schema - -```json -{ - "": { - "repositoryId": 919161, - "downloadStatus": "succeeded" - } -} -``` - -### Implementation Plan - -1. **`server/src/lib/discovery-config.ts`** — add `getMrvaRunResultsDirs()` - reading from `CODEQL_MRVA_RUN_RESULTS_DIRS` env var. -2. **`server/src/tools/codeql/list-mrva-run-results.ts`** — new tool that: - - Scans each dir in `CODEQL_MRVA_RUN_RESULTS_DIRS` for numeric - subdirectories (the MRVA run ID). - - For each run, reads `repo_states.json` and enumerates - `//repo_task.json` entries. - - Reports: run ID, timestamp, number of repos scanned, per-repo status, - result counts, available artifacts (SARIF, BQRS). - - Supports optional filtering by run ID. -3. **`server/src/tools/codeql/index.ts`** — export the new registration fn. -4. **`server/src/tools/codeql-tools.ts`** — register the new tool. -5. **`extensions/vscode/src/bridge/environment-builder.ts`** — set - `CODEQL_MRVA_RUN_RESULTS_DIRS` to `storagePaths.getVariantAnalysisStoragePath()`. -6. **Unit tests:** `server/test/src/tools/codeql/list-mrva-run-results.test.ts` - and `server/test/src/lib/discovery-config.test.ts` (extend). -7. **Client integration tests:** - `client/integration-tests/primitives/tools/list_mrva_run_results/`. - -### Acceptance Criteria - -- [ ] Tool returns structured list of MRVA runs with repo details. -- [ ] Tool handles: empty dirs, missing `repo_states.json`, partial downloads. -- [ ] VS Code extension automatically sets the env var. -- [ ] Unit tests pass. -- [ ] Client integration tests pass. - ---- - -## TODO 2: `profile_codeql_query_from_logs` Tool - -**Status:** Not started - -### Purpose - -Parse CodeQL query evaluation logs into a performance profile, without -requiring re-execution of the query. Works with logs from: - -- `codeql query run` (single query → single QUERY_STARTED/COMPLETED) -- `codeql database analyze` (multiple queries → multiple QUERY_STARTED/COMPLETED) -- vscode-codeql query runs (stored under `CODEQL_QUERY_RUN_RESULTS_DIRS`) - -### Evaluator Log Format (`evaluator-log.jsonl`) - -Pretty-printed JSON objects separated by `}\n{`. Event types observed: - -| Event Type | Single Query | Multi Query | Description | -| --------------------- | ------------ | ----------- | ---------------------------------- | -| `LOG_HEADER` | 1 | 1 | Version info, start time | -| `QUERY_STARTED` | 1 | N | Query name, eventId | -| `PREDICATE_STARTED` | many | many | Has `queryCausingWork` → eventId | -| `PREDICATE_COMPLETED` | many | many | `startEvent`, duration, resultSize | -| `PIPELINE_STARTED` | many | many | `predicateStartEvent`, raReference | -| `PIPELINE_COMPLETED` | many | many | Mirrors PIPELINE_STARTED | -| `CACHE_LOOKUP` | some | some | Cache hits | -| `SENTINEL_EMPTY` | many | many | Empty predicate evaluations | -| `QUERY_COMPLETED` | 1 | N | `startEvent` → query eventId | -| `LOG_FOOTER` | 1 | 1 | End marker | - -**Key multi-query insight:** Each `PREDICATE_STARTED` event has -`queryCausingWork` referencing the `eventId` of the `QUERY_STARTED` event that -triggered it. This allows grouping predicates by query in `database analyze` -logs. - -### vscode-codeql Generated Files Per Query Run - -| File | Size | Purpose | -| ------------------------------------ | -------- | ---------------------------- | -| `evaluator-log.jsonl` | ~13-80MB | Raw structured evaluator log | -| `evaluator-log.summary` | ~23MB | Human-readable summary | -| `evaluator-log.summary.jsonl` | ~18MB | Machine-readable summary | -| `evaluator-log.summary.map` | ~1MB | Source mapping | -| `evaluator-log.summary.symbols.json` | ~1.6MB | Symbol metadata | -| `evaluator-log-end.summary` | ~61KB | End-of-evaluation summary | -| `query.log` | ~7.6MB | Full query server log | -| `results.bqrs` | varies | Binary query results | -| `results-interpreted.sarif` | varies | Interpreted SARIF results | -| `results.dil` | ~26MB | DIL representation | -| `timestamp` | 13B | ISO timestamp | - -### `evaluator-log.summary.jsonl` Format - -Unlike the raw log, the summary uses **different key sets** per event type -(no `type` field). Key patterns: - -1. **Header**: `{ summaryLogVersion, codeqlVersion, startTime }` -2. **Sentinel empty**: `{ completionTime, raHash, predicateName, appearsAs, -evaluationStrategy: "SENTINEL_EMPTY", sentinelRaHash, isCached? }` -3. **Computed predicate**: `{ completionTime, raHash, predicateName, appearsAs, -evaluationStrategy, dependencies, millis, pipelineRuns, position?, -queryCausingWork, ra, resultSize }` -4. **Recursive predicate**: additionally has `deltaSizes, layerSize, -predicateIterationMillis, mainHash` - -### Implementation Plan - -1. **`server/src/lib/evaluator-log-parser.ts`** — reusable streaming parser: - - `parseEvaluatorLogStreaming(logPath, callback)` — stream-parses raw - `evaluator-log.jsonl` using readline + brace-depth tracking. - - `parseEvaluatorLogSummary(logPath, callback)` — stream-parses - `evaluator-log.summary.jsonl`. - - Shared `ProfileData` interface with per-query breakdown. -2. **`server/src/tools/codeql/profile-codeql-query-from-logs.ts`** — new tool: - - Input: `evaluatorLog` (path to `evaluator-log.jsonl` or - `evaluator-log.summary.jsonl`) + optional `outputDir`. - - Auto-detects format (raw vs summary) from the first event. - - Produces `ProfileData` with: - - Per-query breakdown (for multi-query logs). - - Top-N most expensive predicates. - - Total duration, pipeline counts, cache hit rates. - - Outputs JSON profile + optional Mermaid diagram. - - Works with logs from any source: query runs, database analyze, - vscode-codeql query history. -3. **`server/src/tools/codeql/index.ts`** — export new registration fn. -4. **`server/src/tools/codeql-tools.ts`** — register the new tool. -5. **Unit tests:** `server/test/src/lib/evaluator-log-parser.test.ts` and - `server/test/src/tools/codeql/profile-codeql-query-from-logs.test.ts`. -6. **Client integration tests:** - `client/integration-tests/primitives/tools/profile_codeql_query_from_logs/`. - -### Acceptance Criteria - -- [ ] Parses single-query `evaluator-log.jsonl` (from `codeql query run`). -- [ ] Parses multi-query `evaluator-log.jsonl` (from `codeql database analyze`). -- [ ] Parses `evaluator-log.summary.jsonl` (from vscode-codeql query history). -- [ ] Produces per-query profiling breakdown for multi-query logs. -- [ ] Reports top-N most expensive predicates with durations. -- [ ] Handles large logs (80MB+) without excessive memory usage. -- [ ] Unit tests pass. -- [ ] Client integration tests pass. - ---- - -## TODO 3: Enhance `codeql_query_run` and `codeql_database_analyze` Logging - -**Status:** Not started - -### Purpose - -Both tools should always produce the full set of log files that vscode-codeql -generates per query run, so that `profile_codeql_query_from_logs` can analyze -any run without special setup. This will allow deprecating and eventually -removing the `profile_codeql_query` tool. - -### Current State - -**`codeql_query_run`** already: - -- Sets `--evaluator-log` to the log directory ✓ -- Sets `--output` for BQRS ✓ -- Generates SARIF interpretation post-run ✓ -- Creates a `timestamp` file ✓ -- Uses `--logdir` and `--verbosity=progress+` ✓ -- Uses `timeout: 0` (no timeout) via FRESH_PROCESS_SUBCOMMANDS ✓ - -**Missing for `codeql_query_run`:** - -- Does NOT run `codeql generate log-summary` to produce summary files. -- Does NOT enable `--tuple-counting` by default when evaluator logging is on. - -**`codeql_database_analyze`** currently: - -- Has NO log directory setup ✗ -- Does NOT set `--evaluator-log` automatically ✗ -- Does NOT generate summary files ✗ -- Does NOT create a timestamp ✗ -- Does NOT have a `logDir` parameter ✗ -- Uses `timeout: 0` via FRESH_PROCESS_SUBCOMMANDS ✓ - -### Implementation Plan - -1. **`server/src/tools/codeql/database-analyze.ts`** — add `logDir` parameter - and `evaluator-log` / `tuple-counting` / `evaluator-log-level` options to - the input schema. -2. **`server/src/lib/cli-tool-registry.ts`** — in the `registerCLITool`: - - Add `codeql_database_analyze` alongside `codeql_query_run` in the log - directory setup block (set `--evaluator-log`, `--logdir`, `timestamp`, - `--verbosity`). - - For both tools, after successful execution, run - `codeql generate log-summary --format=jsonl` piping the raw evaluator log - to produce `evaluator-log.summary.jsonl`. - - Enable `--tuple-counting` by default when evaluator logging is active. -3. **Update unit tests** for the modified tools. - -### Acceptance Criteria - -- [ ] `codeql_query_run` produces: `evaluator-log.jsonl`, - `evaluator-log.summary.jsonl`, `results.bqrs`, `results-interpreted.sarif`, - `timestamp`. -- [ ] `codeql_database_analyze` produces the same set of log files. -- [ ] `--tuple-counting` is enabled by default for both tools. -- [ ] Logs are discoverable by `list_query_run_results`. -- [ ] Unit tests pass. - ---- - -## TODO 4: VS Code Extension Updates - -**Status:** Not started - -### `environment-builder.ts` Changes - -- Set `CODEQL_DATABASES_BASE_DIRS` from database storage path. -- Set `CODEQL_QUERY_RUN_RESULTS_DIRS` → `storagePaths.getQueryStoragePath()` -- Set `CODEQL_MRVA_RUN_RESULTS_DIRS` → `storagePaths.getVariantAnalysisStoragePath()` - -### Documentation Updates - -- `docs/ql-mcp/tools.md` — add `list_mrva_run_results` and - `profile_codeql_query_from_logs` to tool tables. -- `docs/vscode/extension.md` — document the new env vars and discovery. - ---- - -## Test Data - -Fresh evaluator logs generated for testing: - -| Log | Location | Queries | Size | -| --------------------------------------- | --------------------------------------------------------------- | ---------------------------- | ---- | -| Single query (`codeql query run`) | `.tmp/logs-query-run/evaluator-log.jsonl` | 1 (ListRemoteFlowSources.ql) | 13MB | -| Multi query (`codeql database analyze`) | `.tmp/logs-db-analyze/evaluator-log.jsonl` | 10 (UI5 pack) | 79MB | -| vscode-codeql query run | `~/Library/.../queries/UI5Xss.ql-*/evaluator-log.jsonl` | 1 | 30MB | -| vscode-codeql query run | `~/Library/.../queries/UI5Xss.ql-*/evaluator-log.summary.jsonl` | 1 | 18MB | diff --git a/docs/vscode/extension.md b/docs/vscode/extension.md index 03421d58..eb172611 100644 --- a/docs/vscode/extension.md +++ b/docs/vscode/extension.md @@ -41,6 +41,8 @@ On activation the extension: created by the CodeQL extension and passes their locations to the MCP server via environment variables: - `CODEQL_ADDITIONAL_PACKS` — workspace folders and vscode-codeql database storage + - `CODEQL_DATABASES_BASE_DIRS` — vscode-codeql database storage directory + (enables `list_codeql_databases`) - `CODEQL_QUERY_RUN_RESULTS_DIRS` — vscode-codeql query result directories (enables `list_query_run_results` and `profile_codeql_query_from_logs`) - `CODEQL_MRVA_RUN_RESULTS_DIRS` — vscode-codeql variant analysis result diff --git a/server/dist/codeql-development-mcp-server.js b/server/dist/codeql-development-mcp-server.js index d7d03d53..4e62510d 100755 --- a/server/dist/codeql-development-mcp-server.js +++ b/server/dist/codeql-development-mcp-server.js @@ -2063,7 +2063,7 @@ function registerCLITool(server, definition) { const tempDirsToCleanup = []; try { logger.info(`Executing CLI tool: ${name}`, { command, subcommand, params }); - const formatShouldBePassedToCLI = name === "codeql_bqrs_interpret" || name === "codeql_bqrs_decode" || name === "codeql_generate_query-help" || name === "codeql_database_analyze"; + const formatShouldBePassedToCLI = name === "codeql_bqrs_interpret" || name === "codeql_bqrs_decode" || name === "codeql_bqrs_info" || name === "codeql_generate_query-help" || name === "codeql_database_analyze"; const extractedParams = formatShouldBePassedToCLI ? { _positional: params._positional || [], files: params.files, @@ -2284,6 +2284,10 @@ function registerCLITool(server, definition) { options.output = join5(queryLogDir, "results.bqrs"); } } + if (options.output && typeof options.output === "string") { + const outputDir = dirname4(options.output); + mkdirSync5(outputDir, { recursive: true }); + } } let result; if (command === "codeql") { @@ -2308,20 +2312,27 @@ function registerCLITool(server, definition) { } if (name === "codeql_query_run" && result.success && queryLogDir) { const bqrsPath = options.output; - const sarifPath = join5(queryLogDir, "results.sarif"); - if (existsSync4(bqrsPath)) { + const sarifPath = join5(queryLogDir, "results-interpreted.sarif"); + const queryFilePath = positionalArgs.length > 0 ? positionalArgs[positionalArgs.length - 1] : void 0; + if (existsSync4(bqrsPath) && queryFilePath) { try { - const sarifResult = await executeCodeQLCommand( - "bqrs interpret", - { format: "sarif-latest", output: sarifPath }, - [bqrsPath] + const sarifResult = await interpretBQRSFile( + bqrsPath, + queryFilePath, + "sarif-latest", + sarifPath, + logger ); if (sarifResult.success) { logger.info(`Generated SARIF interpretation at ${sarifPath}`); + } else { + logger.warn(`SARIF interpretation returned error: ${sarifResult.error || sarifResult.stderr}`); } } catch (error) { logger.warn(`Failed to generate SARIF interpretation: ${error}`); } + } else if (existsSync4(bqrsPath) && !queryFilePath) { + logger.warn("Skipping SARIF interpretation: query file path not available"); } result = await processQueryRunResults(result, params, logger); } @@ -2658,22 +2669,28 @@ Warning: Query processing error - ${error}` // src/tools/codeql/bqrs-decode.ts var codeqlBqrsDecodeTool = { name: "codeql_bqrs_decode", - description: "Decode BQRS result files to human-readable formats", + description: "Decode BQRS result files to human-readable formats (text, csv, json). Typical workflow: (1) use list_query_run_results to find BQRS paths from previous codeql_query_run or codeql_database_analyze runs, (2) use codeql_bqrs_info to discover result sets and column schemas, (3) decode specific result sets with this tool. For large result sets, use --rows to paginate.", command: "codeql", subcommand: "bqrs decode", inputSchema: { files: z2.array(z2.string()).describe("BQRS file(s) to decode"), output: createCodeQLSchemas.output(), - format: z2.enum(["csv", "json"]).optional().describe("Output format"), - "max-paths": z2.number().optional().describe("Maximum number of paths to output"), - "start-at": z2.number().optional().describe("Start output at result number"), - "max-results": z2.number().optional().describe("Maximum number of results"), + format: z2.enum(["csv", "json", "text", "bqrs"]).optional().describe("Output format: text (human-readable table, default), csv, json (streaming JSON), or bqrs (binary, requires --output)"), + "result-set": z2.string().optional().describe("Decode a specific result set by name (use codeql_bqrs_info to list available sets). If omitted, all result sets are decoded."), + "sort-key": z2.string().optional().describe("Sort by column(s): comma-separated column indices (0-based)"), + "sort-direction": z2.string().optional().describe('Sort direction(s): comma-separated "asc" or "desc" per column'), + "no-titles": z2.boolean().optional().describe("Omit column titles for text and csv formats"), + entities: z2.string().optional().describe("Control entity column display: comma-separated list of url, string, id, all"), + rows: z2.number().optional().describe("Maximum number of rows to output (for pagination). Use with --start-at for paging."), + "start-at": z2.number().optional().describe('Byte offset to start decoding from (get from codeql_bqrs_info or previous JSON output "next" pointer). Must be used with --rows.'), verbose: createCodeQLSchemas.verbose(), additionalArgs: createCodeQLSchemas.additionalArgs() }, examples: [ "codeql bqrs decode --format=csv --output=results.csv results.bqrs", - "codeql bqrs decode --format=json --max-results=100 results.bqrs" + "codeql bqrs decode --format=json --rows=100 results.bqrs", + "codeql bqrs decode --result-set=#select --format=csv results.bqrs", + "codeql bqrs decode --format=json --entities=url,string results.bqrs" ], resultProcessor: createBQRSResultProcessor() }; @@ -2682,17 +2699,21 @@ var codeqlBqrsDecodeTool = { import { z as z3 } from "zod"; var codeqlBqrsInfoTool = { name: "codeql_bqrs_info", - description: "Get metadata and information about BQRS result files", + description: 'Get metadata about BQRS result files: lists result sets, column names/types, and row counts. Use before codeql_bqrs_decode to discover available result sets (e.g., "#select", "edges", "nodes"). BQRS files are found at /results.bqrs \u2014 use list_query_run_results to discover them. Use --format=json with --paginate-rows to get byte offsets for paginated decoding with codeql_bqrs_decode --start-at.', command: "codeql", subcommand: "bqrs info", inputSchema: { files: z3.array(z3.string()).describe("BQRS file(s) to examine"), + format: z3.enum(["text", "json"]).optional().describe("Output format: text (default) or json. Use json for machine-readable output and pagination offset computation."), + "paginate-rows": z3.number().optional().describe("Compute byte offsets for pagination at intervals of this many rows. Use with --format=json. Offsets can be passed to codeql_bqrs_decode --start-at."), + "paginate-result-set": z3.string().optional().describe("Compute pagination offsets only for this result set name"), verbose: createCodeQLSchemas.verbose(), additionalArgs: createCodeQLSchemas.additionalArgs() }, examples: [ "codeql bqrs info results.bqrs", - "codeql bqrs info --verbose results.bqrs" + "codeql bqrs info --format=json results.bqrs", + "codeql bqrs info --format=json --paginate-rows=100 --paginate-result-set=#select results.bqrs" ], resultProcessor: createBQRSResultProcessor() }; @@ -2737,7 +2758,7 @@ var codeqlBqrsInterpretTool = { import { z as z5 } from "zod"; var codeqlDatabaseAnalyzeTool = { name: "codeql_database_analyze", - description: "Run queries or query suites against CodeQL databases", + description: "Run queries or query suites against CodeQL databases. Produces evaluator logs, BQRS results, and optionally SARIF output. Use list_codeql_databases to discover available databases, and register_database to register new ones. After analysis completes, use list_query_run_results to find result artifacts, then codeql_bqrs_info and codeql_bqrs_decode to inspect results.", command: "codeql", subcommand: "database analyze", inputSchema: { @@ -2753,13 +2774,14 @@ var codeqlDatabaseAnalyzeTool = { "evaluator-log": z5.string().optional().describe("Path to save evaluator log. If not provided and logDir is set, defaults to /evaluator-log.jsonl"), "tuple-counting": z5.boolean().optional().describe("Display tuple counts for each evaluation step in evaluator logs"), "evaluator-log-level": z5.number().min(1).max(5).optional().describe("Evaluator log verbosity level (1-5, default 5)"), + rerun: z5.boolean().optional().describe("Force re-evaluation of queries even if BQRS results already exist in the database. Without this, cached results are reused."), verbose: z5.boolean().optional().describe("Enable verbose output"), additionalArgs: z5.array(z5.string()).optional().describe("Additional command-line arguments") }, examples: [ "codeql database analyze mydb queries.qls --format=sarif-latest --output=results.sarif", "codeql database analyze mydb codeql/java-queries --format=csv", - "codeql database analyze mydb queries.qls --format=sarif-latest --output=results.sarif --log-dir=/path/to/logs --tuple-counting" + "codeql database analyze mydb queries.qls --format=sarif-latest --output=results.sarif --rerun --tuple-counting" ] }; @@ -5938,7 +5960,7 @@ async function discoverDatabases(baseDirs, language) { function registerListDatabasesTool(server) { server.tool( "list_codeql_databases", - "List CodeQL databases discovered in configured base directories (set via CODEQL_DATABASES_BASE_DIRS env var). Returns path, language, CLI version, and creation time for each database.", + "List CodeQL databases discovered in configured base directories (set via CODEQL_DATABASES_BASE_DIRS env var). Returns path, language, CLI version, and creation time for each database. Use the returned database paths with codeql_query_run or codeql_database_analyze to run queries against them.", { language: z12.string().optional().describe('Filter databases by language (e.g., "javascript", "python")') }, @@ -6192,7 +6214,37 @@ import { join as join9 } from "path"; import { z as z14 } from "zod"; init_logger(); var QUERY_RUN_DIR_PATTERN = /^(.+\.ql)-(.+)$/; -async function discoverQueryRunResults(resultsDirs, queryName) { +var RUN_QUERY_PATTERN = /runQuery called with\s+(\S+)/; +var DBSCHEME_DB_PATH_PATTERN = /--dbscheme=(.+?)\/db-(\w+)\//; +var DBSCHEME_LANGUAGE_PATTERN = /semmlecode\.(\w+)\.dbscheme/; +var QLPACK_LANGUAGE_PATTERN = /codeql\/(\w+)-all\//; +function parseQueryLogMetadata(logContent) { + const metadata = {}; + const runQueryMatch = RUN_QUERY_PATTERN.exec(logContent); + if (runQueryMatch) { + metadata.queryPath = runQueryMatch[1]; + } + const dbPathMatch = DBSCHEME_DB_PATH_PATTERN.exec(logContent); + if (dbPathMatch) { + metadata.databasePath = dbPathMatch[1]; + metadata.language = dbPathMatch[2]; + } + if (!metadata.language) { + const langMatch = DBSCHEME_LANGUAGE_PATTERN.exec(logContent); + if (langMatch) { + metadata.language = langMatch[1]; + } + } + if (!metadata.language) { + const packMatch = QLPACK_LANGUAGE_PATTERN.exec(logContent); + if (packMatch) { + metadata.language = packMatch[1]; + } + } + return metadata; +} +async function discoverQueryRunResults(resultsDirs, filter) { + const normalizedFilter = typeof filter === "string" ? { queryName: filter } : filter; const results = []; for (const dir of resultsDirs) { if (!existsSync8(dir)) { @@ -6218,12 +6270,14 @@ async function discoverQueryRunResults(resultsDirs, queryName) { continue; } const [, name, runId] = match; - if (queryName && name !== queryName) { + if (normalizedFilter?.queryName && name !== normalizedFilter.queryName) { continue; } const hasEvaluatorLog = existsSync8(join9(entryPath, "evaluator-log.jsonl")); const hasBqrs = existsSync8(join9(entryPath, "results.bqrs")); const hasSarif = existsSync8(join9(entryPath, "results-interpreted.sarif")); + const hasQueryLog = existsSync8(join9(entryPath, "query.log")); + const hasSummaryLog = existsSync8(join9(entryPath, "evaluator-log.summary.jsonl")); let timestamp2; const timestampPath = join9(entryPath, "timestamp"); if (existsSync8(timestampPath)) { @@ -6232,12 +6286,44 @@ async function discoverQueryRunResults(resultsDirs, queryName) { } catch { } } + let metadata = {}; + if (hasQueryLog) { + try { + const logContent = readFileSync6(join9(entryPath, "query.log"), "utf-8"); + metadata = parseQueryLogMetadata(logContent); + } catch { + } + } + if (normalizedFilter?.language && metadata.language !== normalizedFilter.language) { + continue; + } + if (normalizedFilter?.queryPath) { + if (!metadata.queryPath) { + continue; + } + const filterPath = normalizedFilter.queryPath; + const isExact = filterPath.startsWith("/"); + if (isExact) { + if (metadata.queryPath !== filterPath) { + continue; + } + } else { + if (!metadata.queryPath.toLowerCase().includes(filterPath.toLowerCase())) { + continue; + } + } + } results.push({ + databasePath: metadata.databasePath, hasBqrs, hasEvaluatorLog, + hasQueryLog, hasSarif, + hasSummaryLog, + language: metadata.language, path: entryPath, queryName: name, + queryPath: metadata.queryPath, runId, timestamp: timestamp2 }); @@ -6248,11 +6334,17 @@ async function discoverQueryRunResults(resultsDirs, queryName) { function registerListQueryRunResultsTool(server) { server.tool( "list_query_run_results", - "List discovered query run result directories (set via CODEQL_QUERY_RUN_RESULTS_DIRS env var). Returns path, query name, timestamp, and available artifacts for each run.", + "List discovered query run result directories (set via CODEQL_QUERY_RUN_RESULTS_DIRS env var). Returns path, query name, timestamp, language, query file path, and available artifacts (evaluator-log, bqrs, sarif, query.log, summary) for each run. Filter by queryName, language, or queryPath to narrow results. Use the returned BQRS paths with codeql_bqrs_decode or codeql_bqrs_info to inspect query results.", { - queryName: z14.string().optional().describe('Filter results by query name (e.g., "UI5Xss.ql")') + language: z14.string().optional().describe( + 'Filter by CodeQL language (e.g., "javascript", "python", "java"). Extracted from the database path in query.log. Runs without a query.log are excluded when this filter is set.' + ), + queryName: z14.string().optional().describe('Filter results by query name (e.g., "UI5Xss.ql")'), + queryPath: z14.string().optional().describe( + "Filter by query file path. Absolute paths match exactly; relative paths/substrings match case-insensitively. Requires query.log to be present." + ) }, - async ({ queryName }) => { + async ({ language, queryName, queryPath }) => { try { const resultsDirs = getQueryRunResultsDirs(); if (resultsDirs.length === 0) { @@ -6265,9 +6357,20 @@ function registerListQueryRunResultsTool(server) { ] }; } - const runs = await discoverQueryRunResults(resultsDirs, queryName); + const filter = {}; + if (queryName) filter.queryName = queryName; + if (language) filter.language = language; + if (queryPath) filter.queryPath = queryPath; + const runs = await discoverQueryRunResults( + resultsDirs, + Object.keys(filter).length > 0 ? filter : void 0 + ); if (runs.length === 0) { - const filterMsg = queryName ? ` for query "${queryName}"` : ""; + const filterParts = []; + if (queryName) filterParts.push(`query "${queryName}"`); + if (language) filterParts.push(`language "${language}"`); + if (queryPath) filterParts.push(`path "${queryPath}"`); + const filterMsg = filterParts.length > 0 ? ` for ${filterParts.join(", ")}` : ""; return { content: [ { @@ -6283,12 +6386,18 @@ function registerListQueryRunResultsTool(server) { ...runs.map((run) => { const artifacts = []; if (run.hasEvaluatorLog) artifacts.push("evaluator-log"); + if (run.hasSummaryLog) artifacts.push("summary-log"); if (run.hasBqrs) artifacts.push("bqrs"); if (run.hasSarif) artifacts.push("sarif"); + if (run.hasQueryLog) artifacts.push("query-log"); const parts = [` ${run.queryName} (${run.runId})`]; parts.push(` Path: ${run.path}`); if (run.timestamp) parts.push(` Timestamp: ${run.timestamp}`); + if (run.language) parts.push(` Language: ${run.language}`); + if (run.queryPath) parts.push(` Query: ${run.queryPath}`); + if (run.databasePath) parts.push(` Database: ${run.databasePath}`); parts.push(` Artifacts: ${artifacts.length > 0 ? artifacts.join(", ") : "none"}`); + if (run.hasBqrs) parts.push(` BQRS: ${join9(run.path, "results.bqrs")}`); return parts.join("\n"); }) ]; @@ -7114,7 +7223,7 @@ var codeqlQueryFormatTool = { import { z as z21 } from "zod"; var codeqlQueryRunTool = { name: "codeql_query_run", - description: 'Execute a CodeQL query against a database. Use either "query" parameter for direct file path OR "queryName" + "queryLanguage" for pre-defined tool queries.', + description: 'Execute a CodeQL query against a database. Use either "query" parameter for direct file path OR "queryName" + "queryLanguage" for pre-defined tool queries. Produces evaluator logs and BQRS results in a log directory. Use list_codeql_databases to discover databases, list_query_run_results to find previous results, and codeql_bqrs_decode to inspect BQRS output.', command: "codeql", subcommand: "query run", inputSchema: { diff --git a/server/dist/codeql-development-mcp-server.js.map b/server/dist/codeql-development-mcp-server.js.map index 8e56f45d..d7719e6e 100644 --- a/server/dist/codeql-development-mcp-server.js.map +++ b/server/dist/codeql-development-mcp-server.js.map @@ -1,7 +1,7 @@ { "version": 3, "sources": ["../src/utils/logger.ts", "../src/lib/server-config.ts", "../src/utils/package-paths.ts", "../src/utils/temp-dir.ts", "../src/utils/process-ready.ts", "../src/lib/language-server.ts", "../src/lib/query-server.ts", "../src/lib/cli-server.ts", "../src/lib/server-manager.ts", "../src/lib/cli-executor.ts", "../src/codeql-development-mcp-server.ts", "../src/tools/codeql/bqrs-decode.ts", "../src/lib/cli-tool-registry.ts", "../src/lib/query-results-evaluator.ts", "../src/lib/log-directory-manager.ts", "../src/tools/codeql/bqrs-info.ts", "../src/tools/codeql/bqrs-interpret.ts", "../src/tools/codeql/database-analyze.ts", "../src/tools/codeql/database-create.ts", "../src/tools/codeql/find-class-position.ts", "../src/tools/codeql/find-predicate-position.ts", "../src/tools/codeql/find-query-files.ts", "../src/lib/query-file-finder.ts", "../../node_modules/js-yaml/dist/js-yaml.mjs", "../src/lib/metadata-resolver.ts", "../src/tools/codeql/generate-log-summary.ts", "../src/tools/codeql/generate-query-help.ts", "../src/tools/codeql/list-databases.ts", "../src/lib/discovery-config.ts", "../src/tools/codeql/list-mrva-run-results.ts", "../src/tools/codeql/list-query-run-results.ts", "../src/tools/codeql/pack-install.ts", "../src/tools/codeql/pack-ls.ts", "../src/tools/codeql/profile-codeql-query-from-logs.ts", "../src/lib/evaluator-log-parser.ts", "../src/tools/codeql/profile-codeql-query.ts", "../src/tools/codeql/query-compile.ts", "../src/tools/codeql/query-format.ts", "../src/tools/codeql/query-run.ts", "../src/tools/codeql/quick-evaluate.ts", "../src/tools/codeql/register-database.ts", "../src/tools/codeql/resolve-database.ts", "../src/tools/codeql/resolve-languages.ts", "../src/tools/codeql/resolve-library-path.ts", "../src/tools/codeql/resolve-metadata.ts", "../src/tools/codeql/resolve-qlref.ts", "../src/tools/codeql/resolve-queries.ts", "../src/tools/codeql/resolve-tests.ts", "../src/tools/codeql/test-accept.ts", "../src/tools/codeql/test-extract.ts", "../src/tools/codeql/test-run.ts", "../src/tools/codeql-tools.ts", "../src/lib/validation.ts", "../src/lib/query-scaffolding.ts", "../src/lib/resources.ts", "../src/tools/codeql-resources.ts", "../src/tools/lsp/lsp-diagnostics.ts", "../src/tools/lsp/lsp-server-helper.ts", "../src/tools/lsp/lsp-handlers.ts", "../src/tools/lsp/lsp-tools.ts", "../src/resources/language-resources.ts", "../src/types/language-types.ts", "../src/prompts/workflow-prompts.ts", "../src/prompts/prompt-loader.ts", "../src/tools/monitoring-tools.ts", "../../node_modules/lowdb/lib/core/Low.js", "../../node_modules/lowdb/lib/adapters/node/TextFile.js", "../../node_modules/lowdb/lib/adapters/node/DataFile.js", "../../node_modules/lowdb/lib/adapters/node/JSONFile.js", "../src/lib/session-data-manager.ts", "../src/types/monitoring.ts"], - "sourcesContent": ["/**\n * Simple logger utility.\n *\n * All log output is written to stderr. In stdio transport mode, stdout is\n * reserved exclusively for the MCP JSON-RPC protocol \u2014 any non-protocol\n * bytes on stdout would corrupt the message stream.\n */\nexport const logger = {\n info: (message: string, ...args: unknown[]) => {\n console.error(`[INFO] ${new Date().toISOString()} ${message}`, ...args);\n },\n error: (message: string, ...args: unknown[]) => {\n console.error(`[ERROR] ${new Date().toISOString()} ${message}`, ...args);\n },\n warn: (message: string, ...args: unknown[]) => {\n console.error(`[WARN] ${new Date().toISOString()} ${message}`, ...args);\n },\n debug: (message: string, ...args: unknown[]) => {\n if (process.env.DEBUG) {\n console.error(`[DEBUG] ${new Date().toISOString()} ${message}`, ...args);\n }\n },\n};\n", "/**\n * Configuration types for CodeQL background server processes.\n *\n * CodeQL provides three background server types:\n * 1. language-server \u2013 LSP-based QL validation (JSON-RPC over stdio)\n * 2. query-server2 \u2013 Query evaluation (custom protocol over stdio)\n * 3. cli-server \u2013 JVM reuse for CLI commands (custom protocol over stdio)\n *\n * Each server type has its own configuration options, but they share common\n * settings like searchPath and commonCaches.\n */\n\nimport { createHash } from 'crypto';\n\n/**\n * Server types supported by CodeQL.\n */\nexport type CodeQLServerType = 'cli' | 'language' | 'query';\n\n/**\n * Common configuration shared across all server types.\n */\nexport interface BaseServerConfig {\n /** Path to QL packs (like `codeql query compile --search-path`). */\n searchPath?: string;\n /** Location for cached data (compilation plans, downloaded packs). */\n commonCaches?: string;\n /** Directory for detailed logs. */\n logdir?: string;\n}\n\n/**\n * Configuration for the CodeQL Language Server.\n */\nexport interface LanguageServerConfig extends BaseServerConfig {\n /** Error checking mode. Default: ON_CHANGE */\n checkErrors?: 'EXPLICIT' | 'ON_CHANGE';\n /** Log level for the language server. */\n loglevel?: 'ALL' | 'DEBUG' | 'ERROR' | 'INFO' | 'OFF' | 'TRACE' | 'WARN';\n /** Single-threaded execution. */\n synchronous?: boolean;\n /** Verbosity level for progress. */\n verbosity?: 'errors' | 'progress' | 'progress+' | 'progress++' | 'progress+++' | 'warnings';\n}\n\n/**\n * Configuration for the CodeQL Query Server (query-server2).\n */\nexport interface QueryServerConfig extends BaseServerConfig {\n /** Thread count. 0 = one per core, -N = leave N cores free. */\n threads?: number;\n /** Query evaluation timeout in seconds. */\n timeout?: number;\n /** Maximum disk cache size in MB for intermediate results. */\n maxDiskCache?: number;\n /** Path for structured evaluator performance logs. */\n evaluatorLog?: string;\n /** Include tuple counts in evaluation logs. */\n tupleCounting?: boolean;\n /** Enable debug mode. */\n debug?: boolean;\n}\n\n/**\n * Configuration for the CodeQL CLI Server.\n */\nexport interface CLIServerConfig extends BaseServerConfig {\n // cli-server has fewer options \u2014 just commonCaches and logdir.\n}\n\n/**\n * Union of all server configurations (discriminated by usage context).\n */\nexport type ServerConfig = CLIServerConfig | LanguageServerConfig | QueryServerConfig;\n\n/**\n * Compute a deterministic hash for a server configuration.\n * Used to detect configuration changes that require a server restart.\n *\n * @param type - The server type.\n * @param config - The server configuration.\n * @returns A hex-encoded SHA-256 hash of the canonical JSON representation.\n */\nexport function computeConfigHash(type: CodeQLServerType, config: ServerConfig): string {\n // Deep-sort all keys to ensure deterministic serialization regardless of\n // property insertion order.\n const sortKeys = (_key: string, value: unknown): unknown => {\n if (value && typeof value === 'object' && !Array.isArray(value)) {\n const sorted: Record = {};\n for (const k of Object.keys(value as Record).sort()) {\n sorted[k] = (value as Record)[k];\n }\n return sorted;\n }\n return value;\n };\n const canonical = JSON.stringify({ config, type }, sortKeys);\n return createHash('sha256').update(canonical).digest('hex');\n}\n\n/**\n * Build command-line arguments for a language server from its configuration.\n */\nexport function buildLanguageServerArgs(config: LanguageServerConfig): string[] {\n const args: string[] = [\n 'execute', 'language-server',\n `--check-errors=${config.checkErrors ?? 'ON_CHANGE'}`,\n ];\n\n if (config.searchPath) {\n args.push(`--search-path=${config.searchPath}`);\n }\n if (config.commonCaches) {\n args.push(`--common-caches=${config.commonCaches}`);\n }\n if (config.logdir) {\n args.push(`--logdir=${config.logdir}`);\n }\n if (config.loglevel) {\n args.push(`--loglevel=${config.loglevel}`);\n }\n if (config.synchronous) {\n args.push('--synchronous');\n }\n if (config.verbosity) {\n args.push(`--verbosity=${config.verbosity}`);\n }\n\n return args;\n}\n\n/**\n * Build command-line arguments for a query server from its configuration.\n */\nexport function buildQueryServerArgs(config: QueryServerConfig): string[] {\n const args: string[] = [\n 'execute', 'query-server2',\n ];\n\n if (config.searchPath) {\n args.push(`--search-path=${config.searchPath}`);\n }\n if (config.commonCaches) {\n args.push(`--common-caches=${config.commonCaches}`);\n }\n if (config.logdir) {\n args.push(`--logdir=${config.logdir}`);\n }\n if (config.threads !== undefined) {\n args.push(`--threads=${config.threads}`);\n }\n if (config.timeout !== undefined) {\n args.push(`--timeout=${config.timeout}`);\n }\n if (config.maxDiskCache !== undefined) {\n args.push(`--max-disk-cache=${config.maxDiskCache}`);\n }\n if (config.evaluatorLog) {\n args.push(`--evaluator-log=${config.evaluatorLog}`);\n }\n if (config.debug) {\n args.push('--debug');\n args.push('--tuple-counting');\n } else if (config.tupleCounting) {\n args.push('--tuple-counting');\n }\n\n return args;\n}\n\n/**\n * Build command-line arguments for a CLI server from its configuration.\n */\nexport function buildCLIServerArgs(config: CLIServerConfig): string[] {\n const args: string[] = [\n 'execute', 'cli-server',\n ];\n\n if (config.commonCaches) {\n args.push(`--common-caches=${config.commonCaches}`);\n }\n if (config.logdir) {\n args.push(`--logdir=${config.logdir}`);\n }\n\n return args;\n}\n", "/**\n * Utilities for resolving filesystem paths relative to the server package root.\n *\n * The server can run from three different directory layouts:\n *\n * 1. **Source** (dev): `server/src/lib/` \u2192 packageRoot = `server/`\n * 2. **Bundle in monorepo** (dev/CI): `server/dist/` \u2192 packageRoot = `server/`\n * 3. **Bundle via npm** (production): `/dist/` \u2192 packageRoot = `/`\n *\n * In all three cases, the bundled QL tool query packs live at\n * `/ql//tools/src/`.\n *\n * The \"workspace root\" (monorepo root) is one level above packageRoot when\n * running from the monorepo checkout, and the packageRoot itself when running\n * from an npm install (no parent monorepo).\n */\n\nimport { dirname, resolve } from 'path';\nimport { existsSync, readFileSync } from 'fs';\nimport { fileURLToPath } from 'url';\n\nconst __filename = fileURLToPath(import.meta.url);\nconst __dirname = dirname(__filename);\n\n/**\n * Detect whether the current __dirname looks like source code (`src/lib` or\n * `src/utils`) vs a bundled flat output directory (`dist/`).\n *\n * Uses a tail-of-path check so that unrelated `/src/` segments earlier in the\n * install path (e.g. `~/src/project/node_modules/.../dist`) don't cause a\n * false positive.\n */\nfunction isRunningFromSource(dir: string): boolean {\n const normalized = dir.replace(/\\\\/g, '/');\n return /\\/src(\\/[^/]+)?$/.test(normalized);\n}\n\n/**\n * Get the server package root directory.\n *\n * - From source (`server/src/utils/`): up 2 levels \u2192 `server/`\n * - From bundle (`server/dist/` or `/dist/`): up 1 level \u2192 package root\n */\nexport function getPackageRootDir(currentDir: string = __dirname): string {\n return isRunningFromSource(currentDir)\n ? resolve(currentDir, '..', '..') // src/utils \u2192 server/\n : resolve(currentDir, '..'); // dist/ \u2192 package root\n}\n\n/**\n * Get the workspace root directory (monorepo root when applicable).\n *\n * If a `package.json` with `workspaces` exists one level above the package\n * root, we're in a monorepo and that parent is the workspace root. Otherwise,\n * the packageRoot itself is the workspace root (npm install scenario).\n */\nexport function getWorkspaceRootDir(packageRoot?: string): string {\n const pkgRoot = packageRoot ?? getPackageRootDir();\n const parentDir = resolve(pkgRoot, '..');\n\n // In the monorepo, the parent directory contains a package.json with workspaces\n try {\n const parentPkgPath = resolve(parentDir, 'package.json');\n if (existsSync(parentPkgPath)) {\n const parentPkg = JSON.parse(readFileSync(parentPkgPath, 'utf8'));\n if (parentPkg.workspaces) {\n return parentDir;\n }\n }\n } catch {\n // Not in a monorepo \u2014 fall through\n }\n\n return pkgRoot;\n}\n\n/**\n * Resolve the path to a tool query pack's source directory.\n *\n * @param language - CodeQL language identifier (e.g., \"javascript\", \"cpp\")\n * @param packageRoot - Override the package root (for testing)\n * @returns Absolute path to `ql//tools/src/`\n */\nexport function resolveToolQueryPackPath(language: string, packageRoot?: string): string {\n const pkgRoot = packageRoot ?? getPackageRootDir();\n return resolve(pkgRoot, 'ql', language, 'tools', 'src');\n}\n\n/**\n * Read the package version from the nearest package.json.\n *\n * Cached at first call so the file is read at most once per process.\n */\nlet _cachedVersion: string | undefined;\nexport function getPackageVersion(): string {\n if (_cachedVersion !== undefined) return _cachedVersion;\n try {\n const pkgPath = resolve(getPackageRootDir(), 'package.json');\n const pkg = JSON.parse(readFileSync(pkgPath, 'utf8'));\n _cachedVersion = pkg.version ?? '0.0.0';\n } catch {\n _cachedVersion = '0.0.0';\n }\n return _cachedVersion as string;\n}\n\n/**\n * Get the effective workspace directory for resolving user-supplied relative\n * paths (test directories, database paths, pack dirs, etc.).\n *\n * In a monorepo checkout the workspace root is the monorepo parent. In an\n * npm-installed layout, `workspaceRootDir` falls back to `packageRootDir`\n * which may be read-only and is not the user's project. In that case we\n * fall back to `process.cwd()` so that relative paths resolve against the\n * directory the user actually invoked the server from.\n *\n * Override with `CODEQL_MCP_WORKSPACE` for deterministic behavior.\n */\nexport function getUserWorkspaceDir(): string {\n if (process.env.CODEQL_MCP_WORKSPACE) {\n return process.env.CODEQL_MCP_WORKSPACE;\n }\n // When workspaceRootDir === packageRootDir we are NOT in a monorepo\n // (npm-installed), so fall back to process.cwd().\n if (workspaceRootDir === packageRootDir) {\n return process.cwd();\n }\n return workspaceRootDir;\n}\n\n// Pre-computed values for use throughout the server\nexport const packageRootDir = getPackageRootDir();\nexport const workspaceRootDir = getWorkspaceRootDir(packageRootDir);\n", "/**\n * Secure project-local temporary directory utilities.\n *\n * All temporary files are created under `/.tmp/` which is\n * `.gitignore`d. This avoids writing to the OS temp directory\n * (`os.tmpdir()` / `/tmp`), which is world-readable and triggers\n * CWE-377 / CWE-378 (js/insecure-temporary-file).\n */\n\nimport { mkdirSync, mkdtempSync } from 'fs';\nimport { isAbsolute, join, resolve } from 'path';\nimport { getPackageRootDir } from './package-paths';\n\n/**\n * Base directory for all project-local temporary data.\n *\n * Resolution order:\n * 1. `CODEQL_MCP_TMP_DIR` environment variable \u2014 for read-only package root\n * scenarios (e.g., npm global installs where the package directory is not\n * writable). Relative paths are resolved against process.cwd().\n * 2. `/.tmp` \u2014 default; excluded from version control.\n */\nconst PROJECT_TMP_BASE = process.env.CODEQL_MCP_TMP_DIR\n ? (isAbsolute(process.env.CODEQL_MCP_TMP_DIR) \n ? process.env.CODEQL_MCP_TMP_DIR \n : resolve(process.cwd(), process.env.CODEQL_MCP_TMP_DIR))\n : join(getPackageRootDir(), '.tmp');\n\n/**\n * Return the project-local `.tmp` base directory, creating it if needed.\n */\nexport function getProjectTmpBase(): string {\n mkdirSync(PROJECT_TMP_BASE, { recursive: true });\n return PROJECT_TMP_BASE;\n}\n\n/**\n * Create a unique temporary directory under the project `.tmp` root.\n *\n * Works identically to `fs.mkdtempSync(os.tmpdir(), prefix)` but is\n * scoped to the repository.\n *\n * @param prefix - Directory name prefix (e.g. `'codeql-external-'`).\n * @returns Absolute path to the newly created directory.\n */\nexport function createProjectTempDir(prefix: string): string {\n const base = getProjectTmpBase();\n return mkdtempSync(join(base, prefix));\n}\n\n/**\n * Return a deterministic subdirectory under `.tmp/`, creating it\n * if it does not already exist.\n *\n * Useful for well-known scratch areas such as `query-logs` or `quickeval`.\n *\n * @param name - Subdirectory name (e.g. `'query-logs'`).\n * @returns Absolute path to the subdirectory.\n */\nexport function getProjectTmpDir(name: string): string {\n const dir = join(getProjectTmpBase(), name);\n mkdirSync(dir, { recursive: true });\n return dir;\n}\n", "/**\n * Utility for waiting until a spawned child process is ready.\n *\n * CodeQL background servers (cli-server, query-server2, language-server) run\n * on the JVM and emit stderr log output once the JVM has initialised. Rather\n * than sleeping for a hard-coded duration \u2014 which is fragile on both fast and\n * slow machines \u2014 this helper resolves as soon as the first stderr output\n * arrives (indicating the JVM is alive), or when the maximum timeout expires.\n * It also rejects immediately if the process exits or errors before becoming\n * ready, giving callers a clear error instead of a silent hang.\n */\n\nimport { ChildProcess } from 'child_process';\nimport { clearTimeout, setTimeout } from 'timers';\nimport { logger } from './logger';\n\n/** Default maximum wait for a CodeQL server to become ready (30 s). */\nconst DEFAULT_READY_TIMEOUT_MS = 30_000;\n\n/**\n * Options for {@link waitForProcessReady}.\n */\nexport interface ProcessReadyOptions {\n /**\n * Maximum time in milliseconds to wait for the process to emit its first\n * stderr output. If the timeout is reached without a signal the promise\n * still resolves (best-effort) so the caller can attempt communication.\n *\n * Default: 30 000 ms.\n */\n timeoutMs?: number;\n}\n\n/**\n * Wait until a child process signals readiness.\n *\n * \"Ready\" is defined as any of:\n * 1. The process emits data on **stderr** (JVM startup log line).\n * 2. The process emits data on **stdout** (initial protocol message).\n * 3. The maximum timeout elapses (best-effort resolve).\n *\n * The promise **rejects** if the process emits an `error` event or exits\n * before any of the above conditions are met.\n *\n * @param child - The spawned child process.\n * @param name - A human-readable label for log messages.\n * @param opts - Optional configuration.\n */\nexport function waitForProcessReady(\n child: ChildProcess,\n name: string,\n opts?: ProcessReadyOptions,\n): Promise {\n const timeoutMs = opts?.timeoutMs ?? DEFAULT_READY_TIMEOUT_MS;\n\n return new Promise((resolve, reject) => {\n let settled = false;\n\n const cleanup = () => {\n settled = true;\n child.stderr?.removeListener('data', onStderr);\n child.stdout?.removeListener('data', onStdout);\n child.removeListener('error', onError);\n child.removeListener('exit', onExit);\n clearTimeout(timer);\n };\n\n const onStderr = () => {\n if (settled) return;\n logger.debug(`${name}: ready (stderr output detected)`);\n cleanup();\n resolve();\n };\n\n const onStdout = () => {\n if (settled) return;\n logger.debug(`${name}: ready (stdout output detected)`);\n cleanup();\n resolve();\n };\n\n const onError = (error: Error) => {\n if (settled) return;\n cleanup();\n reject(new Error(`${name} failed to start: ${error.message}`));\n };\n\n const onExit = (code: number | null) => {\n if (settled) return;\n cleanup();\n reject(new Error(`${name} exited before becoming ready (code: ${code})`));\n };\n\n const timer = setTimeout(() => {\n if (settled) return;\n logger.warn(`${name}: readiness timeout (${timeoutMs} ms) \u2014 proceeding anyway`);\n cleanup();\n resolve(); // best-effort: let the caller attempt communication\n }, timeoutMs);\n\n child.stderr?.on('data', onStderr);\n child.stdout?.on('data', onStdout);\n child.on('error', onError);\n child.on('exit', onExit);\n\n // If the process was dead before we even attached listeners, reject now\n if (child.killed || child.exitCode !== null) {\n cleanup();\n reject(new Error(`${name} is not running (exitCode: ${child.exitCode})`));\n }\n });\n}\n", "/**\n * CodeQL Language Server manager for LSP communication\n * Manages the lifecycle and communication with the CodeQL language server process\n */\n\nimport { spawn, ChildProcess } from 'child_process';\nimport { EventEmitter } from 'events';\nimport { setTimeout, clearTimeout } from 'timers';\nimport { pathToFileURL } from 'url';\nimport { delimiter, join } from 'path';\nimport { logger } from '../utils/logger';\nimport { getPackageVersion } from '../utils/package-paths';\nimport { getProjectTmpDir } from '../utils/temp-dir';\nimport { getResolvedCodeQLDir } from './cli-executor';\nimport { waitForProcessReady } from '../utils/process-ready';\n\nexport interface LSPMessage {\n jsonrpc: '2.0';\n id?: number | string;\n method: string;\n params?: unknown;\n result?: unknown;\n error?: {\n code: number;\n message: string;\n data?: unknown;\n };\n}\n\nexport interface Diagnostic {\n range: {\n start: { line: number; character: number };\n end: { line: number; character: number };\n };\n severity: number; // 1=Error, 2=Warning, 3=Information, 4=Hint\n source?: string;\n message: string;\n code?: string | number;\n}\n\nexport interface PublishDiagnosticsParams {\n uri: string;\n diagnostics: Diagnostic[];\n}\n\nexport interface LanguageServerOptions {\n searchPath?: string;\n logdir?: string;\n loglevel?: 'ALL' | 'DEBUG' | 'ERROR' | 'INFO' | 'OFF' | 'TRACE' | 'WARN';\n synchronous?: boolean;\n verbosity?: 'errors' | 'progress' | 'progress+' | 'progress++' | 'progress+++' | 'warnings';\n}\n\n/**\n * Position in a text document (0-based line and character).\n */\nexport interface LSPPosition {\n character: number;\n line: number;\n}\n\n/**\n * A range in a text document.\n */\nexport interface LSPRange {\n end: LSPPosition;\n start: LSPPosition;\n}\n\n/**\n * A location in a resource (file URI + range).\n */\nexport interface LSPLocation {\n range: LSPRange;\n uri: string;\n}\n\n/**\n * Identifies a text document by its URI.\n */\nexport interface TextDocumentIdentifier {\n uri: string;\n}\n\n/**\n * A text document position (document + position within it).\n */\nexport interface TextDocumentPositionParams {\n position: LSPPosition;\n textDocument: TextDocumentIdentifier;\n}\n\n/**\n * A completion item returned by the language server.\n */\nexport interface CompletionItem {\n detail?: string;\n documentation?: string | { kind: string; value: string };\n insertText?: string;\n kind?: number;\n label: string;\n sortText?: string;\n}\n\nexport class CodeQLLanguageServer extends EventEmitter {\n private server: ChildProcess | null = null;\n private messageId = 1;\n private pendingResponses = new Map void; reject: (_error: Error) => void }>();\n private isInitialized = false;\n private currentWorkspaceUri: string | undefined;\n private messageBuffer = '';\n\n constructor(private _options: LanguageServerOptions = {}) {\n super();\n }\n\n async start(): Promise {\n if (this.server) {\n throw new Error('Language server is already running');\n }\n\n logger.info('Starting CodeQL Language Server...');\n\n const args = [\n 'execute', 'language-server',\n '--check-errors=ON_CHANGE'\n ];\n\n // Add optional arguments\n if (this._options.searchPath) {\n args.push(`--search-path=${this._options.searchPath}`);\n }\n if (this._options.logdir) {\n args.push(`--logdir=${this._options.logdir}`);\n }\n if (this._options.loglevel) {\n args.push(`--loglevel=${this._options.loglevel}`);\n }\n if (this._options.synchronous) {\n args.push('--synchronous');\n }\n if (this._options.verbosity) {\n args.push(`--verbosity=${this._options.verbosity}`);\n }\n\n // Build environment with CODEQL_PATH directory prepended to PATH\n // (mirrors the approach in cli-executor.ts getSafeEnvironment).\n const spawnEnv = { ...process.env };\n const codeqlDir = getResolvedCodeQLDir();\n if (codeqlDir && spawnEnv.PATH) {\n spawnEnv.PATH = `${codeqlDir}${delimiter}${spawnEnv.PATH}`;\n } else if (codeqlDir) {\n spawnEnv.PATH = codeqlDir;\n }\n\n this.server = spawn('codeql', args, {\n stdio: ['pipe', 'pipe', 'pipe'],\n env: spawnEnv\n });\n\n this.server.stderr?.on('data', (data) => {\n logger.debug('CodeQL LS stderr:', data.toString());\n });\n\n this.server.stdout?.on('data', (data) => {\n this.handleStdout(data);\n });\n\n this.server.on('error', (error) => {\n logger.error('CodeQL Language Server error:', error);\n this.emit('error', error);\n });\n\n this.server.on('exit', (code) => {\n logger.info('CodeQL Language Server exited with code:', code);\n this.server = null;\n this.isInitialized = false;\n this.emit('exit', code);\n });\n\n // Wait for the JVM to initialise (resolves on first stderr/stdout output)\n await waitForProcessReady(this.server, 'CodeQL Language Server');\n }\n\n private handleStdout(data: Buffer): void {\n this.messageBuffer += data.toString();\n \n let headerEnd = this.messageBuffer.indexOf('\\r\\n\\r\\n');\n while (headerEnd !== -1) {\n const header = this.messageBuffer.substring(0, headerEnd);\n const contentLengthMatch = header.match(/Content-Length: (\\d+)/);\n \n if (contentLengthMatch) {\n const contentLength = parseInt(contentLengthMatch[1]);\n const messageStart = headerEnd + 4;\n const messageEnd = messageStart + contentLength;\n \n if (this.messageBuffer.length >= messageEnd) {\n const messageContent = this.messageBuffer.substring(messageStart, messageEnd);\n this.messageBuffer = this.messageBuffer.substring(messageEnd);\n \n try {\n const message: LSPMessage = JSON.parse(messageContent);\n this.handleMessage(message);\n } catch (error) {\n logger.error('Failed to parse LSP message:', error, messageContent);\n }\n \n headerEnd = this.messageBuffer.indexOf('\\r\\n\\r\\n');\n } else {\n break;\n }\n } else {\n logger.error('Invalid LSP header:', header);\n this.messageBuffer = '';\n break;\n }\n }\n }\n\n private handleMessage(message: LSPMessage): void {\n logger.debug('Received LSP message:', message);\n\n // Handle responses to our requests\n if (message.id !== undefined && this.pendingResponses.has(Number(message.id))) {\n const pending = this.pendingResponses.get(Number(message.id))!;\n this.pendingResponses.delete(Number(message.id));\n \n if (message.error) {\n pending.reject(new Error(`LSP Error: ${message.error.message}`));\n } else {\n pending.resolve(message.result);\n }\n return;\n }\n\n // Handle notifications from server\n if (message.method === 'textDocument/publishDiagnostics') {\n this.emit('diagnostics', message.params as PublishDiagnosticsParams);\n }\n }\n\n private sendMessage(message: LSPMessage): void {\n if (!this.server?.stdin) {\n throw new Error('Language server is not running');\n }\n\n const messageStr = JSON.stringify(message);\n const contentLength = Buffer.byteLength(messageStr, 'utf8');\n const header = `Content-Length: ${contentLength}\\r\\n\\r\\n`;\n const fullMessage = header + messageStr;\n\n logger.debug('Sending LSP message:', fullMessage);\n this.server.stdin.write(fullMessage);\n }\n\n private sendRequest(method: string, params?: unknown): Promise {\n const id = this.messageId++;\n const message: LSPMessage = {\n jsonrpc: '2.0',\n id,\n method,\n params\n };\n\n return new Promise((resolve, reject) => {\n // Wrap resolve/reject to clear the timer when the promise settles.\n const timer = setTimeout(() => {\n if (this.pendingResponses.has(id)) {\n this.pendingResponses.delete(id);\n reject(new Error(`LSP request timeout for method: ${method}`));\n }\n }, 60_000); // 60 second timeout (Windows CI cold JVM can exceed 30s)\n\n this.pendingResponses.set(id, {\n reject: (err: Error) => { clearTimeout(timer); reject(err); },\n resolve: (val: unknown) => { clearTimeout(timer); resolve(val); },\n });\n this.sendMessage(message);\n });\n }\n\n private sendNotification(method: string, params?: unknown): void {\n const message: LSPMessage = {\n jsonrpc: '2.0',\n method,\n params\n };\n this.sendMessage(message);\n }\n\n /**\n * Initialize the language server with an optional workspace URI.\n *\n * If the server is already initialized with a different workspace, a\n * `workspace/didChangeWorkspaceFolders` notification is sent to update\n * the workspace context instead of requiring a full restart.\n */\n async initialize(workspaceUri?: string): Promise {\n if (this.isInitialized) {\n // If workspace changed, notify the server\n if (workspaceUri && workspaceUri !== this.currentWorkspaceUri) {\n await this.updateWorkspace(workspaceUri);\n }\n return;\n }\n\n logger.info('Initializing CodeQL Language Server...');\n\n const initParams = {\n processId: process.pid,\n clientInfo: {\n name: 'codeql-development-mcp-server',\n version: getPackageVersion()\n },\n capabilities: {\n textDocument: {\n completion: { completionItem: { snippetSupport: false } },\n definition: {},\n publishDiagnostics: {},\n references: {},\n synchronization: {\n didClose: true,\n didChange: true,\n didOpen: true,\n },\n },\n workspace: {\n workspaceFolders: true,\n },\n }\n };\n\n if (workspaceUri) {\n (initParams as unknown as { workspaceFolders: unknown[] }).workspaceFolders = [{\n uri: workspaceUri,\n name: 'codeql-workspace'\n }];\n }\n\n await this.sendRequest('initialize', initParams);\n this.sendNotification('initialized', {});\n\n this.currentWorkspaceUri = workspaceUri;\n this.isInitialized = true;\n logger.info('CodeQL Language Server initialized successfully');\n }\n\n /**\n * Update the workspace folders on a running, initialized server.\n */\n private async updateWorkspace(newUri: string): Promise {\n logger.info(`Updating workspace from ${this.currentWorkspaceUri} to ${newUri}`);\n\n const removed = this.currentWorkspaceUri\n ? [{ uri: this.currentWorkspaceUri, name: 'codeql-workspace' }]\n : [];\n\n this.sendNotification('workspace/didChangeWorkspaceFolders', {\n event: {\n added: [{ uri: newUri, name: 'codeql-workspace' }],\n removed,\n },\n });\n\n this.currentWorkspaceUri = newUri;\n }\n\n /**\n * Get the current workspace URI.\n */\n getWorkspaceUri(): string | undefined {\n return this.currentWorkspaceUri;\n }\n\n async evaluateQL(qlCode: string, uri?: string): Promise {\n if (!this.isInitialized) {\n throw new Error('Language server is not initialized');\n }\n\n // Default to a project-local virtual URI rather than /tmp\n const documentUri = uri || pathToFileURL(join(getProjectTmpDir('lsp-eval'), 'eval.ql')).href;\n\n return new Promise((resolve, reject) => {\n let diagnosticsReceived = false;\n const timeout = setTimeout(() => {\n if (!diagnosticsReceived) {\n this.removeListener('diagnostics', diagnosticsHandler);\n reject(new Error('Timeout waiting for diagnostics'));\n }\n }, 90_000); // 90s \u2014 first call triggers JVM start + compilation; Windows CI is slow\n\n // Listen for diagnostics\n const diagnosticsHandler = (params: PublishDiagnosticsParams) => {\n if (params.uri === documentUri) {\n diagnosticsReceived = true;\n clearTimeout(timeout);\n this.removeListener('diagnostics', diagnosticsHandler);\n\n // Close the document\n this.sendNotification('textDocument/didClose', {\n textDocument: { uri: documentUri }\n });\n\n resolve(params.diagnostics);\n }\n };\n\n this.on('diagnostics', diagnosticsHandler);\n\n // Open the document with the QL code\n this.sendNotification('textDocument/didOpen', {\n textDocument: {\n uri: documentUri,\n languageId: 'ql',\n version: 1,\n text: qlCode\n }\n });\n });\n }\n\n // ---- LSP feature methods (issue #1) ----\n\n /**\n * Get code completions at a position in a document.\n */\n async getCompletions(params: TextDocumentPositionParams): Promise {\n if (!this.isInitialized) {\n throw new Error('Language server is not initialized');\n }\n if (!this.isRunning()) {\n throw new Error('Language server process is not running');\n }\n const result = await this.sendRequest('textDocument/completion', params);\n // The result may be a CompletionList or CompletionItem[]\n if (result && typeof result === 'object' && 'items' in (result as object)) {\n return (result as { items: CompletionItem[] }).items;\n }\n return (result as CompletionItem[]) || [];\n }\n\n /**\n * Find the definition(s) of a symbol at a position.\n */\n async getDefinition(params: TextDocumentPositionParams): Promise {\n if (!this.isInitialized) {\n throw new Error('Language server is not initialized');\n }\n if (!this.isRunning()) {\n throw new Error('Language server process is not running');\n }\n const result = await this.sendRequest('textDocument/definition', params);\n return this.normalizeLocations(result);\n }\n\n /**\n * Find all references to a symbol at a position.\n */\n async getReferences(params: TextDocumentPositionParams & { context?: { includeDeclaration: boolean } }): Promise {\n if (!this.isInitialized) {\n throw new Error('Language server is not initialized');\n }\n if (!this.isRunning()) {\n throw new Error('Language server process is not running');\n }\n const result = await this.sendRequest('textDocument/references', {\n ...params,\n context: params.context ?? { includeDeclaration: true },\n });\n return this.normalizeLocations(result);\n }\n\n /**\n * Open a text document in the language server.\n * The document must be opened before requesting completions, definitions, etc.\n */\n openDocument(uri: string, text: string, languageId = 'ql', version = 1): void {\n if (!this.isInitialized) {\n throw new Error('Language server is not initialized');\n }\n this.sendNotification('textDocument/didOpen', {\n textDocument: { uri, languageId, version, text },\n });\n }\n\n /**\n * Close a text document in the language server.\n */\n closeDocument(uri: string): void {\n if (!this.isInitialized) {\n throw new Error('Language server is not initialized');\n }\n this.sendNotification('textDocument/didClose', {\n textDocument: { uri },\n });\n }\n\n /**\n * Normalize a definition/references/implementation result to Location[].\n * The LSP spec allows Location | Location[] | LocationLink[].\n */\n private normalizeLocations(result: unknown): LSPLocation[] {\n if (!result) return [];\n if (Array.isArray(result)) {\n return result.map((item) => {\n // LocationLink has targetUri/targetRange\n if ('targetUri' in item) {\n return { uri: item.targetUri, range: item.targetRange } as LSPLocation;\n }\n return item as LSPLocation;\n });\n }\n // Single Location\n if (typeof result === 'object' && 'uri' in (result as object)) {\n return [result as LSPLocation];\n }\n return [];\n }\n\n async shutdown(): Promise {\n if (!this.server) {\n return;\n }\n\n logger.info('Shutting down CodeQL Language Server...');\n\n try {\n await this.sendRequest('shutdown', {});\n if (this.server) {\n this.sendNotification('exit', {});\n }\n } catch (error) {\n logger.warn('Error during graceful shutdown:', error);\n }\n\n // Force kill if needed\n await new Promise((resolve) => {\n const timer = setTimeout(() => {\n if (this.server) {\n this.server.kill('SIGTERM');\n }\n resolve();\n }, 1000);\n\n if (this.server) {\n this.server.once('exit', () => {\n clearTimeout(timer);\n this.server = null;\n resolve();\n });\n } else {\n clearTimeout(timer);\n resolve();\n }\n });\n\n this.isInitialized = false;\n }\n\n isRunning(): boolean {\n return this.server !== null && !this.server.killed;\n }\n}", "/**\n * CodeQL Query Server (query-server2) client.\n *\n * Manages a long-lived `codeql execute query-server2` process that evaluates\n * queries using a custom JSON-RPC protocol over stdio. Reusing the server\n * avoids repeated JVM startup for each query evaluation.\n *\n * Protocol: The query-server2 uses JSON-RPC with Content-Length headers\n * (same framing as LSP) over stdin/stdout.\n */\n\nimport { ChildProcess, spawn } from 'child_process';\nimport { delimiter } from 'path';\nimport { EventEmitter } from 'events';\nimport { clearTimeout, setTimeout } from 'timers';\nimport { buildQueryServerArgs, QueryServerConfig } from './server-config';\nimport { getResolvedCodeQLDir } from './cli-executor';\nimport { logger } from '../utils/logger';\nimport { waitForProcessReady } from '../utils/process-ready';\n\n/**\n * A pending request awaiting a response from the query server.\n */\ninterface PendingRequest {\n reject: (_error: Error) => void;\n resolve: (_value: unknown) => void;\n}\n\n/**\n * Client for the CodeQL query-server2 process.\n *\n * Spawns `codeql execute query-server2` and communicates over stdin/stdout\n * using JSON-RPC with Content-Length framing.\n */\nexport class CodeQLQueryServer extends EventEmitter {\n private messageBuffer = '';\n private messageId = 1;\n private pendingRequests = new Map();\n private process: ChildProcess | null = null;\n private readonly config: QueryServerConfig;\n\n constructor(config: QueryServerConfig) {\n super();\n this.config = config;\n }\n\n /**\n * Start the query-server2 process.\n */\n async start(): Promise {\n if (this.process) {\n throw new Error('Query server is already running');\n }\n\n logger.info('Starting CodeQL Query Server (query-server2)...');\n\n const args = buildQueryServerArgs(this.config);\n\n // Build environment with CODEQL_PATH directory prepended to PATH\n const spawnEnv = { ...process.env };\n const codeqlDir = getResolvedCodeQLDir();\n if (codeqlDir && spawnEnv.PATH) {\n spawnEnv.PATH = `${codeqlDir}${delimiter}${spawnEnv.PATH}`;\n } else if (codeqlDir) {\n spawnEnv.PATH = codeqlDir;\n }\n\n this.process = spawn('codeql', args, {\n stdio: ['pipe', 'pipe', 'pipe'],\n env: spawnEnv,\n });\n\n this.process.stderr?.on('data', (data: Buffer) => {\n logger.debug('QueryServer2 stderr:', data.toString());\n });\n\n this.process.stdout?.on('data', (data: Buffer) => {\n this.handleStdout(data);\n });\n\n this.process.on('error', (error: Error) => {\n logger.error('Query server process error:', error);\n this.emit('error', error);\n });\n\n this.process.on('exit', (code: number | null) => {\n logger.info(`Query server exited with code: ${code}`);\n this.rejectAllPending(new Error(`Query server exited with code: ${code}`));\n this.process = null;\n this.emit('exit', code);\n });\n\n // Wait for the JVM to initialise (resolves on first stderr/stdout output)\n await waitForProcessReady(this.process, 'CodeQL Query Server');\n logger.info('CodeQL Query Server started');\n }\n\n /**\n * Send a request to the query server and await the response.\n *\n * @param method - The JSON-RPC method name.\n * @param params - The method parameters.\n * @param timeoutMs - Request timeout in milliseconds (default: 300000 = 5 min).\n * @returns The result from the server.\n */\n sendRequest(method: string, params?: unknown, timeoutMs = 300_000): Promise {\n const id = this.messageId++;\n const message = {\n id,\n jsonrpc: '2.0' as const,\n method,\n params,\n };\n\n return new Promise((resolve, reject) => {\n this.pendingRequests.set(id, { reject, resolve });\n\n try {\n this.sendRaw(message);\n } catch (error) {\n // Clean up immediately \u2014 sendRaw() failed so no response will arrive.\n this.pendingRequests.delete(id);\n reject(error instanceof Error ? error : new Error(String(error)));\n return;\n }\n\n const timer = setTimeout(() => {\n if (this.pendingRequests.has(id)) {\n this.pendingRequests.delete(id);\n reject(new Error(`Query server request timeout for method: ${method}`));\n }\n }, timeoutMs);\n\n // Clear the timeout when the promise settles\n const originalResolve = resolve;\n const originalReject = reject;\n const wrapped = {\n reject: (err: Error) => { clearTimeout(timer); originalReject(err); },\n resolve: (val: unknown) => { clearTimeout(timer); originalResolve(val); },\n };\n this.pendingRequests.set(id, wrapped);\n });\n }\n\n /**\n * Gracefully shut down the query server.\n */\n async shutdown(): Promise {\n if (!this.process) {\n return;\n }\n\n logger.info('Shutting down CodeQL Query Server...');\n\n try {\n await this.sendRequest('shutdown', {}, 5000);\n } catch (error) {\n logger.warn('Error during query server graceful shutdown:', error);\n }\n\n // Force kill if process lingers\n await new Promise((resolve) => {\n const timer = setTimeout(() => {\n if (this.process) {\n this.process.kill('SIGTERM');\n this.process = null;\n }\n resolve();\n }, 2000);\n\n if (this.process) {\n this.process.once('exit', () => {\n clearTimeout(timer);\n this.process = null;\n resolve();\n });\n } else {\n clearTimeout(timer);\n resolve();\n }\n });\n }\n\n /**\n * Whether the query server process is running.\n */\n isRunning(): boolean {\n return this.process !== null && !this.process.killed;\n }\n\n // ---- private helpers ----\n\n private handleStdout(data: Buffer): void {\n this.messageBuffer += data.toString();\n\n let headerEnd = this.messageBuffer.indexOf('\\r\\n\\r\\n');\n while (headerEnd !== -1) {\n const header = this.messageBuffer.substring(0, headerEnd);\n const contentLengthMatch = header.match(/Content-Length: (\\d+)/);\n\n if (contentLengthMatch) {\n const contentLength = parseInt(contentLengthMatch[1]);\n const messageStart = headerEnd + 4;\n const messageEnd = messageStart + contentLength;\n\n if (this.messageBuffer.length >= messageEnd) {\n const messageContent = this.messageBuffer.substring(messageStart, messageEnd);\n this.messageBuffer = this.messageBuffer.substring(messageEnd);\n\n try {\n const message = JSON.parse(messageContent);\n this.handleMessage(message);\n } catch (error) {\n logger.error('Failed to parse query server message:', error);\n }\n\n headerEnd = this.messageBuffer.indexOf('\\r\\n\\r\\n');\n } else {\n break;\n }\n } else {\n logger.error('Invalid query server header:', header);\n this.messageBuffer = '';\n break;\n }\n }\n }\n\n private handleMessage(message: { error?: { message: string }; id?: number; method?: string; params?: unknown; result?: unknown }): void {\n logger.debug('QueryServer2 message:', message);\n\n // Handle responses\n if (message.id !== undefined && this.pendingRequests.has(Number(message.id))) {\n const pending = this.pendingRequests.get(Number(message.id))!;\n this.pendingRequests.delete(Number(message.id));\n\n if (message.error) {\n pending.reject(new Error(`Query server error: ${message.error.message}`));\n } else {\n pending.resolve(message.result);\n }\n return;\n }\n\n // Handle notifications (progress, etc.)\n if (message.method) {\n this.emit('notification', { method: message.method, params: message.params });\n }\n }\n\n private rejectAllPending(error: Error): void {\n for (const [id, pending] of this.pendingRequests) {\n pending.reject(error);\n this.pendingRequests.delete(id);\n }\n }\n\n private sendRaw(message: object): void {\n if (!this.process?.stdin) {\n throw new Error('Query server is not running');\n }\n\n const body = JSON.stringify(message);\n const contentLength = Buffer.byteLength(body, 'utf8');\n const frame = `Content-Length: ${contentLength}\\r\\n\\r\\n${body}`;\n this.process.stdin.write(frame);\n }\n}\n", "/**\n * CodeQL CLI Server client.\n *\n * Manages a long-lived `codeql execute cli-server` process that executes CLI\n * commands without repeated JVM startup overhead. Commands are serialized as\n * JSON arrays followed by a NUL byte, and responses are NUL-terminated JSON.\n *\n * Inspired by the `CodeQLCliServer` class in github/vscode-codeql.\n */\n\nimport { ChildProcess, spawn } from 'child_process';\nimport { delimiter } from 'path';\nimport { EventEmitter } from 'events';\nimport { clearTimeout, setTimeout } from 'timers';\nimport { buildCLIServerArgs, CLIServerConfig } from './server-config';\nimport { getResolvedCodeQLDir } from './cli-executor';\nimport { logger } from '../utils/logger';\nimport { waitForProcessReady } from '../utils/process-ready';\n\n/**\n * A queued command waiting to be sent to the CLI server.\n */\ninterface QueuedCommand {\n args: string[];\n reject: (_error: Error) => void;\n resolve: (_value: string) => void;\n}\n\n/**\n * Client for the CodeQL CLI Server process.\n *\n * The cli-server uses a simple NUL-delimited protocol:\n * - **Request**: JSON array of command arguments, followed by a NUL byte.\n * - **Response**: command stdout, terminated by a NUL byte on stdout.\n * stderr is forwarded as-is.\n */\nexport class CodeQLCLIServer extends EventEmitter {\n private commandInProgress = false;\n private commandQueue: Array<() => void> = [];\n private readonly config: CLIServerConfig;\n private currentReject: ((_error: Error) => void) | null = null;\n private currentResolve: ((_value: string) => void) | null = null;\n private nullBuffer = Buffer.alloc(1);\n private process: ChildProcess | null = null;\n private stdoutBuffer = '';\n\n constructor(config: CLIServerConfig) {\n super();\n this.config = config;\n }\n\n /**\n * Start the cli-server process.\n */\n async start(): Promise {\n if (this.process) {\n throw new Error('CLI server is already running');\n }\n\n logger.info('Starting CodeQL CLI Server...');\n\n const args = buildCLIServerArgs(this.config);\n\n const spawnEnv = { ...process.env };\n const codeqlDir = getResolvedCodeQLDir();\n if (codeqlDir && spawnEnv.PATH) {\n spawnEnv.PATH = `${codeqlDir}${delimiter}${spawnEnv.PATH}`;\n } else if (codeqlDir) {\n spawnEnv.PATH = codeqlDir;\n }\n\n this.process = spawn('codeql', args, {\n stdio: ['pipe', 'pipe', 'pipe'],\n env: spawnEnv,\n });\n\n this.process.stdout?.on('data', (data: Buffer) => {\n this.handleStdout(data);\n });\n\n this.process.stderr?.on('data', (data: Buffer) => {\n logger.debug('CLIServer stderr:', data.toString());\n });\n\n this.process.on('error', (error: Error) => {\n logger.error('CLI server process error:', error);\n if (this.currentReject) {\n this.currentReject(error);\n this.currentReject = null;\n this.currentResolve = null;\n }\n this.emit('error', error);\n });\n\n this.process.on('exit', (code: number | null) => {\n logger.info(`CLI server exited with code: ${code}`);\n if (this.currentReject) {\n this.currentReject(new Error(`CLI server exited unexpectedly with code: ${code}`));\n this.currentReject = null;\n this.currentResolve = null;\n }\n this.process = null;\n this.emit('exit', code);\n });\n\n // Wait for the JVM to initialise (resolves on first stderr/stdout output)\n await waitForProcessReady(this.process, 'CodeQL CLI Server');\n logger.info('CodeQL CLI Server started');\n }\n\n /**\n * Run a CodeQL CLI command through the persistent server.\n *\n * Commands are serialized and queued; only one command runs at a time.\n *\n * @param args - The full command arguments (e.g. `['resolve', 'qlpacks']`).\n * @returns The stdout output from the command.\n */\n runCommand(args: string[]): Promise {\n return new Promise((resolve, reject) => {\n const execute = () => {\n this.executeCommand({ args, reject, resolve });\n };\n\n if (this.commandInProgress) {\n this.commandQueue.push(execute);\n } else {\n execute();\n }\n });\n }\n\n /**\n * Gracefully shut down the CLI server.\n */\n async shutdown(): Promise {\n if (!this.process) {\n return;\n }\n\n logger.info('Shutting down CodeQL CLI Server...');\n\n try {\n // Send shutdown command\n this.process.stdin?.write(JSON.stringify(['shutdown']), 'utf8');\n this.process.stdin?.write(this.nullBuffer);\n } catch (error) {\n logger.warn('Error during CLI server shutdown request:', error);\n }\n\n // Give it a moment, then force kill\n await new Promise((resolve) => {\n const timer = setTimeout(() => {\n if (this.process) {\n this.process.kill('SIGTERM');\n this.process = null;\n }\n resolve();\n }, 2000);\n\n if (this.process) {\n this.process.once('exit', () => {\n clearTimeout(timer);\n this.process = null;\n resolve();\n });\n } else {\n clearTimeout(timer);\n resolve();\n }\n });\n\n this.commandInProgress = false;\n this.commandQueue = [];\n logger.info('CodeQL CLI Server stopped');\n }\n\n /**\n * Whether the CLI server process is running.\n */\n isRunning(): boolean {\n return this.process !== null && !this.process.killed;\n }\n\n // ---- private helpers ----\n\n private executeCommand(cmd: QueuedCommand): void {\n if (!this.process?.stdin) {\n cmd.reject(new Error('CLI server is not running'));\n return;\n }\n\n this.commandInProgress = true;\n this.currentResolve = cmd.resolve;\n this.currentReject = cmd.reject;\n\n try {\n this.process.stdin.write(JSON.stringify(cmd.args), 'utf8');\n this.process.stdin.write(this.nullBuffer);\n } catch (error) {\n this.commandInProgress = false;\n this.currentResolve = null;\n this.currentReject = null;\n cmd.reject(error instanceof Error ? error : new Error(String(error)));\n this.runNext();\n }\n }\n\n private handleStdout(data: Buffer): void {\n this.stdoutBuffer += data.toString();\n\n // Process all NUL-delimited responses in the buffer\n let nulIndex = this.stdoutBuffer.indexOf('\\0');\n while (nulIndex !== -1) {\n const result = this.stdoutBuffer.substring(0, nulIndex);\n this.stdoutBuffer = this.stdoutBuffer.substring(nulIndex + 1);\n\n if (this.currentResolve) {\n this.currentResolve(result);\n this.currentResolve = null;\n this.currentReject = null;\n }\n\n this.commandInProgress = false;\n this.runNext();\n\n nulIndex = this.stdoutBuffer.indexOf('\\0');\n }\n }\n\n private runNext(): void {\n const next = this.commandQueue.shift();\n if (next) {\n next();\n }\n }\n}\n", "/**\n * CodeQL Server Manager\n *\n * Manages the lifecycle of CodeQL background server processes:\n * - language-server (LSP-based QL validation)\n * - query-server2 (query evaluation)\n * - cli-server (JVM reuse for CLI commands)\n *\n * Servers are keyed by a hash of their configuration. When a caller requests\n * a server with a different configuration, the old server is shut down and a\n * new one is started. Session-specific cache directories provide isolation.\n */\n\nimport { mkdirSync } from 'fs';\nimport { join } from 'path';\nimport { randomUUID } from 'crypto';\nimport {\n CLIServerConfig,\n CodeQLServerType,\n computeConfigHash,\n LanguageServerConfig,\n QueryServerConfig,\n ServerConfig,\n} from './server-config';\nimport { CodeQLLanguageServer } from './language-server';\nimport { CodeQLQueryServer } from './query-server';\nimport { CodeQLCLIServer } from './cli-server';\nimport { getProjectTmpDir } from '../utils/temp-dir';\nimport { logger } from '../utils/logger';\n\n/**\n * Entry in the managed servers map.\n */\ninterface ManagedServer {\n configHash: string;\n server: CodeQLCLIServer | CodeQLLanguageServer | CodeQLQueryServer;\n sessionId: string;\n type: CodeQLServerType;\n}\n\n/**\n * Options for creating a session-specific cache layout.\n */\nexport interface SessionCacheOptions {\n /** Override the session ID (defaults to a random UUID). */\n sessionId?: string;\n}\n\n/**\n * Manages CodeQL background server processes with config-aware caching.\n *\n * Callers should use `getLanguageServer()`, `getQueryServer()`, or\n * `getCLIServer()` to obtain a running server. If the requested\n * configuration differs from the currently running server of that type, the\n * old server is stopped and replaced.\n */\nexport class CodeQLServerManager {\n /** Keyed by `CodeQLServerType` \u2014 at most one per type at a time. */\n private servers = new Map();\n\n /** In-flight `getOrRestart` promises, keyed by server type, to serialize concurrent calls. */\n private pendingStarts = new Map>();\n\n /** The session ID used for cache isolation. */\n private sessionId: string;\n\n /** Root directory for session-specific caches. */\n private sessionCacheDir: string;\n\n constructor(options?: SessionCacheOptions) {\n this.sessionId = options?.sessionId ?? randomUUID();\n this.sessionCacheDir = join(\n getProjectTmpDir('codeql-cache'),\n this.sessionId,\n );\n // Pre-create the cache directory tree\n for (const subdir of ['compilation-cache', 'logs', 'query-cache']) {\n mkdirSync(join(this.sessionCacheDir, subdir), { recursive: true });\n }\n logger.info(`CodeQLServerManager initialized (session: ${this.sessionId})`);\n }\n\n // ---- Public API ----\n\n /**\n * Get the current session ID.\n */\n getSessionId(): string {\n return this.sessionId;\n }\n\n /**\n * Get the session-specific cache directory.\n */\n getCacheDir(): string {\n return this.sessionCacheDir;\n }\n\n /**\n * Return the session-specific log directory.\n */\n getLogDir(): string {\n return join(this.sessionCacheDir, 'logs');\n }\n\n /**\n * Get or create a Language Server with the given configuration.\n *\n * If a language server is already running with the same config it is reused.\n * If the config has changed the old server is shut down first.\n */\n async getLanguageServer(config: LanguageServerConfig): Promise {\n const enriched = this.enrichConfig(config) as LanguageServerConfig;\n return this.getOrRestart('language', enriched, () => {\n // Convert LanguageServerConfig to the LanguageServerOptions the existing class expects\n return new CodeQLLanguageServer({\n loglevel: enriched.loglevel,\n logdir: enriched.logdir,\n searchPath: enriched.searchPath,\n synchronous: enriched.synchronous,\n verbosity: enriched.verbosity,\n });\n }) as Promise;\n }\n\n /**\n * Get or create a Query Server with the given configuration.\n */\n async getQueryServer(config: QueryServerConfig): Promise {\n const enriched = this.enrichConfig(config) as QueryServerConfig;\n return this.getOrRestart('query', enriched, () => {\n return new CodeQLQueryServer(enriched);\n }) as Promise;\n }\n\n /**\n * Get or create a CLI Server with the given configuration.\n */\n async getCLIServer(config: CLIServerConfig): Promise {\n const enriched = this.enrichConfig(config) as CLIServerConfig;\n return this.getOrRestart('cli', enriched, () => {\n return new CodeQLCLIServer(enriched);\n }) as Promise;\n }\n\n /**\n * Shut down a specific server type.\n */\n async shutdownServer(type: CodeQLServerType): Promise {\n const managed = this.servers.get(type);\n if (!managed) return;\n\n logger.info(`Shutting down ${type} server (session: ${managed.sessionId})`);\n await this.stopServer(managed);\n this.servers.delete(type);\n }\n\n /**\n * Shut down all managed servers.\n */\n async shutdownAll(): Promise {\n logger.info(`Shutting down all servers for session: ${this.sessionId}`);\n const shutdownPromises = Array.from(this.servers.entries()).map(\n async ([type, managed]) => {\n try {\n await this.stopServer(managed);\n } catch (error) {\n logger.error(`Error shutting down ${type} server:`, error);\n }\n },\n );\n await Promise.all(shutdownPromises);\n this.servers.clear();\n logger.info('All servers shut down');\n }\n\n /**\n * Check whether a server of the given type is currently running.\n */\n isRunning(type: CodeQLServerType): boolean {\n const managed = this.servers.get(type);\n if (!managed) return false;\n return managed.server.isRunning();\n }\n\n /**\n * Get status information for all managed servers.\n */\n getStatus(): Record {\n const status: Record = {\n cli: null,\n language: null,\n query: null,\n };\n for (const [type, managed] of this.servers) {\n status[type] = {\n configHash: managed.configHash,\n running: managed.server.isRunning(),\n sessionId: managed.sessionId,\n };\n }\n return status as Record;\n }\n\n // ---- Private helpers ----\n\n /**\n * Eagerly start the language server so the JVM is warm when the first\n * LSP tool call arrives. Uses the default configuration that\n * `lsp-handlers.ts` / `lsp-diagnostics.ts` would create on the first\n * `getLanguageServer()` call. The server is stored in the managed-servers\n * map and reused by subsequent tool invocations.\n *\n * This is fire-and-forget: errors are logged but do not prevent the MCP\n * server from starting.\n */\n async warmUpLanguageServer(): Promise {\n try {\n // Lazy-import to avoid circular dependency at module level\n const { packageRootDir } = await import('../utils/package-paths');\n const { resolve } = await import('path');\n\n const config: LanguageServerConfig = {\n checkErrors: 'ON_CHANGE',\n loglevel: 'WARN',\n searchPath: resolve(packageRootDir, 'ql'),\n };\n logger.info('Warming up language server (background JVM start)...');\n await this.getLanguageServer(config);\n logger.info('Language server warm-up complete');\n } catch (error) {\n logger.warn('Language server warm-up failed (will retry on first tool call):', error);\n }\n }\n\n /**\n * Eagerly start the CLI server so the JVM is warm when the first\n * `executeCodeQLCommand()` call routes through it.\n *\n * The CLI server uses only session-scoped `commonCaches` and `logdir`,\n * both injected by `enrichConfig()`. Passing an empty config is\n * intentional \u2014 it matches what `executeCodeQLCommand()` will request.\n *\n * Fire-and-forget: errors are logged but do not block startup.\n */\n async warmUpCLIServer(): Promise {\n try {\n logger.info('Warming up CLI server (background JVM start)...');\n await this.getCLIServer({});\n logger.info('CLI server warm-up complete');\n } catch (error) {\n logger.warn('CLI server warm-up failed (will retry on first tool call):', error);\n }\n }\n\n /**\n * Enrich a config with session-specific defaults for commonCaches and logdir.\n */\n private enrichConfig(config: T): T {\n return {\n ...config,\n commonCaches: config.commonCaches ?? this.sessionCacheDir,\n logdir: config.logdir ?? this.getLogDir(),\n };\n }\n\n /**\n * Get an existing server if its config matches, otherwise stop the old\n * one and start a new server.\n *\n * Concurrent calls for the same server type are serialized via\n * `pendingStarts` to avoid spawning duplicate server processes.\n */\n private async getOrRestart(\n type: CodeQLServerType,\n config: ServerConfig,\n factory: () => CodeQLCLIServer | CodeQLLanguageServer | CodeQLQueryServer,\n ): Promise {\n // If another call is already starting a server of this type, wait for it\n // to settle (success or failure) and then re-check whether the result is\n // still usable.\n const inflight = this.pendingStarts.get(type);\n if (inflight) {\n try { await inflight; } catch { /* swallow \u2014 original caller handles the rejection */ }\n }\n\n const work = this.doGetOrRestart(type, config, factory);\n this.pendingStarts.set(type, work);\n try {\n return await work;\n } finally {\n // Ensure `work` has settled before removing the pendingStarts entry so\n // that concurrent callers waiting on the same promise see a consistent\n // map state. The try/catch avoids re-throwing a rejection that the\n // outer `try` block already handles.\n try { await work; } catch { /* already handled */ }\n if (this.pendingStarts.get(type) === work) {\n this.pendingStarts.delete(type);\n }\n }\n }\n\n /**\n * Core logic for getOrRestart, separated to allow serialization.\n */\n private async doGetOrRestart(\n type: CodeQLServerType,\n config: ServerConfig,\n factory: () => CodeQLCLIServer | CodeQLLanguageServer | CodeQLQueryServer,\n ): Promise {\n const hash = computeConfigHash(type, config);\n const existing = this.servers.get(type);\n\n // Reuse if config matches and server is still running\n if (existing && existing.configHash === hash && existing.server.isRunning()) {\n logger.debug(`Reusing existing ${type} server (hash: ${hash.substring(0, 8)})`);\n return existing.server;\n }\n\n // Config changed or server died \u2014 stop the old one\n if (existing) {\n logger.info(`${type} server config changed or dead, restarting...`);\n await this.stopServer(existing);\n this.servers.delete(type);\n }\n\n // Start a new server\n const server = factory();\n await server.start();\n\n this.servers.set(type, {\n configHash: hash,\n server,\n sessionId: this.sessionId,\n type,\n });\n\n logger.info(`${type} server started (hash: ${hash.substring(0, 8)})`);\n return server;\n }\n\n /**\n * Stop a managed server, ignoring errors.\n */\n private async stopServer(managed: ManagedServer): Promise {\n try {\n await managed.server.shutdown();\n } catch (error) {\n logger.warn(`Error stopping ${managed.type} server:`, error);\n // Best-effort \u2014 don't propagate\n }\n }\n}\n\n/**\n * Global server manager singleton.\n *\n * Initialized lazily by `getServerManager()`. The MCP server entry point\n * should call `initServerManager()` at startup and `shutdownServerManager()`\n * at graceful shutdown.\n */\nlet globalServerManager: CodeQLServerManager | null = null;\n\n/**\n * Initialize the global server manager (idempotent).\n */\nexport function initServerManager(options?: SessionCacheOptions): CodeQLServerManager {\n if (!globalServerManager) {\n globalServerManager = new CodeQLServerManager(options);\n }\n return globalServerManager;\n}\n\n/**\n * Get the global server manager, creating it if needed.\n */\nexport function getServerManager(): CodeQLServerManager {\n if (!globalServerManager) {\n globalServerManager = new CodeQLServerManager();\n }\n return globalServerManager;\n}\n\n/**\n * Shut down the global server manager and all its servers.\n */\nexport async function shutdownServerManager(): Promise {\n if (globalServerManager) {\n await globalServerManager.shutdownAll();\n globalServerManager = null;\n }\n}\n\n/**\n * Reset the global server manager (for testing only).\n */\nexport function resetServerManager(): void {\n globalServerManager = null;\n}\n", "/**\n * Generic CLI command execution utilities for CodeQL and QLT commands\n */\n\nimport { execFile } from 'child_process';\nimport { existsSync } from 'fs';\nimport { basename, delimiter, dirname, isAbsolute } from 'path';\nimport { promisify } from 'util';\nimport { logger } from '../utils/logger';\n\nconst execFileAsync = promisify(execFile);\n\nexport interface CLIExecutionResult {\n stdout: string;\n stderr: string;\n success: boolean;\n error?: string;\n exitCode?: number;\n}\n\nexport interface CLIExecutionOptions {\n command: string;\n args: string[];\n cwd?: string;\n timeout?: number;\n env?: Record;\n}\n\n// Whitelist of allowed commands to prevent arbitrary command execution\nconst ALLOWED_COMMANDS = new Set([\n 'codeql',\n 'git',\n 'node',\n 'npm',\n 'qlt',\n 'which'\n]);\n\n// Additional commands allowed in test environments\nlet testCommands: Set | null = null;\n\n// Whitelist of safe environment variables to pass to child processes\n// This prevents potentially malicious environment variables from being passed through\nconst SAFE_ENV_VARS = [\n 'HOME', // User home directory\n 'LANG', // Locale setting\n 'LC_ALL', // Locale setting\n 'LC_CTYPE', // Locale setting\n 'PATH', // Required to find executables\n 'SHELL', // User's shell (Unix)\n 'TEMP', // Temporary directory (Windows)\n 'TERM', // Terminal type (Unix)\n 'TMP', // Temporary directory (Windows)\n 'TMPDIR', // Temporary directory (Unix)\n 'USER', // Current user (Unix)\n 'USERNAME', // Current user (Windows)\n] as const;\n\n// Whitelist of safe environment variable prefixes\n// These are needed for CodeQL and Node.js functionality\nconst SAFE_ENV_PREFIXES = [\n 'CODEQL_', // CodeQL-specific variables\n 'NODE_', // Node.js-specific variables (for npm, etc.)\n] as const;\n\n// Pattern for dangerous control characters in CLI arguments\n// Rejected characters:\n// \\x01-\\x08: SOH through BS (start of heading, text, null control chars, backspace)\n// \\x0B: Vertical tab - rarely used legitimately, can cause display issues\n// \\x0C: Form feed - can cause unexpected page breaks in output\n// \\x0E-\\x1F: SO through US (shift out/in, device controls, separators)\n// Allowed characters:\n// \\x00: Null byte - handled separately for clearer error messaging\n// \\x09: Horizontal tab - commonly used in file paths and arguments\n// \\x0A: Newline (LF) - may appear in multi-line arguments\n// \\x0D: Carriage return (CR) - may appear with newlines on Windows\n// eslint-disable-next-line no-control-regex\nconst DANGEROUS_CONTROL_CHARS = /[\\x01-\\x08\\x0B\\x0C\\x0E-\\x1F]/;\n\n/**\n * Enable test-specific commands for testing purposes\n * This should only be called in test environments\n */\nexport function enableTestCommands(): void {\n testCommands = new Set([\n 'cat',\n 'echo',\n 'ls',\n 'sh',\n 'sleep'\n ]);\n}\n\n/**\n * Disable test-specific commands\n */\nexport function disableTestCommands(): void {\n testCommands = null;\n}\n\n/**\n * Check if a command is allowed\n */\nfunction isCommandAllowed(command: string): boolean {\n return ALLOWED_COMMANDS.has(command) || (testCommands !== null && testCommands.has(command));\n}\n\n// Resolved CodeQL binary directory from CODEQL_PATH.\n// When set, this directory is prepended to PATH for all child processes\n// so that `execFile('codeql', ...)` finds the correct binary via execvp().\n// Using PATH lookup (rather than an absolute path) is essential because\n// execvp() handles shell-script shebangs correctly, whereas passing an\n// absolute path to execFile() can fail with ENOENT for shell scripts.\nlet resolvedCodeQLDir: string | null = null;\n\n// Cached result from resolveCodeQLBinary(). `undefined` means not yet resolved.\nlet resolvedBinaryResult: string | undefined;\n\n/**\n * Resolve the CodeQL CLI binary path.\n *\n * Resolution order:\n * 1. `CODEQL_PATH` environment variable \u2014 must point to an existing file whose\n * basename is `codeql` (or `codeql.exe` / `codeql.cmd` on Windows).\n * The parent directory is prepended to PATH for child processes.\n * 2. Falls back to the bare `codeql` command (resolved via PATH at exec time).\n *\n * The resolved value is cached for the lifetime of the process. Call this once\n * at startup; subsequent calls are a no-op and return the cached value.\n */\nexport function resolveCodeQLBinary(): string {\n // Short-circuit if already resolved\n if (resolvedBinaryResult !== undefined) {\n return resolvedBinaryResult;\n }\n\n const envPath = process.env.CODEQL_PATH;\n\n if (!envPath) {\n resolvedCodeQLDir = null;\n resolvedBinaryResult = 'codeql';\n return resolvedBinaryResult;\n }\n\n // Validate the path points to a plausible CodeQL binary\n const base = basename(envPath).toLowerCase();\n const validBaseNames = ['codeql', 'codeql.exe', 'codeql.cmd'];\n if (!validBaseNames.includes(base)) {\n throw new Error(\n `CODEQL_PATH must point to a CodeQL CLI binary (expected basename: codeql), got: ${base}`\n );\n }\n\n // Require an absolute path to avoid ambiguity\n if (!isAbsolute(envPath)) {\n throw new Error(\n `CODEQL_PATH must be an absolute path, got: ${envPath}`\n );\n }\n\n // Verify the file exists\n if (!existsSync(envPath)) {\n throw new Error(\n `CODEQL_PATH points to a file that does not exist: ${envPath}`\n );\n }\n\n resolvedCodeQLDir = dirname(envPath);\n resolvedBinaryResult = 'codeql';\n logger.info(`CodeQL CLI resolved via CODEQL_PATH: ${envPath} (dir: ${resolvedCodeQLDir})`);\n return resolvedBinaryResult;\n}\n\n/**\n * Get the currently resolved CodeQL binary directory, or null if using PATH.\n */\nexport function getResolvedCodeQLDir(): string | null {\n return resolvedCodeQLDir;\n}\n\n/**\n * Reset the resolved CodeQL binary to the default (for testing only).\n */\nexport function resetResolvedCodeQLBinary(): void {\n resolvedCodeQLDir = null;\n resolvedBinaryResult = undefined;\n}\n\n/**\n * Validate that the resolved CodeQL binary is actually callable.\n *\n * Runs `codeql version --format=terse` and verifies the process exits\n * successfully. This catches the case where `CODEQL_PATH` is unset and\n * `codeql` is not on PATH \u2014 the server would otherwise start normally\n * but every tool invocation would fail.\n *\n * @returns The version string reported by the CodeQL CLI.\n * @throws Error if the binary is not reachable or returns a non-zero exit code.\n */\nexport async function validateCodeQLBinaryReachable(): Promise {\n const binary = resolvedBinaryResult ?? 'codeql';\n const env = { ...process.env };\n if (resolvedCodeQLDir) {\n env.PATH = resolvedCodeQLDir + delimiter + (env.PATH || '');\n }\n\n try {\n const { stdout } = await execFileAsync(binary, ['version', '--format=terse'], {\n env,\n timeout: 15_000,\n });\n return stdout.trim();\n } catch (err: unknown) {\n const message = err instanceof Error ? err.message : String(err);\n throw new Error(\n `CodeQL CLI is not reachable (binary: ${binary}). ` +\n `Ensure codeql is on PATH or set the CODEQL_PATH environment variable ` +\n `to the absolute path of the CodeQL CLI binary. Details: ${message}`\n );\n }\n}\n\n/**\n * Sanitize a CLI argument to prevent potential issues with special characters.\n * \n * While execFile() does not spawn a shell (preventing shell injection), we still\n * validate arguments to:\n * 1. Reject null bytes that could truncate strings in C-based commands\n * 2. Reject control characters that could cause unexpected behavior\n * 3. Provide defense-in-depth against potential issues\n * \n * @param arg - The argument to sanitize\n * @returns The sanitized argument\n * @throws Error if the argument contains dangerous characters\n */\nexport function sanitizeCLIArgument(arg: string): string {\n // Reject null bytes - these can truncate strings in C-based commands\n // Error message intentionally excludes argument content to avoid logging potentially sensitive data\n if (arg.includes('\\0')) {\n throw new Error(`CLI argument contains null byte: argument rejected for security`);\n }\n \n // Reject control characters using the module-level constant pattern\n if (DANGEROUS_CONTROL_CHARS.test(arg)) {\n // Error message intentionally excludes argument content to avoid logging potentially sensitive data\n throw new Error(`CLI argument contains control characters: argument rejected for security`);\n }\n \n return arg;\n}\n\n/**\n * Sanitize an array of CLI arguments\n * @param args - The arguments to sanitize\n * @returns The sanitized arguments\n * @throws Error if any argument contains dangerous characters\n */\nexport function sanitizeCLIArguments(args: string[]): string[] {\n return args.map(sanitizeCLIArgument);\n}\n\n/**\n * Filter environment variables to only include safe ones\n * This prevents potentially malicious environment variables from being passed to child processes\n */\nfunction getSafeEnvironment(additionalEnv?: Record): Record {\n const safeEnv: Record = {};\n \n // Copy whitelisted environment variables from process.env\n for (const key of SAFE_ENV_VARS) {\n if (process.env[key] !== undefined) {\n safeEnv[key] = process.env[key]!;\n }\n }\n \n // Copy environment variables with whitelisted prefixes\n for (const [key, value] of Object.entries(process.env)) {\n if (value !== undefined && SAFE_ENV_PREFIXES.some(prefix => key.startsWith(prefix))) {\n safeEnv[key] = value;\n }\n }\n \n // When CODEQL_PATH was set, prepend the resolved directory to PATH so that\n // `execFile('codeql', ...)` finds the user-specified binary via execvp().\n // This approach (PATH manipulation + bare command name) is essential because\n // execvp() handles shell-script shebangs correctly, whereas passing an\n // absolute path to execFile() fails with ENOENT for shell-script launchers.\n if (resolvedCodeQLDir && safeEnv.PATH) {\n safeEnv.PATH = `${resolvedCodeQLDir}${delimiter}${safeEnv.PATH}`;\n } else if (resolvedCodeQLDir) {\n safeEnv.PATH = resolvedCodeQLDir;\n }\n \n // Merge with explicitly provided environment variables\n // These are trusted as they come from the application code, not external sources\n if (additionalEnv) {\n Object.assign(safeEnv, additionalEnv);\n }\n \n return safeEnv;\n}\n\n/**\n * Execute a CLI command and return the result.\n * \n * Security: This function uses execFile() instead of exec() to avoid shell interpretation.\n * Arguments are passed directly to the executable as an array, preventing shell injection.\n * Additional security measures include:\n * - Command whitelist validation\n * - Shell metacharacter detection in command names\n * - CLI argument sanitization (null bytes, control characters)\n * - Environment variable filtering\n */\nexport async function executeCLICommand(options: CLIExecutionOptions): Promise {\n try {\n const { command, args, cwd, timeout = 300000, env } = options; // 5 minute default timeout\n \n // Validate command is in the whitelist to prevent arbitrary command execution\n if (!isCommandAllowed(command)) {\n throw new Error(`Command not allowed: ${command}. Only whitelisted commands can be executed.`);\n }\n \n // Validate command to ensure it doesn't contain shell metacharacters\n if (command.includes(';') || command.includes('|') || command.includes('&') || \n command.includes('$') || command.includes('`') || command.includes('\\n') ||\n command.includes('\\r')) {\n throw new Error(`Invalid command: contains shell metacharacters: ${command}`);\n }\n \n // Sanitize CLI arguments to prevent issues with special characters\n // This provides defense-in-depth even though execFile() doesn't use a shell\n const sanitizedArgs = sanitizeCLIArguments(args);\n \n logger.info(`Executing CLI command: ${command}`, { args: sanitizedArgs, cwd, timeout });\n \n const execOptions = {\n cwd,\n timeout,\n env: getSafeEnvironment(env),\n };\n \n // execFile() is used instead of exec() to avoid shell interpretation\n // Arguments are passed as an array, not interpolated into a command string\n const { stdout, stderr } = await execFileAsync(command, sanitizedArgs, execOptions);\n\n return {\n stdout,\n stderr,\n success: true,\n exitCode: 0\n };\n\n } catch (error: unknown) {\n logger.error('CLI command execution failed:', error);\n \n const err = error as Error & { code?: number; stdout?: string; stderr?: string };\n const errorMessage = err instanceof Error ? err.message : String(error);\n const exitCode = err.code || 1;\n \n return {\n stdout: err.stdout || '',\n stderr: err.stderr || errorMessage,\n success: false,\n error: errorMessage,\n exitCode\n };\n }\n}\n\n/**\n * Build CodeQL command arguments with proper escaping\n */\nexport function buildCodeQLArgs(subcommand: string, options: Record): string[] {\n const args = [subcommand];\n \n // Single-letter parameters that should use -key=value format (with equals sign)\n // Note: CodeQL CLI uses -t=key=value format for metadata, not -t key=value\n const singleLetterParams = new Set(['t', 'o', 'v', 'q', 'h', 'J']);\n \n for (const [key, value] of Object.entries(options)) {\n if (value === undefined || value === null) {\n continue;\n }\n \n const isSingleLetter = key.length === 1 && singleLetterParams.has(key);\n \n if (typeof value === 'boolean') {\n if (value) {\n args.push(isSingleLetter ? `-${key}` : `--${key}`);\n }\n } else if (Array.isArray(value)) {\n // Handle array values (e.g., multiple -t flags for metadata)\n for (const item of value) {\n if (isSingleLetter) {\n // For single-letter params like -t, use -key=value format\n args.push(`-${key}=${String(item)}`);\n } else {\n // For long params, use --key=value format\n args.push(`--${key}=${String(item)}`);\n }\n }\n } else {\n // Handle string, number, and other values\n if (isSingleLetter) {\n // For single-letter params, use -key=value format\n args.push(`-${key}=${String(value)}`);\n } else {\n args.push(`--${key}=${String(value)}`);\n }\n }\n }\n \n return args;\n}\n\n/**\n * Build QLT command arguments with proper escaping\n */\nexport function buildQLTArgs(subcommand: string, options: Record): string[] {\n const args = [subcommand];\n \n for (const [key, value] of Object.entries(options)) {\n if (value === undefined || value === null) {\n continue;\n }\n \n if (typeof value === 'boolean') {\n if (value) {\n args.push(`--${key}`);\n }\n } else if (Array.isArray(value)) {\n // Handle array values\n for (const item of value) {\n args.push(`--${key}`, String(item));\n }\n } else {\n // Handle string, number, and other values\n args.push(`--${key}`, String(value));\n }\n }\n \n return args;\n}\n\n/**\n * CodeQL subcommands that MUST run as fresh processes.\n *\n * These cannot use the cli-server because they:\n * - Spawn extractors or other long-running child processes (database create, test extract)\n * - Produce multi-event NUL-delimited streams (test run)\n * - Are compound orchestration commands (database analyze)\n *\n * Everything else is routed through the persistent cli-server JVM for\n * sub-second execution instead of 2-5 s JVM cold-start per invocation.\n */\nconst FRESH_PROCESS_SUBCOMMANDS = new Set([\n 'database analyze',\n 'database create',\n 'test extract',\n 'test run',\n]);\n\n/**\n * Execute a CodeQL command.\n *\n * By default, commands are routed through the persistent `codeql execute\n * cli-server` process managed by {@link CodeQLServerManager}, eliminating\n * repeated JVM startup overhead (~2-5 s savings per call).\n *\n * Commands listed in {@link FRESH_PROCESS_SUBCOMMANDS} (e.g. `database create`,\n * `test run`) are always executed as fresh processes because they either spawn\n * child extractors, produce streaming output, or require a dedicated working\n * directory.\n *\n * If the cli-server is not available (e.g. during early startup before\n * `initServerManager()` is called), the function falls back transparently to\n * a fresh process.\n */\nexport async function executeCodeQLCommand(\n subcommand: string,\n options: Record,\n additionalArgs: string[] = [],\n cwd?: string\n): Promise {\n const args = buildCodeQLArgs(subcommand, options);\n args.push(...additionalArgs);\n\n // Determine whether this subcommand can use the persistent cli-server.\n // Commands that need a specific CWD also must use a fresh process because\n // the cli-server's CWD is fixed at startup.\n const canUseCLIServer = !FRESH_PROCESS_SUBCOMMANDS.has(subcommand) && !cwd;\n\n if (canUseCLIServer) {\n try {\n // Lazy-import to avoid circular dependency at module level.\n // Use getServerManager() (not initServerManager()) \u2014 if the manager\n // hasn't been initialized yet (e.g. during tests or early startup),\n // this creates one, but we only attempt to *use* the cli-server if\n // it is already running (warmed up at MCP server startup). We never\n // block on starting a new cli-server here \u2014 that would add JVM\n // startup latency to the first fresh-process-fallback call.\n const { getServerManager } = await import('./server-manager');\n const manager = getServerManager();\n\n if (manager.isRunning('cli')) {\n const cliServer = await manager.getCLIServer({});\n const sanitizedArgs = sanitizeCLIArguments(args);\n\n logger.info(`Executing CodeQL command via cli-server: ${subcommand}`, { args: sanitizedArgs });\n\n const stdout = await cliServer.runCommand(sanitizedArgs);\n\n return {\n stdout,\n stderr: '',\n success: true,\n exitCode: 0,\n };\n } else {\n logger.debug(`cli-server not yet running for \"${subcommand}\", using fresh process`);\n }\n } catch (error) {\n // If the cli-server call fails, check whether it's a command-level\n // error (the CLI returned non-zero) or a transport/startup error.\n // For transport errors we fall back to a fresh process; for command\n // errors we return the failure directly.\n const message = error instanceof Error ? error.message : String(error);\n\n // Transport-level errors that warrant a fallback:\n if (message.includes('CLI server is not running') ||\n message.includes('CLI server exited') ||\n message.includes('failed to start')) {\n logger.warn(`cli-server unavailable for \"${subcommand}\", falling back to fresh process: ${message}`);\n // Fall through to fresh-process execution below\n } else {\n // Command-level error \u2014 return it as a failed result\n logger.error(`cli-server command failed for \"${subcommand}\": ${message}`);\n return {\n stdout: '',\n stderr: message,\n success: false,\n error: message,\n exitCode: 1,\n };\n }\n }\n }\n\n // Fresh-process execution (for FRESH_PROCESS_SUBCOMMANDS, CWD-specific\n // calls, or as a fallback when the cli-server is unavailable).\n // Use 0 (no timeout) because CodeQL operations such as query evaluation,\n // database analysis, profiling, and test runs are inherently long-running\n // and should not be killed by a process timeout.\n return executeCLICommand({\n command: 'codeql',\n args,\n cwd,\n timeout: 0\n });\n}\n\n/**\n * Execute a QLT command\n */\nexport async function executeQLTCommand(\n subcommand: string, \n options: Record, \n additionalArgs: string[] = []\n): Promise {\n const args = buildQLTArgs(subcommand, options);\n args.push(...additionalArgs);\n \n return executeCLICommand({\n command: 'qlt',\n args\n });\n}\n\n/**\n * Get help text for a CLI command\n */\nexport async function getCommandHelp(command: string, subcommand?: string): Promise {\n const args = subcommand ? [subcommand, '--help'] : ['--help'];\n \n const result = await executeCLICommand({\n command,\n args\n });\n \n return result.stdout || result.stderr || 'No help available';\n}\n\n/**\n * Validate that a command exists on the system.\n */\nexport async function validateCommandExists(command: string): Promise {\n try {\n const result = await executeCLICommand({\n command: 'which',\n args: [command]\n });\n return result.success;\n } catch {\n return false;\n }\n}", "/**\n * CodeQL Development MCP McpServer\n * Main entry point for the server\n */\n\nimport { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';\nimport { StreamableHTTPServerTransport } from '@modelcontextprotocol/sdk/server/streamableHttp.js';\nimport express from 'express';\nimport cors from 'cors';\nimport dotenv from 'dotenv';\nimport { realpathSync } from 'fs';\nimport { resolve } from 'path';\nimport { pathToFileURL } from 'url';\nimport { registerCodeQLTools, registerCodeQLResources } from './tools';\nimport { registerLSPTools } from './tools/lsp';\nimport { registerLanguageResources } from './resources/language-resources';\nimport { registerWorkflowPrompts } from './prompts/workflow-prompts';\nimport { registerMonitoringTools } from './tools/monitoring-tools';\nimport { sessionDataManager } from './lib/session-data-manager';\nimport { resolveCodeQLBinary, validateCodeQLBinaryReachable } from './lib/cli-executor';\nimport { initServerManager, shutdownServerManager } from './lib/server-manager';\nimport { packageRootDir } from './utils/package-paths';\nimport { logger } from './utils/logger';\n\n// Load environment variables from a .env file co-located with the package root.\n// Uses the package directory (not CWD) so that npm-installed users don't\n// accidentally inherit a .env from their project.\n// Set DOTENV_CONFIG_QUIET to suppress the dotenv banner that would otherwise\n// leak to stdout and corrupt the MCP stdio JSON-RPC channel.\ndotenv.config({ path: resolve(packageRootDir, '.env'), quiet: true });\n\nconst PACKAGE_NAME = 'codeql-development-mcp-server';\nconst VERSION = '2.24.1';\n\n/**\n * Start the MCP server\n */\nexport async function startServer(mode: 'stdio' | 'http' = 'stdio'): Promise {\n logger.info(`Starting CodeQL Development MCP McpServer v${VERSION} in ${mode} mode`);\n\n // Resolve the CodeQL CLI binary path (honors CODEQL_PATH env var).\n // This must happen before any tool registration so that all CodeQL commands\n // use the user-specified binary.\n const codeqlBinary = resolveCodeQLBinary();\n logger.info(`CodeQL CLI binary: ${codeqlBinary}`);\n\n // Validate that the resolved binary is actually callable. This catches\n // misconfigurations early (e.g. codeql not on PATH and CODEQL_PATH unset)\n // instead of failing silently and producing confusing tool-level errors.\n const codeqlVersion = await validateCodeQLBinaryReachable();\n logger.info(`CodeQL CLI version: ${codeqlVersion}`);\n\n const server = new McpServer({\n name: PACKAGE_NAME,\n version: VERSION,\n });\n\n // Register CodeQL tools (legacy high-level helpers)\n registerCodeQLTools(server);\n\n // Register LSP-based tools (diagnostics, completion, definition, references)\n registerLSPTools(server);\n\n // Register CodeQL resources (static guides)\n registerCodeQLResources(server);\n\n // Register language-specific resources (AST references, security patterns)\n registerLanguageResources(server);\n\n // Register high-level workflow prompts (complete development workflows)\n registerWorkflowPrompts(server);\n\n // Register monitoring and reporting tools\n registerMonitoringTools(server);\n\n // Initialize session data manager\n await sessionDataManager.initialize();\n\n // Initialize the CodeQL background server manager and eagerly start the\n // language server and CLI server JVMs so they are warm when the first tool\n // calls arrive. This avoids 2-60 s cold-start penalties per JVM.\n const manager = initServerManager();\n Promise.all([\n manager.warmUpLanguageServer(),\n manager.warmUpCLIServer(),\n ]).catch(() => { /* individual errors logged inside each warm-up method */ });\n\n if (mode === 'stdio') {\n const transport = new StdioServerTransport();\n await server.connect(transport);\n logger.info('McpServer started successfully on STDIO transport');\n } else {\n // HTTP mode\n const app = express();\n app.use(cors());\n app.use(express.json());\n\n const transport = new StreamableHTTPServerTransport({\n sessionIdGenerator: () => Math.random().toString(36).substring(7),\n });\n await server.connect(transport);\n\n app.all('/mcp', (req, res) => {\n transport.handleRequest(req, res, req.body).catch((err) => {\n logger.error('Error handling MCP request:', err);\n if (!res.headersSent) {\n res.status(500).json({ error: 'Internal McpServer Error' });\n }\n });\n });\n\n app.get('/', (_req, res) => {\n res.json({\n name: PACKAGE_NAME,\n version: VERSION,\n description: 'CodeQL Development MCP McpServer',\n status: 'running',\n });\n });\n\n const host = process.env.HTTP_HOST || 'localhost';\n const port = Number(process.env.HTTP_PORT || process.env.PORT) || 3000;\n \n // Return a promise that keeps the process alive\n return new Promise((resolve, reject) => {\n const httpServer = app.listen(port, host, () => {\n logger.info(`HTTP server listening on http://${host}:${port}/mcp`);\n resolve();\n });\n \n httpServer.on('error', (error) => {\n logger.error('HTTP server error:', error);\n reject(error);\n });\n });\n }\n\n setupGracefulShutdown(server);\n return server;\n}\n\n/**\n * Set up graceful shutdown handling\n */\nfunction setupGracefulShutdown(server: McpServer): void {\n const shutdown = async () => {\n logger.info('Shutting down server...');\n try {\n // Shut down all CodeQL background servers first\n await shutdownServerManager();\n await server.close();\n logger.info('McpServer closed gracefully');\n process.exit(0);\n } catch (error) {\n logger.error('Error during shutdown:', error);\n process.exit(1);\n }\n };\n\n process.on('SIGINT', shutdown);\n process.on('SIGTERM', shutdown);\n}\n\n/**\n * Main function to start the server\n */\nasync function main(): Promise {\n try {\n const transportMode = (process.env.TRANSPORT_MODE || 'stdio').toLowerCase();\n const mode: 'stdio' | 'http' = transportMode === 'http' ? 'http' : 'stdio';\n await startServer(mode);\n } catch (error) {\n logger.error('Failed to start server:', error);\n process.exit(1);\n }\n}\n\n// Start the server if this file is run directly.\n// Use realpathSync to resolve npm/npx symlinks so the guard works for both\n// direct invocation and globally-installed npm bin entries.\nconst scriptPath = process.argv[1] ? realpathSync(resolve(process.argv[1])) : undefined;\nif (scriptPath && import.meta.url === pathToFileURL(scriptPath).href) {\n main();\n}\n", "/**\n * CodeQL BQRS decode tool\n */\n\nimport { z } from 'zod';\nimport { CLIToolDefinition, createCodeQLSchemas, createBQRSResultProcessor } from '../../lib/cli-tool-registry';\n\nexport const codeqlBqrsDecodeTool: CLIToolDefinition = {\n name: 'codeql_bqrs_decode',\n description: 'Decode BQRS result files to human-readable formats',\n command: 'codeql',\n subcommand: 'bqrs decode',\n inputSchema: {\n files: z.array(z.string()).describe('BQRS file(s) to decode'),\n output: createCodeQLSchemas.output(),\n format: z.enum(['csv', 'json']).optional().describe('Output format'),\n 'max-paths': z.number().optional().describe('Maximum number of paths to output'),\n 'start-at': z.number().optional().describe('Start output at result number'),\n 'max-results': z.number().optional().describe('Maximum number of results'),\n verbose: createCodeQLSchemas.verbose(),\n additionalArgs: createCodeQLSchemas.additionalArgs()\n },\n examples: [\n 'codeql bqrs decode --format=csv --output=results.csv results.bqrs',\n 'codeql bqrs decode --format=json --max-results=100 results.bqrs'\n ],\n resultProcessor: createBQRSResultProcessor()\n};", "/**\n * Generic tool registry for creating MCP tools from CLI command definitions\n */\n\nimport { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport { z } from 'zod';\nimport { executeCodeQLCommand, executeQLTCommand, CLIExecutionResult } from './cli-executor';\nimport { logger } from '../utils/logger';\nimport { evaluateQueryResults, QueryEvaluationResult, extractQueryMetadata } from './query-results-evaluator';\nimport { getOrCreateLogDirectory } from './log-directory-manager';\nimport { getUserWorkspaceDir, packageRootDir, resolveToolQueryPackPath } from '../utils/package-paths';\nimport { writeFileSync, rmSync, existsSync, mkdirSync } from 'fs';\nimport { basename, dirname, isAbsolute, join, resolve } from 'path';\nimport { createProjectTempDir } from '../utils/temp-dir';\n\nexport type { CLIExecutionResult } from './cli-executor';\n\nexport interface CLIToolDefinition {\n name: string;\n description: string;\n command: 'codeql' | 'qlt';\n subcommand: string;\n inputSchema: Record;\n examples?: string[];\n resultProcessor?: (_result: CLIExecutionResult, _params: Record) => string;\n}\n\n/**\n * Default result processor that formats CLI output appropriately\n */\nexport const defaultCLIResultProcessor = (\n result: CLIExecutionResult, \n _params: Record\n): string => {\n if (!result.success) {\n return `Command failed (exit code ${result.exitCode || 'unknown'}):\\n${result.error || result.stderr}`;\n }\n \n let output = '';\n \n if (result.stdout) {\n output += result.stdout;\n }\n \n if (result.stderr) {\n if (output) {\n output += '\\n\\nWarnings/Info:\\n';\n }\n output += result.stderr;\n }\n \n if (!output) {\n output = 'Command executed successfully (no output)';\n }\n \n return output;\n};\n\n/**\n * Register a CLI tool with the MCP server\n */\nexport function registerCLITool(server: McpServer, definition: CLIToolDefinition): void {\n const {\n name,\n description,\n command,\n subcommand,\n inputSchema,\n resultProcessor = defaultCLIResultProcessor\n } = definition;\n\n server.tool(\n name,\n description,\n inputSchema,\n async (params: Record) => {\n // Track temporary directories for cleanup\n const tempDirsToCleanup: string[] = [];\n \n try {\n logger.info(`Executing CLI tool: ${name}`, { command, subcommand, params });\n\n // Separate positional arguments from named options\n // Extract tool-specific parameters that should not be passed to CLI\n // Note: format is extracted for tools that use it internally but not on CLI\n // For codeql_bqrs_interpret, codeql_bqrs_decode, codeql_generate_query-help, and codeql_database_analyze, format should be passed to CLI\n const formatShouldBePassedToCLI = name === 'codeql_bqrs_interpret' || name === 'codeql_bqrs_decode' || name === 'codeql_generate_query-help' || name === 'codeql_database_analyze';\n \n const extractedParams = formatShouldBePassedToCLI\n ? {\n _positional: params._positional || [],\n files: params.files,\n file: params.file,\n dir: params.dir,\n packDir: params.packDir,\n tests: params.tests,\n query: params.query,\n queryName: params.queryName,\n queryLanguage: params.queryLanguage,\n queryPack: params.queryPack,\n sourceFiles: params.sourceFiles,\n sourceFunction: params.sourceFunction,\n targetFunction: params.targetFunction,\n interpretedOutput: params.interpretedOutput,\n evaluationFunction: params.evaluationFunction,\n evaluationOutput: params.evaluationOutput,\n directory: params.directory,\n logDir: params.logDir,\n qlref: params.qlref\n }\n : {\n _positional: params._positional || [],\n files: params.files,\n file: params.file,\n dir: params.dir,\n packDir: params.packDir,\n tests: params.tests,\n query: params.query,\n queryName: params.queryName,\n queryLanguage: params.queryLanguage,\n queryPack: params.queryPack, \n sourceFiles: params.sourceFiles,\n sourceFunction: params.sourceFunction,\n targetFunction: params.targetFunction,\n format: params.format,\n interpretedOutput: params.interpretedOutput,\n evaluationFunction: params.evaluationFunction,\n evaluationOutput: params.evaluationOutput,\n directory: params.directory,\n logDir: params.logDir,\n qlref: params.qlref\n };\n\n const {\n _positional = [],\n files,\n file,\n dir,\n packDir,\n tests,\n query,\n queryName,\n queryLanguage: _queryLanguage,\n queryPack: _queryPack,\n sourceFiles,\n sourceFunction,\n targetFunction,\n format: _format,\n interpretedOutput: _interpretedOutput,\n evaluationFunction: _evaluationFunction,\n evaluationOutput: _evaluationOutput,\n directory,\n logDir: customLogDir,\n qlref,\n } = extractedParams;\n\n // Get remaining options (everything not extracted above)\n const options = {...params};\n Object.keys(extractedParams).forEach(key => delete options[key]);\n let positionalArgs = Array.isArray(_positional) ? _positional as string[] : [_positional as string];\n\n // Handle files parameter as positional arguments for certain tools\n if (files && Array.isArray(files)) {\n positionalArgs = [...positionalArgs, ...files as string[]];\n }\n\n // Handle file parameter as positional argument for BQRS tools\n if (file && name.startsWith('codeql_bqrs_')) {\n positionalArgs = [...positionalArgs, file as string];\n }\n\n // Handle qlref parameter as positional argument for resolve qlref tool\n if (qlref && name === 'codeql_resolve_qlref') {\n positionalArgs = [...positionalArgs, qlref as string];\n }\n\n // Handle database parameter as positional argument for resolve database tool\n if (options.database && name === 'codeql_resolve_database') {\n positionalArgs = [...positionalArgs, options.database as string];\n delete options.database;\n }\n\n // Handle database parameter as positional argument for database create tool\n if (options.database && name === 'codeql_database_create') {\n positionalArgs = [...positionalArgs, options.database as string];\n delete options.database;\n }\n\n // Handle database and queries parameters as positional arguments for database analyze tool\n if (name === 'codeql_database_analyze') {\n if (options.database) {\n positionalArgs = [...positionalArgs, options.database as string];\n delete options.database;\n }\n if (options.queries) {\n positionalArgs = [...positionalArgs, options.queries as string];\n delete options.queries;\n }\n }\n\n // Handle query parameter as positional argument for generate query-help tool\n if (query && name === 'codeql_generate_query-help') {\n positionalArgs = [...positionalArgs, query as string];\n }\n\n // Handle dir parameter as positional argument for pack tools\n if (dir && (name === 'codeql_pack_ls')) {\n positionalArgs = [...positionalArgs, dir as string];\n }\n \n // Handle tool-specific parameters using switch pattern for better maintainability\n switch (name) {\n case 'codeql_test_accept':\n case 'codeql_test_extract':\n case 'codeql_test_run':\n case 'codeql_resolve_tests':\n // Handle tests parameter as positional arguments for test tools.\n // Resolve relative paths against the user's effective workspace\n // directory. In monorepo layouts this is the repo root; in npm-\n // installed layouts it falls back to process.cwd().\n if (tests && Array.isArray(tests)) {\n const userDir = getUserWorkspaceDir();\n positionalArgs = [...positionalArgs, ...(tests as string[]).map(\n t => isAbsolute(t) ? t : resolve(userDir, t)\n )];\n }\n break;\n \n case 'codeql_query_run': {\n // Resolve database path to absolute path if it's relative\n if (options.database && typeof options.database === 'string' && !isAbsolute(options.database)) {\n options.database = resolve(getUserWorkspaceDir(), options.database);\n logger.info(`Resolved database path to: ${options.database}`);\n }\n \n // Implement query resolution logic with enhanced results processing\n const resolvedQuery = await resolveQueryPath(params, logger);\n if (resolvedQuery) {\n positionalArgs = [...positionalArgs, resolvedQuery];\n } else if (query) {\n positionalArgs = [...positionalArgs, query as string];\n }\n \n // Handle external predicates for tool queries\n if (queryName === 'PrintAST' && sourceFiles) {\n // Create a CSV file with the source file paths for the external predicate\n // The external predicate expects a CSV file with one column containing file paths\n const filePaths = (sourceFiles as string).split(',').map((f: string) => f.trim());\n let tempDir: string;\n let csvPath: string;\n try {\n tempDir = createProjectTempDir('codeql-external-');\n tempDirsToCleanup.push(tempDir); // Track for cleanup\n csvPath = join(tempDir, 'selectedSourceFiles.csv');\n\n // Create CSV content\n const csvContent = filePaths.join('\\n') + '\\n';\n\n writeFileSync(csvPath, csvContent, 'utf8');\n } catch (err) {\n logger.error(`Failed to create external predicate CSV for PrintAST query at path ${csvPath || '[unknown]'}: ${err instanceof Error ? err.message : String(err)}`);\n throw err;\n }\n \n // Add the external predicate with the CSV file path\n const currentExternal = options.external || [];\n const externalArray = Array.isArray(currentExternal) ? currentExternal : [currentExternal];\n externalArray.push(`selectedSourceFiles=${csvPath}`);\n options.external = externalArray;\n \n logger.info(`Created external predicate CSV at ${csvPath} for files: ${filePaths.join(', ')}`);\n }\n \n // Handle external predicates for CallGraphFrom queries\n if (queryName === 'CallGraphFrom' && sourceFunction) {\n const functionNames = (sourceFunction as string).split(',').map((f: string) => f.trim());\n let tempDir: string;\n let csvPath: string;\n try {\n tempDir = createProjectTempDir('codeql-external-');\n tempDirsToCleanup.push(tempDir);\n csvPath = join(tempDir, 'sourceFunction.csv');\n\n // Create CSV content\n const csvContent = functionNames.join('\\n') + '\\n';\n\n writeFileSync(csvPath, csvContent, 'utf8');\n } catch (err) {\n logger.error(`Failed to create external predicate CSV for CallGraphFrom query at path ${csvPath || '[unknown]'}: ${err instanceof Error ? err.message : String(err)}`);\n throw err;\n }\n \n // Add the external predicate with the CSV file path\n const currentExternal = options.external || [];\n const externalArray = Array.isArray(currentExternal) ? currentExternal : [currentExternal];\n externalArray.push(`sourceFunction=${csvPath}`);\n options.external = externalArray;\n \n logger.info(`Created external predicate CSV at ${csvPath} for functions: ${functionNames.join(', ')}`);\n }\n \n // Handle external predicates for CallGraphTo queries\n if (queryName === 'CallGraphTo' && targetFunction) {\n const functionNames = (targetFunction as string).split(',').map((f: string) => f.trim());\n let tempDir: string;\n let csvPath: string;\n try {\n tempDir = createProjectTempDir('codeql-external-');\n tempDirsToCleanup.push(tempDir);\n csvPath = join(tempDir, 'targetFunction.csv');\n\n // Create CSV content\n const csvContent = functionNames.join('\\n') + '\\n';\n\n writeFileSync(csvPath, csvContent, 'utf8');\n } catch (err) {\n logger.error(`Failed to create external predicate CSV for CallGraphTo query at path ${csvPath || '[unknown]'}: ${err instanceof Error ? err.message : String(err)}`);\n throw err;\n }\n \n // Add the external predicate with the CSV file path\n const currentExternal = options.external || [];\n const externalArray = Array.isArray(currentExternal) ? currentExternal : [currentExternal];\n externalArray.push(`targetFunction=${csvPath}`);\n options.external = externalArray;\n \n logger.info(`Created external predicate CSV at ${csvPath} for functions: ${functionNames.join(', ')}`);\n }\n break;\n }\n \n case 'codeql_query_compile':\n case 'codeql_resolve_metadata':\n // Handle query parameter as positional argument for query compilation and metadata tools\n if (query) {\n positionalArgs = [...positionalArgs, query as string];\n }\n break;\n \n case 'codeql_resolve_queries':\n // Handle directory parameter as positional argument\n if (directory) {\n positionalArgs = [...positionalArgs, directory as string];\n }\n break;\n \n default:\n // No special parameter handling needed for other tools\n break;\n }\n\n // Set up logging directory for query/test/analyze runs\n let queryLogDir: string | undefined;\n if (name === 'codeql_query_run' || name === 'codeql_test_run' || name === 'codeql_database_analyze') {\n queryLogDir = getOrCreateLogDirectory(customLogDir as string | undefined);\n logger.info(`Using log directory for ${name}: ${queryLogDir}`);\n\n // Create timestamp file to track when query/test run started\n const timestampPath = join(queryLogDir, 'timestamp');\n writeFileSync(timestampPath, Date.now().toString(), 'utf8');\n\n // Set the --logdir option for CodeQL CLI\n options.logdir = queryLogDir;\n\n // Set verbosity to progress+ to generate detailed query.log/test.log\n if (!options.verbosity) {\n options.verbosity = 'progress+';\n }\n\n // Set evaluator-log if not explicitly provided\n if (!options['evaluator-log']) {\n options['evaluator-log'] = join(queryLogDir, 'evaluator-log.jsonl');\n }\n\n // Enable --tuple-counting by default for evaluator logging\n if (options['tuple-counting'] === undefined) {\n options['tuple-counting'] = true;\n }\n\n // For query run, also handle default output\n if (name === 'codeql_query_run') {\n // If output was not explicitly provided, set it to the log directory\n if (!options.output) {\n options.output = join(queryLogDir, 'results.bqrs');\n }\n }\n }\n\n let result: CLIExecutionResult;\n \n if (command === 'codeql') {\n // For pack commands, set the working directory to where qlpack.yml is located.\n // Resolve to absolute path since the MCP server's cwd may differ from\n // the workspace root (especially when launched by VS Code).\n let cwd: string | undefined;\n if ((name === 'codeql_pack_install' || name === 'codeql_pack_ls') && (dir || packDir)) {\n const rawCwd = (dir || packDir) as string;\n // Resolve relative paths against the user's effective workspace\n // directory rather than a potentially read-only package root.\n cwd = isAbsolute(rawCwd) ? rawCwd : resolve(getUserWorkspaceDir(), rawCwd);\n }\n \n // Add --additional-packs for commands that need to access local test packs.\n // Only set the default examples path when it actually exists on disk\n // (it may be absent in npm-installed layouts where ql/javascript/examples/\n // is not included in the published package).\n const defaultExamplesPath = resolve(packageRootDir, 'ql', 'javascript', 'examples');\n const additionalPacksPath = process.env.CODEQL_ADDITIONAL_PACKS\n || (existsSync(defaultExamplesPath) ? defaultExamplesPath : undefined);\n if (additionalPacksPath && (name === 'codeql_test_run' || name === 'codeql_query_run' || name === 'codeql_query_compile' || name === 'codeql_database_analyze')) {\n options['additional-packs'] = additionalPacksPath;\n }\n \n // Keep test databases for codeql_test_run to allow subsequent query runs\n if (name === 'codeql_test_run') {\n options['keep-databases'] = true;\n }\n \n result = await executeCodeQLCommand(subcommand, options, positionalArgs, cwd);\n } else if (command === 'qlt') {\n result = await executeQLTCommand(subcommand, options, positionalArgs);\n } else {\n throw new Error(`Unsupported command: ${command}`);\n }\n\n // Post-execution processing for codeql_query_run\n if (name === 'codeql_query_run' && result.success && queryLogDir) {\n // Generate SARIF interpretation if results.bqrs exists\n const bqrsPath = options.output as string;\n const sarifPath = join(queryLogDir, 'results.sarif');\n\n if (existsSync(bqrsPath)) {\n try {\n const sarifResult = await executeCodeQLCommand(\n 'bqrs interpret',\n { format: 'sarif-latest', output: sarifPath },\n [bqrsPath]\n );\n\n if (sarifResult.success) {\n logger.info(`Generated SARIF interpretation at ${sarifPath}`);\n }\n } catch (error) {\n logger.warn(`Failed to generate SARIF interpretation: ${error}`);\n }\n }\n\n // Process evaluation results\n result = await processQueryRunResults(result, params, logger);\n }\n\n // Post-execution: generate evaluator log summary for query run / database analyze\n if ((name === 'codeql_query_run' || name === 'codeql_database_analyze') && result.success && queryLogDir) {\n const evalLogPath = options['evaluator-log'] as string | undefined;\n if (evalLogPath && existsSync(evalLogPath)) {\n try {\n const summaryPath = evalLogPath.replace(/\\.jsonl$/, '.summary.jsonl');\n // codeql generate log-summary takes positional args: []\n const summaryResult = await executeCodeQLCommand(\n 'generate log-summary',\n { format: 'predicates' },\n [evalLogPath, summaryPath]\n );\n\n if (summaryResult.success) {\n logger.info(`Generated evaluator log summary at ${summaryPath}`);\n }\n } catch (error) {\n logger.warn(`Failed to generate evaluator log summary: ${error}`);\n }\n }\n }\n\n // Process the result\n const processedResult = resultProcessor(result, params);\n\n return {\n content: [{\n type: 'text' as const,\n text: processedResult\n }],\n isError: !result.success\n };\n\n } catch (error) {\n logger.error(`Error in CLI tool ${name}:`, error);\n \n return {\n content: [{\n type: 'text' as const,\n text: `Failed to execute CLI tool: ${error instanceof Error ? error.message : String(error)}`\n }],\n isError: true\n };\n } finally {\n // Clean up temporary directories\n for (const tempDir of tempDirsToCleanup) {\n try {\n rmSync(tempDir, { recursive: true, force: true });\n logger.info(`Cleaned up temporary directory: ${tempDir}`);\n } catch (cleanupError) {\n logger.error(`Failed to clean up temporary directory ${tempDir}:`, cleanupError);\n }\n }\n }\n }\n );\n}\n\n/**\n * Helper function to create common CodeQL input schemas\n */\nexport const createCodeQLSchemas = {\n database: () => z.string().describe('Path to the CodeQL database'),\n \n query: () => z.string().describe('Path to the CodeQL query file (.ql)'),\n \n output: () => z.string().optional().describe('Output file path'),\n \n outputFormat: () => z.enum(['csv', 'json', 'bqrs', 'sarif-latest', 'sarifv2.1.0']).optional()\n .describe('Output format for results'),\n \n language: () => z.string().optional().describe('Programming language'),\n \n threads: () => z.number().optional().describe('Number of threads to use'),\n \n ram: () => z.number().optional().describe('Amount of RAM to use (MB)'),\n \n timeout: () => z.number().optional().describe('Timeout in seconds'),\n \n verbose: () => z.boolean().optional().describe('Enable verbose output'),\n \n additionalArgs: () => z.array(z.string()).optional().describe('Additional command-line arguments'),\n \n positionalArgs: () => z.array(z.string()).optional().describe('Positional arguments')\n .transform((val) => ({ _positional: val }))\n};\n\n/**\n * Helper function to create common QLT input schemas\n */\nexport const createQLTSchemas = {\n language: () => z.string().describe('Programming language'),\n \n output: () => z.string().optional().describe('Output directory or file path'),\n \n template: () => z.string().optional().describe('Template to use'),\n \n name: () => z.string().optional().describe('Name for generated query'),\n \n description: () => z.string().optional().describe('Description for generated query'),\n \n verbose: () => z.boolean().optional().describe('Enable verbose output'),\n \n force: () => z.boolean().optional().describe('Force overwrite existing files'),\n \n additionalArgs: () => z.array(z.string()).optional().describe('Additional command-line arguments')\n};\n\n/**\n * Create a result processor that formats BQRS output specially\n */\nexport const createBQRSResultProcessor = () => (\n result: CLIExecutionResult, \n params: Record\n): string => {\n if (!result.success) {\n return defaultCLIResultProcessor(result, params);\n }\n \n // For BQRS commands, provide more context about the output\n let output = result.stdout;\n \n if (params.output) {\n output += `\\n\\nResults saved to: ${params.output}`;\n }\n \n if (result.stderr) {\n output += `\\n\\nAdditional information:\\n${result.stderr}`;\n }\n \n return output;\n};\n\n/**\n * Create a result processor that formats database creation output\n */\nexport const createDatabaseResultProcessor = () => (\n result: CLIExecutionResult, \n params: Record\n): string => {\n if (!result.success) {\n return defaultCLIResultProcessor(result, params);\n }\n \n let output = 'Database creation completed successfully';\n \n if (params.database || params._positional) {\n const dbPath = params.database || (Array.isArray(params._positional) ? params._positional[0] : params._positional);\n output += `\\n\\nDatabase location: ${dbPath}`;\n }\n \n if (result.stdout) {\n output += `\\n\\nOutput:\\n${result.stdout}`;\n }\n \n if (result.stderr) {\n output += `\\n\\nAdditional information:\\n${result.stderr}`;\n }\n \n return output;\n};\n\n/**\n * Resolve query path for codeql_query_run tool\n * If queryName and queryLanguage are provided, resolve using codeql resolve queries\n */\nasync function resolveQueryPath(\n params: Record, \n logger: { info: (_message: string, ..._args: unknown[]) => void; error: (_message: string, ..._args: unknown[]) => void }\n): Promise {\n const { queryName, queryLanguage, queryPack, query } = params;\n \n // Validate parameter usage - queryName and query are mutually exclusive\n if (queryName && query) {\n logger.error('Cannot use both \"query\" and \"queryName\" parameters simultaneously. Use either \"query\" for direct file path OR \"queryName\" + \"queryLanguage\" for tool queries.');\n throw new Error('Cannot use both \"query\" and \"queryName\" parameters simultaneously. Use either \"query\" for direct file path OR \"queryName\" + \"queryLanguage\" for tool queries.');\n }\n \n // If no queryName provided, fall back to direct query parameter\n if (!queryName) {\n return query as string || null;\n }\n \n // If queryName provided but no language, we can't resolve\n if (!queryLanguage) {\n logger.error('queryLanguage is required when using queryName parameter. Supported languages: actions, cpp, csharp, go, java, javascript, python, ruby, swift');\n throw new Error('queryLanguage is required when using queryName parameter. Supported languages: actions, cpp, csharp, go, java, javascript, python, ruby, swift');\n }\n \n try {\n // Determine the query pack path - use absolute path to ensure it works regardless of cwd\n const defaultPackPath = resolveToolQueryPackPath(queryLanguage as string);\n const packPath = queryPack as string || defaultPackPath;\n \n logger.info(`Resolving query: ${queryName} for language: ${queryLanguage} in pack: ${packPath}`);\n \n // Execute codeql resolve queries to get available queries\n const { executeCodeQLCommand } = await import('./cli-executor');\n const resolveResult = await executeCodeQLCommand(\n 'resolve queries',\n { format: 'json' },\n [packPath]\n );\n \n if (!resolveResult.success) {\n logger.error('Failed to resolve queries:', resolveResult.stderr || resolveResult.error);\n throw new Error(`Failed to resolve queries: ${resolveResult.stderr || resolveResult.error}`);\n }\n \n // Parse the JSON output to find matching queries\n let resolvedQueries: string[];\n try {\n resolvedQueries = JSON.parse(resolveResult.stdout);\n } catch (parseError) {\n logger.error('Failed to parse resolve queries output:', parseError);\n throw new Error('Failed to parse resolve queries output');\n }\n \n // Find the query that matches the requested name exactly\n const matchingQuery = resolvedQueries.find(queryPath => {\n const fileName = basename(queryPath);\n // Match exact query name: \"PrintAST\" should match \"PrintAST.ql\" only\n return fileName === `${queryName}.ql`;\n });\n\n if (!matchingQuery) {\n logger.error(`Query \"${queryName}.ql\" not found in pack \"${packPath}\". Available queries:`, resolvedQueries.map(q => basename(q)));\n throw new Error(`Query \"${queryName}.ql\" not found in pack \"${packPath}\"`);\n }\n \n logger.info(`Resolved query \"${queryName}\" to: ${matchingQuery}`);\n return matchingQuery;\n \n } catch (error) {\n logger.error('Error resolving query path:', error);\n throw error;\n }\n}\n\n/**\n * Interpret BQRS file using codeql bqrs interpret\n */\nasync function interpretBQRSFile(\n bqrsPath: string,\n queryPath: string,\n format: string,\n outputPath: string,\n logger: { info: (_message: string, ..._args: unknown[]) => void; error: (_message: string, ..._args: unknown[]) => void }\n): Promise {\n try {\n // Extract query metadata to get id and kind\n const metadata = await extractQueryMetadata(queryPath);\n \n // Validate required metadata fields\n const missingFields = [];\n if (!metadata.id) missingFields.push('id');\n if (!metadata.kind) missingFields.push('kind');\n \n if (missingFields.length > 0) {\n return {\n success: false,\n exitCode: 1,\n stdout: '',\n stderr: '',\n error: `Query metadata is incomplete. Missing required field(s): ${missingFields.join(', ')}. Ensure the query file contains @id and @kind metadata.`\n };\n }\n \n // Sanitize metadata values to prevent command injection\n const sanitizedKind = (metadata.kind || '').replace(/[^a-zA-Z0-9_-]/g, '');\n const sanitizedId = (metadata.id || '').replace(/[^a-zA-Z0-9_/:-]/g, '');\n \n // Validate format for query kind\n const graphFormats = ['graphtext', 'dgml', 'dot'];\n if (graphFormats.includes(format) && metadata.kind !== 'graph') {\n return {\n success: false,\n exitCode: 1,\n stdout: '',\n stderr: '',\n error: `Format '${format}' is only compatible with @kind graph queries, but this query has @kind ${metadata.kind}`\n };\n }\n \n // Ensure output directory exists\n mkdirSync(dirname(outputPath), { recursive: true });\n \n // Build the codeql bqrs interpret command\n const params: Record = {\n format: format,\n output: outputPath,\n t: [`kind=${sanitizedKind}`, `id=${sanitizedId}`]\n };\n \n logger.info(`Interpreting BQRS file ${bqrsPath} with format ${format} to ${outputPath}`);\n \n // Execute codeql bqrs interpret\n const result = await executeCodeQLCommand(\n 'bqrs interpret',\n params,\n [bqrsPath]\n );\n \n return result;\n } catch (error) {\n return {\n success: false,\n exitCode: 1,\n stdout: '',\n stderr: '',\n error: `Failed to interpret BQRS file: ${error}`\n };\n }\n}\n\n/**\n * Get default output extension based on format\n */\nfunction getDefaultExtension(format: string): string {\n switch (format) {\n case 'sarif-latest':\n case 'sarifv2.1.0':\n return '.sarif';\n case 'csv':\n return '.csv';\n case 'graphtext':\n return '.txt';\n case 'dgml':\n return '.dgml';\n case 'dot':\n return '.dot';\n default:\n return '.txt';\n }\n}\n\n/**\n * Process query run results with optional interpretation or evaluation\n */\nasync function processQueryRunResults(\n result: CLIExecutionResult,\n params: Record,\n logger: { info: (_message: string, ..._args: unknown[]) => void; error: (_message: string, ..._args: unknown[]) => void }\n): Promise {\n try {\n const { format, interpretedOutput, evaluationFunction, evaluationOutput, output, query, queryName, queryLanguage } = params;\n \n // If no format or evaluationFunction specified, return as-is\n if (!format && !evaluationFunction) {\n return result;\n }\n \n // Ensure output (bqrs file) was generated\n if (!output) {\n return result;\n }\n \n const bqrsPath = output as string;\n \n // Determine the query path for metadata extraction\n let queryPath: string | null = null;\n \n if (query) {\n queryPath = query as string;\n } else if (queryName && queryLanguage) {\n // Try to resolve the query path again for evaluation\n queryPath = await resolveQueryPath(params, logger);\n }\n \n if (!queryPath) {\n logger.error('Cannot determine query path for interpretation/evaluation');\n return {\n ...result,\n stdout: result.stdout + '\\n\\nWarning: Query interpretation skipped - could not determine query path'\n };\n }\n \n // Handle new format parameter (preferred approach)\n if (format) {\n const outputFormat = format as string;\n \n // Determine output path\n let outputFilePath = interpretedOutput as string | undefined;\n if (!outputFilePath) {\n const ext = getDefaultExtension(outputFormat);\n outputFilePath = bqrsPath.replace('.bqrs', ext);\n }\n \n logger.info(`Interpreting query results from ${bqrsPath} with format: ${outputFormat}`);\n \n // Interpret the BQRS file\n const interpretResult = await interpretBQRSFile(\n bqrsPath,\n queryPath,\n outputFormat,\n outputFilePath,\n logger\n );\n \n if (interpretResult.success) {\n let enhancedOutput = result.stdout;\n enhancedOutput += `\\n\\nQuery results interpreted successfully with format: ${outputFormat}`;\n enhancedOutput += `\\nInterpreted output saved to: ${outputFilePath}`;\n \n return {\n ...result,\n stdout: enhancedOutput\n };\n } else {\n logger.error('Query interpretation failed:', interpretResult.error);\n return {\n ...result,\n stdout: result.stdout + `\\n\\nWarning: Query interpretation failed - ${interpretResult.error || interpretResult.stderr}`\n };\n }\n }\n \n // Handle legacy evaluationFunction parameter (deprecated)\n if (evaluationFunction) {\n logger.info(`Using deprecated evaluationFunction parameter. Consider using format parameter instead.`);\n logger.info(`Evaluating query results from ${bqrsPath} using function: ${evaluationFunction}`);\n \n // Perform the evaluation\n const evaluationResult: QueryEvaluationResult = await evaluateQueryResults(\n bqrsPath,\n queryPath,\n evaluationFunction as string,\n evaluationOutput as string | undefined\n );\n \n if (evaluationResult.success) {\n // Append evaluation results to the command output\n let enhancedOutput = result.stdout;\n \n if (evaluationResult.outputPath) {\n enhancedOutput += `\\n\\nQuery evaluation completed successfully.`;\n enhancedOutput += `\\nEvaluation output saved to: ${evaluationResult.outputPath}`;\n }\n \n if (evaluationResult.content) {\n enhancedOutput += `\\n\\n=== Query Results Evaluation ===\\n`;\n enhancedOutput += evaluationResult.content;\n }\n \n return {\n ...result,\n stdout: enhancedOutput\n };\n } else {\n // Evaluation failed, but don't fail the whole operation\n logger.error('Query evaluation failed:', evaluationResult.error);\n return {\n ...result,\n stdout: result.stdout + `\\n\\nWarning: Query evaluation failed - ${evaluationResult.error}`\n };\n }\n }\n \n return result;\n } catch (error) {\n logger.error('Error in query results processing:', error);\n return {\n ...result,\n stdout: result.stdout + `\\n\\nWarning: Query processing error - ${error}`\n };\n }\n}", "/**\n * Query results evaluation functions for processing .bqrs files\n */\n\nimport { executeCodeQLCommand } from './cli-executor';\nimport { logger } from '../utils/logger';\nimport { writeFileSync, readFileSync } from 'fs';\nimport { dirname, isAbsolute } from 'path';\nimport { mkdirSync } from 'fs';\n\nexport interface QueryEvaluationResult {\n success: boolean;\n outputPath?: string;\n content?: string;\n error?: string;\n}\n\nexport interface QueryMetadata {\n kind?: string;\n name?: string;\n description?: string;\n id?: string;\n tags?: string[];\n}\n\n/**\n * Built-in evaluation functions\n */\nexport const BUILT_IN_EVALUATORS = {\n 'json-decode': 'JSON format decoder for query results',\n 'csv-decode': 'CSV format decoder for query results', \n 'mermaid-graph': 'Mermaid diagram generator for @kind graph queries (like PrintAST)',\n} as const;\n\nexport type BuiltInEvaluator = keyof typeof BUILT_IN_EVALUATORS;\n\n/**\n * Extract metadata from a CodeQL query file\n */\nexport async function extractQueryMetadata(queryPath: string): Promise {\n try {\n const queryContent = readFileSync(queryPath, 'utf-8');\n const metadata: QueryMetadata = {};\n \n // Extract metadata from comments using regex patterns\n const kindMatch = queryContent.match(/@kind\\s+([^\\s]+)/);\n if (kindMatch) metadata.kind = kindMatch[1];\n \n const nameMatch = queryContent.match(/@name\\s+(.+)/);\n if (nameMatch) metadata.name = nameMatch[1].trim();\n \n const descMatch = queryContent.match(/@description\\s+(.+)/);\n if (descMatch) metadata.description = descMatch[1].trim();\n \n const idMatch = queryContent.match(/@id\\s+(.+)/);\n if (idMatch) metadata.id = idMatch[1].trim();\n \n const tagsMatch = queryContent.match(/@tags\\s+(.+)/);\n if (tagsMatch) {\n metadata.tags = tagsMatch[1].split(/\\s+/).filter(t => t.length > 0);\n }\n \n return metadata;\n } catch (error) {\n logger.error('Failed to extract query metadata:', error);\n return {};\n }\n}\n\n/**\n * JSON decoder - converts .bqrs to JSON format\n */\nexport async function evaluateWithJsonDecoder(\n bqrsPath: string, \n outputPath?: string\n): Promise {\n try {\n const result = await executeCodeQLCommand(\n 'bqrs decode',\n { format: 'json' },\n [bqrsPath]\n );\n \n if (!result.success) {\n return {\n success: false,\n error: `Failed to decode BQRS file: ${result.stderr || result.error}`\n };\n }\n \n const defaultOutputPath = outputPath || bqrsPath.replace('.bqrs', '.json');\n \n // Ensure output directory exists\n mkdirSync(dirname(defaultOutputPath), { recursive: true });\n \n // Write JSON results\n writeFileSync(defaultOutputPath, result.stdout);\n \n return {\n success: true,\n outputPath: defaultOutputPath,\n content: result.stdout\n };\n } catch (error) {\n return {\n success: false,\n error: `JSON evaluation failed: ${error}`\n };\n }\n}\n\n/**\n * CSV decoder - converts .bqrs to CSV format\n */\nexport async function evaluateWithCsvDecoder(\n bqrsPath: string,\n outputPath?: string\n): Promise {\n try {\n const result = await executeCodeQLCommand(\n 'bqrs decode',\n { format: 'csv' },\n [bqrsPath]\n );\n \n if (!result.success) {\n return {\n success: false,\n error: `Failed to decode BQRS file: ${result.stderr || result.error}`\n };\n }\n \n const defaultOutputPath = outputPath || bqrsPath.replace('.bqrs', '.csv');\n \n // Ensure output directory exists\n mkdirSync(dirname(defaultOutputPath), { recursive: true });\n \n // Write CSV results\n writeFileSync(defaultOutputPath, result.stdout);\n \n return {\n success: true,\n outputPath: defaultOutputPath,\n content: result.stdout\n };\n } catch (error) {\n return {\n success: false,\n error: `CSV evaluation failed: ${error}`\n };\n }\n}\n\n/**\n * Mermaid graph generator - converts @kind graph query results to mermaid diagrams\n */\nexport async function evaluateWithMermaidGraph(\n bqrsPath: string,\n queryPath: string,\n outputPath?: string\n): Promise {\n try {\n // First extract query metadata to confirm this is a graph query\n const metadata = await extractQueryMetadata(queryPath);\n \n if (metadata.kind !== 'graph') {\n logger.error(`Query is not a graph query (kind: ${metadata.kind}), mermaid-graph evaluation is only for @kind graph queries`);\n return {\n success: false,\n error: `Query is not a graph query (kind: ${metadata.kind}), mermaid-graph evaluation is only for @kind graph queries`\n };\n }\n \n // Decode the BQRS file to JSON first\n const jsonResult = await executeCodeQLCommand(\n 'bqrs decode',\n { format: 'json' },\n [bqrsPath]\n );\n \n if (!jsonResult.success) {\n return {\n success: false,\n error: `Failed to decode BQRS file: ${jsonResult.stderr || jsonResult.error}`\n };\n }\n \n // Parse the JSON results\n let queryResults;\n try {\n queryResults = JSON.parse(jsonResult.stdout);\n } catch (parseError) {\n return {\n success: false,\n error: `Failed to parse query results JSON: ${parseError}`\n };\n }\n \n // Generate mermaid diagram from graph results\n const mermaidContent = generateMermaidFromGraphResults(queryResults, metadata);\n \n const defaultOutputPath = outputPath || bqrsPath.replace('.bqrs', '.md');\n \n // Ensure output directory exists\n mkdirSync(dirname(defaultOutputPath), { recursive: true });\n \n // Write markdown file with mermaid diagram\n writeFileSync(defaultOutputPath, mermaidContent);\n \n return {\n success: true,\n outputPath: defaultOutputPath,\n content: mermaidContent\n };\n } catch (error) {\n return {\n success: false,\n error: `Mermaid graph evaluation failed: ${error}`\n };\n }\n}\n\n/**\n * Generate mermaid diagram from CodeQL graph query results\n */\nfunction generateMermaidFromGraphResults(queryResults: unknown, metadata: QueryMetadata): string {\n const queryName = sanitizeMarkdown(metadata.name || 'CodeQL Query Results');\n const queryDesc = sanitizeMarkdown(metadata.description || 'Graph visualization of CodeQL query results');\n \n let mermaidContent = `# ${queryName}\\n\\n${queryDesc}\\n\\n`;\n \n // Handle different result structures that CodeQL graph queries can produce\n if (!queryResults || typeof queryResults !== 'object') {\n mermaidContent += '```mermaid\\ngraph TD\\n A[No Results]\\n```\\n';\n return mermaidContent;\n }\n \n // Check if results have the expected structure for graph queries\n const tuples = queryResults.tuples || queryResults;\n \n if (!Array.isArray(tuples) || tuples.length === 0) {\n mermaidContent += '```mermaid\\ngraph TD\\n A[No Graph Data]\\n```\\n';\n return mermaidContent;\n }\n \n mermaidContent += '```mermaid\\ngraph TD\\n';\n \n // Track nodes and edges to avoid duplicates\n const nodes = new Set();\n const edges = new Set();\n \n // Process each tuple in the results\n tuples.forEach((tuple: unknown, index: number) => {\n if (Array.isArray(tuple) && tuple.length >= 2) {\n // Extract source and target from tuple\n const source = sanitizeNodeId(tuple[0]?.toString() || `node_${index}_0`);\n const target = sanitizeNodeId(tuple[1]?.toString() || `node_${index}_1`);\n const label = tuple[2]?.toString() || '';\n \n // Add nodes\n nodes.add(source);\n nodes.add(target);\n \n // Add edge\n const edgeId = `${source}_${target}`;\n if (!edges.has(edgeId)) {\n if (label) {\n mermaidContent += ` ${source} -->|${sanitizeLabel(label)}| ${target}\\n`;\n } else {\n mermaidContent += ` ${source} --> ${target}\\n`;\n }\n edges.add(edgeId);\n }\n } else if (typeof tuple === 'object' && tuple !== null) {\n // Handle object-based results\n const source = sanitizeNodeId(tuple.source?.toString() || tuple.from?.toString() || `node_${index}_src`);\n const target = sanitizeNodeId(tuple.target?.toString() || tuple.to?.toString() || `node_${index}_tgt`);\n const label = tuple.label?.toString() || tuple.relation?.toString() || '';\n \n nodes.add(source);\n nodes.add(target);\n \n const edgeId = `${source}_${target}`;\n if (!edges.has(edgeId)) {\n if (label) {\n mermaidContent += ` ${source} -->|${sanitizeLabel(label)}| ${target}\\n`;\n } else {\n mermaidContent += ` ${source} --> ${target}\\n`;\n }\n edges.add(edgeId);\n }\n }\n });\n \n // If no edges were created, create a simple diagram showing the first few nodes\n if (edges.size === 0 && nodes.size > 0) {\n const nodeArray = Array.from(nodes).slice(0, 10); // Limit to avoid clutter\n nodeArray.forEach((node, index) => {\n if (index === 0) {\n mermaidContent += ` ${node}[${sanitizeLabel(node)}]\\n`;\n } else {\n mermaidContent += ` ${nodeArray[0]} --> ${node}\\n`;\n }\n });\n }\n \n mermaidContent += '```\\n\\n';\n \n // Add statistics\n mermaidContent += `## Query Statistics\\n\\n`;\n mermaidContent += `- Total nodes: ${nodes.size}\\n`;\n mermaidContent += `- Total edges: ${edges.size}\\n`;\n mermaidContent += `- Total tuples processed: ${tuples.length}\\n`;\n \n return mermaidContent;\n}\n\n/**\n * Sanitize node IDs for mermaid compatibility\n */\nfunction sanitizeNodeId(id: string): string {\n return id\n .replace(/[^a-zA-Z0-9_]/g, '_')\n .replace(/^(\\d)/, 'n$1') // Prefix with 'n' if starts with number\n .substring(0, 50); // Limit length\n}\n\n/**\n * Sanitize labels for mermaid compatibility\n */\nfunction sanitizeLabel(label: string): string {\n return label\n .replace(/[|\"`<>\\n\\r\\t]/g, '') // Remove problematic characters including backticks, newlines, angle brackets\n .replace(/\\s+/g, ' ') // Normalize whitespace\n .trim()\n .substring(0, 30); // Limit length for readability\n}\n\n/**\n * Sanitize markdown content to prevent injection\n */\nfunction sanitizeMarkdown(content: string): string {\n return content\n .replace(/[<>\"`]/g, '') // Remove potentially dangerous characters\n .replace(/\\n/g, ' ') // Convert newlines to spaces\n .replace(/\\s+/g, ' ') // Normalize whitespace\n .trim()\n .substring(0, 100); // Limit length\n}\n\n/**\n * Main evaluation function that determines which evaluator to use\n */\nexport async function evaluateQueryResults(\n bqrsPath: string,\n queryPath: string,\n evaluationFunction?: string,\n outputPath?: string\n): Promise {\n try {\n // If no evaluation function specified, default to json-decode\n const evalFunc = evaluationFunction || 'json-decode';\n \n logger.info(`Evaluating query results with function: ${evalFunc}`);\n \n // Handle built-in evaluation functions\n switch (evalFunc) {\n case 'json-decode':\n return await evaluateWithJsonDecoder(bqrsPath, outputPath);\n \n case 'csv-decode':\n return await evaluateWithCsvDecoder(bqrsPath, outputPath);\n \n case 'mermaid-graph':\n return await evaluateWithMermaidGraph(bqrsPath, queryPath, outputPath);\n \n default:\n // Check if it's a path to a custom evaluation script\n if (isAbsolute(evalFunc)) {\n return await evaluateWithCustomScript(bqrsPath, queryPath, evalFunc, outputPath);\n } else {\n return {\n success: false,\n error: `Unknown evaluation function: ${evalFunc}. Available built-in functions: ${Object.keys(BUILT_IN_EVALUATORS).join(', ')}`\n };\n }\n }\n } catch (error) {\n return {\n success: false,\n error: `Query evaluation failed: ${error}`\n };\n }\n}\n\n/**\n * Execute custom evaluation script\n */\nasync function evaluateWithCustomScript(\n _bqrsPath: string,\n _queryPath: string,\n _scriptPath: string,\n _outputPath?: string\n): Promise {\n // TODO: Implement custom script execution\n // This would need to execute the script with bqrsPath and queryPath as arguments\n // and capture the output\n return {\n success: false,\n error: 'Custom evaluation scripts are not yet implemented'\n };\n}", "/**\n * Log directory management utilities for CodeQL query and test runs\n */\n\nimport { mkdirSync, existsSync } from 'fs';\nimport { join, resolve } from 'path';\nimport { randomBytes } from 'crypto';\nimport { getProjectTmpDir } from '../utils/temp-dir';\n\n/**\n * Ensure that a given path is within a base directory.\n * Throws an error if the path is outside the base directory.\n */\nfunction ensurePathWithinBase(baseDir: string, targetPath: string): string {\n const absBase = resolve(baseDir);\n const absTarget = resolve(targetPath);\n if (!absTarget.startsWith(absBase + '/') && absTarget !== absBase) {\n throw new Error(`Provided log directory is outside the allowed base directory: ${absBase}`);\n }\n return absTarget;\n}\n\n/**\n * Get or create a unique log directory for query/test runs\n * \n * @param logDir - Optional custom log directory from parameters\n * @returns Absolute path to the log directory\n */\nexport function getOrCreateLogDirectory(logDir?: string): string {\n // Use CODEQL_QUERY_LOG_DIR env var or default base\n const baseLogDir = process.env.CODEQL_QUERY_LOG_DIR || getProjectTmpDir('query-logs');\n\n // If logDir is explicitly provided, validate it is within baseLogDir\n if (logDir) {\n const absLogDir = ensurePathWithinBase(baseLogDir, logDir);\n if (!existsSync(absLogDir)) {\n mkdirSync(absLogDir, { recursive: true });\n }\n return absLogDir;\n }\n \n // Otherwise, use baseLogDir and create a unique subdirectory\n \n // Create base directory if it doesn't exist\n if (!existsSync(baseLogDir)) {\n mkdirSync(baseLogDir, { recursive: true });\n }\n \n // Generate unique subdirectory with timestamp and random ID\n const timestamp = new Date().toISOString().replace(/[:.]/g, '-');\n const uniqueId = randomBytes(4).toString('hex');\n const uniqueLogDir = join(baseLogDir, `query-run-${timestamp}-${uniqueId}`);\n \n mkdirSync(uniqueLogDir, { recursive: true });\n \n return uniqueLogDir;\n}\n", "/**\n * CodeQL BQRS info tool\n */\n\nimport { z } from 'zod';\nimport { CLIToolDefinition, createCodeQLSchemas, createBQRSResultProcessor } from '../../lib/cli-tool-registry';\n\nexport const codeqlBqrsInfoTool: CLIToolDefinition = {\n name: 'codeql_bqrs_info',\n description: 'Get metadata and information about BQRS result files',\n command: 'codeql',\n subcommand: 'bqrs info',\n inputSchema: {\n files: z.array(z.string()).describe('BQRS file(s) to examine'),\n verbose: createCodeQLSchemas.verbose(),\n additionalArgs: createCodeQLSchemas.additionalArgs()\n },\n examples: [\n 'codeql bqrs info results.bqrs',\n 'codeql bqrs info --verbose results.bqrs'\n ],\n resultProcessor: createBQRSResultProcessor()\n};", "/**\n * CodeQL BQRS interpret tool\n */\n\nimport { z } from 'zod';\nimport { CLIToolDefinition, createCodeQLSchemas, createBQRSResultProcessor } from '../../lib/cli-tool-registry';\n\nexport const codeqlBqrsInterpretTool: CLIToolDefinition = {\n name: 'codeql_bqrs_interpret',\n description: 'Interpret BQRS result files according to query metadata and generate output in specified formats (CSV, SARIF, graph formats)',\n command: 'codeql',\n subcommand: 'bqrs interpret',\n inputSchema: {\n file: z.string().describe('The BQRS file to interpret'),\n format: z.enum(['csv', 'sarif-latest', 'sarifv2.1.0', 'graphtext', 'dgml', 'dot'])\n .describe('Output format: csv (comma-separated), sarif-latest/sarifv2.1.0 (SARIF), graphtext/dgml/dot (graph formats, only for @kind graph queries)'),\n output: createCodeQLSchemas.output(),\n t: z.array(z.string())\n .describe('Query metadata key=value pairs. At least \"kind\" and \"id\" must be specified (e.g., [\"kind=graph\", \"id=js/print-ast\"])'),\n 'max-paths': z.number().optional()\n .describe('Maximum number of paths to produce for each alert with paths (default: 4)'),\n 'sarif-add-file-contents': z.boolean().optional()\n .describe('[SARIF only] Include full file contents for all files referenced in results'),\n 'sarif-add-snippets': z.boolean().optional()\n .describe('[SARIF only] Include code snippets for each location with context'),\n 'sarif-group-rules-by-pack': z.boolean().optional()\n .describe('[SARIF only] Place rule objects under their QL pack in tool.extensions property'),\n 'sarif-multicause-markdown': z.boolean().optional()\n .describe('[SARIF only] Include multi-cause alerts as Markdown-formatted lists'),\n 'sarif-category': z.string().optional()\n .describe('[SARIF only] Category for this analysis (distinguishes multiple analyses on same code)'),\n 'csv-location-format': z.enum(['uri', 'line-column', 'offset-length']).optional()\n .describe('[CSV only] Format for locations in CSV output (default: line-column)'),\n 'dot-location-url-format': z.string().optional()\n .describe('[DOT only] Format string for file location URLs (placeholders: {path}, {start:line}, {start:column}, {end:line}, {end:column}, {offset}, {length})'),\n threads: z.number().optional()\n .describe('Number of threads for computing paths (0 = one per core, -N = leave N cores unused)'),\n 'column-kind': z.enum(['utf8', 'utf16', 'utf32', 'bytes']).optional()\n .describe('[SARIF only] Column kind for interpreting location columns'),\n 'unicode-new-lines': z.boolean().optional()\n .describe('[SARIF only] Whether unicode newlines (U+2028, U+2029) are considered as newlines'),\n verbose: createCodeQLSchemas.verbose(),\n additionalArgs: createCodeQLSchemas.additionalArgs()\n },\n examples: [\n 'codeql bqrs interpret --format=sarif-latest --output=results.sarif -t kind=problem -t id=js/sql-injection results.bqrs',\n 'codeql bqrs interpret --format=graphtext --output=ast.txt -t kind=graph -t id=js/print-ast results.bqrs',\n 'codeql bqrs interpret --format=csv --csv-location-format=line-column --output=results.csv -t kind=problem -t id=js/xss results.bqrs',\n 'codeql bqrs interpret --format=dot --output=graph.dot -t kind=graph -t id=java/call-graph results.bqrs',\n 'codeql bqrs interpret --format=sarif-latest --sarif-add-snippets --sarif-category=security --output=results.sarif -t kind=path-problem -t id=go/path-injection results.bqrs'\n ],\n resultProcessor: createBQRSResultProcessor()\n};\n", "/**\n * CodeQL database analyze tool\n */\n\nimport { z } from 'zod';\nimport { CLIToolDefinition } from '../../lib/cli-tool-registry';\n\nexport const codeqlDatabaseAnalyzeTool: CLIToolDefinition = {\n name: 'codeql_database_analyze',\n description: 'Run queries or query suites against CodeQL databases',\n command: 'codeql',\n subcommand: 'database analyze',\n inputSchema: {\n database: z.string().describe('Path to the CodeQL database'),\n queries: z.string().describe('Queries or query suite to run'),\n output: z.string().optional().describe('Output file path'),\n format: z.enum(['csv', 'json', 'sarif-latest', 'sarifv2.1.0']).optional()\n .describe('Output format for results'),\n 'download-location': z.string().optional()\n .describe('Location to download missing dependencies'),\n threads: z.number().optional().describe('Number of threads to use'),\n ram: z.number().optional().describe('Amount of RAM to use (MB)'),\n timeout: z.number().optional().describe('Timeout in seconds'),\n logDir: z.string().optional()\n .describe('Custom directory for analysis execution logs (overrides CODEQL_QUERY_LOG_DIR environment variable). If not provided, uses CODEQL_QUERY_LOG_DIR or defaults to .tmp/query-logs/'),\n 'evaluator-log': z.string().optional()\n .describe('Path to save evaluator log. If not provided and logDir is set, defaults to /evaluator-log.jsonl'),\n 'tuple-counting': z.boolean().optional()\n .describe('Display tuple counts for each evaluation step in evaluator logs'),\n 'evaluator-log-level': z.number().min(1).max(5).optional()\n .describe('Evaluator log verbosity level (1-5, default 5)'),\n verbose: z.boolean().optional().describe('Enable verbose output'),\n additionalArgs: z.array(z.string()).optional().describe('Additional command-line arguments')\n },\n examples: [\n 'codeql database analyze mydb queries.qls --format=sarif-latest --output=results.sarif',\n 'codeql database analyze mydb codeql/java-queries --format=csv',\n 'codeql database analyze mydb queries.qls --format=sarif-latest --output=results.sarif --log-dir=/path/to/logs --tuple-counting'\n ]\n};", "/**\n * CodeQL database create tool\n */\n\nimport { z } from 'zod';\nimport { CLIToolDefinition, createDatabaseResultProcessor } from '../../lib/cli-tool-registry';\n\nexport const codeqlDatabaseCreateTool: CLIToolDefinition = {\n name: 'codeql_database_create',\n description: 'Create a CodeQL database from source code',\n command: 'codeql',\n subcommand: 'database create',\n inputSchema: {\n database: z.string().describe('Database path/name to create'),\n language: z.string().optional().describe('Programming language(s) to extract'),\n 'source-root': z.string().optional().describe('Root directory of source code'),\n command: z.string().optional().describe('Build command for compiled languages'),\n 'build-mode': z.enum(['none', 'autobuild', 'manual']).optional()\n .describe('Build mode: none (interpreted langs), autobuild, or manual'),\n threads: z.number().optional().describe('Number of threads to use'),\n ram: z.number().optional().describe('Amount of RAM to use (MB)'),\n verbose: z.boolean().optional().describe('Enable verbose output'),\n overwrite: z.boolean().optional().describe('Overwrite existing database if it exists'),\n 'no-cleanup': z.boolean().optional().describe('Skip database cleanup after finalization'),\n additionalArgs: z.array(z.string()).optional().describe('Additional command-line arguments')\n },\n examples: [\n 'codeql database create --language=java --source-root=/path/to/project mydb',\n 'codeql database create --language=cpp --command=\"make all\" mydb',\n 'codeql database create --language=python,javascript mydb'\n ],\n resultProcessor: createDatabaseResultProcessor()\n};", "/**\n * CodeQL find class position tool\n * \n * Inspired by JordyZomer/codeql-mcp repository:\n * - https://github.com/JordyZomer/codeql-mcp/blob/main/server.py\n * - https://github.com/JordyZomer/codeql-mcp/blob/main/codeqlclient.py\n */\n\nimport { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport { z } from 'zod';\nimport { readFile } from 'fs/promises';\nimport { logger } from '../../utils/logger';\n\nexport interface ClassPosition {\n start_line: number;\n start_col: number;\n end_line: number;\n end_col: number;\n}\n\n/**\n * Find the 1-based position of a class name identifier in a QL file.\n * Returns: { start_line, start_col, end_line, end_col }\n */\nexport async function findClassPosition(filepath: string, className: string): Promise {\n try {\n const content = await readFile(filepath, 'utf-8');\n const lines = content.split('\\n');\n\n for (let i = 0; i < lines.length; i++) {\n const line = lines[i];\n // Match class definition with the specific class name\n const classNameRegex = new RegExp(`\\\\bclass\\\\s+(${className.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&')})\\\\b`);\n const match = classNameRegex.exec(line);\n \n if (match) {\n const start_line = i + 1; // 1-based line numbering\n // The class name is in capture group 1\n const classNameStart = match.index + match[0].indexOf(match[1]);\n const start_col = classNameStart + 1; // 1-based column numbering\n const end_col = start_col + className.length - 1; // end_col is inclusive\n \n return {\n start_line,\n start_col,\n end_line: start_line,\n end_col\n };\n }\n }\n\n throw new Error(`Class name '${className}' not found in file: ${filepath}`);\n } catch (error) {\n if (error instanceof Error && error.message.includes('not found in file')) {\n throw error;\n }\n throw new Error(`Failed to read or parse file ${filepath}: ${error instanceof Error ? error.message : 'Unknown error'}`);\n }\n}\n\n/**\n * Register the find class position tool with the MCP server\n */\nexport function registerFindClassPositionTool(server: McpServer): void {\n server.tool(\n 'find_class_position',\n 'Finds startline, startcol, endline endcol of a class for quickeval',\n {\n file: z.string().describe('Path to the .ql file to search'),\n name: z.string().describe('Name of the class to find'),\n },\n async ({ file, name }) => {\n try {\n const position = await findClassPosition(file, name);\n return {\n content: [{ type: 'text', text: JSON.stringify(position, null, 2) }],\n };\n } catch (error) {\n logger.error('Error finding class position:', error);\n return {\n content: [\n {\n type: 'text',\n text: `Error: ${error instanceof Error ? error.message : 'Unknown error'}`,\n },\n ],\n isError: true,\n };\n }\n }\n );\n}", "/**\n * CodeQL find predicate position tool\n * \n * Inspired by JordyZomer/codeql-mcp repository:\n * - https://github.com/JordyZomer/codeql-mcp/blob/main/server.py\n * - https://github.com/JordyZomer/codeql-mcp/blob/main/codeqlclient.py\n */\n\nimport { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport { z } from 'zod';\nimport { readFile } from 'fs/promises';\nimport { logger } from '../../utils/logger';\n\nexport interface PredicatePosition {\n start_line: number;\n start_col: number;\n end_line: number;\n end_col: number;\n}\n\n/**\n * Find the 1-based position of a predicate name in a QL file.\n * Supports: \n * - predicate name(...) - predicates with no return type\n * - Type name(...) - predicates with return type (e.g., string foo())\n * - name(...) (inside class) - member predicates\n * Returns: { start_line, start_col, end_line, end_col }\n */\nexport async function findPredicatePosition(filepath: string, predicateName: string): Promise {\n try {\n const content = await readFile(filepath, 'utf-8');\n const lines = content.split('\\n');\n const escapedName = predicateName.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&');\n\n for (let i = 0; i < lines.length; i++) {\n const line = lines[i];\n \n // Match predicate definition with the specific predicate name\n // Pattern 1: predicate name(...)\n const predicateKeywordRegex = new RegExp(`\\\\bpredicate\\\\s+(${escapedName})\\\\s*\\\\(`);\n let match = predicateKeywordRegex.exec(line);\n \n // Pattern 2: Type name(...) - predicates with return type\n // Matches: string foo(), int bar(), MyClass baz(), etc.\n // Must start at beginning of line (with optional whitespace) or after certain keywords\n if (!match) {\n const returnTypeRegex = new RegExp(`(?:^|\\\\s)(?:abstract\\\\s+)?(?:cached\\\\s+)?(?:private\\\\s+)?(?:deprecated\\\\s+)?(?:\\\\w+)\\\\s+(${escapedName})\\\\s*\\\\(`);\n match = returnTypeRegex.exec(line);\n }\n \n if (match) {\n const start_line = i + 1; // 1-based line numbering\n // The predicate name is in capture group 1\n const predicateNameStart = match.index + match[0].indexOf(match[1]);\n const start_col = predicateNameStart + 1; // 1-based column numbering\n const end_col = start_col + predicateName.length - 1; // end_col is inclusive\n \n return {\n start_line,\n start_col,\n end_line: start_line,\n end_col\n };\n }\n }\n\n throw new Error(`Predicate name '${predicateName}' not found in file: ${filepath}`);\n } catch (error) {\n if (error instanceof Error && error.message.includes('not found in file')) {\n throw error;\n }\n throw new Error(`Failed to read or parse file ${filepath}: ${error instanceof Error ? error.message : 'Unknown error'}`);\n }\n}\n\n/**\n * Register the find predicate position tool with the MCP server\n */\nexport function registerFindPredicatePositionTool(server: McpServer): void {\n server.tool(\n 'find_predicate_position',\n 'Finds startline, startcol, endline endcol of a predicate for quickeval',\n {\n file: z.string().describe('Path to the .ql file to search'),\n name: z.string().describe('Name of the predicate to find'),\n },\n async ({ file, name }) => {\n try {\n const position = await findPredicatePosition(file, name);\n return {\n content: [{ type: 'text', text: JSON.stringify(position, null, 2) }],\n };\n } catch (error) {\n logger.error('Error finding predicate position:', error);\n return {\n content: [\n {\n type: 'text',\n text: `Error: ${error instanceof Error ? error.message : 'Unknown error'}`,\n },\n ],\n isError: true,\n };\n }\n }\n );\n}", "/**\n * CodeQL find query files tool\n * Discovers and tracks all files related to a CodeQL query\n */\n\nimport { z } from 'zod';\nimport { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport { findCodeQLQueryFiles } from '../../lib/query-file-finder';\nimport { logger } from '../../utils/logger';\n\n/**\n * Register the find_codeql_query_files tool\n */\nexport function registerFindCodeQLQueryFilesTool(server: McpServer): void {\n server.tool(\n 'find_codeql_query_files',\n 'Find and track all files and directories related to a CodeQL query, including resolved metadata',\n {\n queryPath: z.string().describe('Path to the CodeQL query file (.ql)'),\n language: z.string().optional().describe('Programming language (optional, will be inferred if not provided)'),\n resolveMetadata: z.boolean().optional().describe('Whether to resolve query metadata (default: true)')\n },\n async ({ queryPath, language, resolveMetadata }) => {\n try {\n const result = await findCodeQLQueryFiles(\n queryPath,\n language,\n resolveMetadata !== false // Default to true if not specified\n );\n\n return {\n content: [{ type: 'text', text: JSON.stringify(result, null, 2) }]\n };\n } catch (error) {\n logger.error('Error finding CodeQL query files:', error);\n return {\n content: [\n {\n type: 'text',\n text: `Error: ${error instanceof Error ? error.message : 'Unknown error'}`\n }\n ],\n isError: true\n };\n }\n }\n );\n}\n", "/**\n * CodeQL query file finder utilities\n * Handles discovery and tracking of query-related files and directories\n */\n\nimport * as fs from 'fs';\nimport * as path from 'path';\nimport * as yaml from 'js-yaml';\nimport { QueryFileInfo, QueryFilesResult } from '../types/codeql';\nimport { resolveQueryMetadata } from './metadata-resolver';\n\n// Supported CodeQL languages and their file extensions (alphabetically ordered)\nconst LANGUAGE_EXTENSIONS: Record = {\n actions: 'yml',\n cpp: 'cpp',\n csharp: 'cs',\n go: 'go',\n java: 'java',\n javascript: 'js',\n python: 'py',\n ruby: 'rb',\n swift: 'swift',\n typescript: 'ts'\n};\n\nconst KNOWN_LANGUAGES = Object.keys(LANGUAGE_EXTENSIONS);\n\n/**\n * Get the file extension for test code based on language\n */\nfunction getLanguageExtension(language: string): string {\n return LANGUAGE_EXTENSIONS[language.toLowerCase()] || 'txt';\n}\n\n/**\n * Infer the language from the query file's directory structure\n */\nfunction inferLanguageFromPath(queryPath: string): string {\n const parts = queryPath.split(path.sep);\n\n for (const part of parts) {\n if (KNOWN_LANGUAGES.includes(part.toLowerCase())) {\n return part.toLowerCase();\n }\n }\n\n // Default fallback\n return 'unknown';\n}\n\n/**\n * Find the nearest qlpack.yml or codeql-pack.yml file by walking up the directory tree\n */\nfunction findNearestQlpack(startPath: string): string | null {\n let currentPath = startPath;\n const root = path.parse(currentPath).root;\n\n while (currentPath !== root) {\n // Check for codeql-pack.yml first (newer format), then qlpack.yml\n for (const packFile of ['codeql-pack.yml', 'qlpack.yml']) {\n const packPath = path.join(currentPath, packFile);\n if (fs.existsSync(packPath) && fs.statSync(packPath).isFile()) {\n return packPath;\n }\n }\n currentPath = path.dirname(currentPath);\n }\n\n return null;\n}\n\n/**\n * Read and parse qlpack.yml file\n */\nfunction readQlpackMetadata(qlpackPath: string): Record | null {\n try {\n const content = fs.readFileSync(qlpackPath, 'utf-8');\n const parsed = yaml.load(content) as Record;\n return parsed;\n } catch (_error) {\n // If we can't parse it, return null rather than failing\n return null;\n }\n}\n\n/**\n * Check if a file exists and return QueryFileInfo\n */\nfunction checkFile(filePath: string): QueryFileInfo {\n try {\n const exists = fs.existsSync(filePath) && fs.statSync(filePath).isFile();\n return {\n exists,\n path: filePath // Always return path, whether it exists or not\n };\n } catch {\n return {\n exists: false,\n path: filePath // Return the path even on error\n };\n }\n}\n\n/**\n * Check if a directory exists and return QueryFileInfo\n */\nfunction checkDirectory(dirPath: string): QueryFileInfo {\n try {\n const exists = fs.existsSync(dirPath) && fs.statSync(dirPath).isDirectory();\n return {\n exists,\n path: dirPath // Always return path, whether it exists or not\n };\n } catch {\n return {\n exists: false,\n path: dirPath // Return the path even on error\n };\n }\n}\n\n/**\n * Find all test code files in the test directory\n */\nfunction findTestCodeFiles(testDir: string, queryName: string, language: string): string[] {\n if (!fs.existsSync(testDir)) {\n return [];\n }\n\n try {\n const files = fs.readdirSync(testDir);\n const languageExt = getLanguageExtension(language);\n const testFiles: string[] = [];\n\n // Look for files matching the query name or other test code files\n const allValidExtensions = [...new Set([...Object.values(LANGUAGE_EXTENSIONS), 'yaml'])]; // Include yaml as alias for yml\n\n for (const file of files) {\n const filePath = path.join(testDir, file);\n const stat = fs.statSync(filePath);\n\n if (stat.isFile()) {\n // Include the primary test file matching query name\n if (file === `${queryName}.${languageExt}`) {\n testFiles.push(filePath);\n }\n // Include other code files (but not .qlref, .expected, .actual files)\n else if (!file.endsWith('.qlref') && !file.endsWith('.expected') && !file.endsWith('.actual')) {\n const ext = path.extname(file).slice(1);\n if (ext === languageExt || allValidExtensions.includes(ext)) {\n testFiles.push(filePath);\n }\n }\n }\n }\n\n return testFiles;\n } catch {\n return [];\n }\n}\n\n/**\n * Find CodeQL query files and directories based on a query file path\n * Optionally resolves metadata if the query file exists\n */\nexport async function findCodeQLQueryFiles(\n queryFilePath: string,\n language?: string,\n resolveMetadata: boolean = true\n): Promise {\n // Resolve absolute path\n const absoluteQueryPath = path.resolve(queryFilePath);\n\n // Extract query name and directory\n const queryName = path.basename(absoluteQueryPath, '.ql');\n const queryDir = path.dirname(absoluteQueryPath);\n\n // Infer language if not provided\n const detectedLanguage = language || inferLanguageFromPath(absoluteQueryPath);\n\n // Check query file itself\n const queryPath = checkFile(absoluteQueryPath);\n const queryDirectory = checkDirectory(queryDir);\n\n // Check for documentation files\n const mdPath = path.join(queryDir, `${queryName}.md`);\n const qhelpPath = path.join(queryDir, `${queryName}.qhelp`);\n const mdInfo = checkFile(mdPath);\n const qhelpInfo = checkFile(qhelpPath);\n\n const documentationPath: QueryFileInfo = mdInfo.exists ? mdInfo : (qhelpInfo.exists ? qhelpInfo : {\n exists: false,\n path: mdPath // Suggest .md as the default\n });\n\n // Check for specification file\n const qspecPath = path.join(queryDir, `${queryName}.qspec`);\n const specificationPath = checkFile(qspecPath);\n\n // Determine test directory\n // Pattern: if query is in .../src/QueryName/, test should be in .../test/QueryName/\n let testDir: string;\n if (queryDir.includes(`${path.sep}src${path.sep}`)) {\n // Find the last occurrence of /src/ and replace it with /test/\n const parts = queryDir.split(path.sep);\n const srcIndex = parts.lastIndexOf('src');\n if (srcIndex !== -1) {\n parts[srcIndex] = 'test';\n testDir = parts.join(path.sep);\n } else {\n // Fallback in case split didn't find it\n testDir = path.join(path.dirname(queryDir), 'test', queryName);\n }\n } else {\n // Fallback: if not in src directory, construct test dir based on parent\n testDir = path.join(path.dirname(queryDir), 'test', queryName);\n }\n const testDirectory = checkDirectory(testDir);\n\n // Check for .qlref file\n const qlrefPath = path.join(testDir, `${queryName}.qlref`);\n const qlrefInfo = checkFile(qlrefPath);\n\n // Find test code files\n const testCodePaths = findTestCodeFiles(testDir, queryName, detectedLanguage);\n\n // Check for expected results\n const expectedPath = path.join(testDir, `${queryName}.expected`);\n const expectedResultsPath = checkFile(expectedPath);\n\n // Check for actual results\n const actualPath = path.join(testDir, `${queryName}.actual`);\n const actualResultsPath = checkFile(actualPath);\n\n // Check for test database\n const testprojPath = path.join(testDir, `${queryName}.testproj`);\n const testDatabasePath = checkDirectory(testprojPath);\n\n // Determine missing files\n const missingFiles: string[] = [];\n if (!queryPath.exists) missingFiles.push(queryPath.path);\n if (!documentationPath.exists) missingFiles.push(documentationPath.path);\n if (!specificationPath.exists) missingFiles.push(specificationPath.path);\n if (!testDirectory.exists) missingFiles.push(testDirectory.path);\n if (!qlrefInfo.exists) missingFiles.push(qlrefInfo.path);\n if (testCodePaths.length === 0) missingFiles.push(path.join(testDir, `${queryName}.${getLanguageExtension(detectedLanguage)}`));\n if (!expectedResultsPath.exists) missingFiles.push(expectedResultsPath.path);\n\n const allFilesExist = missingFiles.length === 0;\n\n // Resolve metadata if requested and query file exists\n let metadata: { [key: string]: string | string[] } | undefined;\n if (resolveMetadata && queryPath.exists) {\n const resolvedMetadata = await resolveQueryMetadata(absoluteQueryPath);\n if (resolvedMetadata) {\n metadata = resolvedMetadata;\n }\n }\n\n // Resolve pack metadata and directories by finding the nearest qlpack.yml files\n let packMetadata: Record | undefined;\n const queryPackPath = findNearestQlpack(queryDir);\n const queryPackDir = queryPackPath ? path.dirname(queryPackPath) : queryDir;\n if (queryPackPath) {\n const parsed = readQlpackMetadata(queryPackPath);\n if (parsed) {\n packMetadata = parsed;\n }\n }\n\n // Find pack directory for test files\n const testPackPath = findNearestQlpack(testDir);\n const testPackDir = testPackPath ? path.dirname(testPackPath) : testDir;\n\n return {\n queryName,\n language: detectedLanguage,\n\n allFilesExist,\n\n files: {\n query: {\n dir: queryDirectory.path,\n doc: path.basename(documentationPath.path),\n packDir: queryPackDir,\n query: path.basename(queryPath.path),\n spec: path.basename(specificationPath.path)\n },\n test: {\n actual: path.basename(actualResultsPath.path),\n dir: testDirectory.path,\n expected: path.basename(expectedResultsPath.path),\n packDir: testPackDir,\n qlref: path.basename(qlrefInfo.path),\n testCode: testCodePaths,\n testDatabaseDir: testDatabasePath.path\n }\n },\n\n metadata,\n\n missingFiles,\n\n packMetadata,\n\n status: {\n actualResultsExist: actualResultsPath.exists,\n documentationExists: documentationPath.exists,\n expectedResultsExist: expectedResultsPath.exists,\n hasTestCode: testCodePaths.length > 0,\n qlrefExists: qlrefInfo.exists,\n queryExists: queryPath.exists,\n specificationExists: specificationPath.exists,\n testDatabaseDirExists: testDatabasePath.exists,\n testDirectoryExists: testDirectory.exists\n }\n };\n}\n", "\n/*! js-yaml 4.1.1 https://github.com/nodeca/js-yaml @license MIT */\nfunction isNothing(subject) {\n return (typeof subject === 'undefined') || (subject === null);\n}\n\n\nfunction isObject(subject) {\n return (typeof subject === 'object') && (subject !== null);\n}\n\n\nfunction toArray(sequence) {\n if (Array.isArray(sequence)) return sequence;\n else if (isNothing(sequence)) return [];\n\n return [ sequence ];\n}\n\n\nfunction extend(target, source) {\n var index, length, key, sourceKeys;\n\n if (source) {\n sourceKeys = Object.keys(source);\n\n for (index = 0, length = sourceKeys.length; index < length; index += 1) {\n key = sourceKeys[index];\n target[key] = source[key];\n }\n }\n\n return target;\n}\n\n\nfunction repeat(string, count) {\n var result = '', cycle;\n\n for (cycle = 0; cycle < count; cycle += 1) {\n result += string;\n }\n\n return result;\n}\n\n\nfunction isNegativeZero(number) {\n return (number === 0) && (Number.NEGATIVE_INFINITY === 1 / number);\n}\n\n\nvar isNothing_1 = isNothing;\nvar isObject_1 = isObject;\nvar toArray_1 = toArray;\nvar repeat_1 = repeat;\nvar isNegativeZero_1 = isNegativeZero;\nvar extend_1 = extend;\n\nvar common = {\n\tisNothing: isNothing_1,\n\tisObject: isObject_1,\n\ttoArray: toArray_1,\n\trepeat: repeat_1,\n\tisNegativeZero: isNegativeZero_1,\n\textend: extend_1\n};\n\n// YAML error class. http://stackoverflow.com/questions/8458984\n\n\nfunction formatError(exception, compact) {\n var where = '', message = exception.reason || '(unknown reason)';\n\n if (!exception.mark) return message;\n\n if (exception.mark.name) {\n where += 'in \"' + exception.mark.name + '\" ';\n }\n\n where += '(' + (exception.mark.line + 1) + ':' + (exception.mark.column + 1) + ')';\n\n if (!compact && exception.mark.snippet) {\n where += '\\n\\n' + exception.mark.snippet;\n }\n\n return message + ' ' + where;\n}\n\n\nfunction YAMLException$1(reason, mark) {\n // Super constructor\n Error.call(this);\n\n this.name = 'YAMLException';\n this.reason = reason;\n this.mark = mark;\n this.message = formatError(this, false);\n\n // Include stack trace in error object\n if (Error.captureStackTrace) {\n // Chrome and NodeJS\n Error.captureStackTrace(this, this.constructor);\n } else {\n // FF, IE 10+ and Safari 6+. Fallback for others\n this.stack = (new Error()).stack || '';\n }\n}\n\n\n// Inherit from Error\nYAMLException$1.prototype = Object.create(Error.prototype);\nYAMLException$1.prototype.constructor = YAMLException$1;\n\n\nYAMLException$1.prototype.toString = function toString(compact) {\n return this.name + ': ' + formatError(this, compact);\n};\n\n\nvar exception = YAMLException$1;\n\n// get snippet for a single line, respecting maxLength\nfunction getLine(buffer, lineStart, lineEnd, position, maxLineLength) {\n var head = '';\n var tail = '';\n var maxHalfLength = Math.floor(maxLineLength / 2) - 1;\n\n if (position - lineStart > maxHalfLength) {\n head = ' ... ';\n lineStart = position - maxHalfLength + head.length;\n }\n\n if (lineEnd - position > maxHalfLength) {\n tail = ' ...';\n lineEnd = position + maxHalfLength - tail.length;\n }\n\n return {\n str: head + buffer.slice(lineStart, lineEnd).replace(/\\t/g, '\u2192') + tail,\n pos: position - lineStart + head.length // relative position\n };\n}\n\n\nfunction padStart(string, max) {\n return common.repeat(' ', max - string.length) + string;\n}\n\n\nfunction makeSnippet(mark, options) {\n options = Object.create(options || null);\n\n if (!mark.buffer) return null;\n\n if (!options.maxLength) options.maxLength = 79;\n if (typeof options.indent !== 'number') options.indent = 1;\n if (typeof options.linesBefore !== 'number') options.linesBefore = 3;\n if (typeof options.linesAfter !== 'number') options.linesAfter = 2;\n\n var re = /\\r?\\n|\\r|\\0/g;\n var lineStarts = [ 0 ];\n var lineEnds = [];\n var match;\n var foundLineNo = -1;\n\n while ((match = re.exec(mark.buffer))) {\n lineEnds.push(match.index);\n lineStarts.push(match.index + match[0].length);\n\n if (mark.position <= match.index && foundLineNo < 0) {\n foundLineNo = lineStarts.length - 2;\n }\n }\n\n if (foundLineNo < 0) foundLineNo = lineStarts.length - 1;\n\n var result = '', i, line;\n var lineNoLength = Math.min(mark.line + options.linesAfter, lineEnds.length).toString().length;\n var maxLineLength = options.maxLength - (options.indent + lineNoLength + 3);\n\n for (i = 1; i <= options.linesBefore; i++) {\n if (foundLineNo - i < 0) break;\n line = getLine(\n mark.buffer,\n lineStarts[foundLineNo - i],\n lineEnds[foundLineNo - i],\n mark.position - (lineStarts[foundLineNo] - lineStarts[foundLineNo - i]),\n maxLineLength\n );\n result = common.repeat(' ', options.indent) + padStart((mark.line - i + 1).toString(), lineNoLength) +\n ' | ' + line.str + '\\n' + result;\n }\n\n line = getLine(mark.buffer, lineStarts[foundLineNo], lineEnds[foundLineNo], mark.position, maxLineLength);\n result += common.repeat(' ', options.indent) + padStart((mark.line + 1).toString(), lineNoLength) +\n ' | ' + line.str + '\\n';\n result += common.repeat('-', options.indent + lineNoLength + 3 + line.pos) + '^' + '\\n';\n\n for (i = 1; i <= options.linesAfter; i++) {\n if (foundLineNo + i >= lineEnds.length) break;\n line = getLine(\n mark.buffer,\n lineStarts[foundLineNo + i],\n lineEnds[foundLineNo + i],\n mark.position - (lineStarts[foundLineNo] - lineStarts[foundLineNo + i]),\n maxLineLength\n );\n result += common.repeat(' ', options.indent) + padStart((mark.line + i + 1).toString(), lineNoLength) +\n ' | ' + line.str + '\\n';\n }\n\n return result.replace(/\\n$/, '');\n}\n\n\nvar snippet = makeSnippet;\n\nvar TYPE_CONSTRUCTOR_OPTIONS = [\n 'kind',\n 'multi',\n 'resolve',\n 'construct',\n 'instanceOf',\n 'predicate',\n 'represent',\n 'representName',\n 'defaultStyle',\n 'styleAliases'\n];\n\nvar YAML_NODE_KINDS = [\n 'scalar',\n 'sequence',\n 'mapping'\n];\n\nfunction compileStyleAliases(map) {\n var result = {};\n\n if (map !== null) {\n Object.keys(map).forEach(function (style) {\n map[style].forEach(function (alias) {\n result[String(alias)] = style;\n });\n });\n }\n\n return result;\n}\n\nfunction Type$1(tag, options) {\n options = options || {};\n\n Object.keys(options).forEach(function (name) {\n if (TYPE_CONSTRUCTOR_OPTIONS.indexOf(name) === -1) {\n throw new exception('Unknown option \"' + name + '\" is met in definition of \"' + tag + '\" YAML type.');\n }\n });\n\n // TODO: Add tag format check.\n this.options = options; // keep original options in case user wants to extend this type later\n this.tag = tag;\n this.kind = options['kind'] || null;\n this.resolve = options['resolve'] || function () { return true; };\n this.construct = options['construct'] || function (data) { return data; };\n this.instanceOf = options['instanceOf'] || null;\n this.predicate = options['predicate'] || null;\n this.represent = options['represent'] || null;\n this.representName = options['representName'] || null;\n this.defaultStyle = options['defaultStyle'] || null;\n this.multi = options['multi'] || false;\n this.styleAliases = compileStyleAliases(options['styleAliases'] || null);\n\n if (YAML_NODE_KINDS.indexOf(this.kind) === -1) {\n throw new exception('Unknown kind \"' + this.kind + '\" is specified for \"' + tag + '\" YAML type.');\n }\n}\n\nvar type = Type$1;\n\n/*eslint-disable max-len*/\n\n\n\n\n\nfunction compileList(schema, name) {\n var result = [];\n\n schema[name].forEach(function (currentType) {\n var newIndex = result.length;\n\n result.forEach(function (previousType, previousIndex) {\n if (previousType.tag === currentType.tag &&\n previousType.kind === currentType.kind &&\n previousType.multi === currentType.multi) {\n\n newIndex = previousIndex;\n }\n });\n\n result[newIndex] = currentType;\n });\n\n return result;\n}\n\n\nfunction compileMap(/* lists... */) {\n var result = {\n scalar: {},\n sequence: {},\n mapping: {},\n fallback: {},\n multi: {\n scalar: [],\n sequence: [],\n mapping: [],\n fallback: []\n }\n }, index, length;\n\n function collectType(type) {\n if (type.multi) {\n result.multi[type.kind].push(type);\n result.multi['fallback'].push(type);\n } else {\n result[type.kind][type.tag] = result['fallback'][type.tag] = type;\n }\n }\n\n for (index = 0, length = arguments.length; index < length; index += 1) {\n arguments[index].forEach(collectType);\n }\n return result;\n}\n\n\nfunction Schema$1(definition) {\n return this.extend(definition);\n}\n\n\nSchema$1.prototype.extend = function extend(definition) {\n var implicit = [];\n var explicit = [];\n\n if (definition instanceof type) {\n // Schema.extend(type)\n explicit.push(definition);\n\n } else if (Array.isArray(definition)) {\n // Schema.extend([ type1, type2, ... ])\n explicit = explicit.concat(definition);\n\n } else if (definition && (Array.isArray(definition.implicit) || Array.isArray(definition.explicit))) {\n // Schema.extend({ explicit: [ type1, type2, ... ], implicit: [ type1, type2, ... ] })\n if (definition.implicit) implicit = implicit.concat(definition.implicit);\n if (definition.explicit) explicit = explicit.concat(definition.explicit);\n\n } else {\n throw new exception('Schema.extend argument should be a Type, [ Type ], ' +\n 'or a schema definition ({ implicit: [...], explicit: [...] })');\n }\n\n implicit.forEach(function (type$1) {\n if (!(type$1 instanceof type)) {\n throw new exception('Specified list of YAML types (or a single Type object) contains a non-Type object.');\n }\n\n if (type$1.loadKind && type$1.loadKind !== 'scalar') {\n throw new exception('There is a non-scalar type in the implicit list of a schema. Implicit resolving of such types is not supported.');\n }\n\n if (type$1.multi) {\n throw new exception('There is a multi type in the implicit list of a schema. Multi tags can only be listed as explicit.');\n }\n });\n\n explicit.forEach(function (type$1) {\n if (!(type$1 instanceof type)) {\n throw new exception('Specified list of YAML types (or a single Type object) contains a non-Type object.');\n }\n });\n\n var result = Object.create(Schema$1.prototype);\n\n result.implicit = (this.implicit || []).concat(implicit);\n result.explicit = (this.explicit || []).concat(explicit);\n\n result.compiledImplicit = compileList(result, 'implicit');\n result.compiledExplicit = compileList(result, 'explicit');\n result.compiledTypeMap = compileMap(result.compiledImplicit, result.compiledExplicit);\n\n return result;\n};\n\n\nvar schema = Schema$1;\n\nvar str = new type('tag:yaml.org,2002:str', {\n kind: 'scalar',\n construct: function (data) { return data !== null ? data : ''; }\n});\n\nvar seq = new type('tag:yaml.org,2002:seq', {\n kind: 'sequence',\n construct: function (data) { return data !== null ? data : []; }\n});\n\nvar map = new type('tag:yaml.org,2002:map', {\n kind: 'mapping',\n construct: function (data) { return data !== null ? data : {}; }\n});\n\nvar failsafe = new schema({\n explicit: [\n str,\n seq,\n map\n ]\n});\n\nfunction resolveYamlNull(data) {\n if (data === null) return true;\n\n var max = data.length;\n\n return (max === 1 && data === '~') ||\n (max === 4 && (data === 'null' || data === 'Null' || data === 'NULL'));\n}\n\nfunction constructYamlNull() {\n return null;\n}\n\nfunction isNull(object) {\n return object === null;\n}\n\nvar _null = new type('tag:yaml.org,2002:null', {\n kind: 'scalar',\n resolve: resolveYamlNull,\n construct: constructYamlNull,\n predicate: isNull,\n represent: {\n canonical: function () { return '~'; },\n lowercase: function () { return 'null'; },\n uppercase: function () { return 'NULL'; },\n camelcase: function () { return 'Null'; },\n empty: function () { return ''; }\n },\n defaultStyle: 'lowercase'\n});\n\nfunction resolveYamlBoolean(data) {\n if (data === null) return false;\n\n var max = data.length;\n\n return (max === 4 && (data === 'true' || data === 'True' || data === 'TRUE')) ||\n (max === 5 && (data === 'false' || data === 'False' || data === 'FALSE'));\n}\n\nfunction constructYamlBoolean(data) {\n return data === 'true' ||\n data === 'True' ||\n data === 'TRUE';\n}\n\nfunction isBoolean(object) {\n return Object.prototype.toString.call(object) === '[object Boolean]';\n}\n\nvar bool = new type('tag:yaml.org,2002:bool', {\n kind: 'scalar',\n resolve: resolveYamlBoolean,\n construct: constructYamlBoolean,\n predicate: isBoolean,\n represent: {\n lowercase: function (object) { return object ? 'true' : 'false'; },\n uppercase: function (object) { return object ? 'TRUE' : 'FALSE'; },\n camelcase: function (object) { return object ? 'True' : 'False'; }\n },\n defaultStyle: 'lowercase'\n});\n\nfunction isHexCode(c) {\n return ((0x30/* 0 */ <= c) && (c <= 0x39/* 9 */)) ||\n ((0x41/* A */ <= c) && (c <= 0x46/* F */)) ||\n ((0x61/* a */ <= c) && (c <= 0x66/* f */));\n}\n\nfunction isOctCode(c) {\n return ((0x30/* 0 */ <= c) && (c <= 0x37/* 7 */));\n}\n\nfunction isDecCode(c) {\n return ((0x30/* 0 */ <= c) && (c <= 0x39/* 9 */));\n}\n\nfunction resolveYamlInteger(data) {\n if (data === null) return false;\n\n var max = data.length,\n index = 0,\n hasDigits = false,\n ch;\n\n if (!max) return false;\n\n ch = data[index];\n\n // sign\n if (ch === '-' || ch === '+') {\n ch = data[++index];\n }\n\n if (ch === '0') {\n // 0\n if (index + 1 === max) return true;\n ch = data[++index];\n\n // base 2, base 8, base 16\n\n if (ch === 'b') {\n // base 2\n index++;\n\n for (; index < max; index++) {\n ch = data[index];\n if (ch === '_') continue;\n if (ch !== '0' && ch !== '1') return false;\n hasDigits = true;\n }\n return hasDigits && ch !== '_';\n }\n\n\n if (ch === 'x') {\n // base 16\n index++;\n\n for (; index < max; index++) {\n ch = data[index];\n if (ch === '_') continue;\n if (!isHexCode(data.charCodeAt(index))) return false;\n hasDigits = true;\n }\n return hasDigits && ch !== '_';\n }\n\n\n if (ch === 'o') {\n // base 8\n index++;\n\n for (; index < max; index++) {\n ch = data[index];\n if (ch === '_') continue;\n if (!isOctCode(data.charCodeAt(index))) return false;\n hasDigits = true;\n }\n return hasDigits && ch !== '_';\n }\n }\n\n // base 10 (except 0)\n\n // value should not start with `_`;\n if (ch === '_') return false;\n\n for (; index < max; index++) {\n ch = data[index];\n if (ch === '_') continue;\n if (!isDecCode(data.charCodeAt(index))) {\n return false;\n }\n hasDigits = true;\n }\n\n // Should have digits and should not end with `_`\n if (!hasDigits || ch === '_') return false;\n\n return true;\n}\n\nfunction constructYamlInteger(data) {\n var value = data, sign = 1, ch;\n\n if (value.indexOf('_') !== -1) {\n value = value.replace(/_/g, '');\n }\n\n ch = value[0];\n\n if (ch === '-' || ch === '+') {\n if (ch === '-') sign = -1;\n value = value.slice(1);\n ch = value[0];\n }\n\n if (value === '0') return 0;\n\n if (ch === '0') {\n if (value[1] === 'b') return sign * parseInt(value.slice(2), 2);\n if (value[1] === 'x') return sign * parseInt(value.slice(2), 16);\n if (value[1] === 'o') return sign * parseInt(value.slice(2), 8);\n }\n\n return sign * parseInt(value, 10);\n}\n\nfunction isInteger(object) {\n return (Object.prototype.toString.call(object)) === '[object Number]' &&\n (object % 1 === 0 && !common.isNegativeZero(object));\n}\n\nvar int = new type('tag:yaml.org,2002:int', {\n kind: 'scalar',\n resolve: resolveYamlInteger,\n construct: constructYamlInteger,\n predicate: isInteger,\n represent: {\n binary: function (obj) { return obj >= 0 ? '0b' + obj.toString(2) : '-0b' + obj.toString(2).slice(1); },\n octal: function (obj) { return obj >= 0 ? '0o' + obj.toString(8) : '-0o' + obj.toString(8).slice(1); },\n decimal: function (obj) { return obj.toString(10); },\n /* eslint-disable max-len */\n hexadecimal: function (obj) { return obj >= 0 ? '0x' + obj.toString(16).toUpperCase() : '-0x' + obj.toString(16).toUpperCase().slice(1); }\n },\n defaultStyle: 'decimal',\n styleAliases: {\n binary: [ 2, 'bin' ],\n octal: [ 8, 'oct' ],\n decimal: [ 10, 'dec' ],\n hexadecimal: [ 16, 'hex' ]\n }\n});\n\nvar YAML_FLOAT_PATTERN = new RegExp(\n // 2.5e4, 2.5 and integers\n '^(?:[-+]?(?:[0-9][0-9_]*)(?:\\\\.[0-9_]*)?(?:[eE][-+]?[0-9]+)?' +\n // .2e4, .2\n // special case, seems not from spec\n '|\\\\.[0-9_]+(?:[eE][-+]?[0-9]+)?' +\n // .inf\n '|[-+]?\\\\.(?:inf|Inf|INF)' +\n // .nan\n '|\\\\.(?:nan|NaN|NAN))$');\n\nfunction resolveYamlFloat(data) {\n if (data === null) return false;\n\n if (!YAML_FLOAT_PATTERN.test(data) ||\n // Quick hack to not allow integers end with `_`\n // Probably should update regexp & check speed\n data[data.length - 1] === '_') {\n return false;\n }\n\n return true;\n}\n\nfunction constructYamlFloat(data) {\n var value, sign;\n\n value = data.replace(/_/g, '').toLowerCase();\n sign = value[0] === '-' ? -1 : 1;\n\n if ('+-'.indexOf(value[0]) >= 0) {\n value = value.slice(1);\n }\n\n if (value === '.inf') {\n return (sign === 1) ? Number.POSITIVE_INFINITY : Number.NEGATIVE_INFINITY;\n\n } else if (value === '.nan') {\n return NaN;\n }\n return sign * parseFloat(value, 10);\n}\n\n\nvar SCIENTIFIC_WITHOUT_DOT = /^[-+]?[0-9]+e/;\n\nfunction representYamlFloat(object, style) {\n var res;\n\n if (isNaN(object)) {\n switch (style) {\n case 'lowercase': return '.nan';\n case 'uppercase': return '.NAN';\n case 'camelcase': return '.NaN';\n }\n } else if (Number.POSITIVE_INFINITY === object) {\n switch (style) {\n case 'lowercase': return '.inf';\n case 'uppercase': return '.INF';\n case 'camelcase': return '.Inf';\n }\n } else if (Number.NEGATIVE_INFINITY === object) {\n switch (style) {\n case 'lowercase': return '-.inf';\n case 'uppercase': return '-.INF';\n case 'camelcase': return '-.Inf';\n }\n } else if (common.isNegativeZero(object)) {\n return '-0.0';\n }\n\n res = object.toString(10);\n\n // JS stringifier can build scientific format without dots: 5e-100,\n // while YAML requres dot: 5.e-100. Fix it with simple hack\n\n return SCIENTIFIC_WITHOUT_DOT.test(res) ? res.replace('e', '.e') : res;\n}\n\nfunction isFloat(object) {\n return (Object.prototype.toString.call(object) === '[object Number]') &&\n (object % 1 !== 0 || common.isNegativeZero(object));\n}\n\nvar float = new type('tag:yaml.org,2002:float', {\n kind: 'scalar',\n resolve: resolveYamlFloat,\n construct: constructYamlFloat,\n predicate: isFloat,\n represent: representYamlFloat,\n defaultStyle: 'lowercase'\n});\n\nvar json = failsafe.extend({\n implicit: [\n _null,\n bool,\n int,\n float\n ]\n});\n\nvar core = json;\n\nvar YAML_DATE_REGEXP = new RegExp(\n '^([0-9][0-9][0-9][0-9])' + // [1] year\n '-([0-9][0-9])' + // [2] month\n '-([0-9][0-9])$'); // [3] day\n\nvar YAML_TIMESTAMP_REGEXP = new RegExp(\n '^([0-9][0-9][0-9][0-9])' + // [1] year\n '-([0-9][0-9]?)' + // [2] month\n '-([0-9][0-9]?)' + // [3] day\n '(?:[Tt]|[ \\\\t]+)' + // ...\n '([0-9][0-9]?)' + // [4] hour\n ':([0-9][0-9])' + // [5] minute\n ':([0-9][0-9])' + // [6] second\n '(?:\\\\.([0-9]*))?' + // [7] fraction\n '(?:[ \\\\t]*(Z|([-+])([0-9][0-9]?)' + // [8] tz [9] tz_sign [10] tz_hour\n '(?::([0-9][0-9]))?))?$'); // [11] tz_minute\n\nfunction resolveYamlTimestamp(data) {\n if (data === null) return false;\n if (YAML_DATE_REGEXP.exec(data) !== null) return true;\n if (YAML_TIMESTAMP_REGEXP.exec(data) !== null) return true;\n return false;\n}\n\nfunction constructYamlTimestamp(data) {\n var match, year, month, day, hour, minute, second, fraction = 0,\n delta = null, tz_hour, tz_minute, date;\n\n match = YAML_DATE_REGEXP.exec(data);\n if (match === null) match = YAML_TIMESTAMP_REGEXP.exec(data);\n\n if (match === null) throw new Error('Date resolve error');\n\n // match: [1] year [2] month [3] day\n\n year = +(match[1]);\n month = +(match[2]) - 1; // JS month starts with 0\n day = +(match[3]);\n\n if (!match[4]) { // no hour\n return new Date(Date.UTC(year, month, day));\n }\n\n // match: [4] hour [5] minute [6] second [7] fraction\n\n hour = +(match[4]);\n minute = +(match[5]);\n second = +(match[6]);\n\n if (match[7]) {\n fraction = match[7].slice(0, 3);\n while (fraction.length < 3) { // milli-seconds\n fraction += '0';\n }\n fraction = +fraction;\n }\n\n // match: [8] tz [9] tz_sign [10] tz_hour [11] tz_minute\n\n if (match[9]) {\n tz_hour = +(match[10]);\n tz_minute = +(match[11] || 0);\n delta = (tz_hour * 60 + tz_minute) * 60000; // delta in mili-seconds\n if (match[9] === '-') delta = -delta;\n }\n\n date = new Date(Date.UTC(year, month, day, hour, minute, second, fraction));\n\n if (delta) date.setTime(date.getTime() - delta);\n\n return date;\n}\n\nfunction representYamlTimestamp(object /*, style*/) {\n return object.toISOString();\n}\n\nvar timestamp = new type('tag:yaml.org,2002:timestamp', {\n kind: 'scalar',\n resolve: resolveYamlTimestamp,\n construct: constructYamlTimestamp,\n instanceOf: Date,\n represent: representYamlTimestamp\n});\n\nfunction resolveYamlMerge(data) {\n return data === '<<' || data === null;\n}\n\nvar merge = new type('tag:yaml.org,2002:merge', {\n kind: 'scalar',\n resolve: resolveYamlMerge\n});\n\n/*eslint-disable no-bitwise*/\n\n\n\n\n\n// [ 64, 65, 66 ] -> [ padding, CR, LF ]\nvar BASE64_MAP = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=\\n\\r';\n\n\nfunction resolveYamlBinary(data) {\n if (data === null) return false;\n\n var code, idx, bitlen = 0, max = data.length, map = BASE64_MAP;\n\n // Convert one by one.\n for (idx = 0; idx < max; idx++) {\n code = map.indexOf(data.charAt(idx));\n\n // Skip CR/LF\n if (code > 64) continue;\n\n // Fail on illegal characters\n if (code < 0) return false;\n\n bitlen += 6;\n }\n\n // If there are any bits left, source was corrupted\n return (bitlen % 8) === 0;\n}\n\nfunction constructYamlBinary(data) {\n var idx, tailbits,\n input = data.replace(/[\\r\\n=]/g, ''), // remove CR/LF & padding to simplify scan\n max = input.length,\n map = BASE64_MAP,\n bits = 0,\n result = [];\n\n // Collect by 6*4 bits (3 bytes)\n\n for (idx = 0; idx < max; idx++) {\n if ((idx % 4 === 0) && idx) {\n result.push((bits >> 16) & 0xFF);\n result.push((bits >> 8) & 0xFF);\n result.push(bits & 0xFF);\n }\n\n bits = (bits << 6) | map.indexOf(input.charAt(idx));\n }\n\n // Dump tail\n\n tailbits = (max % 4) * 6;\n\n if (tailbits === 0) {\n result.push((bits >> 16) & 0xFF);\n result.push((bits >> 8) & 0xFF);\n result.push(bits & 0xFF);\n } else if (tailbits === 18) {\n result.push((bits >> 10) & 0xFF);\n result.push((bits >> 2) & 0xFF);\n } else if (tailbits === 12) {\n result.push((bits >> 4) & 0xFF);\n }\n\n return new Uint8Array(result);\n}\n\nfunction representYamlBinary(object /*, style*/) {\n var result = '', bits = 0, idx, tail,\n max = object.length,\n map = BASE64_MAP;\n\n // Convert every three bytes to 4 ASCII characters.\n\n for (idx = 0; idx < max; idx++) {\n if ((idx % 3 === 0) && idx) {\n result += map[(bits >> 18) & 0x3F];\n result += map[(bits >> 12) & 0x3F];\n result += map[(bits >> 6) & 0x3F];\n result += map[bits & 0x3F];\n }\n\n bits = (bits << 8) + object[idx];\n }\n\n // Dump tail\n\n tail = max % 3;\n\n if (tail === 0) {\n result += map[(bits >> 18) & 0x3F];\n result += map[(bits >> 12) & 0x3F];\n result += map[(bits >> 6) & 0x3F];\n result += map[bits & 0x3F];\n } else if (tail === 2) {\n result += map[(bits >> 10) & 0x3F];\n result += map[(bits >> 4) & 0x3F];\n result += map[(bits << 2) & 0x3F];\n result += map[64];\n } else if (tail === 1) {\n result += map[(bits >> 2) & 0x3F];\n result += map[(bits << 4) & 0x3F];\n result += map[64];\n result += map[64];\n }\n\n return result;\n}\n\nfunction isBinary(obj) {\n return Object.prototype.toString.call(obj) === '[object Uint8Array]';\n}\n\nvar binary = new type('tag:yaml.org,2002:binary', {\n kind: 'scalar',\n resolve: resolveYamlBinary,\n construct: constructYamlBinary,\n predicate: isBinary,\n represent: representYamlBinary\n});\n\nvar _hasOwnProperty$3 = Object.prototype.hasOwnProperty;\nvar _toString$2 = Object.prototype.toString;\n\nfunction resolveYamlOmap(data) {\n if (data === null) return true;\n\n var objectKeys = [], index, length, pair, pairKey, pairHasKey,\n object = data;\n\n for (index = 0, length = object.length; index < length; index += 1) {\n pair = object[index];\n pairHasKey = false;\n\n if (_toString$2.call(pair) !== '[object Object]') return false;\n\n for (pairKey in pair) {\n if (_hasOwnProperty$3.call(pair, pairKey)) {\n if (!pairHasKey) pairHasKey = true;\n else return false;\n }\n }\n\n if (!pairHasKey) return false;\n\n if (objectKeys.indexOf(pairKey) === -1) objectKeys.push(pairKey);\n else return false;\n }\n\n return true;\n}\n\nfunction constructYamlOmap(data) {\n return data !== null ? data : [];\n}\n\nvar omap = new type('tag:yaml.org,2002:omap', {\n kind: 'sequence',\n resolve: resolveYamlOmap,\n construct: constructYamlOmap\n});\n\nvar _toString$1 = Object.prototype.toString;\n\nfunction resolveYamlPairs(data) {\n if (data === null) return true;\n\n var index, length, pair, keys, result,\n object = data;\n\n result = new Array(object.length);\n\n for (index = 0, length = object.length; index < length; index += 1) {\n pair = object[index];\n\n if (_toString$1.call(pair) !== '[object Object]') return false;\n\n keys = Object.keys(pair);\n\n if (keys.length !== 1) return false;\n\n result[index] = [ keys[0], pair[keys[0]] ];\n }\n\n return true;\n}\n\nfunction constructYamlPairs(data) {\n if (data === null) return [];\n\n var index, length, pair, keys, result,\n object = data;\n\n result = new Array(object.length);\n\n for (index = 0, length = object.length; index < length; index += 1) {\n pair = object[index];\n\n keys = Object.keys(pair);\n\n result[index] = [ keys[0], pair[keys[0]] ];\n }\n\n return result;\n}\n\nvar pairs = new type('tag:yaml.org,2002:pairs', {\n kind: 'sequence',\n resolve: resolveYamlPairs,\n construct: constructYamlPairs\n});\n\nvar _hasOwnProperty$2 = Object.prototype.hasOwnProperty;\n\nfunction resolveYamlSet(data) {\n if (data === null) return true;\n\n var key, object = data;\n\n for (key in object) {\n if (_hasOwnProperty$2.call(object, key)) {\n if (object[key] !== null) return false;\n }\n }\n\n return true;\n}\n\nfunction constructYamlSet(data) {\n return data !== null ? data : {};\n}\n\nvar set = new type('tag:yaml.org,2002:set', {\n kind: 'mapping',\n resolve: resolveYamlSet,\n construct: constructYamlSet\n});\n\nvar _default = core.extend({\n implicit: [\n timestamp,\n merge\n ],\n explicit: [\n binary,\n omap,\n pairs,\n set\n ]\n});\n\n/*eslint-disable max-len,no-use-before-define*/\n\n\n\n\n\n\n\nvar _hasOwnProperty$1 = Object.prototype.hasOwnProperty;\n\n\nvar CONTEXT_FLOW_IN = 1;\nvar CONTEXT_FLOW_OUT = 2;\nvar CONTEXT_BLOCK_IN = 3;\nvar CONTEXT_BLOCK_OUT = 4;\n\n\nvar CHOMPING_CLIP = 1;\nvar CHOMPING_STRIP = 2;\nvar CHOMPING_KEEP = 3;\n\n\nvar PATTERN_NON_PRINTABLE = /[\\x00-\\x08\\x0B\\x0C\\x0E-\\x1F\\x7F-\\x84\\x86-\\x9F\\uFFFE\\uFFFF]|[\\uD800-\\uDBFF](?![\\uDC00-\\uDFFF])|(?:[^\\uD800-\\uDBFF]|^)[\\uDC00-\\uDFFF]/;\nvar PATTERN_NON_ASCII_LINE_BREAKS = /[\\x85\\u2028\\u2029]/;\nvar PATTERN_FLOW_INDICATORS = /[,\\[\\]\\{\\}]/;\nvar PATTERN_TAG_HANDLE = /^(?:!|!!|![a-z\\-]+!)$/i;\nvar PATTERN_TAG_URI = /^(?:!|[^,\\[\\]\\{\\}])(?:%[0-9a-f]{2}|[0-9a-z\\-#;\\/\\?:@&=\\+\\$,_\\.!~\\*'\\(\\)\\[\\]])*$/i;\n\n\nfunction _class(obj) { return Object.prototype.toString.call(obj); }\n\nfunction is_EOL(c) {\n return (c === 0x0A/* LF */) || (c === 0x0D/* CR */);\n}\n\nfunction is_WHITE_SPACE(c) {\n return (c === 0x09/* Tab */) || (c === 0x20/* Space */);\n}\n\nfunction is_WS_OR_EOL(c) {\n return (c === 0x09/* Tab */) ||\n (c === 0x20/* Space */) ||\n (c === 0x0A/* LF */) ||\n (c === 0x0D/* CR */);\n}\n\nfunction is_FLOW_INDICATOR(c) {\n return c === 0x2C/* , */ ||\n c === 0x5B/* [ */ ||\n c === 0x5D/* ] */ ||\n c === 0x7B/* { */ ||\n c === 0x7D/* } */;\n}\n\nfunction fromHexCode(c) {\n var lc;\n\n if ((0x30/* 0 */ <= c) && (c <= 0x39/* 9 */)) {\n return c - 0x30;\n }\n\n /*eslint-disable no-bitwise*/\n lc = c | 0x20;\n\n if ((0x61/* a */ <= lc) && (lc <= 0x66/* f */)) {\n return lc - 0x61 + 10;\n }\n\n return -1;\n}\n\nfunction escapedHexLen(c) {\n if (c === 0x78/* x */) { return 2; }\n if (c === 0x75/* u */) { return 4; }\n if (c === 0x55/* U */) { return 8; }\n return 0;\n}\n\nfunction fromDecimalCode(c) {\n if ((0x30/* 0 */ <= c) && (c <= 0x39/* 9 */)) {\n return c - 0x30;\n }\n\n return -1;\n}\n\nfunction simpleEscapeSequence(c) {\n /* eslint-disable indent */\n return (c === 0x30/* 0 */) ? '\\x00' :\n (c === 0x61/* a */) ? '\\x07' :\n (c === 0x62/* b */) ? '\\x08' :\n (c === 0x74/* t */) ? '\\x09' :\n (c === 0x09/* Tab */) ? '\\x09' :\n (c === 0x6E/* n */) ? '\\x0A' :\n (c === 0x76/* v */) ? '\\x0B' :\n (c === 0x66/* f */) ? '\\x0C' :\n (c === 0x72/* r */) ? '\\x0D' :\n (c === 0x65/* e */) ? '\\x1B' :\n (c === 0x20/* Space */) ? ' ' :\n (c === 0x22/* \" */) ? '\\x22' :\n (c === 0x2F/* / */) ? '/' :\n (c === 0x5C/* \\ */) ? '\\x5C' :\n (c === 0x4E/* N */) ? '\\x85' :\n (c === 0x5F/* _ */) ? '\\xA0' :\n (c === 0x4C/* L */) ? '\\u2028' :\n (c === 0x50/* P */) ? '\\u2029' : '';\n}\n\nfunction charFromCodepoint(c) {\n if (c <= 0xFFFF) {\n return String.fromCharCode(c);\n }\n // Encode UTF-16 surrogate pair\n // https://en.wikipedia.org/wiki/UTF-16#Code_points_U.2B010000_to_U.2B10FFFF\n return String.fromCharCode(\n ((c - 0x010000) >> 10) + 0xD800,\n ((c - 0x010000) & 0x03FF) + 0xDC00\n );\n}\n\n// set a property of a literal object, while protecting against prototype pollution,\n// see https://github.com/nodeca/js-yaml/issues/164 for more details\nfunction setProperty(object, key, value) {\n // used for this specific key only because Object.defineProperty is slow\n if (key === '__proto__') {\n Object.defineProperty(object, key, {\n configurable: true,\n enumerable: true,\n writable: true,\n value: value\n });\n } else {\n object[key] = value;\n }\n}\n\nvar simpleEscapeCheck = new Array(256); // integer, for fast access\nvar simpleEscapeMap = new Array(256);\nfor (var i = 0; i < 256; i++) {\n simpleEscapeCheck[i] = simpleEscapeSequence(i) ? 1 : 0;\n simpleEscapeMap[i] = simpleEscapeSequence(i);\n}\n\n\nfunction State$1(input, options) {\n this.input = input;\n\n this.filename = options['filename'] || null;\n this.schema = options['schema'] || _default;\n this.onWarning = options['onWarning'] || null;\n // (Hidden) Remove? makes the loader to expect YAML 1.1 documents\n // if such documents have no explicit %YAML directive\n this.legacy = options['legacy'] || false;\n\n this.json = options['json'] || false;\n this.listener = options['listener'] || null;\n\n this.implicitTypes = this.schema.compiledImplicit;\n this.typeMap = this.schema.compiledTypeMap;\n\n this.length = input.length;\n this.position = 0;\n this.line = 0;\n this.lineStart = 0;\n this.lineIndent = 0;\n\n // position of first leading tab in the current line,\n // used to make sure there are no tabs in the indentation\n this.firstTabInLine = -1;\n\n this.documents = [];\n\n /*\n this.version;\n this.checkLineBreaks;\n this.tagMap;\n this.anchorMap;\n this.tag;\n this.anchor;\n this.kind;\n this.result;*/\n\n}\n\n\nfunction generateError(state, message) {\n var mark = {\n name: state.filename,\n buffer: state.input.slice(0, -1), // omit trailing \\0\n position: state.position,\n line: state.line,\n column: state.position - state.lineStart\n };\n\n mark.snippet = snippet(mark);\n\n return new exception(message, mark);\n}\n\nfunction throwError(state, message) {\n throw generateError(state, message);\n}\n\nfunction throwWarning(state, message) {\n if (state.onWarning) {\n state.onWarning.call(null, generateError(state, message));\n }\n}\n\n\nvar directiveHandlers = {\n\n YAML: function handleYamlDirective(state, name, args) {\n\n var match, major, minor;\n\n if (state.version !== null) {\n throwError(state, 'duplication of %YAML directive');\n }\n\n if (args.length !== 1) {\n throwError(state, 'YAML directive accepts exactly one argument');\n }\n\n match = /^([0-9]+)\\.([0-9]+)$/.exec(args[0]);\n\n if (match === null) {\n throwError(state, 'ill-formed argument of the YAML directive');\n }\n\n major = parseInt(match[1], 10);\n minor = parseInt(match[2], 10);\n\n if (major !== 1) {\n throwError(state, 'unacceptable YAML version of the document');\n }\n\n state.version = args[0];\n state.checkLineBreaks = (minor < 2);\n\n if (minor !== 1 && minor !== 2) {\n throwWarning(state, 'unsupported YAML version of the document');\n }\n },\n\n TAG: function handleTagDirective(state, name, args) {\n\n var handle, prefix;\n\n if (args.length !== 2) {\n throwError(state, 'TAG directive accepts exactly two arguments');\n }\n\n handle = args[0];\n prefix = args[1];\n\n if (!PATTERN_TAG_HANDLE.test(handle)) {\n throwError(state, 'ill-formed tag handle (first argument) of the TAG directive');\n }\n\n if (_hasOwnProperty$1.call(state.tagMap, handle)) {\n throwError(state, 'there is a previously declared suffix for \"' + handle + '\" tag handle');\n }\n\n if (!PATTERN_TAG_URI.test(prefix)) {\n throwError(state, 'ill-formed tag prefix (second argument) of the TAG directive');\n }\n\n try {\n prefix = decodeURIComponent(prefix);\n } catch (err) {\n throwError(state, 'tag prefix is malformed: ' + prefix);\n }\n\n state.tagMap[handle] = prefix;\n }\n};\n\n\nfunction captureSegment(state, start, end, checkJson) {\n var _position, _length, _character, _result;\n\n if (start < end) {\n _result = state.input.slice(start, end);\n\n if (checkJson) {\n for (_position = 0, _length = _result.length; _position < _length; _position += 1) {\n _character = _result.charCodeAt(_position);\n if (!(_character === 0x09 ||\n (0x20 <= _character && _character <= 0x10FFFF))) {\n throwError(state, 'expected valid JSON character');\n }\n }\n } else if (PATTERN_NON_PRINTABLE.test(_result)) {\n throwError(state, 'the stream contains non-printable characters');\n }\n\n state.result += _result;\n }\n}\n\nfunction mergeMappings(state, destination, source, overridableKeys) {\n var sourceKeys, key, index, quantity;\n\n if (!common.isObject(source)) {\n throwError(state, 'cannot merge mappings; the provided source object is unacceptable');\n }\n\n sourceKeys = Object.keys(source);\n\n for (index = 0, quantity = sourceKeys.length; index < quantity; index += 1) {\n key = sourceKeys[index];\n\n if (!_hasOwnProperty$1.call(destination, key)) {\n setProperty(destination, key, source[key]);\n overridableKeys[key] = true;\n }\n }\n}\n\nfunction storeMappingPair(state, _result, overridableKeys, keyTag, keyNode, valueNode,\n startLine, startLineStart, startPos) {\n\n var index, quantity;\n\n // The output is a plain object here, so keys can only be strings.\n // We need to convert keyNode to a string, but doing so can hang the process\n // (deeply nested arrays that explode exponentially using aliases).\n if (Array.isArray(keyNode)) {\n keyNode = Array.prototype.slice.call(keyNode);\n\n for (index = 0, quantity = keyNode.length; index < quantity; index += 1) {\n if (Array.isArray(keyNode[index])) {\n throwError(state, 'nested arrays are not supported inside keys');\n }\n\n if (typeof keyNode === 'object' && _class(keyNode[index]) === '[object Object]') {\n keyNode[index] = '[object Object]';\n }\n }\n }\n\n // Avoid code execution in load() via toString property\n // (still use its own toString for arrays, timestamps,\n // and whatever user schema extensions happen to have @@toStringTag)\n if (typeof keyNode === 'object' && _class(keyNode) === '[object Object]') {\n keyNode = '[object Object]';\n }\n\n\n keyNode = String(keyNode);\n\n if (_result === null) {\n _result = {};\n }\n\n if (keyTag === 'tag:yaml.org,2002:merge') {\n if (Array.isArray(valueNode)) {\n for (index = 0, quantity = valueNode.length; index < quantity; index += 1) {\n mergeMappings(state, _result, valueNode[index], overridableKeys);\n }\n } else {\n mergeMappings(state, _result, valueNode, overridableKeys);\n }\n } else {\n if (!state.json &&\n !_hasOwnProperty$1.call(overridableKeys, keyNode) &&\n _hasOwnProperty$1.call(_result, keyNode)) {\n state.line = startLine || state.line;\n state.lineStart = startLineStart || state.lineStart;\n state.position = startPos || state.position;\n throwError(state, 'duplicated mapping key');\n }\n\n setProperty(_result, keyNode, valueNode);\n delete overridableKeys[keyNode];\n }\n\n return _result;\n}\n\nfunction readLineBreak(state) {\n var ch;\n\n ch = state.input.charCodeAt(state.position);\n\n if (ch === 0x0A/* LF */) {\n state.position++;\n } else if (ch === 0x0D/* CR */) {\n state.position++;\n if (state.input.charCodeAt(state.position) === 0x0A/* LF */) {\n state.position++;\n }\n } else {\n throwError(state, 'a line break is expected');\n }\n\n state.line += 1;\n state.lineStart = state.position;\n state.firstTabInLine = -1;\n}\n\nfunction skipSeparationSpace(state, allowComments, checkIndent) {\n var lineBreaks = 0,\n ch = state.input.charCodeAt(state.position);\n\n while (ch !== 0) {\n while (is_WHITE_SPACE(ch)) {\n if (ch === 0x09/* Tab */ && state.firstTabInLine === -1) {\n state.firstTabInLine = state.position;\n }\n ch = state.input.charCodeAt(++state.position);\n }\n\n if (allowComments && ch === 0x23/* # */) {\n do {\n ch = state.input.charCodeAt(++state.position);\n } while (ch !== 0x0A/* LF */ && ch !== 0x0D/* CR */ && ch !== 0);\n }\n\n if (is_EOL(ch)) {\n readLineBreak(state);\n\n ch = state.input.charCodeAt(state.position);\n lineBreaks++;\n state.lineIndent = 0;\n\n while (ch === 0x20/* Space */) {\n state.lineIndent++;\n ch = state.input.charCodeAt(++state.position);\n }\n } else {\n break;\n }\n }\n\n if (checkIndent !== -1 && lineBreaks !== 0 && state.lineIndent < checkIndent) {\n throwWarning(state, 'deficient indentation');\n }\n\n return lineBreaks;\n}\n\nfunction testDocumentSeparator(state) {\n var _position = state.position,\n ch;\n\n ch = state.input.charCodeAt(_position);\n\n // Condition state.position === state.lineStart is tested\n // in parent on each call, for efficiency. No needs to test here again.\n if ((ch === 0x2D/* - */ || ch === 0x2E/* . */) &&\n ch === state.input.charCodeAt(_position + 1) &&\n ch === state.input.charCodeAt(_position + 2)) {\n\n _position += 3;\n\n ch = state.input.charCodeAt(_position);\n\n if (ch === 0 || is_WS_OR_EOL(ch)) {\n return true;\n }\n }\n\n return false;\n}\n\nfunction writeFoldedLines(state, count) {\n if (count === 1) {\n state.result += ' ';\n } else if (count > 1) {\n state.result += common.repeat('\\n', count - 1);\n }\n}\n\n\nfunction readPlainScalar(state, nodeIndent, withinFlowCollection) {\n var preceding,\n following,\n captureStart,\n captureEnd,\n hasPendingContent,\n _line,\n _lineStart,\n _lineIndent,\n _kind = state.kind,\n _result = state.result,\n ch;\n\n ch = state.input.charCodeAt(state.position);\n\n if (is_WS_OR_EOL(ch) ||\n is_FLOW_INDICATOR(ch) ||\n ch === 0x23/* # */ ||\n ch === 0x26/* & */ ||\n ch === 0x2A/* * */ ||\n ch === 0x21/* ! */ ||\n ch === 0x7C/* | */ ||\n ch === 0x3E/* > */ ||\n ch === 0x27/* ' */ ||\n ch === 0x22/* \" */ ||\n ch === 0x25/* % */ ||\n ch === 0x40/* @ */ ||\n ch === 0x60/* ` */) {\n return false;\n }\n\n if (ch === 0x3F/* ? */ || ch === 0x2D/* - */) {\n following = state.input.charCodeAt(state.position + 1);\n\n if (is_WS_OR_EOL(following) ||\n withinFlowCollection && is_FLOW_INDICATOR(following)) {\n return false;\n }\n }\n\n state.kind = 'scalar';\n state.result = '';\n captureStart = captureEnd = state.position;\n hasPendingContent = false;\n\n while (ch !== 0) {\n if (ch === 0x3A/* : */) {\n following = state.input.charCodeAt(state.position + 1);\n\n if (is_WS_OR_EOL(following) ||\n withinFlowCollection && is_FLOW_INDICATOR(following)) {\n break;\n }\n\n } else if (ch === 0x23/* # */) {\n preceding = state.input.charCodeAt(state.position - 1);\n\n if (is_WS_OR_EOL(preceding)) {\n break;\n }\n\n } else if ((state.position === state.lineStart && testDocumentSeparator(state)) ||\n withinFlowCollection && is_FLOW_INDICATOR(ch)) {\n break;\n\n } else if (is_EOL(ch)) {\n _line = state.line;\n _lineStart = state.lineStart;\n _lineIndent = state.lineIndent;\n skipSeparationSpace(state, false, -1);\n\n if (state.lineIndent >= nodeIndent) {\n hasPendingContent = true;\n ch = state.input.charCodeAt(state.position);\n continue;\n } else {\n state.position = captureEnd;\n state.line = _line;\n state.lineStart = _lineStart;\n state.lineIndent = _lineIndent;\n break;\n }\n }\n\n if (hasPendingContent) {\n captureSegment(state, captureStart, captureEnd, false);\n writeFoldedLines(state, state.line - _line);\n captureStart = captureEnd = state.position;\n hasPendingContent = false;\n }\n\n if (!is_WHITE_SPACE(ch)) {\n captureEnd = state.position + 1;\n }\n\n ch = state.input.charCodeAt(++state.position);\n }\n\n captureSegment(state, captureStart, captureEnd, false);\n\n if (state.result) {\n return true;\n }\n\n state.kind = _kind;\n state.result = _result;\n return false;\n}\n\nfunction readSingleQuotedScalar(state, nodeIndent) {\n var ch,\n captureStart, captureEnd;\n\n ch = state.input.charCodeAt(state.position);\n\n if (ch !== 0x27/* ' */) {\n return false;\n }\n\n state.kind = 'scalar';\n state.result = '';\n state.position++;\n captureStart = captureEnd = state.position;\n\n while ((ch = state.input.charCodeAt(state.position)) !== 0) {\n if (ch === 0x27/* ' */) {\n captureSegment(state, captureStart, state.position, true);\n ch = state.input.charCodeAt(++state.position);\n\n if (ch === 0x27/* ' */) {\n captureStart = state.position;\n state.position++;\n captureEnd = state.position;\n } else {\n return true;\n }\n\n } else if (is_EOL(ch)) {\n captureSegment(state, captureStart, captureEnd, true);\n writeFoldedLines(state, skipSeparationSpace(state, false, nodeIndent));\n captureStart = captureEnd = state.position;\n\n } else if (state.position === state.lineStart && testDocumentSeparator(state)) {\n throwError(state, 'unexpected end of the document within a single quoted scalar');\n\n } else {\n state.position++;\n captureEnd = state.position;\n }\n }\n\n throwError(state, 'unexpected end of the stream within a single quoted scalar');\n}\n\nfunction readDoubleQuotedScalar(state, nodeIndent) {\n var captureStart,\n captureEnd,\n hexLength,\n hexResult,\n tmp,\n ch;\n\n ch = state.input.charCodeAt(state.position);\n\n if (ch !== 0x22/* \" */) {\n return false;\n }\n\n state.kind = 'scalar';\n state.result = '';\n state.position++;\n captureStart = captureEnd = state.position;\n\n while ((ch = state.input.charCodeAt(state.position)) !== 0) {\n if (ch === 0x22/* \" */) {\n captureSegment(state, captureStart, state.position, true);\n state.position++;\n return true;\n\n } else if (ch === 0x5C/* \\ */) {\n captureSegment(state, captureStart, state.position, true);\n ch = state.input.charCodeAt(++state.position);\n\n if (is_EOL(ch)) {\n skipSeparationSpace(state, false, nodeIndent);\n\n // TODO: rework to inline fn with no type cast?\n } else if (ch < 256 && simpleEscapeCheck[ch]) {\n state.result += simpleEscapeMap[ch];\n state.position++;\n\n } else if ((tmp = escapedHexLen(ch)) > 0) {\n hexLength = tmp;\n hexResult = 0;\n\n for (; hexLength > 0; hexLength--) {\n ch = state.input.charCodeAt(++state.position);\n\n if ((tmp = fromHexCode(ch)) >= 0) {\n hexResult = (hexResult << 4) + tmp;\n\n } else {\n throwError(state, 'expected hexadecimal character');\n }\n }\n\n state.result += charFromCodepoint(hexResult);\n\n state.position++;\n\n } else {\n throwError(state, 'unknown escape sequence');\n }\n\n captureStart = captureEnd = state.position;\n\n } else if (is_EOL(ch)) {\n captureSegment(state, captureStart, captureEnd, true);\n writeFoldedLines(state, skipSeparationSpace(state, false, nodeIndent));\n captureStart = captureEnd = state.position;\n\n } else if (state.position === state.lineStart && testDocumentSeparator(state)) {\n throwError(state, 'unexpected end of the document within a double quoted scalar');\n\n } else {\n state.position++;\n captureEnd = state.position;\n }\n }\n\n throwError(state, 'unexpected end of the stream within a double quoted scalar');\n}\n\nfunction readFlowCollection(state, nodeIndent) {\n var readNext = true,\n _line,\n _lineStart,\n _pos,\n _tag = state.tag,\n _result,\n _anchor = state.anchor,\n following,\n terminator,\n isPair,\n isExplicitPair,\n isMapping,\n overridableKeys = Object.create(null),\n keyNode,\n keyTag,\n valueNode,\n ch;\n\n ch = state.input.charCodeAt(state.position);\n\n if (ch === 0x5B/* [ */) {\n terminator = 0x5D;/* ] */\n isMapping = false;\n _result = [];\n } else if (ch === 0x7B/* { */) {\n terminator = 0x7D;/* } */\n isMapping = true;\n _result = {};\n } else {\n return false;\n }\n\n if (state.anchor !== null) {\n state.anchorMap[state.anchor] = _result;\n }\n\n ch = state.input.charCodeAt(++state.position);\n\n while (ch !== 0) {\n skipSeparationSpace(state, true, nodeIndent);\n\n ch = state.input.charCodeAt(state.position);\n\n if (ch === terminator) {\n state.position++;\n state.tag = _tag;\n state.anchor = _anchor;\n state.kind = isMapping ? 'mapping' : 'sequence';\n state.result = _result;\n return true;\n } else if (!readNext) {\n throwError(state, 'missed comma between flow collection entries');\n } else if (ch === 0x2C/* , */) {\n // \"flow collection entries can never be completely empty\", as per YAML 1.2, section 7.4\n throwError(state, \"expected the node content, but found ','\");\n }\n\n keyTag = keyNode = valueNode = null;\n isPair = isExplicitPair = false;\n\n if (ch === 0x3F/* ? */) {\n following = state.input.charCodeAt(state.position + 1);\n\n if (is_WS_OR_EOL(following)) {\n isPair = isExplicitPair = true;\n state.position++;\n skipSeparationSpace(state, true, nodeIndent);\n }\n }\n\n _line = state.line; // Save the current line.\n _lineStart = state.lineStart;\n _pos = state.position;\n composeNode(state, nodeIndent, CONTEXT_FLOW_IN, false, true);\n keyTag = state.tag;\n keyNode = state.result;\n skipSeparationSpace(state, true, nodeIndent);\n\n ch = state.input.charCodeAt(state.position);\n\n if ((isExplicitPair || state.line === _line) && ch === 0x3A/* : */) {\n isPair = true;\n ch = state.input.charCodeAt(++state.position);\n skipSeparationSpace(state, true, nodeIndent);\n composeNode(state, nodeIndent, CONTEXT_FLOW_IN, false, true);\n valueNode = state.result;\n }\n\n if (isMapping) {\n storeMappingPair(state, _result, overridableKeys, keyTag, keyNode, valueNode, _line, _lineStart, _pos);\n } else if (isPair) {\n _result.push(storeMappingPair(state, null, overridableKeys, keyTag, keyNode, valueNode, _line, _lineStart, _pos));\n } else {\n _result.push(keyNode);\n }\n\n skipSeparationSpace(state, true, nodeIndent);\n\n ch = state.input.charCodeAt(state.position);\n\n if (ch === 0x2C/* , */) {\n readNext = true;\n ch = state.input.charCodeAt(++state.position);\n } else {\n readNext = false;\n }\n }\n\n throwError(state, 'unexpected end of the stream within a flow collection');\n}\n\nfunction readBlockScalar(state, nodeIndent) {\n var captureStart,\n folding,\n chomping = CHOMPING_CLIP,\n didReadContent = false,\n detectedIndent = false,\n textIndent = nodeIndent,\n emptyLines = 0,\n atMoreIndented = false,\n tmp,\n ch;\n\n ch = state.input.charCodeAt(state.position);\n\n if (ch === 0x7C/* | */) {\n folding = false;\n } else if (ch === 0x3E/* > */) {\n folding = true;\n } else {\n return false;\n }\n\n state.kind = 'scalar';\n state.result = '';\n\n while (ch !== 0) {\n ch = state.input.charCodeAt(++state.position);\n\n if (ch === 0x2B/* + */ || ch === 0x2D/* - */) {\n if (CHOMPING_CLIP === chomping) {\n chomping = (ch === 0x2B/* + */) ? CHOMPING_KEEP : CHOMPING_STRIP;\n } else {\n throwError(state, 'repeat of a chomping mode identifier');\n }\n\n } else if ((tmp = fromDecimalCode(ch)) >= 0) {\n if (tmp === 0) {\n throwError(state, 'bad explicit indentation width of a block scalar; it cannot be less than one');\n } else if (!detectedIndent) {\n textIndent = nodeIndent + tmp - 1;\n detectedIndent = true;\n } else {\n throwError(state, 'repeat of an indentation width identifier');\n }\n\n } else {\n break;\n }\n }\n\n if (is_WHITE_SPACE(ch)) {\n do { ch = state.input.charCodeAt(++state.position); }\n while (is_WHITE_SPACE(ch));\n\n if (ch === 0x23/* # */) {\n do { ch = state.input.charCodeAt(++state.position); }\n while (!is_EOL(ch) && (ch !== 0));\n }\n }\n\n while (ch !== 0) {\n readLineBreak(state);\n state.lineIndent = 0;\n\n ch = state.input.charCodeAt(state.position);\n\n while ((!detectedIndent || state.lineIndent < textIndent) &&\n (ch === 0x20/* Space */)) {\n state.lineIndent++;\n ch = state.input.charCodeAt(++state.position);\n }\n\n if (!detectedIndent && state.lineIndent > textIndent) {\n textIndent = state.lineIndent;\n }\n\n if (is_EOL(ch)) {\n emptyLines++;\n continue;\n }\n\n // End of the scalar.\n if (state.lineIndent < textIndent) {\n\n // Perform the chomping.\n if (chomping === CHOMPING_KEEP) {\n state.result += common.repeat('\\n', didReadContent ? 1 + emptyLines : emptyLines);\n } else if (chomping === CHOMPING_CLIP) {\n if (didReadContent) { // i.e. only if the scalar is not empty.\n state.result += '\\n';\n }\n }\n\n // Break this `while` cycle and go to the funciton's epilogue.\n break;\n }\n\n // Folded style: use fancy rules to handle line breaks.\n if (folding) {\n\n // Lines starting with white space characters (more-indented lines) are not folded.\n if (is_WHITE_SPACE(ch)) {\n atMoreIndented = true;\n // except for the first content line (cf. Example 8.1)\n state.result += common.repeat('\\n', didReadContent ? 1 + emptyLines : emptyLines);\n\n // End of more-indented block.\n } else if (atMoreIndented) {\n atMoreIndented = false;\n state.result += common.repeat('\\n', emptyLines + 1);\n\n // Just one line break - perceive as the same line.\n } else if (emptyLines === 0) {\n if (didReadContent) { // i.e. only if we have already read some scalar content.\n state.result += ' ';\n }\n\n // Several line breaks - perceive as different lines.\n } else {\n state.result += common.repeat('\\n', emptyLines);\n }\n\n // Literal style: just add exact number of line breaks between content lines.\n } else {\n // Keep all line breaks except the header line break.\n state.result += common.repeat('\\n', didReadContent ? 1 + emptyLines : emptyLines);\n }\n\n didReadContent = true;\n detectedIndent = true;\n emptyLines = 0;\n captureStart = state.position;\n\n while (!is_EOL(ch) && (ch !== 0)) {\n ch = state.input.charCodeAt(++state.position);\n }\n\n captureSegment(state, captureStart, state.position, false);\n }\n\n return true;\n}\n\nfunction readBlockSequence(state, nodeIndent) {\n var _line,\n _tag = state.tag,\n _anchor = state.anchor,\n _result = [],\n following,\n detected = false,\n ch;\n\n // there is a leading tab before this token, so it can't be a block sequence/mapping;\n // it can still be flow sequence/mapping or a scalar\n if (state.firstTabInLine !== -1) return false;\n\n if (state.anchor !== null) {\n state.anchorMap[state.anchor] = _result;\n }\n\n ch = state.input.charCodeAt(state.position);\n\n while (ch !== 0) {\n if (state.firstTabInLine !== -1) {\n state.position = state.firstTabInLine;\n throwError(state, 'tab characters must not be used in indentation');\n }\n\n if (ch !== 0x2D/* - */) {\n break;\n }\n\n following = state.input.charCodeAt(state.position + 1);\n\n if (!is_WS_OR_EOL(following)) {\n break;\n }\n\n detected = true;\n state.position++;\n\n if (skipSeparationSpace(state, true, -1)) {\n if (state.lineIndent <= nodeIndent) {\n _result.push(null);\n ch = state.input.charCodeAt(state.position);\n continue;\n }\n }\n\n _line = state.line;\n composeNode(state, nodeIndent, CONTEXT_BLOCK_IN, false, true);\n _result.push(state.result);\n skipSeparationSpace(state, true, -1);\n\n ch = state.input.charCodeAt(state.position);\n\n if ((state.line === _line || state.lineIndent > nodeIndent) && (ch !== 0)) {\n throwError(state, 'bad indentation of a sequence entry');\n } else if (state.lineIndent < nodeIndent) {\n break;\n }\n }\n\n if (detected) {\n state.tag = _tag;\n state.anchor = _anchor;\n state.kind = 'sequence';\n state.result = _result;\n return true;\n }\n return false;\n}\n\nfunction readBlockMapping(state, nodeIndent, flowIndent) {\n var following,\n allowCompact,\n _line,\n _keyLine,\n _keyLineStart,\n _keyPos,\n _tag = state.tag,\n _anchor = state.anchor,\n _result = {},\n overridableKeys = Object.create(null),\n keyTag = null,\n keyNode = null,\n valueNode = null,\n atExplicitKey = false,\n detected = false,\n ch;\n\n // there is a leading tab before this token, so it can't be a block sequence/mapping;\n // it can still be flow sequence/mapping or a scalar\n if (state.firstTabInLine !== -1) return false;\n\n if (state.anchor !== null) {\n state.anchorMap[state.anchor] = _result;\n }\n\n ch = state.input.charCodeAt(state.position);\n\n while (ch !== 0) {\n if (!atExplicitKey && state.firstTabInLine !== -1) {\n state.position = state.firstTabInLine;\n throwError(state, 'tab characters must not be used in indentation');\n }\n\n following = state.input.charCodeAt(state.position + 1);\n _line = state.line; // Save the current line.\n\n //\n // Explicit notation case. There are two separate blocks:\n // first for the key (denoted by \"?\") and second for the value (denoted by \":\")\n //\n if ((ch === 0x3F/* ? */ || ch === 0x3A/* : */) && is_WS_OR_EOL(following)) {\n\n if (ch === 0x3F/* ? */) {\n if (atExplicitKey) {\n storeMappingPair(state, _result, overridableKeys, keyTag, keyNode, null, _keyLine, _keyLineStart, _keyPos);\n keyTag = keyNode = valueNode = null;\n }\n\n detected = true;\n atExplicitKey = true;\n allowCompact = true;\n\n } else if (atExplicitKey) {\n // i.e. 0x3A/* : */ === character after the explicit key.\n atExplicitKey = false;\n allowCompact = true;\n\n } else {\n throwError(state, 'incomplete explicit mapping pair; a key node is missed; or followed by a non-tabulated empty line');\n }\n\n state.position += 1;\n ch = following;\n\n //\n // Implicit notation case. Flow-style node as the key first, then \":\", and the value.\n //\n } else {\n _keyLine = state.line;\n _keyLineStart = state.lineStart;\n _keyPos = state.position;\n\n if (!composeNode(state, flowIndent, CONTEXT_FLOW_OUT, false, true)) {\n // Neither implicit nor explicit notation.\n // Reading is done. Go to the epilogue.\n break;\n }\n\n if (state.line === _line) {\n ch = state.input.charCodeAt(state.position);\n\n while (is_WHITE_SPACE(ch)) {\n ch = state.input.charCodeAt(++state.position);\n }\n\n if (ch === 0x3A/* : */) {\n ch = state.input.charCodeAt(++state.position);\n\n if (!is_WS_OR_EOL(ch)) {\n throwError(state, 'a whitespace character is expected after the key-value separator within a block mapping');\n }\n\n if (atExplicitKey) {\n storeMappingPair(state, _result, overridableKeys, keyTag, keyNode, null, _keyLine, _keyLineStart, _keyPos);\n keyTag = keyNode = valueNode = null;\n }\n\n detected = true;\n atExplicitKey = false;\n allowCompact = false;\n keyTag = state.tag;\n keyNode = state.result;\n\n } else if (detected) {\n throwError(state, 'can not read an implicit mapping pair; a colon is missed');\n\n } else {\n state.tag = _tag;\n state.anchor = _anchor;\n return true; // Keep the result of `composeNode`.\n }\n\n } else if (detected) {\n throwError(state, 'can not read a block mapping entry; a multiline key may not be an implicit key');\n\n } else {\n state.tag = _tag;\n state.anchor = _anchor;\n return true; // Keep the result of `composeNode`.\n }\n }\n\n //\n // Common reading code for both explicit and implicit notations.\n //\n if (state.line === _line || state.lineIndent > nodeIndent) {\n if (atExplicitKey) {\n _keyLine = state.line;\n _keyLineStart = state.lineStart;\n _keyPos = state.position;\n }\n\n if (composeNode(state, nodeIndent, CONTEXT_BLOCK_OUT, true, allowCompact)) {\n if (atExplicitKey) {\n keyNode = state.result;\n } else {\n valueNode = state.result;\n }\n }\n\n if (!atExplicitKey) {\n storeMappingPair(state, _result, overridableKeys, keyTag, keyNode, valueNode, _keyLine, _keyLineStart, _keyPos);\n keyTag = keyNode = valueNode = null;\n }\n\n skipSeparationSpace(state, true, -1);\n ch = state.input.charCodeAt(state.position);\n }\n\n if ((state.line === _line || state.lineIndent > nodeIndent) && (ch !== 0)) {\n throwError(state, 'bad indentation of a mapping entry');\n } else if (state.lineIndent < nodeIndent) {\n break;\n }\n }\n\n //\n // Epilogue.\n //\n\n // Special case: last mapping's node contains only the key in explicit notation.\n if (atExplicitKey) {\n storeMappingPair(state, _result, overridableKeys, keyTag, keyNode, null, _keyLine, _keyLineStart, _keyPos);\n }\n\n // Expose the resulting mapping.\n if (detected) {\n state.tag = _tag;\n state.anchor = _anchor;\n state.kind = 'mapping';\n state.result = _result;\n }\n\n return detected;\n}\n\nfunction readTagProperty(state) {\n var _position,\n isVerbatim = false,\n isNamed = false,\n tagHandle,\n tagName,\n ch;\n\n ch = state.input.charCodeAt(state.position);\n\n if (ch !== 0x21/* ! */) return false;\n\n if (state.tag !== null) {\n throwError(state, 'duplication of a tag property');\n }\n\n ch = state.input.charCodeAt(++state.position);\n\n if (ch === 0x3C/* < */) {\n isVerbatim = true;\n ch = state.input.charCodeAt(++state.position);\n\n } else if (ch === 0x21/* ! */) {\n isNamed = true;\n tagHandle = '!!';\n ch = state.input.charCodeAt(++state.position);\n\n } else {\n tagHandle = '!';\n }\n\n _position = state.position;\n\n if (isVerbatim) {\n do { ch = state.input.charCodeAt(++state.position); }\n while (ch !== 0 && ch !== 0x3E/* > */);\n\n if (state.position < state.length) {\n tagName = state.input.slice(_position, state.position);\n ch = state.input.charCodeAt(++state.position);\n } else {\n throwError(state, 'unexpected end of the stream within a verbatim tag');\n }\n } else {\n while (ch !== 0 && !is_WS_OR_EOL(ch)) {\n\n if (ch === 0x21/* ! */) {\n if (!isNamed) {\n tagHandle = state.input.slice(_position - 1, state.position + 1);\n\n if (!PATTERN_TAG_HANDLE.test(tagHandle)) {\n throwError(state, 'named tag handle cannot contain such characters');\n }\n\n isNamed = true;\n _position = state.position + 1;\n } else {\n throwError(state, 'tag suffix cannot contain exclamation marks');\n }\n }\n\n ch = state.input.charCodeAt(++state.position);\n }\n\n tagName = state.input.slice(_position, state.position);\n\n if (PATTERN_FLOW_INDICATORS.test(tagName)) {\n throwError(state, 'tag suffix cannot contain flow indicator characters');\n }\n }\n\n if (tagName && !PATTERN_TAG_URI.test(tagName)) {\n throwError(state, 'tag name cannot contain such characters: ' + tagName);\n }\n\n try {\n tagName = decodeURIComponent(tagName);\n } catch (err) {\n throwError(state, 'tag name is malformed: ' + tagName);\n }\n\n if (isVerbatim) {\n state.tag = tagName;\n\n } else if (_hasOwnProperty$1.call(state.tagMap, tagHandle)) {\n state.tag = state.tagMap[tagHandle] + tagName;\n\n } else if (tagHandle === '!') {\n state.tag = '!' + tagName;\n\n } else if (tagHandle === '!!') {\n state.tag = 'tag:yaml.org,2002:' + tagName;\n\n } else {\n throwError(state, 'undeclared tag handle \"' + tagHandle + '\"');\n }\n\n return true;\n}\n\nfunction readAnchorProperty(state) {\n var _position,\n ch;\n\n ch = state.input.charCodeAt(state.position);\n\n if (ch !== 0x26/* & */) return false;\n\n if (state.anchor !== null) {\n throwError(state, 'duplication of an anchor property');\n }\n\n ch = state.input.charCodeAt(++state.position);\n _position = state.position;\n\n while (ch !== 0 && !is_WS_OR_EOL(ch) && !is_FLOW_INDICATOR(ch)) {\n ch = state.input.charCodeAt(++state.position);\n }\n\n if (state.position === _position) {\n throwError(state, 'name of an anchor node must contain at least one character');\n }\n\n state.anchor = state.input.slice(_position, state.position);\n return true;\n}\n\nfunction readAlias(state) {\n var _position, alias,\n ch;\n\n ch = state.input.charCodeAt(state.position);\n\n if (ch !== 0x2A/* * */) return false;\n\n ch = state.input.charCodeAt(++state.position);\n _position = state.position;\n\n while (ch !== 0 && !is_WS_OR_EOL(ch) && !is_FLOW_INDICATOR(ch)) {\n ch = state.input.charCodeAt(++state.position);\n }\n\n if (state.position === _position) {\n throwError(state, 'name of an alias node must contain at least one character');\n }\n\n alias = state.input.slice(_position, state.position);\n\n if (!_hasOwnProperty$1.call(state.anchorMap, alias)) {\n throwError(state, 'unidentified alias \"' + alias + '\"');\n }\n\n state.result = state.anchorMap[alias];\n skipSeparationSpace(state, true, -1);\n return true;\n}\n\nfunction composeNode(state, parentIndent, nodeContext, allowToSeek, allowCompact) {\n var allowBlockStyles,\n allowBlockScalars,\n allowBlockCollections,\n indentStatus = 1, // 1: this>parent, 0: this=parent, -1: this parentIndent) {\n indentStatus = 1;\n } else if (state.lineIndent === parentIndent) {\n indentStatus = 0;\n } else if (state.lineIndent < parentIndent) {\n indentStatus = -1;\n }\n }\n }\n\n if (indentStatus === 1) {\n while (readTagProperty(state) || readAnchorProperty(state)) {\n if (skipSeparationSpace(state, true, -1)) {\n atNewLine = true;\n allowBlockCollections = allowBlockStyles;\n\n if (state.lineIndent > parentIndent) {\n indentStatus = 1;\n } else if (state.lineIndent === parentIndent) {\n indentStatus = 0;\n } else if (state.lineIndent < parentIndent) {\n indentStatus = -1;\n }\n } else {\n allowBlockCollections = false;\n }\n }\n }\n\n if (allowBlockCollections) {\n allowBlockCollections = atNewLine || allowCompact;\n }\n\n if (indentStatus === 1 || CONTEXT_BLOCK_OUT === nodeContext) {\n if (CONTEXT_FLOW_IN === nodeContext || CONTEXT_FLOW_OUT === nodeContext) {\n flowIndent = parentIndent;\n } else {\n flowIndent = parentIndent + 1;\n }\n\n blockIndent = state.position - state.lineStart;\n\n if (indentStatus === 1) {\n if (allowBlockCollections &&\n (readBlockSequence(state, blockIndent) ||\n readBlockMapping(state, blockIndent, flowIndent)) ||\n readFlowCollection(state, flowIndent)) {\n hasContent = true;\n } else {\n if ((allowBlockScalars && readBlockScalar(state, flowIndent)) ||\n readSingleQuotedScalar(state, flowIndent) ||\n readDoubleQuotedScalar(state, flowIndent)) {\n hasContent = true;\n\n } else if (readAlias(state)) {\n hasContent = true;\n\n if (state.tag !== null || state.anchor !== null) {\n throwError(state, 'alias node should not have any properties');\n }\n\n } else if (readPlainScalar(state, flowIndent, CONTEXT_FLOW_IN === nodeContext)) {\n hasContent = true;\n\n if (state.tag === null) {\n state.tag = '?';\n }\n }\n\n if (state.anchor !== null) {\n state.anchorMap[state.anchor] = state.result;\n }\n }\n } else if (indentStatus === 0) {\n // Special case: block sequences are allowed to have same indentation level as the parent.\n // http://www.yaml.org/spec/1.2/spec.html#id2799784\n hasContent = allowBlockCollections && readBlockSequence(state, blockIndent);\n }\n }\n\n if (state.tag === null) {\n if (state.anchor !== null) {\n state.anchorMap[state.anchor] = state.result;\n }\n\n } else if (state.tag === '?') {\n // Implicit resolving is not allowed for non-scalar types, and '?'\n // non-specific tag is only automatically assigned to plain scalars.\n //\n // We only need to check kind conformity in case user explicitly assigns '?'\n // tag, for example like this: \"! [0]\"\n //\n if (state.result !== null && state.kind !== 'scalar') {\n throwError(state, 'unacceptable node kind for ! tag; it should be \"scalar\", not \"' + state.kind + '\"');\n }\n\n for (typeIndex = 0, typeQuantity = state.implicitTypes.length; typeIndex < typeQuantity; typeIndex += 1) {\n type = state.implicitTypes[typeIndex];\n\n if (type.resolve(state.result)) { // `state.result` updated in resolver if matched\n state.result = type.construct(state.result);\n state.tag = type.tag;\n if (state.anchor !== null) {\n state.anchorMap[state.anchor] = state.result;\n }\n break;\n }\n }\n } else if (state.tag !== '!') {\n if (_hasOwnProperty$1.call(state.typeMap[state.kind || 'fallback'], state.tag)) {\n type = state.typeMap[state.kind || 'fallback'][state.tag];\n } else {\n // looking for multi type\n type = null;\n typeList = state.typeMap.multi[state.kind || 'fallback'];\n\n for (typeIndex = 0, typeQuantity = typeList.length; typeIndex < typeQuantity; typeIndex += 1) {\n if (state.tag.slice(0, typeList[typeIndex].tag.length) === typeList[typeIndex].tag) {\n type = typeList[typeIndex];\n break;\n }\n }\n }\n\n if (!type) {\n throwError(state, 'unknown tag !<' + state.tag + '>');\n }\n\n if (state.result !== null && type.kind !== state.kind) {\n throwError(state, 'unacceptable node kind for !<' + state.tag + '> tag; it should be \"' + type.kind + '\", not \"' + state.kind + '\"');\n }\n\n if (!type.resolve(state.result, state.tag)) { // `state.result` updated in resolver if matched\n throwError(state, 'cannot resolve a node with !<' + state.tag + '> explicit tag');\n } else {\n state.result = type.construct(state.result, state.tag);\n if (state.anchor !== null) {\n state.anchorMap[state.anchor] = state.result;\n }\n }\n }\n\n if (state.listener !== null) {\n state.listener('close', state);\n }\n return state.tag !== null || state.anchor !== null || hasContent;\n}\n\nfunction readDocument(state) {\n var documentStart = state.position,\n _position,\n directiveName,\n directiveArgs,\n hasDirectives = false,\n ch;\n\n state.version = null;\n state.checkLineBreaks = state.legacy;\n state.tagMap = Object.create(null);\n state.anchorMap = Object.create(null);\n\n while ((ch = state.input.charCodeAt(state.position)) !== 0) {\n skipSeparationSpace(state, true, -1);\n\n ch = state.input.charCodeAt(state.position);\n\n if (state.lineIndent > 0 || ch !== 0x25/* % */) {\n break;\n }\n\n hasDirectives = true;\n ch = state.input.charCodeAt(++state.position);\n _position = state.position;\n\n while (ch !== 0 && !is_WS_OR_EOL(ch)) {\n ch = state.input.charCodeAt(++state.position);\n }\n\n directiveName = state.input.slice(_position, state.position);\n directiveArgs = [];\n\n if (directiveName.length < 1) {\n throwError(state, 'directive name must not be less than one character in length');\n }\n\n while (ch !== 0) {\n while (is_WHITE_SPACE(ch)) {\n ch = state.input.charCodeAt(++state.position);\n }\n\n if (ch === 0x23/* # */) {\n do { ch = state.input.charCodeAt(++state.position); }\n while (ch !== 0 && !is_EOL(ch));\n break;\n }\n\n if (is_EOL(ch)) break;\n\n _position = state.position;\n\n while (ch !== 0 && !is_WS_OR_EOL(ch)) {\n ch = state.input.charCodeAt(++state.position);\n }\n\n directiveArgs.push(state.input.slice(_position, state.position));\n }\n\n if (ch !== 0) readLineBreak(state);\n\n if (_hasOwnProperty$1.call(directiveHandlers, directiveName)) {\n directiveHandlers[directiveName](state, directiveName, directiveArgs);\n } else {\n throwWarning(state, 'unknown document directive \"' + directiveName + '\"');\n }\n }\n\n skipSeparationSpace(state, true, -1);\n\n if (state.lineIndent === 0 &&\n state.input.charCodeAt(state.position) === 0x2D/* - */ &&\n state.input.charCodeAt(state.position + 1) === 0x2D/* - */ &&\n state.input.charCodeAt(state.position + 2) === 0x2D/* - */) {\n state.position += 3;\n skipSeparationSpace(state, true, -1);\n\n } else if (hasDirectives) {\n throwError(state, 'directives end mark is expected');\n }\n\n composeNode(state, state.lineIndent - 1, CONTEXT_BLOCK_OUT, false, true);\n skipSeparationSpace(state, true, -1);\n\n if (state.checkLineBreaks &&\n PATTERN_NON_ASCII_LINE_BREAKS.test(state.input.slice(documentStart, state.position))) {\n throwWarning(state, 'non-ASCII line breaks are interpreted as content');\n }\n\n state.documents.push(state.result);\n\n if (state.position === state.lineStart && testDocumentSeparator(state)) {\n\n if (state.input.charCodeAt(state.position) === 0x2E/* . */) {\n state.position += 3;\n skipSeparationSpace(state, true, -1);\n }\n return;\n }\n\n if (state.position < (state.length - 1)) {\n throwError(state, 'end of the stream or a document separator is expected');\n } else {\n return;\n }\n}\n\n\nfunction loadDocuments(input, options) {\n input = String(input);\n options = options || {};\n\n if (input.length !== 0) {\n\n // Add tailing `\\n` if not exists\n if (input.charCodeAt(input.length - 1) !== 0x0A/* LF */ &&\n input.charCodeAt(input.length - 1) !== 0x0D/* CR */) {\n input += '\\n';\n }\n\n // Strip BOM\n if (input.charCodeAt(0) === 0xFEFF) {\n input = input.slice(1);\n }\n }\n\n var state = new State$1(input, options);\n\n var nullpos = input.indexOf('\\0');\n\n if (nullpos !== -1) {\n state.position = nullpos;\n throwError(state, 'null byte is not allowed in input');\n }\n\n // Use 0 as string terminator. That significantly simplifies bounds check.\n state.input += '\\0';\n\n while (state.input.charCodeAt(state.position) === 0x20/* Space */) {\n state.lineIndent += 1;\n state.position += 1;\n }\n\n while (state.position < (state.length - 1)) {\n readDocument(state);\n }\n\n return state.documents;\n}\n\n\nfunction loadAll$1(input, iterator, options) {\n if (iterator !== null && typeof iterator === 'object' && typeof options === 'undefined') {\n options = iterator;\n iterator = null;\n }\n\n var documents = loadDocuments(input, options);\n\n if (typeof iterator !== 'function') {\n return documents;\n }\n\n for (var index = 0, length = documents.length; index < length; index += 1) {\n iterator(documents[index]);\n }\n}\n\n\nfunction load$1(input, options) {\n var documents = loadDocuments(input, options);\n\n if (documents.length === 0) {\n /*eslint-disable no-undefined*/\n return undefined;\n } else if (documents.length === 1) {\n return documents[0];\n }\n throw new exception('expected a single document in the stream, but found more');\n}\n\n\nvar loadAll_1 = loadAll$1;\nvar load_1 = load$1;\n\nvar loader = {\n\tloadAll: loadAll_1,\n\tload: load_1\n};\n\n/*eslint-disable no-use-before-define*/\n\n\n\n\n\nvar _toString = Object.prototype.toString;\nvar _hasOwnProperty = Object.prototype.hasOwnProperty;\n\nvar CHAR_BOM = 0xFEFF;\nvar CHAR_TAB = 0x09; /* Tab */\nvar CHAR_LINE_FEED = 0x0A; /* LF */\nvar CHAR_CARRIAGE_RETURN = 0x0D; /* CR */\nvar CHAR_SPACE = 0x20; /* Space */\nvar CHAR_EXCLAMATION = 0x21; /* ! */\nvar CHAR_DOUBLE_QUOTE = 0x22; /* \" */\nvar CHAR_SHARP = 0x23; /* # */\nvar CHAR_PERCENT = 0x25; /* % */\nvar CHAR_AMPERSAND = 0x26; /* & */\nvar CHAR_SINGLE_QUOTE = 0x27; /* ' */\nvar CHAR_ASTERISK = 0x2A; /* * */\nvar CHAR_COMMA = 0x2C; /* , */\nvar CHAR_MINUS = 0x2D; /* - */\nvar CHAR_COLON = 0x3A; /* : */\nvar CHAR_EQUALS = 0x3D; /* = */\nvar CHAR_GREATER_THAN = 0x3E; /* > */\nvar CHAR_QUESTION = 0x3F; /* ? */\nvar CHAR_COMMERCIAL_AT = 0x40; /* @ */\nvar CHAR_LEFT_SQUARE_BRACKET = 0x5B; /* [ */\nvar CHAR_RIGHT_SQUARE_BRACKET = 0x5D; /* ] */\nvar CHAR_GRAVE_ACCENT = 0x60; /* ` */\nvar CHAR_LEFT_CURLY_BRACKET = 0x7B; /* { */\nvar CHAR_VERTICAL_LINE = 0x7C; /* | */\nvar CHAR_RIGHT_CURLY_BRACKET = 0x7D; /* } */\n\nvar ESCAPE_SEQUENCES = {};\n\nESCAPE_SEQUENCES[0x00] = '\\\\0';\nESCAPE_SEQUENCES[0x07] = '\\\\a';\nESCAPE_SEQUENCES[0x08] = '\\\\b';\nESCAPE_SEQUENCES[0x09] = '\\\\t';\nESCAPE_SEQUENCES[0x0A] = '\\\\n';\nESCAPE_SEQUENCES[0x0B] = '\\\\v';\nESCAPE_SEQUENCES[0x0C] = '\\\\f';\nESCAPE_SEQUENCES[0x0D] = '\\\\r';\nESCAPE_SEQUENCES[0x1B] = '\\\\e';\nESCAPE_SEQUENCES[0x22] = '\\\\\"';\nESCAPE_SEQUENCES[0x5C] = '\\\\\\\\';\nESCAPE_SEQUENCES[0x85] = '\\\\N';\nESCAPE_SEQUENCES[0xA0] = '\\\\_';\nESCAPE_SEQUENCES[0x2028] = '\\\\L';\nESCAPE_SEQUENCES[0x2029] = '\\\\P';\n\nvar DEPRECATED_BOOLEANS_SYNTAX = [\n 'y', 'Y', 'yes', 'Yes', 'YES', 'on', 'On', 'ON',\n 'n', 'N', 'no', 'No', 'NO', 'off', 'Off', 'OFF'\n];\n\nvar DEPRECATED_BASE60_SYNTAX = /^[-+]?[0-9_]+(?::[0-9_]+)+(?:\\.[0-9_]*)?$/;\n\nfunction compileStyleMap(schema, map) {\n var result, keys, index, length, tag, style, type;\n\n if (map === null) return {};\n\n result = {};\n keys = Object.keys(map);\n\n for (index = 0, length = keys.length; index < length; index += 1) {\n tag = keys[index];\n style = String(map[tag]);\n\n if (tag.slice(0, 2) === '!!') {\n tag = 'tag:yaml.org,2002:' + tag.slice(2);\n }\n type = schema.compiledTypeMap['fallback'][tag];\n\n if (type && _hasOwnProperty.call(type.styleAliases, style)) {\n style = type.styleAliases[style];\n }\n\n result[tag] = style;\n }\n\n return result;\n}\n\nfunction encodeHex(character) {\n var string, handle, length;\n\n string = character.toString(16).toUpperCase();\n\n if (character <= 0xFF) {\n handle = 'x';\n length = 2;\n } else if (character <= 0xFFFF) {\n handle = 'u';\n length = 4;\n } else if (character <= 0xFFFFFFFF) {\n handle = 'U';\n length = 8;\n } else {\n throw new exception('code point within a string may not be greater than 0xFFFFFFFF');\n }\n\n return '\\\\' + handle + common.repeat('0', length - string.length) + string;\n}\n\n\nvar QUOTING_TYPE_SINGLE = 1,\n QUOTING_TYPE_DOUBLE = 2;\n\nfunction State(options) {\n this.schema = options['schema'] || _default;\n this.indent = Math.max(1, (options['indent'] || 2));\n this.noArrayIndent = options['noArrayIndent'] || false;\n this.skipInvalid = options['skipInvalid'] || false;\n this.flowLevel = (common.isNothing(options['flowLevel']) ? -1 : options['flowLevel']);\n this.styleMap = compileStyleMap(this.schema, options['styles'] || null);\n this.sortKeys = options['sortKeys'] || false;\n this.lineWidth = options['lineWidth'] || 80;\n this.noRefs = options['noRefs'] || false;\n this.noCompatMode = options['noCompatMode'] || false;\n this.condenseFlow = options['condenseFlow'] || false;\n this.quotingType = options['quotingType'] === '\"' ? QUOTING_TYPE_DOUBLE : QUOTING_TYPE_SINGLE;\n this.forceQuotes = options['forceQuotes'] || false;\n this.replacer = typeof options['replacer'] === 'function' ? options['replacer'] : null;\n\n this.implicitTypes = this.schema.compiledImplicit;\n this.explicitTypes = this.schema.compiledExplicit;\n\n this.tag = null;\n this.result = '';\n\n this.duplicates = [];\n this.usedDuplicates = null;\n}\n\n// Indents every line in a string. Empty lines (\\n only) are not indented.\nfunction indentString(string, spaces) {\n var ind = common.repeat(' ', spaces),\n position = 0,\n next = -1,\n result = '',\n line,\n length = string.length;\n\n while (position < length) {\n next = string.indexOf('\\n', position);\n if (next === -1) {\n line = string.slice(position);\n position = length;\n } else {\n line = string.slice(position, next + 1);\n position = next + 1;\n }\n\n if (line.length && line !== '\\n') result += ind;\n\n result += line;\n }\n\n return result;\n}\n\nfunction generateNextLine(state, level) {\n return '\\n' + common.repeat(' ', state.indent * level);\n}\n\nfunction testImplicitResolving(state, str) {\n var index, length, type;\n\n for (index = 0, length = state.implicitTypes.length; index < length; index += 1) {\n type = state.implicitTypes[index];\n\n if (type.resolve(str)) {\n return true;\n }\n }\n\n return false;\n}\n\n// [33] s-white ::= s-space | s-tab\nfunction isWhitespace(c) {\n return c === CHAR_SPACE || c === CHAR_TAB;\n}\n\n// Returns true if the character can be printed without escaping.\n// From YAML 1.2: \"any allowed characters known to be non-printable\n// should also be escaped. [However,] This isn\u2019t mandatory\"\n// Derived from nb-char - \\t - #x85 - #xA0 - #x2028 - #x2029.\nfunction isPrintable(c) {\n return (0x00020 <= c && c <= 0x00007E)\n || ((0x000A1 <= c && c <= 0x00D7FF) && c !== 0x2028 && c !== 0x2029)\n || ((0x0E000 <= c && c <= 0x00FFFD) && c !== CHAR_BOM)\n || (0x10000 <= c && c <= 0x10FFFF);\n}\n\n// [34] ns-char ::= nb-char - s-white\n// [27] nb-char ::= c-printable - b-char - c-byte-order-mark\n// [26] b-char ::= b-line-feed | b-carriage-return\n// Including s-white (for some reason, examples doesn't match specs in this aspect)\n// ns-char ::= c-printable - b-line-feed - b-carriage-return - c-byte-order-mark\nfunction isNsCharOrWhitespace(c) {\n return isPrintable(c)\n && c !== CHAR_BOM\n // - b-char\n && c !== CHAR_CARRIAGE_RETURN\n && c !== CHAR_LINE_FEED;\n}\n\n// [127] ns-plain-safe(c) ::= c = flow-out \u21D2 ns-plain-safe-out\n// c = flow-in \u21D2 ns-plain-safe-in\n// c = block-key \u21D2 ns-plain-safe-out\n// c = flow-key \u21D2 ns-plain-safe-in\n// [128] ns-plain-safe-out ::= ns-char\n// [129] ns-plain-safe-in ::= ns-char - c-flow-indicator\n// [130] ns-plain-char(c) ::= ( ns-plain-safe(c) - \u201C:\u201D - \u201C#\u201D )\n// | ( /* An ns-char preceding */ \u201C#\u201D )\n// | ( \u201C:\u201D /* Followed by an ns-plain-safe(c) */ )\nfunction isPlainSafe(c, prev, inblock) {\n var cIsNsCharOrWhitespace = isNsCharOrWhitespace(c);\n var cIsNsChar = cIsNsCharOrWhitespace && !isWhitespace(c);\n return (\n // ns-plain-safe\n inblock ? // c = flow-in\n cIsNsCharOrWhitespace\n : cIsNsCharOrWhitespace\n // - c-flow-indicator\n && c !== CHAR_COMMA\n && c !== CHAR_LEFT_SQUARE_BRACKET\n && c !== CHAR_RIGHT_SQUARE_BRACKET\n && c !== CHAR_LEFT_CURLY_BRACKET\n && c !== CHAR_RIGHT_CURLY_BRACKET\n )\n // ns-plain-char\n && c !== CHAR_SHARP // false on '#'\n && !(prev === CHAR_COLON && !cIsNsChar) // false on ': '\n || (isNsCharOrWhitespace(prev) && !isWhitespace(prev) && c === CHAR_SHARP) // change to true on '[^ ]#'\n || (prev === CHAR_COLON && cIsNsChar); // change to true on ':[^ ]'\n}\n\n// Simplified test for values allowed as the first character in plain style.\nfunction isPlainSafeFirst(c) {\n // Uses a subset of ns-char - c-indicator\n // where ns-char = nb-char - s-white.\n // No support of ( ( \u201C?\u201D | \u201C:\u201D | \u201C-\u201D ) /* Followed by an ns-plain-safe(c)) */ ) part\n return isPrintable(c) && c !== CHAR_BOM\n && !isWhitespace(c) // - s-white\n // - (c-indicator ::=\n // \u201C-\u201D | \u201C?\u201D | \u201C:\u201D | \u201C,\u201D | \u201C[\u201D | \u201C]\u201D | \u201C{\u201D | \u201C}\u201D\n && c !== CHAR_MINUS\n && c !== CHAR_QUESTION\n && c !== CHAR_COLON\n && c !== CHAR_COMMA\n && c !== CHAR_LEFT_SQUARE_BRACKET\n && c !== CHAR_RIGHT_SQUARE_BRACKET\n && c !== CHAR_LEFT_CURLY_BRACKET\n && c !== CHAR_RIGHT_CURLY_BRACKET\n // | \u201C#\u201D | \u201C&\u201D | \u201C*\u201D | \u201C!\u201D | \u201C|\u201D | \u201C=\u201D | \u201C>\u201D | \u201C'\u201D | \u201C\"\u201D\n && c !== CHAR_SHARP\n && c !== CHAR_AMPERSAND\n && c !== CHAR_ASTERISK\n && c !== CHAR_EXCLAMATION\n && c !== CHAR_VERTICAL_LINE\n && c !== CHAR_EQUALS\n && c !== CHAR_GREATER_THAN\n && c !== CHAR_SINGLE_QUOTE\n && c !== CHAR_DOUBLE_QUOTE\n // | \u201C%\u201D | \u201C@\u201D | \u201C`\u201D)\n && c !== CHAR_PERCENT\n && c !== CHAR_COMMERCIAL_AT\n && c !== CHAR_GRAVE_ACCENT;\n}\n\n// Simplified test for values allowed as the last character in plain style.\nfunction isPlainSafeLast(c) {\n // just not whitespace or colon, it will be checked to be plain character later\n return !isWhitespace(c) && c !== CHAR_COLON;\n}\n\n// Same as 'string'.codePointAt(pos), but works in older browsers.\nfunction codePointAt(string, pos) {\n var first = string.charCodeAt(pos), second;\n if (first >= 0xD800 && first <= 0xDBFF && pos + 1 < string.length) {\n second = string.charCodeAt(pos + 1);\n if (second >= 0xDC00 && second <= 0xDFFF) {\n // https://mathiasbynens.be/notes/javascript-encoding#surrogate-formulae\n return (first - 0xD800) * 0x400 + second - 0xDC00 + 0x10000;\n }\n }\n return first;\n}\n\n// Determines whether block indentation indicator is required.\nfunction needIndentIndicator(string) {\n var leadingSpaceRe = /^\\n* /;\n return leadingSpaceRe.test(string);\n}\n\nvar STYLE_PLAIN = 1,\n STYLE_SINGLE = 2,\n STYLE_LITERAL = 3,\n STYLE_FOLDED = 4,\n STYLE_DOUBLE = 5;\n\n// Determines which scalar styles are possible and returns the preferred style.\n// lineWidth = -1 => no limit.\n// Pre-conditions: str.length > 0.\n// Post-conditions:\n// STYLE_PLAIN or STYLE_SINGLE => no \\n are in the string.\n// STYLE_LITERAL => no lines are suitable for folding (or lineWidth is -1).\n// STYLE_FOLDED => a line > lineWidth and can be folded (and lineWidth != -1).\nfunction chooseScalarStyle(string, singleLineOnly, indentPerLevel, lineWidth,\n testAmbiguousType, quotingType, forceQuotes, inblock) {\n\n var i;\n var char = 0;\n var prevChar = null;\n var hasLineBreak = false;\n var hasFoldableLine = false; // only checked if shouldTrackWidth\n var shouldTrackWidth = lineWidth !== -1;\n var previousLineBreak = -1; // count the first line correctly\n var plain = isPlainSafeFirst(codePointAt(string, 0))\n && isPlainSafeLast(codePointAt(string, string.length - 1));\n\n if (singleLineOnly || forceQuotes) {\n // Case: no block styles.\n // Check for disallowed characters to rule out plain and single.\n for (i = 0; i < string.length; char >= 0x10000 ? i += 2 : i++) {\n char = codePointAt(string, i);\n if (!isPrintable(char)) {\n return STYLE_DOUBLE;\n }\n plain = plain && isPlainSafe(char, prevChar, inblock);\n prevChar = char;\n }\n } else {\n // Case: block styles permitted.\n for (i = 0; i < string.length; char >= 0x10000 ? i += 2 : i++) {\n char = codePointAt(string, i);\n if (char === CHAR_LINE_FEED) {\n hasLineBreak = true;\n // Check if any line can be folded.\n if (shouldTrackWidth) {\n hasFoldableLine = hasFoldableLine ||\n // Foldable line = too long, and not more-indented.\n (i - previousLineBreak - 1 > lineWidth &&\n string[previousLineBreak + 1] !== ' ');\n previousLineBreak = i;\n }\n } else if (!isPrintable(char)) {\n return STYLE_DOUBLE;\n }\n plain = plain && isPlainSafe(char, prevChar, inblock);\n prevChar = char;\n }\n // in case the end is missing a \\n\n hasFoldableLine = hasFoldableLine || (shouldTrackWidth &&\n (i - previousLineBreak - 1 > lineWidth &&\n string[previousLineBreak + 1] !== ' '));\n }\n // Although every style can represent \\n without escaping, prefer block styles\n // for multiline, since they're more readable and they don't add empty lines.\n // Also prefer folding a super-long line.\n if (!hasLineBreak && !hasFoldableLine) {\n // Strings interpretable as another type have to be quoted;\n // e.g. the string 'true' vs. the boolean true.\n if (plain && !forceQuotes && !testAmbiguousType(string)) {\n return STYLE_PLAIN;\n }\n return quotingType === QUOTING_TYPE_DOUBLE ? STYLE_DOUBLE : STYLE_SINGLE;\n }\n // Edge case: block indentation indicator can only have one digit.\n if (indentPerLevel > 9 && needIndentIndicator(string)) {\n return STYLE_DOUBLE;\n }\n // At this point we know block styles are valid.\n // Prefer literal style unless we want to fold.\n if (!forceQuotes) {\n return hasFoldableLine ? STYLE_FOLDED : STYLE_LITERAL;\n }\n return quotingType === QUOTING_TYPE_DOUBLE ? STYLE_DOUBLE : STYLE_SINGLE;\n}\n\n// Note: line breaking/folding is implemented for only the folded style.\n// NB. We drop the last trailing newline (if any) of a returned block scalar\n// since the dumper adds its own newline. This always works:\n// \u2022 No ending newline => unaffected; already using strip \"-\" chomping.\n// \u2022 Ending newline => removed then restored.\n// Importantly, this keeps the \"+\" chomp indicator from gaining an extra line.\nfunction writeScalar(state, string, level, iskey, inblock) {\n state.dump = (function () {\n if (string.length === 0) {\n return state.quotingType === QUOTING_TYPE_DOUBLE ? '\"\"' : \"''\";\n }\n if (!state.noCompatMode) {\n if (DEPRECATED_BOOLEANS_SYNTAX.indexOf(string) !== -1 || DEPRECATED_BASE60_SYNTAX.test(string)) {\n return state.quotingType === QUOTING_TYPE_DOUBLE ? ('\"' + string + '\"') : (\"'\" + string + \"'\");\n }\n }\n\n var indent = state.indent * Math.max(1, level); // no 0-indent scalars\n // As indentation gets deeper, let the width decrease monotonically\n // to the lower bound min(state.lineWidth, 40).\n // Note that this implies\n // state.lineWidth \u2264 40 + state.indent: width is fixed at the lower bound.\n // state.lineWidth > 40 + state.indent: width decreases until the lower bound.\n // This behaves better than a constant minimum width which disallows narrower options,\n // or an indent threshold which causes the width to suddenly increase.\n var lineWidth = state.lineWidth === -1\n ? -1 : Math.max(Math.min(state.lineWidth, 40), state.lineWidth - indent);\n\n // Without knowing if keys are implicit/explicit, assume implicit for safety.\n var singleLineOnly = iskey\n // No block styles in flow mode.\n || (state.flowLevel > -1 && level >= state.flowLevel);\n function testAmbiguity(string) {\n return testImplicitResolving(state, string);\n }\n\n switch (chooseScalarStyle(string, singleLineOnly, state.indent, lineWidth,\n testAmbiguity, state.quotingType, state.forceQuotes && !iskey, inblock)) {\n\n case STYLE_PLAIN:\n return string;\n case STYLE_SINGLE:\n return \"'\" + string.replace(/'/g, \"''\") + \"'\";\n case STYLE_LITERAL:\n return '|' + blockHeader(string, state.indent)\n + dropEndingNewline(indentString(string, indent));\n case STYLE_FOLDED:\n return '>' + blockHeader(string, state.indent)\n + dropEndingNewline(indentString(foldString(string, lineWidth), indent));\n case STYLE_DOUBLE:\n return '\"' + escapeString(string) + '\"';\n default:\n throw new exception('impossible error: invalid scalar style');\n }\n }());\n}\n\n// Pre-conditions: string is valid for a block scalar, 1 <= indentPerLevel <= 9.\nfunction blockHeader(string, indentPerLevel) {\n var indentIndicator = needIndentIndicator(string) ? String(indentPerLevel) : '';\n\n // note the special case: the string '\\n' counts as a \"trailing\" empty line.\n var clip = string[string.length - 1] === '\\n';\n var keep = clip && (string[string.length - 2] === '\\n' || string === '\\n');\n var chomp = keep ? '+' : (clip ? '' : '-');\n\n return indentIndicator + chomp + '\\n';\n}\n\n// (See the note for writeScalar.)\nfunction dropEndingNewline(string) {\n return string[string.length - 1] === '\\n' ? string.slice(0, -1) : string;\n}\n\n// Note: a long line without a suitable break point will exceed the width limit.\n// Pre-conditions: every char in str isPrintable, str.length > 0, width > 0.\nfunction foldString(string, width) {\n // In folded style, $k$ consecutive newlines output as $k+1$ newlines\u2014\n // unless they're before or after a more-indented line, or at the very\n // beginning or end, in which case $k$ maps to $k$.\n // Therefore, parse each chunk as newline(s) followed by a content line.\n var lineRe = /(\\n+)([^\\n]*)/g;\n\n // first line (possibly an empty line)\n var result = (function () {\n var nextLF = string.indexOf('\\n');\n nextLF = nextLF !== -1 ? nextLF : string.length;\n lineRe.lastIndex = nextLF;\n return foldLine(string.slice(0, nextLF), width);\n }());\n // If we haven't reached the first content line yet, don't add an extra \\n.\n var prevMoreIndented = string[0] === '\\n' || string[0] === ' ';\n var moreIndented;\n\n // rest of the lines\n var match;\n while ((match = lineRe.exec(string))) {\n var prefix = match[1], line = match[2];\n moreIndented = (line[0] === ' ');\n result += prefix\n + (!prevMoreIndented && !moreIndented && line !== ''\n ? '\\n' : '')\n + foldLine(line, width);\n prevMoreIndented = moreIndented;\n }\n\n return result;\n}\n\n// Greedy line breaking.\n// Picks the longest line under the limit each time,\n// otherwise settles for the shortest line over the limit.\n// NB. More-indented lines *cannot* be folded, as that would add an extra \\n.\nfunction foldLine(line, width) {\n if (line === '' || line[0] === ' ') return line;\n\n // Since a more-indented line adds a \\n, breaks can't be followed by a space.\n var breakRe = / [^ ]/g; // note: the match index will always be <= length-2.\n var match;\n // start is an inclusive index. end, curr, and next are exclusive.\n var start = 0, end, curr = 0, next = 0;\n var result = '';\n\n // Invariants: 0 <= start <= length-1.\n // 0 <= curr <= next <= max(0, length-2). curr - start <= width.\n // Inside the loop:\n // A match implies length >= 2, so curr and next are <= length-2.\n while ((match = breakRe.exec(line))) {\n next = match.index;\n // maintain invariant: curr - start <= width\n if (next - start > width) {\n end = (curr > start) ? curr : next; // derive end <= length-2\n result += '\\n' + line.slice(start, end);\n // skip the space that was output as \\n\n start = end + 1; // derive start <= length-1\n }\n curr = next;\n }\n\n // By the invariants, start <= length-1, so there is something left over.\n // It is either the whole string or a part starting from non-whitespace.\n result += '\\n';\n // Insert a break if the remainder is too long and there is a break available.\n if (line.length - start > width && curr > start) {\n result += line.slice(start, curr) + '\\n' + line.slice(curr + 1);\n } else {\n result += line.slice(start);\n }\n\n return result.slice(1); // drop extra \\n joiner\n}\n\n// Escapes a double-quoted string.\nfunction escapeString(string) {\n var result = '';\n var char = 0;\n var escapeSeq;\n\n for (var i = 0; i < string.length; char >= 0x10000 ? i += 2 : i++) {\n char = codePointAt(string, i);\n escapeSeq = ESCAPE_SEQUENCES[char];\n\n if (!escapeSeq && isPrintable(char)) {\n result += string[i];\n if (char >= 0x10000) result += string[i + 1];\n } else {\n result += escapeSeq || encodeHex(char);\n }\n }\n\n return result;\n}\n\nfunction writeFlowSequence(state, level, object) {\n var _result = '',\n _tag = state.tag,\n index,\n length,\n value;\n\n for (index = 0, length = object.length; index < length; index += 1) {\n value = object[index];\n\n if (state.replacer) {\n value = state.replacer.call(object, String(index), value);\n }\n\n // Write only valid elements, put null instead of invalid elements.\n if (writeNode(state, level, value, false, false) ||\n (typeof value === 'undefined' &&\n writeNode(state, level, null, false, false))) {\n\n if (_result !== '') _result += ',' + (!state.condenseFlow ? ' ' : '');\n _result += state.dump;\n }\n }\n\n state.tag = _tag;\n state.dump = '[' + _result + ']';\n}\n\nfunction writeBlockSequence(state, level, object, compact) {\n var _result = '',\n _tag = state.tag,\n index,\n length,\n value;\n\n for (index = 0, length = object.length; index < length; index += 1) {\n value = object[index];\n\n if (state.replacer) {\n value = state.replacer.call(object, String(index), value);\n }\n\n // Write only valid elements, put null instead of invalid elements.\n if (writeNode(state, level + 1, value, true, true, false, true) ||\n (typeof value === 'undefined' &&\n writeNode(state, level + 1, null, true, true, false, true))) {\n\n if (!compact || _result !== '') {\n _result += generateNextLine(state, level);\n }\n\n if (state.dump && CHAR_LINE_FEED === state.dump.charCodeAt(0)) {\n _result += '-';\n } else {\n _result += '- ';\n }\n\n _result += state.dump;\n }\n }\n\n state.tag = _tag;\n state.dump = _result || '[]'; // Empty sequence if no valid values.\n}\n\nfunction writeFlowMapping(state, level, object) {\n var _result = '',\n _tag = state.tag,\n objectKeyList = Object.keys(object),\n index,\n length,\n objectKey,\n objectValue,\n pairBuffer;\n\n for (index = 0, length = objectKeyList.length; index < length; index += 1) {\n\n pairBuffer = '';\n if (_result !== '') pairBuffer += ', ';\n\n if (state.condenseFlow) pairBuffer += '\"';\n\n objectKey = objectKeyList[index];\n objectValue = object[objectKey];\n\n if (state.replacer) {\n objectValue = state.replacer.call(object, objectKey, objectValue);\n }\n\n if (!writeNode(state, level, objectKey, false, false)) {\n continue; // Skip this pair because of invalid key;\n }\n\n if (state.dump.length > 1024) pairBuffer += '? ';\n\n pairBuffer += state.dump + (state.condenseFlow ? '\"' : '') + ':' + (state.condenseFlow ? '' : ' ');\n\n if (!writeNode(state, level, objectValue, false, false)) {\n continue; // Skip this pair because of invalid value.\n }\n\n pairBuffer += state.dump;\n\n // Both key and value are valid.\n _result += pairBuffer;\n }\n\n state.tag = _tag;\n state.dump = '{' + _result + '}';\n}\n\nfunction writeBlockMapping(state, level, object, compact) {\n var _result = '',\n _tag = state.tag,\n objectKeyList = Object.keys(object),\n index,\n length,\n objectKey,\n objectValue,\n explicitPair,\n pairBuffer;\n\n // Allow sorting keys so that the output file is deterministic\n if (state.sortKeys === true) {\n // Default sorting\n objectKeyList.sort();\n } else if (typeof state.sortKeys === 'function') {\n // Custom sort function\n objectKeyList.sort(state.sortKeys);\n } else if (state.sortKeys) {\n // Something is wrong\n throw new exception('sortKeys must be a boolean or a function');\n }\n\n for (index = 0, length = objectKeyList.length; index < length; index += 1) {\n pairBuffer = '';\n\n if (!compact || _result !== '') {\n pairBuffer += generateNextLine(state, level);\n }\n\n objectKey = objectKeyList[index];\n objectValue = object[objectKey];\n\n if (state.replacer) {\n objectValue = state.replacer.call(object, objectKey, objectValue);\n }\n\n if (!writeNode(state, level + 1, objectKey, true, true, true)) {\n continue; // Skip this pair because of invalid key.\n }\n\n explicitPair = (state.tag !== null && state.tag !== '?') ||\n (state.dump && state.dump.length > 1024);\n\n if (explicitPair) {\n if (state.dump && CHAR_LINE_FEED === state.dump.charCodeAt(0)) {\n pairBuffer += '?';\n } else {\n pairBuffer += '? ';\n }\n }\n\n pairBuffer += state.dump;\n\n if (explicitPair) {\n pairBuffer += generateNextLine(state, level);\n }\n\n if (!writeNode(state, level + 1, objectValue, true, explicitPair)) {\n continue; // Skip this pair because of invalid value.\n }\n\n if (state.dump && CHAR_LINE_FEED === state.dump.charCodeAt(0)) {\n pairBuffer += ':';\n } else {\n pairBuffer += ': ';\n }\n\n pairBuffer += state.dump;\n\n // Both key and value are valid.\n _result += pairBuffer;\n }\n\n state.tag = _tag;\n state.dump = _result || '{}'; // Empty mapping if no valid pairs.\n}\n\nfunction detectType(state, object, explicit) {\n var _result, typeList, index, length, type, style;\n\n typeList = explicit ? state.explicitTypes : state.implicitTypes;\n\n for (index = 0, length = typeList.length; index < length; index += 1) {\n type = typeList[index];\n\n if ((type.instanceOf || type.predicate) &&\n (!type.instanceOf || ((typeof object === 'object') && (object instanceof type.instanceOf))) &&\n (!type.predicate || type.predicate(object))) {\n\n if (explicit) {\n if (type.multi && type.representName) {\n state.tag = type.representName(object);\n } else {\n state.tag = type.tag;\n }\n } else {\n state.tag = '?';\n }\n\n if (type.represent) {\n style = state.styleMap[type.tag] || type.defaultStyle;\n\n if (_toString.call(type.represent) === '[object Function]') {\n _result = type.represent(object, style);\n } else if (_hasOwnProperty.call(type.represent, style)) {\n _result = type.represent[style](object, style);\n } else {\n throw new exception('!<' + type.tag + '> tag resolver accepts not \"' + style + '\" style');\n }\n\n state.dump = _result;\n }\n\n return true;\n }\n }\n\n return false;\n}\n\n// Serializes `object` and writes it to global `result`.\n// Returns true on success, or false on invalid object.\n//\nfunction writeNode(state, level, object, block, compact, iskey, isblockseq) {\n state.tag = null;\n state.dump = object;\n\n if (!detectType(state, object, false)) {\n detectType(state, object, true);\n }\n\n var type = _toString.call(state.dump);\n var inblock = block;\n var tagStr;\n\n if (block) {\n block = (state.flowLevel < 0 || state.flowLevel > level);\n }\n\n var objectOrArray = type === '[object Object]' || type === '[object Array]',\n duplicateIndex,\n duplicate;\n\n if (objectOrArray) {\n duplicateIndex = state.duplicates.indexOf(object);\n duplicate = duplicateIndex !== -1;\n }\n\n if ((state.tag !== null && state.tag !== '?') || duplicate || (state.indent !== 2 && level > 0)) {\n compact = false;\n }\n\n if (duplicate && state.usedDuplicates[duplicateIndex]) {\n state.dump = '*ref_' + duplicateIndex;\n } else {\n if (objectOrArray && duplicate && !state.usedDuplicates[duplicateIndex]) {\n state.usedDuplicates[duplicateIndex] = true;\n }\n if (type === '[object Object]') {\n if (block && (Object.keys(state.dump).length !== 0)) {\n writeBlockMapping(state, level, state.dump, compact);\n if (duplicate) {\n state.dump = '&ref_' + duplicateIndex + state.dump;\n }\n } else {\n writeFlowMapping(state, level, state.dump);\n if (duplicate) {\n state.dump = '&ref_' + duplicateIndex + ' ' + state.dump;\n }\n }\n } else if (type === '[object Array]') {\n if (block && (state.dump.length !== 0)) {\n if (state.noArrayIndent && !isblockseq && level > 0) {\n writeBlockSequence(state, level - 1, state.dump, compact);\n } else {\n writeBlockSequence(state, level, state.dump, compact);\n }\n if (duplicate) {\n state.dump = '&ref_' + duplicateIndex + state.dump;\n }\n } else {\n writeFlowSequence(state, level, state.dump);\n if (duplicate) {\n state.dump = '&ref_' + duplicateIndex + ' ' + state.dump;\n }\n }\n } else if (type === '[object String]') {\n if (state.tag !== '?') {\n writeScalar(state, state.dump, level, iskey, inblock);\n }\n } else if (type === '[object Undefined]') {\n return false;\n } else {\n if (state.skipInvalid) return false;\n throw new exception('unacceptable kind of an object to dump ' + type);\n }\n\n if (state.tag !== null && state.tag !== '?') {\n // Need to encode all characters except those allowed by the spec:\n //\n // [35] ns-dec-digit ::= [#x30-#x39] /* 0-9 */\n // [36] ns-hex-digit ::= ns-dec-digit\n // | [#x41-#x46] /* A-F */ | [#x61-#x66] /* a-f */\n // [37] ns-ascii-letter ::= [#x41-#x5A] /* A-Z */ | [#x61-#x7A] /* a-z */\n // [38] ns-word-char ::= ns-dec-digit | ns-ascii-letter | \u201C-\u201D\n // [39] ns-uri-char ::= \u201C%\u201D ns-hex-digit ns-hex-digit | ns-word-char | \u201C#\u201D\n // | \u201C;\u201D | \u201C/\u201D | \u201C?\u201D | \u201C:\u201D | \u201C@\u201D | \u201C&\u201D | \u201C=\u201D | \u201C+\u201D | \u201C$\u201D | \u201C,\u201D\n // | \u201C_\u201D | \u201C.\u201D | \u201C!\u201D | \u201C~\u201D | \u201C*\u201D | \u201C'\u201D | \u201C(\u201D | \u201C)\u201D | \u201C[\u201D | \u201C]\u201D\n //\n // Also need to encode '!' because it has special meaning (end of tag prefix).\n //\n tagStr = encodeURI(\n state.tag[0] === '!' ? state.tag.slice(1) : state.tag\n ).replace(/!/g, '%21');\n\n if (state.tag[0] === '!') {\n tagStr = '!' + tagStr;\n } else if (tagStr.slice(0, 18) === 'tag:yaml.org,2002:') {\n tagStr = '!!' + tagStr.slice(18);\n } else {\n tagStr = '!<' + tagStr + '>';\n }\n\n state.dump = tagStr + ' ' + state.dump;\n }\n }\n\n return true;\n}\n\nfunction getDuplicateReferences(object, state) {\n var objects = [],\n duplicatesIndexes = [],\n index,\n length;\n\n inspectNode(object, objects, duplicatesIndexes);\n\n for (index = 0, length = duplicatesIndexes.length; index < length; index += 1) {\n state.duplicates.push(objects[duplicatesIndexes[index]]);\n }\n state.usedDuplicates = new Array(length);\n}\n\nfunction inspectNode(object, objects, duplicatesIndexes) {\n var objectKeyList,\n index,\n length;\n\n if (object !== null && typeof object === 'object') {\n index = objects.indexOf(object);\n if (index !== -1) {\n if (duplicatesIndexes.indexOf(index) === -1) {\n duplicatesIndexes.push(index);\n }\n } else {\n objects.push(object);\n\n if (Array.isArray(object)) {\n for (index = 0, length = object.length; index < length; index += 1) {\n inspectNode(object[index], objects, duplicatesIndexes);\n }\n } else {\n objectKeyList = Object.keys(object);\n\n for (index = 0, length = objectKeyList.length; index < length; index += 1) {\n inspectNode(object[objectKeyList[index]], objects, duplicatesIndexes);\n }\n }\n }\n }\n}\n\nfunction dump$1(input, options) {\n options = options || {};\n\n var state = new State(options);\n\n if (!state.noRefs) getDuplicateReferences(input, state);\n\n var value = input;\n\n if (state.replacer) {\n value = state.replacer.call({ '': value }, '', value);\n }\n\n if (writeNode(state, 0, value, true, true)) return state.dump + '\\n';\n\n return '';\n}\n\nvar dump_1 = dump$1;\n\nvar dumper = {\n\tdump: dump_1\n};\n\nfunction renamed(from, to) {\n return function () {\n throw new Error('Function yaml.' + from + ' is removed in js-yaml 4. ' +\n 'Use yaml.' + to + ' instead, which is now safe by default.');\n };\n}\n\n\nvar Type = type;\nvar Schema = schema;\nvar FAILSAFE_SCHEMA = failsafe;\nvar JSON_SCHEMA = json;\nvar CORE_SCHEMA = core;\nvar DEFAULT_SCHEMA = _default;\nvar load = loader.load;\nvar loadAll = loader.loadAll;\nvar dump = dumper.dump;\nvar YAMLException = exception;\n\n// Re-export all types in case user wants to create custom schema\nvar types = {\n binary: binary,\n float: float,\n map: map,\n null: _null,\n pairs: pairs,\n set: set,\n timestamp: timestamp,\n bool: bool,\n int: int,\n merge: merge,\n omap: omap,\n seq: seq,\n str: str\n};\n\n// Removed functions from JS-YAML 3.0.x\nvar safeLoad = renamed('safeLoad', 'load');\nvar safeLoadAll = renamed('safeLoadAll', 'loadAll');\nvar safeDump = renamed('safeDump', 'dump');\n\nvar jsYaml = {\n\tType: Type,\n\tSchema: Schema,\n\tFAILSAFE_SCHEMA: FAILSAFE_SCHEMA,\n\tJSON_SCHEMA: JSON_SCHEMA,\n\tCORE_SCHEMA: CORE_SCHEMA,\n\tDEFAULT_SCHEMA: DEFAULT_SCHEMA,\n\tload: load,\n\tloadAll: loadAll,\n\tdump: dump,\n\tYAMLException: YAMLException,\n\ttypes: types,\n\tsafeLoad: safeLoad,\n\tsafeLoadAll: safeLoadAll,\n\tsafeDump: safeDump\n};\n\nexport { CORE_SCHEMA, DEFAULT_SCHEMA, FAILSAFE_SCHEMA, JSON_SCHEMA, Schema, Type, YAMLException, jsYaml as default, dump, load, loadAll, safeDump, safeLoad, safeLoadAll, types };\n", "/**\n * CodeQL metadata resolver utilities\n * Handles resolution of query metadata using the CodeQL CLI\n */\n\nimport { executeCodeQLCommand } from './cli-executor';\nimport { logger } from '../utils/logger';\n\n/**\n * Query metadata structure returned by codeql resolve metadata\n */\nexport interface QueryMetadata {\n [key: string]: string | string[];\n}\n\n/**\n * Resolve metadata for a CodeQL query file\n * @param queryPath - Absolute or relative path to the .ql query file\n * @returns Parsed metadata object or null if resolution fails\n */\nexport async function resolveQueryMetadata(queryPath: string): Promise {\n try {\n logger.info(`Resolving metadata for query: ${queryPath}`);\n\n const result = await executeCodeQLCommand(\n 'resolve metadata',\n { format: 'json' },\n [queryPath]\n );\n\n if (!result.success) {\n logger.error(`Failed to resolve metadata for ${queryPath}:`, result.stderr || result.error);\n return null;\n }\n\n // Parse the JSON output\n try {\n const metadata = JSON.parse(result.stdout);\n return metadata;\n } catch (parseError) {\n logger.error(`Failed to parse metadata JSON for ${queryPath}:`, parseError);\n return null;\n }\n } catch (error) {\n logger.error(`Error resolving metadata for ${queryPath}:`, error);\n return null;\n }\n}\n", "/**\n * CodeQL generate log-summary tool\n */\n\nimport { z } from 'zod';\nimport { CLIToolDefinition, createCodeQLSchemas, defaultCLIResultProcessor } from '../../lib/cli-tool-registry';\n\nexport const codeqlGenerateLogSummaryTool: CLIToolDefinition = {\n name: 'codeql_generate_log-summary',\n description: 'Create a summary of a structured JSON evaluator event log file',\n command: 'codeql',\n subcommand: 'generate log-summary',\n inputSchema: {\n inputLog: z.string().describe('Path to the evaluator log file to summarize'),\n outputFile: z.string().optional().describe('Path to write the summary (optional, defaults to stdout)'),\n format: z.enum(['text', 'predicates', 'overall']).optional()\n .describe('Output format: text (human-readable), predicates (JSON), or overall (stats)'),\n 'minify-output': z.boolean().optional().describe('Minify JSON output'),\n utc: z.boolean().optional().describe('Force UTC timestamps'),\n 'deduplicate-stage-summaries': z.boolean().optional().describe('Deduplicate stage summaries'),\n verbose: createCodeQLSchemas.verbose(),\n additionalArgs: createCodeQLSchemas.additionalArgs()\n },\n examples: [\n 'codeql generate log-summary --format=text -- evaluator-log.json.txt summary.txt',\n 'codeql generate log-summary --format=predicates --minify-output -- evaluator-log.json.txt',\n 'codeql generate log-summary --format=overall -- evaluator-log.json.txt overall-stats.json'\n ],\n resultProcessor: defaultCLIResultProcessor\n};", "/**\n * CodeQL generate query-help tool\n */\n\nimport { z } from 'zod';\nimport { CLIToolDefinition, createCodeQLSchemas, defaultCLIResultProcessor } from '../../lib/cli-tool-registry';\n\nexport const codeqlGenerateQueryHelpTool: CLIToolDefinition = {\n name: 'codeql_generate_query-help',\n description: 'Generate query help documentation from QLDoc comments',\n command: 'codeql',\n subcommand: 'generate query-help',\n inputSchema: {\n query: z.string().describe('Path to the query file to generate help for'),\n outputFile: z.string().optional().describe('Path to write the help documentation'),\n format: z.enum(['markdown', 'text', 'html']).optional()\n .describe('Output format for the help documentation'),\n verbose: createCodeQLSchemas.verbose(),\n additionalArgs: createCodeQLSchemas.additionalArgs()\n },\n examples: [\n 'codeql generate query-help -- MyQuery.ql',\n 'codeql generate query-help --format=markdown -- MyQuery.ql help.md',\n 'codeql generate query-help --format=html -- MyQuery.ql help.html'\n ],\n resultProcessor: defaultCLIResultProcessor\n};", "/**\n * list_codeql_databases tool\n *\n * Discovers CodeQL databases in configured base directories.\n * Scans each directory in `CODEQL_DATABASES_BASE_DIRS` for subdirectories\n * containing `codeql-database.yml`, extracts metadata (language, CLI version,\n * creation time), and returns the list.\n */\n\nimport { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport { existsSync, readdirSync, readFileSync, statSync } from 'fs';\nimport { join } from 'path';\nimport { z } from 'zod';\nimport { getDatabaseBaseDirs } from '../../lib/discovery-config';\nimport { logger } from '../../utils/logger';\n\nexport interface DatabaseInfo {\n cliVersion?: string;\n creationTime?: string;\n language?: string;\n name: string;\n path: string;\n}\n\n/**\n * Parse `codeql-database.yml` to extract metadata.\n * Uses simple line-based parsing to avoid a YAML dependency.\n */\nfunction parseDatabaseYml(ymlPath: string): Partial {\n try {\n const content = readFileSync(ymlPath, 'utf-8');\n const info: Partial = {};\n\n for (const line of content.split('\\n')) {\n const trimmed = line.trim();\n const colonIdx = trimmed.indexOf(':');\n if (colonIdx === -1) continue;\n\n const key = trimmed.substring(0, colonIdx).trim();\n const value = trimmed.substring(colonIdx + 1).trim().replace(/^[\"']|[\"']$/g, '');\n\n switch (key) {\n case 'primaryLanguage':\n info.language = value;\n break;\n case 'cliVersion':\n info.cliVersion = value;\n break;\n case 'creationTime':\n info.creationTime = value;\n break;\n }\n }\n\n return info;\n } catch {\n return {};\n }\n}\n\n/**\n * Discover CodeQL databases in the given base directories.\n *\n * @param baseDirs - Directories to scan for database subdirectories\n * @param language - Optional language filter\n * @returns List of discovered databases with metadata\n */\nexport async function discoverDatabases(\n baseDirs: string[],\n language?: string,\n): Promise {\n const databases: DatabaseInfo[] = [];\n\n for (const baseDir of baseDirs) {\n if (!existsSync(baseDir)) {\n continue;\n }\n\n let entries: string[];\n try {\n entries = readdirSync(baseDir);\n } catch {\n continue;\n }\n\n for (const entry of entries) {\n const entryPath = join(baseDir, entry);\n\n // Skip non-directories\n try {\n if (!statSync(entryPath).isDirectory()) {\n continue;\n }\n } catch {\n continue;\n }\n\n // Check for codeql-database.yml\n const ymlPath = join(entryPath, 'codeql-database.yml');\n if (!existsSync(ymlPath)) {\n continue;\n }\n\n const metadata = parseDatabaseYml(ymlPath);\n\n // Apply language filter\n if (language && metadata.language !== language) {\n continue;\n }\n\n databases.push({\n cliVersion: metadata.cliVersion,\n creationTime: metadata.creationTime,\n language: metadata.language,\n name: entry,\n path: entryPath,\n });\n }\n }\n\n return databases;\n}\n\n/**\n * Register the list_codeql_databases tool with the MCP server.\n */\nexport function registerListDatabasesTool(server: McpServer): void {\n server.tool(\n 'list_codeql_databases',\n 'List CodeQL databases discovered in configured base directories (set via CODEQL_DATABASES_BASE_DIRS env var). Returns path, language, CLI version, and creation time for each database.',\n {\n language: z\n .string()\n .optional()\n .describe('Filter databases by language (e.g., \"javascript\", \"python\")'),\n },\n async ({ language }) => {\n try {\n const baseDirs = getDatabaseBaseDirs();\n\n if (baseDirs.length === 0) {\n return {\n content: [\n {\n type: 'text' as const,\n text: 'No database base directories configured. Set the CODEQL_DATABASES_BASE_DIRS environment variable to a colon-separated list of directories to search.',\n },\n ],\n };\n }\n\n const databases = await discoverDatabases(baseDirs, language);\n\n if (databases.length === 0) {\n const filterMsg = language ? ` for language \"${language}\"` : '';\n return {\n content: [\n {\n type: 'text' as const,\n text: `No CodeQL databases found${filterMsg} in: ${baseDirs.join(', ')}`,\n },\n ],\n };\n }\n\n const lines = [\n `Found ${databases.length} CodeQL database(s):`,\n '',\n ...databases.map((db) => {\n const parts = [` ${db.name}`];\n parts.push(` Path: ${db.path}`);\n if (db.language) parts.push(` Language: ${db.language}`);\n if (db.cliVersion) parts.push(` CLI Version: ${db.cliVersion}`);\n if (db.creationTime) parts.push(` Created: ${db.creationTime}`);\n return parts.join('\\n');\n }),\n ];\n\n return {\n content: [{ type: 'text' as const, text: lines.join('\\n') }],\n };\n } catch (error) {\n logger.error('Error listing databases:', error);\n return {\n content: [\n {\n type: 'text' as const,\n text: `Error: ${error instanceof Error ? error.message : 'Unknown error'}`,\n },\n ],\n isError: true,\n };\n }\n },\n );\n}\n", "/**\n * Discovery configuration for locating CodeQL databases, query run results,\n * and MRVA (Multi-Repository Variant Analysis) run results.\n *\n * Reads colon-separated directory lists from environment variables:\n * - `CODEQL_DATABASES_BASE_DIRS` \u2014 directories to search for CodeQL databases\n * - `CODEQL_MRVA_RUN_RESULTS_DIRS` \u2014 directories containing MRVA run result subdirectories\n * - `CODEQL_QUERY_RUN_RESULTS_DIRS` \u2014 directories containing per-run query result subdirectories\n *\n * The VS Code extension sets these automatically from vscode-codeql storage paths.\n * CLI users can set them manually.\n */\n\n/**\n * Parse a colon-separated list of directories from an environment variable.\n */\nfunction parsePathList(envValue: string | undefined): string[] {\n if (!envValue) {\n return [];\n }\n return envValue\n .split(':')\n .map((p) => p.trim())\n .filter((p) => p.length > 0);\n}\n\n/**\n * Get the list of base directories to search for CodeQL databases.\n *\n * Each directory is expected to contain one or more CodeQL database directories\n * (each with a `codeql-database.yml` file).\n *\n * Set via `CODEQL_DATABASES_BASE_DIRS` (colon-separated).\n */\nexport function getDatabaseBaseDirs(): string[] {\n return parsePathList(process.env.CODEQL_DATABASES_BASE_DIRS);\n}\n\n/**\n * Get the list of directories containing MRVA run result subdirectories.\n *\n * Each directory is expected to contain numeric subdirectories (run IDs),\n * each holding `timestamp`, `repo_states.json`, and per-repository\n * subdirectories with `repo_task.json`, `results/results.sarif`, and\n * `results/results.bqrs`.\n *\n * Set via `CODEQL_MRVA_RUN_RESULTS_DIRS` (colon-separated).\n */\nexport function getMrvaRunResultsDirs(): string[] {\n return parsePathList(process.env.CODEQL_MRVA_RUN_RESULTS_DIRS);\n}\n\n/**\n * Get the list of directories containing per-run query result subdirectories.\n *\n * Each directory is expected to contain subdirectories named like\n * `.ql-/`, each holding artifacts such as\n * `evaluator-log.jsonl`, `results.bqrs`, and `results-interpreted.sarif`.\n *\n * Set via `CODEQL_QUERY_RUN_RESULTS_DIRS` (colon-separated).\n */\nexport function getQueryRunResultsDirs(): string[] {\n return parsePathList(process.env.CODEQL_QUERY_RUN_RESULTS_DIRS);\n}\n", "/**\n * list_mrva_run_results tool\n *\n * Discovers MRVA (Multi-Repository Variant Analysis) run result directories\n * in configured search paths.\n * Scans each directory in `CODEQL_MRVA_RUN_RESULTS_DIRS` for numeric\n * subdirectories representing variant analysis runs created by vscode-codeql.\n * Reports run ID, timestamp, repositories scanned, analysis status, and\n * available artifacts for each run.\n */\n\nimport { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport { existsSync, readdirSync, readFileSync, statSync } from 'fs';\nimport { join } from 'path';\nimport { z } from 'zod';\nimport { getMrvaRunResultsDirs } from '../../lib/discovery-config';\nimport { logger } from '../../utils/logger';\n\nexport interface MrvaRepoResult {\n analysisStatus?: string;\n fullName: string;\n hasBqrs: boolean;\n hasSarif: boolean;\n resultCount?: number;\n}\n\nexport interface MrvaRunResult {\n path: string;\n repositories: MrvaRepoResult[];\n runId: string;\n timestamp?: string;\n}\n\n/**\n * Pattern matching numeric MRVA run directory names.\n */\nconst NUMERIC_DIR_PATTERN = /^\\d+$/;\n\n/**\n * Directory names to skip when walking repository subdirectories.\n */\nconst SKIP_DIRS = new Set(['.DS_Store', 'exported-results']);\n\n/**\n * Discover MRVA run result directories in the given search paths.\n *\n * @param resultsDirs - Directories to scan for MRVA run subdirectories\n * @param runId - Optional run ID filter (e.g., \"20442\")\n * @returns List of discovered MRVA run results with repository inventory\n */\nexport async function discoverMrvaRunResults(\n resultsDirs: string[],\n runId?: string,\n): Promise {\n const results: MrvaRunResult[] = [];\n\n for (const dir of resultsDirs) {\n if (!existsSync(dir)) {\n continue;\n }\n\n let entries: string[];\n try {\n entries = readdirSync(dir);\n } catch {\n continue;\n }\n\n for (const entry of entries) {\n const entryPath = join(dir, entry);\n\n // Skip non-directories\n try {\n if (!statSync(entryPath).isDirectory()) {\n continue;\n }\n } catch {\n continue;\n }\n\n // Match numeric directory names\n if (!NUMERIC_DIR_PATTERN.test(entry)) {\n continue;\n }\n\n // Apply run ID filter\n if (runId && entry !== runId) {\n continue;\n }\n\n // Read timestamp if available\n let timestamp: string | undefined;\n const timestampPath = join(entryPath, 'timestamp');\n if (existsSync(timestampPath)) {\n try {\n timestamp = readFileSync(timestampPath, 'utf-8').trim();\n } catch {\n // Ignore read errors\n }\n }\n\n // Discover repository subdirectories\n const repositories = discoverRepoResults(entryPath);\n\n results.push({\n path: entryPath,\n repositories,\n runId: entry,\n timestamp,\n });\n }\n }\n\n return results;\n}\n\n/**\n * Walk a single MRVA run directory to discover per-repository results.\n *\n * The directory structure is `//` containing `repo_task.json`\n * and optionally `results/results.sarif` and `results/results.bqrs`.\n */\nfunction discoverRepoResults(runPath: string): MrvaRepoResult[] {\n const repos: MrvaRepoResult[] = [];\n\n let ownerEntries: string[];\n try {\n ownerEntries = readdirSync(runPath);\n } catch {\n return repos;\n }\n\n for (const ownerEntry of ownerEntries) {\n if (SKIP_DIRS.has(ownerEntry)) {\n continue;\n }\n\n // Skip non-directory entries (timestamp, repo_states.json, etc.)\n const ownerPath = join(runPath, ownerEntry);\n try {\n if (!statSync(ownerPath).isDirectory()) {\n continue;\n }\n } catch {\n continue;\n }\n\n let repoEntries: string[];\n try {\n repoEntries = readdirSync(ownerPath);\n } catch {\n continue;\n }\n\n for (const repoEntry of repoEntries) {\n const repoPath = join(ownerPath, repoEntry);\n try {\n if (!statSync(repoPath).isDirectory()) {\n continue;\n }\n } catch {\n continue;\n }\n\n const fullName = `${ownerEntry}/${repoEntry}`;\n\n // Parse repo_task.json if present\n let analysisStatus: string | undefined;\n let resultCount: number | undefined;\n const repoTaskPath = join(repoPath, 'repo_task.json');\n if (existsSync(repoTaskPath)) {\n try {\n const raw = readFileSync(repoTaskPath, 'utf-8');\n const task = JSON.parse(raw);\n if (typeof task.analysisStatus === 'string') {\n analysisStatus = task.analysisStatus;\n }\n if (typeof task.resultCount === 'number') {\n resultCount = task.resultCount;\n }\n } catch {\n // Ignore parse errors\n }\n }\n\n // Check for SARIF and BQRS artifacts\n const hasSarif = existsSync(join(repoPath, 'results', 'results.sarif'));\n const hasBqrs = existsSync(join(repoPath, 'results', 'results.bqrs'));\n\n repos.push({\n analysisStatus,\n fullName,\n hasBqrs,\n hasSarif,\n resultCount,\n });\n }\n }\n\n return repos;\n}\n\n/**\n * Register the list_mrva_run_results tool with the MCP server.\n */\nexport function registerListMrvaRunResultsTool(server: McpServer): void {\n server.tool(\n 'list_mrva_run_results',\n 'List discovered MRVA (Multi-Repository Variant Analysis) run results (set via CODEQL_MRVA_RUN_RESULTS_DIRS env var). Returns run ID, timestamp, repositories scanned, analysis status, and available artifacts for each run.',\n {\n runId: z\n .string()\n .optional()\n .describe('Filter results by run ID (e.g., \"20442\")'),\n },\n async ({ runId }) => {\n try {\n const resultsDirs = getMrvaRunResultsDirs();\n\n if (resultsDirs.length === 0) {\n return {\n content: [\n {\n type: 'text' as const,\n text: 'No MRVA run results directories configured. Set the CODEQL_MRVA_RUN_RESULTS_DIRS environment variable to a colon-separated list of directories to search.',\n },\n ],\n };\n }\n\n const runs = await discoverMrvaRunResults(resultsDirs, runId);\n\n if (runs.length === 0) {\n const filterMsg = runId ? ` for run ID \"${runId}\"` : '';\n return {\n content: [\n {\n type: 'text' as const,\n text: `No MRVA run results found${filterMsg} in: ${resultsDirs.join(', ')}`,\n },\n ],\n };\n }\n\n const lines = [\n `Found ${runs.length} MRVA run result(s):`,\n '',\n ...runs.map((run) => {\n const parts = [` Run ${run.runId}`];\n parts.push(` Path: ${run.path}`);\n if (run.timestamp) parts.push(` Timestamp: ${run.timestamp}`);\n parts.push(` Repositories: ${run.repositories.length}`);\n for (const repo of run.repositories) {\n const artifacts: string[] = [];\n if (repo.hasSarif) artifacts.push('sarif');\n if (repo.hasBqrs) artifacts.push('bqrs');\n const status = repo.analysisStatus ?? 'unknown';\n const count = repo.resultCount !== undefined ? `, ${repo.resultCount} result(s)` : '';\n parts.push(` ${repo.fullName} [${status}${count}] artifacts: ${artifacts.length > 0 ? artifacts.join(', ') : 'none'}`);\n }\n return parts.join('\\n');\n }),\n ];\n\n return {\n content: [{ type: 'text' as const, text: lines.join('\\n') }],\n };\n } catch (error) {\n logger.error('Error listing MRVA run results:', error);\n return {\n content: [\n {\n type: 'text' as const,\n text: `Error: ${error instanceof Error ? error.message : 'Unknown error'}`,\n },\n ],\n isError: true,\n };\n }\n },\n );\n}\n", "/**\n * list_query_run_results tool\n *\n * Discovers per-query-run result directories in configured search paths.\n * Scans each directory in `CODEQL_QUERY_RUN_RESULTS_DIRS` for subdirectories\n * matching the `.ql-` naming convention used by vscode-codeql.\n * Reports which artifacts (evaluator logs, BQRS, SARIF) are present in each run.\n */\n\nimport { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport { existsSync, readdirSync, readFileSync, statSync } from 'fs';\nimport { join } from 'path';\nimport { z } from 'zod';\nimport { getQueryRunResultsDirs } from '../../lib/discovery-config';\nimport { logger } from '../../utils/logger';\n\nexport interface QueryRunResult {\n hasBqrs: boolean;\n hasEvaluatorLog: boolean;\n hasSarif: boolean;\n path: string;\n queryName: string;\n runId: string;\n timestamp?: string;\n}\n\n/**\n * Pattern matching vscode-codeql query run directory names: `.ql-`\n */\nconst QUERY_RUN_DIR_PATTERN = /^(.+\\.ql)-(.+)$/;\n\n/**\n * Discover query run result directories in the given search paths.\n *\n * @param resultsDirs - Directories to scan for per-run subdirectories\n * @param queryName - Optional query name filter (e.g., \"UI5Xss.ql\")\n * @returns List of discovered query run results with artifact inventory\n */\nexport async function discoverQueryRunResults(\n resultsDirs: string[],\n queryName?: string,\n): Promise {\n const results: QueryRunResult[] = [];\n\n for (const dir of resultsDirs) {\n if (!existsSync(dir)) {\n continue;\n }\n\n let entries: string[];\n try {\n entries = readdirSync(dir);\n } catch {\n continue;\n }\n\n for (const entry of entries) {\n const entryPath = join(dir, entry);\n\n // Skip non-directories\n try {\n if (!statSync(entryPath).isDirectory()) {\n continue;\n }\n } catch {\n continue;\n }\n\n // Match the naming pattern\n const match = QUERY_RUN_DIR_PATTERN.exec(entry);\n if (!match) {\n continue;\n }\n\n const [, name, runId] = match;\n\n // Apply query name filter\n if (queryName && name !== queryName) {\n continue;\n }\n\n // Check which artifacts are present\n const hasEvaluatorLog = existsSync(join(entryPath, 'evaluator-log.jsonl'));\n const hasBqrs = existsSync(join(entryPath, 'results.bqrs'));\n const hasSarif = existsSync(join(entryPath, 'results-interpreted.sarif'));\n\n // Read timestamp if available\n let timestamp: string | undefined;\n const timestampPath = join(entryPath, 'timestamp');\n if (existsSync(timestampPath)) {\n try {\n timestamp = readFileSync(timestampPath, 'utf-8').trim();\n } catch {\n // Ignore read errors\n }\n }\n\n results.push({\n hasBqrs,\n hasEvaluatorLog,\n hasSarif,\n path: entryPath,\n queryName: name,\n runId,\n timestamp,\n });\n }\n }\n\n return results;\n}\n\n/**\n * Register the list_query_run_results tool with the MCP server.\n */\nexport function registerListQueryRunResultsTool(server: McpServer): void {\n server.tool(\n 'list_query_run_results',\n 'List discovered query run result directories (set via CODEQL_QUERY_RUN_RESULTS_DIRS env var). Returns path, query name, timestamp, and available artifacts for each run.',\n {\n queryName: z\n .string()\n .optional()\n .describe('Filter results by query name (e.g., \"UI5Xss.ql\")'),\n },\n async ({ queryName }) => {\n try {\n const resultsDirs = getQueryRunResultsDirs();\n\n if (resultsDirs.length === 0) {\n return {\n content: [\n {\n type: 'text' as const,\n text: 'No query run results directories configured. Set the CODEQL_QUERY_RUN_RESULTS_DIRS environment variable to a colon-separated list of directories to search.',\n },\n ],\n };\n }\n\n const runs = await discoverQueryRunResults(resultsDirs, queryName);\n\n if (runs.length === 0) {\n const filterMsg = queryName ? ` for query \"${queryName}\"` : '';\n return {\n content: [\n {\n type: 'text' as const,\n text: `No query run results found${filterMsg} in: ${resultsDirs.join(', ')}`,\n },\n ],\n };\n }\n\n const lines = [\n `Found ${runs.length} query run result(s):`,\n '',\n ...runs.map((run) => {\n const artifacts: string[] = [];\n if (run.hasEvaluatorLog) artifacts.push('evaluator-log');\n if (run.hasBqrs) artifacts.push('bqrs');\n if (run.hasSarif) artifacts.push('sarif');\n const parts = [` ${run.queryName} (${run.runId})`];\n parts.push(` Path: ${run.path}`);\n if (run.timestamp) parts.push(` Timestamp: ${run.timestamp}`);\n parts.push(` Artifacts: ${artifacts.length > 0 ? artifacts.join(', ') : 'none'}`);\n return parts.join('\\n');\n }),\n ];\n\n return {\n content: [{ type: 'text' as const, text: lines.join('\\n') }],\n };\n } catch (error) {\n logger.error('Error listing query run results:', error);\n return {\n content: [\n {\n type: 'text' as const,\n text: `Error: ${error instanceof Error ? error.message : 'Unknown error'}`,\n },\n ],\n isError: true,\n };\n }\n },\n );\n}\n", "/**\n * CodeQL pack install tool\n */\n\nimport { z } from 'zod';\nimport { CLIToolDefinition, createCodeQLSchemas } from '../../lib/cli-tool-registry';\n\nexport const codeqlPackInstallTool: CLIToolDefinition = {\n name: 'codeql_pack_install',\n description: 'Install CodeQL pack dependencies',\n command: 'codeql',\n subcommand: 'pack install',\n inputSchema: {\n packDir: z.string().optional().describe('Directory containing qlpack.yml (default: current)'),\n force: z.boolean().optional().describe('Force reinstall of dependencies'),\n 'no-strict-mode': z.boolean().optional()\n .describe('Allow non-strict dependency resolution'),\n verbose: createCodeQLSchemas.verbose(),\n additionalArgs: createCodeQLSchemas.additionalArgs()\n },\n examples: [\n 'codeql pack install',\n 'codeql pack install --force /path/to/pack',\n 'codeql pack install --no-strict-mode'\n ]\n};", "/**\n * CodeQL pack ls tool\n */\n\nimport { z } from 'zod';\nimport { CLIToolDefinition, createCodeQLSchemas, defaultCLIResultProcessor } from '../../lib/cli-tool-registry';\n\nexport const codeqlPackLsTool: CLIToolDefinition = {\n name: 'codeql_pack_ls',\n description: 'List CodeQL packs under some local directory path',\n command: 'codeql',\n subcommand: 'pack ls',\n inputSchema: {\n dir: z.string().optional().describe('The root directory of the package or workspace, defaults to the current working directory'),\n format: z.enum(['text', 'json']).optional()\n .describe('Output format: text (default) or json'),\n groups: z.string().optional()\n .describe('List of CodeQL pack groups to include or exclude'),\n verbose: createCodeQLSchemas.verbose(),\n additionalArgs: createCodeQLSchemas.additionalArgs()\n },\n examples: [\n 'codeql pack ls -- .',\n 'codeql pack ls --format=json -- /path/to/pack-directory',\n 'codeql pack ls --format=json --groups=queries,tests -- .'\n ],\n resultProcessor: defaultCLIResultProcessor\n};", "/**\n * MCP tool: profile_codeql_query_from_logs\n *\n * Parses CodeQL query evaluation logs into a performance profile WITHOUT\n * running the query. Works with logs from `codeql query run`,\n * `codeql database analyze`, or vscode-codeql query history.\n */\n\nimport { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport { existsSync, mkdirSync, writeFileSync } from 'fs';\nimport { basename, dirname, join } from 'path';\nimport { z } from 'zod';\nimport {\n parseEvaluatorLog,\n type PredicateProfile,\n type ProfileData,\n} from '../../lib/evaluator-log-parser';\nimport { logger } from '../../utils/logger';\n\n// ---------------------------------------------------------------------------\n// Formatting helpers\n// ---------------------------------------------------------------------------\n\n/**\n * Format the full profile data as pretty-printed JSON.\n */\nfunction formatAsJson(profile: ProfileData): string {\n return JSON.stringify(profile, null, 2);\n}\n\n/**\n * Format profile data as a Mermaid diagram.\n *\n * For single-query logs the diagram has one query root node with sub-nodes\n * for the top-N most expensive predicates. For multi-query logs each query\n * gets its own sub-graph.\n */\nfunction formatAsMermaid(profile: ProfileData, topN: number): string {\n const lines: string[] = [];\n\n lines.push('```mermaid');\n lines.push('graph TD');\n lines.push('');\n\n if (profile.queries.length <= 1) {\n // Single query layout\n const query = profile.queries[0] ?? {\n queryName: 'unknown',\n totalDurationMs: 0,\n predicates: [],\n predicateCount: 0,\n cacheHits: 0,\n };\n const qLabel = sanitizeMermaid(basename(query.queryName));\n lines.push(\n ` QUERY[\"${qLabel}
Total: ${query.totalDurationMs.toFixed(2)}ms
Predicates: ${query.predicateCount}\"]`\n );\n lines.push('');\n\n const topPredicates = getTopPredicates(query.predicates, topN);\n topPredicates.forEach((pred, idx) => {\n const nodeId = `P${idx}`;\n const name = sanitizeMermaid(pred.predicateName).substring(0, 50);\n const dur = pred.durationMs.toFixed(2);\n const size =\n pred.resultSize !== undefined ? String(pred.resultSize) : '?';\n lines.push(\n ` ${nodeId}[\"${name}
${dur}ms | ${size} results\"]`\n );\n });\n\n lines.push('');\n\n topPredicates.forEach((_pred, idx) => {\n lines.push(` QUERY --> P${idx}`);\n });\n } else {\n // Multi-query layout\n lines.push(\n ` ROOT[\"Evaluation Log
${profile.queries.length} queries\"]`\n );\n lines.push('');\n\n profile.queries.forEach((query, qIdx) => {\n const qNodeId = `Q${qIdx}`;\n const qLabel = sanitizeMermaid(basename(query.queryName));\n lines.push(\n ` ${qNodeId}[\"${qLabel}
${query.totalDurationMs.toFixed(2)}ms
Predicates: ${query.predicateCount}\"]`\n );\n lines.push(` ROOT --> ${qNodeId}`);\n\n const topPredicates = getTopPredicates(query.predicates, topN);\n topPredicates.forEach((pred, pIdx) => {\n const nodeId = `Q${qIdx}P${pIdx}`;\n const name = sanitizeMermaid(pred.predicateName).substring(0, 50);\n const dur = pred.durationMs.toFixed(2);\n const size =\n pred.resultSize !== undefined ? String(pred.resultSize) : '?';\n lines.push(\n ` ${nodeId}[\"${name}
${dur}ms | ${size} results\"]`\n );\n lines.push(` ${qNodeId} --> ${nodeId}`);\n });\n lines.push('');\n });\n }\n\n lines.push('');\n lines.push(\n ' classDef default fill:#e1f5ff,stroke:#333,stroke-width:2px'\n );\n lines.push(\n ' classDef query fill:#ffe1e1,stroke:#333,stroke-width:3px'\n );\n lines.push(' class QUERY query');\n lines.push('```');\n\n return lines.join('\\n');\n}\n\n/**\n * Sanitize a string for safe inclusion in a Mermaid node label.\n */\nfunction sanitizeMermaid(text: string): string {\n return text.replace(/[<>\"]/g, '');\n}\n\n/**\n * Return the top-N most expensive predicates sorted by descending duration.\n */\nfunction getTopPredicates(\n predicates: PredicateProfile[],\n topN: number\n): PredicateProfile[] {\n return [...predicates]\n .sort((a, b) => b.durationMs - a.durationMs)\n .slice(0, topN);\n}\n\n// ---------------------------------------------------------------------------\n// Text summary\n// ---------------------------------------------------------------------------\n\nfunction buildTextSummary(\n profile: ProfileData,\n topN: number,\n outputFiles: string[]\n): string {\n const sections: string[] = [];\n\n sections.push('Query log profiling completed successfully!');\n sections.push('');\n sections.push('Output Files:');\n for (const f of outputFiles) {\n sections.push(` - ${f}`);\n }\n\n sections.push('');\n sections.push(`Log Format: ${profile.logFormat}`);\n if (profile.codeqlVersion) {\n sections.push(`CodeQL Version: ${profile.codeqlVersion}`);\n }\n sections.push(`Total Events: ${profile.totalEvents}`);\n sections.push(`Queries: ${profile.queries.length}`);\n\n for (const query of profile.queries) {\n sections.push('');\n sections.push(`--- ${basename(query.queryName)} ---`);\n sections.push(` Total Duration: ${query.totalDurationMs.toFixed(2)} ms`);\n sections.push(` Predicates Evaluated: ${query.predicateCount}`);\n sections.push(` Cache Hits: ${query.cacheHits}`);\n\n const top = getTopPredicates(query.predicates, topN);\n if (top.length > 0) {\n sections.push(` Top ${top.length} Most Expensive Predicates:`);\n top.forEach((pred, idx) => {\n const sizeStr =\n pred.resultSize !== undefined ? `, ${pred.resultSize} results` : '';\n sections.push(\n ` ${idx + 1}. ${pred.predicateName} (${pred.durationMs.toFixed(2)} ms${sizeStr})`\n );\n });\n }\n }\n\n return sections.join('\\n');\n}\n\n// ---------------------------------------------------------------------------\n// Tool registration\n// ---------------------------------------------------------------------------\n\n/**\n * Register the `profile_codeql_query_from_logs` tool with the MCP server.\n */\nexport function registerProfileCodeQLQueryFromLogsTool(\n server: McpServer\n): void {\n server.tool(\n 'profile_codeql_query_from_logs',\n 'Parse CodeQL query evaluation logs into a performance profile without re-running the query. Works with logs from codeql query run, codeql database analyze, or vscode-codeql query history.',\n {\n evaluatorLog: z\n .string()\n .describe(\n 'Path to evaluator-log.jsonl or evaluator-log.summary.jsonl'\n ),\n outputDir: z\n .string()\n .optional()\n .describe(\n 'Directory to write profile output files (defaults to same directory as log)'\n ),\n topN: z\n .number()\n .optional()\n .describe(\n 'Number of most expensive predicates to highlight (default: 20)'\n ),\n },\n async (params) => {\n try {\n const { evaluatorLog, outputDir, topN } = params;\n const effectiveTopN = topN ?? 20;\n\n // Validate input path\n if (!existsSync(evaluatorLog)) {\n return {\n content: [\n {\n type: 'text' as const,\n text: `Evaluator log not found at: ${evaluatorLog}`,\n },\n ],\n isError: true,\n };\n }\n\n // Parse log\n logger.info(`Parsing evaluator log from: ${evaluatorLog}`);\n const profile = parseEvaluatorLog(evaluatorLog);\n\n // Determine output directory\n const profileOutputDir = outputDir ?? dirname(evaluatorLog);\n mkdirSync(profileOutputDir, { recursive: true });\n\n // Write profile JSON\n const jsonPath = join(\n profileOutputDir,\n 'query-evaluation-profile.json'\n );\n writeFileSync(jsonPath, formatAsJson(profile));\n logger.info(`Profile JSON written to: ${jsonPath}`);\n\n // Write Mermaid diagram\n const mdPath = join(\n profileOutputDir,\n 'query-evaluation-profile.md'\n );\n writeFileSync(mdPath, formatAsMermaid(profile, effectiveTopN));\n logger.info(`Profile Mermaid diagram written to: ${mdPath}`);\n\n // Build response\n const outputFilesList = [\n `Profile JSON: ${jsonPath}`,\n `Profile Mermaid: ${mdPath}`,\n `Evaluator Log: ${evaluatorLog}`,\n ];\n\n const responseText = buildTextSummary(\n profile,\n effectiveTopN,\n outputFilesList\n );\n\n return {\n content: [{ type: 'text' as const, text: responseText }],\n };\n } catch (error) {\n logger.error(\n 'Error profiling CodeQL query from logs:',\n error\n );\n return {\n content: [\n {\n type: 'text' as const,\n text: `Failed to profile query from logs: ${error instanceof Error ? error.message : String(error)}`,\n },\n ],\n isError: true,\n };\n }\n }\n );\n}\n", "/**\n * Reusable parser for CodeQL evaluator log files.\n *\n * Supports two formats:\n * - **Raw** (`evaluator-log.jsonl`): Pretty-printed JSON objects with a `type`\n * field (`LOG_HEADER`, `QUERY_STARTED`, `PREDICATE_STARTED`, etc.)\n * - **Summary** (`evaluator-log.summary.jsonl`): Pretty-printed JSON objects\n * without a `type` field; identified by `summaryLogVersion` or\n * `evaluationStrategy`.\n *\n * Both formats use pretty-printed JSON separated by `}\\n{` boundaries.\n */\n\nimport { readFileSync } from 'fs';\nimport { logger } from '../utils/logger';\n\n// ---------------------------------------------------------------------------\n// Public interfaces\n// ---------------------------------------------------------------------------\n\n/** Performance profile for a single evaluated predicate. */\nexport interface PredicateProfile {\n predicateName: string;\n position?: string;\n durationMs: number;\n resultSize?: number;\n pipelineCount?: number;\n evaluationStrategy?: string;\n dependencies: string[];\n}\n\n/** Performance profile for a single query within a log. */\nexport interface QueryProfile {\n queryName: string;\n totalDurationMs: number;\n predicateCount: number;\n predicates: PredicateProfile[];\n cacheHits: number;\n}\n\n/** Top-level result returned by all parse functions. */\nexport interface ProfileData {\n codeqlVersion?: string;\n logFormat: 'raw' | 'summary';\n queries: QueryProfile[];\n totalEvents: number;\n}\n\n// ---------------------------------------------------------------------------\n// Format detection\n// ---------------------------------------------------------------------------\n\n/**\n * Auto-detect whether the first parsed JSON object comes from a raw\n * evaluator log or a summary log.\n *\n * Raw events always contain a `type` string field.\n * Summary events never have `type`; the header carries `summaryLogVersion`.\n */\nexport function detectLogFormat(firstEvent: Record): 'raw' | 'summary' {\n if (typeof firstEvent.type === 'string') {\n return 'raw';\n }\n return 'summary';\n}\n\n// ---------------------------------------------------------------------------\n// Helpers\n// ---------------------------------------------------------------------------\n\n/**\n * Split a pretty-printed multi-JSON file into individual JSON strings.\n *\n * The log file contains multiple JSON objects that are pretty-printed,\n * separated by the pattern `}\\n\\n{` (closing brace, blank line, opening\n * brace). We split on `\\n}\\n` boundaries and reconstruct valid objects.\n */\nfunction splitJsonObjects(content: string): string[] {\n // Trim leading/trailing whitespace\n const trimmed = content.trim();\n if (trimmed.length === 0) {\n return [];\n }\n\n // Split on closing-brace + newline(s) + opening-brace boundaries.\n // We use a regex that matches `}\\n` followed by optional blank lines\n // then `{` \u2013 capturing the boundary so we can reconstruct.\n const parts = trimmed.split(/\\n\\}\\s*\\n\\s*\\{/);\n\n if (parts.length === 1) {\n // Single object or single-line \u2013 return as-is\n return [trimmed];\n }\n\n // Reconstruct: first part needs closing `}`, middle parts need both,\n // last part needs opening `{`.\n return parts.map((part, idx) => {\n if (idx === 0) {\n return part + '\\n}';\n }\n if (idx === parts.length - 1) {\n return '{\\n' + part;\n }\n return '{\\n' + part + '\\n}';\n });\n}\n\n/**\n * Parse all JSON objects from an evaluator log file.\n */\nfunction parseJsonObjects(logPath: string): Record[] {\n const content = readFileSync(logPath, 'utf-8');\n const objectStrings = splitJsonObjects(content);\n\n const results: Record[] = [];\n for (const objStr of objectStrings) {\n try {\n results.push(JSON.parse(objStr) as Record);\n } catch {\n logger.warn(\n `Failed to parse evaluator log object: ${objStr.substring(0, 120)}...`\n );\n }\n }\n return results;\n}\n\n// ---------------------------------------------------------------------------\n// Raw evaluator log parsing\n// ---------------------------------------------------------------------------\n\n/**\n * Parse a raw `evaluator-log.jsonl` file into {@link ProfileData}.\n *\n * Tracks `QUERY_STARTED`/`QUERY_COMPLETED` pairs, computes predicate\n * durations from `PREDICATE_STARTED`/`PREDICATE_COMPLETED` nanoTime\n * differences, and groups predicates by `queryCausingWork`.\n */\nexport function parseRawEvaluatorLog(logPath: string): ProfileData {\n const events = parseJsonObjects(logPath);\n\n let codeqlVersion: string | undefined;\n\n // Maps: eventId \u2192 event data for lookups\n const queryStartEvents = new Map<\n number,\n { queryName: string; nanoTime: number }\n >();\n const predicateStartEvents = new Map<\n number,\n {\n predicateName: string;\n position?: string;\n predicateType?: string;\n dependencies: string[];\n queryCausingWork?: number;\n nanoTime: number;\n pipelineCount: number;\n }\n >();\n\n // Completed predicate profiles grouped by query eventId\n const queryPredicates = new Map();\n // Query end nanoTimes keyed by query start eventId\n const queryEndNanoTimes = new Map();\n // Track cache lookups per query\n const queryCacheHits = new Map();\n // Fallback query eventId for predicates without queryCausingWork\n let firstQueryEventId: number | undefined;\n\n for (const event of events) {\n const eventType = event.type as string | undefined;\n\n switch (eventType) {\n case 'LOG_HEADER': {\n codeqlVersion = event.codeqlVersion as string | undefined;\n break;\n }\n\n case 'QUERY_STARTED': {\n const eid = event.eventId as number;\n const qName = (event.queryName as string) || 'unknown';\n queryStartEvents.set(eid, {\n queryName: qName,\n nanoTime: event.nanoTime as number,\n });\n queryPredicates.set(eid, []);\n queryCacheHits.set(eid, 0);\n if (firstQueryEventId === undefined) {\n firstQueryEventId = eid;\n }\n break;\n }\n\n case 'QUERY_COMPLETED': {\n const startEid = event.startEvent as number;\n queryEndNanoTimes.set(startEid, event.nanoTime as number);\n break;\n }\n\n case 'PREDICATE_STARTED': {\n const eid = event.eventId as number;\n const deps = event.dependencies as Record | undefined;\n predicateStartEvents.set(eid, {\n predicateName: (event.predicateName as string) || 'unknown',\n position: event.position as string | undefined,\n predicateType: event.predicateType as string | undefined,\n dependencies: deps ? Object.keys(deps) : [],\n queryCausingWork: event.queryCausingWork as number | undefined,\n nanoTime: event.nanoTime as number,\n pipelineCount: 0,\n });\n break;\n }\n\n case 'PIPELINE_COMPLETED': {\n // Count pipelines for the parent predicate\n const pipelineStartEid = event.startEvent as number;\n // Find the pipeline_started event to get predicateStartEvent\n const pipelineStartEvt = events.find(\n (e) =>\n (e.type as string) === 'PIPELINE_STARTED' &&\n (e.eventId as number) === pipelineStartEid\n );\n if (pipelineStartEvt) {\n const predEid = pipelineStartEvt.predicateStartEvent as number;\n const predStart = predicateStartEvents.get(predEid);\n if (predStart) {\n predStart.pipelineCount += 1;\n }\n }\n break;\n }\n\n case 'PREDICATE_COMPLETED': {\n const startEid = event.startEvent as number;\n const predStart = predicateStartEvents.get(startEid);\n if (predStart) {\n const durationNs =\n (event.nanoTime as number) - predStart.nanoTime;\n const durationMs = durationNs / 1_000_000;\n\n const profile: PredicateProfile = {\n predicateName: predStart.predicateName,\n position: predStart.position,\n durationMs,\n resultSize: event.resultSize as number | undefined,\n pipelineCount:\n predStart.pipelineCount > 0\n ? predStart.pipelineCount\n : undefined,\n evaluationStrategy: predStart.predicateType,\n dependencies: predStart.dependencies,\n };\n\n const qEid =\n predStart.queryCausingWork ?? firstQueryEventId;\n if (qEid !== undefined) {\n let arr = queryPredicates.get(qEid);\n if (!arr) {\n arr = [];\n queryPredicates.set(qEid, arr);\n }\n arr.push(profile);\n }\n }\n break;\n }\n\n case 'CACHE_LOOKUP': {\n // Attribute to the most recent query\n const qEid =\n (event.queryCausingWork as number | undefined) ??\n firstQueryEventId;\n if (qEid !== undefined) {\n queryCacheHits.set(qEid, (queryCacheHits.get(qEid) ?? 0) + 1);\n }\n break;\n }\n }\n }\n\n // Build QueryProfile entries\n const queries: QueryProfile[] = [];\n for (const [qEid, startInfo] of queryStartEvents) {\n const predicates = queryPredicates.get(qEid) ?? [];\n const endNano = queryEndNanoTimes.get(qEid);\n const totalDurationMs =\n endNano !== undefined\n ? (endNano - startInfo.nanoTime) / 1_000_000\n : predicates.reduce((sum, p) => sum + p.durationMs, 0);\n\n queries.push({\n queryName: startInfo.queryName,\n totalDurationMs,\n predicateCount: predicates.length,\n predicates,\n cacheHits: queryCacheHits.get(qEid) ?? 0,\n });\n }\n\n return {\n codeqlVersion,\n logFormat: 'raw',\n queries,\n totalEvents: events.length,\n };\n}\n\n// ---------------------------------------------------------------------------\n// Summary log parsing\n// ---------------------------------------------------------------------------\n\n/**\n * Parse an `evaluator-log.summary.jsonl` file into {@link ProfileData}.\n *\n * Summary events carry `millis` directly (already in ms). Predicates are\n * grouped by `queryCausingWork` which is a **string** (query name) in the\n * summary format.\n */\nexport function parseSummaryLog(logPath: string): ProfileData {\n const events = parseJsonObjects(logPath);\n\n let codeqlVersion: string | undefined;\n\n // queryCausingWork (string) \u2192 collected predicates\n const queryPredicatesMap = new Map();\n // Track total millis per query\n const queryTotalMs = new Map();\n // Track cache hits per query\n const queryCacheHits = new Map();\n\n for (const event of events) {\n // Header detection\n if (event.summaryLogVersion !== undefined) {\n codeqlVersion = event.codeqlVersion as string | undefined;\n continue;\n }\n\n const strategy = event.evaluationStrategy as string | undefined;\n\n // Skip sentinel-empty entries (no useful timing data)\n if (strategy === 'SENTINEL_EMPTY') {\n continue;\n }\n\n // Skip events without millis (non-predicate summaries)\n if (event.millis === undefined) {\n continue;\n }\n\n const predicateName =\n (event.predicateName as string) || 'unknown';\n const millis = event.millis as number;\n const queryName =\n (event.queryCausingWork as string) || 'unknown';\n\n const deps = event.dependencies as Record | undefined;\n const pipelineRuns = event.pipelineRuns as number | undefined;\n\n const profile: PredicateProfile = {\n predicateName,\n position: event.position as string | undefined,\n durationMs: millis,\n resultSize: event.resultSize as number | undefined,\n pipelineCount: pipelineRuns,\n evaluationStrategy: strategy,\n dependencies: deps ? Object.keys(deps) : [],\n };\n\n // Check if this is a cached entry\n if (event.isCached === true || strategy === 'CACHEHIT') {\n queryCacheHits.set(\n queryName,\n (queryCacheHits.get(queryName) ?? 0) + 1\n );\n }\n\n let arr = queryPredicatesMap.get(queryName);\n if (!arr) {\n arr = [];\n queryPredicatesMap.set(queryName, arr);\n }\n arr.push(profile);\n\n queryTotalMs.set(\n queryName,\n (queryTotalMs.get(queryName) ?? 0) + millis\n );\n }\n\n // Build QueryProfile entries\n const queries: QueryProfile[] = [];\n for (const [queryName, predicates] of queryPredicatesMap) {\n queries.push({\n queryName,\n totalDurationMs: queryTotalMs.get(queryName) ?? 0,\n predicateCount: predicates.length,\n predicates,\n cacheHits: queryCacheHits.get(queryName) ?? 0,\n });\n }\n\n return {\n codeqlVersion,\n logFormat: 'summary',\n queries,\n totalEvents: events.length,\n };\n}\n\n// ---------------------------------------------------------------------------\n// Auto-detect entry point\n// ---------------------------------------------------------------------------\n\n/**\n * Auto-detect the log format and parse accordingly.\n *\n * @param logPath - Absolute path to `evaluator-log.jsonl` or\n * `evaluator-log.summary.jsonl`.\n * @returns Parsed profile data.\n */\nexport function parseEvaluatorLog(logPath: string): ProfileData {\n const events = parseJsonObjects(logPath);\n\n if (events.length === 0) {\n return {\n logFormat: 'raw',\n queries: [],\n totalEvents: 0,\n };\n }\n\n const format = detectLogFormat(events[0]);\n\n if (format === 'raw') {\n return parseRawEvaluatorLog(logPath);\n }\n return parseSummaryLog(logPath);\n}\n", "/**\n * CodeQL query profiling tool\n */\n\nimport { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport { z } from 'zod';\nimport { executeCodeQLCommand } from '../../lib/cli-executor';\nimport { logger } from '../../utils/logger';\nimport { writeFileSync, readFileSync, existsSync } from 'fs';\nimport { join, dirname, basename } from 'path';\nimport { mkdirSync } from 'fs';\n\ninterface EvaluatorLogEvent {\n time: string;\n type: string;\n eventId: number;\n nanoTime: number;\n [key: string]: unknown;\n}\n\ninterface PipelineNode {\n eventId: number;\n name: string;\n position?: string;\n type?: string;\n startTime: number;\n endTime: number;\n duration: number;\n resultSize?: number;\n tupleCount?: number;\n dependencies: string[];\n dependencyEventIds: number[];\n}\n\ninterface ProfileData {\n queryName: string;\n totalDuration: number;\n totalEvents: number;\n pipelines: PipelineNode[];\n}\n\n/**\n * Parse evaluator log and create profile data\n */\nfunction parseEvaluatorLog(logPath: string): ProfileData {\n const logContent = readFileSync(logPath, 'utf-8');\n \n // Split by empty lines to get each JSON object (handles both JSONL and pretty-printed JSON)\n const jsonObjects = logContent.split('\\n\\n').filter((s) => s.trim());\n const events: EvaluatorLogEvent[] = jsonObjects\n .map((obj) => {\n try {\n return JSON.parse(obj);\n } catch (_error) {\n logger.warn(`Failed to parse evaluator log object: ${obj.substring(0, 100)}...`);\n return null;\n }\n })\n .filter((event): event is EvaluatorLogEvent => event !== null);\n\n // Map to track pipeline nodes by their start event ID\n const pipelineMap = new Map>();\n // Map to track dependency event IDs by predicate name\n const predicateNameToEventId = new Map();\n \n let queryName = '';\n let queryStartTime = 0;\n let queryEndTime = 0;\n\n for (const event of events) {\n switch (event.type) {\n case 'QUERY_STARTED':\n queryName = (event.queryName as string) || '';\n queryStartTime = event.nanoTime;\n break;\n\n case 'QUERY_COMPLETED':\n queryEndTime = event.nanoTime;\n break;\n\n case 'PREDICATE_STARTED': {\n const predicateName = event.predicateName as string;\n const position = event.position as string | undefined;\n const predicateType = event.predicateType as string | undefined;\n const dependencies = event.dependencies as Record | undefined;\n \n // Track this predicate's event ID by name for dependency resolution\n predicateNameToEventId.set(predicateName, event.eventId);\n \n // Get dependency event IDs\n const dependencyEventIds: number[] = [];\n const dependencyNames: string[] = [];\n if (dependencies) {\n for (const depName of Object.keys(dependencies)) {\n dependencyNames.push(depName);\n const depEventId = predicateNameToEventId.get(depName);\n if (depEventId !== undefined) {\n dependencyEventIds.push(depEventId);\n }\n }\n }\n\n pipelineMap.set(event.eventId, {\n eventId: event.eventId,\n name: predicateName,\n position,\n type: predicateType,\n startTime: event.nanoTime,\n dependencies: dependencyNames,\n dependencyEventIds,\n });\n break;\n }\n\n case 'PREDICATE_COMPLETED': {\n const startEventId = event.startEvent as number;\n const pipelineInfo = pipelineMap.get(startEventId);\n if (pipelineInfo) {\n const startEvent = events.find((e) => e.eventId === startEventId);\n if (startEvent) {\n const duration = (event.nanoTime - startEvent.nanoTime) / 1_000_000; // Convert to ms\n pipelineInfo.endTime = event.nanoTime;\n pipelineInfo.duration = duration;\n pipelineInfo.resultSize = event.resultSize as number | undefined;\n pipelineInfo.tupleCount = event.tupleCount as number | undefined;\n }\n }\n break;\n }\n }\n }\n\n // Convert to array and maintain original evaluation order (by eventId)\n const pipelines: PipelineNode[] = Array.from(pipelineMap.values())\n .filter((p): p is PipelineNode => p.duration !== undefined)\n .sort((a, b) => a.eventId - b.eventId);\n\n const totalDuration = queryEndTime > 0 ? (queryEndTime - queryStartTime) / 1_000_000 : 0;\n\n return {\n queryName,\n totalDuration,\n totalEvents: events.length,\n pipelines,\n };\n}\n\n/**\n * Format profile data as JSON\n */\nfunction formatAsJson(profile: ProfileData): string {\n return JSON.stringify(profile, null, 2);\n}\n\n/**\n * Format profile data as Mermaid diagram\n * Creates a graph showing the query evaluation pipelines in order of execution\n * with dependencies as edges, annotated with duration and result sizes\n */\nfunction formatAsMermaid(profile: ProfileData): string {\n const lines: string[] = [];\n\n lines.push('```mermaid');\n lines.push('graph TD');\n lines.push('');\n \n // Add query root node\n lines.push(` QUERY[\"${basename(profile.queryName)}
Total: ${profile.totalDuration.toFixed(2)}ms\"]`);\n lines.push('');\n \n // Create nodes for each pipeline in evaluation order (already sorted by eventId)\n profile.pipelines.forEach((pipeline) => {\n const nodeId = `P${pipeline.eventId}`;\n const duration = pipeline.duration.toFixed(2);\n const resultSize = pipeline.resultSize !== undefined ? pipeline.resultSize : '?';\n // Sanitize predicate name for Mermaid\n const name = pipeline.name.replace(/[<>]/g, '').substring(0, 40);\n lines.push(` ${nodeId}[\"${name}
${duration}ms | ${resultSize} results\"]`);\n });\n \n lines.push('');\n \n // Add edges from QUERY to root pipelines (those with no dependencies)\n const rootPipelines = profile.pipelines.filter((p) => p.dependencies.length === 0);\n \n rootPipelines.forEach((pipeline) => {\n lines.push(` QUERY --> P${pipeline.eventId}`);\n });\n \n lines.push('');\n \n // Add edges between pipelines based on dependencies (using eventIds to preserve links)\n profile.pipelines.forEach((pipeline) => {\n pipeline.dependencyEventIds.forEach((depEventId) => {\n const duration = pipeline.duration.toFixed(2);\n lines.push(` P${depEventId} -->|\"${duration}ms\"| P${pipeline.eventId}`);\n });\n });\n \n lines.push('');\n lines.push(' classDef default fill:#e1f5ff,stroke:#333,stroke-width:2px');\n lines.push(' classDef query fill:#ffe1e1,stroke:#333,stroke-width:3px');\n lines.push(' class QUERY query');\n lines.push('```');\n\n return lines.join('\\n');\n}\n\n/**\n * Register the profile_codeql_query tool\n */\nexport function registerProfileCodeQLQueryTool(server: McpServer): void {\n server.tool(\n 'profile_codeql_query',\n 'Profile the performance of a CodeQL query run against a specific database by analyzing the evaluator log JSON file',\n {\n query: z.string().describe('Path to the .ql query file'),\n database: z.string().describe('Path to the CodeQL database directory'),\n evaluatorLog: z\n .string()\n .optional()\n .describe(\n 'Path to an existing structured JSON log (e.g., evaluator-log.jsonl) file. If not provided, the tool will run the query to generate one.'\n ),\n outputDir: z\n .string()\n .optional()\n .describe('Directory to write profiling data files (defaults to same directory as evaluator log)'),\n },\n async (params) => {\n try {\n const { query, database, evaluatorLog, outputDir } = params;\n let logPath = evaluatorLog;\n let bqrsPath: string | undefined;\n let sarifPath: string | undefined;\n\n // If evaluator log not provided, run the query to generate one\n if (!logPath) {\n logger.info('No evaluator log provided, running query to generate one');\n\n // Determine output directory\n const defaultOutputDir = outputDir || join(dirname(query as string), 'profile-output');\n mkdirSync(defaultOutputDir, { recursive: true });\n\n logPath = join(defaultOutputDir, 'evaluator-log.jsonl');\n bqrsPath = join(defaultOutputDir, 'query-results.bqrs');\n sarifPath = join(defaultOutputDir, 'query-results.sarif');\n\n // Run query with evaluator logging and tuple counting\n const queryResult = await executeCodeQLCommand(\n 'query run',\n {\n database: database as string,\n output: bqrsPath,\n 'evaluator-log': logPath,\n 'tuple-counting': true,\n 'evaluator-log-level': 5,\n },\n [query as string]\n );\n\n if (!queryResult.success) {\n return {\n content: [\n {\n type: 'text' as const,\n text: `Failed to run query: ${queryResult.stderr || queryResult.error}`,\n },\n ],\n isError: true,\n };\n }\n\n // Generate SARIF interpretation\n if (existsSync(bqrsPath)) {\n try {\n const sarifResult = await executeCodeQLCommand(\n 'bqrs interpret',\n { format: 'sarif-latest', output: sarifPath },\n [bqrsPath]\n );\n\n if (sarifResult.success) {\n logger.info(`Generated SARIF interpretation at ${sarifPath}`);\n }\n } catch (error) {\n logger.warn(`Failed to generate SARIF interpretation: ${error}`);\n }\n }\n }\n\n // Verify evaluator log exists\n if (!existsSync(logPath)) {\n return {\n content: [\n {\n type: 'text' as const,\n text: `Evaluator log not found at: ${logPath}`,\n },\n ],\n isError: true,\n };\n }\n\n // Parse the evaluator log\n logger.info(`Parsing evaluator log from: ${logPath}`);\n const profile = parseEvaluatorLog(logPath);\n\n // Determine output directory for profile\n const profileOutputDir = outputDir || dirname(logPath);\n mkdirSync(profileOutputDir, { recursive: true });\n\n // Write profile JSON file\n const jsonPath = join(profileOutputDir, 'query-evaluation-profile.json');\n const jsonContent = formatAsJson(profile);\n writeFileSync(jsonPath, jsonContent);\n logger.info(`Profile JSON written to: ${jsonPath}`);\n\n // Write profile Mermaid diagram file\n const mdPath = join(profileOutputDir, 'query-evaluation-profile.md');\n const mdContent = formatAsMermaid(profile);\n writeFileSync(mdPath, mdContent);\n logger.info(`Profile Mermaid diagram written to: ${mdPath}`);\n\n // Build response message\n const outputFiles: string[] = [\n `Profile JSON: ${jsonPath}`,\n `Profile Mermaid: ${mdPath}`,\n `Evaluator Log: ${logPath}`,\n ];\n\n if (bqrsPath) {\n outputFiles.push(`Query Results (BQRS): ${bqrsPath}`);\n }\n\n if (sarifPath && existsSync(sarifPath)) {\n outputFiles.push(`Query Results (SARIF): ${sarifPath}`);\n }\n\n const responseText = [\n 'Query profiling completed successfully!',\n '',\n 'Output Files:',\n ...outputFiles.map((f) => ` - ${f}`),\n '',\n 'Profile Summary:',\n ` - Query: ${basename(profile.queryName)}`,\n ` - Total Duration: ${profile.totalDuration.toFixed(2)} ms`,\n ` - Total Pipelines: ${profile.pipelines.length}`,\n ` - Total Events: ${profile.totalEvents}`,\n '',\n 'First 5 Pipeline Nodes (in evaluation order):',\n ...profile.pipelines.slice(0, 5).map((p, idx) => {\n return ` ${idx + 1}. ${p.name} (${p.duration.toFixed(2)} ms, ${p.resultSize || '?'} results)`;\n }),\n ].join('\\n');\n\n return {\n content: [\n {\n type: 'text' as const,\n text: responseText,\n },\n ],\n };\n } catch (error) {\n logger.error('Error profiling CodeQL query:', error);\n\n return {\n content: [\n {\n type: 'text' as const,\n text: `Failed to profile query: ${error instanceof Error ? error.message : String(error)}`,\n },\n ],\n isError: true,\n };\n }\n }\n );\n}\n", "/**\n * CodeQL query compile tool\n */\n\nimport { z } from 'zod';\nimport { CLIToolDefinition } from '../../lib/cli-tool-registry';\n\nexport const codeqlQueryCompileTool: CLIToolDefinition = {\n name: 'codeql_query_compile',\n description: 'Compile and validate CodeQL queries',\n command: 'codeql',\n subcommand: 'query compile',\n inputSchema: {\n query: z.string().describe('Path to the CodeQL query file (.ql)'),\n database: z.string().optional().describe('Path to the CodeQL database'),\n library: z.string().optional().describe('Path to query library'),\n output: z.string().optional().describe('Output file path'),\n warnings: z.enum(['hide', 'show', 'error']).optional()\n .describe('How to handle compilation warnings'),\n verbose: z.boolean().optional().describe('Enable verbose output'),\n additionalArgs: z.array(z.string()).optional().describe('Additional command-line arguments')\n },\n examples: [\n 'codeql query compile --database=/path/to/db MyQuery.ql',\n 'codeql query compile --library=/path/to/lib --output=compiled.qlo MyQuery.ql'\n ]\n};", "/**\n * CodeQL query format tool\n */\n\nimport { z } from 'zod';\nimport { CLIToolDefinition, createCodeQLSchemas, defaultCLIResultProcessor, CLIExecutionResult } from '../../lib/cli-tool-registry';\n\n/**\n * Custom result processor for codeql query format tool\n * Exit code 1 with --check-only means \"file would change\" - this is success for format checking\n */\nfunction formatResultProcessor(result: CLIExecutionResult, params: Record): string {\n const isCheckOnly = params['check-only'];\n const hasFormatChanges = result.exitCode === 1;\n \n if (isCheckOnly && hasFormatChanges) {\n // Mark as success for the CLI tool registry since detecting format changes is the intended behavior\n result.success = true;\n return result.stdout || result.stderr || 'File would change by autoformatting.';\n }\n \n return defaultCLIResultProcessor(result, params);\n}\n\nexport const codeqlQueryFormatTool: CLIToolDefinition = {\n name: 'codeql_query_format',\n description: 'Automatically format CodeQL source code files',\n command: 'codeql',\n subcommand: 'query format',\n inputSchema: {\n files: z.array(z.string()).describe('One or more .ql or .qll source files to format'),\n output: z.string().optional().describe('Write formatted code to this file instead of stdout'),\n 'in-place': z.boolean().optional().describe('Overwrite each input file with formatted version'),\n 'check-only': z.boolean().optional().describe('Check formatting without writing output'),\n backup: z.string().optional().describe('Backup extension when overwriting existing files'),\n 'no-syntax-errors': z.boolean().optional().describe('Ignore syntax errors and pretend file is formatted'),\n verbose: createCodeQLSchemas.verbose(),\n additionalArgs: createCodeQLSchemas.additionalArgs()\n },\n examples: [\n 'codeql query format -i -- ExampleQuery.ql',\n 'codeql query format --in-place -- queries/*.ql',\n 'codeql query format --check-only -- queries/*.ql'\n ],\n resultProcessor: formatResultProcessor\n};", "/**\n * CodeQL query run tool\n */\n\nimport { z } from 'zod';\nimport { CLIToolDefinition, createCodeQLSchemas } from '../../lib/cli-tool-registry';\n\nexport const codeqlQueryRunTool: CLIToolDefinition = {\n name: 'codeql_query_run',\n description: 'Execute a CodeQL query against a database. Use either \"query\" parameter for direct file path OR \"queryName\" + \"queryLanguage\" for pre-defined tool queries.',\n command: 'codeql',\n subcommand: 'query run',\n inputSchema: {\n query: z.string().optional().describe('Path to the CodeQL query file (.ql) - cannot be used with queryName'),\n queryName: z.string().optional().describe('Name of pre-defined query to run (e.g., \"PrintAST\", \"CallGraphFrom\", \"CallGraphTo\") - requires queryLanguage'),\n queryLanguage: z.string().optional().describe('Programming language for tools queries (e.g., \"javascript\", \"java\", \"python\") - required when using queryName'),\n queryPack: z.string().optional().describe('Query pack path (defaults to server/ql//tools/src/ for tool queries)'),\n sourceFiles: z.string().optional().describe('Comma-separated list of source file paths for PrintAST queries (e.g., \"src/main.js,src/utils.js\" or just \"main.js\")'),\n sourceFunction: z.string().optional().describe('Comma-separated list of source function names for CallGraphFrom queries (e.g., \"main,processData\")'),\n targetFunction: z.string().optional().describe('Comma-separated list of target function names for CallGraphTo queries (e.g., \"helper,validateInput\")'),\n database: createCodeQLSchemas.database(),\n output: createCodeQLSchemas.output(),\n external: z.array(z.string()).optional()\n .describe('External predicate data: predicate=file.csv'),\n timeout: createCodeQLSchemas.timeout(),\n logDir: z.string().optional()\n .describe('Custom directory for query execution logs (overrides CODEQL_QUERY_LOG_DIR environment variable). If not provided, uses CODEQL_QUERY_LOG_DIR or defaults to .tmp/query-logs/'),\n 'evaluator-log': z.string().optional().describe('Path to save evaluator log (deprecated: use logDir instead)'),\n 'evaluator-log-minify': z.boolean().optional()\n .describe('Minimize evaluator log for smaller size'),\n 'evaluator-log-level': z.number().min(1).max(5).optional()\n .describe('Evaluator log verbosity level (1-5, default 5)'),\n 'tuple-counting': z.boolean().optional()\n .describe('Display tuple counts for each evaluation step in evaluator logs'),\n format: z.enum(['sarif-latest', 'sarifv2.1.0', 'csv', 'graphtext', 'dgml', 'dot']).optional()\n .describe('Output format for query results via codeql bqrs interpret. Defaults to sarif-latest for @kind problem/path-problem queries, graphtext for @kind graph queries. Graph formats (graphtext, dgml, dot) only work with @kind graph queries.'),\n interpretedOutput: z.string().optional()\n .describe('Output file for interpreted results (e.g., results.sarif, results.txt). If not provided, defaults based on format: .sarif for SARIF, .txt for graphtext/csv, .dgml for dgml, .dot for dot'),\n evaluationFunction: z.string().optional()\n .describe('[DEPRECATED - use format parameter instead] Built-in function for query results evaluation (e.g., \"mermaid-graph\", \"json-decode\", \"csv-decode\") or path to custom evaluation script'),\n evaluationOutput: z.string().optional()\n .describe('[DEPRECATED - use interpretedOutput parameter instead] Output file for evaluation results'),\n verbose: createCodeQLSchemas.verbose(),\n additionalArgs: createCodeQLSchemas.additionalArgs()\n },\n examples: [\n 'codeql query run --database=mydb --output=results.bqrs MyQuery.ql',\n 'codeql query run --database=mydb --query-name=PrintAST --query-language=javascript --source-files=src/index.js --output=results.bqrs --format=graphtext --interpreted-output=results.txt',\n 'codeql query run --database=mydb --external=data=input.csv --output=results.bqrs MyQuery.ql --format=sarif-latest --interpreted-output=results.sarif',\n 'codeql query run --database=mydb --evaluator-log=eval.log --tuple-counting --evaluator-log-level=5 --output=results.bqrs MyQuery.ql',\n 'codeql query run --database=mydb --query-name=PrintAST --query-language=javascript --source-files=\"main.js,utils.js\" --format=graphtext',\n 'codeql query run --database=mydb --log-dir=/custom/log/path --tuple-counting --output=results.bqrs MyQuery.ql'\n ]\n};", "/**\n * CodeQL quick evaluate tool\n * \n * Inspired by JordyZomer/codeql-mcp repository:\n * - https://github.com/JordyZomer/codeql-mcp/blob/main/server.py\n * - https://github.com/JordyZomer/codeql-mcp/blob/main/codeqlclient.py\n */\n\nimport { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport { z } from 'zod';\nimport { join, resolve } from 'path';\nimport { findClassPosition } from './find-class-position';\nimport { findPredicatePosition } from './find-predicate-position';\nimport { logger } from '../../utils/logger';\nimport { getProjectTmpDir } from '../../utils/temp-dir';\n\nexport interface QuickEvaluateParams {\n file: string;\n db: string;\n symbol: string;\n output_path?: string;\n}\n\n/**\n * Quick evaluate either a class or a predicate in a CodeQL query.\n * This allows debugging a select portion of QL code without running the whole query.\n */\nexport async function quickEvaluate({\n file,\n db: _db,\n symbol,\n output_path\n}: QuickEvaluateParams): Promise {\n try {\n // Try to find as a class first, then as a predicate\n try {\n await findClassPosition(file, symbol);\n } catch {\n try {\n await findPredicatePosition(file, symbol);\n } catch {\n throw new Error(`Symbol '${symbol}' not found as class or predicate in file: ${file}`);\n }\n }\n \n const resolvedOutput = resolve(output_path || join(getProjectTmpDir('quickeval'), 'quickeval.bqrs'));\n \n // For now, return the resolved output path\n // In a full implementation, this would use the CodeQL CLI or query server\n // to perform the actual quick evaluation with the position parameters\n return resolvedOutput;\n } catch (error) {\n throw new Error(`CodeQL evaluation failed: ${error instanceof Error ? error.message : 'Unknown error'}`);\n }\n}\n\n/**\n * Register the quick evaluate tool with the MCP server\n */\nexport function registerQuickEvaluateTool(server: McpServer): void {\n server.tool(\n 'quick_evaluate',\n 'Quick evaluate either a class or a predicate in a CodeQL query for debugging',\n {\n file: z.string().describe('Path to the .ql file containing the symbol'),\n db: z.string().describe('Path to the CodeQL database'),\n symbol: z.string().describe('Name of the class or predicate to evaluate'),\n output_path: z.string().optional().describe('Output path for results (defaults to project-local .tmp/quickeval/)'),\n },\n async ({ file, db, symbol, output_path }) => {\n try {\n const result = await quickEvaluate({ file, db, symbol, output_path });\n return {\n content: [{ type: 'text', text: result }],\n };\n } catch (error) {\n logger.error('Error in quick evaluate:', error);\n return {\n content: [\n {\n type: 'text',\n text: `Error: ${error instanceof Error ? error.message : 'Unknown error'}`,\n },\n ],\n isError: true,\n };\n }\n }\n );\n}", "/**\n * CodeQL register database tool\n * \n * Inspired by JordyZomer/codeql-mcp repository:\n * - https://github.com/JordyZomer/codeql-mcp/blob/main/server.py\n * - https://github.com/JordyZomer/codeql-mcp/blob/main/codeqlclient.py\n */\n\nimport { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport { z } from 'zod';\nimport { access, constants } from 'fs/promises';\nimport { resolve } from 'path';\nimport { logger } from '../../utils/logger';\n\nexport interface DatabaseRegistration {\n uri: string;\n content: {\n sourceArchiveZip: string;\n dbDir: string;\n };\n}\n\n/**\n * Register a CodeQL database given a local path to the database directory.\n * Validates that the database exists and has required structure.\n * Supports both full databases (with src.zip) and test databases (with src/ folder).\n */\nexport async function registerDatabase(dbPath: string): Promise {\n try {\n const resolvedPath = resolve(dbPath);\n \n // Check if database directory exists\n await access(resolvedPath, constants.F_OK);\n \n // Check for codeql-database.yml (required for all CodeQL databases)\n const dbYmlPath = resolve(resolvedPath, 'codeql-database.yml');\n await access(dbYmlPath, constants.F_OK);\n \n // Check if src.zip exists (for full databases) OR src/ directory exists (for test databases)\n const srcZipPath = resolve(resolvedPath, 'src.zip');\n const srcDirPath = resolve(resolvedPath, 'src');\n \n let hasSrcZip = false;\n let hasSrcDir = false;\n \n try {\n await access(srcZipPath, constants.F_OK);\n hasSrcZip = true;\n } catch {\n // src.zip not found, check for src/ directory\n }\n \n if (!hasSrcZip) {\n try {\n await access(srcDirPath, constants.F_OK);\n hasSrcDir = true;\n } catch {\n // src directory not found either\n }\n }\n \n if (!hasSrcZip && !hasSrcDir) {\n throw new Error(`Missing required source archive (src.zip) or source directory (src/) in: ${dbPath}`);\n }\n \n // For now, we just validate and return success message\n // In a full implementation, this would register with a query server\n const sourceType = hasSrcZip ? 'src.zip' : 'src/';\n return `Database registered: ${dbPath} (source: ${sourceType})`;\n } catch (error) {\n if (error instanceof Error) {\n const errorCode = (error as { code?: string }).code;\n if (errorCode === 'ENOENT') {\n if (error.message.includes('codeql-database.yml')) {\n throw new Error(`Missing required codeql-database.yml in: ${dbPath}`);\n }\n throw new Error(`Database path does not exist: ${dbPath}`);\n }\n if (errorCode === 'EACCES') {\n throw new Error(`Database path does not exist: ${dbPath}`);\n }\n }\n throw new Error(`Failed to register database: ${error instanceof Error ? error.message : 'Unknown error'}`);\n }\n}\n\n/**\n * Register the register database tool with the MCP server\n */\nexport function registerRegisterDatabaseTool(server: McpServer): void {\n server.tool(\n 'register_database',\n 'Register a CodeQL database given a local path to the database directory',\n {\n db_path: z.string().describe('Path to the CodeQL database directory'),\n },\n async ({ db_path }) => {\n try {\n const result = await registerDatabase(db_path);\n return {\n content: [{ type: 'text', text: result }],\n };\n } catch (error) {\n logger.error('Error registering database:', error);\n return {\n content: [\n {\n type: 'text',\n text: `Error: ${error instanceof Error ? error.message : 'Unknown error'}`,\n },\n ],\n isError: true,\n };\n }\n }\n );\n}", "/**\n * CodeQL resolve database tool\n */\n\nimport { z } from 'zod';\nimport { CLIToolDefinition, createCodeQLSchemas, defaultCLIResultProcessor } from '../../lib/cli-tool-registry';\n\nexport const codeqlResolveDatabaseTool: CLIToolDefinition = {\n name: 'codeql_resolve_database',\n description: 'Resolve database path and validate database structure',\n command: 'codeql',\n subcommand: 'resolve database',\n inputSchema: {\n database: z.string().describe('Database path to resolve'),\n format: z.enum(['text', 'json', 'betterjson']).optional()\n .describe('Output format for database information'),\n verbose: createCodeQLSchemas.verbose(),\n additionalArgs: createCodeQLSchemas.additionalArgs()\n },\n examples: [\n 'codeql resolve database -- /path/to/database',\n 'codeql resolve database --format=json -- my-database',\n 'codeql resolve database --format=betterjson -- database-dir'\n ],\n resultProcessor: defaultCLIResultProcessor\n};", "/**\n * CodeQL resolve languages tool\n */\n\nimport { z } from 'zod';\nimport { CLIToolDefinition, defaultCLIResultProcessor } from '../../lib/cli-tool-registry';\n\nexport const codeqlResolveLanguagesTool: CLIToolDefinition = {\n name: 'codeql_resolve_languages',\n description: 'List installed CodeQL extractor packs',\n command: 'codeql',\n subcommand: 'resolve languages',\n inputSchema: {\n format: z.enum(['text', 'json', 'betterjson']).optional()\n .describe('Output format for language information'),\n verbose: z.boolean().optional().describe('Enable verbose output'),\n additionalArgs: z.array(z.string()).optional().describe('Additional command-line arguments')\n },\n examples: [\n 'codeql resolve languages --format=text',\n 'codeql resolve languages --format=json',\n 'codeql resolve languages --format=betterjson'\n ],\n resultProcessor: defaultCLIResultProcessor\n};", "/**\n * CodeQL resolve library-path tool\n */\n\nimport { z } from 'zod';\nimport { CLIToolDefinition, defaultCLIResultProcessor } from '../../lib/cli-tool-registry';\n\nexport const codeqlResolveLibraryPathTool: CLIToolDefinition = {\n name: 'codeql_resolve_library-path',\n description: 'Resolve library path for CodeQL queries and libraries',\n command: 'codeql',\n subcommand: 'resolve library-path',\n inputSchema: {\n language: z.string().optional().describe('Programming language to resolve library path for'),\n format: z.enum(['text', 'json', 'betterjson']).optional()\n .describe('Output format for library path information'),\n verbose: z.boolean().optional().describe('Enable verbose output'),\n additionalArgs: z.array(z.string()).optional().describe('Additional command-line arguments')\n },\n examples: [\n 'codeql resolve library-path --language=java',\n 'codeql resolve library-path --format=json --language=python',\n 'codeql resolve library-path --format=betterjson'\n ],\n resultProcessor: defaultCLIResultProcessor\n};", "/**\n * CodeQL resolve metadata tool\n */\n\nimport { z } from 'zod';\nimport { CLIToolDefinition, defaultCLIResultProcessor } from '../../lib/cli-tool-registry';\n\nexport const codeqlResolveMetadataTool: CLIToolDefinition = {\n name: 'codeql_resolve_metadata',\n description: 'Resolve and return the key-value metadata pairs from a CodeQL query source file.',\n command: 'codeql',\n subcommand: 'resolve metadata',\n inputSchema: {\n query: z.string().describe('Query file to resolve metadata for'),\n format: z.enum(['json']).optional()\n .describe('Output format for metadata information (always JSON, optional for future compatibility)'),\n verbose: z.boolean().optional().describe('Enable verbose output'),\n additionalArgs: z.array(z.string()).optional().describe('Additional command-line arguments')\n },\n examples: [\n 'codeql resolve metadata -- relative-path/2/MyQuery.ql',\n 'codeql resolve metadata --format=json -- /absolute-plus/relative-path/2/MyQuery.ql'\n ],\n resultProcessor: defaultCLIResultProcessor\n};", "/**\n * CodeQL resolve qlref tool\n */\n\nimport { z } from 'zod';\nimport { CLIToolDefinition, createCodeQLSchemas, defaultCLIResultProcessor } from '../../lib/cli-tool-registry';\n\nexport const codeqlResolveQlrefTool: CLIToolDefinition = {\n name: 'codeql_resolve_qlref',\n description: 'Resolve qlref files to their corresponding query files',\n command: 'codeql',\n subcommand: 'resolve qlref',\n inputSchema: {\n qlref: z.string().describe('Path to the .qlref file to resolve'),\n format: z.enum(['text', 'json', 'betterjson']).optional()\n .describe('Output format for qlref resolution'),\n verbose: createCodeQLSchemas.verbose(),\n additionalArgs: createCodeQLSchemas.additionalArgs()\n },\n examples: [\n 'codeql resolve qlref -- test/MyQuery.qlref',\n 'codeql resolve qlref --format=json -- test/MyQuery.qlref',\n 'codeql resolve qlref --format=betterjson -- test/MyQuery.qlref'\n ],\n resultProcessor: defaultCLIResultProcessor\n};", "/**\n * CodeQL resolve queries tool\n */\n\nimport { z } from 'zod';\nimport { CLIToolDefinition, createCodeQLSchemas, CLIExecutionResult } from '../../lib/cli-tool-registry';\n\n/**\n * Result processor that only returns stdout for JSON formats\n * This prevents warnings/info from stderr from corrupting JSON output\n */\nconst jsonOnlyResultProcessor = (\n result: CLIExecutionResult,\n params: Record\n): string => {\n if (!result.success) {\n return `Command failed (exit code ${result.exitCode || 'unknown'}):\\n${result.error || result.stderr}`;\n }\n\n // For JSON formats (including bylanguage), only return stdout to avoid mixing warnings with JSON\n if (params.format === 'json' || params.format === 'betterjson' || params.format === 'bylanguage') {\n return result.stdout || '[]';\n }\n\n // For text format, include warnings\n let output = '';\n\n if (result.stdout) {\n output += result.stdout;\n }\n\n if (result.stderr) {\n if (output) {\n output += '\\n\\nWarnings/Info:\\n';\n }\n output += result.stderr;\n }\n\n if (!output) {\n output = 'Command executed successfully (no output)';\n }\n\n return output;\n};\n\nexport const codeqlResolveQueriesTool: CLIToolDefinition = {\n name: 'codeql_resolve_queries',\n description: 'List available CodeQL queries found on the local filesystem',\n command: 'codeql',\n subcommand: 'resolve queries',\n inputSchema: {\n directory: z.string().optional().describe('Directory to search for queries'),\n language: z.string().optional().describe('Filter queries by programming language'),\n format: z.enum(['text', 'json', 'betterjson', 'bylanguage']).optional()\n .describe('Output format for query list'),\n 'additional-packs': z.union([z.string(), z.array(z.string())]).optional()\n .describe('Additional pack directories to search for CodeQL packs'),\n verbose: createCodeQLSchemas.verbose(),\n additionalArgs: createCodeQLSchemas.additionalArgs()\n },\n examples: [\n 'codeql resolve queries',\n 'codeql resolve queries --language=java --format=json',\n 'codeql resolve queries --format=betterjson -- /path/to/queries',\n 'codeql resolve queries --additional-packs=/path/to/packs codeql/java-queries'\n ],\n resultProcessor: jsonOnlyResultProcessor\n};", "/**\n * CodeQL resolve tests tool\n */\n\nimport { z } from 'zod';\nimport { CLIToolDefinition, createCodeQLSchemas, defaultCLIResultProcessor } from '../../lib/cli-tool-registry';\n\nexport const codeqlResolveTestsTool: CLIToolDefinition = {\n name: 'codeql_resolve_tests',\n description: 'Resolve the local filesystem paths of unit tests and/or queries under some base directory',\n command: 'codeql',\n subcommand: 'resolve tests',\n inputSchema: {\n tests: z.array(z.string()).optional().describe('One or more tests (.ql, .qlref files, or test directories)'),\n format: z.enum(['text', 'json']).optional()\n .describe('Output format for test list'),\n verbose: createCodeQLSchemas.verbose(),\n additionalArgs: createCodeQLSchemas.additionalArgs()\n },\n examples: [\n 'codeql resolve tests',\n 'codeql resolve tests --format=json -- test-directory',\n 'codeql resolve tests --format=json -- test1.ql test2.ql'\n ],\n resultProcessor: defaultCLIResultProcessor\n};", "/**\n * CodeQL test accept tool\n */\n\nimport { z } from 'zod';\nimport { CLIToolDefinition, createCodeQLSchemas, defaultCLIResultProcessor } from '../../lib/cli-tool-registry';\n\nexport const codeqlTestAcceptTool: CLIToolDefinition = {\n name: 'codeql_test_accept',\n description: 'Accept new test results as the expected baseline',\n command: 'codeql',\n subcommand: 'test accept',\n inputSchema: {\n tests: z.array(z.string()).describe('One or more tests (.ql, .qlref files, or test directories)'),\n verbose: createCodeQLSchemas.verbose(),\n additionalArgs: createCodeQLSchemas.additionalArgs()\n },\n examples: [\n 'codeql test accept -- languages/java/test/MyQuery/MyQuery.qlref',\n 'codeql test accept -- languages/java/test/MyQuery/',\n 'codeql test accept -- languages/java/src/MyQuery/MyQuery.ql'\n ],\n resultProcessor: defaultCLIResultProcessor\n};", "/**\n * CodeQL test extract tool\n */\n\nimport { z } from 'zod';\nimport { CLIToolDefinition, createCodeQLSchemas, defaultCLIResultProcessor } from '../../lib/cli-tool-registry';\n\nexport const codeqlTestExtractTool: CLIToolDefinition = {\n name: 'codeql_test_extract',\n description: 'Extract test databases for CodeQL query tests',\n command: 'codeql',\n subcommand: 'test extract',\n inputSchema: {\n tests: z.array(z.string()).describe('One or more test directories or files'),\n language: z.string().optional().describe('Programming language for extraction'),\n threads: createCodeQLSchemas.threads(),\n ram: createCodeQLSchemas.ram(),\n verbose: createCodeQLSchemas.verbose(),\n additionalArgs: createCodeQLSchemas.additionalArgs()\n },\n examples: [\n 'codeql test extract -- languages/java/test/MyQuery/',\n 'codeql test extract --language=java --threads=4 -- test-directory',\n 'codeql test extract --threads=2 --ram=2048 -- multiple/test/directories'\n ],\n resultProcessor: defaultCLIResultProcessor\n};", "/**\n * CodeQL test run tool\n */\n\nimport { CLIToolDefinition, createCodeQLSchemas } from '../../lib/cli-tool-registry';\nimport { z } from 'zod';\n\nexport const codeqlTestRunTool: CLIToolDefinition = {\n name: 'codeql_test_run',\n description: 'Run CodeQL query tests',\n command: 'codeql',\n subcommand: 'test run',\n inputSchema: {\n tests: z.array(z.string()).describe('One or more tests (.ql, .qlref files, or test directories)'),\n 'show-extractor-output': z.boolean().optional()\n .describe('Show output from extractors during test execution'),\n 'keep-databases': z.boolean().optional()\n .describe('Keep test databases after running tests'),\n 'learn': z.boolean().optional()\n .describe('Accept current output as expected for failing tests'),\n logDir: z.string().optional()\n .describe('Custom directory for test execution logs (overrides CODEQL_QUERY_LOG_DIR environment variable). If not provided, uses CODEQL_QUERY_LOG_DIR or defaults to .tmp/query-logs/'),\n threads: createCodeQLSchemas.threads(),\n ram: createCodeQLSchemas.ram(),\n verbose: createCodeQLSchemas.verbose(),\n additionalArgs: createCodeQLSchemas.additionalArgs()\n },\n examples: [\n 'codeql test run /path/to/tests',\n 'codeql test run --learn /path/to/failing/tests',\n 'codeql test run --threads=4 --keep-databases /path/to/tests',\n 'codeql test run --log-dir=/custom/log/path /path/to/tests'\n ]\n};", "/**\n * CodeQL tools registration for MCP server\n * Includes both high-level helpers and CLI command wrappers\n */\n\nimport { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport { z } from 'zod';\nimport { validateCodeQLSyntax } from '../lib/validation';\nimport { createCodeQLQuery } from '../lib/query-scaffolding';\nimport { registerCLITool } from '../lib/cli-tool-registry';\nimport {\n codeqlBqrsDecodeTool,\n codeqlBqrsInfoTool,\n codeqlBqrsInterpretTool,\n codeqlDatabaseAnalyzeTool,\n codeqlDatabaseCreateTool,\n codeqlGenerateLogSummaryTool,\n codeqlGenerateQueryHelpTool,\n codeqlPackInstallTool,\n codeqlPackLsTool,\n codeqlQueryCompileTool,\n codeqlQueryFormatTool,\n codeqlQueryRunTool,\n codeqlResolveDatabaseTool,\n codeqlResolveLanguagesTool,\n codeqlResolveLibraryPathTool,\n codeqlResolveMetadataTool,\n codeqlResolveQlrefTool,\n codeqlResolveQueriesTool,\n codeqlResolveTestsTool,\n codeqlTestAcceptTool,\n codeqlTestExtractTool,\n codeqlTestRunTool,\n registerFindClassPositionTool,\n registerFindCodeQLQueryFilesTool,\n registerFindPredicatePositionTool,\n registerListDatabasesTool,\n registerListMrvaRunResultsTool,\n registerListQueryRunResultsTool,\n registerProfileCodeQLQueryFromLogsTool,\n registerProfileCodeQLQueryTool,\n registerQuickEvaluateTool,\n registerRegisterDatabaseTool\n} from './codeql';\nimport { logger } from '../utils/logger';\n\n/**\n * Register all CodeQL tools with the MCP server\n */\nexport function registerCodeQLTools(server: McpServer): void {\n // Register high-level helper tools\n \n // Tool: Validate CodeQL Query (heuristic-based)\n server.tool(\n 'validate_codeql_query',\n 'Quick heuristic validation for CodeQL query structure - checks for common patterns like from/where/select clauses and metadata presence. Does NOT compile the query. For authoritative validation with actual compilation, use codeql_lsp_diagnostics instead.',\n {\n query: z.string().describe('The CodeQL query to validate'),\n language: z.string().optional().describe('Target programming language'),\n },\n async ({ query, language }) => {\n try {\n const validation = validateCodeQLSyntax(query, language);\n return {\n content: [{ type: 'text', text: JSON.stringify(validation, null, 2) }],\n };\n } catch (error) {\n logger.error('Error validating CodeQL query:', error);\n return {\n content: [\n {\n type: 'text',\n text: `Error: ${error instanceof Error ? error.message : 'Unknown error'}`,\n },\n ],\n isError: true,\n };\n }\n }\n );\n\n // Tool: Create CodeQL Query\n server.tool(\n 'create_codeql_query',\n 'Create directory structure and files for a new CodeQL query with tests',\n {\n basePath: z.string().describe('Base path where src/ and test/ directories will be created'),\n queryName: z.string().describe('Name of the query (e.g., MySecurityQuery)'),\n language: z.string().describe('Target programming language (e.g., javascript, python, java)'),\n description: z.string().optional().describe('Description of what the query does'),\n queryId: z.string().optional().describe('Custom query ID (defaults to language/example/queryname)'),\n },\n async ({ basePath, queryName, language, description, queryId }) => {\n try {\n const result = createCodeQLQuery({\n basePath,\n queryName,\n language,\n description,\n queryId\n });\n \n const summary = {\n success: true,\n queryPath: result.queryPath,\n testPath: result.testPath,\n qlrefPath: result.qlrefPath,\n testCodePath: result.testCodePath,\n filesCreated: result.filesCreated,\n nextSteps: [\n 'Review and customize the generated query in: ' + result.queryPath,\n 'Add test cases to: ' + result.testCodePath,\n 'Run codeql_pack_install to install dependencies',\n 'Run codeql_test_extract to create test database',\n 'Run codeql_test_run to execute tests'\n ]\n };\n \n return {\n content: [{ type: 'text', text: JSON.stringify(summary, null, 2) }],\n };\n } catch (error) {\n logger.error('Error creating CodeQL query:', error);\n return {\n content: [\n {\n type: 'text',\n text: `Error: ${error instanceof Error ? error.message : 'Unknown error'}`,\n },\n ],\n isError: true,\n };\n }\n }\n );\n\n // Register CLI tools (alphabetically by tool name)\n registerCLITool(server, codeqlBqrsDecodeTool);\n registerCLITool(server, codeqlBqrsInfoTool);\n registerCLITool(server, codeqlBqrsInterpretTool);\n registerCLITool(server, codeqlDatabaseAnalyzeTool);\n registerCLITool(server, codeqlDatabaseCreateTool);\n registerCLITool(server, codeqlGenerateLogSummaryTool);\n registerCLITool(server, codeqlGenerateQueryHelpTool);\n registerCLITool(server, codeqlPackInstallTool);\n registerCLITool(server, codeqlPackLsTool);\n registerCLITool(server, codeqlQueryCompileTool);\n registerCLITool(server, codeqlQueryFormatTool);\n registerCLITool(server, codeqlQueryRunTool);\n registerCLITool(server, codeqlResolveDatabaseTool);\n registerCLITool(server, codeqlResolveLanguagesTool);\n registerCLITool(server, codeqlResolveLibraryPathTool);\n registerCLITool(server, codeqlResolveMetadataTool);\n registerCLITool(server, codeqlResolveQlrefTool);\n registerCLITool(server, codeqlResolveQueriesTool);\n registerCLITool(server, codeqlResolveTestsTool);\n registerCLITool(server, codeqlTestAcceptTool);\n registerCLITool(server, codeqlTestExtractTool);\n registerCLITool(server, codeqlTestRunTool);\n\n // Register new MCP tools (inspired by JordyZomer/codeql-mcp repository)\n registerFindClassPositionTool(server);\n registerFindCodeQLQueryFilesTool(server);\n registerFindPredicatePositionTool(server);\n registerListDatabasesTool(server);\n registerListMrvaRunResultsTool(server);\n registerListQueryRunResultsTool(server);\n registerProfileCodeQLQueryFromLogsTool(server);\n registerProfileCodeQLQueryTool(server);\n registerQuickEvaluateTool(server);\n registerRegisterDatabaseTool(server);\n}\n", "/**\n * CodeQL query validation utilities\n */\n\nimport { resolve, normalize, isAbsolute, relative } from 'path';\n\nexport interface CodeQLValidationResult {\n isValid: boolean;\n errors: string[];\n warnings: string[];\n suggestions: string[];\n}\n\n/**\n * Validates CodeQL query syntax and structure\n */\nexport function validateCodeQLSyntax(query: string, _language?: string): CodeQLValidationResult {\n const validation: CodeQLValidationResult = {\n isValid: true,\n errors: [],\n warnings: [],\n suggestions: [],\n };\n\n if (!query.trim()) {\n validation.isValid = false;\n validation.errors.push('Query cannot be empty');\n return validation;\n }\n\n if (!query.includes('from') && !query.includes('select')) {\n validation.warnings.push('Query should typically include \"from\" and \"select\" clauses');\n }\n\n if (!query.includes('@name') && !query.includes('@description')) {\n validation.suggestions.push('Consider adding @name and @description metadata');\n }\n\n return validation;\n}\n\n/**\n * Validates a file path to prevent path traversal attacks\n * @param filePath - The file path to validate\n * @param workspaceRoot - Optional workspace root directory. If not provided, allows any absolute path but still blocks traversal attempts\n * @returns The validated absolute path\n * @throws Error if the path contains path traversal sequences\n */\nexport function validateFilePath(filePath: string, workspaceRoot?: string): string {\n // Normalize the path to resolve any . or .. segments\n const normalizedPath = normalize(filePath);\n \n // Check for path traversal attempts in the normalized path\n // This blocks paths like \"../../../etc/passwd\" even after normalization\n if (normalizedPath.includes('..')) {\n throw new Error(`Invalid file path: path traversal detected in \"${filePath}\"`);\n }\n \n // Resolve to absolute path\n const absolutePath = isAbsolute(normalizedPath) \n ? normalizedPath \n : resolve(workspaceRoot || process.cwd(), normalizedPath);\n \n // If workspace root is specified, ensure the resolved path is within it\n if (workspaceRoot) {\n const relativePath = relative(workspaceRoot, absolutePath);\n \n // If relative path starts with .. or is absolute, it's outside workspace\n if (relativePath.startsWith('..') || isAbsolute(relativePath)) {\n throw new Error(`Invalid file path: \"${filePath}\" is outside the workspace root`);\n }\n }\n \n return absolutePath;\n}", "/**\n * CodeQL query scaffolding utilities\n * Handles creation of query directory structure and files\n */\n\nimport * as fs from 'fs';\nimport * as path from 'path';\n\nexport interface QueryScaffoldingOptions {\n basePath: string;\n queryName: string;\n language: string;\n description?: string;\n queryId?: string;\n}\n\nexport interface QueryScaffoldingResult {\n queryPath: string;\n testPath: string;\n qlrefPath: string;\n testCodePath: string;\n filesCreated: string[];\n}\n\n/**\n * Get the file extension for test code based on language\n */\nfunction getLanguageExtension(language: string): string {\n const extensions: Record = {\n javascript: 'js',\n typescript: 'ts',\n python: 'py',\n java: 'java',\n csharp: 'cs',\n cpp: 'cpp',\n go: 'go',\n ruby: 'rb',\n actions: 'yml'\n };\n return extensions[language.toLowerCase()] || 'txt';\n}\n\n/**\n * Generate query template content\n */\nfunction generateQueryTemplate(\n queryName: string,\n language: string,\n description?: string,\n queryId?: string\n): string {\n const desc = description || `${queryName} query`;\n const id = queryId || `${language}/example/${queryName.toLowerCase()}`;\n \n return `/**\n * @id ${id}\n * @name ${queryName}\n * @description ${desc}\n * @kind problem\n * @precision medium\n * @problem.severity warning\n */\n\nimport ${language}\n\n// TODO: Implement query logic\nfrom File f\nwhere f.getBaseName() = \"${queryName}.${getLanguageExtension(language)}\"\nselect f, \"TODO: Add query logic\"\n`;\n}\n\n/**\n * Create the directory structure and files for a new CodeQL query\n */\nexport function createCodeQLQuery(options: QueryScaffoldingOptions): QueryScaffoldingResult {\n const { basePath, queryName, language, description, queryId } = options;\n \n // Resolve absolute paths\n const absoluteBasePath = path.resolve(basePath);\n \n // Define paths with intermediate directory\n const srcDir = path.join(absoluteBasePath, 'src', queryName);\n const testDir = path.join(absoluteBasePath, 'test', queryName);\n \n const queryPath = path.join(srcDir, `${queryName}.ql`);\n const qlrefPath = path.join(testDir, `${queryName}.qlref`);\n const testCodePath = path.join(testDir, `${queryName}.${getLanguageExtension(language)}`);\n \n const filesCreated: string[] = [];\n \n try {\n // Create directories (recursive: true is a no-op if they already exist)\n fs.mkdirSync(srcDir, { recursive: true });\n fs.mkdirSync(testDir, { recursive: true });\n \n // Create files atomically using 'wx' flag (exclusive create) to avoid\n // TOCTOU race between existsSync check and writeFileSync (CWE-367).\n // The 'wx' flag fails with EEXIST if the file already exists.\n try {\n const queryContent = generateQueryTemplate(queryName, language, description, queryId);\n fs.writeFileSync(queryPath, queryContent, { encoding: 'utf8', flag: 'wx' });\n filesCreated.push(queryPath);\n } catch (e: unknown) {\n const err = e as { code?: string };\n if (err.code !== 'EEXIST') throw e;\n }\n \n try {\n const qlrefContent = `${queryName}/${queryName}.ql\\n`;\n fs.writeFileSync(qlrefPath, qlrefContent, { encoding: 'utf8', flag: 'wx' });\n filesCreated.push(qlrefPath);\n } catch (e: unknown) {\n const err = e as { code?: string };\n if (err.code !== 'EEXIST') throw e;\n }\n \n try {\n const testCodeContent = `// Test code for ${queryName}\\n// TODO: Add test cases\\n`;\n fs.writeFileSync(testCodePath, testCodeContent, { encoding: 'utf8', flag: 'wx' });\n filesCreated.push(testCodePath);\n } catch (e: unknown) {\n const err = e as { code?: string };\n if (err.code !== 'EEXIST') throw e;\n }\n \n return {\n queryPath,\n testPath: testDir,\n qlrefPath,\n testCodePath,\n filesCreated\n };\n } catch (error) {\n throw new Error(`Failed to create query scaffolding: ${error instanceof Error ? error.message : 'Unknown error'}`);\n }\n}\n", "/**\n * CodeQL learning resources utilities\n */\n\nimport { readFileSync } from 'fs';\nimport { join, dirname } from 'path';\nimport { fileURLToPath } from 'url';\n\nconst __filename = fileURLToPath(import.meta.url);\nconst __dirname = dirname(__filename);\n\n/**\n * Get the getting started guide content\n */\nexport function getGettingStartedGuide(): string {\n try {\n return readFileSync(join(__dirname, '../resources/getting-started.md'), 'utf-8');\n } catch {\n return 'Getting started guide not available';\n }\n}\n\n/**\n * Get the query basics guide content\n */\nexport function getQueryBasicsGuide(): string {\n try {\n return readFileSync(join(__dirname, '../resources/query-basics.md'), 'utf-8');\n } catch {\n return 'Query basics guide not available';\n }\n}\n\n/**\n * Get the security templates content\n */\nexport function getSecurityTemplates(): string {\n try {\n return readFileSync(join(__dirname, '../resources/security-templates.md'), 'utf-8');\n } catch {\n return 'Security templates not available';\n }\n}\n\n/**\n * Get the performance patterns content\n */\nexport function getPerformancePatterns(): string {\n try {\n return readFileSync(join(__dirname, '../resources/performance-patterns.md'), 'utf-8');\n } catch {\n return 'Performance patterns not available';\n }\n}", "/**\n * CodeQL resources registration for MCP server\n */\n\nimport { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport {\n getGettingStartedGuide,\n getQueryBasicsGuide,\n getSecurityTemplates,\n getPerformancePatterns,\n} from '../lib/resources';\n\n/**\n * Register all CodeQL resources with the MCP server\n */\nexport function registerCodeQLResources(server: McpServer): void {\n // Getting Started Guide\n server.resource(\n 'CodeQL Getting Started',\n 'codeql://learning/getting-started',\n {\n description: 'Comprehensive introduction to CodeQL for beginners',\n mimeType: 'text/markdown',\n },\n async () => {\n return {\n contents: [\n {\n uri: 'codeql://learning/getting-started',\n mimeType: 'text/markdown',\n text: getGettingStartedGuide(),\n },\n ],\n };\n }\n );\n\n // Query Basics Guide\n server.resource(\n 'CodeQL Query Basics',\n 'codeql://learning/query-basics',\n {\n description: 'Learn the fundamentals of writing CodeQL queries',\n mimeType: 'text/markdown',\n },\n async () => {\n return {\n contents: [\n {\n uri: 'codeql://learning/query-basics',\n mimeType: 'text/markdown',\n text: getQueryBasicsGuide(),\n },\n ],\n };\n }\n );\n\n // Security Templates\n server.resource(\n 'CodeQL Security Templates',\n 'codeql://templates/security',\n {\n description: 'Ready-to-use security query templates',\n mimeType: 'text/markdown',\n },\n async () => {\n return {\n contents: [\n {\n uri: 'codeql://templates/security',\n mimeType: 'text/markdown',\n text: getSecurityTemplates(),\n },\n ],\n };\n }\n );\n\n // Performance Patterns\n server.resource(\n 'CodeQL Performance Patterns',\n 'codeql://patterns/performance',\n {\n description: 'Best practices for writing efficient CodeQL queries',\n mimeType: 'text/markdown',\n },\n async () => {\n return {\n contents: [\n {\n uri: 'codeql://patterns/performance',\n mimeType: 'text/markdown',\n text: getPerformancePatterns(),\n },\n ],\n };\n }\n );\n}\n", "/**\n * CodeQL LSP Diagnostics tool for MCP server.\n *\n * Provides real-time QL code validation through LSP communication.\n * Renamed from `codeql_language_server_eval` to `codeql_lsp_diagnostics`\n * for consistency with the `codeql_lsp_*` tool naming convention.\n */\n\nimport { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport { z } from 'zod';\nimport { Diagnostic, LanguageServerOptions } from '../../lib/language-server';\nimport { logger } from '../../utils/logger';\nimport { getProjectTmpDir } from '../../utils/temp-dir';\nimport { join } from 'path';\nimport { pathToFileURL } from 'url';\nimport { getInitializedLanguageServer } from './lsp-server-helper';\n\nexport interface LspDiagnosticsParams {\n qlCode: string;\n serverOptions?: LanguageServerOptions;\n workspaceUri?: string;\n}\n\nexport interface LspDiagnosticsResult {\n diagnostics: Diagnostic[];\n formattedOutput: string;\n isValid: boolean;\n summary: {\n errorCount: number;\n hintCount: number;\n infoCount: number;\n warningCount: number;\n };\n}\n\n/**\n * Format diagnostics for human-readable output.\n */\nfunction formatDiagnostics(diagnostics: Diagnostic[]): string {\n if (diagnostics.length === 0) {\n return '\u2705 No issues found in QL code';\n }\n\n const lines: string[] = [];\n lines.push(`Found ${diagnostics.length} issue(s):\\n`);\n\n diagnostics.forEach((diagnostic, index) => {\n const severityIcon = getSeverityIcon(diagnostic.severity);\n const severityName = getSeverityName(diagnostic.severity);\n const location = `Line ${diagnostic.range.start.line + 1}, Column ${diagnostic.range.start.character + 1}`;\n\n lines.push(`${index + 1}. ${severityIcon} ${severityName} at ${location}`);\n lines.push(` ${diagnostic.message}`);\n if (diagnostic.source) {\n lines.push(` Source: ${diagnostic.source}`);\n }\n if (diagnostic.code) {\n lines.push(` Code: ${diagnostic.code}`);\n }\n lines.push('');\n });\n\n return lines.join('\\n');\n}\n\nfunction getSeverityIcon(severity: number): string {\n switch (severity) {\n case 1: return '\u274C'; // Error\n case 2: return '\u26A0\uFE0F'; // Warning\n case 3: return '\u2139\uFE0F'; // Information\n case 4: return '\uD83D\uDCA1'; // Hint\n default: return '\u2753';\n }\n}\n\nfunction getSeverityName(severity: number): string {\n switch (severity) {\n case 1: return 'Error';\n case 2: return 'Warning';\n case 3: return 'Information';\n case 4: return 'Hint';\n default: return 'Unknown';\n }\n}\n\n/**\n * Evaluate QL code using the CodeQL Language Server and return diagnostics.\n */\nexport async function lspDiagnostics({\n qlCode,\n workspaceUri,\n serverOptions = {}\n}: LspDiagnosticsParams): Promise {\n try {\n logger.info('Evaluating QL code via Language Server...');\n\n const languageServer = await getInitializedLanguageServer({\n serverOptions,\n workspaceUri,\n });\n\n // Generate unique URI for this evaluation\n const evalUri = pathToFileURL(join(getProjectTmpDir('lsp-eval'), `eval_${Date.now()}.ql`)).href;\n\n const diagnostics = await languageServer.evaluateQL(qlCode, evalUri);\n\n // Count diagnostics by severity\n const summary = {\n errorCount: diagnostics.filter(d => d.severity === 1).length,\n hintCount: diagnostics.filter(d => d.severity === 4).length,\n infoCount: diagnostics.filter(d => d.severity === 3).length,\n warningCount: diagnostics.filter(d => d.severity === 2).length,\n };\n\n const isValid = summary.errorCount === 0;\n const formattedOutput = formatDiagnostics(diagnostics);\n\n logger.info(`QL evaluation complete. Valid: ${isValid}, Issues: ${diagnostics.length}`);\n\n return {\n diagnostics,\n formattedOutput,\n isValid,\n summary,\n };\n\n } catch (error) {\n logger.error('Error evaluating QL code:', error);\n throw new Error(`QL evaluation failed: ${error instanceof Error ? error.message : 'Unknown error'}`);\n }\n}\n\n/**\n * Shutdown the language server via the server manager.\n */\nexport async function shutdownDiagnosticsServer(): Promise {\n const { getServerManager } = await import('../../lib/server-manager');\n const manager = getServerManager();\n await manager.shutdownServer('language');\n}\n\n/**\n * Register the codeql_lsp_diagnostics tool with the MCP server.\n */\nexport function registerLspDiagnosticsTool(server: McpServer): void {\n server.tool(\n 'codeql_lsp_diagnostics',\n 'Authoritative syntax and semantic validation of CodeQL (QL) code via the CodeQL Language Server. Compiles the query and provides real-time diagnostics with precise error locations. Use this for accurate validation; for quick heuristic checks without compilation, use validate_codeql_query instead. Note: inline ql_code is evaluated as a virtual document and cannot resolve pack imports (e.g. `import javascript`). For validating queries with imports, use codeql_query_compile on the actual file instead.',\n {\n log_level: z.enum(['OFF', 'ERROR', 'WARN', 'INFO', 'DEBUG', 'TRACE', 'ALL']).optional().describe('Language server log level'),\n ql_code: z.string().describe('The CodeQL (QL) code to evaluate for syntax and semantic errors'),\n search_path: z.string().optional().describe('Optional search path for CodeQL libraries'),\n workspace_uri: z.string().optional().describe('Optional workspace URI for context (defaults to ./ql directory)'),\n },\n async ({ ql_code, workspace_uri, search_path, log_level }) => {\n try {\n const serverOptions: LanguageServerOptions = {};\n\n if (search_path) {\n serverOptions.searchPath = search_path;\n }\n if (log_level) {\n serverOptions.loglevel = log_level;\n }\n\n const result = await lspDiagnostics({\n qlCode: ql_code,\n serverOptions,\n workspaceUri: workspace_uri,\n });\n\n // Return structured result\n const responseContent = {\n diagnostics: result.diagnostics.map(d => ({\n code: d.code,\n column: d.range.start.character + 1, // Convert to 1-based column numbers\n line: d.range.start.line + 1, // Convert to 1-based line numbers\n message: d.message,\n severity: getSeverityName(d.severity),\n source: d.source,\n })),\n formattedOutput: result.formattedOutput,\n isValid: result.isValid,\n summary: result.summary,\n };\n\n return {\n content: [\n {\n text: JSON.stringify(responseContent, null, 2),\n type: 'text',\n }\n ],\n };\n\n } catch (error) {\n logger.error('Error in codeql_lsp_diagnostics tool:', error);\n return {\n content: [\n {\n text: `Error: ${error instanceof Error ? error.message : 'Unknown error'}`,\n type: 'text',\n },\n ],\n isError: true,\n };\n }\n }\n );\n\n // NOTE: Cleanup is handled centrally by shutdownServerManager() in\n // codeql-development-mcp-server.ts (setupGracefulShutdown). Registering\n // additional process.on('SIGINT'/'SIGTERM') handlers here would\n // accumulate on repeated calls and is unnecessary.\n}\n", "/**\n * Shared helper for obtaining a running, initialized CodeQL Language Server.\n *\n * Both `lsp-diagnostics.ts` and `lsp-handlers.ts` need to:\n * 1. Build a `LanguageServerConfig` with sensible defaults\n * 2. Obtain a server instance from the `CodeQLServerManager`\n * 3. Resolve a workspace URI (relative \u2192 absolute \u2192 `file://`)\n * 4. Initialize the server with the resolved workspace\n *\n * Centralizing this logic avoids duplication and ensures consistent\n * default behaviour across all LSP tools.\n */\n\nimport { isAbsolute, resolve } from 'path';\nimport { pathToFileURL } from 'url';\n\nimport { CodeQLLanguageServer, LanguageServerOptions } from '../../lib/language-server';\nimport { LanguageServerConfig } from '../../lib/server-config';\nimport { getServerManager } from '../../lib/server-manager';\nimport { logger } from '../../utils/logger';\n\n/**\n * Options accepted by {@link getInitializedLanguageServer}.\n */\nexport interface InitializedServerOptions {\n /** Language-server-level options (loglevel, searchPath, etc.). */\n serverOptions?: LanguageServerOptions;\n /** Workspace URI \u2014 may be a `file://` URI, absolute path, or relative path. */\n workspaceUri?: string;\n}\n\n/**\n * Return a running, initialized `CodeQLLanguageServer`.\n *\n * - Resolves `searchPath` to the bundled `ql` directory when not provided.\n * - Converts relative / bare-directory `workspaceUri` paths to `file://` URIs\n * resolved against `getUserWorkspaceDir()` (respects `CODEQL_MCP_WORKSPACE`).\n * - Falls back to the bundled `ql` directory when no workspace is given.\n * - Delegates lifecycle management to the global `CodeQLServerManager`.\n */\nexport async function getInitializedLanguageServer(\n opts: InitializedServerOptions = {},\n): Promise {\n const { packageRootDir: pkgRoot, getUserWorkspaceDir } = await import('../../utils/package-paths');\n const options = opts.serverOptions ?? {};\n\n const config: LanguageServerConfig = {\n checkErrors: 'ON_CHANGE',\n loglevel: options.loglevel ?? 'WARN',\n searchPath: options.searchPath ?? resolve(pkgRoot, 'ql'),\n synchronous: options.synchronous,\n verbosity: options.verbosity,\n };\n\n const manager = getServerManager();\n const server = await manager.getLanguageServer(config);\n\n // Normalize workspace URI: convert relative / bare directory paths to\n // file:// URIs against getUserWorkspaceDir() (respects CODEQL_MCP_WORKSPACE).\n let effectiveUri = opts.workspaceUri;\n if (effectiveUri && !effectiveUri.startsWith('file://')) {\n const absWorkspace = isAbsolute(effectiveUri)\n ? effectiveUri\n : resolve(getUserWorkspaceDir(), effectiveUri);\n effectiveUri = pathToFileURL(absWorkspace).href;\n }\n effectiveUri = effectiveUri ?? pathToFileURL(resolve(pkgRoot, 'ql')).href;\n\n await server.initialize(effectiveUri);\n logger.debug(`Language server initialized with workspace: ${effectiveUri}`);\n\n return server;\n}\n", "/**\n * CodeQL LSP tool handlers.\n *\n * Bridges MCP tool invocations to LSP requests on the CodeQL Language Server.\n * Each handler acquires a language server via the CodeQLServerManager,\n * opens the requested document, sends the LSP request, and returns the result.\n */\n\nimport { readFile } from 'fs/promises';\nimport { isAbsolute, resolve } from 'path';\nimport { pathToFileURL } from 'url';\n\nimport {\n CompletionItem,\n LSPLocation,\n TextDocumentPositionParams,\n} from '../../lib/language-server';\nimport { logger } from '../../utils/logger';\nimport { getUserWorkspaceDir } from '../../utils/package-paths';\nimport { getInitializedLanguageServer } from './lsp-server-helper';\n\n/**\n * Common parameters for LSP tool invocations.\n */\nexport interface LSPToolParams {\n /** 0-based character offset within the line. */\n character: number;\n /** Optional override for the file content (if not reading from disk). */\n fileContent?: string;\n /**\n * Path to the QL file. May be absolute or relative.\n * Relative paths are resolved against `getUserWorkspaceDir()`\n * (respects the `CODEQL_MCP_WORKSPACE` environment variable).\n */\n filePath: string;\n /** 0-based line number in the document. */\n line: number;\n /** Optional search path for CodeQL libraries. */\n searchPath?: string;\n /** Optional workspace URI for context. */\n workspaceUri?: string;\n}\n\n/**\n * Get a running, initialized language server for the given parameters.\n */\nasync function getInitializedServer(params: LSPToolParams) {\n return getInitializedLanguageServer({\n serverOptions: { searchPath: params.searchPath },\n workspaceUri: params.workspaceUri,\n });\n}\n\n/**\n * Resolve the file path to an absolute path and file:// URI.\n */\nfunction prepareDocumentPosition(\n params: LSPToolParams,\n): { absPath: string; docUri: string } {\n // Resolve relative paths against getUserWorkspaceDir() so that\n // CODEQL_MCP_WORKSPACE is respected and behaviour is consistent across tools.\n const absPath = isAbsolute(params.filePath)\n ? params.filePath\n : resolve(getUserWorkspaceDir(), params.filePath);\n const docUri = pathToFileURL(absPath).href;\n\n return { absPath, docUri };\n}\n\n/**\n * Read file content and open the document in the language server.\n */\nasync function openDocumentForPosition(\n server: Awaited>,\n params: LSPToolParams,\n absPath: string,\n docUri: string,\n): Promise {\n // Read file content from disk or use provided content\n let text: string;\n if (params.fileContent) {\n text = params.fileContent;\n } else {\n try {\n text = await readFile(absPath, 'utf-8');\n } catch (error) {\n throw new Error(`Cannot read file: ${absPath}: ${error instanceof Error ? error.message : error}`);\n }\n }\n\n // Open the document so the language server knows about it\n server.openDocument(docUri, text);\n\n return {\n position: { character: params.character, line: params.line },\n textDocument: { uri: docUri },\n };\n}\n\n/**\n * Get code completions at a position.\n */\nexport async function lspCompletion(params: LSPToolParams): Promise {\n logger.info(`LSP completion at ${params.filePath}:${params.line}:${params.character}`);\n const server = await getInitializedServer(params);\n const { absPath, docUri } = prepareDocumentPosition(params);\n const positionParams = await openDocumentForPosition(server, params, absPath, docUri);\n\n try {\n return await server.getCompletions(positionParams);\n } finally {\n server.closeDocument(docUri);\n }\n}\n\n/**\n * Go to definition of a symbol at a position.\n */\nexport async function lspDefinition(params: LSPToolParams): Promise {\n logger.info(`LSP definition at ${params.filePath}:${params.line}:${params.character}`);\n const server = await getInitializedServer(params);\n const { absPath, docUri } = prepareDocumentPosition(params);\n const positionParams = await openDocumentForPosition(server, params, absPath, docUri);\n\n try {\n return await server.getDefinition(positionParams);\n } finally {\n server.closeDocument(docUri);\n }\n}\n\n/**\n * Find all references to a symbol at a position.\n */\nexport async function lspReferences(params: LSPToolParams): Promise {\n logger.info(`LSP references at ${params.filePath}:${params.line}:${params.character}`);\n const server = await getInitializedServer(params);\n const { absPath, docUri } = prepareDocumentPosition(params);\n const positionParams = await openDocumentForPosition(server, params, absPath, docUri);\n\n try {\n return await server.getReferences({\n ...positionParams,\n context: { includeDeclaration: true },\n });\n } finally {\n server.closeDocument(docUri);\n }\n}\n", "/**\n * CodeQL LSP MCP tool definitions.\n *\n * Registers four LSP-based tools:\n * - codeql_lsp_completion \u2013 code completions at cursor position\n * - codeql_lsp_definition \u2013 go to definition\n * - codeql_lsp_diagnostics \u2013 QL code validation via LSP diagnostics\n * - codeql_lsp_references \u2013 find all references\n */\n\nimport { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport { z } from 'zod';\nimport { registerLspDiagnosticsTool } from './lsp-diagnostics';\nimport {\n lspCompletion,\n lspDefinition,\n lspReferences,\n} from './lsp-handlers';\nimport { logger } from '../../utils/logger';\n\n/**\n * Shared Zod schema for the common LSP tool parameters.\n */\nconst lspParamsSchema = {\n character: z.number().int().min(0).describe('0-based character offset within the line'),\n file_content: z.string().optional().describe('Optional file content override (reads from disk if omitted)'),\n file_path: z.string().describe('Path to the CodeQL (.ql/.qll) file. Relative paths are resolved against the user workspace directory (see CODEQL_MCP_WORKSPACE).'),\n line: z.number().int().min(0).describe('0-based line number in the document'),\n search_path: z.string().optional().describe('Optional search path for CodeQL libraries'),\n workspace_uri: z.string().optional().describe('Optional workspace URI for context (defaults to ./ql directory)'),\n};\n\n/**\n * Helper to build the handler params from the raw MCP tool input.\n */\nfunction toHandlerParams(input: {\n character: number;\n file_content?: string;\n file_path: string;\n line: number;\n search_path?: string;\n workspace_uri?: string;\n}) {\n return {\n character: input.character,\n fileContent: input.file_content,\n filePath: input.file_path,\n line: input.line,\n searchPath: input.search_path,\n workspaceUri: input.workspace_uri,\n };\n}\n\n/**\n * Register all LSP-based tools with the MCP server.\n */\nexport function registerLSPTools(server: McpServer): void {\n // --- codeql_lsp_diagnostics (relocated from codeql_language_server_eval) ---\n registerLspDiagnosticsTool(server);\n\n // --- codeql_lsp_completion ---\n server.tool(\n 'codeql_lsp_completion',\n 'Get code completions at a cursor position in a CodeQL file. Returns completion items with labels, documentation, and insert text. The file must be a .ql or .qll file. IMPORTANT: Set workspace_uri to the pack or workspace root directory for dependency resolution; without it, completions for imported libraries will be empty.',\n lspParamsSchema,\n async (input) => {\n try {\n const items = await lspCompletion(toHandlerParams(input));\n return {\n content: [{\n text: JSON.stringify({\n completionCount: items.length,\n items: items.map((item) => ({\n detail: item.detail,\n documentation: item.documentation,\n insertText: item.insertText,\n kind: item.kind,\n label: item.label,\n })),\n }, null, 2),\n type: 'text' as const,\n }],\n };\n } catch (error) {\n logger.error('codeql_lsp_completion error:', error);\n return {\n content: [{ text: `Error: ${error instanceof Error ? error.message : 'Unknown error'}`, type: 'text' as const }],\n isError: true,\n };\n }\n },\n );\n\n // --- codeql_lsp_definition ---\n server.tool(\n 'codeql_lsp_definition',\n 'Go to the definition of a CodeQL symbol at a given position. Returns one or more file locations where the symbol is defined. Set workspace_uri to the pack root for dependency resolution.',\n lspParamsSchema,\n async (input) => {\n try {\n const locations = await lspDefinition(toHandlerParams(input));\n return {\n content: [{\n text: JSON.stringify({\n definitionCount: locations.length,\n locations: locations.map((loc) => ({\n endCharacter: loc.range.end.character,\n endLine: loc.range.end.line + 1,\n startCharacter: loc.range.start.character,\n startLine: loc.range.start.line + 1,\n uri: loc.uri,\n })),\n }, null, 2),\n type: 'text' as const,\n }],\n };\n } catch (error) {\n logger.error('codeql_lsp_definition error:', error);\n return {\n content: [{ text: `Error: ${error instanceof Error ? error.message : 'Unknown error'}`, type: 'text' as const }],\n isError: true,\n };\n }\n },\n );\n\n // --- codeql_lsp_references ---\n server.tool(\n 'codeql_lsp_references',\n 'Find all references to a CodeQL symbol at a given position. Returns file locations of all usages, including the declaration. Set workspace_uri to the pack root for dependency resolution.',\n lspParamsSchema,\n async (input) => {\n try {\n const locations = await lspReferences(toHandlerParams(input));\n return {\n content: [{\n text: JSON.stringify({\n locations: locations.map((loc) => ({\n endCharacter: loc.range.end.character,\n endLine: loc.range.end.line + 1,\n startCharacter: loc.range.start.character,\n startLine: loc.range.start.line + 1,\n uri: loc.uri,\n })),\n referenceCount: locations.length,\n }, null, 2),\n type: 'text' as const,\n }],\n };\n } catch (error) {\n logger.error('codeql_lsp_references error:', error);\n return {\n content: [{ text: `Error: ${error instanceof Error ? error.message : 'Unknown error'}`, type: 'text' as const }],\n isError: true,\n };\n }\n },\n );\n}\n", "/**\n * Language-specific resources implementation\n * Dynamically loads and serves language-specific AST references and security patterns\n */\n\nimport { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport { readFileSync, existsSync } from 'fs';\nimport { join } from 'path';\nimport { LANGUAGE_RESOURCES } from '../types/language-types';\nimport { workspaceRootDir } from '../utils/package-paths';\nimport { logger } from '../utils/logger';\n\n/**\n * Get the base path for ql resources.\n * Uses the workspace root (monorepo root or package root) so that\n * resource files are found regardless of the server's process.cwd().\n */\nfunction getQLBasePath(): string {\n return workspaceRootDir;\n}\n\n/**\n * Load content from a resource file\n */\nfunction loadResourceContent(relativePath: string): string | null {\n try {\n const fullPath = join(getQLBasePath(), relativePath);\n \n if (!existsSync(fullPath)) {\n logger.warn(`Resource file not found: ${fullPath}`);\n return null;\n }\n \n return readFileSync(fullPath, 'utf-8');\n } catch (error) {\n logger.error(`Error loading resource file ${relativePath}:`, error);\n return null;\n }\n}\n\n/**\n * Register language-specific AST resources\n */\nexport function registerLanguageASTResources(server: McpServer): void {\n for (const langResource of LANGUAGE_RESOURCES) {\n if (!langResource.astFile) continue;\n \n const resourceUri = `codeql://languages/${langResource.language}/ast`;\n \n server.resource(\n `${langResource.language.toUpperCase()} AST Reference`,\n resourceUri,\n {\n description: `CodeQL AST class reference for ${langResource.language} programs`,\n mimeType: 'text/markdown'\n },\n async () => {\n const content = loadResourceContent(langResource.astFile!);\n \n if (!content) {\n return {\n contents: [{\n uri: resourceUri,\n mimeType: 'text/markdown',\n text: `# ${langResource.language.toUpperCase()} AST Reference\\n\\nResource file not found or could not be loaded.`\n }]\n };\n }\n \n return {\n contents: [{\n uri: resourceUri,\n mimeType: 'text/markdown',\n text: content\n }]\n };\n }\n );\n }\n}\n\n/**\n * Register language-specific security pattern resources\n */\nexport function registerLanguageSecurityResources(server: McpServer): void {\n for (const langResource of LANGUAGE_RESOURCES) {\n if (!langResource.securityFile) continue;\n \n const resourceUri = `codeql://languages/${langResource.language}/security`;\n \n server.resource(\n `${langResource.language.toUpperCase()} Security Patterns`,\n resourceUri,\n {\n description: `CodeQL security query patterns and framework modeling for ${langResource.language}`,\n mimeType: 'text/markdown'\n },\n async () => {\n const content = loadResourceContent(langResource.securityFile!);\n \n if (!content) {\n return {\n contents: [{\n uri: resourceUri,\n mimeType: 'text/markdown',\n text: `# ${langResource.language.toUpperCase()} Security Patterns\\n\\nResource file not found or could not be loaded.`\n }]\n };\n }\n \n return {\n contents: [{\n uri: resourceUri,\n mimeType: 'text/markdown',\n text: content\n }]\n };\n }\n );\n }\n}\n\n/**\n * Register additional language-specific resources (like Go's dataflow patterns)\n */\nexport function registerLanguageAdditionalResources(server: McpServer): void {\n for (const langResource of LANGUAGE_RESOURCES) {\n if (!langResource.additionalFiles) continue;\n \n for (const [resourceType, filePath] of Object.entries(langResource.additionalFiles)) {\n const resourceUri = `codeql://languages/${langResource.language}/${resourceType}`;\n \n server.resource(\n `${langResource.language.toUpperCase()} ${resourceType.replace('-', ' ').replace(/\\b\\w/g, l => l.toUpperCase())}`,\n resourceUri,\n {\n description: `CodeQL ${resourceType.replace('-', ' ')} guide for ${langResource.language}`,\n mimeType: 'text/markdown'\n },\n async () => {\n const content = loadResourceContent(filePath);\n \n if (!content) {\n return {\n contents: [{\n uri: resourceUri,\n mimeType: 'text/markdown',\n text: `# ${langResource.language.toUpperCase()} ${resourceType.replace('-', ' ').replace(/\\b\\w/g, l => l.toUpperCase())}\\n\\nResource file not found or could not be loaded.`\n }]\n };\n }\n \n return {\n contents: [{\n uri: resourceUri,\n mimeType: 'text/markdown',\n text: content\n }]\n };\n }\n );\n }\n }\n}\n\n/**\n * Register all language-specific resources\n */\nexport function registerLanguageResources(server: McpServer): void {\n logger.info('Registering language-specific resources...');\n \n // Register AST references for all languages\n registerLanguageASTResources(server);\n \n // Register security patterns for languages that have them\n registerLanguageSecurityResources(server);\n \n // Register additional resources (like Go's dataflow patterns)\n registerLanguageAdditionalResources(server);\n \n logger.info(`Registered resources for ${LANGUAGE_RESOURCES.length} languages`);\n}", "/**\n * Type definitions and constants for language-specific resources\n */\n\n// Language mappings to resource files\nexport interface LanguageResource {\n language: string;\n astFile?: string;\n securityFile?: string;\n additionalFiles?: Record;\n}\n\nexport const LANGUAGE_RESOURCES: LanguageResource[] = [\n {\n language: 'actions',\n astFile: 'ql/languages/actions/tools/dev/actions_ast.prompt.md'\n },\n {\n language: 'cpp',\n astFile: 'ql/languages/cpp/tools/dev/cpp_ast.prompt.md',\n securityFile: 'ql/languages/cpp/tools/dev/cpp_security_query_guide.prompt.md'\n },\n {\n language: 'csharp',\n astFile: 'ql/languages/csharp/tools/dev/csharp_ast.prompt.md',\n securityFile: 'ql/languages/csharp/tools/dev/csharp_security_query_guide.prompt.md'\n },\n {\n language: 'go',\n astFile: 'ql/languages/go/tools/dev/go_ast.prompt.md',\n securityFile: 'ql/languages/go/tools/dev/go_security_query_guide.prompt.md',\n additionalFiles: {\n 'dataflow': 'ql/languages/go/tools/dev/go_dataflow.prompt.md',\n 'library-modeling': 'ql/languages/go/tools/dev/go_library_modeling.prompt.md',\n 'basic-queries': 'ql/languages/go/tools/dev/go_basic_queries.prompt.md'\n }\n },\n {\n language: 'java',\n astFile: 'ql/languages/java/tools/dev/java_ast.prompt.md'\n },\n {\n language: 'javascript',\n astFile: 'ql/languages/javascript/tools/dev/javascript_ast.prompt.md',\n securityFile: 'ql/languages/javascript/tools/dev/javascript_security_query_guide.prompt.md'\n },\n {\n language: 'python',\n astFile: 'ql/languages/python/tools/dev/python_ast.prompt.md',\n securityFile: 'ql/languages/python/tools/dev/python_security_query_guide.prompt.md'\n },\n {\n language: 'ql',\n astFile: 'ql/languages/ql/tools/dev/ql_ast.prompt.md'\n },\n {\n language: 'ruby',\n astFile: 'ql/languages/ruby/tools/dev/ruby_ast.prompt.md'\n }\n];", "/**\n * MCP Server workflow prompts for CodeQL development\n *\n * All prompt content is loaded from .prompt.md files in this directory.\n * This file only handles prompt registration and parameter processing.\n */\n\nimport { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport { z } from 'zod';\nimport { basename } from 'path';\nimport { loadPromptTemplate, processPromptTemplate } from './prompt-loader';\nimport { logger } from '../utils/logger';\n\n/** Supported CodeQL languages for tools queries */\nexport const SUPPORTED_LANGUAGES = [\n 'actions',\n 'cpp',\n 'csharp',\n 'go',\n 'java',\n 'javascript',\n 'python',\n 'ruby',\n 'swift'\n] as const;\n\n// \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n// Exported parameter schemas for each workflow prompt.\n//\n// Extracting the schemas makes it easy to unit-test required vs optional\n// validation independently of the MCP server registration.\n//\n// **Convention for VS Code UX consistency**:\n// Every prompt MUST expose at least one parameter \u2013 even if all parameters\n// are optional \u2013 so that VS Code always displays the parameter input dialog\n// and allows the user to customize the prompt before Copilot Chat processes\n// it. The `description` field on each Zod schema member doubles as the\n// placeholder text shown in the VS Code input box.\n// \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n/**\n * Schema for test_driven_development prompt parameters.\n *\n * - `language` is **required** \u2013 the TDD workflow is language-specific.\n * - `queryName` is optional \u2013 defaults to '[QueryName]' if omitted.\n */\nexport const testDrivenDevelopmentSchema = z.object({\n language: z\n .enum(SUPPORTED_LANGUAGES)\n .describe('Programming language for the query'),\n queryName: z\n .string()\n .optional()\n .describe('Name of the query to develop'),\n});\n\n/**\n * Schema for tools_query_workflow prompt parameters.\n *\n * - `language` and `database` are **required**.\n * - `sourceFiles`, `sourceFunction`, `targetFunction` are optional context.\n */\nexport const toolsQueryWorkflowSchema = z.object({\n database: z\n .string()\n .describe('Path to the CodeQL database'),\n language: z\n .enum(SUPPORTED_LANGUAGES)\n .describe('Programming language for the tools queries'),\n sourceFiles: z\n .string()\n .optional()\n .describe('Comma-separated source file names for PrintAST (e.g., \"main.js,utils.js\")'),\n sourceFunction: z\n .string()\n .optional()\n .describe('Function name for PrintCFG or CallGraphFrom (e.g., \"processData\")'),\n targetFunction: z\n .string()\n .optional()\n .describe('Function name for CallGraphTo (e.g., \"validate\")'),\n});\n\n/**\n * Schema for workshop_creation_workflow prompt parameters.\n * Uses z.coerce.number() for numStages to handle string inputs from VSCode slash commands.\n *\n * - `queryPath` and `language` are **required**.\n * - `workshopName` and `numStages` are optional.\n */\nexport const workshopCreationWorkflowSchema = z.object({\n queryPath: z\n .string()\n .describe('Path to the production-grade CodeQL query (.ql or .qlref)'),\n language: z\n .enum(SUPPORTED_LANGUAGES)\n .describe('Programming language of the query'),\n workshopName: z\n .string()\n .optional()\n .describe('Name for the workshop directory'),\n numStages: z\n .coerce.number()\n .optional()\n .describe('Number of incremental stages (default: 4-8)'),\n});\n\n/**\n * Schema for ql_tdd_basic prompt parameters.\n *\n * All parameters are optional \u2013 but at least one should be present so the\n * VS Code quick-pick dialog appears.\n */\nexport const qlTddBasicSchema = z.object({\n language: z\n .enum(SUPPORTED_LANGUAGES)\n .optional()\n .describe('Programming language for the query (optional)'),\n queryName: z\n .string()\n .optional()\n .describe('Name of the query to develop'),\n});\n\n/**\n * Schema for ql_tdd_advanced prompt parameters.\n *\n * All parameters are optional.\n */\nexport const qlTddAdvancedSchema = z.object({\n database: z\n .string()\n .optional()\n .describe('Path to the CodeQL database for analysis'),\n language: z\n .enum(SUPPORTED_LANGUAGES)\n .optional()\n .describe('Programming language for the query (optional)'),\n queryName: z\n .string()\n .optional()\n .describe('Name of the query to develop'),\n});\n\n/**\n * Schema for sarif_rank_false_positives / sarif_rank_true_positives.\n *\n * Both parameters are optional.\n */\nexport const sarifRankSchema = z.object({\n queryId: z\n .string()\n .optional()\n .describe('CodeQL query/rule identifier'),\n sarifPath: z\n .string()\n .optional()\n .describe('Path to the SARIF file to analyze'),\n});\n\n/**\n * Schema for explain_codeql_query prompt parameters.\n *\n * - `queryPath` and `language` are **required**.\n * - `databasePath` is optional.\n */\nexport const explainCodeqlQuerySchema = z.object({\n databasePath: z\n .string()\n .optional()\n .describe('Optional path to a real CodeQL database for profiling'),\n language: z\n .enum(SUPPORTED_LANGUAGES)\n .describe('Programming language of the query'),\n queryPath: z\n .string()\n .describe('Path to the CodeQL query file (.ql or .qlref)'),\n});\n\n/**\n * Schema for document_codeql_query prompt parameters.\n *\n * - `queryPath` and `language` are **required**.\n */\nexport const documentCodeqlQuerySchema = z.object({\n language: z\n .enum(SUPPORTED_LANGUAGES)\n .describe('Programming language of the query'),\n queryPath: z\n .string()\n .describe('Path to the CodeQL query file (.ql or .qlref)'),\n});\n\n/**\n * Schema for ql_lsp_iterative_development prompt parameters.\n *\n * All parameters are optional.\n */\nexport const qlLspIterativeDevelopmentSchema = z.object({\n language: z\n .enum(SUPPORTED_LANGUAGES)\n .optional()\n .describe('Programming language for the query'),\n queryPath: z\n .string()\n .optional()\n .describe('Path to the query file being developed'),\n workspaceUri: z\n .string()\n .optional()\n .describe('Workspace URI for LSP dependency resolution'),\n});\n\n// \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n// Prompt names (exported for testing)\n// \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n/** Names of every workflow prompt registered with the MCP server. */\nexport const WORKFLOW_PROMPT_NAMES = [\n 'document_codeql_query',\n 'explain_codeql_query',\n 'ql_lsp_iterative_development',\n 'ql_tdd_advanced',\n 'ql_tdd_basic',\n 'sarif_rank_false_positives',\n 'sarif_rank_true_positives',\n 'test_driven_development',\n 'tools_query_workflow',\n 'workshop_creation_workflow',\n] as const;\n\n/**\n * Register MCP workflow prompts\n *\n * Each prompt loads its content from a corresponding .prompt.md file\n * and processes any parameter substitutions.\n *\n * **UX note**: Every prompt schema is passed to `server.prompt()` so that\n * VS Code always displays the parameter-input quick-pick before the prompt\n * is sent to Copilot Chat. This lets users review and customise the values.\n */\nexport function registerWorkflowPrompts(server: McpServer): void {\n // Test-Driven Development Prompt\n server.prompt(\n 'test_driven_development',\n 'Test-driven development workflow for CodeQL queries using MCP tools',\n testDrivenDevelopmentSchema.shape,\n async ({ language, queryName }) => {\n const template = loadPromptTemplate('ql-tdd-basic.prompt.md');\n const content = processPromptTemplate(template, {\n language,\n queryName: queryName || '[QueryName]'\n });\n\n return {\n messages: [\n {\n role: 'user',\n content: {\n type: 'text',\n text: `## Context\\n\\n- **Language**: ${language}\\n${queryName ? `- **Query Name**: ${queryName}\\n` : ''}\\n${content}`\n }\n }\n ]\n };\n }\n );\n\n // Tools Query Workflow Prompt\n server.prompt(\n 'tools_query_workflow',\n 'Guide for using built-in tools queries (PrintAST, PrintCFG, CallGraphFrom, CallGraphTo) to understand code structure',\n toolsQueryWorkflowSchema.shape,\n async ({\n language,\n database,\n sourceFiles,\n sourceFunction,\n targetFunction\n }) => {\n const template = loadPromptTemplate('tools-query-workflow.prompt.md');\n const content = processPromptTemplate(template, {\n language,\n database\n });\n\n const contextSection = buildToolsQueryContext(\n language,\n database,\n sourceFiles,\n sourceFunction,\n targetFunction\n );\n\n return {\n messages: [\n {\n role: 'user',\n content: {\n type: 'text',\n text: contextSection + content\n }\n }\n ]\n };\n }\n );\n\n // Workshop Creation Workflow Prompt\n server.prompt(\n 'workshop_creation_workflow',\n 'Guide for creating CodeQL query development workshops from production-grade queries',\n workshopCreationWorkflowSchema.shape,\n async ({ queryPath, language, workshopName, numStages }) => {\n const template = loadPromptTemplate('workshop-creation-workflow.prompt.md');\n\n // Derive workshop name from query path if not provided\n const derivedName =\n workshopName ||\n basename(queryPath)\n .replace(/\\.(ql|qlref)$/, '')\n .toLowerCase()\n .replace(/[^a-z0-9]+/g, '-') ||\n 'codeql-workshop';\n\n const contextSection = buildWorkshopContext(\n queryPath,\n language,\n derivedName,\n numStages\n );\n\n return {\n messages: [\n {\n role: 'user',\n content: {\n type: 'text',\n text: contextSection + template\n }\n }\n ]\n };\n }\n );\n\n // TDD Basic Prompt - Test-Driven Development Checklist\n server.prompt(\n 'ql_tdd_basic',\n 'Test-driven CodeQL query development checklist - write tests first, implement query, iterate until tests pass',\n qlTddBasicSchema.shape,\n async ({ language, queryName }) => {\n const template = loadPromptTemplate('ql-tdd-basic.prompt.md');\n\n let contextSection = '## Your Development Context\\n\\n';\n if (language) {\n contextSection += `- **Language**: ${language}\\n`;\n }\n if (queryName) {\n contextSection += `- **Query Name**: ${queryName}\\n`;\n }\n if (language || queryName) {\n contextSection += '\\n';\n }\n\n return {\n messages: [\n {\n role: 'user',\n content: {\n type: 'text',\n text: contextSection + template\n }\n }\n ]\n };\n }\n );\n\n // TDD Advanced Prompt - Advanced Techniques with AST/CFG/CallGraph\n server.prompt(\n 'ql_tdd_advanced',\n 'Advanced test-driven CodeQL development with AST visualization, control flow, and call graph analysis',\n qlTddAdvancedSchema.shape,\n async ({ language, queryName, database }) => {\n const template = loadPromptTemplate('ql-tdd-advanced.prompt.md');\n\n let contextSection = '## Your Development Context\\n\\n';\n if (language) {\n contextSection += `- **Language**: ${language}\\n`;\n }\n if (queryName) {\n contextSection += `- **Query Name**: ${queryName}\\n`;\n }\n if (database) {\n contextSection += `- **Database**: ${database}\\n`;\n }\n if (language || queryName || database) {\n contextSection += '\\n';\n }\n\n return {\n messages: [\n {\n role: 'user',\n content: {\n type: 'text',\n text: contextSection + template\n }\n }\n ]\n };\n }\n );\n\n // SARIF Rank False Positives Prompt\n server.prompt(\n 'sarif_rank_false_positives',\n 'Analyze SARIF results to identify likely false positives in CodeQL query results',\n sarifRankSchema.shape,\n async ({ queryId, sarifPath }) => {\n const template = loadPromptTemplate('sarif-rank-false-positives.prompt.md');\n\n let contextSection = '## Analysis Context\\n\\n';\n if (queryId) {\n contextSection += `- **Query ID**: ${queryId}\\n`;\n }\n if (sarifPath) {\n contextSection += `- **SARIF File**: ${sarifPath}\\n`;\n }\n if (queryId || sarifPath) {\n contextSection += '\\n';\n }\n\n return {\n messages: [\n {\n role: 'user',\n content: {\n type: 'text',\n text: contextSection + template\n }\n }\n ]\n };\n }\n );\n\n // SARIF Rank True Positives Prompt\n server.prompt(\n 'sarif_rank_true_positives',\n 'Analyze SARIF results to identify likely true positives in CodeQL query results',\n sarifRankSchema.shape,\n async ({ queryId, sarifPath }) => {\n const template = loadPromptTemplate('sarif-rank-true-positives.prompt.md');\n\n let contextSection = '## Analysis Context\\n\\n';\n if (queryId) {\n contextSection += `- **Query ID**: ${queryId}\\n`;\n }\n if (sarifPath) {\n contextSection += `- **SARIF File**: ${sarifPath}\\n`;\n }\n if (queryId || sarifPath) {\n contextSection += '\\n';\n }\n\n return {\n messages: [\n {\n role: 'user',\n content: {\n type: 'text',\n text: contextSection + template\n }\n }\n ]\n };\n }\n );\n\n // Explain CodeQL Query Prompt (for workshop learning content)\n server.prompt(\n 'explain_codeql_query',\n 'Generate detailed explanation of a CodeQL query for workshop learning content - uses MCP tools to gather context and produces both verbal explanations and mermaid evaluation diagrams',\n explainCodeqlQuerySchema.shape,\n async ({ queryPath, language, databasePath }) => {\n const template = loadPromptTemplate('explain-codeql-query.prompt.md');\n\n let contextSection = '## Query to Explain\\n\\n';\n contextSection += `- **Query Path**: ${queryPath}\\n`;\n contextSection += `- **Language**: ${language}\\n`;\n if (databasePath) {\n contextSection += `- **Database Path**: ${databasePath}\\n`;\n }\n contextSection += '\\n';\n\n return {\n messages: [\n {\n role: 'user',\n content: {\n type: 'text',\n text: contextSection + template\n }\n }\n ]\n };\n }\n );\n\n // Document CodeQL Query Prompt\n server.prompt(\n 'document_codeql_query',\n 'Create or update documentation for a CodeQL query - generates standardized markdown documentation as a sibling file to the query',\n documentCodeqlQuerySchema.shape,\n async ({ queryPath, language }) => {\n const template = loadPromptTemplate('document-codeql-query.prompt.md');\n\n const contextSection = `## Query to Document\n\n- **Query Path**: ${queryPath}\n- **Language**: ${language}\n\n`;\n\n return {\n messages: [\n {\n role: 'user',\n content: {\n type: 'text',\n text: contextSection + template\n }\n }\n ]\n };\n }\n );\n\n // LSP-powered Iterative Development Prompt\n server.prompt(\n 'ql_lsp_iterative_development',\n 'Iterative CodeQL query development using LSP tools for completion, navigation, and validation',\n qlLspIterativeDevelopmentSchema.shape,\n async ({ language, queryPath, workspaceUri }) => {\n const template = loadPromptTemplate('ql-lsp-iterative-development.prompt.md');\n\n let contextSection = '## Your Development Context\\n\\n';\n if (language) {\n contextSection += `- **Language**: ${language}\\n`;\n }\n if (queryPath) {\n contextSection += `- **Query Path**: ${queryPath}\\n`;\n }\n if (workspaceUri) {\n contextSection += `- **Workspace URI**: ${workspaceUri}\\n`;\n }\n if (language || queryPath || workspaceUri) {\n contextSection += '\\n';\n }\n\n return {\n messages: [\n {\n role: 'user',\n content: {\n type: 'text',\n text: contextSection + template,\n },\n },\n ],\n };\n }\n );\n\n logger.info(`Registered ${WORKFLOW_PROMPT_NAMES.length} workflow prompts`);\n}\n\n/**\n * Build context section for tools query workflow\n */\nexport function buildToolsQueryContext(\n language: string,\n database: string,\n sourceFiles?: string,\n sourceFunction?: string,\n targetFunction?: string\n): string {\n const lines = [\n '## Your Context',\n '',\n `- **Language**: ${language}`,\n `- **Database**: ${database}`\n ];\n\n if (sourceFiles) {\n lines.push(`- **Source Files**: ${sourceFiles}`);\n }\n if (sourceFunction) {\n lines.push(`- **Source Function**: ${sourceFunction}`);\n }\n if (targetFunction) {\n lines.push(`- **Target Function**: ${targetFunction}`);\n }\n\n lines.push('', '## Recommended Next Steps', '');\n\n if (sourceFiles) {\n lines.push(\n `1. Run \\`codeql_query_run\\` with queryName=\"PrintAST\", sourceFiles=\"${sourceFiles}\"`\n );\n } else {\n lines.push('1. Identify source files to analyze with PrintAST');\n }\n\n if (sourceFunction) {\n lines.push(\n `2. Run \\`codeql_query_run\\` with queryName=\"PrintCFG\" or \"CallGraphFrom\", sourceFunction=\"${sourceFunction}\"`\n );\n } else {\n lines.push(\n '2. Identify key functions for CFG or call graph analysis'\n );\n }\n\n if (targetFunction) {\n lines.push(\n `3. Run \\`codeql_query_run\\` with queryName=\"CallGraphTo\", targetFunction=\"${targetFunction}\"`\n );\n } else {\n lines.push('3. Identify target functions to find callers');\n }\n\n lines.push('', '');\n return lines.join('\\n');\n}\n\n/**\n * Build context section for workshop creation workflow\n */\nexport function buildWorkshopContext(\n queryPath: string,\n language: string,\n workshopName: string,\n numStages?: number\n): string {\n return `## Your Workshop Context\n\n- **Target Query**: ${queryPath}\n- **Language**: ${language}\n- **Workshop Name**: ${workshopName}\n- **Suggested Stages**: ${numStages || '4-8 (auto-detect based on query complexity)'}\n\n## Immediate Actions\n\n1. **Locate query files**: Use \\`find_codeql_query_files\\` with queryPath=\"${queryPath}\"\n2. **Understand query for learning content**: Use the \\`explain_codeql_query\\` prompt with queryPath=\"${queryPath}\" and language=\"${language}\"\n3. **Document each workshop stage**: Use the \\`document_codeql_query\\` prompt to create/update documentation for each solution query\n4. **Verify tests pass**: Use \\`codeql_test_run\\` on existing tests\n5. **Run tools queries**: Generate AST/CFG understanding for workshop materials\n\n`;\n}\n", "/**\n * Utility functions for loading prompt template files\n */\n\nimport { readFileSync } from 'fs';\nimport { join, dirname } from 'path';\nimport { fileURLToPath } from 'url';\n\nconst __filename = fileURLToPath(import.meta.url);\nconst __dirname = dirname(__filename);\n\n/**\n * Load a prompt template from a .prompt.md file\n */\nexport function loadPromptTemplate(promptFileName: string): string {\n try {\n const promptPath = join(__dirname, promptFileName);\n return readFileSync(promptPath, 'utf-8');\n } catch (error) {\n return `Prompt template '${promptFileName}' not available: ${error instanceof Error ? error.message : 'Unknown error'}`;\n }\n}\n\n/**\n * Process prompt template by replacing placeholders with actual values\n */\nexport function processPromptTemplate(template: string, variables: Record): string {\n let processed = template;\n \n // Replace variables in the format {{variable}} or {variable}\n for (const [key, value] of Object.entries(variables)) {\n const patterns = [\n new RegExp(`\\\\{\\\\{${key}\\\\}\\\\}`, 'g'),\n new RegExp(`\\\\{${key}\\\\}`, 'g')\n ];\n \n for (const pattern of patterns) {\n processed = processed.replace(pattern, value);\n }\n }\n \n return processed;\n}", "/**\n * Monitoring Tools - MCP tool implementations for session management and reporting\n * Provides the MCP Tool APIs specified in the monitoring specification\n */\n\nimport { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport { z } from 'zod';\nimport { randomUUID } from 'crypto';\nimport { sessionDataManager } from '../lib/session-data-manager';\nimport {\n QueryDevelopmentSession,\n SessionFilter,\n QualityScoreRecord,\n ComparisonReport,\n AggregateReport,\n ExportResult,\n FunctionalTestResult,\n} from '../types/monitoring';\nimport { logger } from '../utils/logger';\n\n/**\n * Register all monitoring and reporting tools with the MCP server\n * Note: These tools are opt-in and disabled by default for end-users.\n * Set enableMonitoringTools: true in monitoring config to enable them.\n */\nexport function registerMonitoringTools(server: McpServer): void {\n const config = sessionDataManager.getConfig();\n \n // Check if monitoring tools are enabled (opt-in, disabled by default)\n if (!config.enableMonitoringTools) {\n logger.info('Monitoring tools are disabled (opt-in). Set enableMonitoringTools: true to enable session_* tools.');\n return;\n }\n\n // Session Management Tools - session_start removed per feedback (auto-creation instead)\n registerSessionEndTool(server);\n registerSessionGetTool(server);\n registerSessionListTool(server);\n registerSessionUpdateStateTool(server);\n\n // Session Analytics Tools\n registerSessionGetCallHistoryTool(server);\n registerSessionGetTestHistoryTool(server);\n registerSessionGetScoreHistoryTool(server);\n registerSessionCalculateCurrentScoreTool(server);\n\n // Batch Operations Tools\n registerSessionsCompareTool(server);\n registerSessionsAggregateTool(server);\n registerSessionsExportTool(server);\n\n // Note: Functional Testing Support Tools are internal only, not exposed as MCP tools\n\n logger.info('Registered monitoring and reporting tools');\n}\n\n/**\n * Session Management Tools\n */\n\n// session_start tool removed - sessions are now auto-created when needed\n// Sessions are automatically created when MCP tools are called with queryPath\n// If explicit session creation is needed, provide sessionId=null and it will auto-create\n\nfunction registerSessionEndTool(server: McpServer): void {\n server.tool(\n 'session_end',\n 'End a query development session with final status',\n {\n sessionId: z.string().describe('ID of the session to end'),\n status: z.enum(['completed', 'failed', 'abandoned']).describe('Final status of the session'),\n },\n async ({ sessionId, status }) => {\n try {\n const session = await sessionDataManager.endSession(sessionId, status);\n \n if (!session) {\n return {\n content: [\n {\n type: 'text',\n text: `Session not found: ${sessionId}`,\n },\n ],\n isError: true,\n };\n }\n\n return {\n content: [\n {\n type: 'text',\n text: JSON.stringify(session, null, 2),\n },\n ],\n };\n } catch (error) {\n logger.error('Error ending session:', error);\n return {\n content: [\n {\n type: 'text',\n text: `Error ending session: ${error instanceof Error ? error.message : 'Unknown error'}`,\n },\n ],\n isError: true,\n };\n }\n }\n );\n}\n\nfunction registerSessionGetTool(server: McpServer): void {\n server.tool(\n 'session_get',\n 'Get complete details of a specific query development session',\n {\n sessionId: z.string().describe('ID of the session to retrieve'),\n },\n async ({ sessionId }) => {\n try {\n const session = await sessionDataManager.getSession(sessionId);\n \n if (!session) {\n return {\n content: [\n {\n type: 'text',\n text: `Session not found: ${sessionId}`,\n },\n ],\n isError: true,\n };\n }\n\n return {\n content: [\n {\n type: 'text',\n text: JSON.stringify(session, null, 2),\n },\n ],\n };\n } catch (error) {\n logger.error('Error getting session:', error);\n return {\n content: [\n {\n type: 'text',\n text: `Error getting session: ${error instanceof Error ? error.message : 'Unknown error'}`,\n },\n ],\n isError: true,\n };\n }\n }\n );\n}\n\nfunction registerSessionListTool(server: McpServer): void {\n server.tool(\n 'session_list',\n 'List query development sessions with optional filtering',\n {\n queryPath: z.string().optional().describe('Filter by query path (partial match)'),\n status: z.string().optional().describe('Filter by session status'),\n dateRange: z.array(z.string()).length(2).optional().describe('Filter by date range [start, end] (ISO timestamps)'),\n language: z.string().optional().describe('Filter by programming language'),\n queryType: z.string().optional().describe('Filter by query type'),\n },\n async ({ queryPath, status, dateRange, language, queryType }) => {\n try {\n const filters: SessionFilter = {};\n if (queryPath) filters.queryPath = queryPath;\n if (status) filters.status = status;\n if (dateRange) filters.dateRange = [dateRange[0], dateRange[1]];\n if (language) filters.language = language;\n if (queryType) filters.queryType = queryType;\n\n const sessions = await sessionDataManager.listSessions(\n Object.keys(filters).length > 0 ? filters : undefined\n );\n\n const sessionList = {\n totalSessions: sessions.length,\n sessions: sessions.map(s => ({\n sessionId: s.sessionId,\n queryPath: s.queryPath,\n language: s.language,\n status: s.status,\n startTime: s.startTime,\n endTime: s.endTime,\n mcpCallsCount: s.mcpCalls.length,\n testExecutionsCount: s.testExecutions.length,\n currentScore: s.qualityScores.length > 0 \n ? s.qualityScores[s.qualityScores.length - 1].overallScore \n : null,\n })),\n };\n\n return {\n content: [\n {\n type: 'text',\n text: JSON.stringify(sessionList, null, 2),\n },\n ],\n recommendations: generateListRecommendations(sessions),\n };\n } catch (error) {\n logger.error('Error listing sessions:', error);\n return {\n content: [\n {\n type: 'text',\n text: `Error listing sessions: ${error instanceof Error ? error.message : 'Unknown error'}`,\n },\n ],\n isError: true,\n };\n }\n }\n );\n}\n\nfunction registerSessionUpdateStateTool(server: McpServer): void {\n server.tool(\n 'session_update_state',\n 'Update the current state of a query development session',\n {\n sessionId: z.string().describe('ID of the session to update'),\n filesPresent: z.array(z.string()).optional().describe('List of files present in the query development'),\n compilationStatus: z.enum(['unknown', 'success', 'failed']).optional().describe('Current compilation status'),\n testStatus: z.enum(['unknown', 'passing', 'failing', 'no_tests']).optional().describe('Current test status'),\n documentationStatus: z.enum(['unknown', 'present', 'missing', 'incomplete']).optional().describe('Documentation status'),\n },\n async ({ sessionId, filesPresent, compilationStatus, testStatus, documentationStatus }) => {\n try {\n const stateUpdate: Record = {};\n if (filesPresent !== undefined) stateUpdate.filesPresent = filesPresent;\n if (compilationStatus !== undefined) stateUpdate.compilationStatus = compilationStatus;\n if (testStatus !== undefined) stateUpdate.testStatus = testStatus;\n if (documentationStatus !== undefined) stateUpdate.documentationStatus = documentationStatus;\n\n const session = await sessionDataManager.updateSessionState(sessionId, stateUpdate);\n \n if (!session) {\n return {\n content: [\n {\n type: 'text',\n text: `Session not found: ${sessionId}`,\n },\n ],\n isError: true,\n };\n }\n\n return {\n content: [\n {\n type: 'text',\n text: JSON.stringify(session, null, 2),\n },\n ],\n recommendations: generateRecommendations(session, 'session_update_state'),\n };\n } catch (error) {\n logger.error('Error updating session state:', error);\n return {\n content: [\n {\n type: 'text',\n text: `Error updating session state: ${error instanceof Error ? error.message : 'Unknown error'}`,\n },\n ],\n isError: true,\n };\n }\n }\n );\n}\n\n/**\n * Session Analytics Tools\n */\n\nfunction registerSessionGetCallHistoryTool(server: McpServer): void {\n server.tool(\n 'session_get_call_history',\n 'Get MCP call history for a specific session',\n {\n sessionId: z.string().describe('ID of the session'),\n limit: z.number().optional().describe('Maximum number of calls to return (most recent first)'),\n },\n async ({ sessionId, limit }) => {\n try {\n const session = await sessionDataManager.getSession(sessionId);\n \n if (!session) {\n return {\n content: [\n {\n type: 'text',\n text: `Session not found: ${sessionId}`,\n },\n ],\n isError: true,\n };\n }\n\n let calls = [...session.mcpCalls].reverse(); // Most recent first\n if (limit && limit > 0) {\n calls = calls.slice(0, limit);\n }\n\n return {\n content: [\n {\n type: 'text',\n text: JSON.stringify({\n sessionId,\n totalCalls: session.mcpCalls.length,\n callHistory: calls,\n }, null, 2),\n },\n ],\n };\n } catch (error) {\n logger.error('Error getting call history:', error);\n return {\n content: [\n {\n type: 'text',\n text: `Error getting call history: ${error instanceof Error ? error.message : 'Unknown error'}`,\n },\n ],\n isError: true,\n };\n }\n }\n );\n}\n\nfunction registerSessionGetTestHistoryTool(server: McpServer): void {\n server.tool(\n 'session_get_test_history',\n 'Get test execution history for a specific session',\n {\n sessionId: z.string().describe('ID of the session'),\n limit: z.number().optional().describe('Maximum number of test executions to return (most recent first)'),\n },\n async ({ sessionId, limit }) => {\n try {\n const session = await sessionDataManager.getSession(sessionId);\n \n if (!session) {\n return {\n content: [\n {\n type: 'text',\n text: `Session not found: ${sessionId}`,\n },\n ],\n isError: true,\n };\n }\n\n let tests = [...session.testExecutions].reverse(); // Most recent first\n if (limit && limit > 0) {\n tests = tests.slice(0, limit);\n }\n\n return {\n content: [\n {\n type: 'text',\n text: JSON.stringify({\n sessionId,\n totalTests: session.testExecutions.length,\n testHistory: tests,\n }, null, 2),\n },\n ],\n };\n } catch (error) {\n logger.error('Error getting test history:', error);\n return {\n content: [\n {\n type: 'text',\n text: `Error getting test history: ${error instanceof Error ? error.message : 'Unknown error'}`,\n },\n ],\n isError: true,\n };\n }\n }\n );\n}\n\nfunction registerSessionGetScoreHistoryTool(server: McpServer): void {\n server.tool(\n 'session_get_score_history',\n 'Get quality score history for a specific session',\n {\n sessionId: z.string().describe('ID of the session'),\n limit: z.number().optional().describe('Maximum number of scores to return (most recent first)'),\n },\n async ({ sessionId, limit }) => {\n try {\n const session = await sessionDataManager.getSession(sessionId);\n \n if (!session) {\n return {\n content: [\n {\n type: 'text',\n text: `Session not found: ${sessionId}`,\n },\n ],\n isError: true,\n };\n }\n\n let scores = [...session.qualityScores].reverse(); // Most recent first\n if (limit && limit > 0) {\n scores = scores.slice(0, limit);\n }\n\n return {\n content: [\n {\n type: 'text',\n text: JSON.stringify({\n sessionId,\n totalScores: session.qualityScores.length,\n scoreHistory: scores,\n }, null, 2),\n },\n ],\n };\n } catch (error) {\n logger.error('Error getting score history:', error);\n return {\n content: [\n {\n type: 'text',\n text: `Error getting score history: ${error instanceof Error ? error.message : 'Unknown error'}`,\n },\n ],\n isError: true,\n };\n }\n }\n );\n}\n\nfunction registerSessionCalculateCurrentScoreTool(server: McpServer): void {\n server.tool(\n 'session_calculate_current_score',\n 'Calculate current quality score for a session based on its state',\n {\n sessionId: z.string().describe('ID of the session'),\n },\n async ({ sessionId }) => {\n try {\n const session = await sessionDataManager.getSession(sessionId);\n \n if (!session) {\n return {\n content: [\n {\n type: 'text',\n text: `Session not found: ${sessionId}`,\n },\n ],\n isError: true,\n };\n }\n\n // Calculate quality score based on current state\n const scoreRecord = calculateQualityScore(session);\n \n // Add the score to the session\n await sessionDataManager.addQualityScore(sessionId, scoreRecord);\n \n // Get updated session with new score\n const updatedSession = await sessionDataManager.getSession(sessionId);\n\n return {\n content: [\n {\n type: 'text',\n text: JSON.stringify(scoreRecord, null, 2),\n },\n ],\n recommendations: generateRecommendations(updatedSession, 'session_calculate_current_score'),\n };\n } catch (error) {\n logger.error('Error calculating current score:', error);\n return {\n content: [\n {\n type: 'text',\n text: `Error calculating current score: ${error instanceof Error ? error.message : 'Unknown error'}`,\n },\n ],\n isError: true,\n };\n }\n }\n );\n}\n\n/**\n * Batch Operations Tools\n */\n\nfunction registerSessionsCompareTool(server: McpServer): void {\n server.tool(\n 'sessions_compare',\n 'Compare multiple query development sessions across specified dimensions',\n {\n sessionIds: z.array(z.string()).describe('Array of session IDs to compare'),\n dimensions: z.array(z.string()).optional().describe('Specific dimensions to compare (default: all)'),\n },\n async ({ sessionIds, dimensions }) => {\n try {\n const sessions = await Promise.all(\n sessionIds.map(id => sessionDataManager.getSession(id))\n );\n\n const validSessions = sessions.filter(s => s !== null) as QueryDevelopmentSession[];\n \n if (validSessions.length === 0) {\n return {\n content: [\n {\n type: 'text',\n text: 'No valid sessions found for comparison',\n },\n ],\n isError: true,\n };\n }\n\n const comparison = await compareSessions(validSessions, dimensions);\n\n return {\n content: [\n {\n type: 'text',\n text: JSON.stringify(comparison, null, 2),\n },\n ],\n };\n } catch (error) {\n logger.error('Error comparing sessions:', error);\n return {\n content: [\n {\n type: 'text',\n text: `Error comparing sessions: ${error instanceof Error ? error.message : 'Unknown error'}`,\n },\n ],\n isError: true,\n };\n }\n }\n );\n}\n\nfunction registerSessionsAggregateTool(server: McpServer): void {\n server.tool(\n 'sessions_aggregate',\n 'Generate aggregate insights from multiple sessions based on filters',\n {\n queryPath: z.string().optional().describe('Filter by query path (partial match)'),\n status: z.string().optional().describe('Filter by session status'),\n dateRange: z.array(z.string()).length(2).optional().describe('Filter by date range [start, end] (ISO timestamps)'),\n language: z.string().optional().describe('Filter by programming language'),\n queryType: z.string().optional().describe('Filter by query type'),\n },\n async ({ queryPath, status, dateRange, language, queryType }) => {\n try {\n const filters: SessionFilter = {};\n if (queryPath) filters.queryPath = queryPath;\n if (status) filters.status = status;\n if (dateRange) filters.dateRange = [dateRange[0], dateRange[1]];\n if (language) filters.language = language;\n if (queryType) filters.queryType = queryType;\n\n const sessions = await sessionDataManager.listSessions(\n Object.keys(filters).length > 0 ? filters : undefined\n );\n\n const aggregate = await aggregateSessions(sessions, filters);\n\n return {\n content: [\n {\n type: 'text',\n text: JSON.stringify(aggregate, null, 2),\n },\n ],\n };\n } catch (error) {\n logger.error('Error aggregating sessions:', error);\n return {\n content: [\n {\n type: 'text',\n text: `Error aggregating sessions: ${error instanceof Error ? error.message : 'Unknown error'}`,\n },\n ],\n isError: true,\n };\n }\n }\n );\n}\n\nfunction registerSessionsExportTool(server: McpServer): void {\n server.tool(\n 'sessions_export',\n 'Export session data in specified format for external analysis',\n {\n sessionIds: z.array(z.string()).describe('Array of session IDs to export'),\n format: z.enum(['json', 'html', 'markdown']).optional().default('json').describe('Export format'),\n },\n async ({ sessionIds, format = 'json' }) => {\n try {\n const sessions = await Promise.all(\n sessionIds.map(id => sessionDataManager.getSession(id))\n );\n\n const validSessions = sessions.filter(s => s !== null) as QueryDevelopmentSession[];\n \n if (validSessions.length === 0) {\n return {\n content: [\n {\n type: 'text',\n text: 'No valid sessions found for export',\n },\n ],\n isError: true,\n };\n }\n\n const exportResult = await exportSessions(validSessions, format);\n\n return {\n content: [\n {\n type: 'text',\n text: JSON.stringify(exportResult, null, 2),\n },\n ],\n };\n } catch (error) {\n logger.error('Error exporting sessions:', error);\n return {\n content: [\n {\n type: 'text',\n text: `Error exporting sessions: ${error instanceof Error ? error.message : 'Unknown error'}`,\n },\n ],\n isError: true,\n };\n }\n }\n );\n}\n\n/**\n * Helper Functions\n */\n\n/**\n * Calculate quality score for a session based on current state and history\n */\nfunction calculateQualityScore(session: QueryDevelopmentSession): QualityScoreRecord {\n const timestamp = new Date().toISOString();\n \n // Calculate syntactic correctness (25%)\n const syntacticCorrectness = session.currentState.compilationStatus === 'success' ? 100 :\n session.currentState.compilationStatus === 'failed' ? 0 : 50;\n\n // Calculate test coverage and results (30%)\n const testCoverageResults = session.currentState.testStatus === 'passing' ? 100 :\n session.currentState.testStatus === 'failing' ? 25 :\n session.currentState.testStatus === 'no_tests' ? 0 : 50;\n\n // Calculate documentation quality (20%)\n const documentationQuality = session.currentState.documentationStatus === 'present' ? 100 :\n session.currentState.documentationStatus === 'incomplete' ? 60 :\n session.currentState.documentationStatus === 'missing' ? 0 : 50;\n\n // Calculate functional correctness (25%) - based on successful test runs\n const successfulTests = session.testExecutions.filter(t => t.success && t.type === 'test_run').length;\n const totalTests = session.testExecutions.filter(t => t.type === 'test_run').length;\n const functionalCorrectness = totalTests > 0 ? (successfulTests / totalTests) * 100 : 50;\n\n // Calculate overall score\n const overallScore = Math.round(\n (syntacticCorrectness * 0.25) +\n (testCoverageResults * 0.30) +\n (documentationQuality * 0.20) +\n (functionalCorrectness * 0.25)\n );\n\n // Determine grade\n const grade = overallScore >= 90 ? 'A' :\n overallScore >= 80 ? 'B' :\n overallScore >= 70 ? 'C' :\n overallScore >= 60 ? 'D' : 'F';\n\n // Generate recommendations\n const recommendations: string[] = [];\n if (syntacticCorrectness < 100) {\n recommendations.push('Fix compilation errors to improve syntactic correctness');\n }\n if (testCoverageResults < 70) {\n recommendations.push('Add comprehensive tests and ensure they pass');\n }\n if (documentationQuality < 80) {\n recommendations.push('Add or improve query documentation with examples');\n }\n if (functionalCorrectness < 80) {\n recommendations.push('Improve test pass rate and verify query logic');\n }\n\n return {\n scoreId: randomUUID(),\n timestamp,\n overallScore,\n dimensions: {\n syntacticCorrectness,\n testCoverageResults,\n documentationQuality,\n functionalCorrectness,\n },\n grade,\n recommendations,\n };\n}\n\n/**\n * Compare multiple sessions\n */\nasync function compareSessions(\n sessions: QueryDevelopmentSession[],\n dimensions?: string[]\n): Promise {\n const timestamp = new Date().toISOString();\n const sessionIds = sessions.map(s => s.sessionId);\n \n const results: Record = {\n sessionCount: sessions.length,\n sessionOverview: sessions.map(s => ({\n sessionId: s.sessionId,\n queryPath: s.queryPath,\n status: s.status,\n mcpCallsCount: s.mcpCalls.length,\n duration: s.endTime ? \n new Date(s.endTime).getTime() - new Date(s.startTime).getTime() : \n new Date().getTime() - new Date(s.startTime).getTime(),\n currentScore: s.qualityScores.length > 0 ? \n s.qualityScores[s.qualityScores.length - 1].overallScore : null,\n })),\n };\n\n if (!dimensions || dimensions.includes('quality')) {\n const qualityScores = sessions.map(s => \n s.qualityScores.length > 0 ? s.qualityScores[s.qualityScores.length - 1] : null\n );\n results.qualityComparison = {\n averageScore: qualityScores\n .filter(q => q !== null)\n .reduce((sum, q) => sum + q!.overallScore, 0) / qualityScores.filter(q => q !== null).length,\n scoreRange: {\n min: Math.min(...qualityScores.filter(q => q !== null).map(q => q!.overallScore)),\n max: Math.max(...qualityScores.filter(q => q !== null).map(q => q!.overallScore)),\n },\n };\n }\n\n if (!dimensions || dimensions.includes('activity')) {\n results.activityComparison = {\n totalMCPCalls: sessions.reduce((sum, s) => sum + s.mcpCalls.length, 0),\n averageCallsPerSession: sessions.reduce((sum, s) => sum + s.mcpCalls.length, 0) / sessions.length,\n mostActiveTool: getMostUsedTool(sessions),\n };\n }\n\n return {\n sessionIds,\n dimensions: dimensions || ['all'],\n timestamp,\n results,\n };\n}\n\n/**\n * Aggregate insights from multiple sessions\n */\nasync function aggregateSessions(\n sessions: QueryDevelopmentSession[],\n filters: SessionFilter\n): Promise {\n const timestamp = new Date().toISOString();\n \n const completedSessions = sessions.filter(s => s.status === 'completed');\n const successRate = sessions.length > 0 ? completedSessions.length / sessions.length : 0;\n \n const qualityScores = sessions\n .map(s => s.qualityScores.length > 0 ? s.qualityScores[s.qualityScores.length - 1].overallScore : null)\n .filter(score => score !== null) as number[];\n \n const averageQualityScore = qualityScores.length > 0 ? \n qualityScores.reduce((sum, score) => sum + score, 0) / qualityScores.length : 0;\n\n const commonPatterns = identifyCommonPatterns(sessions);\n const recommendations = generateAggregateRecommendations(sessions);\n\n return {\n filters,\n timestamp,\n totalSessions: sessions.length,\n successRate,\n averageQualityScore,\n commonPatterns,\n recommendations,\n };\n}\n\n/**\n * Export sessions in specified format\n */\nasync function exportSessions(\n sessions: QueryDevelopmentSession[],\n format: 'json' | 'html' | 'markdown'\n): Promise {\n const timestamp = new Date().toISOString();\n const filename = `session-export-${timestamp.replace(/[:.]/g, '-')}.${format}`;\n \n let content: string;\n \n switch (format) {\n case 'json':\n content = JSON.stringify(sessions, null, 2);\n break;\n case 'html':\n content = generateHTMLReport(sessions);\n break;\n case 'markdown':\n content = generateMarkdownReport(sessions);\n break;\n }\n\n return {\n format,\n filename,\n content,\n timestamp,\n };\n}\n\n/**\n * Utility functions\n */\n\nfunction getMostUsedTool(sessions: QueryDevelopmentSession[]): string {\n const toolCounts: Record = {};\n \n sessions.forEach(session => {\n session.mcpCalls.forEach(call => {\n toolCounts[call.toolName] = (toolCounts[call.toolName] || 0) + 1;\n });\n });\n\n return Object.entries(toolCounts)\n .sort(([, a], [, b]) => b - a)[0]?.[0] || 'none';\n}\n\nfunction identifyCommonPatterns(sessions: QueryDevelopmentSession[]): string[] {\n const patterns: string[] = [];\n \n const commonTools = getMostUsedTool(sessions);\n if (commonTools && commonTools !== 'none') {\n patterns.push(`Most commonly used tool: ${commonTools}`);\n }\n\n const completionRate = sessions.filter(s => s.status === 'completed').length / sessions.length;\n if (completionRate > 0.8) {\n patterns.push('High completion rate indicates effective workflow');\n } else if (completionRate < 0.5) {\n patterns.push('Low completion rate suggests workflow issues');\n }\n\n return patterns;\n}\n\nfunction generateAggregateRecommendations(sessions: QueryDevelopmentSession[]): string[] {\n const recommendations: string[] = [];\n \n const failedSessions = sessions.filter(s => s.status === 'failed');\n if (failedSessions.length > sessions.length * 0.3) {\n recommendations.push('High failure rate - consider improving error handling and guidance');\n }\n\n const averageCallsPerSession = sessions.reduce((sum, s) => sum + s.mcpCalls.length, 0) / sessions.length;\n if (averageCallsPerSession > 20) {\n recommendations.push('High number of MCP calls per session - consider workflow optimization');\n }\n\n return recommendations;\n}\n\nfunction generateHTMLReport(sessions: QueryDevelopmentSession[]): string {\n const html = `\n\n\n\n Session Export Report\n \n\n\n

Query Development Sessions Report

\n

Generated: ${new Date().toISOString()}

\n

Total Sessions: ${sessions.length}

\n \n ${sessions.map(session => `\n
\n

Session: ${session.sessionId}

\n

Query Path: ${session.queryPath}

\n

Status: ${session.status}

\n

Language: ${session.language}

\n

Start Time: ${session.startTime}

\n

MCP Calls: ${session.mcpCalls.length}

\n

Test Executions: ${session.testExecutions.length}

\n

Quality Scores: ${session.qualityScores.length}

\n
\n `).join('')}\n\n`;\n \n return html;\n}\n\nfunction generateMarkdownReport(sessions: QueryDevelopmentSession[]): string {\n const md = `# Query Development Sessions Report\n\nGenerated: ${new Date().toISOString()}\nTotal Sessions: ${sessions.length}\n\n## Session Summary\n\n| Session ID | Query Path | Status | Language | MCP Calls | Test Executions |\n|------------|-----------|--------|----------|-----------|-----------------|\n${sessions.map(session => \n `| ${session.sessionId} | ${session.queryPath} | ${session.status} | ${session.language} | ${session.mcpCalls.length} | ${session.testExecutions.length} |`\n).join('\\n')}\n\n## Detailed Sessions\n\n${sessions.map(session => `\n### Session: ${session.sessionId}\n\n- **Query Path:** ${session.queryPath}\n- **Status:** ${session.status}\n- **Language:** ${session.language}\n- **Start Time:** ${session.startTime}\n- **End Time:** ${session.endTime || 'N/A'}\n- **MCP Calls:** ${session.mcpCalls.length}\n- **Test Executions:** ${session.testExecutions.length}\n- **Quality Scores:** ${session.qualityScores.length}\n\n${session.recommendations.length > 0 ? `\n**Current Recommendations:**\n${session.recommendations.map(rec => `- ${rec}`).join('\\n')}\n` : ''}\n`).join('\\n')}`;\n\n return md;\n}\n\nfunction _calculateAverageDuration(sessions: QueryDevelopmentSession[]): number {\n const completedSessions = sessions.filter(s => s.endTime);\n if (completedSessions.length === 0) return 0;\n\n const totalDuration = completedSessions.reduce((sum, session) => {\n return sum + (new Date(session.endTime!).getTime() - new Date(session.startTime).getTime());\n }, 0);\n\n return totalDuration / completedSessions.length;\n}\n\nfunction _identifyFailureReasons(results: FunctionalTestResult[]): string[] {\n const failedResults = results.filter(r => !r.passed);\n const reasons: Record = {};\n\n failedResults.forEach(result => {\n Object.entries(result.criteria).forEach(([criterion, passed]) => {\n if (!passed) {\n reasons[criterion] = (reasons[criterion] || 0) + 1;\n }\n });\n });\n\n return Object.entries(reasons)\n .sort(([, a], [, b]) => b - a)\n .map(([reason, count]) => `${reason}: ${count} sessions`);\n}\n\n/**\n * Generate recommendations for MCP tool responses\n * Returns a map of MCP primitive paths to recommendation reasons\n */\nfunction generateRecommendations(\n session: QueryDevelopmentSession | null,\n currentTool: string\n): Record {\n if (!session) {\n return {};\n }\n\n const recommendations: Record = {};\n\n // Session state-based recommendations\n if (session.currentState.compilationStatus === 'failed') {\n recommendations['codeql_query_format'] = 'Format query to fix potential syntax issues';\n recommendations['codeql_query_compile'] = 'Recompile after fixing syntax errors';\n } else if (session.currentState.compilationStatus === 'success') {\n if (session.currentState.testStatus === 'unknown' || session.currentState.testStatus === 'no_tests') {\n recommendations['codeql_test_run'] = 'Run tests to validate query functionality';\n } else if (session.currentState.testStatus === 'failing') {\n recommendations['session_get_test_history'] = 'Review test failures to identify issues';\n recommendations['codeql_query_compile'] = 'Verify query logic matches test expectations';\n } else if (session.currentState.testStatus === 'passing') {\n recommendations['session_calculate_current_score'] = 'Calculate quality score for completed query';\n }\n }\n\n // Tool-specific follow-up recommendations\n switch (currentTool) {\n case 'session_get':\n if (session.mcpCalls.length === 0) {\n recommendations['codeql_query_compile'] = 'Start development by compiling the query';\n }\n break;\n case 'session_end':\n if (session.status === 'completed') {\n recommendations['sessions_export'] = 'Export session data for analysis';\n }\n break;\n case 'session_calculate_current_score': {\n const latestScore = session.qualityScores[session.qualityScores.length - 1];\n if (latestScore && latestScore.overallScore < 80) {\n if (latestScore.dimensions.syntacticCorrectness < 100) {\n recommendations['codeql_query_format'] = 'Improve syntax and formatting';\n }\n if (latestScore.dimensions.testCoverageResults < 70) {\n recommendations['codeql_test_run'] = 'Improve test coverage and results';\n }\n }\n break;\n }\n case 'session_update_state':\n // Recommend next logical step based on updated state\n if (session.currentState.compilationStatus === 'success' && session.currentState.testStatus === 'unknown') {\n recommendations['codeql_test_run'] = 'Run tests now that compilation is successful';\n }\n break;\n }\n\n return recommendations;\n}\n\n/**\n * Generate recommendations for session list results\n */\nfunction generateListRecommendations(sessions: QueryDevelopmentSession[]): Record {\n const recommendations: Record = {};\n\n const activeSessions = sessions.filter(s => s.status === 'active');\n const completedSessions = sessions.filter(s => s.status === 'completed');\n\n if (activeSessions.length > 0) {\n recommendations['session_get'] = `Review details of ${activeSessions.length} active session(s)`;\n }\n\n if (completedSessions.length > 1) {\n recommendations['sessions_compare'] = 'Compare completed sessions to identify patterns';\n recommendations['sessions_aggregate'] = 'Generate aggregate insights from multiple sessions';\n }\n\n if (sessions.length > 5) {\n recommendations['sessions_export'] = 'Export session data for comprehensive analysis';\n }\n\n return recommendations;\n}", "function checkArgs(adapter, defaultData) {\n if (adapter === undefined)\n throw new Error('lowdb: missing adapter');\n if (defaultData === undefined)\n throw new Error('lowdb: missing default data');\n}\nexport class Low {\n adapter;\n data;\n constructor(adapter, defaultData) {\n checkArgs(adapter, defaultData);\n this.adapter = adapter;\n this.data = defaultData;\n }\n async read() {\n const data = await this.adapter.read();\n if (data)\n this.data = data;\n }\n async write() {\n if (this.data)\n await this.adapter.write(this.data);\n }\n async update(fn) {\n fn(this.data);\n await this.write();\n }\n}\nexport class LowSync {\n adapter;\n data;\n constructor(adapter, defaultData) {\n checkArgs(adapter, defaultData);\n this.adapter = adapter;\n this.data = defaultData;\n }\n read() {\n const data = this.adapter.read();\n if (data)\n this.data = data;\n }\n write() {\n if (this.data)\n this.adapter.write(this.data);\n }\n update(fn) {\n fn(this.data);\n this.write();\n }\n}\n", "import { readFileSync, renameSync, writeFileSync } from 'node:fs';\nimport { readFile } from 'node:fs/promises';\nimport path from 'node:path';\nimport { Writer } from 'steno';\nexport class TextFile {\n #filename;\n #writer;\n constructor(filename) {\n this.#filename = filename;\n this.#writer = new Writer(filename);\n }\n async read() {\n let data;\n try {\n data = await readFile(this.#filename, 'utf-8');\n }\n catch (e) {\n if (e.code === 'ENOENT') {\n return null;\n }\n throw e;\n }\n return data;\n }\n write(str) {\n return this.#writer.write(str);\n }\n}\nexport class TextFileSync {\n #tempFilename;\n #filename;\n constructor(filename) {\n this.#filename = filename;\n const f = filename.toString();\n this.#tempFilename = path.join(path.dirname(f), `.${path.basename(f)}.tmp`);\n }\n read() {\n let data;\n try {\n data = readFileSync(this.#filename, 'utf-8');\n }\n catch (e) {\n if (e.code === 'ENOENT') {\n return null;\n }\n throw e;\n }\n return data;\n }\n write(str) {\n writeFileSync(this.#tempFilename, str);\n renameSync(this.#tempFilename, this.#filename);\n }\n}\n", "import { TextFile, TextFileSync } from './TextFile.js';\nexport class DataFile {\n #adapter;\n #parse;\n #stringify;\n constructor(filename, { parse, stringify, }) {\n this.#adapter = new TextFile(filename);\n this.#parse = parse;\n this.#stringify = stringify;\n }\n async read() {\n const data = await this.#adapter.read();\n if (data === null) {\n return null;\n }\n else {\n return this.#parse(data);\n }\n }\n write(obj) {\n return this.#adapter.write(this.#stringify(obj));\n }\n}\nexport class DataFileSync {\n #adapter;\n #parse;\n #stringify;\n constructor(filename, { parse, stringify, }) {\n this.#adapter = new TextFileSync(filename);\n this.#parse = parse;\n this.#stringify = stringify;\n }\n read() {\n const data = this.#adapter.read();\n if (data === null) {\n return null;\n }\n else {\n return this.#parse(data);\n }\n }\n write(obj) {\n this.#adapter.write(this.#stringify(obj));\n }\n}\n", "import { DataFile, DataFileSync } from './DataFile.js';\nexport class JSONFile extends DataFile {\n constructor(filename) {\n super(filename, {\n parse: JSON.parse,\n stringify: (data) => JSON.stringify(data, null, 2),\n });\n }\n}\nexport class JSONFileSync extends DataFileSync {\n constructor(filename) {\n super(filename, {\n parse: JSON.parse,\n stringify: (data) => JSON.stringify(data, null, 2),\n });\n }\n}\n", "/**\n * Session Data Management\n * Provides unified JSON storage and session lifecycle management using lowdb\n */\n\nimport { Low } from 'lowdb';\nimport { JSONFileSync } from 'lowdb/node';\nimport { mkdirSync, writeFileSync } from 'fs';\nimport { join } from 'path';\nimport { randomUUID } from 'crypto';\nimport { getProjectTmpBase } from '../utils/temp-dir';\nimport {\n QueryDevelopmentSession,\n QueryState,\n MCPCallRecord,\n TestExecutionRecord,\n QualityScoreRecord,\n SessionFilter,\n MonitoringConfig,\n MonitoringConfigSchema,\n} from '../types/monitoring';\nimport { logger } from '../utils/logger';\n\n/**\n * Database schema for lowdb - sessions only\n */\ninterface SessionDatabase {\n sessions: QueryDevelopmentSession[];\n}\n\n/**\n * Session Data Manager - handles all session persistence and lifecycle\n */\nexport class SessionDataManager {\n private db: Low;\n private config: MonitoringConfig;\n private storageDir: string;\n\n constructor(configOverrides: Partial = {}) {\n this.config = MonitoringConfigSchema.parse({\n ...MonitoringConfigSchema.parse({}),\n ...configOverrides,\n });\n\n this.storageDir = this.config.storageLocation;\n this.ensureStorageDirectory();\n\n const adapter = new JSONFileSync(join(this.storageDir, 'sessions.json'));\n this.db = new Low(adapter, {\n sessions: [],\n });\n\n this.initializeDatabase();\n }\n\n /**\n * Initialize the database and ensure it's properly set up\n */\n async initialize(): Promise {\n await this.initializeDatabase();\n }\n\n /**\n * Initialize the database and ensure it's properly set up\n */\n private async initializeDatabase(): Promise {\n try {\n await this.db.read();\n \n logger.info(`Session data manager initialized with ${this.db.data.sessions.length} sessions`);\n } catch (error) {\n logger.error('Failed to initialize session database:', error);\n throw error;\n }\n }\n\n /**\n * Ensure storage directory structure exists\n */\n private ensureStorageDirectory(): void {\n try {\n // mkdirSync with recursive: true is a no-op if directories already exist\n mkdirSync(this.storageDir, { recursive: true });\n\n // Create subdirectories\n const subdirs = ['sessions-archive', 'exports'];\n for (const subdir of subdirs) {\n mkdirSync(join(this.storageDir, subdir), { recursive: true });\n }\n\n // Use 'wx' flag (exclusive create) to atomically create config only\n // if it doesn't exist, avoiding TOCTOU race (CWE-367).\n const configPath = join(this.storageDir, 'config.json');\n try {\n writeFileSync(configPath, JSON.stringify(this.config, null, 2), { flag: 'wx' });\n } catch (e: unknown) {\n const err = e as { code?: string };\n if (err.code !== 'EEXIST') throw e;\n }\n\n logger.debug(`Storage directory initialized: ${this.storageDir}`);\n } catch (error) {\n logger.error('Failed to create storage directory:', error);\n throw error;\n }\n }\n\n /**\n * Start a new query development session\n */\n async startSession(\n queryPath: string,\n language?: string,\n queryType?: string,\n description?: string\n ): Promise {\n const sessionId = randomUUID();\n const startTime = new Date().toISOString();\n\n const session: QueryDevelopmentSession = {\n sessionId,\n queryPath,\n language: language || 'unknown',\n queryType,\n description,\n startTime,\n status: 'active',\n mcpCalls: [],\n testExecutions: [],\n qualityScores: [],\n currentState: {\n filesPresent: [],\n compilationStatus: 'unknown',\n testStatus: 'unknown',\n documentationStatus: 'unknown',\n lastActivity: startTime,\n },\n recommendations: [],\n };\n\n await this.db.read();\n this.db.data.sessions.push(session);\n await this.db.write();\n\n logger.info(`Started new session: ${sessionId} for query: ${queryPath}`);\n return sessionId;\n }\n\n /**\n * End a session with final status\n */\n async endSession(\n sessionId: string,\n status: 'completed' | 'failed' | 'abandoned'\n ): Promise {\n await this.db.read();\n \n const session = this.db.data.sessions.find(s => s.sessionId === sessionId);\n if (!session) {\n logger.warn(`Session not found: ${sessionId}`);\n return null;\n }\n\n session.status = status;\n session.endTime = new Date().toISOString();\n session.currentState.lastActivity = session.endTime;\n\n await this.db.write();\n\n // Archive completed session if enabled\n if (this.config.archiveCompletedSessions && status === 'completed') {\n await this.archiveSession(sessionId);\n }\n\n logger.info(`Ended session: ${sessionId} with status: ${status}`);\n return session;\n }\n\n /**\n * Get a specific session by ID\n */\n async getSession(sessionId: string): Promise {\n await this.db.read();\n const session = this.db.data.sessions.find(s => s.sessionId === sessionId);\n return session || null;\n }\n\n /**\n * List sessions with optional filtering\n */\n async listSessions(filters?: SessionFilter): Promise {\n await this.db.read();\n let sessions = [...this.db.data.sessions];\n\n if (filters) {\n if (filters.queryPath) {\n sessions = sessions.filter(s => s.queryPath.includes(filters.queryPath!));\n }\n if (filters.status) {\n sessions = sessions.filter(s => s.status === filters.status);\n }\n if (filters.language) {\n sessions = sessions.filter(s => s.language === filters.language);\n }\n if (filters.queryType) {\n sessions = sessions.filter(s => s.queryType === filters.queryType);\n }\n if (filters.dateRange) {\n const [start, end] = filters.dateRange;\n sessions = sessions.filter(s => \n s.startTime >= start && s.startTime <= end\n );\n }\n }\n\n return sessions;\n }\n\n /**\n * Update session state\n */\n async updateSessionState(\n sessionId: string,\n stateUpdate: Partial\n ): Promise {\n await this.db.read();\n \n const session = this.db.data.sessions.find(s => s.sessionId === sessionId);\n if (!session) {\n logger.warn(`Session not found: ${sessionId}`);\n return null;\n }\n\n session.currentState = {\n ...session.currentState,\n ...stateUpdate,\n lastActivity: new Date().toISOString(),\n };\n\n await this.db.write();\n return session;\n }\n\n /**\n * Add MCP call record to session\n */\n async addMCPCall(sessionId: string, callRecord: MCPCallRecord): Promise {\n await this.db.read();\n \n const session = this.db.data.sessions.find(s => s.sessionId === sessionId);\n if (!session) {\n logger.warn(`Session not found for MCP call: ${sessionId}`);\n return;\n }\n\n session.mcpCalls.push(callRecord);\n session.currentState.lastActivity = callRecord.timestamp;\n\n // Update next suggested tool if provided\n if (callRecord.nextSuggestedTool) {\n session.nextSuggestedTool = callRecord.nextSuggestedTool;\n }\n\n await this.db.write();\n }\n\n /**\n * Add test execution record to session\n */\n async addTestExecution(sessionId: string, testRecord: TestExecutionRecord): Promise {\n await this.db.read();\n \n const session = this.db.data.sessions.find(s => s.sessionId === sessionId);\n if (!session) {\n logger.warn(`Session not found for test execution: ${sessionId}`);\n return;\n }\n\n session.testExecutions.push(testRecord);\n session.currentState.lastActivity = testRecord.timestamp;\n\n // Update compilation/test status based on execution\n if (testRecord.type === 'compilation') {\n session.currentState.compilationStatus = testRecord.success ? 'success' : 'failed';\n } else if (testRecord.type === 'test_run') {\n session.currentState.testStatus = testRecord.success ? 'passing' : 'failing';\n }\n\n await this.db.write();\n }\n\n /**\n * Add quality score record to session\n */\n async addQualityScore(sessionId: string, scoreRecord: QualityScoreRecord): Promise {\n await this.db.read();\n \n const session = this.db.data.sessions.find(s => s.sessionId === sessionId);\n if (!session) {\n logger.warn(`Session not found for quality score: ${sessionId}`);\n return;\n }\n\n session.qualityScores.push(scoreRecord);\n session.currentState.lastActivity = scoreRecord.timestamp;\n session.recommendations = scoreRecord.recommendations;\n\n await this.db.write();\n }\n\n /**\n * Archive a completed session to monthly file\n */\n private async archiveSession(sessionId: string): Promise {\n try {\n const session = await this.getSession(sessionId);\n if (!session) return;\n\n const date = new Date(session.endTime || session.startTime);\n const monthDir = `${date.getFullYear()}-${String(date.getMonth() + 1).padStart(2, '0')}`;\n const archiveDir = join(this.storageDir, 'sessions-archive', monthDir);\n\n mkdirSync(archiveDir, { recursive: true });\n\n const archiveFile = join(archiveDir, `${sessionId}.json`);\n writeFileSync(archiveFile, JSON.stringify(session, null, 2));\n\n // Remove from active sessions\n await this.db.read();\n this.db.data.sessions = this.db.data.sessions.filter(s => s.sessionId !== sessionId);\n await this.db.write();\n\n logger.info(`Archived session: ${sessionId} to ${archiveFile}`);\n } catch (error) {\n logger.error(`Failed to archive session ${sessionId}:`, error);\n }\n }\n\n /**\n * Get active sessions for a specific query path\n */\n async getActiveSessionsForQuery(queryPath: string): Promise {\n await this.db.read();\n return this.db.data.sessions.filter(s => \n s.queryPath === queryPath && s.status === 'active'\n );\n }\n\n /**\n * Clean up old sessions based on retention policy\n */\n async cleanupOldSessions(): Promise {\n const cutoffDate = new Date();\n cutoffDate.setDate(cutoffDate.getDate() - this.config.retentionDays);\n const cutoffTimestamp = cutoffDate.toISOString();\n\n await this.db.read();\n const sessionsToRemove = this.db.data.sessions.filter(s => \n s.endTime && s.endTime < cutoffTimestamp\n );\n\n if (sessionsToRemove.length > 0) {\n this.db.data.sessions = this.db.data.sessions.filter(s => \n !s.endTime || s.endTime >= cutoffTimestamp\n );\n await this.db.write();\n\n logger.info(`Cleaned up ${sessionsToRemove.length} old sessions`);\n }\n }\n\n /**\n * Get configuration\n */\n getConfig(): MonitoringConfig {\n return this.config;\n }\n\n /**\n * Update configuration\n */\n async updateConfig(configUpdate: Partial): Promise {\n this.config = MonitoringConfigSchema.parse({\n ...this.config,\n ...configUpdate,\n });\n\n // Update config.json file only\n const configPath = join(this.storageDir, 'config.json');\n writeFileSync(configPath, JSON.stringify(this.config, null, 2));\n\n logger.info('Updated monitoring configuration');\n }\n}\n\n/**\n * Parse boolean environment variable\n */\nfunction parseBoolEnv(envVar: string | undefined, defaultValue: boolean): boolean {\n if (envVar === undefined) return defaultValue;\n return envVar.toLowerCase() === 'true' || envVar === '1';\n}\n\n// Export singleton instance with environment variable support\nexport const sessionDataManager = new SessionDataManager({\n storageLocation: process.env.MONITORING_STORAGE_LOCATION || join(getProjectTmpBase(), '.ql-mcp-tracking'),\n enableMonitoringTools: parseBoolEnv(process.env.ENABLE_MONITORING_TOOLS, false),\n});", "import { z } from 'zod';\n\n/**\n * Monitoring and Reporting types for CodeQL Development MCP Server\n * Based on the specification in docs/mcp-server-monitoring-and-reporting.md\n */\n\n/**\n * MCP Call Record - captures individual MCP tool calls\n */\nexport const MCPCallRecordSchema = z.object({\n callId: z.string(),\n timestamp: z.string(), // ISO timestamp\n toolName: z.string(),\n parameters: z.record(z.any()),\n result: z.any(),\n success: z.boolean(),\n duration: z.number(), // milliseconds\n nextSuggestedTool: z.string().optional(),\n});\n\nexport type MCPCallRecord = z.infer;\n\n/**\n * Test Execution Record - captures query compilation and test runs\n */\nexport const TestExecutionRecordSchema = z.object({\n executionId: z.string(),\n timestamp: z.string(),\n type: z.enum(['compilation', 'test_run', 'database_build']),\n success: z.boolean(),\n details: z.record(z.any()),\n metrics: z.object({\n passRate: z.number().optional(),\n coverage: z.number().optional(),\n performance: z.number().optional(),\n }).optional(),\n});\n\nexport type TestExecutionRecord = z.infer;\n\n/**\n * Quality Score Record - multi-dimensional quality assessment\n */\nexport const QualityScoreRecordSchema = z.object({\n scoreId: z.string(),\n timestamp: z.string(),\n overallScore: z.number().min(0).max(100), // 0-100\n dimensions: z.object({\n syntacticCorrectness: z.number().min(0).max(100),\n testCoverageResults: z.number().min(0).max(100),\n documentationQuality: z.number().min(0).max(100),\n functionalCorrectness: z.number().min(0).max(100),\n }),\n grade: z.enum(['A', 'B', 'C', 'D', 'F']),\n recommendations: z.array(z.string()),\n});\n\nexport type QualityScoreRecord = z.infer;\n\n/**\n * Query State - current state of the query development\n */\nexport const QueryStateSchema = z.object({\n filesPresent: z.array(z.string()),\n compilationStatus: z.enum(['unknown', 'success', 'failed']),\n testStatus: z.enum(['unknown', 'passing', 'failing', 'no_tests']),\n documentationStatus: z.enum(['unknown', 'present', 'missing', 'incomplete']),\n lastActivity: z.string(), // ISO timestamp\n});\n\nexport type QueryState = z.infer;\n\n/**\n * Query Development Session - main data structure for tracking\n */\nexport const QueryDevelopmentSessionSchema = z.object({\n // Session Metadata\n sessionId: z.string(),\n queryPath: z.string(),\n language: z.string(),\n queryType: z.string().optional(),\n description: z.string().optional(),\n startTime: z.string(), // ISO timestamp\n endTime: z.string().optional(), // ISO timestamp\n status: z.enum(['active', 'completed', 'failed', 'abandoned']),\n\n // MCP Call History\n mcpCalls: z.array(MCPCallRecordSchema),\n\n // Test Execution Records\n testExecutions: z.array(TestExecutionRecordSchema),\n\n // Quality Metrics\n qualityScores: z.array(QualityScoreRecordSchema),\n\n // Development State\n currentState: QueryStateSchema,\n recommendations: z.array(z.string()),\n nextSuggestedTool: z.string().optional(),\n});\n\nexport type QueryDevelopmentSession = z.infer;\n\n/**\n * Session Filter for listing and searching\n */\nexport const SessionFilterSchema = z.object({\n queryPath: z.string().optional(),\n status: z.string().optional(),\n dateRange: z.tuple([z.string(), z.string()]).optional(),\n language: z.string().optional(),\n queryType: z.string().optional(),\n});\n\nexport type SessionFilter = z.infer;\n\n/**\n * Comparison Report for analyzing multiple sessions\n */\nexport const ComparisonReportSchema = z.object({\n sessionIds: z.array(z.string()),\n dimensions: z.array(z.string()),\n timestamp: z.string(),\n results: z.record(z.any()),\n});\n\nexport type ComparisonReport = z.infer;\n\n/**\n * Aggregate Report for batch analysis\n */\nexport const AggregateReportSchema = z.object({\n filters: SessionFilterSchema,\n timestamp: z.string(),\n totalSessions: z.number(),\n successRate: z.number(),\n averageQualityScore: z.number(),\n commonPatterns: z.array(z.string()),\n recommendations: z.array(z.string()),\n});\n\nexport type AggregateReport = z.infer;\n\n/**\n * Export Result for data export operations\n */\nexport const ExportResultSchema = z.object({\n format: z.enum(['json', 'html', 'markdown']),\n filename: z.string(),\n content: z.string(),\n timestamp: z.string(),\n});\n\nexport type ExportResult = z.infer;\n\n/**\n * Functional Test Result for automated testing\n */\nexport const FunctionalTestResultSchema = z.object({\n sessionId: z.string(),\n queryPath: z.string(),\n passed: z.boolean(),\n criteria: z.record(z.any()),\n details: z.record(z.any()),\n timestamp: z.string(),\n});\n\nexport type FunctionalTestResult = z.infer;\n\n/**\n * Test Report for comprehensive test analysis\n */\nexport const TestReportSchema = z.object({\n sessionIds: z.array(z.string()),\n criteria: z.record(z.any()),\n timestamp: z.string(),\n overallPassRate: z.number(),\n results: z.array(FunctionalTestResultSchema),\n summary: z.record(z.any()),\n});\n\nexport type TestReport = z.infer;\n\n/**\n * Monitoring Configuration\n */\nexport const MonitoringConfigSchema = z.object({\n storageLocation: z.string().default('.ql-mcp-tracking/'),\n autoTrackSessions: z.boolean().default(true),\n retentionDays: z.number().default(90),\n includeCallParameters: z.boolean().default(true),\n includeCallResults: z.boolean().default(true),\n maxActiveSessionsPerQuery: z.number().default(3),\n scoringFrequency: z.enum(['per_call', 'periodic', 'manual']).default('per_call'),\n archiveCompletedSessions: z.boolean().default(true),\n enableRecommendations: z.boolean().default(true),\n enableMonitoringTools: z.boolean().default(false), // Opt-in: session_* tools disabled by default for end-users\n});\n\nexport type MonitoringConfig = z.infer;"], - "mappings": "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", + "sourcesContent": ["/**\n * Simple logger utility.\n *\n * All log output is written to stderr. In stdio transport mode, stdout is\n * reserved exclusively for the MCP JSON-RPC protocol \u2014 any non-protocol\n * bytes on stdout would corrupt the message stream.\n */\nexport const logger = {\n info: (message: string, ...args: unknown[]) => {\n console.error(`[INFO] ${new Date().toISOString()} ${message}`, ...args);\n },\n error: (message: string, ...args: unknown[]) => {\n console.error(`[ERROR] ${new Date().toISOString()} ${message}`, ...args);\n },\n warn: (message: string, ...args: unknown[]) => {\n console.error(`[WARN] ${new Date().toISOString()} ${message}`, ...args);\n },\n debug: (message: string, ...args: unknown[]) => {\n if (process.env.DEBUG) {\n console.error(`[DEBUG] ${new Date().toISOString()} ${message}`, ...args);\n }\n },\n};\n", "/**\n * Configuration types for CodeQL background server processes.\n *\n * CodeQL provides three background server types:\n * 1. language-server \u2013 LSP-based QL validation (JSON-RPC over stdio)\n * 2. query-server2 \u2013 Query evaluation (custom protocol over stdio)\n * 3. cli-server \u2013 JVM reuse for CLI commands (custom protocol over stdio)\n *\n * Each server type has its own configuration options, but they share common\n * settings like searchPath and commonCaches.\n */\n\nimport { createHash } from 'crypto';\n\n/**\n * Server types supported by CodeQL.\n */\nexport type CodeQLServerType = 'cli' | 'language' | 'query';\n\n/**\n * Common configuration shared across all server types.\n */\nexport interface BaseServerConfig {\n /** Path to QL packs (like `codeql query compile --search-path`). */\n searchPath?: string;\n /** Location for cached data (compilation plans, downloaded packs). */\n commonCaches?: string;\n /** Directory for detailed logs. */\n logdir?: string;\n}\n\n/**\n * Configuration for the CodeQL Language Server.\n */\nexport interface LanguageServerConfig extends BaseServerConfig {\n /** Error checking mode. Default: ON_CHANGE */\n checkErrors?: 'EXPLICIT' | 'ON_CHANGE';\n /** Log level for the language server. */\n loglevel?: 'ALL' | 'DEBUG' | 'ERROR' | 'INFO' | 'OFF' | 'TRACE' | 'WARN';\n /** Single-threaded execution. */\n synchronous?: boolean;\n /** Verbosity level for progress. */\n verbosity?: 'errors' | 'progress' | 'progress+' | 'progress++' | 'progress+++' | 'warnings';\n}\n\n/**\n * Configuration for the CodeQL Query Server (query-server2).\n */\nexport interface QueryServerConfig extends BaseServerConfig {\n /** Thread count. 0 = one per core, -N = leave N cores free. */\n threads?: number;\n /** Query evaluation timeout in seconds. */\n timeout?: number;\n /** Maximum disk cache size in MB for intermediate results. */\n maxDiskCache?: number;\n /** Path for structured evaluator performance logs. */\n evaluatorLog?: string;\n /** Include tuple counts in evaluation logs. */\n tupleCounting?: boolean;\n /** Enable debug mode. */\n debug?: boolean;\n}\n\n/**\n * Configuration for the CodeQL CLI Server.\n */\nexport interface CLIServerConfig extends BaseServerConfig {\n // cli-server has fewer options \u2014 just commonCaches and logdir.\n}\n\n/**\n * Union of all server configurations (discriminated by usage context).\n */\nexport type ServerConfig = CLIServerConfig | LanguageServerConfig | QueryServerConfig;\n\n/**\n * Compute a deterministic hash for a server configuration.\n * Used to detect configuration changes that require a server restart.\n *\n * @param type - The server type.\n * @param config - The server configuration.\n * @returns A hex-encoded SHA-256 hash of the canonical JSON representation.\n */\nexport function computeConfigHash(type: CodeQLServerType, config: ServerConfig): string {\n // Deep-sort all keys to ensure deterministic serialization regardless of\n // property insertion order.\n const sortKeys = (_key: string, value: unknown): unknown => {\n if (value && typeof value === 'object' && !Array.isArray(value)) {\n const sorted: Record = {};\n for (const k of Object.keys(value as Record).sort()) {\n sorted[k] = (value as Record)[k];\n }\n return sorted;\n }\n return value;\n };\n const canonical = JSON.stringify({ config, type }, sortKeys);\n return createHash('sha256').update(canonical).digest('hex');\n}\n\n/**\n * Build command-line arguments for a language server from its configuration.\n */\nexport function buildLanguageServerArgs(config: LanguageServerConfig): string[] {\n const args: string[] = [\n 'execute', 'language-server',\n `--check-errors=${config.checkErrors ?? 'ON_CHANGE'}`,\n ];\n\n if (config.searchPath) {\n args.push(`--search-path=${config.searchPath}`);\n }\n if (config.commonCaches) {\n args.push(`--common-caches=${config.commonCaches}`);\n }\n if (config.logdir) {\n args.push(`--logdir=${config.logdir}`);\n }\n if (config.loglevel) {\n args.push(`--loglevel=${config.loglevel}`);\n }\n if (config.synchronous) {\n args.push('--synchronous');\n }\n if (config.verbosity) {\n args.push(`--verbosity=${config.verbosity}`);\n }\n\n return args;\n}\n\n/**\n * Build command-line arguments for a query server from its configuration.\n */\nexport function buildQueryServerArgs(config: QueryServerConfig): string[] {\n const args: string[] = [\n 'execute', 'query-server2',\n ];\n\n if (config.searchPath) {\n args.push(`--search-path=${config.searchPath}`);\n }\n if (config.commonCaches) {\n args.push(`--common-caches=${config.commonCaches}`);\n }\n if (config.logdir) {\n args.push(`--logdir=${config.logdir}`);\n }\n if (config.threads !== undefined) {\n args.push(`--threads=${config.threads}`);\n }\n if (config.timeout !== undefined) {\n args.push(`--timeout=${config.timeout}`);\n }\n if (config.maxDiskCache !== undefined) {\n args.push(`--max-disk-cache=${config.maxDiskCache}`);\n }\n if (config.evaluatorLog) {\n args.push(`--evaluator-log=${config.evaluatorLog}`);\n }\n if (config.debug) {\n args.push('--debug');\n args.push('--tuple-counting');\n } else if (config.tupleCounting) {\n args.push('--tuple-counting');\n }\n\n return args;\n}\n\n/**\n * Build command-line arguments for a CLI server from its configuration.\n */\nexport function buildCLIServerArgs(config: CLIServerConfig): string[] {\n const args: string[] = [\n 'execute', 'cli-server',\n ];\n\n if (config.commonCaches) {\n args.push(`--common-caches=${config.commonCaches}`);\n }\n if (config.logdir) {\n args.push(`--logdir=${config.logdir}`);\n }\n\n return args;\n}\n", "/**\n * Utilities for resolving filesystem paths relative to the server package root.\n *\n * The server can run from three different directory layouts:\n *\n * 1. **Source** (dev): `server/src/lib/` \u2192 packageRoot = `server/`\n * 2. **Bundle in monorepo** (dev/CI): `server/dist/` \u2192 packageRoot = `server/`\n * 3. **Bundle via npm** (production): `/dist/` \u2192 packageRoot = `/`\n *\n * In all three cases, the bundled QL tool query packs live at\n * `/ql//tools/src/`.\n *\n * The \"workspace root\" (monorepo root) is one level above packageRoot when\n * running from the monorepo checkout, and the packageRoot itself when running\n * from an npm install (no parent monorepo).\n */\n\nimport { dirname, resolve } from 'path';\nimport { existsSync, readFileSync } from 'fs';\nimport { fileURLToPath } from 'url';\n\nconst __filename = fileURLToPath(import.meta.url);\nconst __dirname = dirname(__filename);\n\n/**\n * Detect whether the current __dirname looks like source code (`src/lib` or\n * `src/utils`) vs a bundled flat output directory (`dist/`).\n *\n * Uses a tail-of-path check so that unrelated `/src/` segments earlier in the\n * install path (e.g. `~/src/project/node_modules/.../dist`) don't cause a\n * false positive.\n */\nfunction isRunningFromSource(dir: string): boolean {\n const normalized = dir.replace(/\\\\/g, '/');\n return /\\/src(\\/[^/]+)?$/.test(normalized);\n}\n\n/**\n * Get the server package root directory.\n *\n * - From source (`server/src/utils/`): up 2 levels \u2192 `server/`\n * - From bundle (`server/dist/` or `/dist/`): up 1 level \u2192 package root\n */\nexport function getPackageRootDir(currentDir: string = __dirname): string {\n return isRunningFromSource(currentDir)\n ? resolve(currentDir, '..', '..') // src/utils \u2192 server/\n : resolve(currentDir, '..'); // dist/ \u2192 package root\n}\n\n/**\n * Get the workspace root directory (monorepo root when applicable).\n *\n * If a `package.json` with `workspaces` exists one level above the package\n * root, we're in a monorepo and that parent is the workspace root. Otherwise,\n * the packageRoot itself is the workspace root (npm install scenario).\n */\nexport function getWorkspaceRootDir(packageRoot?: string): string {\n const pkgRoot = packageRoot ?? getPackageRootDir();\n const parentDir = resolve(pkgRoot, '..');\n\n // In the monorepo, the parent directory contains a package.json with workspaces\n try {\n const parentPkgPath = resolve(parentDir, 'package.json');\n if (existsSync(parentPkgPath)) {\n const parentPkg = JSON.parse(readFileSync(parentPkgPath, 'utf8'));\n if (parentPkg.workspaces) {\n return parentDir;\n }\n }\n } catch {\n // Not in a monorepo \u2014 fall through\n }\n\n return pkgRoot;\n}\n\n/**\n * Resolve the path to a tool query pack's source directory.\n *\n * @param language - CodeQL language identifier (e.g., \"javascript\", \"cpp\")\n * @param packageRoot - Override the package root (for testing)\n * @returns Absolute path to `ql//tools/src/`\n */\nexport function resolveToolQueryPackPath(language: string, packageRoot?: string): string {\n const pkgRoot = packageRoot ?? getPackageRootDir();\n return resolve(pkgRoot, 'ql', language, 'tools', 'src');\n}\n\n/**\n * Read the package version from the nearest package.json.\n *\n * Cached at first call so the file is read at most once per process.\n */\nlet _cachedVersion: string | undefined;\nexport function getPackageVersion(): string {\n if (_cachedVersion !== undefined) return _cachedVersion;\n try {\n const pkgPath = resolve(getPackageRootDir(), 'package.json');\n const pkg = JSON.parse(readFileSync(pkgPath, 'utf8'));\n _cachedVersion = pkg.version ?? '0.0.0';\n } catch {\n _cachedVersion = '0.0.0';\n }\n return _cachedVersion as string;\n}\n\n/**\n * Get the effective workspace directory for resolving user-supplied relative\n * paths (test directories, database paths, pack dirs, etc.).\n *\n * In a monorepo checkout the workspace root is the monorepo parent. In an\n * npm-installed layout, `workspaceRootDir` falls back to `packageRootDir`\n * which may be read-only and is not the user's project. In that case we\n * fall back to `process.cwd()` so that relative paths resolve against the\n * directory the user actually invoked the server from.\n *\n * Override with `CODEQL_MCP_WORKSPACE` for deterministic behavior.\n */\nexport function getUserWorkspaceDir(): string {\n if (process.env.CODEQL_MCP_WORKSPACE) {\n return process.env.CODEQL_MCP_WORKSPACE;\n }\n // When workspaceRootDir === packageRootDir we are NOT in a monorepo\n // (npm-installed), so fall back to process.cwd().\n if (workspaceRootDir === packageRootDir) {\n return process.cwd();\n }\n return workspaceRootDir;\n}\n\n// Pre-computed values for use throughout the server\nexport const packageRootDir = getPackageRootDir();\nexport const workspaceRootDir = getWorkspaceRootDir(packageRootDir);\n", "/**\n * Secure project-local temporary directory utilities.\n *\n * All temporary files are created under `/.tmp/` which is\n * `.gitignore`d. This avoids writing to the OS temp directory\n * (`os.tmpdir()` / `/tmp`), which is world-readable and triggers\n * CWE-377 / CWE-378 (js/insecure-temporary-file).\n */\n\nimport { mkdirSync, mkdtempSync } from 'fs';\nimport { isAbsolute, join, resolve } from 'path';\nimport { getPackageRootDir } from './package-paths';\n\n/**\n * Base directory for all project-local temporary data.\n *\n * Resolution order:\n * 1. `CODEQL_MCP_TMP_DIR` environment variable \u2014 for read-only package root\n * scenarios (e.g., npm global installs where the package directory is not\n * writable). Relative paths are resolved against process.cwd().\n * 2. `/.tmp` \u2014 default; excluded from version control.\n */\nconst PROJECT_TMP_BASE = process.env.CODEQL_MCP_TMP_DIR\n ? (isAbsolute(process.env.CODEQL_MCP_TMP_DIR) \n ? process.env.CODEQL_MCP_TMP_DIR \n : resolve(process.cwd(), process.env.CODEQL_MCP_TMP_DIR))\n : join(getPackageRootDir(), '.tmp');\n\n/**\n * Return the project-local `.tmp` base directory, creating it if needed.\n */\nexport function getProjectTmpBase(): string {\n mkdirSync(PROJECT_TMP_BASE, { recursive: true });\n return PROJECT_TMP_BASE;\n}\n\n/**\n * Create a unique temporary directory under the project `.tmp` root.\n *\n * Works identically to `fs.mkdtempSync(os.tmpdir(), prefix)` but is\n * scoped to the repository.\n *\n * @param prefix - Directory name prefix (e.g. `'codeql-external-'`).\n * @returns Absolute path to the newly created directory.\n */\nexport function createProjectTempDir(prefix: string): string {\n const base = getProjectTmpBase();\n return mkdtempSync(join(base, prefix));\n}\n\n/**\n * Return a deterministic subdirectory under `.tmp/`, creating it\n * if it does not already exist.\n *\n * Useful for well-known scratch areas such as `query-logs` or `quickeval`.\n *\n * @param name - Subdirectory name (e.g. `'query-logs'`).\n * @returns Absolute path to the subdirectory.\n */\nexport function getProjectTmpDir(name: string): string {\n const dir = join(getProjectTmpBase(), name);\n mkdirSync(dir, { recursive: true });\n return dir;\n}\n", "/**\n * Utility for waiting until a spawned child process is ready.\n *\n * CodeQL background servers (cli-server, query-server2, language-server) run\n * on the JVM and emit stderr log output once the JVM has initialised. Rather\n * than sleeping for a hard-coded duration \u2014 which is fragile on both fast and\n * slow machines \u2014 this helper resolves as soon as the first stderr output\n * arrives (indicating the JVM is alive), or when the maximum timeout expires.\n * It also rejects immediately if the process exits or errors before becoming\n * ready, giving callers a clear error instead of a silent hang.\n */\n\nimport { ChildProcess } from 'child_process';\nimport { clearTimeout, setTimeout } from 'timers';\nimport { logger } from './logger';\n\n/** Default maximum wait for a CodeQL server to become ready (30 s). */\nconst DEFAULT_READY_TIMEOUT_MS = 30_000;\n\n/**\n * Options for {@link waitForProcessReady}.\n */\nexport interface ProcessReadyOptions {\n /**\n * Maximum time in milliseconds to wait for the process to emit its first\n * stderr output. If the timeout is reached without a signal the promise\n * still resolves (best-effort) so the caller can attempt communication.\n *\n * Default: 30 000 ms.\n */\n timeoutMs?: number;\n}\n\n/**\n * Wait until a child process signals readiness.\n *\n * \"Ready\" is defined as any of:\n * 1. The process emits data on **stderr** (JVM startup log line).\n * 2. The process emits data on **stdout** (initial protocol message).\n * 3. The maximum timeout elapses (best-effort resolve).\n *\n * The promise **rejects** if the process emits an `error` event or exits\n * before any of the above conditions are met.\n *\n * @param child - The spawned child process.\n * @param name - A human-readable label for log messages.\n * @param opts - Optional configuration.\n */\nexport function waitForProcessReady(\n child: ChildProcess,\n name: string,\n opts?: ProcessReadyOptions,\n): Promise {\n const timeoutMs = opts?.timeoutMs ?? DEFAULT_READY_TIMEOUT_MS;\n\n return new Promise((resolve, reject) => {\n let settled = false;\n\n const cleanup = () => {\n settled = true;\n child.stderr?.removeListener('data', onStderr);\n child.stdout?.removeListener('data', onStdout);\n child.removeListener('error', onError);\n child.removeListener('exit', onExit);\n clearTimeout(timer);\n };\n\n const onStderr = () => {\n if (settled) return;\n logger.debug(`${name}: ready (stderr output detected)`);\n cleanup();\n resolve();\n };\n\n const onStdout = () => {\n if (settled) return;\n logger.debug(`${name}: ready (stdout output detected)`);\n cleanup();\n resolve();\n };\n\n const onError = (error: Error) => {\n if (settled) return;\n cleanup();\n reject(new Error(`${name} failed to start: ${error.message}`));\n };\n\n const onExit = (code: number | null) => {\n if (settled) return;\n cleanup();\n reject(new Error(`${name} exited before becoming ready (code: ${code})`));\n };\n\n const timer = setTimeout(() => {\n if (settled) return;\n logger.warn(`${name}: readiness timeout (${timeoutMs} ms) \u2014 proceeding anyway`);\n cleanup();\n resolve(); // best-effort: let the caller attempt communication\n }, timeoutMs);\n\n child.stderr?.on('data', onStderr);\n child.stdout?.on('data', onStdout);\n child.on('error', onError);\n child.on('exit', onExit);\n\n // If the process was dead before we even attached listeners, reject now\n if (child.killed || child.exitCode !== null) {\n cleanup();\n reject(new Error(`${name} is not running (exitCode: ${child.exitCode})`));\n }\n });\n}\n", "/**\n * CodeQL Language Server manager for LSP communication\n * Manages the lifecycle and communication with the CodeQL language server process\n */\n\nimport { spawn, ChildProcess } from 'child_process';\nimport { EventEmitter } from 'events';\nimport { setTimeout, clearTimeout } from 'timers';\nimport { pathToFileURL } from 'url';\nimport { delimiter, join } from 'path';\nimport { logger } from '../utils/logger';\nimport { getPackageVersion } from '../utils/package-paths';\nimport { getProjectTmpDir } from '../utils/temp-dir';\nimport { getResolvedCodeQLDir } from './cli-executor';\nimport { waitForProcessReady } from '../utils/process-ready';\n\nexport interface LSPMessage {\n jsonrpc: '2.0';\n id?: number | string;\n method: string;\n params?: unknown;\n result?: unknown;\n error?: {\n code: number;\n message: string;\n data?: unknown;\n };\n}\n\nexport interface Diagnostic {\n range: {\n start: { line: number; character: number };\n end: { line: number; character: number };\n };\n severity: number; // 1=Error, 2=Warning, 3=Information, 4=Hint\n source?: string;\n message: string;\n code?: string | number;\n}\n\nexport interface PublishDiagnosticsParams {\n uri: string;\n diagnostics: Diagnostic[];\n}\n\nexport interface LanguageServerOptions {\n searchPath?: string;\n logdir?: string;\n loglevel?: 'ALL' | 'DEBUG' | 'ERROR' | 'INFO' | 'OFF' | 'TRACE' | 'WARN';\n synchronous?: boolean;\n verbosity?: 'errors' | 'progress' | 'progress+' | 'progress++' | 'progress+++' | 'warnings';\n}\n\n/**\n * Position in a text document (0-based line and character).\n */\nexport interface LSPPosition {\n character: number;\n line: number;\n}\n\n/**\n * A range in a text document.\n */\nexport interface LSPRange {\n end: LSPPosition;\n start: LSPPosition;\n}\n\n/**\n * A location in a resource (file URI + range).\n */\nexport interface LSPLocation {\n range: LSPRange;\n uri: string;\n}\n\n/**\n * Identifies a text document by its URI.\n */\nexport interface TextDocumentIdentifier {\n uri: string;\n}\n\n/**\n * A text document position (document + position within it).\n */\nexport interface TextDocumentPositionParams {\n position: LSPPosition;\n textDocument: TextDocumentIdentifier;\n}\n\n/**\n * A completion item returned by the language server.\n */\nexport interface CompletionItem {\n detail?: string;\n documentation?: string | { kind: string; value: string };\n insertText?: string;\n kind?: number;\n label: string;\n sortText?: string;\n}\n\nexport class CodeQLLanguageServer extends EventEmitter {\n private server: ChildProcess | null = null;\n private messageId = 1;\n private pendingResponses = new Map void; reject: (_error: Error) => void }>();\n private isInitialized = false;\n private currentWorkspaceUri: string | undefined;\n private messageBuffer = '';\n\n constructor(private _options: LanguageServerOptions = {}) {\n super();\n }\n\n async start(): Promise {\n if (this.server) {\n throw new Error('Language server is already running');\n }\n\n logger.info('Starting CodeQL Language Server...');\n\n const args = [\n 'execute', 'language-server',\n '--check-errors=ON_CHANGE'\n ];\n\n // Add optional arguments\n if (this._options.searchPath) {\n args.push(`--search-path=${this._options.searchPath}`);\n }\n if (this._options.logdir) {\n args.push(`--logdir=${this._options.logdir}`);\n }\n if (this._options.loglevel) {\n args.push(`--loglevel=${this._options.loglevel}`);\n }\n if (this._options.synchronous) {\n args.push('--synchronous');\n }\n if (this._options.verbosity) {\n args.push(`--verbosity=${this._options.verbosity}`);\n }\n\n // Build environment with CODEQL_PATH directory prepended to PATH\n // (mirrors the approach in cli-executor.ts getSafeEnvironment).\n const spawnEnv = { ...process.env };\n const codeqlDir = getResolvedCodeQLDir();\n if (codeqlDir && spawnEnv.PATH) {\n spawnEnv.PATH = `${codeqlDir}${delimiter}${spawnEnv.PATH}`;\n } else if (codeqlDir) {\n spawnEnv.PATH = codeqlDir;\n }\n\n this.server = spawn('codeql', args, {\n stdio: ['pipe', 'pipe', 'pipe'],\n env: spawnEnv\n });\n\n this.server.stderr?.on('data', (data) => {\n logger.debug('CodeQL LS stderr:', data.toString());\n });\n\n this.server.stdout?.on('data', (data) => {\n this.handleStdout(data);\n });\n\n this.server.on('error', (error) => {\n logger.error('CodeQL Language Server error:', error);\n this.emit('error', error);\n });\n\n this.server.on('exit', (code) => {\n logger.info('CodeQL Language Server exited with code:', code);\n this.server = null;\n this.isInitialized = false;\n this.emit('exit', code);\n });\n\n // Wait for the JVM to initialise (resolves on first stderr/stdout output)\n await waitForProcessReady(this.server, 'CodeQL Language Server');\n }\n\n private handleStdout(data: Buffer): void {\n this.messageBuffer += data.toString();\n \n let headerEnd = this.messageBuffer.indexOf('\\r\\n\\r\\n');\n while (headerEnd !== -1) {\n const header = this.messageBuffer.substring(0, headerEnd);\n const contentLengthMatch = header.match(/Content-Length: (\\d+)/);\n \n if (contentLengthMatch) {\n const contentLength = parseInt(contentLengthMatch[1]);\n const messageStart = headerEnd + 4;\n const messageEnd = messageStart + contentLength;\n \n if (this.messageBuffer.length >= messageEnd) {\n const messageContent = this.messageBuffer.substring(messageStart, messageEnd);\n this.messageBuffer = this.messageBuffer.substring(messageEnd);\n \n try {\n const message: LSPMessage = JSON.parse(messageContent);\n this.handleMessage(message);\n } catch (error) {\n logger.error('Failed to parse LSP message:', error, messageContent);\n }\n \n headerEnd = this.messageBuffer.indexOf('\\r\\n\\r\\n');\n } else {\n break;\n }\n } else {\n logger.error('Invalid LSP header:', header);\n this.messageBuffer = '';\n break;\n }\n }\n }\n\n private handleMessage(message: LSPMessage): void {\n logger.debug('Received LSP message:', message);\n\n // Handle responses to our requests\n if (message.id !== undefined && this.pendingResponses.has(Number(message.id))) {\n const pending = this.pendingResponses.get(Number(message.id))!;\n this.pendingResponses.delete(Number(message.id));\n \n if (message.error) {\n pending.reject(new Error(`LSP Error: ${message.error.message}`));\n } else {\n pending.resolve(message.result);\n }\n return;\n }\n\n // Handle notifications from server\n if (message.method === 'textDocument/publishDiagnostics') {\n this.emit('diagnostics', message.params as PublishDiagnosticsParams);\n }\n }\n\n private sendMessage(message: LSPMessage): void {\n if (!this.server?.stdin) {\n throw new Error('Language server is not running');\n }\n\n const messageStr = JSON.stringify(message);\n const contentLength = Buffer.byteLength(messageStr, 'utf8');\n const header = `Content-Length: ${contentLength}\\r\\n\\r\\n`;\n const fullMessage = header + messageStr;\n\n logger.debug('Sending LSP message:', fullMessage);\n this.server.stdin.write(fullMessage);\n }\n\n private sendRequest(method: string, params?: unknown): Promise {\n const id = this.messageId++;\n const message: LSPMessage = {\n jsonrpc: '2.0',\n id,\n method,\n params\n };\n\n return new Promise((resolve, reject) => {\n // Wrap resolve/reject to clear the timer when the promise settles.\n const timer = setTimeout(() => {\n if (this.pendingResponses.has(id)) {\n this.pendingResponses.delete(id);\n reject(new Error(`LSP request timeout for method: ${method}`));\n }\n }, 60_000); // 60 second timeout (Windows CI cold JVM can exceed 30s)\n\n this.pendingResponses.set(id, {\n reject: (err: Error) => { clearTimeout(timer); reject(err); },\n resolve: (val: unknown) => { clearTimeout(timer); resolve(val); },\n });\n this.sendMessage(message);\n });\n }\n\n private sendNotification(method: string, params?: unknown): void {\n const message: LSPMessage = {\n jsonrpc: '2.0',\n method,\n params\n };\n this.sendMessage(message);\n }\n\n /**\n * Initialize the language server with an optional workspace URI.\n *\n * If the server is already initialized with a different workspace, a\n * `workspace/didChangeWorkspaceFolders` notification is sent to update\n * the workspace context instead of requiring a full restart.\n */\n async initialize(workspaceUri?: string): Promise {\n if (this.isInitialized) {\n // If workspace changed, notify the server\n if (workspaceUri && workspaceUri !== this.currentWorkspaceUri) {\n await this.updateWorkspace(workspaceUri);\n }\n return;\n }\n\n logger.info('Initializing CodeQL Language Server...');\n\n const initParams = {\n processId: process.pid,\n clientInfo: {\n name: 'codeql-development-mcp-server',\n version: getPackageVersion()\n },\n capabilities: {\n textDocument: {\n completion: { completionItem: { snippetSupport: false } },\n definition: {},\n publishDiagnostics: {},\n references: {},\n synchronization: {\n didClose: true,\n didChange: true,\n didOpen: true,\n },\n },\n workspace: {\n workspaceFolders: true,\n },\n }\n };\n\n if (workspaceUri) {\n (initParams as unknown as { workspaceFolders: unknown[] }).workspaceFolders = [{\n uri: workspaceUri,\n name: 'codeql-workspace'\n }];\n }\n\n await this.sendRequest('initialize', initParams);\n this.sendNotification('initialized', {});\n\n this.currentWorkspaceUri = workspaceUri;\n this.isInitialized = true;\n logger.info('CodeQL Language Server initialized successfully');\n }\n\n /**\n * Update the workspace folders on a running, initialized server.\n */\n private async updateWorkspace(newUri: string): Promise {\n logger.info(`Updating workspace from ${this.currentWorkspaceUri} to ${newUri}`);\n\n const removed = this.currentWorkspaceUri\n ? [{ uri: this.currentWorkspaceUri, name: 'codeql-workspace' }]\n : [];\n\n this.sendNotification('workspace/didChangeWorkspaceFolders', {\n event: {\n added: [{ uri: newUri, name: 'codeql-workspace' }],\n removed,\n },\n });\n\n this.currentWorkspaceUri = newUri;\n }\n\n /**\n * Get the current workspace URI.\n */\n getWorkspaceUri(): string | undefined {\n return this.currentWorkspaceUri;\n }\n\n async evaluateQL(qlCode: string, uri?: string): Promise {\n if (!this.isInitialized) {\n throw new Error('Language server is not initialized');\n }\n\n // Default to a project-local virtual URI rather than /tmp\n const documentUri = uri || pathToFileURL(join(getProjectTmpDir('lsp-eval'), 'eval.ql')).href;\n\n return new Promise((resolve, reject) => {\n let diagnosticsReceived = false;\n const timeout = setTimeout(() => {\n if (!diagnosticsReceived) {\n this.removeListener('diagnostics', diagnosticsHandler);\n reject(new Error('Timeout waiting for diagnostics'));\n }\n }, 90_000); // 90s \u2014 first call triggers JVM start + compilation; Windows CI is slow\n\n // Listen for diagnostics\n const diagnosticsHandler = (params: PublishDiagnosticsParams) => {\n if (params.uri === documentUri) {\n diagnosticsReceived = true;\n clearTimeout(timeout);\n this.removeListener('diagnostics', diagnosticsHandler);\n\n // Close the document\n this.sendNotification('textDocument/didClose', {\n textDocument: { uri: documentUri }\n });\n\n resolve(params.diagnostics);\n }\n };\n\n this.on('diagnostics', diagnosticsHandler);\n\n // Open the document with the QL code\n this.sendNotification('textDocument/didOpen', {\n textDocument: {\n uri: documentUri,\n languageId: 'ql',\n version: 1,\n text: qlCode\n }\n });\n });\n }\n\n // ---- LSP feature methods (issue #1) ----\n\n /**\n * Get code completions at a position in a document.\n */\n async getCompletions(params: TextDocumentPositionParams): Promise {\n if (!this.isInitialized) {\n throw new Error('Language server is not initialized');\n }\n if (!this.isRunning()) {\n throw new Error('Language server process is not running');\n }\n const result = await this.sendRequest('textDocument/completion', params);\n // The result may be a CompletionList or CompletionItem[]\n if (result && typeof result === 'object' && 'items' in (result as object)) {\n return (result as { items: CompletionItem[] }).items;\n }\n return (result as CompletionItem[]) || [];\n }\n\n /**\n * Find the definition(s) of a symbol at a position.\n */\n async getDefinition(params: TextDocumentPositionParams): Promise {\n if (!this.isInitialized) {\n throw new Error('Language server is not initialized');\n }\n if (!this.isRunning()) {\n throw new Error('Language server process is not running');\n }\n const result = await this.sendRequest('textDocument/definition', params);\n return this.normalizeLocations(result);\n }\n\n /**\n * Find all references to a symbol at a position.\n */\n async getReferences(params: TextDocumentPositionParams & { context?: { includeDeclaration: boolean } }): Promise {\n if (!this.isInitialized) {\n throw new Error('Language server is not initialized');\n }\n if (!this.isRunning()) {\n throw new Error('Language server process is not running');\n }\n const result = await this.sendRequest('textDocument/references', {\n ...params,\n context: params.context ?? { includeDeclaration: true },\n });\n return this.normalizeLocations(result);\n }\n\n /**\n * Open a text document in the language server.\n * The document must be opened before requesting completions, definitions, etc.\n */\n openDocument(uri: string, text: string, languageId = 'ql', version = 1): void {\n if (!this.isInitialized) {\n throw new Error('Language server is not initialized');\n }\n this.sendNotification('textDocument/didOpen', {\n textDocument: { uri, languageId, version, text },\n });\n }\n\n /**\n * Close a text document in the language server.\n */\n closeDocument(uri: string): void {\n if (!this.isInitialized) {\n throw new Error('Language server is not initialized');\n }\n this.sendNotification('textDocument/didClose', {\n textDocument: { uri },\n });\n }\n\n /**\n * Normalize a definition/references/implementation result to Location[].\n * The LSP spec allows Location | Location[] | LocationLink[].\n */\n private normalizeLocations(result: unknown): LSPLocation[] {\n if (!result) return [];\n if (Array.isArray(result)) {\n return result.map((item) => {\n // LocationLink has targetUri/targetRange\n if ('targetUri' in item) {\n return { uri: item.targetUri, range: item.targetRange } as LSPLocation;\n }\n return item as LSPLocation;\n });\n }\n // Single Location\n if (typeof result === 'object' && 'uri' in (result as object)) {\n return [result as LSPLocation];\n }\n return [];\n }\n\n async shutdown(): Promise {\n if (!this.server) {\n return;\n }\n\n logger.info('Shutting down CodeQL Language Server...');\n\n try {\n await this.sendRequest('shutdown', {});\n if (this.server) {\n this.sendNotification('exit', {});\n }\n } catch (error) {\n logger.warn('Error during graceful shutdown:', error);\n }\n\n // Force kill if needed\n await new Promise((resolve) => {\n const timer = setTimeout(() => {\n if (this.server) {\n this.server.kill('SIGTERM');\n }\n resolve();\n }, 1000);\n\n if (this.server) {\n this.server.once('exit', () => {\n clearTimeout(timer);\n this.server = null;\n resolve();\n });\n } else {\n clearTimeout(timer);\n resolve();\n }\n });\n\n this.isInitialized = false;\n }\n\n isRunning(): boolean {\n return this.server !== null && !this.server.killed;\n }\n}", "/**\n * CodeQL Query Server (query-server2) client.\n *\n * Manages a long-lived `codeql execute query-server2` process that evaluates\n * queries using a custom JSON-RPC protocol over stdio. Reusing the server\n * avoids repeated JVM startup for each query evaluation.\n *\n * Protocol: The query-server2 uses JSON-RPC with Content-Length headers\n * (same framing as LSP) over stdin/stdout.\n */\n\nimport { ChildProcess, spawn } from 'child_process';\nimport { delimiter } from 'path';\nimport { EventEmitter } from 'events';\nimport { clearTimeout, setTimeout } from 'timers';\nimport { buildQueryServerArgs, QueryServerConfig } from './server-config';\nimport { getResolvedCodeQLDir } from './cli-executor';\nimport { logger } from '../utils/logger';\nimport { waitForProcessReady } from '../utils/process-ready';\n\n/**\n * A pending request awaiting a response from the query server.\n */\ninterface PendingRequest {\n reject: (_error: Error) => void;\n resolve: (_value: unknown) => void;\n}\n\n/**\n * Client for the CodeQL query-server2 process.\n *\n * Spawns `codeql execute query-server2` and communicates over stdin/stdout\n * using JSON-RPC with Content-Length framing.\n */\nexport class CodeQLQueryServer extends EventEmitter {\n private messageBuffer = '';\n private messageId = 1;\n private pendingRequests = new Map();\n private process: ChildProcess | null = null;\n private readonly config: QueryServerConfig;\n\n constructor(config: QueryServerConfig) {\n super();\n this.config = config;\n }\n\n /**\n * Start the query-server2 process.\n */\n async start(): Promise {\n if (this.process) {\n throw new Error('Query server is already running');\n }\n\n logger.info('Starting CodeQL Query Server (query-server2)...');\n\n const args = buildQueryServerArgs(this.config);\n\n // Build environment with CODEQL_PATH directory prepended to PATH\n const spawnEnv = { ...process.env };\n const codeqlDir = getResolvedCodeQLDir();\n if (codeqlDir && spawnEnv.PATH) {\n spawnEnv.PATH = `${codeqlDir}${delimiter}${spawnEnv.PATH}`;\n } else if (codeqlDir) {\n spawnEnv.PATH = codeqlDir;\n }\n\n this.process = spawn('codeql', args, {\n stdio: ['pipe', 'pipe', 'pipe'],\n env: spawnEnv,\n });\n\n this.process.stderr?.on('data', (data: Buffer) => {\n logger.debug('QueryServer2 stderr:', data.toString());\n });\n\n this.process.stdout?.on('data', (data: Buffer) => {\n this.handleStdout(data);\n });\n\n this.process.on('error', (error: Error) => {\n logger.error('Query server process error:', error);\n this.emit('error', error);\n });\n\n this.process.on('exit', (code: number | null) => {\n logger.info(`Query server exited with code: ${code}`);\n this.rejectAllPending(new Error(`Query server exited with code: ${code}`));\n this.process = null;\n this.emit('exit', code);\n });\n\n // Wait for the JVM to initialise (resolves on first stderr/stdout output)\n await waitForProcessReady(this.process, 'CodeQL Query Server');\n logger.info('CodeQL Query Server started');\n }\n\n /**\n * Send a request to the query server and await the response.\n *\n * @param method - The JSON-RPC method name.\n * @param params - The method parameters.\n * @param timeoutMs - Request timeout in milliseconds (default: 300000 = 5 min).\n * @returns The result from the server.\n */\n sendRequest(method: string, params?: unknown, timeoutMs = 300_000): Promise {\n const id = this.messageId++;\n const message = {\n id,\n jsonrpc: '2.0' as const,\n method,\n params,\n };\n\n return new Promise((resolve, reject) => {\n this.pendingRequests.set(id, { reject, resolve });\n\n try {\n this.sendRaw(message);\n } catch (error) {\n // Clean up immediately \u2014 sendRaw() failed so no response will arrive.\n this.pendingRequests.delete(id);\n reject(error instanceof Error ? error : new Error(String(error)));\n return;\n }\n\n const timer = setTimeout(() => {\n if (this.pendingRequests.has(id)) {\n this.pendingRequests.delete(id);\n reject(new Error(`Query server request timeout for method: ${method}`));\n }\n }, timeoutMs);\n\n // Clear the timeout when the promise settles\n const originalResolve = resolve;\n const originalReject = reject;\n const wrapped = {\n reject: (err: Error) => { clearTimeout(timer); originalReject(err); },\n resolve: (val: unknown) => { clearTimeout(timer); originalResolve(val); },\n };\n this.pendingRequests.set(id, wrapped);\n });\n }\n\n /**\n * Gracefully shut down the query server.\n */\n async shutdown(): Promise {\n if (!this.process) {\n return;\n }\n\n logger.info('Shutting down CodeQL Query Server...');\n\n try {\n await this.sendRequest('shutdown', {}, 5000);\n } catch (error) {\n logger.warn('Error during query server graceful shutdown:', error);\n }\n\n // Force kill if process lingers\n await new Promise((resolve) => {\n const timer = setTimeout(() => {\n if (this.process) {\n this.process.kill('SIGTERM');\n this.process = null;\n }\n resolve();\n }, 2000);\n\n if (this.process) {\n this.process.once('exit', () => {\n clearTimeout(timer);\n this.process = null;\n resolve();\n });\n } else {\n clearTimeout(timer);\n resolve();\n }\n });\n }\n\n /**\n * Whether the query server process is running.\n */\n isRunning(): boolean {\n return this.process !== null && !this.process.killed;\n }\n\n // ---- private helpers ----\n\n private handleStdout(data: Buffer): void {\n this.messageBuffer += data.toString();\n\n let headerEnd = this.messageBuffer.indexOf('\\r\\n\\r\\n');\n while (headerEnd !== -1) {\n const header = this.messageBuffer.substring(0, headerEnd);\n const contentLengthMatch = header.match(/Content-Length: (\\d+)/);\n\n if (contentLengthMatch) {\n const contentLength = parseInt(contentLengthMatch[1]);\n const messageStart = headerEnd + 4;\n const messageEnd = messageStart + contentLength;\n\n if (this.messageBuffer.length >= messageEnd) {\n const messageContent = this.messageBuffer.substring(messageStart, messageEnd);\n this.messageBuffer = this.messageBuffer.substring(messageEnd);\n\n try {\n const message = JSON.parse(messageContent);\n this.handleMessage(message);\n } catch (error) {\n logger.error('Failed to parse query server message:', error);\n }\n\n headerEnd = this.messageBuffer.indexOf('\\r\\n\\r\\n');\n } else {\n break;\n }\n } else {\n logger.error('Invalid query server header:', header);\n this.messageBuffer = '';\n break;\n }\n }\n }\n\n private handleMessage(message: { error?: { message: string }; id?: number; method?: string; params?: unknown; result?: unknown }): void {\n logger.debug('QueryServer2 message:', message);\n\n // Handle responses\n if (message.id !== undefined && this.pendingRequests.has(Number(message.id))) {\n const pending = this.pendingRequests.get(Number(message.id))!;\n this.pendingRequests.delete(Number(message.id));\n\n if (message.error) {\n pending.reject(new Error(`Query server error: ${message.error.message}`));\n } else {\n pending.resolve(message.result);\n }\n return;\n }\n\n // Handle notifications (progress, etc.)\n if (message.method) {\n this.emit('notification', { method: message.method, params: message.params });\n }\n }\n\n private rejectAllPending(error: Error): void {\n for (const [id, pending] of this.pendingRequests) {\n pending.reject(error);\n this.pendingRequests.delete(id);\n }\n }\n\n private sendRaw(message: object): void {\n if (!this.process?.stdin) {\n throw new Error('Query server is not running');\n }\n\n const body = JSON.stringify(message);\n const contentLength = Buffer.byteLength(body, 'utf8');\n const frame = `Content-Length: ${contentLength}\\r\\n\\r\\n${body}`;\n this.process.stdin.write(frame);\n }\n}\n", "/**\n * CodeQL CLI Server client.\n *\n * Manages a long-lived `codeql execute cli-server` process that executes CLI\n * commands without repeated JVM startup overhead. Commands are serialized as\n * JSON arrays followed by a NUL byte, and responses are NUL-terminated JSON.\n *\n * Inspired by the `CodeQLCliServer` class in github/vscode-codeql.\n */\n\nimport { ChildProcess, spawn } from 'child_process';\nimport { delimiter } from 'path';\nimport { EventEmitter } from 'events';\nimport { clearTimeout, setTimeout } from 'timers';\nimport { buildCLIServerArgs, CLIServerConfig } from './server-config';\nimport { getResolvedCodeQLDir } from './cli-executor';\nimport { logger } from '../utils/logger';\nimport { waitForProcessReady } from '../utils/process-ready';\n\n/**\n * A queued command waiting to be sent to the CLI server.\n */\ninterface QueuedCommand {\n args: string[];\n reject: (_error: Error) => void;\n resolve: (_value: string) => void;\n}\n\n/**\n * Client for the CodeQL CLI Server process.\n *\n * The cli-server uses a simple NUL-delimited protocol:\n * - **Request**: JSON array of command arguments, followed by a NUL byte.\n * - **Response**: command stdout, terminated by a NUL byte on stdout.\n * stderr is forwarded as-is.\n */\nexport class CodeQLCLIServer extends EventEmitter {\n private commandInProgress = false;\n private commandQueue: Array<() => void> = [];\n private readonly config: CLIServerConfig;\n private currentReject: ((_error: Error) => void) | null = null;\n private currentResolve: ((_value: string) => void) | null = null;\n private nullBuffer = Buffer.alloc(1);\n private process: ChildProcess | null = null;\n private stdoutBuffer = '';\n\n constructor(config: CLIServerConfig) {\n super();\n this.config = config;\n }\n\n /**\n * Start the cli-server process.\n */\n async start(): Promise {\n if (this.process) {\n throw new Error('CLI server is already running');\n }\n\n logger.info('Starting CodeQL CLI Server...');\n\n const args = buildCLIServerArgs(this.config);\n\n const spawnEnv = { ...process.env };\n const codeqlDir = getResolvedCodeQLDir();\n if (codeqlDir && spawnEnv.PATH) {\n spawnEnv.PATH = `${codeqlDir}${delimiter}${spawnEnv.PATH}`;\n } else if (codeqlDir) {\n spawnEnv.PATH = codeqlDir;\n }\n\n this.process = spawn('codeql', args, {\n stdio: ['pipe', 'pipe', 'pipe'],\n env: spawnEnv,\n });\n\n this.process.stdout?.on('data', (data: Buffer) => {\n this.handleStdout(data);\n });\n\n this.process.stderr?.on('data', (data: Buffer) => {\n logger.debug('CLIServer stderr:', data.toString());\n });\n\n this.process.on('error', (error: Error) => {\n logger.error('CLI server process error:', error);\n if (this.currentReject) {\n this.currentReject(error);\n this.currentReject = null;\n this.currentResolve = null;\n }\n this.emit('error', error);\n });\n\n this.process.on('exit', (code: number | null) => {\n logger.info(`CLI server exited with code: ${code}`);\n if (this.currentReject) {\n this.currentReject(new Error(`CLI server exited unexpectedly with code: ${code}`));\n this.currentReject = null;\n this.currentResolve = null;\n }\n this.process = null;\n this.emit('exit', code);\n });\n\n // Wait for the JVM to initialise (resolves on first stderr/stdout output)\n await waitForProcessReady(this.process, 'CodeQL CLI Server');\n logger.info('CodeQL CLI Server started');\n }\n\n /**\n * Run a CodeQL CLI command through the persistent server.\n *\n * Commands are serialized and queued; only one command runs at a time.\n *\n * @param args - The full command arguments (e.g. `['resolve', 'qlpacks']`).\n * @returns The stdout output from the command.\n */\n runCommand(args: string[]): Promise {\n return new Promise((resolve, reject) => {\n const execute = () => {\n this.executeCommand({ args, reject, resolve });\n };\n\n if (this.commandInProgress) {\n this.commandQueue.push(execute);\n } else {\n execute();\n }\n });\n }\n\n /**\n * Gracefully shut down the CLI server.\n */\n async shutdown(): Promise {\n if (!this.process) {\n return;\n }\n\n logger.info('Shutting down CodeQL CLI Server...');\n\n try {\n // Send shutdown command\n this.process.stdin?.write(JSON.stringify(['shutdown']), 'utf8');\n this.process.stdin?.write(this.nullBuffer);\n } catch (error) {\n logger.warn('Error during CLI server shutdown request:', error);\n }\n\n // Give it a moment, then force kill\n await new Promise((resolve) => {\n const timer = setTimeout(() => {\n if (this.process) {\n this.process.kill('SIGTERM');\n this.process = null;\n }\n resolve();\n }, 2000);\n\n if (this.process) {\n this.process.once('exit', () => {\n clearTimeout(timer);\n this.process = null;\n resolve();\n });\n } else {\n clearTimeout(timer);\n resolve();\n }\n });\n\n this.commandInProgress = false;\n this.commandQueue = [];\n logger.info('CodeQL CLI Server stopped');\n }\n\n /**\n * Whether the CLI server process is running.\n */\n isRunning(): boolean {\n return this.process !== null && !this.process.killed;\n }\n\n // ---- private helpers ----\n\n private executeCommand(cmd: QueuedCommand): void {\n if (!this.process?.stdin) {\n cmd.reject(new Error('CLI server is not running'));\n return;\n }\n\n this.commandInProgress = true;\n this.currentResolve = cmd.resolve;\n this.currentReject = cmd.reject;\n\n try {\n this.process.stdin.write(JSON.stringify(cmd.args), 'utf8');\n this.process.stdin.write(this.nullBuffer);\n } catch (error) {\n this.commandInProgress = false;\n this.currentResolve = null;\n this.currentReject = null;\n cmd.reject(error instanceof Error ? error : new Error(String(error)));\n this.runNext();\n }\n }\n\n private handleStdout(data: Buffer): void {\n this.stdoutBuffer += data.toString();\n\n // Process all NUL-delimited responses in the buffer\n let nulIndex = this.stdoutBuffer.indexOf('\\0');\n while (nulIndex !== -1) {\n const result = this.stdoutBuffer.substring(0, nulIndex);\n this.stdoutBuffer = this.stdoutBuffer.substring(nulIndex + 1);\n\n if (this.currentResolve) {\n this.currentResolve(result);\n this.currentResolve = null;\n this.currentReject = null;\n }\n\n this.commandInProgress = false;\n this.runNext();\n\n nulIndex = this.stdoutBuffer.indexOf('\\0');\n }\n }\n\n private runNext(): void {\n const next = this.commandQueue.shift();\n if (next) {\n next();\n }\n }\n}\n", "/**\n * CodeQL Server Manager\n *\n * Manages the lifecycle of CodeQL background server processes:\n * - language-server (LSP-based QL validation)\n * - query-server2 (query evaluation)\n * - cli-server (JVM reuse for CLI commands)\n *\n * Servers are keyed by a hash of their configuration. When a caller requests\n * a server with a different configuration, the old server is shut down and a\n * new one is started. Session-specific cache directories provide isolation.\n */\n\nimport { mkdirSync } from 'fs';\nimport { join } from 'path';\nimport { randomUUID } from 'crypto';\nimport {\n CLIServerConfig,\n CodeQLServerType,\n computeConfigHash,\n LanguageServerConfig,\n QueryServerConfig,\n ServerConfig,\n} from './server-config';\nimport { CodeQLLanguageServer } from './language-server';\nimport { CodeQLQueryServer } from './query-server';\nimport { CodeQLCLIServer } from './cli-server';\nimport { getProjectTmpDir } from '../utils/temp-dir';\nimport { logger } from '../utils/logger';\n\n/**\n * Entry in the managed servers map.\n */\ninterface ManagedServer {\n configHash: string;\n server: CodeQLCLIServer | CodeQLLanguageServer | CodeQLQueryServer;\n sessionId: string;\n type: CodeQLServerType;\n}\n\n/**\n * Options for creating a session-specific cache layout.\n */\nexport interface SessionCacheOptions {\n /** Override the session ID (defaults to a random UUID). */\n sessionId?: string;\n}\n\n/**\n * Manages CodeQL background server processes with config-aware caching.\n *\n * Callers should use `getLanguageServer()`, `getQueryServer()`, or\n * `getCLIServer()` to obtain a running server. If the requested\n * configuration differs from the currently running server of that type, the\n * old server is stopped and replaced.\n */\nexport class CodeQLServerManager {\n /** Keyed by `CodeQLServerType` \u2014 at most one per type at a time. */\n private servers = new Map();\n\n /** In-flight `getOrRestart` promises, keyed by server type, to serialize concurrent calls. */\n private pendingStarts = new Map>();\n\n /** The session ID used for cache isolation. */\n private sessionId: string;\n\n /** Root directory for session-specific caches. */\n private sessionCacheDir: string;\n\n constructor(options?: SessionCacheOptions) {\n this.sessionId = options?.sessionId ?? randomUUID();\n this.sessionCacheDir = join(\n getProjectTmpDir('codeql-cache'),\n this.sessionId,\n );\n // Pre-create the cache directory tree\n for (const subdir of ['compilation-cache', 'logs', 'query-cache']) {\n mkdirSync(join(this.sessionCacheDir, subdir), { recursive: true });\n }\n logger.info(`CodeQLServerManager initialized (session: ${this.sessionId})`);\n }\n\n // ---- Public API ----\n\n /**\n * Get the current session ID.\n */\n getSessionId(): string {\n return this.sessionId;\n }\n\n /**\n * Get the session-specific cache directory.\n */\n getCacheDir(): string {\n return this.sessionCacheDir;\n }\n\n /**\n * Return the session-specific log directory.\n */\n getLogDir(): string {\n return join(this.sessionCacheDir, 'logs');\n }\n\n /**\n * Get or create a Language Server with the given configuration.\n *\n * If a language server is already running with the same config it is reused.\n * If the config has changed the old server is shut down first.\n */\n async getLanguageServer(config: LanguageServerConfig): Promise {\n const enriched = this.enrichConfig(config) as LanguageServerConfig;\n return this.getOrRestart('language', enriched, () => {\n // Convert LanguageServerConfig to the LanguageServerOptions the existing class expects\n return new CodeQLLanguageServer({\n loglevel: enriched.loglevel,\n logdir: enriched.logdir,\n searchPath: enriched.searchPath,\n synchronous: enriched.synchronous,\n verbosity: enriched.verbosity,\n });\n }) as Promise;\n }\n\n /**\n * Get or create a Query Server with the given configuration.\n */\n async getQueryServer(config: QueryServerConfig): Promise {\n const enriched = this.enrichConfig(config) as QueryServerConfig;\n return this.getOrRestart('query', enriched, () => {\n return new CodeQLQueryServer(enriched);\n }) as Promise;\n }\n\n /**\n * Get or create a CLI Server with the given configuration.\n */\n async getCLIServer(config: CLIServerConfig): Promise {\n const enriched = this.enrichConfig(config) as CLIServerConfig;\n return this.getOrRestart('cli', enriched, () => {\n return new CodeQLCLIServer(enriched);\n }) as Promise;\n }\n\n /**\n * Shut down a specific server type.\n */\n async shutdownServer(type: CodeQLServerType): Promise {\n const managed = this.servers.get(type);\n if (!managed) return;\n\n logger.info(`Shutting down ${type} server (session: ${managed.sessionId})`);\n await this.stopServer(managed);\n this.servers.delete(type);\n }\n\n /**\n * Shut down all managed servers.\n */\n async shutdownAll(): Promise {\n logger.info(`Shutting down all servers for session: ${this.sessionId}`);\n const shutdownPromises = Array.from(this.servers.entries()).map(\n async ([type, managed]) => {\n try {\n await this.stopServer(managed);\n } catch (error) {\n logger.error(`Error shutting down ${type} server:`, error);\n }\n },\n );\n await Promise.all(shutdownPromises);\n this.servers.clear();\n logger.info('All servers shut down');\n }\n\n /**\n * Check whether a server of the given type is currently running.\n */\n isRunning(type: CodeQLServerType): boolean {\n const managed = this.servers.get(type);\n if (!managed) return false;\n return managed.server.isRunning();\n }\n\n /**\n * Get status information for all managed servers.\n */\n getStatus(): Record {\n const status: Record = {\n cli: null,\n language: null,\n query: null,\n };\n for (const [type, managed] of this.servers) {\n status[type] = {\n configHash: managed.configHash,\n running: managed.server.isRunning(),\n sessionId: managed.sessionId,\n };\n }\n return status as Record;\n }\n\n // ---- Private helpers ----\n\n /**\n * Eagerly start the language server so the JVM is warm when the first\n * LSP tool call arrives. Uses the default configuration that\n * `lsp-handlers.ts` / `lsp-diagnostics.ts` would create on the first\n * `getLanguageServer()` call. The server is stored in the managed-servers\n * map and reused by subsequent tool invocations.\n *\n * This is fire-and-forget: errors are logged but do not prevent the MCP\n * server from starting.\n */\n async warmUpLanguageServer(): Promise {\n try {\n // Lazy-import to avoid circular dependency at module level\n const { packageRootDir } = await import('../utils/package-paths');\n const { resolve } = await import('path');\n\n const config: LanguageServerConfig = {\n checkErrors: 'ON_CHANGE',\n loglevel: 'WARN',\n searchPath: resolve(packageRootDir, 'ql'),\n };\n logger.info('Warming up language server (background JVM start)...');\n await this.getLanguageServer(config);\n logger.info('Language server warm-up complete');\n } catch (error) {\n logger.warn('Language server warm-up failed (will retry on first tool call):', error);\n }\n }\n\n /**\n * Eagerly start the CLI server so the JVM is warm when the first\n * `executeCodeQLCommand()` call routes through it.\n *\n * The CLI server uses only session-scoped `commonCaches` and `logdir`,\n * both injected by `enrichConfig()`. Passing an empty config is\n * intentional \u2014 it matches what `executeCodeQLCommand()` will request.\n *\n * Fire-and-forget: errors are logged but do not block startup.\n */\n async warmUpCLIServer(): Promise {\n try {\n logger.info('Warming up CLI server (background JVM start)...');\n await this.getCLIServer({});\n logger.info('CLI server warm-up complete');\n } catch (error) {\n logger.warn('CLI server warm-up failed (will retry on first tool call):', error);\n }\n }\n\n /**\n * Enrich a config with session-specific defaults for commonCaches and logdir.\n */\n private enrichConfig(config: T): T {\n return {\n ...config,\n commonCaches: config.commonCaches ?? this.sessionCacheDir,\n logdir: config.logdir ?? this.getLogDir(),\n };\n }\n\n /**\n * Get an existing server if its config matches, otherwise stop the old\n * one and start a new server.\n *\n * Concurrent calls for the same server type are serialized via\n * `pendingStarts` to avoid spawning duplicate server processes.\n */\n private async getOrRestart(\n type: CodeQLServerType,\n config: ServerConfig,\n factory: () => CodeQLCLIServer | CodeQLLanguageServer | CodeQLQueryServer,\n ): Promise {\n // If another call is already starting a server of this type, wait for it\n // to settle (success or failure) and then re-check whether the result is\n // still usable.\n const inflight = this.pendingStarts.get(type);\n if (inflight) {\n try { await inflight; } catch { /* swallow \u2014 original caller handles the rejection */ }\n }\n\n const work = this.doGetOrRestart(type, config, factory);\n this.pendingStarts.set(type, work);\n try {\n return await work;\n } finally {\n // Ensure `work` has settled before removing the pendingStarts entry so\n // that concurrent callers waiting on the same promise see a consistent\n // map state. The try/catch avoids re-throwing a rejection that the\n // outer `try` block already handles.\n try { await work; } catch { /* already handled */ }\n if (this.pendingStarts.get(type) === work) {\n this.pendingStarts.delete(type);\n }\n }\n }\n\n /**\n * Core logic for getOrRestart, separated to allow serialization.\n */\n private async doGetOrRestart(\n type: CodeQLServerType,\n config: ServerConfig,\n factory: () => CodeQLCLIServer | CodeQLLanguageServer | CodeQLQueryServer,\n ): Promise {\n const hash = computeConfigHash(type, config);\n const existing = this.servers.get(type);\n\n // Reuse if config matches and server is still running\n if (existing && existing.configHash === hash && existing.server.isRunning()) {\n logger.debug(`Reusing existing ${type} server (hash: ${hash.substring(0, 8)})`);\n return existing.server;\n }\n\n // Config changed or server died \u2014 stop the old one\n if (existing) {\n logger.info(`${type} server config changed or dead, restarting...`);\n await this.stopServer(existing);\n this.servers.delete(type);\n }\n\n // Start a new server\n const server = factory();\n await server.start();\n\n this.servers.set(type, {\n configHash: hash,\n server,\n sessionId: this.sessionId,\n type,\n });\n\n logger.info(`${type} server started (hash: ${hash.substring(0, 8)})`);\n return server;\n }\n\n /**\n * Stop a managed server, ignoring errors.\n */\n private async stopServer(managed: ManagedServer): Promise {\n try {\n await managed.server.shutdown();\n } catch (error) {\n logger.warn(`Error stopping ${managed.type} server:`, error);\n // Best-effort \u2014 don't propagate\n }\n }\n}\n\n/**\n * Global server manager singleton.\n *\n * Initialized lazily by `getServerManager()`. The MCP server entry point\n * should call `initServerManager()` at startup and `shutdownServerManager()`\n * at graceful shutdown.\n */\nlet globalServerManager: CodeQLServerManager | null = null;\n\n/**\n * Initialize the global server manager (idempotent).\n */\nexport function initServerManager(options?: SessionCacheOptions): CodeQLServerManager {\n if (!globalServerManager) {\n globalServerManager = new CodeQLServerManager(options);\n }\n return globalServerManager;\n}\n\n/**\n * Get the global server manager, creating it if needed.\n */\nexport function getServerManager(): CodeQLServerManager {\n if (!globalServerManager) {\n globalServerManager = new CodeQLServerManager();\n }\n return globalServerManager;\n}\n\n/**\n * Shut down the global server manager and all its servers.\n */\nexport async function shutdownServerManager(): Promise {\n if (globalServerManager) {\n await globalServerManager.shutdownAll();\n globalServerManager = null;\n }\n}\n\n/**\n * Reset the global server manager (for testing only).\n */\nexport function resetServerManager(): void {\n globalServerManager = null;\n}\n", "/**\n * Generic CLI command execution utilities for CodeQL and QLT commands\n */\n\nimport { execFile } from 'child_process';\nimport { existsSync } from 'fs';\nimport { basename, delimiter, dirname, isAbsolute } from 'path';\nimport { promisify } from 'util';\nimport { logger } from '../utils/logger';\n\nconst execFileAsync = promisify(execFile);\n\nexport interface CLIExecutionResult {\n stdout: string;\n stderr: string;\n success: boolean;\n error?: string;\n exitCode?: number;\n}\n\nexport interface CLIExecutionOptions {\n command: string;\n args: string[];\n cwd?: string;\n timeout?: number;\n env?: Record;\n}\n\n// Whitelist of allowed commands to prevent arbitrary command execution\nconst ALLOWED_COMMANDS = new Set([\n 'codeql',\n 'git',\n 'node',\n 'npm',\n 'qlt',\n 'which'\n]);\n\n// Additional commands allowed in test environments\nlet testCommands: Set | null = null;\n\n// Whitelist of safe environment variables to pass to child processes\n// This prevents potentially malicious environment variables from being passed through\nconst SAFE_ENV_VARS = [\n 'HOME', // User home directory\n 'LANG', // Locale setting\n 'LC_ALL', // Locale setting\n 'LC_CTYPE', // Locale setting\n 'PATH', // Required to find executables\n 'SHELL', // User's shell (Unix)\n 'TEMP', // Temporary directory (Windows)\n 'TERM', // Terminal type (Unix)\n 'TMP', // Temporary directory (Windows)\n 'TMPDIR', // Temporary directory (Unix)\n 'USER', // Current user (Unix)\n 'USERNAME', // Current user (Windows)\n] as const;\n\n// Whitelist of safe environment variable prefixes\n// These are needed for CodeQL and Node.js functionality\nconst SAFE_ENV_PREFIXES = [\n 'CODEQL_', // CodeQL-specific variables\n 'NODE_', // Node.js-specific variables (for npm, etc.)\n] as const;\n\n// Pattern for dangerous control characters in CLI arguments\n// Rejected characters:\n// \\x01-\\x08: SOH through BS (start of heading, text, null control chars, backspace)\n// \\x0B: Vertical tab - rarely used legitimately, can cause display issues\n// \\x0C: Form feed - can cause unexpected page breaks in output\n// \\x0E-\\x1F: SO through US (shift out/in, device controls, separators)\n// Allowed characters:\n// \\x00: Null byte - handled separately for clearer error messaging\n// \\x09: Horizontal tab - commonly used in file paths and arguments\n// \\x0A: Newline (LF) - may appear in multi-line arguments\n// \\x0D: Carriage return (CR) - may appear with newlines on Windows\n// eslint-disable-next-line no-control-regex\nconst DANGEROUS_CONTROL_CHARS = /[\\x01-\\x08\\x0B\\x0C\\x0E-\\x1F]/;\n\n/**\n * Enable test-specific commands for testing purposes\n * This should only be called in test environments\n */\nexport function enableTestCommands(): void {\n testCommands = new Set([\n 'cat',\n 'echo',\n 'ls',\n 'sh',\n 'sleep'\n ]);\n}\n\n/**\n * Disable test-specific commands\n */\nexport function disableTestCommands(): void {\n testCommands = null;\n}\n\n/**\n * Check if a command is allowed\n */\nfunction isCommandAllowed(command: string): boolean {\n return ALLOWED_COMMANDS.has(command) || (testCommands !== null && testCommands.has(command));\n}\n\n// Resolved CodeQL binary directory from CODEQL_PATH.\n// When set, this directory is prepended to PATH for all child processes\n// so that `execFile('codeql', ...)` finds the correct binary via execvp().\n// Using PATH lookup (rather than an absolute path) is essential because\n// execvp() handles shell-script shebangs correctly, whereas passing an\n// absolute path to execFile() can fail with ENOENT for shell scripts.\nlet resolvedCodeQLDir: string | null = null;\n\n// Cached result from resolveCodeQLBinary(). `undefined` means not yet resolved.\nlet resolvedBinaryResult: string | undefined;\n\n/**\n * Resolve the CodeQL CLI binary path.\n *\n * Resolution order:\n * 1. `CODEQL_PATH` environment variable \u2014 must point to an existing file whose\n * basename is `codeql` (or `codeql.exe` / `codeql.cmd` on Windows).\n * The parent directory is prepended to PATH for child processes.\n * 2. Falls back to the bare `codeql` command (resolved via PATH at exec time).\n *\n * The resolved value is cached for the lifetime of the process. Call this once\n * at startup; subsequent calls are a no-op and return the cached value.\n */\nexport function resolveCodeQLBinary(): string {\n // Short-circuit if already resolved\n if (resolvedBinaryResult !== undefined) {\n return resolvedBinaryResult;\n }\n\n const envPath = process.env.CODEQL_PATH;\n\n if (!envPath) {\n resolvedCodeQLDir = null;\n resolvedBinaryResult = 'codeql';\n return resolvedBinaryResult;\n }\n\n // Validate the path points to a plausible CodeQL binary\n const base = basename(envPath).toLowerCase();\n const validBaseNames = ['codeql', 'codeql.exe', 'codeql.cmd'];\n if (!validBaseNames.includes(base)) {\n throw new Error(\n `CODEQL_PATH must point to a CodeQL CLI binary (expected basename: codeql), got: ${base}`\n );\n }\n\n // Require an absolute path to avoid ambiguity\n if (!isAbsolute(envPath)) {\n throw new Error(\n `CODEQL_PATH must be an absolute path, got: ${envPath}`\n );\n }\n\n // Verify the file exists\n if (!existsSync(envPath)) {\n throw new Error(\n `CODEQL_PATH points to a file that does not exist: ${envPath}`\n );\n }\n\n resolvedCodeQLDir = dirname(envPath);\n resolvedBinaryResult = 'codeql';\n logger.info(`CodeQL CLI resolved via CODEQL_PATH: ${envPath} (dir: ${resolvedCodeQLDir})`);\n return resolvedBinaryResult;\n}\n\n/**\n * Get the currently resolved CodeQL binary directory, or null if using PATH.\n */\nexport function getResolvedCodeQLDir(): string | null {\n return resolvedCodeQLDir;\n}\n\n/**\n * Reset the resolved CodeQL binary to the default (for testing only).\n */\nexport function resetResolvedCodeQLBinary(): void {\n resolvedCodeQLDir = null;\n resolvedBinaryResult = undefined;\n}\n\n/**\n * Validate that the resolved CodeQL binary is actually callable.\n *\n * Runs `codeql version --format=terse` and verifies the process exits\n * successfully. This catches the case where `CODEQL_PATH` is unset and\n * `codeql` is not on PATH \u2014 the server would otherwise start normally\n * but every tool invocation would fail.\n *\n * @returns The version string reported by the CodeQL CLI.\n * @throws Error if the binary is not reachable or returns a non-zero exit code.\n */\nexport async function validateCodeQLBinaryReachable(): Promise {\n const binary = resolvedBinaryResult ?? 'codeql';\n const env = { ...process.env };\n if (resolvedCodeQLDir) {\n env.PATH = resolvedCodeQLDir + delimiter + (env.PATH || '');\n }\n\n try {\n const { stdout } = await execFileAsync(binary, ['version', '--format=terse'], {\n env,\n timeout: 15_000,\n });\n return stdout.trim();\n } catch (err: unknown) {\n const message = err instanceof Error ? err.message : String(err);\n throw new Error(\n `CodeQL CLI is not reachable (binary: ${binary}). ` +\n `Ensure codeql is on PATH or set the CODEQL_PATH environment variable ` +\n `to the absolute path of the CodeQL CLI binary. Details: ${message}`\n );\n }\n}\n\n/**\n * Sanitize a CLI argument to prevent potential issues with special characters.\n * \n * While execFile() does not spawn a shell (preventing shell injection), we still\n * validate arguments to:\n * 1. Reject null bytes that could truncate strings in C-based commands\n * 2. Reject control characters that could cause unexpected behavior\n * 3. Provide defense-in-depth against potential issues\n * \n * @param arg - The argument to sanitize\n * @returns The sanitized argument\n * @throws Error if the argument contains dangerous characters\n */\nexport function sanitizeCLIArgument(arg: string): string {\n // Reject null bytes - these can truncate strings in C-based commands\n // Error message intentionally excludes argument content to avoid logging potentially sensitive data\n if (arg.includes('\\0')) {\n throw new Error(`CLI argument contains null byte: argument rejected for security`);\n }\n \n // Reject control characters using the module-level constant pattern\n if (DANGEROUS_CONTROL_CHARS.test(arg)) {\n // Error message intentionally excludes argument content to avoid logging potentially sensitive data\n throw new Error(`CLI argument contains control characters: argument rejected for security`);\n }\n \n return arg;\n}\n\n/**\n * Sanitize an array of CLI arguments\n * @param args - The arguments to sanitize\n * @returns The sanitized arguments\n * @throws Error if any argument contains dangerous characters\n */\nexport function sanitizeCLIArguments(args: string[]): string[] {\n return args.map(sanitizeCLIArgument);\n}\n\n/**\n * Filter environment variables to only include safe ones\n * This prevents potentially malicious environment variables from being passed to child processes\n */\nfunction getSafeEnvironment(additionalEnv?: Record): Record {\n const safeEnv: Record = {};\n \n // Copy whitelisted environment variables from process.env\n for (const key of SAFE_ENV_VARS) {\n if (process.env[key] !== undefined) {\n safeEnv[key] = process.env[key]!;\n }\n }\n \n // Copy environment variables with whitelisted prefixes\n for (const [key, value] of Object.entries(process.env)) {\n if (value !== undefined && SAFE_ENV_PREFIXES.some(prefix => key.startsWith(prefix))) {\n safeEnv[key] = value;\n }\n }\n \n // When CODEQL_PATH was set, prepend the resolved directory to PATH so that\n // `execFile('codeql', ...)` finds the user-specified binary via execvp().\n // This approach (PATH manipulation + bare command name) is essential because\n // execvp() handles shell-script shebangs correctly, whereas passing an\n // absolute path to execFile() fails with ENOENT for shell-script launchers.\n if (resolvedCodeQLDir && safeEnv.PATH) {\n safeEnv.PATH = `${resolvedCodeQLDir}${delimiter}${safeEnv.PATH}`;\n } else if (resolvedCodeQLDir) {\n safeEnv.PATH = resolvedCodeQLDir;\n }\n \n // Merge with explicitly provided environment variables\n // These are trusted as they come from the application code, not external sources\n if (additionalEnv) {\n Object.assign(safeEnv, additionalEnv);\n }\n \n return safeEnv;\n}\n\n/**\n * Execute a CLI command and return the result.\n * \n * Security: This function uses execFile() instead of exec() to avoid shell interpretation.\n * Arguments are passed directly to the executable as an array, preventing shell injection.\n * Additional security measures include:\n * - Command whitelist validation\n * - Shell metacharacter detection in command names\n * - CLI argument sanitization (null bytes, control characters)\n * - Environment variable filtering\n */\nexport async function executeCLICommand(options: CLIExecutionOptions): Promise {\n try {\n const { command, args, cwd, timeout = 300000, env } = options; // 5 minute default timeout\n \n // Validate command is in the whitelist to prevent arbitrary command execution\n if (!isCommandAllowed(command)) {\n throw new Error(`Command not allowed: ${command}. Only whitelisted commands can be executed.`);\n }\n \n // Validate command to ensure it doesn't contain shell metacharacters\n if (command.includes(';') || command.includes('|') || command.includes('&') || \n command.includes('$') || command.includes('`') || command.includes('\\n') ||\n command.includes('\\r')) {\n throw new Error(`Invalid command: contains shell metacharacters: ${command}`);\n }\n \n // Sanitize CLI arguments to prevent issues with special characters\n // This provides defense-in-depth even though execFile() doesn't use a shell\n const sanitizedArgs = sanitizeCLIArguments(args);\n \n logger.info(`Executing CLI command: ${command}`, { args: sanitizedArgs, cwd, timeout });\n \n const execOptions = {\n cwd,\n timeout,\n env: getSafeEnvironment(env),\n };\n \n // execFile() is used instead of exec() to avoid shell interpretation\n // Arguments are passed as an array, not interpolated into a command string\n const { stdout, stderr } = await execFileAsync(command, sanitizedArgs, execOptions);\n\n return {\n stdout,\n stderr,\n success: true,\n exitCode: 0\n };\n\n } catch (error: unknown) {\n logger.error('CLI command execution failed:', error);\n \n const err = error as Error & { code?: number; stdout?: string; stderr?: string };\n const errorMessage = err instanceof Error ? err.message : String(error);\n const exitCode = err.code || 1;\n \n return {\n stdout: err.stdout || '',\n stderr: err.stderr || errorMessage,\n success: false,\n error: errorMessage,\n exitCode\n };\n }\n}\n\n/**\n * Build CodeQL command arguments with proper escaping\n */\nexport function buildCodeQLArgs(subcommand: string, options: Record): string[] {\n const args = [subcommand];\n \n // Single-letter parameters that should use -key=value format (with equals sign)\n // Note: CodeQL CLI uses -t=key=value format for metadata, not -t key=value\n const singleLetterParams = new Set(['t', 'o', 'v', 'q', 'h', 'J']);\n \n for (const [key, value] of Object.entries(options)) {\n if (value === undefined || value === null) {\n continue;\n }\n \n const isSingleLetter = key.length === 1 && singleLetterParams.has(key);\n \n if (typeof value === 'boolean') {\n if (value) {\n args.push(isSingleLetter ? `-${key}` : `--${key}`);\n }\n } else if (Array.isArray(value)) {\n // Handle array values (e.g., multiple -t flags for metadata)\n for (const item of value) {\n if (isSingleLetter) {\n // For single-letter params like -t, use -key=value format\n args.push(`-${key}=${String(item)}`);\n } else {\n // For long params, use --key=value format\n args.push(`--${key}=${String(item)}`);\n }\n }\n } else {\n // Handle string, number, and other values\n if (isSingleLetter) {\n // For single-letter params, use -key=value format\n args.push(`-${key}=${String(value)}`);\n } else {\n args.push(`--${key}=${String(value)}`);\n }\n }\n }\n \n return args;\n}\n\n/**\n * Build QLT command arguments with proper escaping\n */\nexport function buildQLTArgs(subcommand: string, options: Record): string[] {\n const args = [subcommand];\n \n for (const [key, value] of Object.entries(options)) {\n if (value === undefined || value === null) {\n continue;\n }\n \n if (typeof value === 'boolean') {\n if (value) {\n args.push(`--${key}`);\n }\n } else if (Array.isArray(value)) {\n // Handle array values\n for (const item of value) {\n args.push(`--${key}`, String(item));\n }\n } else {\n // Handle string, number, and other values\n args.push(`--${key}`, String(value));\n }\n }\n \n return args;\n}\n\n/**\n * CodeQL subcommands that MUST run as fresh processes.\n *\n * These cannot use the cli-server because they:\n * - Spawn extractors or other long-running child processes (database create, test extract)\n * - Produce multi-event NUL-delimited streams (test run)\n * - Are compound orchestration commands (database analyze)\n *\n * Everything else is routed through the persistent cli-server JVM for\n * sub-second execution instead of 2-5 s JVM cold-start per invocation.\n */\nconst FRESH_PROCESS_SUBCOMMANDS = new Set([\n 'database analyze',\n 'database create',\n 'test extract',\n 'test run',\n]);\n\n/**\n * Execute a CodeQL command.\n *\n * By default, commands are routed through the persistent `codeql execute\n * cli-server` process managed by {@link CodeQLServerManager}, eliminating\n * repeated JVM startup overhead (~2-5 s savings per call).\n *\n * Commands listed in {@link FRESH_PROCESS_SUBCOMMANDS} (e.g. `database create`,\n * `test run`) are always executed as fresh processes because they either spawn\n * child extractors, produce streaming output, or require a dedicated working\n * directory.\n *\n * If the cli-server is not available (e.g. during early startup before\n * `initServerManager()` is called), the function falls back transparently to\n * a fresh process.\n */\nexport async function executeCodeQLCommand(\n subcommand: string,\n options: Record,\n additionalArgs: string[] = [],\n cwd?: string\n): Promise {\n const args = buildCodeQLArgs(subcommand, options);\n args.push(...additionalArgs);\n\n // Determine whether this subcommand can use the persistent cli-server.\n // Commands that need a specific CWD also must use a fresh process because\n // the cli-server's CWD is fixed at startup.\n const canUseCLIServer = !FRESH_PROCESS_SUBCOMMANDS.has(subcommand) && !cwd;\n\n if (canUseCLIServer) {\n try {\n // Lazy-import to avoid circular dependency at module level.\n // Use getServerManager() (not initServerManager()) \u2014 if the manager\n // hasn't been initialized yet (e.g. during tests or early startup),\n // this creates one, but we only attempt to *use* the cli-server if\n // it is already running (warmed up at MCP server startup). We never\n // block on starting a new cli-server here \u2014 that would add JVM\n // startup latency to the first fresh-process-fallback call.\n const { getServerManager } = await import('./server-manager');\n const manager = getServerManager();\n\n if (manager.isRunning('cli')) {\n const cliServer = await manager.getCLIServer({});\n const sanitizedArgs = sanitizeCLIArguments(args);\n\n logger.info(`Executing CodeQL command via cli-server: ${subcommand}`, { args: sanitizedArgs });\n\n const stdout = await cliServer.runCommand(sanitizedArgs);\n\n return {\n stdout,\n stderr: '',\n success: true,\n exitCode: 0,\n };\n } else {\n logger.debug(`cli-server not yet running for \"${subcommand}\", using fresh process`);\n }\n } catch (error) {\n // If the cli-server call fails, check whether it's a command-level\n // error (the CLI returned non-zero) or a transport/startup error.\n // For transport errors we fall back to a fresh process; for command\n // errors we return the failure directly.\n const message = error instanceof Error ? error.message : String(error);\n\n // Transport-level errors that warrant a fallback:\n if (message.includes('CLI server is not running') ||\n message.includes('CLI server exited') ||\n message.includes('failed to start')) {\n logger.warn(`cli-server unavailable for \"${subcommand}\", falling back to fresh process: ${message}`);\n // Fall through to fresh-process execution below\n } else {\n // Command-level error \u2014 return it as a failed result\n logger.error(`cli-server command failed for \"${subcommand}\": ${message}`);\n return {\n stdout: '',\n stderr: message,\n success: false,\n error: message,\n exitCode: 1,\n };\n }\n }\n }\n\n // Fresh-process execution (for FRESH_PROCESS_SUBCOMMANDS, CWD-specific\n // calls, or as a fallback when the cli-server is unavailable).\n // Use 0 (no timeout) because CodeQL operations such as query evaluation,\n // database analysis, profiling, and test runs are inherently long-running\n // and should not be killed by a process timeout.\n return executeCLICommand({\n command: 'codeql',\n args,\n cwd,\n timeout: 0\n });\n}\n\n/**\n * Execute a QLT command\n */\nexport async function executeQLTCommand(\n subcommand: string, \n options: Record, \n additionalArgs: string[] = []\n): Promise {\n const args = buildQLTArgs(subcommand, options);\n args.push(...additionalArgs);\n \n return executeCLICommand({\n command: 'qlt',\n args\n });\n}\n\n/**\n * Get help text for a CLI command\n */\nexport async function getCommandHelp(command: string, subcommand?: string): Promise {\n const args = subcommand ? [subcommand, '--help'] : ['--help'];\n \n const result = await executeCLICommand({\n command,\n args\n });\n \n return result.stdout || result.stderr || 'No help available';\n}\n\n/**\n * Validate that a command exists on the system.\n */\nexport async function validateCommandExists(command: string): Promise {\n try {\n const result = await executeCLICommand({\n command: 'which',\n args: [command]\n });\n return result.success;\n } catch {\n return false;\n }\n}", "/**\n * CodeQL Development MCP McpServer\n * Main entry point for the server\n */\n\nimport { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';\nimport { StreamableHTTPServerTransport } from '@modelcontextprotocol/sdk/server/streamableHttp.js';\nimport express from 'express';\nimport cors from 'cors';\nimport dotenv from 'dotenv';\nimport { realpathSync } from 'fs';\nimport { resolve } from 'path';\nimport { pathToFileURL } from 'url';\nimport { registerCodeQLTools, registerCodeQLResources } from './tools';\nimport { registerLSPTools } from './tools/lsp';\nimport { registerLanguageResources } from './resources/language-resources';\nimport { registerWorkflowPrompts } from './prompts/workflow-prompts';\nimport { registerMonitoringTools } from './tools/monitoring-tools';\nimport { sessionDataManager } from './lib/session-data-manager';\nimport { resolveCodeQLBinary, validateCodeQLBinaryReachable } from './lib/cli-executor';\nimport { initServerManager, shutdownServerManager } from './lib/server-manager';\nimport { packageRootDir } from './utils/package-paths';\nimport { logger } from './utils/logger';\n\n// Load environment variables from a .env file co-located with the package root.\n// Uses the package directory (not CWD) so that npm-installed users don't\n// accidentally inherit a .env from their project.\n// Set DOTENV_CONFIG_QUIET to suppress the dotenv banner that would otherwise\n// leak to stdout and corrupt the MCP stdio JSON-RPC channel.\ndotenv.config({ path: resolve(packageRootDir, '.env'), quiet: true });\n\nconst PACKAGE_NAME = 'codeql-development-mcp-server';\nconst VERSION = '2.24.1';\n\n/**\n * Start the MCP server\n */\nexport async function startServer(mode: 'stdio' | 'http' = 'stdio'): Promise {\n logger.info(`Starting CodeQL Development MCP McpServer v${VERSION} in ${mode} mode`);\n\n // Resolve the CodeQL CLI binary path (honors CODEQL_PATH env var).\n // This must happen before any tool registration so that all CodeQL commands\n // use the user-specified binary.\n const codeqlBinary = resolveCodeQLBinary();\n logger.info(`CodeQL CLI binary: ${codeqlBinary}`);\n\n // Validate that the resolved binary is actually callable. This catches\n // misconfigurations early (e.g. codeql not on PATH and CODEQL_PATH unset)\n // instead of failing silently and producing confusing tool-level errors.\n const codeqlVersion = await validateCodeQLBinaryReachable();\n logger.info(`CodeQL CLI version: ${codeqlVersion}`);\n\n const server = new McpServer({\n name: PACKAGE_NAME,\n version: VERSION,\n });\n\n // Register CodeQL tools (legacy high-level helpers)\n registerCodeQLTools(server);\n\n // Register LSP-based tools (diagnostics, completion, definition, references)\n registerLSPTools(server);\n\n // Register CodeQL resources (static guides)\n registerCodeQLResources(server);\n\n // Register language-specific resources (AST references, security patterns)\n registerLanguageResources(server);\n\n // Register high-level workflow prompts (complete development workflows)\n registerWorkflowPrompts(server);\n\n // Register monitoring and reporting tools\n registerMonitoringTools(server);\n\n // Initialize session data manager\n await sessionDataManager.initialize();\n\n // Initialize the CodeQL background server manager and eagerly start the\n // language server and CLI server JVMs so they are warm when the first tool\n // calls arrive. This avoids 2-60 s cold-start penalties per JVM.\n const manager = initServerManager();\n Promise.all([\n manager.warmUpLanguageServer(),\n manager.warmUpCLIServer(),\n ]).catch(() => { /* individual errors logged inside each warm-up method */ });\n\n if (mode === 'stdio') {\n const transport = new StdioServerTransport();\n await server.connect(transport);\n logger.info('McpServer started successfully on STDIO transport');\n } else {\n // HTTP mode\n const app = express();\n app.use(cors());\n app.use(express.json());\n\n const transport = new StreamableHTTPServerTransport({\n sessionIdGenerator: () => Math.random().toString(36).substring(7),\n });\n await server.connect(transport);\n\n app.all('/mcp', (req, res) => {\n transport.handleRequest(req, res, req.body).catch((err) => {\n logger.error('Error handling MCP request:', err);\n if (!res.headersSent) {\n res.status(500).json({ error: 'Internal McpServer Error' });\n }\n });\n });\n\n app.get('/', (_req, res) => {\n res.json({\n name: PACKAGE_NAME,\n version: VERSION,\n description: 'CodeQL Development MCP McpServer',\n status: 'running',\n });\n });\n\n const host = process.env.HTTP_HOST || 'localhost';\n const port = Number(process.env.HTTP_PORT || process.env.PORT) || 3000;\n \n // Return a promise that keeps the process alive\n return new Promise((resolve, reject) => {\n const httpServer = app.listen(port, host, () => {\n logger.info(`HTTP server listening on http://${host}:${port}/mcp`);\n resolve();\n });\n \n httpServer.on('error', (error) => {\n logger.error('HTTP server error:', error);\n reject(error);\n });\n });\n }\n\n setupGracefulShutdown(server);\n return server;\n}\n\n/**\n * Set up graceful shutdown handling\n */\nfunction setupGracefulShutdown(server: McpServer): void {\n const shutdown = async () => {\n logger.info('Shutting down server...');\n try {\n // Shut down all CodeQL background servers first\n await shutdownServerManager();\n await server.close();\n logger.info('McpServer closed gracefully');\n process.exit(0);\n } catch (error) {\n logger.error('Error during shutdown:', error);\n process.exit(1);\n }\n };\n\n process.on('SIGINT', shutdown);\n process.on('SIGTERM', shutdown);\n}\n\n/**\n * Main function to start the server\n */\nasync function main(): Promise {\n try {\n const transportMode = (process.env.TRANSPORT_MODE || 'stdio').toLowerCase();\n const mode: 'stdio' | 'http' = transportMode === 'http' ? 'http' : 'stdio';\n await startServer(mode);\n } catch (error) {\n logger.error('Failed to start server:', error);\n process.exit(1);\n }\n}\n\n// Start the server if this file is run directly.\n// Use realpathSync to resolve npm/npx symlinks so the guard works for both\n// direct invocation and globally-installed npm bin entries.\nconst scriptPath = process.argv[1] ? realpathSync(resolve(process.argv[1])) : undefined;\nif (scriptPath && import.meta.url === pathToFileURL(scriptPath).href) {\n main();\n}\n", "/**\n * CodeQL BQRS decode tool\n *\n * Decodes BQRS (Binary Query Result Set) files to human-readable formats.\n * Use `list_query_run_results` to discover BQRS files from previous query runs,\n * then decode them with this tool. For long-running queries (codeql_query_run)\n * or suites (codeql_database_analyze), the BQRS file is located at\n * `/results.bqrs`. Use `codeql_bqrs_info` first to discover available\n * result sets and column schemas.\n */\n\nimport { z } from 'zod';\nimport { CLIToolDefinition, createCodeQLSchemas, createBQRSResultProcessor } from '../../lib/cli-tool-registry';\n\nexport const codeqlBqrsDecodeTool: CLIToolDefinition = {\n name: 'codeql_bqrs_decode',\n description:\n 'Decode BQRS result files to human-readable formats (text, csv, json). ' +\n 'Typical workflow: (1) use list_query_run_results to find BQRS paths from previous codeql_query_run or codeql_database_analyze runs, ' +\n '(2) use codeql_bqrs_info to discover result sets and column schemas, ' +\n '(3) decode specific result sets with this tool. ' +\n 'For large result sets, use --rows to paginate.',\n command: 'codeql',\n subcommand: 'bqrs decode',\n inputSchema: {\n files: z.array(z.string()).describe('BQRS file(s) to decode'),\n output: createCodeQLSchemas.output(),\n format: z.enum(['csv', 'json', 'text', 'bqrs']).optional()\n .describe('Output format: text (human-readable table, default), csv, json (streaming JSON), or bqrs (binary, requires --output)'),\n 'result-set': z.string().optional()\n .describe('Decode a specific result set by name (use codeql_bqrs_info to list available sets). If omitted, all result sets are decoded.'),\n 'sort-key': z.string().optional()\n .describe('Sort by column(s): comma-separated column indices (0-based)'),\n 'sort-direction': z.string().optional()\n .describe('Sort direction(s): comma-separated \"asc\" or \"desc\" per column'),\n 'no-titles': z.boolean().optional()\n .describe('Omit column titles for text and csv formats'),\n entities: z.string().optional()\n .describe('Control entity column display: comma-separated list of url, string, id, all'),\n rows: z.number().optional()\n .describe('Maximum number of rows to output (for pagination). Use with --start-at for paging.'),\n 'start-at': z.number().optional()\n .describe('Byte offset to start decoding from (get from codeql_bqrs_info or previous JSON output \"next\" pointer). Must be used with --rows.'),\n verbose: createCodeQLSchemas.verbose(),\n additionalArgs: createCodeQLSchemas.additionalArgs()\n },\n examples: [\n 'codeql bqrs decode --format=csv --output=results.csv results.bqrs',\n 'codeql bqrs decode --format=json --rows=100 results.bqrs',\n 'codeql bqrs decode --result-set=#select --format=csv results.bqrs',\n 'codeql bqrs decode --format=json --entities=url,string results.bqrs'\n ],\n resultProcessor: createBQRSResultProcessor()\n};", "/**\n * Generic tool registry for creating MCP tools from CLI command definitions\n */\n\nimport { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport { z } from 'zod';\nimport { executeCodeQLCommand, executeQLTCommand, CLIExecutionResult } from './cli-executor';\nimport { logger } from '../utils/logger';\nimport { evaluateQueryResults, QueryEvaluationResult, extractQueryMetadata } from './query-results-evaluator';\nimport { getOrCreateLogDirectory } from './log-directory-manager';\nimport { getUserWorkspaceDir, packageRootDir, resolveToolQueryPackPath } from '../utils/package-paths';\nimport { writeFileSync, rmSync, existsSync, mkdirSync } from 'fs';\nimport { basename, dirname, isAbsolute, join, resolve } from 'path';\nimport { createProjectTempDir } from '../utils/temp-dir';\n\nexport type { CLIExecutionResult } from './cli-executor';\n\nexport interface CLIToolDefinition {\n name: string;\n description: string;\n command: 'codeql' | 'qlt';\n subcommand: string;\n inputSchema: Record;\n examples?: string[];\n resultProcessor?: (_result: CLIExecutionResult, _params: Record) => string;\n}\n\n/**\n * Default result processor that formats CLI output appropriately\n */\nexport const defaultCLIResultProcessor = (\n result: CLIExecutionResult, \n _params: Record\n): string => {\n if (!result.success) {\n return `Command failed (exit code ${result.exitCode || 'unknown'}):\\n${result.error || result.stderr}`;\n }\n \n let output = '';\n \n if (result.stdout) {\n output += result.stdout;\n }\n \n if (result.stderr) {\n if (output) {\n output += '\\n\\nWarnings/Info:\\n';\n }\n output += result.stderr;\n }\n \n if (!output) {\n output = 'Command executed successfully (no output)';\n }\n \n return output;\n};\n\n/**\n * Register a CLI tool with the MCP server\n */\nexport function registerCLITool(server: McpServer, definition: CLIToolDefinition): void {\n const {\n name,\n description,\n command,\n subcommand,\n inputSchema,\n resultProcessor = defaultCLIResultProcessor\n } = definition;\n\n server.tool(\n name,\n description,\n inputSchema,\n async (params: Record) => {\n // Track temporary directories for cleanup\n const tempDirsToCleanup: string[] = [];\n \n try {\n logger.info(`Executing CLI tool: ${name}`, { command, subcommand, params });\n\n // Separate positional arguments from named options\n // Extract tool-specific parameters that should not be passed to CLI\n // Note: format is extracted for tools that use it internally but not on CLI\n // For codeql_bqrs_interpret, codeql_bqrs_decode, codeql_bqrs_info, codeql_generate_query-help, and codeql_database_analyze, format should be passed to CLI\n const formatShouldBePassedToCLI = name === 'codeql_bqrs_interpret' || name === 'codeql_bqrs_decode' || name === 'codeql_bqrs_info' || name === 'codeql_generate_query-help' || name === 'codeql_database_analyze';\n \n const extractedParams = formatShouldBePassedToCLI\n ? {\n _positional: params._positional || [],\n files: params.files,\n file: params.file,\n dir: params.dir,\n packDir: params.packDir,\n tests: params.tests,\n query: params.query,\n queryName: params.queryName,\n queryLanguage: params.queryLanguage,\n queryPack: params.queryPack,\n sourceFiles: params.sourceFiles,\n sourceFunction: params.sourceFunction,\n targetFunction: params.targetFunction,\n interpretedOutput: params.interpretedOutput,\n evaluationFunction: params.evaluationFunction,\n evaluationOutput: params.evaluationOutput,\n directory: params.directory,\n logDir: params.logDir,\n qlref: params.qlref\n }\n : {\n _positional: params._positional || [],\n files: params.files,\n file: params.file,\n dir: params.dir,\n packDir: params.packDir,\n tests: params.tests,\n query: params.query,\n queryName: params.queryName,\n queryLanguage: params.queryLanguage,\n queryPack: params.queryPack, \n sourceFiles: params.sourceFiles,\n sourceFunction: params.sourceFunction,\n targetFunction: params.targetFunction,\n format: params.format,\n interpretedOutput: params.interpretedOutput,\n evaluationFunction: params.evaluationFunction,\n evaluationOutput: params.evaluationOutput,\n directory: params.directory,\n logDir: params.logDir,\n qlref: params.qlref\n };\n\n const {\n _positional = [],\n files,\n file,\n dir,\n packDir,\n tests,\n query,\n queryName,\n queryLanguage: _queryLanguage,\n queryPack: _queryPack,\n sourceFiles,\n sourceFunction,\n targetFunction,\n format: _format,\n interpretedOutput: _interpretedOutput,\n evaluationFunction: _evaluationFunction,\n evaluationOutput: _evaluationOutput,\n directory,\n logDir: customLogDir,\n qlref,\n } = extractedParams;\n\n // Get remaining options (everything not extracted above)\n const options = {...params};\n Object.keys(extractedParams).forEach(key => delete options[key]);\n let positionalArgs = Array.isArray(_positional) ? _positional as string[] : [_positional as string];\n\n // Handle files parameter as positional arguments for certain tools\n if (files && Array.isArray(files)) {\n positionalArgs = [...positionalArgs, ...files as string[]];\n }\n\n // Handle file parameter as positional argument for BQRS tools\n if (file && name.startsWith('codeql_bqrs_')) {\n positionalArgs = [...positionalArgs, file as string];\n }\n\n // Handle qlref parameter as positional argument for resolve qlref tool\n if (qlref && name === 'codeql_resolve_qlref') {\n positionalArgs = [...positionalArgs, qlref as string];\n }\n\n // Handle database parameter as positional argument for resolve database tool\n if (options.database && name === 'codeql_resolve_database') {\n positionalArgs = [...positionalArgs, options.database as string];\n delete options.database;\n }\n\n // Handle database parameter as positional argument for database create tool\n if (options.database && name === 'codeql_database_create') {\n positionalArgs = [...positionalArgs, options.database as string];\n delete options.database;\n }\n\n // Handle database and queries parameters as positional arguments for database analyze tool\n if (name === 'codeql_database_analyze') {\n if (options.database) {\n positionalArgs = [...positionalArgs, options.database as string];\n delete options.database;\n }\n if (options.queries) {\n positionalArgs = [...positionalArgs, options.queries as string];\n delete options.queries;\n }\n }\n\n // Handle query parameter as positional argument for generate query-help tool\n if (query && name === 'codeql_generate_query-help') {\n positionalArgs = [...positionalArgs, query as string];\n }\n\n // Handle dir parameter as positional argument for pack tools\n if (dir && (name === 'codeql_pack_ls')) {\n positionalArgs = [...positionalArgs, dir as string];\n }\n \n // Handle tool-specific parameters using switch pattern for better maintainability\n switch (name) {\n case 'codeql_test_accept':\n case 'codeql_test_extract':\n case 'codeql_test_run':\n case 'codeql_resolve_tests':\n // Handle tests parameter as positional arguments for test tools.\n // Resolve relative paths against the user's effective workspace\n // directory. In monorepo layouts this is the repo root; in npm-\n // installed layouts it falls back to process.cwd().\n if (tests && Array.isArray(tests)) {\n const userDir = getUserWorkspaceDir();\n positionalArgs = [...positionalArgs, ...(tests as string[]).map(\n t => isAbsolute(t) ? t : resolve(userDir, t)\n )];\n }\n break;\n \n case 'codeql_query_run': {\n // Resolve database path to absolute path if it's relative\n if (options.database && typeof options.database === 'string' && !isAbsolute(options.database)) {\n options.database = resolve(getUserWorkspaceDir(), options.database);\n logger.info(`Resolved database path to: ${options.database}`);\n }\n \n // Implement query resolution logic with enhanced results processing\n const resolvedQuery = await resolveQueryPath(params, logger);\n if (resolvedQuery) {\n positionalArgs = [...positionalArgs, resolvedQuery];\n } else if (query) {\n positionalArgs = [...positionalArgs, query as string];\n }\n \n // Handle external predicates for tool queries\n if (queryName === 'PrintAST' && sourceFiles) {\n // Create a CSV file with the source file paths for the external predicate\n // The external predicate expects a CSV file with one column containing file paths\n const filePaths = (sourceFiles as string).split(',').map((f: string) => f.trim());\n let tempDir: string;\n let csvPath: string;\n try {\n tempDir = createProjectTempDir('codeql-external-');\n tempDirsToCleanup.push(tempDir); // Track for cleanup\n csvPath = join(tempDir, 'selectedSourceFiles.csv');\n\n // Create CSV content\n const csvContent = filePaths.join('\\n') + '\\n';\n\n writeFileSync(csvPath, csvContent, 'utf8');\n } catch (err) {\n logger.error(`Failed to create external predicate CSV for PrintAST query at path ${csvPath || '[unknown]'}: ${err instanceof Error ? err.message : String(err)}`);\n throw err;\n }\n \n // Add the external predicate with the CSV file path\n const currentExternal = options.external || [];\n const externalArray = Array.isArray(currentExternal) ? currentExternal : [currentExternal];\n externalArray.push(`selectedSourceFiles=${csvPath}`);\n options.external = externalArray;\n \n logger.info(`Created external predicate CSV at ${csvPath} for files: ${filePaths.join(', ')}`);\n }\n \n // Handle external predicates for CallGraphFrom queries\n if (queryName === 'CallGraphFrom' && sourceFunction) {\n const functionNames = (sourceFunction as string).split(',').map((f: string) => f.trim());\n let tempDir: string;\n let csvPath: string;\n try {\n tempDir = createProjectTempDir('codeql-external-');\n tempDirsToCleanup.push(tempDir);\n csvPath = join(tempDir, 'sourceFunction.csv');\n\n // Create CSV content\n const csvContent = functionNames.join('\\n') + '\\n';\n\n writeFileSync(csvPath, csvContent, 'utf8');\n } catch (err) {\n logger.error(`Failed to create external predicate CSV for CallGraphFrom query at path ${csvPath || '[unknown]'}: ${err instanceof Error ? err.message : String(err)}`);\n throw err;\n }\n \n // Add the external predicate with the CSV file path\n const currentExternal = options.external || [];\n const externalArray = Array.isArray(currentExternal) ? currentExternal : [currentExternal];\n externalArray.push(`sourceFunction=${csvPath}`);\n options.external = externalArray;\n \n logger.info(`Created external predicate CSV at ${csvPath} for functions: ${functionNames.join(', ')}`);\n }\n \n // Handle external predicates for CallGraphTo queries\n if (queryName === 'CallGraphTo' && targetFunction) {\n const functionNames = (targetFunction as string).split(',').map((f: string) => f.trim());\n let tempDir: string;\n let csvPath: string;\n try {\n tempDir = createProjectTempDir('codeql-external-');\n tempDirsToCleanup.push(tempDir);\n csvPath = join(tempDir, 'targetFunction.csv');\n\n // Create CSV content\n const csvContent = functionNames.join('\\n') + '\\n';\n\n writeFileSync(csvPath, csvContent, 'utf8');\n } catch (err) {\n logger.error(`Failed to create external predicate CSV for CallGraphTo query at path ${csvPath || '[unknown]'}: ${err instanceof Error ? err.message : String(err)}`);\n throw err;\n }\n \n // Add the external predicate with the CSV file path\n const currentExternal = options.external || [];\n const externalArray = Array.isArray(currentExternal) ? currentExternal : [currentExternal];\n externalArray.push(`targetFunction=${csvPath}`);\n options.external = externalArray;\n \n logger.info(`Created external predicate CSV at ${csvPath} for functions: ${functionNames.join(', ')}`);\n }\n break;\n }\n \n case 'codeql_query_compile':\n case 'codeql_resolve_metadata':\n // Handle query parameter as positional argument for query compilation and metadata tools\n if (query) {\n positionalArgs = [...positionalArgs, query as string];\n }\n break;\n \n case 'codeql_resolve_queries':\n // Handle directory parameter as positional argument\n if (directory) {\n positionalArgs = [...positionalArgs, directory as string];\n }\n break;\n \n default:\n // No special parameter handling needed for other tools\n break;\n }\n\n // Set up logging directory for query/test/analyze runs\n let queryLogDir: string | undefined;\n if (name === 'codeql_query_run' || name === 'codeql_test_run' || name === 'codeql_database_analyze') {\n queryLogDir = getOrCreateLogDirectory(customLogDir as string | undefined);\n logger.info(`Using log directory for ${name}: ${queryLogDir}`);\n\n // Create timestamp file to track when query/test run started\n const timestampPath = join(queryLogDir, 'timestamp');\n writeFileSync(timestampPath, Date.now().toString(), 'utf8');\n\n // Set the --logdir option for CodeQL CLI\n options.logdir = queryLogDir;\n\n // Set verbosity to progress+ to generate detailed query.log/test.log\n if (!options.verbosity) {\n options.verbosity = 'progress+';\n }\n\n // Set evaluator-log if not explicitly provided\n if (!options['evaluator-log']) {\n options['evaluator-log'] = join(queryLogDir, 'evaluator-log.jsonl');\n }\n\n // Enable --tuple-counting by default for evaluator logging\n if (options['tuple-counting'] === undefined) {\n options['tuple-counting'] = true;\n }\n\n // For query run, also handle default output\n if (name === 'codeql_query_run') {\n // If output was not explicitly provided, set it to the log directory\n if (!options.output) {\n options.output = join(queryLogDir, 'results.bqrs');\n }\n }\n\n // Ensure the parent directory of --output exists (the CLI will not create it)\n if (options.output && typeof options.output === 'string') {\n const outputDir = dirname(options.output);\n mkdirSync(outputDir, { recursive: true });\n }\n }\n\n let result: CLIExecutionResult;\n \n if (command === 'codeql') {\n // For pack commands, set the working directory to where qlpack.yml is located.\n // Resolve to absolute path since the MCP server's cwd may differ from\n // the workspace root (especially when launched by VS Code).\n let cwd: string | undefined;\n if ((name === 'codeql_pack_install' || name === 'codeql_pack_ls') && (dir || packDir)) {\n const rawCwd = (dir || packDir) as string;\n // Resolve relative paths against the user's effective workspace\n // directory rather than a potentially read-only package root.\n cwd = isAbsolute(rawCwd) ? rawCwd : resolve(getUserWorkspaceDir(), rawCwd);\n }\n \n // Add --additional-packs for commands that need to access local test packs.\n // Only set the default examples path when it actually exists on disk\n // (it may be absent in npm-installed layouts where ql/javascript/examples/\n // is not included in the published package).\n const defaultExamplesPath = resolve(packageRootDir, 'ql', 'javascript', 'examples');\n const additionalPacksPath = process.env.CODEQL_ADDITIONAL_PACKS\n || (existsSync(defaultExamplesPath) ? defaultExamplesPath : undefined);\n if (additionalPacksPath && (name === 'codeql_test_run' || name === 'codeql_query_run' || name === 'codeql_query_compile' || name === 'codeql_database_analyze')) {\n options['additional-packs'] = additionalPacksPath;\n }\n \n // Keep test databases for codeql_test_run to allow subsequent query runs\n if (name === 'codeql_test_run') {\n options['keep-databases'] = true;\n }\n \n result = await executeCodeQLCommand(subcommand, options, positionalArgs, cwd);\n } else if (command === 'qlt') {\n result = await executeQLTCommand(subcommand, options, positionalArgs);\n } else {\n throw new Error(`Unsupported command: ${command}`);\n }\n\n // Post-execution processing for codeql_query_run\n if (name === 'codeql_query_run' && result.success && queryLogDir) {\n // Generate SARIF interpretation if results.bqrs exists and query path is known\n const bqrsPath = options.output as string;\n const sarifPath = join(queryLogDir, 'results-interpreted.sarif');\n\n // The query file path is the last positional argument (set during query resolution)\n const queryFilePath = positionalArgs.length > 0 ? positionalArgs[positionalArgs.length - 1] : undefined;\n\n if (existsSync(bqrsPath) && queryFilePath) {\n try {\n const sarifResult = await interpretBQRSFile(\n bqrsPath,\n queryFilePath,\n 'sarif-latest',\n sarifPath,\n logger\n );\n\n if (sarifResult.success) {\n logger.info(`Generated SARIF interpretation at ${sarifPath}`);\n } else {\n logger.warn(`SARIF interpretation returned error: ${sarifResult.error || sarifResult.stderr}`);\n }\n } catch (error) {\n logger.warn(`Failed to generate SARIF interpretation: ${error}`);\n }\n } else if (existsSync(bqrsPath) && !queryFilePath) {\n logger.warn('Skipping SARIF interpretation: query file path not available');\n }\n\n // Process evaluation results\n result = await processQueryRunResults(result, params, logger);\n }\n\n // Post-execution: generate evaluator log summary for query run / database analyze\n if ((name === 'codeql_query_run' || name === 'codeql_database_analyze') && result.success && queryLogDir) {\n const evalLogPath = options['evaluator-log'] as string | undefined;\n if (evalLogPath && existsSync(evalLogPath)) {\n try {\n const summaryPath = evalLogPath.replace(/\\.jsonl$/, '.summary.jsonl');\n // codeql generate log-summary takes positional args: []\n const summaryResult = await executeCodeQLCommand(\n 'generate log-summary',\n { format: 'predicates' },\n [evalLogPath, summaryPath]\n );\n\n if (summaryResult.success) {\n logger.info(`Generated evaluator log summary at ${summaryPath}`);\n }\n } catch (error) {\n logger.warn(`Failed to generate evaluator log summary: ${error}`);\n }\n }\n }\n\n // Process the result\n const processedResult = resultProcessor(result, params);\n\n return {\n content: [{\n type: 'text' as const,\n text: processedResult\n }],\n isError: !result.success\n };\n\n } catch (error) {\n logger.error(`Error in CLI tool ${name}:`, error);\n \n return {\n content: [{\n type: 'text' as const,\n text: `Failed to execute CLI tool: ${error instanceof Error ? error.message : String(error)}`\n }],\n isError: true\n };\n } finally {\n // Clean up temporary directories\n for (const tempDir of tempDirsToCleanup) {\n try {\n rmSync(tempDir, { recursive: true, force: true });\n logger.info(`Cleaned up temporary directory: ${tempDir}`);\n } catch (cleanupError) {\n logger.error(`Failed to clean up temporary directory ${tempDir}:`, cleanupError);\n }\n }\n }\n }\n );\n}\n\n/**\n * Helper function to create common CodeQL input schemas\n */\nexport const createCodeQLSchemas = {\n database: () => z.string().describe('Path to the CodeQL database'),\n \n query: () => z.string().describe('Path to the CodeQL query file (.ql)'),\n \n output: () => z.string().optional().describe('Output file path'),\n \n outputFormat: () => z.enum(['csv', 'json', 'bqrs', 'sarif-latest', 'sarifv2.1.0']).optional()\n .describe('Output format for results'),\n \n language: () => z.string().optional().describe('Programming language'),\n \n threads: () => z.number().optional().describe('Number of threads to use'),\n \n ram: () => z.number().optional().describe('Amount of RAM to use (MB)'),\n \n timeout: () => z.number().optional().describe('Timeout in seconds'),\n \n verbose: () => z.boolean().optional().describe('Enable verbose output'),\n \n additionalArgs: () => z.array(z.string()).optional().describe('Additional command-line arguments'),\n \n positionalArgs: () => z.array(z.string()).optional().describe('Positional arguments')\n .transform((val) => ({ _positional: val }))\n};\n\n/**\n * Helper function to create common QLT input schemas\n */\nexport const createQLTSchemas = {\n language: () => z.string().describe('Programming language'),\n \n output: () => z.string().optional().describe('Output directory or file path'),\n \n template: () => z.string().optional().describe('Template to use'),\n \n name: () => z.string().optional().describe('Name for generated query'),\n \n description: () => z.string().optional().describe('Description for generated query'),\n \n verbose: () => z.boolean().optional().describe('Enable verbose output'),\n \n force: () => z.boolean().optional().describe('Force overwrite existing files'),\n \n additionalArgs: () => z.array(z.string()).optional().describe('Additional command-line arguments')\n};\n\n/**\n * Create a result processor that formats BQRS output specially\n */\nexport const createBQRSResultProcessor = () => (\n result: CLIExecutionResult, \n params: Record\n): string => {\n if (!result.success) {\n return defaultCLIResultProcessor(result, params);\n }\n \n // For BQRS commands, provide more context about the output\n let output = result.stdout;\n \n if (params.output) {\n output += `\\n\\nResults saved to: ${params.output}`;\n }\n \n if (result.stderr) {\n output += `\\n\\nAdditional information:\\n${result.stderr}`;\n }\n \n return output;\n};\n\n/**\n * Create a result processor that formats database creation output\n */\nexport const createDatabaseResultProcessor = () => (\n result: CLIExecutionResult, \n params: Record\n): string => {\n if (!result.success) {\n return defaultCLIResultProcessor(result, params);\n }\n \n let output = 'Database creation completed successfully';\n \n if (params.database || params._positional) {\n const dbPath = params.database || (Array.isArray(params._positional) ? params._positional[0] : params._positional);\n output += `\\n\\nDatabase location: ${dbPath}`;\n }\n \n if (result.stdout) {\n output += `\\n\\nOutput:\\n${result.stdout}`;\n }\n \n if (result.stderr) {\n output += `\\n\\nAdditional information:\\n${result.stderr}`;\n }\n \n return output;\n};\n\n/**\n * Resolve query path for codeql_query_run tool\n * If queryName and queryLanguage are provided, resolve using codeql resolve queries\n */\nasync function resolveQueryPath(\n params: Record, \n logger: { info: (_message: string, ..._args: unknown[]) => void; error: (_message: string, ..._args: unknown[]) => void }\n): Promise {\n const { queryName, queryLanguage, queryPack, query } = params;\n \n // Validate parameter usage - queryName and query are mutually exclusive\n if (queryName && query) {\n logger.error('Cannot use both \"query\" and \"queryName\" parameters simultaneously. Use either \"query\" for direct file path OR \"queryName\" + \"queryLanguage\" for tool queries.');\n throw new Error('Cannot use both \"query\" and \"queryName\" parameters simultaneously. Use either \"query\" for direct file path OR \"queryName\" + \"queryLanguage\" for tool queries.');\n }\n \n // If no queryName provided, fall back to direct query parameter\n if (!queryName) {\n return query as string || null;\n }\n \n // If queryName provided but no language, we can't resolve\n if (!queryLanguage) {\n logger.error('queryLanguage is required when using queryName parameter. Supported languages: actions, cpp, csharp, go, java, javascript, python, ruby, swift');\n throw new Error('queryLanguage is required when using queryName parameter. Supported languages: actions, cpp, csharp, go, java, javascript, python, ruby, swift');\n }\n \n try {\n // Determine the query pack path - use absolute path to ensure it works regardless of cwd\n const defaultPackPath = resolveToolQueryPackPath(queryLanguage as string);\n const packPath = queryPack as string || defaultPackPath;\n \n logger.info(`Resolving query: ${queryName} for language: ${queryLanguage} in pack: ${packPath}`);\n \n // Execute codeql resolve queries to get available queries\n const { executeCodeQLCommand } = await import('./cli-executor');\n const resolveResult = await executeCodeQLCommand(\n 'resolve queries',\n { format: 'json' },\n [packPath]\n );\n \n if (!resolveResult.success) {\n logger.error('Failed to resolve queries:', resolveResult.stderr || resolveResult.error);\n throw new Error(`Failed to resolve queries: ${resolveResult.stderr || resolveResult.error}`);\n }\n \n // Parse the JSON output to find matching queries\n let resolvedQueries: string[];\n try {\n resolvedQueries = JSON.parse(resolveResult.stdout);\n } catch (parseError) {\n logger.error('Failed to parse resolve queries output:', parseError);\n throw new Error('Failed to parse resolve queries output');\n }\n \n // Find the query that matches the requested name exactly\n const matchingQuery = resolvedQueries.find(queryPath => {\n const fileName = basename(queryPath);\n // Match exact query name: \"PrintAST\" should match \"PrintAST.ql\" only\n return fileName === `${queryName}.ql`;\n });\n\n if (!matchingQuery) {\n logger.error(`Query \"${queryName}.ql\" not found in pack \"${packPath}\". Available queries:`, resolvedQueries.map(q => basename(q)));\n throw new Error(`Query \"${queryName}.ql\" not found in pack \"${packPath}\"`);\n }\n \n logger.info(`Resolved query \"${queryName}\" to: ${matchingQuery}`);\n return matchingQuery;\n \n } catch (error) {\n logger.error('Error resolving query path:', error);\n throw error;\n }\n}\n\n/**\n * Interpret BQRS file using codeql bqrs interpret\n */\nasync function interpretBQRSFile(\n bqrsPath: string,\n queryPath: string,\n format: string,\n outputPath: string,\n logger: { info: (_message: string, ..._args: unknown[]) => void; error: (_message: string, ..._args: unknown[]) => void }\n): Promise {\n try {\n // Extract query metadata to get id and kind\n const metadata = await extractQueryMetadata(queryPath);\n \n // Validate required metadata fields\n const missingFields = [];\n if (!metadata.id) missingFields.push('id');\n if (!metadata.kind) missingFields.push('kind');\n \n if (missingFields.length > 0) {\n return {\n success: false,\n exitCode: 1,\n stdout: '',\n stderr: '',\n error: `Query metadata is incomplete. Missing required field(s): ${missingFields.join(', ')}. Ensure the query file contains @id and @kind metadata.`\n };\n }\n \n // Sanitize metadata values to prevent command injection\n const sanitizedKind = (metadata.kind || '').replace(/[^a-zA-Z0-9_-]/g, '');\n const sanitizedId = (metadata.id || '').replace(/[^a-zA-Z0-9_/:-]/g, '');\n \n // Validate format for query kind\n const graphFormats = ['graphtext', 'dgml', 'dot'];\n if (graphFormats.includes(format) && metadata.kind !== 'graph') {\n return {\n success: false,\n exitCode: 1,\n stdout: '',\n stderr: '',\n error: `Format '${format}' is only compatible with @kind graph queries, but this query has @kind ${metadata.kind}`\n };\n }\n \n // Ensure output directory exists\n mkdirSync(dirname(outputPath), { recursive: true });\n \n // Build the codeql bqrs interpret command\n const params: Record = {\n format: format,\n output: outputPath,\n t: [`kind=${sanitizedKind}`, `id=${sanitizedId}`]\n };\n \n logger.info(`Interpreting BQRS file ${bqrsPath} with format ${format} to ${outputPath}`);\n \n // Execute codeql bqrs interpret\n const result = await executeCodeQLCommand(\n 'bqrs interpret',\n params,\n [bqrsPath]\n );\n \n return result;\n } catch (error) {\n return {\n success: false,\n exitCode: 1,\n stdout: '',\n stderr: '',\n error: `Failed to interpret BQRS file: ${error}`\n };\n }\n}\n\n/**\n * Get default output extension based on format\n */\nfunction getDefaultExtension(format: string): string {\n switch (format) {\n case 'sarif-latest':\n case 'sarifv2.1.0':\n return '.sarif';\n case 'csv':\n return '.csv';\n case 'graphtext':\n return '.txt';\n case 'dgml':\n return '.dgml';\n case 'dot':\n return '.dot';\n default:\n return '.txt';\n }\n}\n\n/**\n * Process query run results with optional interpretation or evaluation\n */\nasync function processQueryRunResults(\n result: CLIExecutionResult,\n params: Record,\n logger: { info: (_message: string, ..._args: unknown[]) => void; error: (_message: string, ..._args: unknown[]) => void }\n): Promise {\n try {\n const { format, interpretedOutput, evaluationFunction, evaluationOutput, output, query, queryName, queryLanguage } = params;\n \n // If no format or evaluationFunction specified, return as-is\n if (!format && !evaluationFunction) {\n return result;\n }\n \n // Ensure output (bqrs file) was generated\n if (!output) {\n return result;\n }\n \n const bqrsPath = output as string;\n \n // Determine the query path for metadata extraction\n let queryPath: string | null = null;\n \n if (query) {\n queryPath = query as string;\n } else if (queryName && queryLanguage) {\n // Try to resolve the query path again for evaluation\n queryPath = await resolveQueryPath(params, logger);\n }\n \n if (!queryPath) {\n logger.error('Cannot determine query path for interpretation/evaluation');\n return {\n ...result,\n stdout: result.stdout + '\\n\\nWarning: Query interpretation skipped - could not determine query path'\n };\n }\n \n // Handle new format parameter (preferred approach)\n if (format) {\n const outputFormat = format as string;\n \n // Determine output path\n let outputFilePath = interpretedOutput as string | undefined;\n if (!outputFilePath) {\n const ext = getDefaultExtension(outputFormat);\n outputFilePath = bqrsPath.replace('.bqrs', ext);\n }\n \n logger.info(`Interpreting query results from ${bqrsPath} with format: ${outputFormat}`);\n \n // Interpret the BQRS file\n const interpretResult = await interpretBQRSFile(\n bqrsPath,\n queryPath,\n outputFormat,\n outputFilePath,\n logger\n );\n \n if (interpretResult.success) {\n let enhancedOutput = result.stdout;\n enhancedOutput += `\\n\\nQuery results interpreted successfully with format: ${outputFormat}`;\n enhancedOutput += `\\nInterpreted output saved to: ${outputFilePath}`;\n \n return {\n ...result,\n stdout: enhancedOutput\n };\n } else {\n logger.error('Query interpretation failed:', interpretResult.error);\n return {\n ...result,\n stdout: result.stdout + `\\n\\nWarning: Query interpretation failed - ${interpretResult.error || interpretResult.stderr}`\n };\n }\n }\n \n // Handle legacy evaluationFunction parameter (deprecated)\n if (evaluationFunction) {\n logger.info(`Using deprecated evaluationFunction parameter. Consider using format parameter instead.`);\n logger.info(`Evaluating query results from ${bqrsPath} using function: ${evaluationFunction}`);\n \n // Perform the evaluation\n const evaluationResult: QueryEvaluationResult = await evaluateQueryResults(\n bqrsPath,\n queryPath,\n evaluationFunction as string,\n evaluationOutput as string | undefined\n );\n \n if (evaluationResult.success) {\n // Append evaluation results to the command output\n let enhancedOutput = result.stdout;\n \n if (evaluationResult.outputPath) {\n enhancedOutput += `\\n\\nQuery evaluation completed successfully.`;\n enhancedOutput += `\\nEvaluation output saved to: ${evaluationResult.outputPath}`;\n }\n \n if (evaluationResult.content) {\n enhancedOutput += `\\n\\n=== Query Results Evaluation ===\\n`;\n enhancedOutput += evaluationResult.content;\n }\n \n return {\n ...result,\n stdout: enhancedOutput\n };\n } else {\n // Evaluation failed, but don't fail the whole operation\n logger.error('Query evaluation failed:', evaluationResult.error);\n return {\n ...result,\n stdout: result.stdout + `\\n\\nWarning: Query evaluation failed - ${evaluationResult.error}`\n };\n }\n }\n \n return result;\n } catch (error) {\n logger.error('Error in query results processing:', error);\n return {\n ...result,\n stdout: result.stdout + `\\n\\nWarning: Query processing error - ${error}`\n };\n }\n}", "/**\n * Query results evaluation functions for processing .bqrs files\n */\n\nimport { executeCodeQLCommand } from './cli-executor';\nimport { logger } from '../utils/logger';\nimport { writeFileSync, readFileSync } from 'fs';\nimport { dirname, isAbsolute } from 'path';\nimport { mkdirSync } from 'fs';\n\nexport interface QueryEvaluationResult {\n success: boolean;\n outputPath?: string;\n content?: string;\n error?: string;\n}\n\nexport interface QueryMetadata {\n kind?: string;\n name?: string;\n description?: string;\n id?: string;\n tags?: string[];\n}\n\n/**\n * Built-in evaluation functions\n */\nexport const BUILT_IN_EVALUATORS = {\n 'json-decode': 'JSON format decoder for query results',\n 'csv-decode': 'CSV format decoder for query results', \n 'mermaid-graph': 'Mermaid diagram generator for @kind graph queries (like PrintAST)',\n} as const;\n\nexport type BuiltInEvaluator = keyof typeof BUILT_IN_EVALUATORS;\n\n/**\n * Extract metadata from a CodeQL query file\n */\nexport async function extractQueryMetadata(queryPath: string): Promise {\n try {\n const queryContent = readFileSync(queryPath, 'utf-8');\n const metadata: QueryMetadata = {};\n \n // Extract metadata from comments using regex patterns\n const kindMatch = queryContent.match(/@kind\\s+([^\\s]+)/);\n if (kindMatch) metadata.kind = kindMatch[1];\n \n const nameMatch = queryContent.match(/@name\\s+(.+)/);\n if (nameMatch) metadata.name = nameMatch[1].trim();\n \n const descMatch = queryContent.match(/@description\\s+(.+)/);\n if (descMatch) metadata.description = descMatch[1].trim();\n \n const idMatch = queryContent.match(/@id\\s+(.+)/);\n if (idMatch) metadata.id = idMatch[1].trim();\n \n const tagsMatch = queryContent.match(/@tags\\s+(.+)/);\n if (tagsMatch) {\n metadata.tags = tagsMatch[1].split(/\\s+/).filter(t => t.length > 0);\n }\n \n return metadata;\n } catch (error) {\n logger.error('Failed to extract query metadata:', error);\n return {};\n }\n}\n\n/**\n * JSON decoder - converts .bqrs to JSON format\n */\nexport async function evaluateWithJsonDecoder(\n bqrsPath: string, \n outputPath?: string\n): Promise {\n try {\n const result = await executeCodeQLCommand(\n 'bqrs decode',\n { format: 'json' },\n [bqrsPath]\n );\n \n if (!result.success) {\n return {\n success: false,\n error: `Failed to decode BQRS file: ${result.stderr || result.error}`\n };\n }\n \n const defaultOutputPath = outputPath || bqrsPath.replace('.bqrs', '.json');\n \n // Ensure output directory exists\n mkdirSync(dirname(defaultOutputPath), { recursive: true });\n \n // Write JSON results\n writeFileSync(defaultOutputPath, result.stdout);\n \n return {\n success: true,\n outputPath: defaultOutputPath,\n content: result.stdout\n };\n } catch (error) {\n return {\n success: false,\n error: `JSON evaluation failed: ${error}`\n };\n }\n}\n\n/**\n * CSV decoder - converts .bqrs to CSV format\n */\nexport async function evaluateWithCsvDecoder(\n bqrsPath: string,\n outputPath?: string\n): Promise {\n try {\n const result = await executeCodeQLCommand(\n 'bqrs decode',\n { format: 'csv' },\n [bqrsPath]\n );\n \n if (!result.success) {\n return {\n success: false,\n error: `Failed to decode BQRS file: ${result.stderr || result.error}`\n };\n }\n \n const defaultOutputPath = outputPath || bqrsPath.replace('.bqrs', '.csv');\n \n // Ensure output directory exists\n mkdirSync(dirname(defaultOutputPath), { recursive: true });\n \n // Write CSV results\n writeFileSync(defaultOutputPath, result.stdout);\n \n return {\n success: true,\n outputPath: defaultOutputPath,\n content: result.stdout\n };\n } catch (error) {\n return {\n success: false,\n error: `CSV evaluation failed: ${error}`\n };\n }\n}\n\n/**\n * Mermaid graph generator - converts @kind graph query results to mermaid diagrams\n */\nexport async function evaluateWithMermaidGraph(\n bqrsPath: string,\n queryPath: string,\n outputPath?: string\n): Promise {\n try {\n // First extract query metadata to confirm this is a graph query\n const metadata = await extractQueryMetadata(queryPath);\n \n if (metadata.kind !== 'graph') {\n logger.error(`Query is not a graph query (kind: ${metadata.kind}), mermaid-graph evaluation is only for @kind graph queries`);\n return {\n success: false,\n error: `Query is not a graph query (kind: ${metadata.kind}), mermaid-graph evaluation is only for @kind graph queries`\n };\n }\n \n // Decode the BQRS file to JSON first\n const jsonResult = await executeCodeQLCommand(\n 'bqrs decode',\n { format: 'json' },\n [bqrsPath]\n );\n \n if (!jsonResult.success) {\n return {\n success: false,\n error: `Failed to decode BQRS file: ${jsonResult.stderr || jsonResult.error}`\n };\n }\n \n // Parse the JSON results\n let queryResults;\n try {\n queryResults = JSON.parse(jsonResult.stdout);\n } catch (parseError) {\n return {\n success: false,\n error: `Failed to parse query results JSON: ${parseError}`\n };\n }\n \n // Generate mermaid diagram from graph results\n const mermaidContent = generateMermaidFromGraphResults(queryResults, metadata);\n \n const defaultOutputPath = outputPath || bqrsPath.replace('.bqrs', '.md');\n \n // Ensure output directory exists\n mkdirSync(dirname(defaultOutputPath), { recursive: true });\n \n // Write markdown file with mermaid diagram\n writeFileSync(defaultOutputPath, mermaidContent);\n \n return {\n success: true,\n outputPath: defaultOutputPath,\n content: mermaidContent\n };\n } catch (error) {\n return {\n success: false,\n error: `Mermaid graph evaluation failed: ${error}`\n };\n }\n}\n\n/**\n * Generate mermaid diagram from CodeQL graph query results\n */\nfunction generateMermaidFromGraphResults(queryResults: unknown, metadata: QueryMetadata): string {\n const queryName = sanitizeMarkdown(metadata.name || 'CodeQL Query Results');\n const queryDesc = sanitizeMarkdown(metadata.description || 'Graph visualization of CodeQL query results');\n \n let mermaidContent = `# ${queryName}\\n\\n${queryDesc}\\n\\n`;\n \n // Handle different result structures that CodeQL graph queries can produce\n if (!queryResults || typeof queryResults !== 'object') {\n mermaidContent += '```mermaid\\ngraph TD\\n A[No Results]\\n```\\n';\n return mermaidContent;\n }\n \n // Check if results have the expected structure for graph queries\n const tuples = queryResults.tuples || queryResults;\n \n if (!Array.isArray(tuples) || tuples.length === 0) {\n mermaidContent += '```mermaid\\ngraph TD\\n A[No Graph Data]\\n```\\n';\n return mermaidContent;\n }\n \n mermaidContent += '```mermaid\\ngraph TD\\n';\n \n // Track nodes and edges to avoid duplicates\n const nodes = new Set();\n const edges = new Set();\n \n // Process each tuple in the results\n tuples.forEach((tuple: unknown, index: number) => {\n if (Array.isArray(tuple) && tuple.length >= 2) {\n // Extract source and target from tuple\n const source = sanitizeNodeId(tuple[0]?.toString() || `node_${index}_0`);\n const target = sanitizeNodeId(tuple[1]?.toString() || `node_${index}_1`);\n const label = tuple[2]?.toString() || '';\n \n // Add nodes\n nodes.add(source);\n nodes.add(target);\n \n // Add edge\n const edgeId = `${source}_${target}`;\n if (!edges.has(edgeId)) {\n if (label) {\n mermaidContent += ` ${source} -->|${sanitizeLabel(label)}| ${target}\\n`;\n } else {\n mermaidContent += ` ${source} --> ${target}\\n`;\n }\n edges.add(edgeId);\n }\n } else if (typeof tuple === 'object' && tuple !== null) {\n // Handle object-based results\n const source = sanitizeNodeId(tuple.source?.toString() || tuple.from?.toString() || `node_${index}_src`);\n const target = sanitizeNodeId(tuple.target?.toString() || tuple.to?.toString() || `node_${index}_tgt`);\n const label = tuple.label?.toString() || tuple.relation?.toString() || '';\n \n nodes.add(source);\n nodes.add(target);\n \n const edgeId = `${source}_${target}`;\n if (!edges.has(edgeId)) {\n if (label) {\n mermaidContent += ` ${source} -->|${sanitizeLabel(label)}| ${target}\\n`;\n } else {\n mermaidContent += ` ${source} --> ${target}\\n`;\n }\n edges.add(edgeId);\n }\n }\n });\n \n // If no edges were created, create a simple diagram showing the first few nodes\n if (edges.size === 0 && nodes.size > 0) {\n const nodeArray = Array.from(nodes).slice(0, 10); // Limit to avoid clutter\n nodeArray.forEach((node, index) => {\n if (index === 0) {\n mermaidContent += ` ${node}[${sanitizeLabel(node)}]\\n`;\n } else {\n mermaidContent += ` ${nodeArray[0]} --> ${node}\\n`;\n }\n });\n }\n \n mermaidContent += '```\\n\\n';\n \n // Add statistics\n mermaidContent += `## Query Statistics\\n\\n`;\n mermaidContent += `- Total nodes: ${nodes.size}\\n`;\n mermaidContent += `- Total edges: ${edges.size}\\n`;\n mermaidContent += `- Total tuples processed: ${tuples.length}\\n`;\n \n return mermaidContent;\n}\n\n/**\n * Sanitize node IDs for mermaid compatibility\n */\nfunction sanitizeNodeId(id: string): string {\n return id\n .replace(/[^a-zA-Z0-9_]/g, '_')\n .replace(/^(\\d)/, 'n$1') // Prefix with 'n' if starts with number\n .substring(0, 50); // Limit length\n}\n\n/**\n * Sanitize labels for mermaid compatibility\n */\nfunction sanitizeLabel(label: string): string {\n return label\n .replace(/[|\"`<>\\n\\r\\t]/g, '') // Remove problematic characters including backticks, newlines, angle brackets\n .replace(/\\s+/g, ' ') // Normalize whitespace\n .trim()\n .substring(0, 30); // Limit length for readability\n}\n\n/**\n * Sanitize markdown content to prevent injection\n */\nfunction sanitizeMarkdown(content: string): string {\n return content\n .replace(/[<>\"`]/g, '') // Remove potentially dangerous characters\n .replace(/\\n/g, ' ') // Convert newlines to spaces\n .replace(/\\s+/g, ' ') // Normalize whitespace\n .trim()\n .substring(0, 100); // Limit length\n}\n\n/**\n * Main evaluation function that determines which evaluator to use\n */\nexport async function evaluateQueryResults(\n bqrsPath: string,\n queryPath: string,\n evaluationFunction?: string,\n outputPath?: string\n): Promise {\n try {\n // If no evaluation function specified, default to json-decode\n const evalFunc = evaluationFunction || 'json-decode';\n \n logger.info(`Evaluating query results with function: ${evalFunc}`);\n \n // Handle built-in evaluation functions\n switch (evalFunc) {\n case 'json-decode':\n return await evaluateWithJsonDecoder(bqrsPath, outputPath);\n \n case 'csv-decode':\n return await evaluateWithCsvDecoder(bqrsPath, outputPath);\n \n case 'mermaid-graph':\n return await evaluateWithMermaidGraph(bqrsPath, queryPath, outputPath);\n \n default:\n // Check if it's a path to a custom evaluation script\n if (isAbsolute(evalFunc)) {\n return await evaluateWithCustomScript(bqrsPath, queryPath, evalFunc, outputPath);\n } else {\n return {\n success: false,\n error: `Unknown evaluation function: ${evalFunc}. Available built-in functions: ${Object.keys(BUILT_IN_EVALUATORS).join(', ')}`\n };\n }\n }\n } catch (error) {\n return {\n success: false,\n error: `Query evaluation failed: ${error}`\n };\n }\n}\n\n/**\n * Execute custom evaluation script\n */\nasync function evaluateWithCustomScript(\n _bqrsPath: string,\n _queryPath: string,\n _scriptPath: string,\n _outputPath?: string\n): Promise {\n // TODO: Implement custom script execution\n // This would need to execute the script with bqrsPath and queryPath as arguments\n // and capture the output\n return {\n success: false,\n error: 'Custom evaluation scripts are not yet implemented'\n };\n}", "/**\n * Log directory management utilities for CodeQL query and test runs\n */\n\nimport { mkdirSync, existsSync } from 'fs';\nimport { join, resolve } from 'path';\nimport { randomBytes } from 'crypto';\nimport { getProjectTmpDir } from '../utils/temp-dir';\n\n/**\n * Ensure that a given path is within a base directory.\n * Throws an error if the path is outside the base directory.\n */\nfunction ensurePathWithinBase(baseDir: string, targetPath: string): string {\n const absBase = resolve(baseDir);\n const absTarget = resolve(targetPath);\n if (!absTarget.startsWith(absBase + '/') && absTarget !== absBase) {\n throw new Error(`Provided log directory is outside the allowed base directory: ${absBase}`);\n }\n return absTarget;\n}\n\n/**\n * Get or create a unique log directory for query/test runs\n * \n * @param logDir - Optional custom log directory from parameters\n * @returns Absolute path to the log directory\n */\nexport function getOrCreateLogDirectory(logDir?: string): string {\n // Use CODEQL_QUERY_LOG_DIR env var or default base\n const baseLogDir = process.env.CODEQL_QUERY_LOG_DIR || getProjectTmpDir('query-logs');\n\n // If logDir is explicitly provided, validate it is within baseLogDir\n if (logDir) {\n const absLogDir = ensurePathWithinBase(baseLogDir, logDir);\n if (!existsSync(absLogDir)) {\n mkdirSync(absLogDir, { recursive: true });\n }\n return absLogDir;\n }\n \n // Otherwise, use baseLogDir and create a unique subdirectory\n \n // Create base directory if it doesn't exist\n if (!existsSync(baseLogDir)) {\n mkdirSync(baseLogDir, { recursive: true });\n }\n \n // Generate unique subdirectory with timestamp and random ID\n const timestamp = new Date().toISOString().replace(/[:.]/g, '-');\n const uniqueId = randomBytes(4).toString('hex');\n const uniqueLogDir = join(baseLogDir, `query-run-${timestamp}-${uniqueId}`);\n \n mkdirSync(uniqueLogDir, { recursive: true });\n \n return uniqueLogDir;\n}\n", "/**\n * CodeQL BQRS info tool\n *\n * Lists result sets, column schemas, and row counts in a BQRS file.\n * Use this tool before codeql_bqrs_decode to discover available result\n * sets and their column types. BQRS files are produced by codeql_query_run\n * and codeql_database_analyze \u2014 use list_query_run_results to find them.\n */\n\nimport { z } from 'zod';\nimport { CLIToolDefinition, createCodeQLSchemas, createBQRSResultProcessor } from '../../lib/cli-tool-registry';\n\nexport const codeqlBqrsInfoTool: CLIToolDefinition = {\n name: 'codeql_bqrs_info',\n description:\n 'Get metadata about BQRS result files: lists result sets, column names/types, and row counts. ' +\n 'Use before codeql_bqrs_decode to discover available result sets (e.g., \"#select\", \"edges\", \"nodes\"). ' +\n 'BQRS files are found at /results.bqrs \u2014 use list_query_run_results to discover them. ' +\n 'Use --format=json with --paginate-rows to get byte offsets for paginated decoding with codeql_bqrs_decode --start-at.',\n command: 'codeql',\n subcommand: 'bqrs info',\n inputSchema: {\n files: z.array(z.string()).describe('BQRS file(s) to examine'),\n format: z.enum(['text', 'json']).optional()\n .describe('Output format: text (default) or json. Use json for machine-readable output and pagination offset computation.'),\n 'paginate-rows': z.number().optional()\n .describe('Compute byte offsets for pagination at intervals of this many rows. Use with --format=json. Offsets can be passed to codeql_bqrs_decode --start-at.'),\n 'paginate-result-set': z.string().optional()\n .describe('Compute pagination offsets only for this result set name'),\n verbose: createCodeQLSchemas.verbose(),\n additionalArgs: createCodeQLSchemas.additionalArgs()\n },\n examples: [\n 'codeql bqrs info results.bqrs',\n 'codeql bqrs info --format=json results.bqrs',\n 'codeql bqrs info --format=json --paginate-rows=100 --paginate-result-set=#select results.bqrs'\n ],\n resultProcessor: createBQRSResultProcessor()\n};", "/**\n * CodeQL BQRS interpret tool\n */\n\nimport { z } from 'zod';\nimport { CLIToolDefinition, createCodeQLSchemas, createBQRSResultProcessor } from '../../lib/cli-tool-registry';\n\nexport const codeqlBqrsInterpretTool: CLIToolDefinition = {\n name: 'codeql_bqrs_interpret',\n description: 'Interpret BQRS result files according to query metadata and generate output in specified formats (CSV, SARIF, graph formats)',\n command: 'codeql',\n subcommand: 'bqrs interpret',\n inputSchema: {\n file: z.string().describe('The BQRS file to interpret'),\n format: z.enum(['csv', 'sarif-latest', 'sarifv2.1.0', 'graphtext', 'dgml', 'dot'])\n .describe('Output format: csv (comma-separated), sarif-latest/sarifv2.1.0 (SARIF), graphtext/dgml/dot (graph formats, only for @kind graph queries)'),\n output: createCodeQLSchemas.output(),\n t: z.array(z.string())\n .describe('Query metadata key=value pairs. At least \"kind\" and \"id\" must be specified (e.g., [\"kind=graph\", \"id=js/print-ast\"])'),\n 'max-paths': z.number().optional()\n .describe('Maximum number of paths to produce for each alert with paths (default: 4)'),\n 'sarif-add-file-contents': z.boolean().optional()\n .describe('[SARIF only] Include full file contents for all files referenced in results'),\n 'sarif-add-snippets': z.boolean().optional()\n .describe('[SARIF only] Include code snippets for each location with context'),\n 'sarif-group-rules-by-pack': z.boolean().optional()\n .describe('[SARIF only] Place rule objects under their QL pack in tool.extensions property'),\n 'sarif-multicause-markdown': z.boolean().optional()\n .describe('[SARIF only] Include multi-cause alerts as Markdown-formatted lists'),\n 'sarif-category': z.string().optional()\n .describe('[SARIF only] Category for this analysis (distinguishes multiple analyses on same code)'),\n 'csv-location-format': z.enum(['uri', 'line-column', 'offset-length']).optional()\n .describe('[CSV only] Format for locations in CSV output (default: line-column)'),\n 'dot-location-url-format': z.string().optional()\n .describe('[DOT only] Format string for file location URLs (placeholders: {path}, {start:line}, {start:column}, {end:line}, {end:column}, {offset}, {length})'),\n threads: z.number().optional()\n .describe('Number of threads for computing paths (0 = one per core, -N = leave N cores unused)'),\n 'column-kind': z.enum(['utf8', 'utf16', 'utf32', 'bytes']).optional()\n .describe('[SARIF only] Column kind for interpreting location columns'),\n 'unicode-new-lines': z.boolean().optional()\n .describe('[SARIF only] Whether unicode newlines (U+2028, U+2029) are considered as newlines'),\n verbose: createCodeQLSchemas.verbose(),\n additionalArgs: createCodeQLSchemas.additionalArgs()\n },\n examples: [\n 'codeql bqrs interpret --format=sarif-latest --output=results.sarif -t kind=problem -t id=js/sql-injection results.bqrs',\n 'codeql bqrs interpret --format=graphtext --output=ast.txt -t kind=graph -t id=js/print-ast results.bqrs',\n 'codeql bqrs interpret --format=csv --csv-location-format=line-column --output=results.csv -t kind=problem -t id=js/xss results.bqrs',\n 'codeql bqrs interpret --format=dot --output=graph.dot -t kind=graph -t id=java/call-graph results.bqrs',\n 'codeql bqrs interpret --format=sarif-latest --sarif-add-snippets --sarif-category=security --output=results.sarif -t kind=path-problem -t id=go/path-injection results.bqrs'\n ],\n resultProcessor: createBQRSResultProcessor()\n};\n", "/**\n * CodeQL database analyze tool\n */\n\nimport { z } from 'zod';\nimport { CLIToolDefinition } from '../../lib/cli-tool-registry';\n\nexport const codeqlDatabaseAnalyzeTool: CLIToolDefinition = {\n name: 'codeql_database_analyze',\n description:\n 'Run queries or query suites against CodeQL databases. ' +\n 'Produces evaluator logs, BQRS results, and optionally SARIF output. ' +\n 'Use list_codeql_databases to discover available databases, and register_database to register new ones. ' +\n 'After analysis completes, use list_query_run_results to find result artifacts, then codeql_bqrs_info and codeql_bqrs_decode to inspect results.',\n command: 'codeql',\n subcommand: 'database analyze',\n inputSchema: {\n database: z.string().describe('Path to the CodeQL database'),\n queries: z.string().describe('Queries or query suite to run'),\n output: z.string().optional().describe('Output file path'),\n format: z.enum(['csv', 'json', 'sarif-latest', 'sarifv2.1.0']).optional()\n .describe('Output format for results'),\n 'download-location': z.string().optional()\n .describe('Location to download missing dependencies'),\n threads: z.number().optional().describe('Number of threads to use'),\n ram: z.number().optional().describe('Amount of RAM to use (MB)'),\n timeout: z.number().optional().describe('Timeout in seconds'),\n logDir: z.string().optional()\n .describe('Custom directory for analysis execution logs (overrides CODEQL_QUERY_LOG_DIR environment variable). If not provided, uses CODEQL_QUERY_LOG_DIR or defaults to .tmp/query-logs/'),\n 'evaluator-log': z.string().optional()\n .describe('Path to save evaluator log. If not provided and logDir is set, defaults to /evaluator-log.jsonl'),\n 'tuple-counting': z.boolean().optional()\n .describe('Display tuple counts for each evaluation step in evaluator logs'),\n 'evaluator-log-level': z.number().min(1).max(5).optional()\n .describe('Evaluator log verbosity level (1-5, default 5)'),\n rerun: z.boolean().optional()\n .describe('Force re-evaluation of queries even if BQRS results already exist in the database. Without this, cached results are reused.'),\n verbose: z.boolean().optional().describe('Enable verbose output'),\n additionalArgs: z.array(z.string()).optional().describe('Additional command-line arguments')\n },\n examples: [\n 'codeql database analyze mydb queries.qls --format=sarif-latest --output=results.sarif',\n 'codeql database analyze mydb codeql/java-queries --format=csv',\n 'codeql database analyze mydb queries.qls --format=sarif-latest --output=results.sarif --rerun --tuple-counting'\n ]\n};", "/**\n * CodeQL database create tool\n */\n\nimport { z } from 'zod';\nimport { CLIToolDefinition, createDatabaseResultProcessor } from '../../lib/cli-tool-registry';\n\nexport const codeqlDatabaseCreateTool: CLIToolDefinition = {\n name: 'codeql_database_create',\n description: 'Create a CodeQL database from source code',\n command: 'codeql',\n subcommand: 'database create',\n inputSchema: {\n database: z.string().describe('Database path/name to create'),\n language: z.string().optional().describe('Programming language(s) to extract'),\n 'source-root': z.string().optional().describe('Root directory of source code'),\n command: z.string().optional().describe('Build command for compiled languages'),\n 'build-mode': z.enum(['none', 'autobuild', 'manual']).optional()\n .describe('Build mode: none (interpreted langs), autobuild, or manual'),\n threads: z.number().optional().describe('Number of threads to use'),\n ram: z.number().optional().describe('Amount of RAM to use (MB)'),\n verbose: z.boolean().optional().describe('Enable verbose output'),\n overwrite: z.boolean().optional().describe('Overwrite existing database if it exists'),\n 'no-cleanup': z.boolean().optional().describe('Skip database cleanup after finalization'),\n additionalArgs: z.array(z.string()).optional().describe('Additional command-line arguments')\n },\n examples: [\n 'codeql database create --language=java --source-root=/path/to/project mydb',\n 'codeql database create --language=cpp --command=\"make all\" mydb',\n 'codeql database create --language=python,javascript mydb'\n ],\n resultProcessor: createDatabaseResultProcessor()\n};", "/**\n * CodeQL find class position tool\n * \n * Inspired by JordyZomer/codeql-mcp repository:\n * - https://github.com/JordyZomer/codeql-mcp/blob/main/server.py\n * - https://github.com/JordyZomer/codeql-mcp/blob/main/codeqlclient.py\n */\n\nimport { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport { z } from 'zod';\nimport { readFile } from 'fs/promises';\nimport { logger } from '../../utils/logger';\n\nexport interface ClassPosition {\n start_line: number;\n start_col: number;\n end_line: number;\n end_col: number;\n}\n\n/**\n * Find the 1-based position of a class name identifier in a QL file.\n * Returns: { start_line, start_col, end_line, end_col }\n */\nexport async function findClassPosition(filepath: string, className: string): Promise {\n try {\n const content = await readFile(filepath, 'utf-8');\n const lines = content.split('\\n');\n\n for (let i = 0; i < lines.length; i++) {\n const line = lines[i];\n // Match class definition with the specific class name\n const classNameRegex = new RegExp(`\\\\bclass\\\\s+(${className.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&')})\\\\b`);\n const match = classNameRegex.exec(line);\n \n if (match) {\n const start_line = i + 1; // 1-based line numbering\n // The class name is in capture group 1\n const classNameStart = match.index + match[0].indexOf(match[1]);\n const start_col = classNameStart + 1; // 1-based column numbering\n const end_col = start_col + className.length - 1; // end_col is inclusive\n \n return {\n start_line,\n start_col,\n end_line: start_line,\n end_col\n };\n }\n }\n\n throw new Error(`Class name '${className}' not found in file: ${filepath}`);\n } catch (error) {\n if (error instanceof Error && error.message.includes('not found in file')) {\n throw error;\n }\n throw new Error(`Failed to read or parse file ${filepath}: ${error instanceof Error ? error.message : 'Unknown error'}`);\n }\n}\n\n/**\n * Register the find class position tool with the MCP server\n */\nexport function registerFindClassPositionTool(server: McpServer): void {\n server.tool(\n 'find_class_position',\n 'Finds startline, startcol, endline endcol of a class for quickeval',\n {\n file: z.string().describe('Path to the .ql file to search'),\n name: z.string().describe('Name of the class to find'),\n },\n async ({ file, name }) => {\n try {\n const position = await findClassPosition(file, name);\n return {\n content: [{ type: 'text', text: JSON.stringify(position, null, 2) }],\n };\n } catch (error) {\n logger.error('Error finding class position:', error);\n return {\n content: [\n {\n type: 'text',\n text: `Error: ${error instanceof Error ? error.message : 'Unknown error'}`,\n },\n ],\n isError: true,\n };\n }\n }\n );\n}", "/**\n * CodeQL find predicate position tool\n * \n * Inspired by JordyZomer/codeql-mcp repository:\n * - https://github.com/JordyZomer/codeql-mcp/blob/main/server.py\n * - https://github.com/JordyZomer/codeql-mcp/blob/main/codeqlclient.py\n */\n\nimport { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport { z } from 'zod';\nimport { readFile } from 'fs/promises';\nimport { logger } from '../../utils/logger';\n\nexport interface PredicatePosition {\n start_line: number;\n start_col: number;\n end_line: number;\n end_col: number;\n}\n\n/**\n * Find the 1-based position of a predicate name in a QL file.\n * Supports: \n * - predicate name(...) - predicates with no return type\n * - Type name(...) - predicates with return type (e.g., string foo())\n * - name(...) (inside class) - member predicates\n * Returns: { start_line, start_col, end_line, end_col }\n */\nexport async function findPredicatePosition(filepath: string, predicateName: string): Promise {\n try {\n const content = await readFile(filepath, 'utf-8');\n const lines = content.split('\\n');\n const escapedName = predicateName.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&');\n\n for (let i = 0; i < lines.length; i++) {\n const line = lines[i];\n \n // Match predicate definition with the specific predicate name\n // Pattern 1: predicate name(...)\n const predicateKeywordRegex = new RegExp(`\\\\bpredicate\\\\s+(${escapedName})\\\\s*\\\\(`);\n let match = predicateKeywordRegex.exec(line);\n \n // Pattern 2: Type name(...) - predicates with return type\n // Matches: string foo(), int bar(), MyClass baz(), etc.\n // Must start at beginning of line (with optional whitespace) or after certain keywords\n if (!match) {\n const returnTypeRegex = new RegExp(`(?:^|\\\\s)(?:abstract\\\\s+)?(?:cached\\\\s+)?(?:private\\\\s+)?(?:deprecated\\\\s+)?(?:\\\\w+)\\\\s+(${escapedName})\\\\s*\\\\(`);\n match = returnTypeRegex.exec(line);\n }\n \n if (match) {\n const start_line = i + 1; // 1-based line numbering\n // The predicate name is in capture group 1\n const predicateNameStart = match.index + match[0].indexOf(match[1]);\n const start_col = predicateNameStart + 1; // 1-based column numbering\n const end_col = start_col + predicateName.length - 1; // end_col is inclusive\n \n return {\n start_line,\n start_col,\n end_line: start_line,\n end_col\n };\n }\n }\n\n throw new Error(`Predicate name '${predicateName}' not found in file: ${filepath}`);\n } catch (error) {\n if (error instanceof Error && error.message.includes('not found in file')) {\n throw error;\n }\n throw new Error(`Failed to read or parse file ${filepath}: ${error instanceof Error ? error.message : 'Unknown error'}`);\n }\n}\n\n/**\n * Register the find predicate position tool with the MCP server\n */\nexport function registerFindPredicatePositionTool(server: McpServer): void {\n server.tool(\n 'find_predicate_position',\n 'Finds startline, startcol, endline endcol of a predicate for quickeval',\n {\n file: z.string().describe('Path to the .ql file to search'),\n name: z.string().describe('Name of the predicate to find'),\n },\n async ({ file, name }) => {\n try {\n const position = await findPredicatePosition(file, name);\n return {\n content: [{ type: 'text', text: JSON.stringify(position, null, 2) }],\n };\n } catch (error) {\n logger.error('Error finding predicate position:', error);\n return {\n content: [\n {\n type: 'text',\n text: `Error: ${error instanceof Error ? error.message : 'Unknown error'}`,\n },\n ],\n isError: true,\n };\n }\n }\n );\n}", "/**\n * CodeQL find query files tool\n * Discovers and tracks all files related to a CodeQL query\n */\n\nimport { z } from 'zod';\nimport { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport { findCodeQLQueryFiles } from '../../lib/query-file-finder';\nimport { logger } from '../../utils/logger';\n\n/**\n * Register the find_codeql_query_files tool\n */\nexport function registerFindCodeQLQueryFilesTool(server: McpServer): void {\n server.tool(\n 'find_codeql_query_files',\n 'Find and track all files and directories related to a CodeQL query, including resolved metadata',\n {\n queryPath: z.string().describe('Path to the CodeQL query file (.ql)'),\n language: z.string().optional().describe('Programming language (optional, will be inferred if not provided)'),\n resolveMetadata: z.boolean().optional().describe('Whether to resolve query metadata (default: true)')\n },\n async ({ queryPath, language, resolveMetadata }) => {\n try {\n const result = await findCodeQLQueryFiles(\n queryPath,\n language,\n resolveMetadata !== false // Default to true if not specified\n );\n\n return {\n content: [{ type: 'text', text: JSON.stringify(result, null, 2) }]\n };\n } catch (error) {\n logger.error('Error finding CodeQL query files:', error);\n return {\n content: [\n {\n type: 'text',\n text: `Error: ${error instanceof Error ? error.message : 'Unknown error'}`\n }\n ],\n isError: true\n };\n }\n }\n );\n}\n", "/**\n * CodeQL query file finder utilities\n * Handles discovery and tracking of query-related files and directories\n */\n\nimport * as fs from 'fs';\nimport * as path from 'path';\nimport * as yaml from 'js-yaml';\nimport { QueryFileInfo, QueryFilesResult } from '../types/codeql';\nimport { resolveQueryMetadata } from './metadata-resolver';\n\n// Supported CodeQL languages and their file extensions (alphabetically ordered)\nconst LANGUAGE_EXTENSIONS: Record = {\n actions: 'yml',\n cpp: 'cpp',\n csharp: 'cs',\n go: 'go',\n java: 'java',\n javascript: 'js',\n python: 'py',\n ruby: 'rb',\n swift: 'swift',\n typescript: 'ts'\n};\n\nconst KNOWN_LANGUAGES = Object.keys(LANGUAGE_EXTENSIONS);\n\n/**\n * Get the file extension for test code based on language\n */\nfunction getLanguageExtension(language: string): string {\n return LANGUAGE_EXTENSIONS[language.toLowerCase()] || 'txt';\n}\n\n/**\n * Infer the language from the query file's directory structure\n */\nfunction inferLanguageFromPath(queryPath: string): string {\n const parts = queryPath.split(path.sep);\n\n for (const part of parts) {\n if (KNOWN_LANGUAGES.includes(part.toLowerCase())) {\n return part.toLowerCase();\n }\n }\n\n // Default fallback\n return 'unknown';\n}\n\n/**\n * Find the nearest qlpack.yml or codeql-pack.yml file by walking up the directory tree\n */\nfunction findNearestQlpack(startPath: string): string | null {\n let currentPath = startPath;\n const root = path.parse(currentPath).root;\n\n while (currentPath !== root) {\n // Check for codeql-pack.yml first (newer format), then qlpack.yml\n for (const packFile of ['codeql-pack.yml', 'qlpack.yml']) {\n const packPath = path.join(currentPath, packFile);\n if (fs.existsSync(packPath) && fs.statSync(packPath).isFile()) {\n return packPath;\n }\n }\n currentPath = path.dirname(currentPath);\n }\n\n return null;\n}\n\n/**\n * Read and parse qlpack.yml file\n */\nfunction readQlpackMetadata(qlpackPath: string): Record | null {\n try {\n const content = fs.readFileSync(qlpackPath, 'utf-8');\n const parsed = yaml.load(content) as Record;\n return parsed;\n } catch (_error) {\n // If we can't parse it, return null rather than failing\n return null;\n }\n}\n\n/**\n * Check if a file exists and return QueryFileInfo\n */\nfunction checkFile(filePath: string): QueryFileInfo {\n try {\n const exists = fs.existsSync(filePath) && fs.statSync(filePath).isFile();\n return {\n exists,\n path: filePath // Always return path, whether it exists or not\n };\n } catch {\n return {\n exists: false,\n path: filePath // Return the path even on error\n };\n }\n}\n\n/**\n * Check if a directory exists and return QueryFileInfo\n */\nfunction checkDirectory(dirPath: string): QueryFileInfo {\n try {\n const exists = fs.existsSync(dirPath) && fs.statSync(dirPath).isDirectory();\n return {\n exists,\n path: dirPath // Always return path, whether it exists or not\n };\n } catch {\n return {\n exists: false,\n path: dirPath // Return the path even on error\n };\n }\n}\n\n/**\n * Find all test code files in the test directory\n */\nfunction findTestCodeFiles(testDir: string, queryName: string, language: string): string[] {\n if (!fs.existsSync(testDir)) {\n return [];\n }\n\n try {\n const files = fs.readdirSync(testDir);\n const languageExt = getLanguageExtension(language);\n const testFiles: string[] = [];\n\n // Look for files matching the query name or other test code files\n const allValidExtensions = [...new Set([...Object.values(LANGUAGE_EXTENSIONS), 'yaml'])]; // Include yaml as alias for yml\n\n for (const file of files) {\n const filePath = path.join(testDir, file);\n const stat = fs.statSync(filePath);\n\n if (stat.isFile()) {\n // Include the primary test file matching query name\n if (file === `${queryName}.${languageExt}`) {\n testFiles.push(filePath);\n }\n // Include other code files (but not .qlref, .expected, .actual files)\n else if (!file.endsWith('.qlref') && !file.endsWith('.expected') && !file.endsWith('.actual')) {\n const ext = path.extname(file).slice(1);\n if (ext === languageExt || allValidExtensions.includes(ext)) {\n testFiles.push(filePath);\n }\n }\n }\n }\n\n return testFiles;\n } catch {\n return [];\n }\n}\n\n/**\n * Find CodeQL query files and directories based on a query file path\n * Optionally resolves metadata if the query file exists\n */\nexport async function findCodeQLQueryFiles(\n queryFilePath: string,\n language?: string,\n resolveMetadata: boolean = true\n): Promise {\n // Resolve absolute path\n const absoluteQueryPath = path.resolve(queryFilePath);\n\n // Extract query name and directory\n const queryName = path.basename(absoluteQueryPath, '.ql');\n const queryDir = path.dirname(absoluteQueryPath);\n\n // Infer language if not provided\n const detectedLanguage = language || inferLanguageFromPath(absoluteQueryPath);\n\n // Check query file itself\n const queryPath = checkFile(absoluteQueryPath);\n const queryDirectory = checkDirectory(queryDir);\n\n // Check for documentation files\n const mdPath = path.join(queryDir, `${queryName}.md`);\n const qhelpPath = path.join(queryDir, `${queryName}.qhelp`);\n const mdInfo = checkFile(mdPath);\n const qhelpInfo = checkFile(qhelpPath);\n\n const documentationPath: QueryFileInfo = mdInfo.exists ? mdInfo : (qhelpInfo.exists ? qhelpInfo : {\n exists: false,\n path: mdPath // Suggest .md as the default\n });\n\n // Check for specification file\n const qspecPath = path.join(queryDir, `${queryName}.qspec`);\n const specificationPath = checkFile(qspecPath);\n\n // Determine test directory\n // Pattern: if query is in .../src/QueryName/, test should be in .../test/QueryName/\n let testDir: string;\n if (queryDir.includes(`${path.sep}src${path.sep}`)) {\n // Find the last occurrence of /src/ and replace it with /test/\n const parts = queryDir.split(path.sep);\n const srcIndex = parts.lastIndexOf('src');\n if (srcIndex !== -1) {\n parts[srcIndex] = 'test';\n testDir = parts.join(path.sep);\n } else {\n // Fallback in case split didn't find it\n testDir = path.join(path.dirname(queryDir), 'test', queryName);\n }\n } else {\n // Fallback: if not in src directory, construct test dir based on parent\n testDir = path.join(path.dirname(queryDir), 'test', queryName);\n }\n const testDirectory = checkDirectory(testDir);\n\n // Check for .qlref file\n const qlrefPath = path.join(testDir, `${queryName}.qlref`);\n const qlrefInfo = checkFile(qlrefPath);\n\n // Find test code files\n const testCodePaths = findTestCodeFiles(testDir, queryName, detectedLanguage);\n\n // Check for expected results\n const expectedPath = path.join(testDir, `${queryName}.expected`);\n const expectedResultsPath = checkFile(expectedPath);\n\n // Check for actual results\n const actualPath = path.join(testDir, `${queryName}.actual`);\n const actualResultsPath = checkFile(actualPath);\n\n // Check for test database\n const testprojPath = path.join(testDir, `${queryName}.testproj`);\n const testDatabasePath = checkDirectory(testprojPath);\n\n // Determine missing files\n const missingFiles: string[] = [];\n if (!queryPath.exists) missingFiles.push(queryPath.path);\n if (!documentationPath.exists) missingFiles.push(documentationPath.path);\n if (!specificationPath.exists) missingFiles.push(specificationPath.path);\n if (!testDirectory.exists) missingFiles.push(testDirectory.path);\n if (!qlrefInfo.exists) missingFiles.push(qlrefInfo.path);\n if (testCodePaths.length === 0) missingFiles.push(path.join(testDir, `${queryName}.${getLanguageExtension(detectedLanguage)}`));\n if (!expectedResultsPath.exists) missingFiles.push(expectedResultsPath.path);\n\n const allFilesExist = missingFiles.length === 0;\n\n // Resolve metadata if requested and query file exists\n let metadata: { [key: string]: string | string[] } | undefined;\n if (resolveMetadata && queryPath.exists) {\n const resolvedMetadata = await resolveQueryMetadata(absoluteQueryPath);\n if (resolvedMetadata) {\n metadata = resolvedMetadata;\n }\n }\n\n // Resolve pack metadata and directories by finding the nearest qlpack.yml files\n let packMetadata: Record | undefined;\n const queryPackPath = findNearestQlpack(queryDir);\n const queryPackDir = queryPackPath ? path.dirname(queryPackPath) : queryDir;\n if (queryPackPath) {\n const parsed = readQlpackMetadata(queryPackPath);\n if (parsed) {\n packMetadata = parsed;\n }\n }\n\n // Find pack directory for test files\n const testPackPath = findNearestQlpack(testDir);\n const testPackDir = testPackPath ? path.dirname(testPackPath) : testDir;\n\n return {\n queryName,\n language: detectedLanguage,\n\n allFilesExist,\n\n files: {\n query: {\n dir: queryDirectory.path,\n doc: path.basename(documentationPath.path),\n packDir: queryPackDir,\n query: path.basename(queryPath.path),\n spec: path.basename(specificationPath.path)\n },\n test: {\n actual: path.basename(actualResultsPath.path),\n dir: testDirectory.path,\n expected: path.basename(expectedResultsPath.path),\n packDir: testPackDir,\n qlref: path.basename(qlrefInfo.path),\n testCode: testCodePaths,\n testDatabaseDir: testDatabasePath.path\n }\n },\n\n metadata,\n\n missingFiles,\n\n packMetadata,\n\n status: {\n actualResultsExist: actualResultsPath.exists,\n documentationExists: documentationPath.exists,\n expectedResultsExist: expectedResultsPath.exists,\n hasTestCode: testCodePaths.length > 0,\n qlrefExists: qlrefInfo.exists,\n queryExists: queryPath.exists,\n specificationExists: specificationPath.exists,\n testDatabaseDirExists: testDatabasePath.exists,\n testDirectoryExists: testDirectory.exists\n }\n };\n}\n", "\n/*! js-yaml 4.1.1 https://github.com/nodeca/js-yaml @license MIT */\nfunction isNothing(subject) {\n return (typeof subject === 'undefined') || (subject === null);\n}\n\n\nfunction isObject(subject) {\n return (typeof subject === 'object') && (subject !== null);\n}\n\n\nfunction toArray(sequence) {\n if (Array.isArray(sequence)) return sequence;\n else if (isNothing(sequence)) return [];\n\n return [ sequence ];\n}\n\n\nfunction extend(target, source) {\n var index, length, key, sourceKeys;\n\n if (source) {\n sourceKeys = Object.keys(source);\n\n for (index = 0, length = sourceKeys.length; index < length; index += 1) {\n key = sourceKeys[index];\n target[key] = source[key];\n }\n }\n\n return target;\n}\n\n\nfunction repeat(string, count) {\n var result = '', cycle;\n\n for (cycle = 0; cycle < count; cycle += 1) {\n result += string;\n }\n\n return result;\n}\n\n\nfunction isNegativeZero(number) {\n return (number === 0) && (Number.NEGATIVE_INFINITY === 1 / number);\n}\n\n\nvar isNothing_1 = isNothing;\nvar isObject_1 = isObject;\nvar toArray_1 = toArray;\nvar repeat_1 = repeat;\nvar isNegativeZero_1 = isNegativeZero;\nvar extend_1 = extend;\n\nvar common = {\n\tisNothing: isNothing_1,\n\tisObject: isObject_1,\n\ttoArray: toArray_1,\n\trepeat: repeat_1,\n\tisNegativeZero: isNegativeZero_1,\n\textend: extend_1\n};\n\n// YAML error class. http://stackoverflow.com/questions/8458984\n\n\nfunction formatError(exception, compact) {\n var where = '', message = exception.reason || '(unknown reason)';\n\n if (!exception.mark) return message;\n\n if (exception.mark.name) {\n where += 'in \"' + exception.mark.name + '\" ';\n }\n\n where += '(' + (exception.mark.line + 1) + ':' + (exception.mark.column + 1) + ')';\n\n if (!compact && exception.mark.snippet) {\n where += '\\n\\n' + exception.mark.snippet;\n }\n\n return message + ' ' + where;\n}\n\n\nfunction YAMLException$1(reason, mark) {\n // Super constructor\n Error.call(this);\n\n this.name = 'YAMLException';\n this.reason = reason;\n this.mark = mark;\n this.message = formatError(this, false);\n\n // Include stack trace in error object\n if (Error.captureStackTrace) {\n // Chrome and NodeJS\n Error.captureStackTrace(this, this.constructor);\n } else {\n // FF, IE 10+ and Safari 6+. Fallback for others\n this.stack = (new Error()).stack || '';\n }\n}\n\n\n// Inherit from Error\nYAMLException$1.prototype = Object.create(Error.prototype);\nYAMLException$1.prototype.constructor = YAMLException$1;\n\n\nYAMLException$1.prototype.toString = function toString(compact) {\n return this.name + ': ' + formatError(this, compact);\n};\n\n\nvar exception = YAMLException$1;\n\n// get snippet for a single line, respecting maxLength\nfunction getLine(buffer, lineStart, lineEnd, position, maxLineLength) {\n var head = '';\n var tail = '';\n var maxHalfLength = Math.floor(maxLineLength / 2) - 1;\n\n if (position - lineStart > maxHalfLength) {\n head = ' ... ';\n lineStart = position - maxHalfLength + head.length;\n }\n\n if (lineEnd - position > maxHalfLength) {\n tail = ' ...';\n lineEnd = position + maxHalfLength - tail.length;\n }\n\n return {\n str: head + buffer.slice(lineStart, lineEnd).replace(/\\t/g, '\u2192') + tail,\n pos: position - lineStart + head.length // relative position\n };\n}\n\n\nfunction padStart(string, max) {\n return common.repeat(' ', max - string.length) + string;\n}\n\n\nfunction makeSnippet(mark, options) {\n options = Object.create(options || null);\n\n if (!mark.buffer) return null;\n\n if (!options.maxLength) options.maxLength = 79;\n if (typeof options.indent !== 'number') options.indent = 1;\n if (typeof options.linesBefore !== 'number') options.linesBefore = 3;\n if (typeof options.linesAfter !== 'number') options.linesAfter = 2;\n\n var re = /\\r?\\n|\\r|\\0/g;\n var lineStarts = [ 0 ];\n var lineEnds = [];\n var match;\n var foundLineNo = -1;\n\n while ((match = re.exec(mark.buffer))) {\n lineEnds.push(match.index);\n lineStarts.push(match.index + match[0].length);\n\n if (mark.position <= match.index && foundLineNo < 0) {\n foundLineNo = lineStarts.length - 2;\n }\n }\n\n if (foundLineNo < 0) foundLineNo = lineStarts.length - 1;\n\n var result = '', i, line;\n var lineNoLength = Math.min(mark.line + options.linesAfter, lineEnds.length).toString().length;\n var maxLineLength = options.maxLength - (options.indent + lineNoLength + 3);\n\n for (i = 1; i <= options.linesBefore; i++) {\n if (foundLineNo - i < 0) break;\n line = getLine(\n mark.buffer,\n lineStarts[foundLineNo - i],\n lineEnds[foundLineNo - i],\n mark.position - (lineStarts[foundLineNo] - lineStarts[foundLineNo - i]),\n maxLineLength\n );\n result = common.repeat(' ', options.indent) + padStart((mark.line - i + 1).toString(), lineNoLength) +\n ' | ' + line.str + '\\n' + result;\n }\n\n line = getLine(mark.buffer, lineStarts[foundLineNo], lineEnds[foundLineNo], mark.position, maxLineLength);\n result += common.repeat(' ', options.indent) + padStart((mark.line + 1).toString(), lineNoLength) +\n ' | ' + line.str + '\\n';\n result += common.repeat('-', options.indent + lineNoLength + 3 + line.pos) + '^' + '\\n';\n\n for (i = 1; i <= options.linesAfter; i++) {\n if (foundLineNo + i >= lineEnds.length) break;\n line = getLine(\n mark.buffer,\n lineStarts[foundLineNo + i],\n lineEnds[foundLineNo + i],\n mark.position - (lineStarts[foundLineNo] - lineStarts[foundLineNo + i]),\n maxLineLength\n );\n result += common.repeat(' ', options.indent) + padStart((mark.line + i + 1).toString(), lineNoLength) +\n ' | ' + line.str + '\\n';\n }\n\n return result.replace(/\\n$/, '');\n}\n\n\nvar snippet = makeSnippet;\n\nvar TYPE_CONSTRUCTOR_OPTIONS = [\n 'kind',\n 'multi',\n 'resolve',\n 'construct',\n 'instanceOf',\n 'predicate',\n 'represent',\n 'representName',\n 'defaultStyle',\n 'styleAliases'\n];\n\nvar YAML_NODE_KINDS = [\n 'scalar',\n 'sequence',\n 'mapping'\n];\n\nfunction compileStyleAliases(map) {\n var result = {};\n\n if (map !== null) {\n Object.keys(map).forEach(function (style) {\n map[style].forEach(function (alias) {\n result[String(alias)] = style;\n });\n });\n }\n\n return result;\n}\n\nfunction Type$1(tag, options) {\n options = options || {};\n\n Object.keys(options).forEach(function (name) {\n if (TYPE_CONSTRUCTOR_OPTIONS.indexOf(name) === -1) {\n throw new exception('Unknown option \"' + name + '\" is met in definition of \"' + tag + '\" YAML type.');\n }\n });\n\n // TODO: Add tag format check.\n this.options = options; // keep original options in case user wants to extend this type later\n this.tag = tag;\n this.kind = options['kind'] || null;\n this.resolve = options['resolve'] || function () { return true; };\n this.construct = options['construct'] || function (data) { return data; };\n this.instanceOf = options['instanceOf'] || null;\n this.predicate = options['predicate'] || null;\n this.represent = options['represent'] || null;\n this.representName = options['representName'] || null;\n this.defaultStyle = options['defaultStyle'] || null;\n this.multi = options['multi'] || false;\n this.styleAliases = compileStyleAliases(options['styleAliases'] || null);\n\n if (YAML_NODE_KINDS.indexOf(this.kind) === -1) {\n throw new exception('Unknown kind \"' + this.kind + '\" is specified for \"' + tag + '\" YAML type.');\n }\n}\n\nvar type = Type$1;\n\n/*eslint-disable max-len*/\n\n\n\n\n\nfunction compileList(schema, name) {\n var result = [];\n\n schema[name].forEach(function (currentType) {\n var newIndex = result.length;\n\n result.forEach(function (previousType, previousIndex) {\n if (previousType.tag === currentType.tag &&\n previousType.kind === currentType.kind &&\n previousType.multi === currentType.multi) {\n\n newIndex = previousIndex;\n }\n });\n\n result[newIndex] = currentType;\n });\n\n return result;\n}\n\n\nfunction compileMap(/* lists... */) {\n var result = {\n scalar: {},\n sequence: {},\n mapping: {},\n fallback: {},\n multi: {\n scalar: [],\n sequence: [],\n mapping: [],\n fallback: []\n }\n }, index, length;\n\n function collectType(type) {\n if (type.multi) {\n result.multi[type.kind].push(type);\n result.multi['fallback'].push(type);\n } else {\n result[type.kind][type.tag] = result['fallback'][type.tag] = type;\n }\n }\n\n for (index = 0, length = arguments.length; index < length; index += 1) {\n arguments[index].forEach(collectType);\n }\n return result;\n}\n\n\nfunction Schema$1(definition) {\n return this.extend(definition);\n}\n\n\nSchema$1.prototype.extend = function extend(definition) {\n var implicit = [];\n var explicit = [];\n\n if (definition instanceof type) {\n // Schema.extend(type)\n explicit.push(definition);\n\n } else if (Array.isArray(definition)) {\n // Schema.extend([ type1, type2, ... ])\n explicit = explicit.concat(definition);\n\n } else if (definition && (Array.isArray(definition.implicit) || Array.isArray(definition.explicit))) {\n // Schema.extend({ explicit: [ type1, type2, ... ], implicit: [ type1, type2, ... ] })\n if (definition.implicit) implicit = implicit.concat(definition.implicit);\n if (definition.explicit) explicit = explicit.concat(definition.explicit);\n\n } else {\n throw new exception('Schema.extend argument should be a Type, [ Type ], ' +\n 'or a schema definition ({ implicit: [...], explicit: [...] })');\n }\n\n implicit.forEach(function (type$1) {\n if (!(type$1 instanceof type)) {\n throw new exception('Specified list of YAML types (or a single Type object) contains a non-Type object.');\n }\n\n if (type$1.loadKind && type$1.loadKind !== 'scalar') {\n throw new exception('There is a non-scalar type in the implicit list of a schema. Implicit resolving of such types is not supported.');\n }\n\n if (type$1.multi) {\n throw new exception('There is a multi type in the implicit list of a schema. Multi tags can only be listed as explicit.');\n }\n });\n\n explicit.forEach(function (type$1) {\n if (!(type$1 instanceof type)) {\n throw new exception('Specified list of YAML types (or a single Type object) contains a non-Type object.');\n }\n });\n\n var result = Object.create(Schema$1.prototype);\n\n result.implicit = (this.implicit || []).concat(implicit);\n result.explicit = (this.explicit || []).concat(explicit);\n\n result.compiledImplicit = compileList(result, 'implicit');\n result.compiledExplicit = compileList(result, 'explicit');\n result.compiledTypeMap = compileMap(result.compiledImplicit, result.compiledExplicit);\n\n return result;\n};\n\n\nvar schema = Schema$1;\n\nvar str = new type('tag:yaml.org,2002:str', {\n kind: 'scalar',\n construct: function (data) { return data !== null ? data : ''; }\n});\n\nvar seq = new type('tag:yaml.org,2002:seq', {\n kind: 'sequence',\n construct: function (data) { return data !== null ? data : []; }\n});\n\nvar map = new type('tag:yaml.org,2002:map', {\n kind: 'mapping',\n construct: function (data) { return data !== null ? data : {}; }\n});\n\nvar failsafe = new schema({\n explicit: [\n str,\n seq,\n map\n ]\n});\n\nfunction resolveYamlNull(data) {\n if (data === null) return true;\n\n var max = data.length;\n\n return (max === 1 && data === '~') ||\n (max === 4 && (data === 'null' || data === 'Null' || data === 'NULL'));\n}\n\nfunction constructYamlNull() {\n return null;\n}\n\nfunction isNull(object) {\n return object === null;\n}\n\nvar _null = new type('tag:yaml.org,2002:null', {\n kind: 'scalar',\n resolve: resolveYamlNull,\n construct: constructYamlNull,\n predicate: isNull,\n represent: {\n canonical: function () { return '~'; },\n lowercase: function () { return 'null'; },\n uppercase: function () { return 'NULL'; },\n camelcase: function () { return 'Null'; },\n empty: function () { return ''; }\n },\n defaultStyle: 'lowercase'\n});\n\nfunction resolveYamlBoolean(data) {\n if (data === null) return false;\n\n var max = data.length;\n\n return (max === 4 && (data === 'true' || data === 'True' || data === 'TRUE')) ||\n (max === 5 && (data === 'false' || data === 'False' || data === 'FALSE'));\n}\n\nfunction constructYamlBoolean(data) {\n return data === 'true' ||\n data === 'True' ||\n data === 'TRUE';\n}\n\nfunction isBoolean(object) {\n return Object.prototype.toString.call(object) === '[object Boolean]';\n}\n\nvar bool = new type('tag:yaml.org,2002:bool', {\n kind: 'scalar',\n resolve: resolveYamlBoolean,\n construct: constructYamlBoolean,\n predicate: isBoolean,\n represent: {\n lowercase: function (object) { return object ? 'true' : 'false'; },\n uppercase: function (object) { return object ? 'TRUE' : 'FALSE'; },\n camelcase: function (object) { return object ? 'True' : 'False'; }\n },\n defaultStyle: 'lowercase'\n});\n\nfunction isHexCode(c) {\n return ((0x30/* 0 */ <= c) && (c <= 0x39/* 9 */)) ||\n ((0x41/* A */ <= c) && (c <= 0x46/* F */)) ||\n ((0x61/* a */ <= c) && (c <= 0x66/* f */));\n}\n\nfunction isOctCode(c) {\n return ((0x30/* 0 */ <= c) && (c <= 0x37/* 7 */));\n}\n\nfunction isDecCode(c) {\n return ((0x30/* 0 */ <= c) && (c <= 0x39/* 9 */));\n}\n\nfunction resolveYamlInteger(data) {\n if (data === null) return false;\n\n var max = data.length,\n index = 0,\n hasDigits = false,\n ch;\n\n if (!max) return false;\n\n ch = data[index];\n\n // sign\n if (ch === '-' || ch === '+') {\n ch = data[++index];\n }\n\n if (ch === '0') {\n // 0\n if (index + 1 === max) return true;\n ch = data[++index];\n\n // base 2, base 8, base 16\n\n if (ch === 'b') {\n // base 2\n index++;\n\n for (; index < max; index++) {\n ch = data[index];\n if (ch === '_') continue;\n if (ch !== '0' && ch !== '1') return false;\n hasDigits = true;\n }\n return hasDigits && ch !== '_';\n }\n\n\n if (ch === 'x') {\n // base 16\n index++;\n\n for (; index < max; index++) {\n ch = data[index];\n if (ch === '_') continue;\n if (!isHexCode(data.charCodeAt(index))) return false;\n hasDigits = true;\n }\n return hasDigits && ch !== '_';\n }\n\n\n if (ch === 'o') {\n // base 8\n index++;\n\n for (; index < max; index++) {\n ch = data[index];\n if (ch === '_') continue;\n if (!isOctCode(data.charCodeAt(index))) return false;\n hasDigits = true;\n }\n return hasDigits && ch !== '_';\n }\n }\n\n // base 10 (except 0)\n\n // value should not start with `_`;\n if (ch === '_') return false;\n\n for (; index < max; index++) {\n ch = data[index];\n if (ch === '_') continue;\n if (!isDecCode(data.charCodeAt(index))) {\n return false;\n }\n hasDigits = true;\n }\n\n // Should have digits and should not end with `_`\n if (!hasDigits || ch === '_') return false;\n\n return true;\n}\n\nfunction constructYamlInteger(data) {\n var value = data, sign = 1, ch;\n\n if (value.indexOf('_') !== -1) {\n value = value.replace(/_/g, '');\n }\n\n ch = value[0];\n\n if (ch === '-' || ch === '+') {\n if (ch === '-') sign = -1;\n value = value.slice(1);\n ch = value[0];\n }\n\n if (value === '0') return 0;\n\n if (ch === '0') {\n if (value[1] === 'b') return sign * parseInt(value.slice(2), 2);\n if (value[1] === 'x') return sign * parseInt(value.slice(2), 16);\n if (value[1] === 'o') return sign * parseInt(value.slice(2), 8);\n }\n\n return sign * parseInt(value, 10);\n}\n\nfunction isInteger(object) {\n return (Object.prototype.toString.call(object)) === '[object Number]' &&\n (object % 1 === 0 && !common.isNegativeZero(object));\n}\n\nvar int = new type('tag:yaml.org,2002:int', {\n kind: 'scalar',\n resolve: resolveYamlInteger,\n construct: constructYamlInteger,\n predicate: isInteger,\n represent: {\n binary: function (obj) { return obj >= 0 ? '0b' + obj.toString(2) : '-0b' + obj.toString(2).slice(1); },\n octal: function (obj) { return obj >= 0 ? '0o' + obj.toString(8) : '-0o' + obj.toString(8).slice(1); },\n decimal: function (obj) { return obj.toString(10); },\n /* eslint-disable max-len */\n hexadecimal: function (obj) { return obj >= 0 ? '0x' + obj.toString(16).toUpperCase() : '-0x' + obj.toString(16).toUpperCase().slice(1); }\n },\n defaultStyle: 'decimal',\n styleAliases: {\n binary: [ 2, 'bin' ],\n octal: [ 8, 'oct' ],\n decimal: [ 10, 'dec' ],\n hexadecimal: [ 16, 'hex' ]\n }\n});\n\nvar YAML_FLOAT_PATTERN = new RegExp(\n // 2.5e4, 2.5 and integers\n '^(?:[-+]?(?:[0-9][0-9_]*)(?:\\\\.[0-9_]*)?(?:[eE][-+]?[0-9]+)?' +\n // .2e4, .2\n // special case, seems not from spec\n '|\\\\.[0-9_]+(?:[eE][-+]?[0-9]+)?' +\n // .inf\n '|[-+]?\\\\.(?:inf|Inf|INF)' +\n // .nan\n '|\\\\.(?:nan|NaN|NAN))$');\n\nfunction resolveYamlFloat(data) {\n if (data === null) return false;\n\n if (!YAML_FLOAT_PATTERN.test(data) ||\n // Quick hack to not allow integers end with `_`\n // Probably should update regexp & check speed\n data[data.length - 1] === '_') {\n return false;\n }\n\n return true;\n}\n\nfunction constructYamlFloat(data) {\n var value, sign;\n\n value = data.replace(/_/g, '').toLowerCase();\n sign = value[0] === '-' ? -1 : 1;\n\n if ('+-'.indexOf(value[0]) >= 0) {\n value = value.slice(1);\n }\n\n if (value === '.inf') {\n return (sign === 1) ? Number.POSITIVE_INFINITY : Number.NEGATIVE_INFINITY;\n\n } else if (value === '.nan') {\n return NaN;\n }\n return sign * parseFloat(value, 10);\n}\n\n\nvar SCIENTIFIC_WITHOUT_DOT = /^[-+]?[0-9]+e/;\n\nfunction representYamlFloat(object, style) {\n var res;\n\n if (isNaN(object)) {\n switch (style) {\n case 'lowercase': return '.nan';\n case 'uppercase': return '.NAN';\n case 'camelcase': return '.NaN';\n }\n } else if (Number.POSITIVE_INFINITY === object) {\n switch (style) {\n case 'lowercase': return '.inf';\n case 'uppercase': return '.INF';\n case 'camelcase': return '.Inf';\n }\n } else if (Number.NEGATIVE_INFINITY === object) {\n switch (style) {\n case 'lowercase': return '-.inf';\n case 'uppercase': return '-.INF';\n case 'camelcase': return '-.Inf';\n }\n } else if (common.isNegativeZero(object)) {\n return '-0.0';\n }\n\n res = object.toString(10);\n\n // JS stringifier can build scientific format without dots: 5e-100,\n // while YAML requres dot: 5.e-100. Fix it with simple hack\n\n return SCIENTIFIC_WITHOUT_DOT.test(res) ? res.replace('e', '.e') : res;\n}\n\nfunction isFloat(object) {\n return (Object.prototype.toString.call(object) === '[object Number]') &&\n (object % 1 !== 0 || common.isNegativeZero(object));\n}\n\nvar float = new type('tag:yaml.org,2002:float', {\n kind: 'scalar',\n resolve: resolveYamlFloat,\n construct: constructYamlFloat,\n predicate: isFloat,\n represent: representYamlFloat,\n defaultStyle: 'lowercase'\n});\n\nvar json = failsafe.extend({\n implicit: [\n _null,\n bool,\n int,\n float\n ]\n});\n\nvar core = json;\n\nvar YAML_DATE_REGEXP = new RegExp(\n '^([0-9][0-9][0-9][0-9])' + // [1] year\n '-([0-9][0-9])' + // [2] month\n '-([0-9][0-9])$'); // [3] day\n\nvar YAML_TIMESTAMP_REGEXP = new RegExp(\n '^([0-9][0-9][0-9][0-9])' + // [1] year\n '-([0-9][0-9]?)' + // [2] month\n '-([0-9][0-9]?)' + // [3] day\n '(?:[Tt]|[ \\\\t]+)' + // ...\n '([0-9][0-9]?)' + // [4] hour\n ':([0-9][0-9])' + // [5] minute\n ':([0-9][0-9])' + // [6] second\n '(?:\\\\.([0-9]*))?' + // [7] fraction\n '(?:[ \\\\t]*(Z|([-+])([0-9][0-9]?)' + // [8] tz [9] tz_sign [10] tz_hour\n '(?::([0-9][0-9]))?))?$'); // [11] tz_minute\n\nfunction resolveYamlTimestamp(data) {\n if (data === null) return false;\n if (YAML_DATE_REGEXP.exec(data) !== null) return true;\n if (YAML_TIMESTAMP_REGEXP.exec(data) !== null) return true;\n return false;\n}\n\nfunction constructYamlTimestamp(data) {\n var match, year, month, day, hour, minute, second, fraction = 0,\n delta = null, tz_hour, tz_minute, date;\n\n match = YAML_DATE_REGEXP.exec(data);\n if (match === null) match = YAML_TIMESTAMP_REGEXP.exec(data);\n\n if (match === null) throw new Error('Date resolve error');\n\n // match: [1] year [2] month [3] day\n\n year = +(match[1]);\n month = +(match[2]) - 1; // JS month starts with 0\n day = +(match[3]);\n\n if (!match[4]) { // no hour\n return new Date(Date.UTC(year, month, day));\n }\n\n // match: [4] hour [5] minute [6] second [7] fraction\n\n hour = +(match[4]);\n minute = +(match[5]);\n second = +(match[6]);\n\n if (match[7]) {\n fraction = match[7].slice(0, 3);\n while (fraction.length < 3) { // milli-seconds\n fraction += '0';\n }\n fraction = +fraction;\n }\n\n // match: [8] tz [9] tz_sign [10] tz_hour [11] tz_minute\n\n if (match[9]) {\n tz_hour = +(match[10]);\n tz_minute = +(match[11] || 0);\n delta = (tz_hour * 60 + tz_minute) * 60000; // delta in mili-seconds\n if (match[9] === '-') delta = -delta;\n }\n\n date = new Date(Date.UTC(year, month, day, hour, minute, second, fraction));\n\n if (delta) date.setTime(date.getTime() - delta);\n\n return date;\n}\n\nfunction representYamlTimestamp(object /*, style*/) {\n return object.toISOString();\n}\n\nvar timestamp = new type('tag:yaml.org,2002:timestamp', {\n kind: 'scalar',\n resolve: resolveYamlTimestamp,\n construct: constructYamlTimestamp,\n instanceOf: Date,\n represent: representYamlTimestamp\n});\n\nfunction resolveYamlMerge(data) {\n return data === '<<' || data === null;\n}\n\nvar merge = new type('tag:yaml.org,2002:merge', {\n kind: 'scalar',\n resolve: resolveYamlMerge\n});\n\n/*eslint-disable no-bitwise*/\n\n\n\n\n\n// [ 64, 65, 66 ] -> [ padding, CR, LF ]\nvar BASE64_MAP = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=\\n\\r';\n\n\nfunction resolveYamlBinary(data) {\n if (data === null) return false;\n\n var code, idx, bitlen = 0, max = data.length, map = BASE64_MAP;\n\n // Convert one by one.\n for (idx = 0; idx < max; idx++) {\n code = map.indexOf(data.charAt(idx));\n\n // Skip CR/LF\n if (code > 64) continue;\n\n // Fail on illegal characters\n if (code < 0) return false;\n\n bitlen += 6;\n }\n\n // If there are any bits left, source was corrupted\n return (bitlen % 8) === 0;\n}\n\nfunction constructYamlBinary(data) {\n var idx, tailbits,\n input = data.replace(/[\\r\\n=]/g, ''), // remove CR/LF & padding to simplify scan\n max = input.length,\n map = BASE64_MAP,\n bits = 0,\n result = [];\n\n // Collect by 6*4 bits (3 bytes)\n\n for (idx = 0; idx < max; idx++) {\n if ((idx % 4 === 0) && idx) {\n result.push((bits >> 16) & 0xFF);\n result.push((bits >> 8) & 0xFF);\n result.push(bits & 0xFF);\n }\n\n bits = (bits << 6) | map.indexOf(input.charAt(idx));\n }\n\n // Dump tail\n\n tailbits = (max % 4) * 6;\n\n if (tailbits === 0) {\n result.push((bits >> 16) & 0xFF);\n result.push((bits >> 8) & 0xFF);\n result.push(bits & 0xFF);\n } else if (tailbits === 18) {\n result.push((bits >> 10) & 0xFF);\n result.push((bits >> 2) & 0xFF);\n } else if (tailbits === 12) {\n result.push((bits >> 4) & 0xFF);\n }\n\n return new Uint8Array(result);\n}\n\nfunction representYamlBinary(object /*, style*/) {\n var result = '', bits = 0, idx, tail,\n max = object.length,\n map = BASE64_MAP;\n\n // Convert every three bytes to 4 ASCII characters.\n\n for (idx = 0; idx < max; idx++) {\n if ((idx % 3 === 0) && idx) {\n result += map[(bits >> 18) & 0x3F];\n result += map[(bits >> 12) & 0x3F];\n result += map[(bits >> 6) & 0x3F];\n result += map[bits & 0x3F];\n }\n\n bits = (bits << 8) + object[idx];\n }\n\n // Dump tail\n\n tail = max % 3;\n\n if (tail === 0) {\n result += map[(bits >> 18) & 0x3F];\n result += map[(bits >> 12) & 0x3F];\n result += map[(bits >> 6) & 0x3F];\n result += map[bits & 0x3F];\n } else if (tail === 2) {\n result += map[(bits >> 10) & 0x3F];\n result += map[(bits >> 4) & 0x3F];\n result += map[(bits << 2) & 0x3F];\n result += map[64];\n } else if (tail === 1) {\n result += map[(bits >> 2) & 0x3F];\n result += map[(bits << 4) & 0x3F];\n result += map[64];\n result += map[64];\n }\n\n return result;\n}\n\nfunction isBinary(obj) {\n return Object.prototype.toString.call(obj) === '[object Uint8Array]';\n}\n\nvar binary = new type('tag:yaml.org,2002:binary', {\n kind: 'scalar',\n resolve: resolveYamlBinary,\n construct: constructYamlBinary,\n predicate: isBinary,\n represent: representYamlBinary\n});\n\nvar _hasOwnProperty$3 = Object.prototype.hasOwnProperty;\nvar _toString$2 = Object.prototype.toString;\n\nfunction resolveYamlOmap(data) {\n if (data === null) return true;\n\n var objectKeys = [], index, length, pair, pairKey, pairHasKey,\n object = data;\n\n for (index = 0, length = object.length; index < length; index += 1) {\n pair = object[index];\n pairHasKey = false;\n\n if (_toString$2.call(pair) !== '[object Object]') return false;\n\n for (pairKey in pair) {\n if (_hasOwnProperty$3.call(pair, pairKey)) {\n if (!pairHasKey) pairHasKey = true;\n else return false;\n }\n }\n\n if (!pairHasKey) return false;\n\n if (objectKeys.indexOf(pairKey) === -1) objectKeys.push(pairKey);\n else return false;\n }\n\n return true;\n}\n\nfunction constructYamlOmap(data) {\n return data !== null ? data : [];\n}\n\nvar omap = new type('tag:yaml.org,2002:omap', {\n kind: 'sequence',\n resolve: resolveYamlOmap,\n construct: constructYamlOmap\n});\n\nvar _toString$1 = Object.prototype.toString;\n\nfunction resolveYamlPairs(data) {\n if (data === null) return true;\n\n var index, length, pair, keys, result,\n object = data;\n\n result = new Array(object.length);\n\n for (index = 0, length = object.length; index < length; index += 1) {\n pair = object[index];\n\n if (_toString$1.call(pair) !== '[object Object]') return false;\n\n keys = Object.keys(pair);\n\n if (keys.length !== 1) return false;\n\n result[index] = [ keys[0], pair[keys[0]] ];\n }\n\n return true;\n}\n\nfunction constructYamlPairs(data) {\n if (data === null) return [];\n\n var index, length, pair, keys, result,\n object = data;\n\n result = new Array(object.length);\n\n for (index = 0, length = object.length; index < length; index += 1) {\n pair = object[index];\n\n keys = Object.keys(pair);\n\n result[index] = [ keys[0], pair[keys[0]] ];\n }\n\n return result;\n}\n\nvar pairs = new type('tag:yaml.org,2002:pairs', {\n kind: 'sequence',\n resolve: resolveYamlPairs,\n construct: constructYamlPairs\n});\n\nvar _hasOwnProperty$2 = Object.prototype.hasOwnProperty;\n\nfunction resolveYamlSet(data) {\n if (data === null) return true;\n\n var key, object = data;\n\n for (key in object) {\n if (_hasOwnProperty$2.call(object, key)) {\n if (object[key] !== null) return false;\n }\n }\n\n return true;\n}\n\nfunction constructYamlSet(data) {\n return data !== null ? data : {};\n}\n\nvar set = new type('tag:yaml.org,2002:set', {\n kind: 'mapping',\n resolve: resolveYamlSet,\n construct: constructYamlSet\n});\n\nvar _default = core.extend({\n implicit: [\n timestamp,\n merge\n ],\n explicit: [\n binary,\n omap,\n pairs,\n set\n ]\n});\n\n/*eslint-disable max-len,no-use-before-define*/\n\n\n\n\n\n\n\nvar _hasOwnProperty$1 = Object.prototype.hasOwnProperty;\n\n\nvar CONTEXT_FLOW_IN = 1;\nvar CONTEXT_FLOW_OUT = 2;\nvar CONTEXT_BLOCK_IN = 3;\nvar CONTEXT_BLOCK_OUT = 4;\n\n\nvar CHOMPING_CLIP = 1;\nvar CHOMPING_STRIP = 2;\nvar CHOMPING_KEEP = 3;\n\n\nvar PATTERN_NON_PRINTABLE = /[\\x00-\\x08\\x0B\\x0C\\x0E-\\x1F\\x7F-\\x84\\x86-\\x9F\\uFFFE\\uFFFF]|[\\uD800-\\uDBFF](?![\\uDC00-\\uDFFF])|(?:[^\\uD800-\\uDBFF]|^)[\\uDC00-\\uDFFF]/;\nvar PATTERN_NON_ASCII_LINE_BREAKS = /[\\x85\\u2028\\u2029]/;\nvar PATTERN_FLOW_INDICATORS = /[,\\[\\]\\{\\}]/;\nvar PATTERN_TAG_HANDLE = /^(?:!|!!|![a-z\\-]+!)$/i;\nvar PATTERN_TAG_URI = /^(?:!|[^,\\[\\]\\{\\}])(?:%[0-9a-f]{2}|[0-9a-z\\-#;\\/\\?:@&=\\+\\$,_\\.!~\\*'\\(\\)\\[\\]])*$/i;\n\n\nfunction _class(obj) { return Object.prototype.toString.call(obj); }\n\nfunction is_EOL(c) {\n return (c === 0x0A/* LF */) || (c === 0x0D/* CR */);\n}\n\nfunction is_WHITE_SPACE(c) {\n return (c === 0x09/* Tab */) || (c === 0x20/* Space */);\n}\n\nfunction is_WS_OR_EOL(c) {\n return (c === 0x09/* Tab */) ||\n (c === 0x20/* Space */) ||\n (c === 0x0A/* LF */) ||\n (c === 0x0D/* CR */);\n}\n\nfunction is_FLOW_INDICATOR(c) {\n return c === 0x2C/* , */ ||\n c === 0x5B/* [ */ ||\n c === 0x5D/* ] */ ||\n c === 0x7B/* { */ ||\n c === 0x7D/* } */;\n}\n\nfunction fromHexCode(c) {\n var lc;\n\n if ((0x30/* 0 */ <= c) && (c <= 0x39/* 9 */)) {\n return c - 0x30;\n }\n\n /*eslint-disable no-bitwise*/\n lc = c | 0x20;\n\n if ((0x61/* a */ <= lc) && (lc <= 0x66/* f */)) {\n return lc - 0x61 + 10;\n }\n\n return -1;\n}\n\nfunction escapedHexLen(c) {\n if (c === 0x78/* x */) { return 2; }\n if (c === 0x75/* u */) { return 4; }\n if (c === 0x55/* U */) { return 8; }\n return 0;\n}\n\nfunction fromDecimalCode(c) {\n if ((0x30/* 0 */ <= c) && (c <= 0x39/* 9 */)) {\n return c - 0x30;\n }\n\n return -1;\n}\n\nfunction simpleEscapeSequence(c) {\n /* eslint-disable indent */\n return (c === 0x30/* 0 */) ? '\\x00' :\n (c === 0x61/* a */) ? '\\x07' :\n (c === 0x62/* b */) ? '\\x08' :\n (c === 0x74/* t */) ? '\\x09' :\n (c === 0x09/* Tab */) ? '\\x09' :\n (c === 0x6E/* n */) ? '\\x0A' :\n (c === 0x76/* v */) ? '\\x0B' :\n (c === 0x66/* f */) ? '\\x0C' :\n (c === 0x72/* r */) ? '\\x0D' :\n (c === 0x65/* e */) ? '\\x1B' :\n (c === 0x20/* Space */) ? ' ' :\n (c === 0x22/* \" */) ? '\\x22' :\n (c === 0x2F/* / */) ? '/' :\n (c === 0x5C/* \\ */) ? '\\x5C' :\n (c === 0x4E/* N */) ? '\\x85' :\n (c === 0x5F/* _ */) ? '\\xA0' :\n (c === 0x4C/* L */) ? '\\u2028' :\n (c === 0x50/* P */) ? '\\u2029' : '';\n}\n\nfunction charFromCodepoint(c) {\n if (c <= 0xFFFF) {\n return String.fromCharCode(c);\n }\n // Encode UTF-16 surrogate pair\n // https://en.wikipedia.org/wiki/UTF-16#Code_points_U.2B010000_to_U.2B10FFFF\n return String.fromCharCode(\n ((c - 0x010000) >> 10) + 0xD800,\n ((c - 0x010000) & 0x03FF) + 0xDC00\n );\n}\n\n// set a property of a literal object, while protecting against prototype pollution,\n// see https://github.com/nodeca/js-yaml/issues/164 for more details\nfunction setProperty(object, key, value) {\n // used for this specific key only because Object.defineProperty is slow\n if (key === '__proto__') {\n Object.defineProperty(object, key, {\n configurable: true,\n enumerable: true,\n writable: true,\n value: value\n });\n } else {\n object[key] = value;\n }\n}\n\nvar simpleEscapeCheck = new Array(256); // integer, for fast access\nvar simpleEscapeMap = new Array(256);\nfor (var i = 0; i < 256; i++) {\n simpleEscapeCheck[i] = simpleEscapeSequence(i) ? 1 : 0;\n simpleEscapeMap[i] = simpleEscapeSequence(i);\n}\n\n\nfunction State$1(input, options) {\n this.input = input;\n\n this.filename = options['filename'] || null;\n this.schema = options['schema'] || _default;\n this.onWarning = options['onWarning'] || null;\n // (Hidden) Remove? makes the loader to expect YAML 1.1 documents\n // if such documents have no explicit %YAML directive\n this.legacy = options['legacy'] || false;\n\n this.json = options['json'] || false;\n this.listener = options['listener'] || null;\n\n this.implicitTypes = this.schema.compiledImplicit;\n this.typeMap = this.schema.compiledTypeMap;\n\n this.length = input.length;\n this.position = 0;\n this.line = 0;\n this.lineStart = 0;\n this.lineIndent = 0;\n\n // position of first leading tab in the current line,\n // used to make sure there are no tabs in the indentation\n this.firstTabInLine = -1;\n\n this.documents = [];\n\n /*\n this.version;\n this.checkLineBreaks;\n this.tagMap;\n this.anchorMap;\n this.tag;\n this.anchor;\n this.kind;\n this.result;*/\n\n}\n\n\nfunction generateError(state, message) {\n var mark = {\n name: state.filename,\n buffer: state.input.slice(0, -1), // omit trailing \\0\n position: state.position,\n line: state.line,\n column: state.position - state.lineStart\n };\n\n mark.snippet = snippet(mark);\n\n return new exception(message, mark);\n}\n\nfunction throwError(state, message) {\n throw generateError(state, message);\n}\n\nfunction throwWarning(state, message) {\n if (state.onWarning) {\n state.onWarning.call(null, generateError(state, message));\n }\n}\n\n\nvar directiveHandlers = {\n\n YAML: function handleYamlDirective(state, name, args) {\n\n var match, major, minor;\n\n if (state.version !== null) {\n throwError(state, 'duplication of %YAML directive');\n }\n\n if (args.length !== 1) {\n throwError(state, 'YAML directive accepts exactly one argument');\n }\n\n match = /^([0-9]+)\\.([0-9]+)$/.exec(args[0]);\n\n if (match === null) {\n throwError(state, 'ill-formed argument of the YAML directive');\n }\n\n major = parseInt(match[1], 10);\n minor = parseInt(match[2], 10);\n\n if (major !== 1) {\n throwError(state, 'unacceptable YAML version of the document');\n }\n\n state.version = args[0];\n state.checkLineBreaks = (minor < 2);\n\n if (minor !== 1 && minor !== 2) {\n throwWarning(state, 'unsupported YAML version of the document');\n }\n },\n\n TAG: function handleTagDirective(state, name, args) {\n\n var handle, prefix;\n\n if (args.length !== 2) {\n throwError(state, 'TAG directive accepts exactly two arguments');\n }\n\n handle = args[0];\n prefix = args[1];\n\n if (!PATTERN_TAG_HANDLE.test(handle)) {\n throwError(state, 'ill-formed tag handle (first argument) of the TAG directive');\n }\n\n if (_hasOwnProperty$1.call(state.tagMap, handle)) {\n throwError(state, 'there is a previously declared suffix for \"' + handle + '\" tag handle');\n }\n\n if (!PATTERN_TAG_URI.test(prefix)) {\n throwError(state, 'ill-formed tag prefix (second argument) of the TAG directive');\n }\n\n try {\n prefix = decodeURIComponent(prefix);\n } catch (err) {\n throwError(state, 'tag prefix is malformed: ' + prefix);\n }\n\n state.tagMap[handle] = prefix;\n }\n};\n\n\nfunction captureSegment(state, start, end, checkJson) {\n var _position, _length, _character, _result;\n\n if (start < end) {\n _result = state.input.slice(start, end);\n\n if (checkJson) {\n for (_position = 0, _length = _result.length; _position < _length; _position += 1) {\n _character = _result.charCodeAt(_position);\n if (!(_character === 0x09 ||\n (0x20 <= _character && _character <= 0x10FFFF))) {\n throwError(state, 'expected valid JSON character');\n }\n }\n } else if (PATTERN_NON_PRINTABLE.test(_result)) {\n throwError(state, 'the stream contains non-printable characters');\n }\n\n state.result += _result;\n }\n}\n\nfunction mergeMappings(state, destination, source, overridableKeys) {\n var sourceKeys, key, index, quantity;\n\n if (!common.isObject(source)) {\n throwError(state, 'cannot merge mappings; the provided source object is unacceptable');\n }\n\n sourceKeys = Object.keys(source);\n\n for (index = 0, quantity = sourceKeys.length; index < quantity; index += 1) {\n key = sourceKeys[index];\n\n if (!_hasOwnProperty$1.call(destination, key)) {\n setProperty(destination, key, source[key]);\n overridableKeys[key] = true;\n }\n }\n}\n\nfunction storeMappingPair(state, _result, overridableKeys, keyTag, keyNode, valueNode,\n startLine, startLineStart, startPos) {\n\n var index, quantity;\n\n // The output is a plain object here, so keys can only be strings.\n // We need to convert keyNode to a string, but doing so can hang the process\n // (deeply nested arrays that explode exponentially using aliases).\n if (Array.isArray(keyNode)) {\n keyNode = Array.prototype.slice.call(keyNode);\n\n for (index = 0, quantity = keyNode.length; index < quantity; index += 1) {\n if (Array.isArray(keyNode[index])) {\n throwError(state, 'nested arrays are not supported inside keys');\n }\n\n if (typeof keyNode === 'object' && _class(keyNode[index]) === '[object Object]') {\n keyNode[index] = '[object Object]';\n }\n }\n }\n\n // Avoid code execution in load() via toString property\n // (still use its own toString for arrays, timestamps,\n // and whatever user schema extensions happen to have @@toStringTag)\n if (typeof keyNode === 'object' && _class(keyNode) === '[object Object]') {\n keyNode = '[object Object]';\n }\n\n\n keyNode = String(keyNode);\n\n if (_result === null) {\n _result = {};\n }\n\n if (keyTag === 'tag:yaml.org,2002:merge') {\n if (Array.isArray(valueNode)) {\n for (index = 0, quantity = valueNode.length; index < quantity; index += 1) {\n mergeMappings(state, _result, valueNode[index], overridableKeys);\n }\n } else {\n mergeMappings(state, _result, valueNode, overridableKeys);\n }\n } else {\n if (!state.json &&\n !_hasOwnProperty$1.call(overridableKeys, keyNode) &&\n _hasOwnProperty$1.call(_result, keyNode)) {\n state.line = startLine || state.line;\n state.lineStart = startLineStart || state.lineStart;\n state.position = startPos || state.position;\n throwError(state, 'duplicated mapping key');\n }\n\n setProperty(_result, keyNode, valueNode);\n delete overridableKeys[keyNode];\n }\n\n return _result;\n}\n\nfunction readLineBreak(state) {\n var ch;\n\n ch = state.input.charCodeAt(state.position);\n\n if (ch === 0x0A/* LF */) {\n state.position++;\n } else if (ch === 0x0D/* CR */) {\n state.position++;\n if (state.input.charCodeAt(state.position) === 0x0A/* LF */) {\n state.position++;\n }\n } else {\n throwError(state, 'a line break is expected');\n }\n\n state.line += 1;\n state.lineStart = state.position;\n state.firstTabInLine = -1;\n}\n\nfunction skipSeparationSpace(state, allowComments, checkIndent) {\n var lineBreaks = 0,\n ch = state.input.charCodeAt(state.position);\n\n while (ch !== 0) {\n while (is_WHITE_SPACE(ch)) {\n if (ch === 0x09/* Tab */ && state.firstTabInLine === -1) {\n state.firstTabInLine = state.position;\n }\n ch = state.input.charCodeAt(++state.position);\n }\n\n if (allowComments && ch === 0x23/* # */) {\n do {\n ch = state.input.charCodeAt(++state.position);\n } while (ch !== 0x0A/* LF */ && ch !== 0x0D/* CR */ && ch !== 0);\n }\n\n if (is_EOL(ch)) {\n readLineBreak(state);\n\n ch = state.input.charCodeAt(state.position);\n lineBreaks++;\n state.lineIndent = 0;\n\n while (ch === 0x20/* Space */) {\n state.lineIndent++;\n ch = state.input.charCodeAt(++state.position);\n }\n } else {\n break;\n }\n }\n\n if (checkIndent !== -1 && lineBreaks !== 0 && state.lineIndent < checkIndent) {\n throwWarning(state, 'deficient indentation');\n }\n\n return lineBreaks;\n}\n\nfunction testDocumentSeparator(state) {\n var _position = state.position,\n ch;\n\n ch = state.input.charCodeAt(_position);\n\n // Condition state.position === state.lineStart is tested\n // in parent on each call, for efficiency. No needs to test here again.\n if ((ch === 0x2D/* - */ || ch === 0x2E/* . */) &&\n ch === state.input.charCodeAt(_position + 1) &&\n ch === state.input.charCodeAt(_position + 2)) {\n\n _position += 3;\n\n ch = state.input.charCodeAt(_position);\n\n if (ch === 0 || is_WS_OR_EOL(ch)) {\n return true;\n }\n }\n\n return false;\n}\n\nfunction writeFoldedLines(state, count) {\n if (count === 1) {\n state.result += ' ';\n } else if (count > 1) {\n state.result += common.repeat('\\n', count - 1);\n }\n}\n\n\nfunction readPlainScalar(state, nodeIndent, withinFlowCollection) {\n var preceding,\n following,\n captureStart,\n captureEnd,\n hasPendingContent,\n _line,\n _lineStart,\n _lineIndent,\n _kind = state.kind,\n _result = state.result,\n ch;\n\n ch = state.input.charCodeAt(state.position);\n\n if (is_WS_OR_EOL(ch) ||\n is_FLOW_INDICATOR(ch) ||\n ch === 0x23/* # */ ||\n ch === 0x26/* & */ ||\n ch === 0x2A/* * */ ||\n ch === 0x21/* ! */ ||\n ch === 0x7C/* | */ ||\n ch === 0x3E/* > */ ||\n ch === 0x27/* ' */ ||\n ch === 0x22/* \" */ ||\n ch === 0x25/* % */ ||\n ch === 0x40/* @ */ ||\n ch === 0x60/* ` */) {\n return false;\n }\n\n if (ch === 0x3F/* ? */ || ch === 0x2D/* - */) {\n following = state.input.charCodeAt(state.position + 1);\n\n if (is_WS_OR_EOL(following) ||\n withinFlowCollection && is_FLOW_INDICATOR(following)) {\n return false;\n }\n }\n\n state.kind = 'scalar';\n state.result = '';\n captureStart = captureEnd = state.position;\n hasPendingContent = false;\n\n while (ch !== 0) {\n if (ch === 0x3A/* : */) {\n following = state.input.charCodeAt(state.position + 1);\n\n if (is_WS_OR_EOL(following) ||\n withinFlowCollection && is_FLOW_INDICATOR(following)) {\n break;\n }\n\n } else if (ch === 0x23/* # */) {\n preceding = state.input.charCodeAt(state.position - 1);\n\n if (is_WS_OR_EOL(preceding)) {\n break;\n }\n\n } else if ((state.position === state.lineStart && testDocumentSeparator(state)) ||\n withinFlowCollection && is_FLOW_INDICATOR(ch)) {\n break;\n\n } else if (is_EOL(ch)) {\n _line = state.line;\n _lineStart = state.lineStart;\n _lineIndent = state.lineIndent;\n skipSeparationSpace(state, false, -1);\n\n if (state.lineIndent >= nodeIndent) {\n hasPendingContent = true;\n ch = state.input.charCodeAt(state.position);\n continue;\n } else {\n state.position = captureEnd;\n state.line = _line;\n state.lineStart = _lineStart;\n state.lineIndent = _lineIndent;\n break;\n }\n }\n\n if (hasPendingContent) {\n captureSegment(state, captureStart, captureEnd, false);\n writeFoldedLines(state, state.line - _line);\n captureStart = captureEnd = state.position;\n hasPendingContent = false;\n }\n\n if (!is_WHITE_SPACE(ch)) {\n captureEnd = state.position + 1;\n }\n\n ch = state.input.charCodeAt(++state.position);\n }\n\n captureSegment(state, captureStart, captureEnd, false);\n\n if (state.result) {\n return true;\n }\n\n state.kind = _kind;\n state.result = _result;\n return false;\n}\n\nfunction readSingleQuotedScalar(state, nodeIndent) {\n var ch,\n captureStart, captureEnd;\n\n ch = state.input.charCodeAt(state.position);\n\n if (ch !== 0x27/* ' */) {\n return false;\n }\n\n state.kind = 'scalar';\n state.result = '';\n state.position++;\n captureStart = captureEnd = state.position;\n\n while ((ch = state.input.charCodeAt(state.position)) !== 0) {\n if (ch === 0x27/* ' */) {\n captureSegment(state, captureStart, state.position, true);\n ch = state.input.charCodeAt(++state.position);\n\n if (ch === 0x27/* ' */) {\n captureStart = state.position;\n state.position++;\n captureEnd = state.position;\n } else {\n return true;\n }\n\n } else if (is_EOL(ch)) {\n captureSegment(state, captureStart, captureEnd, true);\n writeFoldedLines(state, skipSeparationSpace(state, false, nodeIndent));\n captureStart = captureEnd = state.position;\n\n } else if (state.position === state.lineStart && testDocumentSeparator(state)) {\n throwError(state, 'unexpected end of the document within a single quoted scalar');\n\n } else {\n state.position++;\n captureEnd = state.position;\n }\n }\n\n throwError(state, 'unexpected end of the stream within a single quoted scalar');\n}\n\nfunction readDoubleQuotedScalar(state, nodeIndent) {\n var captureStart,\n captureEnd,\n hexLength,\n hexResult,\n tmp,\n ch;\n\n ch = state.input.charCodeAt(state.position);\n\n if (ch !== 0x22/* \" */) {\n return false;\n }\n\n state.kind = 'scalar';\n state.result = '';\n state.position++;\n captureStart = captureEnd = state.position;\n\n while ((ch = state.input.charCodeAt(state.position)) !== 0) {\n if (ch === 0x22/* \" */) {\n captureSegment(state, captureStart, state.position, true);\n state.position++;\n return true;\n\n } else if (ch === 0x5C/* \\ */) {\n captureSegment(state, captureStart, state.position, true);\n ch = state.input.charCodeAt(++state.position);\n\n if (is_EOL(ch)) {\n skipSeparationSpace(state, false, nodeIndent);\n\n // TODO: rework to inline fn with no type cast?\n } else if (ch < 256 && simpleEscapeCheck[ch]) {\n state.result += simpleEscapeMap[ch];\n state.position++;\n\n } else if ((tmp = escapedHexLen(ch)) > 0) {\n hexLength = tmp;\n hexResult = 0;\n\n for (; hexLength > 0; hexLength--) {\n ch = state.input.charCodeAt(++state.position);\n\n if ((tmp = fromHexCode(ch)) >= 0) {\n hexResult = (hexResult << 4) + tmp;\n\n } else {\n throwError(state, 'expected hexadecimal character');\n }\n }\n\n state.result += charFromCodepoint(hexResult);\n\n state.position++;\n\n } else {\n throwError(state, 'unknown escape sequence');\n }\n\n captureStart = captureEnd = state.position;\n\n } else if (is_EOL(ch)) {\n captureSegment(state, captureStart, captureEnd, true);\n writeFoldedLines(state, skipSeparationSpace(state, false, nodeIndent));\n captureStart = captureEnd = state.position;\n\n } else if (state.position === state.lineStart && testDocumentSeparator(state)) {\n throwError(state, 'unexpected end of the document within a double quoted scalar');\n\n } else {\n state.position++;\n captureEnd = state.position;\n }\n }\n\n throwError(state, 'unexpected end of the stream within a double quoted scalar');\n}\n\nfunction readFlowCollection(state, nodeIndent) {\n var readNext = true,\n _line,\n _lineStart,\n _pos,\n _tag = state.tag,\n _result,\n _anchor = state.anchor,\n following,\n terminator,\n isPair,\n isExplicitPair,\n isMapping,\n overridableKeys = Object.create(null),\n keyNode,\n keyTag,\n valueNode,\n ch;\n\n ch = state.input.charCodeAt(state.position);\n\n if (ch === 0x5B/* [ */) {\n terminator = 0x5D;/* ] */\n isMapping = false;\n _result = [];\n } else if (ch === 0x7B/* { */) {\n terminator = 0x7D;/* } */\n isMapping = true;\n _result = {};\n } else {\n return false;\n }\n\n if (state.anchor !== null) {\n state.anchorMap[state.anchor] = _result;\n }\n\n ch = state.input.charCodeAt(++state.position);\n\n while (ch !== 0) {\n skipSeparationSpace(state, true, nodeIndent);\n\n ch = state.input.charCodeAt(state.position);\n\n if (ch === terminator) {\n state.position++;\n state.tag = _tag;\n state.anchor = _anchor;\n state.kind = isMapping ? 'mapping' : 'sequence';\n state.result = _result;\n return true;\n } else if (!readNext) {\n throwError(state, 'missed comma between flow collection entries');\n } else if (ch === 0x2C/* , */) {\n // \"flow collection entries can never be completely empty\", as per YAML 1.2, section 7.4\n throwError(state, \"expected the node content, but found ','\");\n }\n\n keyTag = keyNode = valueNode = null;\n isPair = isExplicitPair = false;\n\n if (ch === 0x3F/* ? */) {\n following = state.input.charCodeAt(state.position + 1);\n\n if (is_WS_OR_EOL(following)) {\n isPair = isExplicitPair = true;\n state.position++;\n skipSeparationSpace(state, true, nodeIndent);\n }\n }\n\n _line = state.line; // Save the current line.\n _lineStart = state.lineStart;\n _pos = state.position;\n composeNode(state, nodeIndent, CONTEXT_FLOW_IN, false, true);\n keyTag = state.tag;\n keyNode = state.result;\n skipSeparationSpace(state, true, nodeIndent);\n\n ch = state.input.charCodeAt(state.position);\n\n if ((isExplicitPair || state.line === _line) && ch === 0x3A/* : */) {\n isPair = true;\n ch = state.input.charCodeAt(++state.position);\n skipSeparationSpace(state, true, nodeIndent);\n composeNode(state, nodeIndent, CONTEXT_FLOW_IN, false, true);\n valueNode = state.result;\n }\n\n if (isMapping) {\n storeMappingPair(state, _result, overridableKeys, keyTag, keyNode, valueNode, _line, _lineStart, _pos);\n } else if (isPair) {\n _result.push(storeMappingPair(state, null, overridableKeys, keyTag, keyNode, valueNode, _line, _lineStart, _pos));\n } else {\n _result.push(keyNode);\n }\n\n skipSeparationSpace(state, true, nodeIndent);\n\n ch = state.input.charCodeAt(state.position);\n\n if (ch === 0x2C/* , */) {\n readNext = true;\n ch = state.input.charCodeAt(++state.position);\n } else {\n readNext = false;\n }\n }\n\n throwError(state, 'unexpected end of the stream within a flow collection');\n}\n\nfunction readBlockScalar(state, nodeIndent) {\n var captureStart,\n folding,\n chomping = CHOMPING_CLIP,\n didReadContent = false,\n detectedIndent = false,\n textIndent = nodeIndent,\n emptyLines = 0,\n atMoreIndented = false,\n tmp,\n ch;\n\n ch = state.input.charCodeAt(state.position);\n\n if (ch === 0x7C/* | */) {\n folding = false;\n } else if (ch === 0x3E/* > */) {\n folding = true;\n } else {\n return false;\n }\n\n state.kind = 'scalar';\n state.result = '';\n\n while (ch !== 0) {\n ch = state.input.charCodeAt(++state.position);\n\n if (ch === 0x2B/* + */ || ch === 0x2D/* - */) {\n if (CHOMPING_CLIP === chomping) {\n chomping = (ch === 0x2B/* + */) ? CHOMPING_KEEP : CHOMPING_STRIP;\n } else {\n throwError(state, 'repeat of a chomping mode identifier');\n }\n\n } else if ((tmp = fromDecimalCode(ch)) >= 0) {\n if (tmp === 0) {\n throwError(state, 'bad explicit indentation width of a block scalar; it cannot be less than one');\n } else if (!detectedIndent) {\n textIndent = nodeIndent + tmp - 1;\n detectedIndent = true;\n } else {\n throwError(state, 'repeat of an indentation width identifier');\n }\n\n } else {\n break;\n }\n }\n\n if (is_WHITE_SPACE(ch)) {\n do { ch = state.input.charCodeAt(++state.position); }\n while (is_WHITE_SPACE(ch));\n\n if (ch === 0x23/* # */) {\n do { ch = state.input.charCodeAt(++state.position); }\n while (!is_EOL(ch) && (ch !== 0));\n }\n }\n\n while (ch !== 0) {\n readLineBreak(state);\n state.lineIndent = 0;\n\n ch = state.input.charCodeAt(state.position);\n\n while ((!detectedIndent || state.lineIndent < textIndent) &&\n (ch === 0x20/* Space */)) {\n state.lineIndent++;\n ch = state.input.charCodeAt(++state.position);\n }\n\n if (!detectedIndent && state.lineIndent > textIndent) {\n textIndent = state.lineIndent;\n }\n\n if (is_EOL(ch)) {\n emptyLines++;\n continue;\n }\n\n // End of the scalar.\n if (state.lineIndent < textIndent) {\n\n // Perform the chomping.\n if (chomping === CHOMPING_KEEP) {\n state.result += common.repeat('\\n', didReadContent ? 1 + emptyLines : emptyLines);\n } else if (chomping === CHOMPING_CLIP) {\n if (didReadContent) { // i.e. only if the scalar is not empty.\n state.result += '\\n';\n }\n }\n\n // Break this `while` cycle and go to the funciton's epilogue.\n break;\n }\n\n // Folded style: use fancy rules to handle line breaks.\n if (folding) {\n\n // Lines starting with white space characters (more-indented lines) are not folded.\n if (is_WHITE_SPACE(ch)) {\n atMoreIndented = true;\n // except for the first content line (cf. Example 8.1)\n state.result += common.repeat('\\n', didReadContent ? 1 + emptyLines : emptyLines);\n\n // End of more-indented block.\n } else if (atMoreIndented) {\n atMoreIndented = false;\n state.result += common.repeat('\\n', emptyLines + 1);\n\n // Just one line break - perceive as the same line.\n } else if (emptyLines === 0) {\n if (didReadContent) { // i.e. only if we have already read some scalar content.\n state.result += ' ';\n }\n\n // Several line breaks - perceive as different lines.\n } else {\n state.result += common.repeat('\\n', emptyLines);\n }\n\n // Literal style: just add exact number of line breaks between content lines.\n } else {\n // Keep all line breaks except the header line break.\n state.result += common.repeat('\\n', didReadContent ? 1 + emptyLines : emptyLines);\n }\n\n didReadContent = true;\n detectedIndent = true;\n emptyLines = 0;\n captureStart = state.position;\n\n while (!is_EOL(ch) && (ch !== 0)) {\n ch = state.input.charCodeAt(++state.position);\n }\n\n captureSegment(state, captureStart, state.position, false);\n }\n\n return true;\n}\n\nfunction readBlockSequence(state, nodeIndent) {\n var _line,\n _tag = state.tag,\n _anchor = state.anchor,\n _result = [],\n following,\n detected = false,\n ch;\n\n // there is a leading tab before this token, so it can't be a block sequence/mapping;\n // it can still be flow sequence/mapping or a scalar\n if (state.firstTabInLine !== -1) return false;\n\n if (state.anchor !== null) {\n state.anchorMap[state.anchor] = _result;\n }\n\n ch = state.input.charCodeAt(state.position);\n\n while (ch !== 0) {\n if (state.firstTabInLine !== -1) {\n state.position = state.firstTabInLine;\n throwError(state, 'tab characters must not be used in indentation');\n }\n\n if (ch !== 0x2D/* - */) {\n break;\n }\n\n following = state.input.charCodeAt(state.position + 1);\n\n if (!is_WS_OR_EOL(following)) {\n break;\n }\n\n detected = true;\n state.position++;\n\n if (skipSeparationSpace(state, true, -1)) {\n if (state.lineIndent <= nodeIndent) {\n _result.push(null);\n ch = state.input.charCodeAt(state.position);\n continue;\n }\n }\n\n _line = state.line;\n composeNode(state, nodeIndent, CONTEXT_BLOCK_IN, false, true);\n _result.push(state.result);\n skipSeparationSpace(state, true, -1);\n\n ch = state.input.charCodeAt(state.position);\n\n if ((state.line === _line || state.lineIndent > nodeIndent) && (ch !== 0)) {\n throwError(state, 'bad indentation of a sequence entry');\n } else if (state.lineIndent < nodeIndent) {\n break;\n }\n }\n\n if (detected) {\n state.tag = _tag;\n state.anchor = _anchor;\n state.kind = 'sequence';\n state.result = _result;\n return true;\n }\n return false;\n}\n\nfunction readBlockMapping(state, nodeIndent, flowIndent) {\n var following,\n allowCompact,\n _line,\n _keyLine,\n _keyLineStart,\n _keyPos,\n _tag = state.tag,\n _anchor = state.anchor,\n _result = {},\n overridableKeys = Object.create(null),\n keyTag = null,\n keyNode = null,\n valueNode = null,\n atExplicitKey = false,\n detected = false,\n ch;\n\n // there is a leading tab before this token, so it can't be a block sequence/mapping;\n // it can still be flow sequence/mapping or a scalar\n if (state.firstTabInLine !== -1) return false;\n\n if (state.anchor !== null) {\n state.anchorMap[state.anchor] = _result;\n }\n\n ch = state.input.charCodeAt(state.position);\n\n while (ch !== 0) {\n if (!atExplicitKey && state.firstTabInLine !== -1) {\n state.position = state.firstTabInLine;\n throwError(state, 'tab characters must not be used in indentation');\n }\n\n following = state.input.charCodeAt(state.position + 1);\n _line = state.line; // Save the current line.\n\n //\n // Explicit notation case. There are two separate blocks:\n // first for the key (denoted by \"?\") and second for the value (denoted by \":\")\n //\n if ((ch === 0x3F/* ? */ || ch === 0x3A/* : */) && is_WS_OR_EOL(following)) {\n\n if (ch === 0x3F/* ? */) {\n if (atExplicitKey) {\n storeMappingPair(state, _result, overridableKeys, keyTag, keyNode, null, _keyLine, _keyLineStart, _keyPos);\n keyTag = keyNode = valueNode = null;\n }\n\n detected = true;\n atExplicitKey = true;\n allowCompact = true;\n\n } else if (atExplicitKey) {\n // i.e. 0x3A/* : */ === character after the explicit key.\n atExplicitKey = false;\n allowCompact = true;\n\n } else {\n throwError(state, 'incomplete explicit mapping pair; a key node is missed; or followed by a non-tabulated empty line');\n }\n\n state.position += 1;\n ch = following;\n\n //\n // Implicit notation case. Flow-style node as the key first, then \":\", and the value.\n //\n } else {\n _keyLine = state.line;\n _keyLineStart = state.lineStart;\n _keyPos = state.position;\n\n if (!composeNode(state, flowIndent, CONTEXT_FLOW_OUT, false, true)) {\n // Neither implicit nor explicit notation.\n // Reading is done. Go to the epilogue.\n break;\n }\n\n if (state.line === _line) {\n ch = state.input.charCodeAt(state.position);\n\n while (is_WHITE_SPACE(ch)) {\n ch = state.input.charCodeAt(++state.position);\n }\n\n if (ch === 0x3A/* : */) {\n ch = state.input.charCodeAt(++state.position);\n\n if (!is_WS_OR_EOL(ch)) {\n throwError(state, 'a whitespace character is expected after the key-value separator within a block mapping');\n }\n\n if (atExplicitKey) {\n storeMappingPair(state, _result, overridableKeys, keyTag, keyNode, null, _keyLine, _keyLineStart, _keyPos);\n keyTag = keyNode = valueNode = null;\n }\n\n detected = true;\n atExplicitKey = false;\n allowCompact = false;\n keyTag = state.tag;\n keyNode = state.result;\n\n } else if (detected) {\n throwError(state, 'can not read an implicit mapping pair; a colon is missed');\n\n } else {\n state.tag = _tag;\n state.anchor = _anchor;\n return true; // Keep the result of `composeNode`.\n }\n\n } else if (detected) {\n throwError(state, 'can not read a block mapping entry; a multiline key may not be an implicit key');\n\n } else {\n state.tag = _tag;\n state.anchor = _anchor;\n return true; // Keep the result of `composeNode`.\n }\n }\n\n //\n // Common reading code for both explicit and implicit notations.\n //\n if (state.line === _line || state.lineIndent > nodeIndent) {\n if (atExplicitKey) {\n _keyLine = state.line;\n _keyLineStart = state.lineStart;\n _keyPos = state.position;\n }\n\n if (composeNode(state, nodeIndent, CONTEXT_BLOCK_OUT, true, allowCompact)) {\n if (atExplicitKey) {\n keyNode = state.result;\n } else {\n valueNode = state.result;\n }\n }\n\n if (!atExplicitKey) {\n storeMappingPair(state, _result, overridableKeys, keyTag, keyNode, valueNode, _keyLine, _keyLineStart, _keyPos);\n keyTag = keyNode = valueNode = null;\n }\n\n skipSeparationSpace(state, true, -1);\n ch = state.input.charCodeAt(state.position);\n }\n\n if ((state.line === _line || state.lineIndent > nodeIndent) && (ch !== 0)) {\n throwError(state, 'bad indentation of a mapping entry');\n } else if (state.lineIndent < nodeIndent) {\n break;\n }\n }\n\n //\n // Epilogue.\n //\n\n // Special case: last mapping's node contains only the key in explicit notation.\n if (atExplicitKey) {\n storeMappingPair(state, _result, overridableKeys, keyTag, keyNode, null, _keyLine, _keyLineStart, _keyPos);\n }\n\n // Expose the resulting mapping.\n if (detected) {\n state.tag = _tag;\n state.anchor = _anchor;\n state.kind = 'mapping';\n state.result = _result;\n }\n\n return detected;\n}\n\nfunction readTagProperty(state) {\n var _position,\n isVerbatim = false,\n isNamed = false,\n tagHandle,\n tagName,\n ch;\n\n ch = state.input.charCodeAt(state.position);\n\n if (ch !== 0x21/* ! */) return false;\n\n if (state.tag !== null) {\n throwError(state, 'duplication of a tag property');\n }\n\n ch = state.input.charCodeAt(++state.position);\n\n if (ch === 0x3C/* < */) {\n isVerbatim = true;\n ch = state.input.charCodeAt(++state.position);\n\n } else if (ch === 0x21/* ! */) {\n isNamed = true;\n tagHandle = '!!';\n ch = state.input.charCodeAt(++state.position);\n\n } else {\n tagHandle = '!';\n }\n\n _position = state.position;\n\n if (isVerbatim) {\n do { ch = state.input.charCodeAt(++state.position); }\n while (ch !== 0 && ch !== 0x3E/* > */);\n\n if (state.position < state.length) {\n tagName = state.input.slice(_position, state.position);\n ch = state.input.charCodeAt(++state.position);\n } else {\n throwError(state, 'unexpected end of the stream within a verbatim tag');\n }\n } else {\n while (ch !== 0 && !is_WS_OR_EOL(ch)) {\n\n if (ch === 0x21/* ! */) {\n if (!isNamed) {\n tagHandle = state.input.slice(_position - 1, state.position + 1);\n\n if (!PATTERN_TAG_HANDLE.test(tagHandle)) {\n throwError(state, 'named tag handle cannot contain such characters');\n }\n\n isNamed = true;\n _position = state.position + 1;\n } else {\n throwError(state, 'tag suffix cannot contain exclamation marks');\n }\n }\n\n ch = state.input.charCodeAt(++state.position);\n }\n\n tagName = state.input.slice(_position, state.position);\n\n if (PATTERN_FLOW_INDICATORS.test(tagName)) {\n throwError(state, 'tag suffix cannot contain flow indicator characters');\n }\n }\n\n if (tagName && !PATTERN_TAG_URI.test(tagName)) {\n throwError(state, 'tag name cannot contain such characters: ' + tagName);\n }\n\n try {\n tagName = decodeURIComponent(tagName);\n } catch (err) {\n throwError(state, 'tag name is malformed: ' + tagName);\n }\n\n if (isVerbatim) {\n state.tag = tagName;\n\n } else if (_hasOwnProperty$1.call(state.tagMap, tagHandle)) {\n state.tag = state.tagMap[tagHandle] + tagName;\n\n } else if (tagHandle === '!') {\n state.tag = '!' + tagName;\n\n } else if (tagHandle === '!!') {\n state.tag = 'tag:yaml.org,2002:' + tagName;\n\n } else {\n throwError(state, 'undeclared tag handle \"' + tagHandle + '\"');\n }\n\n return true;\n}\n\nfunction readAnchorProperty(state) {\n var _position,\n ch;\n\n ch = state.input.charCodeAt(state.position);\n\n if (ch !== 0x26/* & */) return false;\n\n if (state.anchor !== null) {\n throwError(state, 'duplication of an anchor property');\n }\n\n ch = state.input.charCodeAt(++state.position);\n _position = state.position;\n\n while (ch !== 0 && !is_WS_OR_EOL(ch) && !is_FLOW_INDICATOR(ch)) {\n ch = state.input.charCodeAt(++state.position);\n }\n\n if (state.position === _position) {\n throwError(state, 'name of an anchor node must contain at least one character');\n }\n\n state.anchor = state.input.slice(_position, state.position);\n return true;\n}\n\nfunction readAlias(state) {\n var _position, alias,\n ch;\n\n ch = state.input.charCodeAt(state.position);\n\n if (ch !== 0x2A/* * */) return false;\n\n ch = state.input.charCodeAt(++state.position);\n _position = state.position;\n\n while (ch !== 0 && !is_WS_OR_EOL(ch) && !is_FLOW_INDICATOR(ch)) {\n ch = state.input.charCodeAt(++state.position);\n }\n\n if (state.position === _position) {\n throwError(state, 'name of an alias node must contain at least one character');\n }\n\n alias = state.input.slice(_position, state.position);\n\n if (!_hasOwnProperty$1.call(state.anchorMap, alias)) {\n throwError(state, 'unidentified alias \"' + alias + '\"');\n }\n\n state.result = state.anchorMap[alias];\n skipSeparationSpace(state, true, -1);\n return true;\n}\n\nfunction composeNode(state, parentIndent, nodeContext, allowToSeek, allowCompact) {\n var allowBlockStyles,\n allowBlockScalars,\n allowBlockCollections,\n indentStatus = 1, // 1: this>parent, 0: this=parent, -1: this parentIndent) {\n indentStatus = 1;\n } else if (state.lineIndent === parentIndent) {\n indentStatus = 0;\n } else if (state.lineIndent < parentIndent) {\n indentStatus = -1;\n }\n }\n }\n\n if (indentStatus === 1) {\n while (readTagProperty(state) || readAnchorProperty(state)) {\n if (skipSeparationSpace(state, true, -1)) {\n atNewLine = true;\n allowBlockCollections = allowBlockStyles;\n\n if (state.lineIndent > parentIndent) {\n indentStatus = 1;\n } else if (state.lineIndent === parentIndent) {\n indentStatus = 0;\n } else if (state.lineIndent < parentIndent) {\n indentStatus = -1;\n }\n } else {\n allowBlockCollections = false;\n }\n }\n }\n\n if (allowBlockCollections) {\n allowBlockCollections = atNewLine || allowCompact;\n }\n\n if (indentStatus === 1 || CONTEXT_BLOCK_OUT === nodeContext) {\n if (CONTEXT_FLOW_IN === nodeContext || CONTEXT_FLOW_OUT === nodeContext) {\n flowIndent = parentIndent;\n } else {\n flowIndent = parentIndent + 1;\n }\n\n blockIndent = state.position - state.lineStart;\n\n if (indentStatus === 1) {\n if (allowBlockCollections &&\n (readBlockSequence(state, blockIndent) ||\n readBlockMapping(state, blockIndent, flowIndent)) ||\n readFlowCollection(state, flowIndent)) {\n hasContent = true;\n } else {\n if ((allowBlockScalars && readBlockScalar(state, flowIndent)) ||\n readSingleQuotedScalar(state, flowIndent) ||\n readDoubleQuotedScalar(state, flowIndent)) {\n hasContent = true;\n\n } else if (readAlias(state)) {\n hasContent = true;\n\n if (state.tag !== null || state.anchor !== null) {\n throwError(state, 'alias node should not have any properties');\n }\n\n } else if (readPlainScalar(state, flowIndent, CONTEXT_FLOW_IN === nodeContext)) {\n hasContent = true;\n\n if (state.tag === null) {\n state.tag = '?';\n }\n }\n\n if (state.anchor !== null) {\n state.anchorMap[state.anchor] = state.result;\n }\n }\n } else if (indentStatus === 0) {\n // Special case: block sequences are allowed to have same indentation level as the parent.\n // http://www.yaml.org/spec/1.2/spec.html#id2799784\n hasContent = allowBlockCollections && readBlockSequence(state, blockIndent);\n }\n }\n\n if (state.tag === null) {\n if (state.anchor !== null) {\n state.anchorMap[state.anchor] = state.result;\n }\n\n } else if (state.tag === '?') {\n // Implicit resolving is not allowed for non-scalar types, and '?'\n // non-specific tag is only automatically assigned to plain scalars.\n //\n // We only need to check kind conformity in case user explicitly assigns '?'\n // tag, for example like this: \"! [0]\"\n //\n if (state.result !== null && state.kind !== 'scalar') {\n throwError(state, 'unacceptable node kind for ! tag; it should be \"scalar\", not \"' + state.kind + '\"');\n }\n\n for (typeIndex = 0, typeQuantity = state.implicitTypes.length; typeIndex < typeQuantity; typeIndex += 1) {\n type = state.implicitTypes[typeIndex];\n\n if (type.resolve(state.result)) { // `state.result` updated in resolver if matched\n state.result = type.construct(state.result);\n state.tag = type.tag;\n if (state.anchor !== null) {\n state.anchorMap[state.anchor] = state.result;\n }\n break;\n }\n }\n } else if (state.tag !== '!') {\n if (_hasOwnProperty$1.call(state.typeMap[state.kind || 'fallback'], state.tag)) {\n type = state.typeMap[state.kind || 'fallback'][state.tag];\n } else {\n // looking for multi type\n type = null;\n typeList = state.typeMap.multi[state.kind || 'fallback'];\n\n for (typeIndex = 0, typeQuantity = typeList.length; typeIndex < typeQuantity; typeIndex += 1) {\n if (state.tag.slice(0, typeList[typeIndex].tag.length) === typeList[typeIndex].tag) {\n type = typeList[typeIndex];\n break;\n }\n }\n }\n\n if (!type) {\n throwError(state, 'unknown tag !<' + state.tag + '>');\n }\n\n if (state.result !== null && type.kind !== state.kind) {\n throwError(state, 'unacceptable node kind for !<' + state.tag + '> tag; it should be \"' + type.kind + '\", not \"' + state.kind + '\"');\n }\n\n if (!type.resolve(state.result, state.tag)) { // `state.result` updated in resolver if matched\n throwError(state, 'cannot resolve a node with !<' + state.tag + '> explicit tag');\n } else {\n state.result = type.construct(state.result, state.tag);\n if (state.anchor !== null) {\n state.anchorMap[state.anchor] = state.result;\n }\n }\n }\n\n if (state.listener !== null) {\n state.listener('close', state);\n }\n return state.tag !== null || state.anchor !== null || hasContent;\n}\n\nfunction readDocument(state) {\n var documentStart = state.position,\n _position,\n directiveName,\n directiveArgs,\n hasDirectives = false,\n ch;\n\n state.version = null;\n state.checkLineBreaks = state.legacy;\n state.tagMap = Object.create(null);\n state.anchorMap = Object.create(null);\n\n while ((ch = state.input.charCodeAt(state.position)) !== 0) {\n skipSeparationSpace(state, true, -1);\n\n ch = state.input.charCodeAt(state.position);\n\n if (state.lineIndent > 0 || ch !== 0x25/* % */) {\n break;\n }\n\n hasDirectives = true;\n ch = state.input.charCodeAt(++state.position);\n _position = state.position;\n\n while (ch !== 0 && !is_WS_OR_EOL(ch)) {\n ch = state.input.charCodeAt(++state.position);\n }\n\n directiveName = state.input.slice(_position, state.position);\n directiveArgs = [];\n\n if (directiveName.length < 1) {\n throwError(state, 'directive name must not be less than one character in length');\n }\n\n while (ch !== 0) {\n while (is_WHITE_SPACE(ch)) {\n ch = state.input.charCodeAt(++state.position);\n }\n\n if (ch === 0x23/* # */) {\n do { ch = state.input.charCodeAt(++state.position); }\n while (ch !== 0 && !is_EOL(ch));\n break;\n }\n\n if (is_EOL(ch)) break;\n\n _position = state.position;\n\n while (ch !== 0 && !is_WS_OR_EOL(ch)) {\n ch = state.input.charCodeAt(++state.position);\n }\n\n directiveArgs.push(state.input.slice(_position, state.position));\n }\n\n if (ch !== 0) readLineBreak(state);\n\n if (_hasOwnProperty$1.call(directiveHandlers, directiveName)) {\n directiveHandlers[directiveName](state, directiveName, directiveArgs);\n } else {\n throwWarning(state, 'unknown document directive \"' + directiveName + '\"');\n }\n }\n\n skipSeparationSpace(state, true, -1);\n\n if (state.lineIndent === 0 &&\n state.input.charCodeAt(state.position) === 0x2D/* - */ &&\n state.input.charCodeAt(state.position + 1) === 0x2D/* - */ &&\n state.input.charCodeAt(state.position + 2) === 0x2D/* - */) {\n state.position += 3;\n skipSeparationSpace(state, true, -1);\n\n } else if (hasDirectives) {\n throwError(state, 'directives end mark is expected');\n }\n\n composeNode(state, state.lineIndent - 1, CONTEXT_BLOCK_OUT, false, true);\n skipSeparationSpace(state, true, -1);\n\n if (state.checkLineBreaks &&\n PATTERN_NON_ASCII_LINE_BREAKS.test(state.input.slice(documentStart, state.position))) {\n throwWarning(state, 'non-ASCII line breaks are interpreted as content');\n }\n\n state.documents.push(state.result);\n\n if (state.position === state.lineStart && testDocumentSeparator(state)) {\n\n if (state.input.charCodeAt(state.position) === 0x2E/* . */) {\n state.position += 3;\n skipSeparationSpace(state, true, -1);\n }\n return;\n }\n\n if (state.position < (state.length - 1)) {\n throwError(state, 'end of the stream or a document separator is expected');\n } else {\n return;\n }\n}\n\n\nfunction loadDocuments(input, options) {\n input = String(input);\n options = options || {};\n\n if (input.length !== 0) {\n\n // Add tailing `\\n` if not exists\n if (input.charCodeAt(input.length - 1) !== 0x0A/* LF */ &&\n input.charCodeAt(input.length - 1) !== 0x0D/* CR */) {\n input += '\\n';\n }\n\n // Strip BOM\n if (input.charCodeAt(0) === 0xFEFF) {\n input = input.slice(1);\n }\n }\n\n var state = new State$1(input, options);\n\n var nullpos = input.indexOf('\\0');\n\n if (nullpos !== -1) {\n state.position = nullpos;\n throwError(state, 'null byte is not allowed in input');\n }\n\n // Use 0 as string terminator. That significantly simplifies bounds check.\n state.input += '\\0';\n\n while (state.input.charCodeAt(state.position) === 0x20/* Space */) {\n state.lineIndent += 1;\n state.position += 1;\n }\n\n while (state.position < (state.length - 1)) {\n readDocument(state);\n }\n\n return state.documents;\n}\n\n\nfunction loadAll$1(input, iterator, options) {\n if (iterator !== null && typeof iterator === 'object' && typeof options === 'undefined') {\n options = iterator;\n iterator = null;\n }\n\n var documents = loadDocuments(input, options);\n\n if (typeof iterator !== 'function') {\n return documents;\n }\n\n for (var index = 0, length = documents.length; index < length; index += 1) {\n iterator(documents[index]);\n }\n}\n\n\nfunction load$1(input, options) {\n var documents = loadDocuments(input, options);\n\n if (documents.length === 0) {\n /*eslint-disable no-undefined*/\n return undefined;\n } else if (documents.length === 1) {\n return documents[0];\n }\n throw new exception('expected a single document in the stream, but found more');\n}\n\n\nvar loadAll_1 = loadAll$1;\nvar load_1 = load$1;\n\nvar loader = {\n\tloadAll: loadAll_1,\n\tload: load_1\n};\n\n/*eslint-disable no-use-before-define*/\n\n\n\n\n\nvar _toString = Object.prototype.toString;\nvar _hasOwnProperty = Object.prototype.hasOwnProperty;\n\nvar CHAR_BOM = 0xFEFF;\nvar CHAR_TAB = 0x09; /* Tab */\nvar CHAR_LINE_FEED = 0x0A; /* LF */\nvar CHAR_CARRIAGE_RETURN = 0x0D; /* CR */\nvar CHAR_SPACE = 0x20; /* Space */\nvar CHAR_EXCLAMATION = 0x21; /* ! */\nvar CHAR_DOUBLE_QUOTE = 0x22; /* \" */\nvar CHAR_SHARP = 0x23; /* # */\nvar CHAR_PERCENT = 0x25; /* % */\nvar CHAR_AMPERSAND = 0x26; /* & */\nvar CHAR_SINGLE_QUOTE = 0x27; /* ' */\nvar CHAR_ASTERISK = 0x2A; /* * */\nvar CHAR_COMMA = 0x2C; /* , */\nvar CHAR_MINUS = 0x2D; /* - */\nvar CHAR_COLON = 0x3A; /* : */\nvar CHAR_EQUALS = 0x3D; /* = */\nvar CHAR_GREATER_THAN = 0x3E; /* > */\nvar CHAR_QUESTION = 0x3F; /* ? */\nvar CHAR_COMMERCIAL_AT = 0x40; /* @ */\nvar CHAR_LEFT_SQUARE_BRACKET = 0x5B; /* [ */\nvar CHAR_RIGHT_SQUARE_BRACKET = 0x5D; /* ] */\nvar CHAR_GRAVE_ACCENT = 0x60; /* ` */\nvar CHAR_LEFT_CURLY_BRACKET = 0x7B; /* { */\nvar CHAR_VERTICAL_LINE = 0x7C; /* | */\nvar CHAR_RIGHT_CURLY_BRACKET = 0x7D; /* } */\n\nvar ESCAPE_SEQUENCES = {};\n\nESCAPE_SEQUENCES[0x00] = '\\\\0';\nESCAPE_SEQUENCES[0x07] = '\\\\a';\nESCAPE_SEQUENCES[0x08] = '\\\\b';\nESCAPE_SEQUENCES[0x09] = '\\\\t';\nESCAPE_SEQUENCES[0x0A] = '\\\\n';\nESCAPE_SEQUENCES[0x0B] = '\\\\v';\nESCAPE_SEQUENCES[0x0C] = '\\\\f';\nESCAPE_SEQUENCES[0x0D] = '\\\\r';\nESCAPE_SEQUENCES[0x1B] = '\\\\e';\nESCAPE_SEQUENCES[0x22] = '\\\\\"';\nESCAPE_SEQUENCES[0x5C] = '\\\\\\\\';\nESCAPE_SEQUENCES[0x85] = '\\\\N';\nESCAPE_SEQUENCES[0xA0] = '\\\\_';\nESCAPE_SEQUENCES[0x2028] = '\\\\L';\nESCAPE_SEQUENCES[0x2029] = '\\\\P';\n\nvar DEPRECATED_BOOLEANS_SYNTAX = [\n 'y', 'Y', 'yes', 'Yes', 'YES', 'on', 'On', 'ON',\n 'n', 'N', 'no', 'No', 'NO', 'off', 'Off', 'OFF'\n];\n\nvar DEPRECATED_BASE60_SYNTAX = /^[-+]?[0-9_]+(?::[0-9_]+)+(?:\\.[0-9_]*)?$/;\n\nfunction compileStyleMap(schema, map) {\n var result, keys, index, length, tag, style, type;\n\n if (map === null) return {};\n\n result = {};\n keys = Object.keys(map);\n\n for (index = 0, length = keys.length; index < length; index += 1) {\n tag = keys[index];\n style = String(map[tag]);\n\n if (tag.slice(0, 2) === '!!') {\n tag = 'tag:yaml.org,2002:' + tag.slice(2);\n }\n type = schema.compiledTypeMap['fallback'][tag];\n\n if (type && _hasOwnProperty.call(type.styleAliases, style)) {\n style = type.styleAliases[style];\n }\n\n result[tag] = style;\n }\n\n return result;\n}\n\nfunction encodeHex(character) {\n var string, handle, length;\n\n string = character.toString(16).toUpperCase();\n\n if (character <= 0xFF) {\n handle = 'x';\n length = 2;\n } else if (character <= 0xFFFF) {\n handle = 'u';\n length = 4;\n } else if (character <= 0xFFFFFFFF) {\n handle = 'U';\n length = 8;\n } else {\n throw new exception('code point within a string may not be greater than 0xFFFFFFFF');\n }\n\n return '\\\\' + handle + common.repeat('0', length - string.length) + string;\n}\n\n\nvar QUOTING_TYPE_SINGLE = 1,\n QUOTING_TYPE_DOUBLE = 2;\n\nfunction State(options) {\n this.schema = options['schema'] || _default;\n this.indent = Math.max(1, (options['indent'] || 2));\n this.noArrayIndent = options['noArrayIndent'] || false;\n this.skipInvalid = options['skipInvalid'] || false;\n this.flowLevel = (common.isNothing(options['flowLevel']) ? -1 : options['flowLevel']);\n this.styleMap = compileStyleMap(this.schema, options['styles'] || null);\n this.sortKeys = options['sortKeys'] || false;\n this.lineWidth = options['lineWidth'] || 80;\n this.noRefs = options['noRefs'] || false;\n this.noCompatMode = options['noCompatMode'] || false;\n this.condenseFlow = options['condenseFlow'] || false;\n this.quotingType = options['quotingType'] === '\"' ? QUOTING_TYPE_DOUBLE : QUOTING_TYPE_SINGLE;\n this.forceQuotes = options['forceQuotes'] || false;\n this.replacer = typeof options['replacer'] === 'function' ? options['replacer'] : null;\n\n this.implicitTypes = this.schema.compiledImplicit;\n this.explicitTypes = this.schema.compiledExplicit;\n\n this.tag = null;\n this.result = '';\n\n this.duplicates = [];\n this.usedDuplicates = null;\n}\n\n// Indents every line in a string. Empty lines (\\n only) are not indented.\nfunction indentString(string, spaces) {\n var ind = common.repeat(' ', spaces),\n position = 0,\n next = -1,\n result = '',\n line,\n length = string.length;\n\n while (position < length) {\n next = string.indexOf('\\n', position);\n if (next === -1) {\n line = string.slice(position);\n position = length;\n } else {\n line = string.slice(position, next + 1);\n position = next + 1;\n }\n\n if (line.length && line !== '\\n') result += ind;\n\n result += line;\n }\n\n return result;\n}\n\nfunction generateNextLine(state, level) {\n return '\\n' + common.repeat(' ', state.indent * level);\n}\n\nfunction testImplicitResolving(state, str) {\n var index, length, type;\n\n for (index = 0, length = state.implicitTypes.length; index < length; index += 1) {\n type = state.implicitTypes[index];\n\n if (type.resolve(str)) {\n return true;\n }\n }\n\n return false;\n}\n\n// [33] s-white ::= s-space | s-tab\nfunction isWhitespace(c) {\n return c === CHAR_SPACE || c === CHAR_TAB;\n}\n\n// Returns true if the character can be printed without escaping.\n// From YAML 1.2: \"any allowed characters known to be non-printable\n// should also be escaped. [However,] This isn\u2019t mandatory\"\n// Derived from nb-char - \\t - #x85 - #xA0 - #x2028 - #x2029.\nfunction isPrintable(c) {\n return (0x00020 <= c && c <= 0x00007E)\n || ((0x000A1 <= c && c <= 0x00D7FF) && c !== 0x2028 && c !== 0x2029)\n || ((0x0E000 <= c && c <= 0x00FFFD) && c !== CHAR_BOM)\n || (0x10000 <= c && c <= 0x10FFFF);\n}\n\n// [34] ns-char ::= nb-char - s-white\n// [27] nb-char ::= c-printable - b-char - c-byte-order-mark\n// [26] b-char ::= b-line-feed | b-carriage-return\n// Including s-white (for some reason, examples doesn't match specs in this aspect)\n// ns-char ::= c-printable - b-line-feed - b-carriage-return - c-byte-order-mark\nfunction isNsCharOrWhitespace(c) {\n return isPrintable(c)\n && c !== CHAR_BOM\n // - b-char\n && c !== CHAR_CARRIAGE_RETURN\n && c !== CHAR_LINE_FEED;\n}\n\n// [127] ns-plain-safe(c) ::= c = flow-out \u21D2 ns-plain-safe-out\n// c = flow-in \u21D2 ns-plain-safe-in\n// c = block-key \u21D2 ns-plain-safe-out\n// c = flow-key \u21D2 ns-plain-safe-in\n// [128] ns-plain-safe-out ::= ns-char\n// [129] ns-plain-safe-in ::= ns-char - c-flow-indicator\n// [130] ns-plain-char(c) ::= ( ns-plain-safe(c) - \u201C:\u201D - \u201C#\u201D )\n// | ( /* An ns-char preceding */ \u201C#\u201D )\n// | ( \u201C:\u201D /* Followed by an ns-plain-safe(c) */ )\nfunction isPlainSafe(c, prev, inblock) {\n var cIsNsCharOrWhitespace = isNsCharOrWhitespace(c);\n var cIsNsChar = cIsNsCharOrWhitespace && !isWhitespace(c);\n return (\n // ns-plain-safe\n inblock ? // c = flow-in\n cIsNsCharOrWhitespace\n : cIsNsCharOrWhitespace\n // - c-flow-indicator\n && c !== CHAR_COMMA\n && c !== CHAR_LEFT_SQUARE_BRACKET\n && c !== CHAR_RIGHT_SQUARE_BRACKET\n && c !== CHAR_LEFT_CURLY_BRACKET\n && c !== CHAR_RIGHT_CURLY_BRACKET\n )\n // ns-plain-char\n && c !== CHAR_SHARP // false on '#'\n && !(prev === CHAR_COLON && !cIsNsChar) // false on ': '\n || (isNsCharOrWhitespace(prev) && !isWhitespace(prev) && c === CHAR_SHARP) // change to true on '[^ ]#'\n || (prev === CHAR_COLON && cIsNsChar); // change to true on ':[^ ]'\n}\n\n// Simplified test for values allowed as the first character in plain style.\nfunction isPlainSafeFirst(c) {\n // Uses a subset of ns-char - c-indicator\n // where ns-char = nb-char - s-white.\n // No support of ( ( \u201C?\u201D | \u201C:\u201D | \u201C-\u201D ) /* Followed by an ns-plain-safe(c)) */ ) part\n return isPrintable(c) && c !== CHAR_BOM\n && !isWhitespace(c) // - s-white\n // - (c-indicator ::=\n // \u201C-\u201D | \u201C?\u201D | \u201C:\u201D | \u201C,\u201D | \u201C[\u201D | \u201C]\u201D | \u201C{\u201D | \u201C}\u201D\n && c !== CHAR_MINUS\n && c !== CHAR_QUESTION\n && c !== CHAR_COLON\n && c !== CHAR_COMMA\n && c !== CHAR_LEFT_SQUARE_BRACKET\n && c !== CHAR_RIGHT_SQUARE_BRACKET\n && c !== CHAR_LEFT_CURLY_BRACKET\n && c !== CHAR_RIGHT_CURLY_BRACKET\n // | \u201C#\u201D | \u201C&\u201D | \u201C*\u201D | \u201C!\u201D | \u201C|\u201D | \u201C=\u201D | \u201C>\u201D | \u201C'\u201D | \u201C\"\u201D\n && c !== CHAR_SHARP\n && c !== CHAR_AMPERSAND\n && c !== CHAR_ASTERISK\n && c !== CHAR_EXCLAMATION\n && c !== CHAR_VERTICAL_LINE\n && c !== CHAR_EQUALS\n && c !== CHAR_GREATER_THAN\n && c !== CHAR_SINGLE_QUOTE\n && c !== CHAR_DOUBLE_QUOTE\n // | \u201C%\u201D | \u201C@\u201D | \u201C`\u201D)\n && c !== CHAR_PERCENT\n && c !== CHAR_COMMERCIAL_AT\n && c !== CHAR_GRAVE_ACCENT;\n}\n\n// Simplified test for values allowed as the last character in plain style.\nfunction isPlainSafeLast(c) {\n // just not whitespace or colon, it will be checked to be plain character later\n return !isWhitespace(c) && c !== CHAR_COLON;\n}\n\n// Same as 'string'.codePointAt(pos), but works in older browsers.\nfunction codePointAt(string, pos) {\n var first = string.charCodeAt(pos), second;\n if (first >= 0xD800 && first <= 0xDBFF && pos + 1 < string.length) {\n second = string.charCodeAt(pos + 1);\n if (second >= 0xDC00 && second <= 0xDFFF) {\n // https://mathiasbynens.be/notes/javascript-encoding#surrogate-formulae\n return (first - 0xD800) * 0x400 + second - 0xDC00 + 0x10000;\n }\n }\n return first;\n}\n\n// Determines whether block indentation indicator is required.\nfunction needIndentIndicator(string) {\n var leadingSpaceRe = /^\\n* /;\n return leadingSpaceRe.test(string);\n}\n\nvar STYLE_PLAIN = 1,\n STYLE_SINGLE = 2,\n STYLE_LITERAL = 3,\n STYLE_FOLDED = 4,\n STYLE_DOUBLE = 5;\n\n// Determines which scalar styles are possible and returns the preferred style.\n// lineWidth = -1 => no limit.\n// Pre-conditions: str.length > 0.\n// Post-conditions:\n// STYLE_PLAIN or STYLE_SINGLE => no \\n are in the string.\n// STYLE_LITERAL => no lines are suitable for folding (or lineWidth is -1).\n// STYLE_FOLDED => a line > lineWidth and can be folded (and lineWidth != -1).\nfunction chooseScalarStyle(string, singleLineOnly, indentPerLevel, lineWidth,\n testAmbiguousType, quotingType, forceQuotes, inblock) {\n\n var i;\n var char = 0;\n var prevChar = null;\n var hasLineBreak = false;\n var hasFoldableLine = false; // only checked if shouldTrackWidth\n var shouldTrackWidth = lineWidth !== -1;\n var previousLineBreak = -1; // count the first line correctly\n var plain = isPlainSafeFirst(codePointAt(string, 0))\n && isPlainSafeLast(codePointAt(string, string.length - 1));\n\n if (singleLineOnly || forceQuotes) {\n // Case: no block styles.\n // Check for disallowed characters to rule out plain and single.\n for (i = 0; i < string.length; char >= 0x10000 ? i += 2 : i++) {\n char = codePointAt(string, i);\n if (!isPrintable(char)) {\n return STYLE_DOUBLE;\n }\n plain = plain && isPlainSafe(char, prevChar, inblock);\n prevChar = char;\n }\n } else {\n // Case: block styles permitted.\n for (i = 0; i < string.length; char >= 0x10000 ? i += 2 : i++) {\n char = codePointAt(string, i);\n if (char === CHAR_LINE_FEED) {\n hasLineBreak = true;\n // Check if any line can be folded.\n if (shouldTrackWidth) {\n hasFoldableLine = hasFoldableLine ||\n // Foldable line = too long, and not more-indented.\n (i - previousLineBreak - 1 > lineWidth &&\n string[previousLineBreak + 1] !== ' ');\n previousLineBreak = i;\n }\n } else if (!isPrintable(char)) {\n return STYLE_DOUBLE;\n }\n plain = plain && isPlainSafe(char, prevChar, inblock);\n prevChar = char;\n }\n // in case the end is missing a \\n\n hasFoldableLine = hasFoldableLine || (shouldTrackWidth &&\n (i - previousLineBreak - 1 > lineWidth &&\n string[previousLineBreak + 1] !== ' '));\n }\n // Although every style can represent \\n without escaping, prefer block styles\n // for multiline, since they're more readable and they don't add empty lines.\n // Also prefer folding a super-long line.\n if (!hasLineBreak && !hasFoldableLine) {\n // Strings interpretable as another type have to be quoted;\n // e.g. the string 'true' vs. the boolean true.\n if (plain && !forceQuotes && !testAmbiguousType(string)) {\n return STYLE_PLAIN;\n }\n return quotingType === QUOTING_TYPE_DOUBLE ? STYLE_DOUBLE : STYLE_SINGLE;\n }\n // Edge case: block indentation indicator can only have one digit.\n if (indentPerLevel > 9 && needIndentIndicator(string)) {\n return STYLE_DOUBLE;\n }\n // At this point we know block styles are valid.\n // Prefer literal style unless we want to fold.\n if (!forceQuotes) {\n return hasFoldableLine ? STYLE_FOLDED : STYLE_LITERAL;\n }\n return quotingType === QUOTING_TYPE_DOUBLE ? STYLE_DOUBLE : STYLE_SINGLE;\n}\n\n// Note: line breaking/folding is implemented for only the folded style.\n// NB. We drop the last trailing newline (if any) of a returned block scalar\n// since the dumper adds its own newline. This always works:\n// \u2022 No ending newline => unaffected; already using strip \"-\" chomping.\n// \u2022 Ending newline => removed then restored.\n// Importantly, this keeps the \"+\" chomp indicator from gaining an extra line.\nfunction writeScalar(state, string, level, iskey, inblock) {\n state.dump = (function () {\n if (string.length === 0) {\n return state.quotingType === QUOTING_TYPE_DOUBLE ? '\"\"' : \"''\";\n }\n if (!state.noCompatMode) {\n if (DEPRECATED_BOOLEANS_SYNTAX.indexOf(string) !== -1 || DEPRECATED_BASE60_SYNTAX.test(string)) {\n return state.quotingType === QUOTING_TYPE_DOUBLE ? ('\"' + string + '\"') : (\"'\" + string + \"'\");\n }\n }\n\n var indent = state.indent * Math.max(1, level); // no 0-indent scalars\n // As indentation gets deeper, let the width decrease monotonically\n // to the lower bound min(state.lineWidth, 40).\n // Note that this implies\n // state.lineWidth \u2264 40 + state.indent: width is fixed at the lower bound.\n // state.lineWidth > 40 + state.indent: width decreases until the lower bound.\n // This behaves better than a constant minimum width which disallows narrower options,\n // or an indent threshold which causes the width to suddenly increase.\n var lineWidth = state.lineWidth === -1\n ? -1 : Math.max(Math.min(state.lineWidth, 40), state.lineWidth - indent);\n\n // Without knowing if keys are implicit/explicit, assume implicit for safety.\n var singleLineOnly = iskey\n // No block styles in flow mode.\n || (state.flowLevel > -1 && level >= state.flowLevel);\n function testAmbiguity(string) {\n return testImplicitResolving(state, string);\n }\n\n switch (chooseScalarStyle(string, singleLineOnly, state.indent, lineWidth,\n testAmbiguity, state.quotingType, state.forceQuotes && !iskey, inblock)) {\n\n case STYLE_PLAIN:\n return string;\n case STYLE_SINGLE:\n return \"'\" + string.replace(/'/g, \"''\") + \"'\";\n case STYLE_LITERAL:\n return '|' + blockHeader(string, state.indent)\n + dropEndingNewline(indentString(string, indent));\n case STYLE_FOLDED:\n return '>' + blockHeader(string, state.indent)\n + dropEndingNewline(indentString(foldString(string, lineWidth), indent));\n case STYLE_DOUBLE:\n return '\"' + escapeString(string) + '\"';\n default:\n throw new exception('impossible error: invalid scalar style');\n }\n }());\n}\n\n// Pre-conditions: string is valid for a block scalar, 1 <= indentPerLevel <= 9.\nfunction blockHeader(string, indentPerLevel) {\n var indentIndicator = needIndentIndicator(string) ? String(indentPerLevel) : '';\n\n // note the special case: the string '\\n' counts as a \"trailing\" empty line.\n var clip = string[string.length - 1] === '\\n';\n var keep = clip && (string[string.length - 2] === '\\n' || string === '\\n');\n var chomp = keep ? '+' : (clip ? '' : '-');\n\n return indentIndicator + chomp + '\\n';\n}\n\n// (See the note for writeScalar.)\nfunction dropEndingNewline(string) {\n return string[string.length - 1] === '\\n' ? string.slice(0, -1) : string;\n}\n\n// Note: a long line without a suitable break point will exceed the width limit.\n// Pre-conditions: every char in str isPrintable, str.length > 0, width > 0.\nfunction foldString(string, width) {\n // In folded style, $k$ consecutive newlines output as $k+1$ newlines\u2014\n // unless they're before or after a more-indented line, or at the very\n // beginning or end, in which case $k$ maps to $k$.\n // Therefore, parse each chunk as newline(s) followed by a content line.\n var lineRe = /(\\n+)([^\\n]*)/g;\n\n // first line (possibly an empty line)\n var result = (function () {\n var nextLF = string.indexOf('\\n');\n nextLF = nextLF !== -1 ? nextLF : string.length;\n lineRe.lastIndex = nextLF;\n return foldLine(string.slice(0, nextLF), width);\n }());\n // If we haven't reached the first content line yet, don't add an extra \\n.\n var prevMoreIndented = string[0] === '\\n' || string[0] === ' ';\n var moreIndented;\n\n // rest of the lines\n var match;\n while ((match = lineRe.exec(string))) {\n var prefix = match[1], line = match[2];\n moreIndented = (line[0] === ' ');\n result += prefix\n + (!prevMoreIndented && !moreIndented && line !== ''\n ? '\\n' : '')\n + foldLine(line, width);\n prevMoreIndented = moreIndented;\n }\n\n return result;\n}\n\n// Greedy line breaking.\n// Picks the longest line under the limit each time,\n// otherwise settles for the shortest line over the limit.\n// NB. More-indented lines *cannot* be folded, as that would add an extra \\n.\nfunction foldLine(line, width) {\n if (line === '' || line[0] === ' ') return line;\n\n // Since a more-indented line adds a \\n, breaks can't be followed by a space.\n var breakRe = / [^ ]/g; // note: the match index will always be <= length-2.\n var match;\n // start is an inclusive index. end, curr, and next are exclusive.\n var start = 0, end, curr = 0, next = 0;\n var result = '';\n\n // Invariants: 0 <= start <= length-1.\n // 0 <= curr <= next <= max(0, length-2). curr - start <= width.\n // Inside the loop:\n // A match implies length >= 2, so curr and next are <= length-2.\n while ((match = breakRe.exec(line))) {\n next = match.index;\n // maintain invariant: curr - start <= width\n if (next - start > width) {\n end = (curr > start) ? curr : next; // derive end <= length-2\n result += '\\n' + line.slice(start, end);\n // skip the space that was output as \\n\n start = end + 1; // derive start <= length-1\n }\n curr = next;\n }\n\n // By the invariants, start <= length-1, so there is something left over.\n // It is either the whole string or a part starting from non-whitespace.\n result += '\\n';\n // Insert a break if the remainder is too long and there is a break available.\n if (line.length - start > width && curr > start) {\n result += line.slice(start, curr) + '\\n' + line.slice(curr + 1);\n } else {\n result += line.slice(start);\n }\n\n return result.slice(1); // drop extra \\n joiner\n}\n\n// Escapes a double-quoted string.\nfunction escapeString(string) {\n var result = '';\n var char = 0;\n var escapeSeq;\n\n for (var i = 0; i < string.length; char >= 0x10000 ? i += 2 : i++) {\n char = codePointAt(string, i);\n escapeSeq = ESCAPE_SEQUENCES[char];\n\n if (!escapeSeq && isPrintable(char)) {\n result += string[i];\n if (char >= 0x10000) result += string[i + 1];\n } else {\n result += escapeSeq || encodeHex(char);\n }\n }\n\n return result;\n}\n\nfunction writeFlowSequence(state, level, object) {\n var _result = '',\n _tag = state.tag,\n index,\n length,\n value;\n\n for (index = 0, length = object.length; index < length; index += 1) {\n value = object[index];\n\n if (state.replacer) {\n value = state.replacer.call(object, String(index), value);\n }\n\n // Write only valid elements, put null instead of invalid elements.\n if (writeNode(state, level, value, false, false) ||\n (typeof value === 'undefined' &&\n writeNode(state, level, null, false, false))) {\n\n if (_result !== '') _result += ',' + (!state.condenseFlow ? ' ' : '');\n _result += state.dump;\n }\n }\n\n state.tag = _tag;\n state.dump = '[' + _result + ']';\n}\n\nfunction writeBlockSequence(state, level, object, compact) {\n var _result = '',\n _tag = state.tag,\n index,\n length,\n value;\n\n for (index = 0, length = object.length; index < length; index += 1) {\n value = object[index];\n\n if (state.replacer) {\n value = state.replacer.call(object, String(index), value);\n }\n\n // Write only valid elements, put null instead of invalid elements.\n if (writeNode(state, level + 1, value, true, true, false, true) ||\n (typeof value === 'undefined' &&\n writeNode(state, level + 1, null, true, true, false, true))) {\n\n if (!compact || _result !== '') {\n _result += generateNextLine(state, level);\n }\n\n if (state.dump && CHAR_LINE_FEED === state.dump.charCodeAt(0)) {\n _result += '-';\n } else {\n _result += '- ';\n }\n\n _result += state.dump;\n }\n }\n\n state.tag = _tag;\n state.dump = _result || '[]'; // Empty sequence if no valid values.\n}\n\nfunction writeFlowMapping(state, level, object) {\n var _result = '',\n _tag = state.tag,\n objectKeyList = Object.keys(object),\n index,\n length,\n objectKey,\n objectValue,\n pairBuffer;\n\n for (index = 0, length = objectKeyList.length; index < length; index += 1) {\n\n pairBuffer = '';\n if (_result !== '') pairBuffer += ', ';\n\n if (state.condenseFlow) pairBuffer += '\"';\n\n objectKey = objectKeyList[index];\n objectValue = object[objectKey];\n\n if (state.replacer) {\n objectValue = state.replacer.call(object, objectKey, objectValue);\n }\n\n if (!writeNode(state, level, objectKey, false, false)) {\n continue; // Skip this pair because of invalid key;\n }\n\n if (state.dump.length > 1024) pairBuffer += '? ';\n\n pairBuffer += state.dump + (state.condenseFlow ? '\"' : '') + ':' + (state.condenseFlow ? '' : ' ');\n\n if (!writeNode(state, level, objectValue, false, false)) {\n continue; // Skip this pair because of invalid value.\n }\n\n pairBuffer += state.dump;\n\n // Both key and value are valid.\n _result += pairBuffer;\n }\n\n state.tag = _tag;\n state.dump = '{' + _result + '}';\n}\n\nfunction writeBlockMapping(state, level, object, compact) {\n var _result = '',\n _tag = state.tag,\n objectKeyList = Object.keys(object),\n index,\n length,\n objectKey,\n objectValue,\n explicitPair,\n pairBuffer;\n\n // Allow sorting keys so that the output file is deterministic\n if (state.sortKeys === true) {\n // Default sorting\n objectKeyList.sort();\n } else if (typeof state.sortKeys === 'function') {\n // Custom sort function\n objectKeyList.sort(state.sortKeys);\n } else if (state.sortKeys) {\n // Something is wrong\n throw new exception('sortKeys must be a boolean or a function');\n }\n\n for (index = 0, length = objectKeyList.length; index < length; index += 1) {\n pairBuffer = '';\n\n if (!compact || _result !== '') {\n pairBuffer += generateNextLine(state, level);\n }\n\n objectKey = objectKeyList[index];\n objectValue = object[objectKey];\n\n if (state.replacer) {\n objectValue = state.replacer.call(object, objectKey, objectValue);\n }\n\n if (!writeNode(state, level + 1, objectKey, true, true, true)) {\n continue; // Skip this pair because of invalid key.\n }\n\n explicitPair = (state.tag !== null && state.tag !== '?') ||\n (state.dump && state.dump.length > 1024);\n\n if (explicitPair) {\n if (state.dump && CHAR_LINE_FEED === state.dump.charCodeAt(0)) {\n pairBuffer += '?';\n } else {\n pairBuffer += '? ';\n }\n }\n\n pairBuffer += state.dump;\n\n if (explicitPair) {\n pairBuffer += generateNextLine(state, level);\n }\n\n if (!writeNode(state, level + 1, objectValue, true, explicitPair)) {\n continue; // Skip this pair because of invalid value.\n }\n\n if (state.dump && CHAR_LINE_FEED === state.dump.charCodeAt(0)) {\n pairBuffer += ':';\n } else {\n pairBuffer += ': ';\n }\n\n pairBuffer += state.dump;\n\n // Both key and value are valid.\n _result += pairBuffer;\n }\n\n state.tag = _tag;\n state.dump = _result || '{}'; // Empty mapping if no valid pairs.\n}\n\nfunction detectType(state, object, explicit) {\n var _result, typeList, index, length, type, style;\n\n typeList = explicit ? state.explicitTypes : state.implicitTypes;\n\n for (index = 0, length = typeList.length; index < length; index += 1) {\n type = typeList[index];\n\n if ((type.instanceOf || type.predicate) &&\n (!type.instanceOf || ((typeof object === 'object') && (object instanceof type.instanceOf))) &&\n (!type.predicate || type.predicate(object))) {\n\n if (explicit) {\n if (type.multi && type.representName) {\n state.tag = type.representName(object);\n } else {\n state.tag = type.tag;\n }\n } else {\n state.tag = '?';\n }\n\n if (type.represent) {\n style = state.styleMap[type.tag] || type.defaultStyle;\n\n if (_toString.call(type.represent) === '[object Function]') {\n _result = type.represent(object, style);\n } else if (_hasOwnProperty.call(type.represent, style)) {\n _result = type.represent[style](object, style);\n } else {\n throw new exception('!<' + type.tag + '> tag resolver accepts not \"' + style + '\" style');\n }\n\n state.dump = _result;\n }\n\n return true;\n }\n }\n\n return false;\n}\n\n// Serializes `object` and writes it to global `result`.\n// Returns true on success, or false on invalid object.\n//\nfunction writeNode(state, level, object, block, compact, iskey, isblockseq) {\n state.tag = null;\n state.dump = object;\n\n if (!detectType(state, object, false)) {\n detectType(state, object, true);\n }\n\n var type = _toString.call(state.dump);\n var inblock = block;\n var tagStr;\n\n if (block) {\n block = (state.flowLevel < 0 || state.flowLevel > level);\n }\n\n var objectOrArray = type === '[object Object]' || type === '[object Array]',\n duplicateIndex,\n duplicate;\n\n if (objectOrArray) {\n duplicateIndex = state.duplicates.indexOf(object);\n duplicate = duplicateIndex !== -1;\n }\n\n if ((state.tag !== null && state.tag !== '?') || duplicate || (state.indent !== 2 && level > 0)) {\n compact = false;\n }\n\n if (duplicate && state.usedDuplicates[duplicateIndex]) {\n state.dump = '*ref_' + duplicateIndex;\n } else {\n if (objectOrArray && duplicate && !state.usedDuplicates[duplicateIndex]) {\n state.usedDuplicates[duplicateIndex] = true;\n }\n if (type === '[object Object]') {\n if (block && (Object.keys(state.dump).length !== 0)) {\n writeBlockMapping(state, level, state.dump, compact);\n if (duplicate) {\n state.dump = '&ref_' + duplicateIndex + state.dump;\n }\n } else {\n writeFlowMapping(state, level, state.dump);\n if (duplicate) {\n state.dump = '&ref_' + duplicateIndex + ' ' + state.dump;\n }\n }\n } else if (type === '[object Array]') {\n if (block && (state.dump.length !== 0)) {\n if (state.noArrayIndent && !isblockseq && level > 0) {\n writeBlockSequence(state, level - 1, state.dump, compact);\n } else {\n writeBlockSequence(state, level, state.dump, compact);\n }\n if (duplicate) {\n state.dump = '&ref_' + duplicateIndex + state.dump;\n }\n } else {\n writeFlowSequence(state, level, state.dump);\n if (duplicate) {\n state.dump = '&ref_' + duplicateIndex + ' ' + state.dump;\n }\n }\n } else if (type === '[object String]') {\n if (state.tag !== '?') {\n writeScalar(state, state.dump, level, iskey, inblock);\n }\n } else if (type === '[object Undefined]') {\n return false;\n } else {\n if (state.skipInvalid) return false;\n throw new exception('unacceptable kind of an object to dump ' + type);\n }\n\n if (state.tag !== null && state.tag !== '?') {\n // Need to encode all characters except those allowed by the spec:\n //\n // [35] ns-dec-digit ::= [#x30-#x39] /* 0-9 */\n // [36] ns-hex-digit ::= ns-dec-digit\n // | [#x41-#x46] /* A-F */ | [#x61-#x66] /* a-f */\n // [37] ns-ascii-letter ::= [#x41-#x5A] /* A-Z */ | [#x61-#x7A] /* a-z */\n // [38] ns-word-char ::= ns-dec-digit | ns-ascii-letter | \u201C-\u201D\n // [39] ns-uri-char ::= \u201C%\u201D ns-hex-digit ns-hex-digit | ns-word-char | \u201C#\u201D\n // | \u201C;\u201D | \u201C/\u201D | \u201C?\u201D | \u201C:\u201D | \u201C@\u201D | \u201C&\u201D | \u201C=\u201D | \u201C+\u201D | \u201C$\u201D | \u201C,\u201D\n // | \u201C_\u201D | \u201C.\u201D | \u201C!\u201D | \u201C~\u201D | \u201C*\u201D | \u201C'\u201D | \u201C(\u201D | \u201C)\u201D | \u201C[\u201D | \u201C]\u201D\n //\n // Also need to encode '!' because it has special meaning (end of tag prefix).\n //\n tagStr = encodeURI(\n state.tag[0] === '!' ? state.tag.slice(1) : state.tag\n ).replace(/!/g, '%21');\n\n if (state.tag[0] === '!') {\n tagStr = '!' + tagStr;\n } else if (tagStr.slice(0, 18) === 'tag:yaml.org,2002:') {\n tagStr = '!!' + tagStr.slice(18);\n } else {\n tagStr = '!<' + tagStr + '>';\n }\n\n state.dump = tagStr + ' ' + state.dump;\n }\n }\n\n return true;\n}\n\nfunction getDuplicateReferences(object, state) {\n var objects = [],\n duplicatesIndexes = [],\n index,\n length;\n\n inspectNode(object, objects, duplicatesIndexes);\n\n for (index = 0, length = duplicatesIndexes.length; index < length; index += 1) {\n state.duplicates.push(objects[duplicatesIndexes[index]]);\n }\n state.usedDuplicates = new Array(length);\n}\n\nfunction inspectNode(object, objects, duplicatesIndexes) {\n var objectKeyList,\n index,\n length;\n\n if (object !== null && typeof object === 'object') {\n index = objects.indexOf(object);\n if (index !== -1) {\n if (duplicatesIndexes.indexOf(index) === -1) {\n duplicatesIndexes.push(index);\n }\n } else {\n objects.push(object);\n\n if (Array.isArray(object)) {\n for (index = 0, length = object.length; index < length; index += 1) {\n inspectNode(object[index], objects, duplicatesIndexes);\n }\n } else {\n objectKeyList = Object.keys(object);\n\n for (index = 0, length = objectKeyList.length; index < length; index += 1) {\n inspectNode(object[objectKeyList[index]], objects, duplicatesIndexes);\n }\n }\n }\n }\n}\n\nfunction dump$1(input, options) {\n options = options || {};\n\n var state = new State(options);\n\n if (!state.noRefs) getDuplicateReferences(input, state);\n\n var value = input;\n\n if (state.replacer) {\n value = state.replacer.call({ '': value }, '', value);\n }\n\n if (writeNode(state, 0, value, true, true)) return state.dump + '\\n';\n\n return '';\n}\n\nvar dump_1 = dump$1;\n\nvar dumper = {\n\tdump: dump_1\n};\n\nfunction renamed(from, to) {\n return function () {\n throw new Error('Function yaml.' + from + ' is removed in js-yaml 4. ' +\n 'Use yaml.' + to + ' instead, which is now safe by default.');\n };\n}\n\n\nvar Type = type;\nvar Schema = schema;\nvar FAILSAFE_SCHEMA = failsafe;\nvar JSON_SCHEMA = json;\nvar CORE_SCHEMA = core;\nvar DEFAULT_SCHEMA = _default;\nvar load = loader.load;\nvar loadAll = loader.loadAll;\nvar dump = dumper.dump;\nvar YAMLException = exception;\n\n// Re-export all types in case user wants to create custom schema\nvar types = {\n binary: binary,\n float: float,\n map: map,\n null: _null,\n pairs: pairs,\n set: set,\n timestamp: timestamp,\n bool: bool,\n int: int,\n merge: merge,\n omap: omap,\n seq: seq,\n str: str\n};\n\n// Removed functions from JS-YAML 3.0.x\nvar safeLoad = renamed('safeLoad', 'load');\nvar safeLoadAll = renamed('safeLoadAll', 'loadAll');\nvar safeDump = renamed('safeDump', 'dump');\n\nvar jsYaml = {\n\tType: Type,\n\tSchema: Schema,\n\tFAILSAFE_SCHEMA: FAILSAFE_SCHEMA,\n\tJSON_SCHEMA: JSON_SCHEMA,\n\tCORE_SCHEMA: CORE_SCHEMA,\n\tDEFAULT_SCHEMA: DEFAULT_SCHEMA,\n\tload: load,\n\tloadAll: loadAll,\n\tdump: dump,\n\tYAMLException: YAMLException,\n\ttypes: types,\n\tsafeLoad: safeLoad,\n\tsafeLoadAll: safeLoadAll,\n\tsafeDump: safeDump\n};\n\nexport { CORE_SCHEMA, DEFAULT_SCHEMA, FAILSAFE_SCHEMA, JSON_SCHEMA, Schema, Type, YAMLException, jsYaml as default, dump, load, loadAll, safeDump, safeLoad, safeLoadAll, types };\n", "/**\n * CodeQL metadata resolver utilities\n * Handles resolution of query metadata using the CodeQL CLI\n */\n\nimport { executeCodeQLCommand } from './cli-executor';\nimport { logger } from '../utils/logger';\n\n/**\n * Query metadata structure returned by codeql resolve metadata\n */\nexport interface QueryMetadata {\n [key: string]: string | string[];\n}\n\n/**\n * Resolve metadata for a CodeQL query file\n * @param queryPath - Absolute or relative path to the .ql query file\n * @returns Parsed metadata object or null if resolution fails\n */\nexport async function resolveQueryMetadata(queryPath: string): Promise {\n try {\n logger.info(`Resolving metadata for query: ${queryPath}`);\n\n const result = await executeCodeQLCommand(\n 'resolve metadata',\n { format: 'json' },\n [queryPath]\n );\n\n if (!result.success) {\n logger.error(`Failed to resolve metadata for ${queryPath}:`, result.stderr || result.error);\n return null;\n }\n\n // Parse the JSON output\n try {\n const metadata = JSON.parse(result.stdout);\n return metadata;\n } catch (parseError) {\n logger.error(`Failed to parse metadata JSON for ${queryPath}:`, parseError);\n return null;\n }\n } catch (error) {\n logger.error(`Error resolving metadata for ${queryPath}:`, error);\n return null;\n }\n}\n", "/**\n * CodeQL generate log-summary tool\n */\n\nimport { z } from 'zod';\nimport { CLIToolDefinition, createCodeQLSchemas, defaultCLIResultProcessor } from '../../lib/cli-tool-registry';\n\nexport const codeqlGenerateLogSummaryTool: CLIToolDefinition = {\n name: 'codeql_generate_log-summary',\n description: 'Create a summary of a structured JSON evaluator event log file',\n command: 'codeql',\n subcommand: 'generate log-summary',\n inputSchema: {\n inputLog: z.string().describe('Path to the evaluator log file to summarize'),\n outputFile: z.string().optional().describe('Path to write the summary (optional, defaults to stdout)'),\n format: z.enum(['text', 'predicates', 'overall']).optional()\n .describe('Output format: text (human-readable), predicates (JSON), or overall (stats)'),\n 'minify-output': z.boolean().optional().describe('Minify JSON output'),\n utc: z.boolean().optional().describe('Force UTC timestamps'),\n 'deduplicate-stage-summaries': z.boolean().optional().describe('Deduplicate stage summaries'),\n verbose: createCodeQLSchemas.verbose(),\n additionalArgs: createCodeQLSchemas.additionalArgs()\n },\n examples: [\n 'codeql generate log-summary --format=text -- evaluator-log.json.txt summary.txt',\n 'codeql generate log-summary --format=predicates --minify-output -- evaluator-log.json.txt',\n 'codeql generate log-summary --format=overall -- evaluator-log.json.txt overall-stats.json'\n ],\n resultProcessor: defaultCLIResultProcessor\n};", "/**\n * CodeQL generate query-help tool\n */\n\nimport { z } from 'zod';\nimport { CLIToolDefinition, createCodeQLSchemas, defaultCLIResultProcessor } from '../../lib/cli-tool-registry';\n\nexport const codeqlGenerateQueryHelpTool: CLIToolDefinition = {\n name: 'codeql_generate_query-help',\n description: 'Generate query help documentation from QLDoc comments',\n command: 'codeql',\n subcommand: 'generate query-help',\n inputSchema: {\n query: z.string().describe('Path to the query file to generate help for'),\n outputFile: z.string().optional().describe('Path to write the help documentation'),\n format: z.enum(['markdown', 'text', 'html']).optional()\n .describe('Output format for the help documentation'),\n verbose: createCodeQLSchemas.verbose(),\n additionalArgs: createCodeQLSchemas.additionalArgs()\n },\n examples: [\n 'codeql generate query-help -- MyQuery.ql',\n 'codeql generate query-help --format=markdown -- MyQuery.ql help.md',\n 'codeql generate query-help --format=html -- MyQuery.ql help.html'\n ],\n resultProcessor: defaultCLIResultProcessor\n};", "/**\n * list_codeql_databases tool\n *\n * Discovers CodeQL databases in configured base directories.\n * Scans each directory in `CODEQL_DATABASES_BASE_DIRS` for subdirectories\n * containing `codeql-database.yml`, extracts metadata (language, CLI version,\n * creation time), and returns the list.\n */\n\nimport { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport { existsSync, readdirSync, readFileSync, statSync } from 'fs';\nimport { join } from 'path';\nimport { z } from 'zod';\nimport { getDatabaseBaseDirs } from '../../lib/discovery-config';\nimport { logger } from '../../utils/logger';\n\nexport interface DatabaseInfo {\n cliVersion?: string;\n creationTime?: string;\n language?: string;\n name: string;\n path: string;\n}\n\n/**\n * Parse `codeql-database.yml` to extract metadata.\n * Uses simple line-based parsing to avoid a YAML dependency.\n */\nfunction parseDatabaseYml(ymlPath: string): Partial {\n try {\n const content = readFileSync(ymlPath, 'utf-8');\n const info: Partial = {};\n\n for (const line of content.split('\\n')) {\n const trimmed = line.trim();\n const colonIdx = trimmed.indexOf(':');\n if (colonIdx === -1) continue;\n\n const key = trimmed.substring(0, colonIdx).trim();\n const value = trimmed.substring(colonIdx + 1).trim().replace(/^[\"']|[\"']$/g, '');\n\n switch (key) {\n case 'primaryLanguage':\n info.language = value;\n break;\n case 'cliVersion':\n info.cliVersion = value;\n break;\n case 'creationTime':\n info.creationTime = value;\n break;\n }\n }\n\n return info;\n } catch {\n return {};\n }\n}\n\n/**\n * Discover CodeQL databases in the given base directories.\n *\n * @param baseDirs - Directories to scan for database subdirectories\n * @param language - Optional language filter\n * @returns List of discovered databases with metadata\n */\nexport async function discoverDatabases(\n baseDirs: string[],\n language?: string,\n): Promise {\n const databases: DatabaseInfo[] = [];\n\n for (const baseDir of baseDirs) {\n if (!existsSync(baseDir)) {\n continue;\n }\n\n let entries: string[];\n try {\n entries = readdirSync(baseDir);\n } catch {\n continue;\n }\n\n for (const entry of entries) {\n const entryPath = join(baseDir, entry);\n\n // Skip non-directories\n try {\n if (!statSync(entryPath).isDirectory()) {\n continue;\n }\n } catch {\n continue;\n }\n\n // Check for codeql-database.yml\n const ymlPath = join(entryPath, 'codeql-database.yml');\n if (!existsSync(ymlPath)) {\n continue;\n }\n\n const metadata = parseDatabaseYml(ymlPath);\n\n // Apply language filter\n if (language && metadata.language !== language) {\n continue;\n }\n\n databases.push({\n cliVersion: metadata.cliVersion,\n creationTime: metadata.creationTime,\n language: metadata.language,\n name: entry,\n path: entryPath,\n });\n }\n }\n\n return databases;\n}\n\n/**\n * Register the list_codeql_databases tool with the MCP server.\n */\nexport function registerListDatabasesTool(server: McpServer): void {\n server.tool(\n 'list_codeql_databases',\n 'List CodeQL databases discovered in configured base directories (set via CODEQL_DATABASES_BASE_DIRS env var). Returns path, language, CLI version, and creation time for each database. Use the returned database paths with codeql_query_run or codeql_database_analyze to run queries against them.',\n {\n language: z\n .string()\n .optional()\n .describe('Filter databases by language (e.g., \"javascript\", \"python\")'),\n },\n async ({ language }) => {\n try {\n const baseDirs = getDatabaseBaseDirs();\n\n if (baseDirs.length === 0) {\n return {\n content: [\n {\n type: 'text' as const,\n text: 'No database base directories configured. Set the CODEQL_DATABASES_BASE_DIRS environment variable to a colon-separated list of directories to search.',\n },\n ],\n };\n }\n\n const databases = await discoverDatabases(baseDirs, language);\n\n if (databases.length === 0) {\n const filterMsg = language ? ` for language \"${language}\"` : '';\n return {\n content: [\n {\n type: 'text' as const,\n text: `No CodeQL databases found${filterMsg} in: ${baseDirs.join(', ')}`,\n },\n ],\n };\n }\n\n const lines = [\n `Found ${databases.length} CodeQL database(s):`,\n '',\n ...databases.map((db) => {\n const parts = [` ${db.name}`];\n parts.push(` Path: ${db.path}`);\n if (db.language) parts.push(` Language: ${db.language}`);\n if (db.cliVersion) parts.push(` CLI Version: ${db.cliVersion}`);\n if (db.creationTime) parts.push(` Created: ${db.creationTime}`);\n return parts.join('\\n');\n }),\n ];\n\n return {\n content: [{ type: 'text' as const, text: lines.join('\\n') }],\n };\n } catch (error) {\n logger.error('Error listing databases:', error);\n return {\n content: [\n {\n type: 'text' as const,\n text: `Error: ${error instanceof Error ? error.message : 'Unknown error'}`,\n },\n ],\n isError: true,\n };\n }\n },\n );\n}\n", "/**\n * Discovery configuration for locating CodeQL databases, query run results,\n * and MRVA (Multi-Repository Variant Analysis) run results.\n *\n * Reads colon-separated directory lists from environment variables:\n * - `CODEQL_DATABASES_BASE_DIRS` \u2014 directories to search for CodeQL databases\n * - `CODEQL_MRVA_RUN_RESULTS_DIRS` \u2014 directories containing MRVA run result subdirectories\n * - `CODEQL_QUERY_RUN_RESULTS_DIRS` \u2014 directories containing per-run query result subdirectories\n *\n * The VS Code extension sets these automatically from vscode-codeql storage paths.\n * CLI users can set them manually.\n */\n\n/**\n * Parse a colon-separated list of directories from an environment variable.\n */\nfunction parsePathList(envValue: string | undefined): string[] {\n if (!envValue) {\n return [];\n }\n return envValue\n .split(':')\n .map((p) => p.trim())\n .filter((p) => p.length > 0);\n}\n\n/**\n * Get the list of base directories to search for CodeQL databases.\n *\n * Each directory is expected to contain one or more CodeQL database directories\n * (each with a `codeql-database.yml` file).\n *\n * Set via `CODEQL_DATABASES_BASE_DIRS` (colon-separated).\n */\nexport function getDatabaseBaseDirs(): string[] {\n return parsePathList(process.env.CODEQL_DATABASES_BASE_DIRS);\n}\n\n/**\n * Get the list of directories containing MRVA run result subdirectories.\n *\n * Each directory is expected to contain numeric subdirectories (run IDs),\n * each holding `timestamp`, `repo_states.json`, and per-repository\n * subdirectories with `repo_task.json`, `results/results.sarif`, and\n * `results/results.bqrs`.\n *\n * Set via `CODEQL_MRVA_RUN_RESULTS_DIRS` (colon-separated).\n */\nexport function getMrvaRunResultsDirs(): string[] {\n return parsePathList(process.env.CODEQL_MRVA_RUN_RESULTS_DIRS);\n}\n\n/**\n * Get the list of directories containing per-run query result subdirectories.\n *\n * Each directory is expected to contain subdirectories named like\n * `.ql-/`, each holding artifacts such as\n * `evaluator-log.jsonl`, `results.bqrs`, and `results-interpreted.sarif`.\n *\n * Set via `CODEQL_QUERY_RUN_RESULTS_DIRS` (colon-separated).\n */\nexport function getQueryRunResultsDirs(): string[] {\n return parsePathList(process.env.CODEQL_QUERY_RUN_RESULTS_DIRS);\n}\n", "/**\n * list_mrva_run_results tool\n *\n * Discovers MRVA (Multi-Repository Variant Analysis) run result directories\n * in configured search paths.\n * Scans each directory in `CODEQL_MRVA_RUN_RESULTS_DIRS` for numeric\n * subdirectories representing variant analysis runs created by vscode-codeql.\n * Reports run ID, timestamp, repositories scanned, analysis status, and\n * available artifacts for each run.\n */\n\nimport { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport { existsSync, readdirSync, readFileSync, statSync } from 'fs';\nimport { join } from 'path';\nimport { z } from 'zod';\nimport { getMrvaRunResultsDirs } from '../../lib/discovery-config';\nimport { logger } from '../../utils/logger';\n\nexport interface MrvaRepoResult {\n analysisStatus?: string;\n fullName: string;\n hasBqrs: boolean;\n hasSarif: boolean;\n resultCount?: number;\n}\n\nexport interface MrvaRunResult {\n path: string;\n repositories: MrvaRepoResult[];\n runId: string;\n timestamp?: string;\n}\n\n/**\n * Pattern matching numeric MRVA run directory names.\n */\nconst NUMERIC_DIR_PATTERN = /^\\d+$/;\n\n/**\n * Directory names to skip when walking repository subdirectories.\n */\nconst SKIP_DIRS = new Set(['.DS_Store', 'exported-results']);\n\n/**\n * Discover MRVA run result directories in the given search paths.\n *\n * @param resultsDirs - Directories to scan for MRVA run subdirectories\n * @param runId - Optional run ID filter (e.g., \"20442\")\n * @returns List of discovered MRVA run results with repository inventory\n */\nexport async function discoverMrvaRunResults(\n resultsDirs: string[],\n runId?: string,\n): Promise {\n const results: MrvaRunResult[] = [];\n\n for (const dir of resultsDirs) {\n if (!existsSync(dir)) {\n continue;\n }\n\n let entries: string[];\n try {\n entries = readdirSync(dir);\n } catch {\n continue;\n }\n\n for (const entry of entries) {\n const entryPath = join(dir, entry);\n\n // Skip non-directories\n try {\n if (!statSync(entryPath).isDirectory()) {\n continue;\n }\n } catch {\n continue;\n }\n\n // Match numeric directory names\n if (!NUMERIC_DIR_PATTERN.test(entry)) {\n continue;\n }\n\n // Apply run ID filter\n if (runId && entry !== runId) {\n continue;\n }\n\n // Read timestamp if available\n let timestamp: string | undefined;\n const timestampPath = join(entryPath, 'timestamp');\n if (existsSync(timestampPath)) {\n try {\n timestamp = readFileSync(timestampPath, 'utf-8').trim();\n } catch {\n // Ignore read errors\n }\n }\n\n // Discover repository subdirectories\n const repositories = discoverRepoResults(entryPath);\n\n results.push({\n path: entryPath,\n repositories,\n runId: entry,\n timestamp,\n });\n }\n }\n\n return results;\n}\n\n/**\n * Walk a single MRVA run directory to discover per-repository results.\n *\n * The directory structure is `//` containing `repo_task.json`\n * and optionally `results/results.sarif` and `results/results.bqrs`.\n */\nfunction discoverRepoResults(runPath: string): MrvaRepoResult[] {\n const repos: MrvaRepoResult[] = [];\n\n let ownerEntries: string[];\n try {\n ownerEntries = readdirSync(runPath);\n } catch {\n return repos;\n }\n\n for (const ownerEntry of ownerEntries) {\n if (SKIP_DIRS.has(ownerEntry)) {\n continue;\n }\n\n // Skip non-directory entries (timestamp, repo_states.json, etc.)\n const ownerPath = join(runPath, ownerEntry);\n try {\n if (!statSync(ownerPath).isDirectory()) {\n continue;\n }\n } catch {\n continue;\n }\n\n let repoEntries: string[];\n try {\n repoEntries = readdirSync(ownerPath);\n } catch {\n continue;\n }\n\n for (const repoEntry of repoEntries) {\n const repoPath = join(ownerPath, repoEntry);\n try {\n if (!statSync(repoPath).isDirectory()) {\n continue;\n }\n } catch {\n continue;\n }\n\n const fullName = `${ownerEntry}/${repoEntry}`;\n\n // Parse repo_task.json if present\n let analysisStatus: string | undefined;\n let resultCount: number | undefined;\n const repoTaskPath = join(repoPath, 'repo_task.json');\n if (existsSync(repoTaskPath)) {\n try {\n const raw = readFileSync(repoTaskPath, 'utf-8');\n const task = JSON.parse(raw);\n if (typeof task.analysisStatus === 'string') {\n analysisStatus = task.analysisStatus;\n }\n if (typeof task.resultCount === 'number') {\n resultCount = task.resultCount;\n }\n } catch {\n // Ignore parse errors\n }\n }\n\n // Check for SARIF and BQRS artifacts\n const hasSarif = existsSync(join(repoPath, 'results', 'results.sarif'));\n const hasBqrs = existsSync(join(repoPath, 'results', 'results.bqrs'));\n\n repos.push({\n analysisStatus,\n fullName,\n hasBqrs,\n hasSarif,\n resultCount,\n });\n }\n }\n\n return repos;\n}\n\n/**\n * Register the list_mrva_run_results tool with the MCP server.\n */\nexport function registerListMrvaRunResultsTool(server: McpServer): void {\n server.tool(\n 'list_mrva_run_results',\n 'List discovered MRVA (Multi-Repository Variant Analysis) run results (set via CODEQL_MRVA_RUN_RESULTS_DIRS env var). Returns run ID, timestamp, repositories scanned, analysis status, and available artifacts for each run.',\n {\n runId: z\n .string()\n .optional()\n .describe('Filter results by run ID (e.g., \"20442\")'),\n },\n async ({ runId }) => {\n try {\n const resultsDirs = getMrvaRunResultsDirs();\n\n if (resultsDirs.length === 0) {\n return {\n content: [\n {\n type: 'text' as const,\n text: 'No MRVA run results directories configured. Set the CODEQL_MRVA_RUN_RESULTS_DIRS environment variable to a colon-separated list of directories to search.',\n },\n ],\n };\n }\n\n const runs = await discoverMrvaRunResults(resultsDirs, runId);\n\n if (runs.length === 0) {\n const filterMsg = runId ? ` for run ID \"${runId}\"` : '';\n return {\n content: [\n {\n type: 'text' as const,\n text: `No MRVA run results found${filterMsg} in: ${resultsDirs.join(', ')}`,\n },\n ],\n };\n }\n\n const lines = [\n `Found ${runs.length} MRVA run result(s):`,\n '',\n ...runs.map((run) => {\n const parts = [` Run ${run.runId}`];\n parts.push(` Path: ${run.path}`);\n if (run.timestamp) parts.push(` Timestamp: ${run.timestamp}`);\n parts.push(` Repositories: ${run.repositories.length}`);\n for (const repo of run.repositories) {\n const artifacts: string[] = [];\n if (repo.hasSarif) artifacts.push('sarif');\n if (repo.hasBqrs) artifacts.push('bqrs');\n const status = repo.analysisStatus ?? 'unknown';\n const count = repo.resultCount !== undefined ? `, ${repo.resultCount} result(s)` : '';\n parts.push(` ${repo.fullName} [${status}${count}] artifacts: ${artifacts.length > 0 ? artifacts.join(', ') : 'none'}`);\n }\n return parts.join('\\n');\n }),\n ];\n\n return {\n content: [{ type: 'text' as const, text: lines.join('\\n') }],\n };\n } catch (error) {\n logger.error('Error listing MRVA run results:', error);\n return {\n content: [\n {\n type: 'text' as const,\n text: `Error: ${error instanceof Error ? error.message : 'Unknown error'}`,\n },\n ],\n isError: true,\n };\n }\n },\n );\n}\n", "/**\n * list_query_run_results tool\n *\n * Discovers per-query-run result directories in configured search paths.\n * Scans each directory in `CODEQL_QUERY_RUN_RESULTS_DIRS` for subdirectories\n * matching the `.ql-` naming convention used by vscode-codeql.\n * Reports which artifacts (evaluator logs, BQRS, SARIF) are present in each run.\n *\n * Supports filtering by:\n * - `queryName` \u2014 exact match on the query file name (e.g., \"UI5Xss.ql\")\n * - `language` \u2014 filter by CodeQL language extracted from query.log db-scheme path\n * - `queryPath` \u2014 substring or exact match against the full query file path\n */\n\nimport { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport { existsSync, readdirSync, readFileSync, statSync } from 'fs';\nimport { join } from 'path';\nimport { z } from 'zod';\nimport { getQueryRunResultsDirs } from '../../lib/discovery-config';\nimport { logger } from '../../utils/logger';\n\nexport interface QueryRunResult {\n databasePath?: string;\n hasBqrs: boolean;\n hasEvaluatorLog: boolean;\n hasQueryLog: boolean;\n hasSarif: boolean;\n hasSummaryLog: boolean;\n language?: string;\n path: string;\n queryName: string;\n queryPath?: string;\n runId: string;\n timestamp?: string;\n}\n\n/**\n * Metadata extracted from a vscode-codeql query.log file.\n */\nexport interface QueryLogMetadata {\n databasePath?: string;\n language?: string;\n queryPath?: string;\n}\n\n/**\n * Filters for narrowing query run results.\n */\nexport interface QueryRunResultsFilter {\n language?: string;\n queryName?: string;\n queryPath?: string;\n}\n\n/**\n * Pattern matching vscode-codeql query run directory names: `.ql-`\n */\nconst QUERY_RUN_DIR_PATTERN = /^(.+\\.ql)-(.+)$/;\n\n/**\n * Pattern matching the `runQuery called with ` line in query.log.\n * Example: `[2026-02-15 12:52:37] [SPAMMY] execute query-server2> runQuery called with /path/to/Query.ql`\n */\nconst RUN_QUERY_PATTERN = /runQuery called with\\s+(\\S+)/;\n\n/**\n * Pattern matching the `--dbscheme=` argument in query.log when it\n * includes the database root directory with the `db-/` segment.\n * Example: `--dbscheme=/databases/my-db/db-javascript/semmlecode.javascript.dbscheme`\n */\nconst DBSCHEME_DB_PATH_PATTERN = /--dbscheme=(.+?)\\/db-(\\w+)\\//;\n\n/**\n * Fallback pattern matching language from the semmlecode dbscheme filename.\n * Matches both `semmlecode..dbscheme` and `semmlecode.dbscheme`\n * (the latter is used by Java). Also matches dbscheme paths from QL packs\n * like `codeql/-all/`.\n *\n * Examples:\n * - `semmlecode.javascript.dbscheme` \u2192 javascript\n * - `semmlecode.python.dbscheme` \u2192 python\n * - `codeql/javascript-all/2.6.20/semmlecode.javascript.dbscheme` \u2192 javascript\n * - `semmlecode.dbscheme` (Java) \u2192 java (from `db-java/` or `codeql/java-all/`)\n */\nconst DBSCHEME_LANGUAGE_PATTERN = /semmlecode\\.(\\w+)\\.dbscheme/;\n\n/**\n * Fallback pattern to extract language from QL pack path in dbscheme references.\n * Example: `codeql/javascript-all/2.6.20/` \u2192 javascript\n */\nconst QLPACK_LANGUAGE_PATTERN = /codeql\\/(\\w+)-all\\//;\n\n/**\n * Parse a vscode-codeql query.log file to extract metadata about the query run.\n *\n * Extracts:\n * - `queryPath` \u2014 from the `runQuery called with ` line\n * - `databasePath` \u2014 the database root from the `--dbscheme=` argument (when available)\n * - `language` \u2014 from `db-/` segment, or `semmlecode..dbscheme`,\n * or `codeql/-all/` QL pack path\n *\n * @param logContent - Raw content of the query.log file\n * @returns Extracted metadata (fields are undefined if not found)\n */\nexport function parseQueryLogMetadata(logContent: string): QueryLogMetadata {\n const metadata: QueryLogMetadata = {};\n\n // Extract query path from runQuery line\n const runQueryMatch = RUN_QUERY_PATTERN.exec(logContent);\n if (runQueryMatch) {\n metadata.queryPath = runQueryMatch[1];\n }\n\n // Try to extract database path and language from --dbscheme=/db-/\n const dbPathMatch = DBSCHEME_DB_PATH_PATTERN.exec(logContent);\n if (dbPathMatch) {\n metadata.databasePath = dbPathMatch[1];\n metadata.language = dbPathMatch[2];\n }\n\n // If language wasn't found from db path, try semmlecode..dbscheme\n if (!metadata.language) {\n const langMatch = DBSCHEME_LANGUAGE_PATTERN.exec(logContent);\n if (langMatch) {\n metadata.language = langMatch[1];\n }\n }\n\n // Last resort: extract from codeql/-all/ QL pack path\n if (!metadata.language) {\n const packMatch = QLPACK_LANGUAGE_PATTERN.exec(logContent);\n if (packMatch) {\n metadata.language = packMatch[1];\n }\n }\n\n return metadata;\n}\n\n/**\n * Discover query run result directories in the given search paths.\n *\n * @param resultsDirs - Directories to scan for per-run subdirectories\n * @param filter - Optional filters: queryName, language, queryPath\n * @returns List of discovered query run results with artifact inventory\n */\nexport async function discoverQueryRunResults(\n resultsDirs: string[],\n filter?: QueryRunResultsFilter | string,\n): Promise {\n // Backward-compatible: if filter is a string, treat as queryName\n const normalizedFilter: QueryRunResultsFilter | undefined =\n typeof filter === 'string' ? { queryName: filter } : filter;\n\n const results: QueryRunResult[] = [];\n\n for (const dir of resultsDirs) {\n if (!existsSync(dir)) {\n continue;\n }\n\n let entries: string[];\n try {\n entries = readdirSync(dir);\n } catch {\n continue;\n }\n\n for (const entry of entries) {\n const entryPath = join(dir, entry);\n\n // Skip non-directories\n try {\n if (!statSync(entryPath).isDirectory()) {\n continue;\n }\n } catch {\n continue;\n }\n\n // Match the naming pattern\n const match = QUERY_RUN_DIR_PATTERN.exec(entry);\n if (!match) {\n continue;\n }\n\n const [, name, runId] = match;\n\n // Apply query name filter (cheap, no I/O needed)\n if (normalizedFilter?.queryName && name !== normalizedFilter.queryName) {\n continue;\n }\n\n // Check which artifacts are present\n const hasEvaluatorLog = existsSync(join(entryPath, 'evaluator-log.jsonl'));\n const hasBqrs = existsSync(join(entryPath, 'results.bqrs'));\n const hasSarif = existsSync(join(entryPath, 'results-interpreted.sarif'));\n const hasQueryLog = existsSync(join(entryPath, 'query.log'));\n const hasSummaryLog = existsSync(join(entryPath, 'evaluator-log.summary.jsonl'));\n\n // Read timestamp if available\n let timestamp: string | undefined;\n const timestampPath = join(entryPath, 'timestamp');\n if (existsSync(timestampPath)) {\n try {\n timestamp = readFileSync(timestampPath, 'utf-8').trim();\n } catch {\n // Ignore read errors\n }\n }\n\n // Parse query.log for metadata (queryPath, language, databasePath)\n let metadata: QueryLogMetadata = {};\n if (hasQueryLog) {\n try {\n const logContent = readFileSync(join(entryPath, 'query.log'), 'utf-8');\n metadata = parseQueryLogMetadata(logContent);\n } catch {\n // Ignore read errors\n }\n }\n\n // Apply language filter (requires metadata from query.log)\n if (normalizedFilter?.language && metadata.language !== normalizedFilter.language) {\n continue;\n }\n\n // Apply queryPath filter (substring or exact match)\n if (normalizedFilter?.queryPath) {\n if (!metadata.queryPath) {\n continue;\n }\n const filterPath = normalizedFilter.queryPath;\n const isExact = filterPath.startsWith('/');\n if (isExact) {\n if (metadata.queryPath !== filterPath) {\n continue;\n }\n } else {\n if (!metadata.queryPath.toLowerCase().includes(filterPath.toLowerCase())) {\n continue;\n }\n }\n }\n\n results.push({\n databasePath: metadata.databasePath,\n hasBqrs,\n hasEvaluatorLog,\n hasQueryLog,\n hasSarif,\n hasSummaryLog,\n language: metadata.language,\n path: entryPath,\n queryName: name,\n queryPath: metadata.queryPath,\n runId,\n timestamp,\n });\n }\n }\n\n return results;\n}\n\n/**\n * Register the list_query_run_results tool with the MCP server.\n */\nexport function registerListQueryRunResultsTool(server: McpServer): void {\n server.tool(\n 'list_query_run_results',\n 'List discovered query run result directories (set via CODEQL_QUERY_RUN_RESULTS_DIRS env var). Returns path, query name, timestamp, language, query file path, and available artifacts (evaluator-log, bqrs, sarif, query.log, summary) for each run. Filter by queryName, language, or queryPath to narrow results. Use the returned BQRS paths with codeql_bqrs_decode or codeql_bqrs_info to inspect query results.',\n {\n language: z\n .string()\n .optional()\n .describe(\n 'Filter by CodeQL language (e.g., \"javascript\", \"python\", \"java\"). Extracted from the database path in query.log. Runs without a query.log are excluded when this filter is set.',\n ),\n queryName: z\n .string()\n .optional()\n .describe('Filter results by query name (e.g., \"UI5Xss.ql\")'),\n queryPath: z\n .string()\n .optional()\n .describe(\n 'Filter by query file path. Absolute paths match exactly; relative paths/substrings match case-insensitively. Requires query.log to be present.',\n ),\n },\n async ({ language, queryName, queryPath }) => {\n try {\n const resultsDirs = getQueryRunResultsDirs();\n\n if (resultsDirs.length === 0) {\n return {\n content: [\n {\n type: 'text' as const,\n text: 'No query run results directories configured. Set the CODEQL_QUERY_RUN_RESULTS_DIRS environment variable to a colon-separated list of directories to search.',\n },\n ],\n };\n }\n\n const filter: QueryRunResultsFilter = {};\n if (queryName) filter.queryName = queryName;\n if (language) filter.language = language;\n if (queryPath) filter.queryPath = queryPath;\n\n const runs = await discoverQueryRunResults(\n resultsDirs,\n Object.keys(filter).length > 0 ? filter : undefined,\n );\n\n if (runs.length === 0) {\n const filterParts: string[] = [];\n if (queryName) filterParts.push(`query \"${queryName}\"`);\n if (language) filterParts.push(`language \"${language}\"`);\n if (queryPath) filterParts.push(`path \"${queryPath}\"`);\n const filterMsg = filterParts.length > 0 ? ` for ${filterParts.join(', ')}` : '';\n return {\n content: [\n {\n type: 'text' as const,\n text: `No query run results found${filterMsg} in: ${resultsDirs.join(', ')}`,\n },\n ],\n };\n }\n\n const lines = [\n `Found ${runs.length} query run result(s):`,\n '',\n ...runs.map((run) => {\n const artifacts: string[] = [];\n if (run.hasEvaluatorLog) artifacts.push('evaluator-log');\n if (run.hasSummaryLog) artifacts.push('summary-log');\n if (run.hasBqrs) artifacts.push('bqrs');\n if (run.hasSarif) artifacts.push('sarif');\n if (run.hasQueryLog) artifacts.push('query-log');\n const parts = [` ${run.queryName} (${run.runId})`];\n parts.push(` Path: ${run.path}`);\n if (run.timestamp) parts.push(` Timestamp: ${run.timestamp}`);\n if (run.language) parts.push(` Language: ${run.language}`);\n if (run.queryPath) parts.push(` Query: ${run.queryPath}`);\n if (run.databasePath) parts.push(` Database: ${run.databasePath}`);\n parts.push(` Artifacts: ${artifacts.length > 0 ? artifacts.join(', ') : 'none'}`);\n if (run.hasBqrs) parts.push(` BQRS: ${join(run.path, 'results.bqrs')}`);\n return parts.join('\\n');\n }),\n ];\n\n return {\n content: [{ type: 'text' as const, text: lines.join('\\n') }],\n };\n } catch (error) {\n logger.error('Error listing query run results:', error);\n return {\n content: [\n {\n type: 'text' as const,\n text: `Error: ${error instanceof Error ? error.message : 'Unknown error'}`,\n },\n ],\n isError: true,\n };\n }\n },\n );\n}\n", "/**\n * CodeQL pack install tool\n */\n\nimport { z } from 'zod';\nimport { CLIToolDefinition, createCodeQLSchemas } from '../../lib/cli-tool-registry';\n\nexport const codeqlPackInstallTool: CLIToolDefinition = {\n name: 'codeql_pack_install',\n description: 'Install CodeQL pack dependencies',\n command: 'codeql',\n subcommand: 'pack install',\n inputSchema: {\n packDir: z.string().optional().describe('Directory containing qlpack.yml (default: current)'),\n force: z.boolean().optional().describe('Force reinstall of dependencies'),\n 'no-strict-mode': z.boolean().optional()\n .describe('Allow non-strict dependency resolution'),\n verbose: createCodeQLSchemas.verbose(),\n additionalArgs: createCodeQLSchemas.additionalArgs()\n },\n examples: [\n 'codeql pack install',\n 'codeql pack install --force /path/to/pack',\n 'codeql pack install --no-strict-mode'\n ]\n};", "/**\n * CodeQL pack ls tool\n */\n\nimport { z } from 'zod';\nimport { CLIToolDefinition, createCodeQLSchemas, defaultCLIResultProcessor } from '../../lib/cli-tool-registry';\n\nexport const codeqlPackLsTool: CLIToolDefinition = {\n name: 'codeql_pack_ls',\n description: 'List CodeQL packs under some local directory path',\n command: 'codeql',\n subcommand: 'pack ls',\n inputSchema: {\n dir: z.string().optional().describe('The root directory of the package or workspace, defaults to the current working directory'),\n format: z.enum(['text', 'json']).optional()\n .describe('Output format: text (default) or json'),\n groups: z.string().optional()\n .describe('List of CodeQL pack groups to include or exclude'),\n verbose: createCodeQLSchemas.verbose(),\n additionalArgs: createCodeQLSchemas.additionalArgs()\n },\n examples: [\n 'codeql pack ls -- .',\n 'codeql pack ls --format=json -- /path/to/pack-directory',\n 'codeql pack ls --format=json --groups=queries,tests -- .'\n ],\n resultProcessor: defaultCLIResultProcessor\n};", "/**\n * MCP tool: profile_codeql_query_from_logs\n *\n * Parses CodeQL query evaluation logs into a performance profile WITHOUT\n * running the query. Works with logs from `codeql query run`,\n * `codeql database analyze`, or vscode-codeql query history.\n */\n\nimport { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport { existsSync, mkdirSync, writeFileSync } from 'fs';\nimport { basename, dirname, join } from 'path';\nimport { z } from 'zod';\nimport {\n parseEvaluatorLog,\n type PredicateProfile,\n type ProfileData,\n} from '../../lib/evaluator-log-parser';\nimport { logger } from '../../utils/logger';\n\n// ---------------------------------------------------------------------------\n// Formatting helpers\n// ---------------------------------------------------------------------------\n\n/**\n * Format the full profile data as pretty-printed JSON.\n */\nfunction formatAsJson(profile: ProfileData): string {\n return JSON.stringify(profile, null, 2);\n}\n\n/**\n * Format profile data as a Mermaid diagram.\n *\n * For single-query logs the diagram has one query root node with sub-nodes\n * for the top-N most expensive predicates. For multi-query logs each query\n * gets its own sub-graph.\n */\nfunction formatAsMermaid(profile: ProfileData, topN: number): string {\n const lines: string[] = [];\n\n lines.push('```mermaid');\n lines.push('graph TD');\n lines.push('');\n\n if (profile.queries.length <= 1) {\n // Single query layout\n const query = profile.queries[0] ?? {\n queryName: 'unknown',\n totalDurationMs: 0,\n predicates: [],\n predicateCount: 0,\n cacheHits: 0,\n };\n const qLabel = sanitizeMermaid(basename(query.queryName));\n lines.push(\n ` QUERY[\"${qLabel}
Total: ${query.totalDurationMs.toFixed(2)}ms
Predicates: ${query.predicateCount}\"]`\n );\n lines.push('');\n\n const topPredicates = getTopPredicates(query.predicates, topN);\n topPredicates.forEach((pred, idx) => {\n const nodeId = `P${idx}`;\n const name = sanitizeMermaid(pred.predicateName).substring(0, 50);\n const dur = pred.durationMs.toFixed(2);\n const size =\n pred.resultSize !== undefined ? String(pred.resultSize) : '?';\n lines.push(\n ` ${nodeId}[\"${name}
${dur}ms | ${size} results\"]`\n );\n });\n\n lines.push('');\n\n topPredicates.forEach((_pred, idx) => {\n lines.push(` QUERY --> P${idx}`);\n });\n } else {\n // Multi-query layout\n lines.push(\n ` ROOT[\"Evaluation Log
${profile.queries.length} queries\"]`\n );\n lines.push('');\n\n profile.queries.forEach((query, qIdx) => {\n const qNodeId = `Q${qIdx}`;\n const qLabel = sanitizeMermaid(basename(query.queryName));\n lines.push(\n ` ${qNodeId}[\"${qLabel}
${query.totalDurationMs.toFixed(2)}ms
Predicates: ${query.predicateCount}\"]`\n );\n lines.push(` ROOT --> ${qNodeId}`);\n\n const topPredicates = getTopPredicates(query.predicates, topN);\n topPredicates.forEach((pred, pIdx) => {\n const nodeId = `Q${qIdx}P${pIdx}`;\n const name = sanitizeMermaid(pred.predicateName).substring(0, 50);\n const dur = pred.durationMs.toFixed(2);\n const size =\n pred.resultSize !== undefined ? String(pred.resultSize) : '?';\n lines.push(\n ` ${nodeId}[\"${name}
${dur}ms | ${size} results\"]`\n );\n lines.push(` ${qNodeId} --> ${nodeId}`);\n });\n lines.push('');\n });\n }\n\n lines.push('');\n lines.push(\n ' classDef default fill:#e1f5ff,stroke:#333,stroke-width:2px'\n );\n lines.push(\n ' classDef query fill:#ffe1e1,stroke:#333,stroke-width:3px'\n );\n lines.push(' class QUERY query');\n lines.push('```');\n\n return lines.join('\\n');\n}\n\n/**\n * Sanitize a string for safe inclusion in a Mermaid node label.\n */\nfunction sanitizeMermaid(text: string): string {\n return text.replace(/[<>\"]/g, '');\n}\n\n/**\n * Return the top-N most expensive predicates sorted by descending duration.\n */\nfunction getTopPredicates(\n predicates: PredicateProfile[],\n topN: number\n): PredicateProfile[] {\n return [...predicates]\n .sort((a, b) => b.durationMs - a.durationMs)\n .slice(0, topN);\n}\n\n// ---------------------------------------------------------------------------\n// Text summary\n// ---------------------------------------------------------------------------\n\nfunction buildTextSummary(\n profile: ProfileData,\n topN: number,\n outputFiles: string[]\n): string {\n const sections: string[] = [];\n\n sections.push('Query log profiling completed successfully!');\n sections.push('');\n sections.push('Output Files:');\n for (const f of outputFiles) {\n sections.push(` - ${f}`);\n }\n\n sections.push('');\n sections.push(`Log Format: ${profile.logFormat}`);\n if (profile.codeqlVersion) {\n sections.push(`CodeQL Version: ${profile.codeqlVersion}`);\n }\n sections.push(`Total Events: ${profile.totalEvents}`);\n sections.push(`Queries: ${profile.queries.length}`);\n\n for (const query of profile.queries) {\n sections.push('');\n sections.push(`--- ${basename(query.queryName)} ---`);\n sections.push(` Total Duration: ${query.totalDurationMs.toFixed(2)} ms`);\n sections.push(` Predicates Evaluated: ${query.predicateCount}`);\n sections.push(` Cache Hits: ${query.cacheHits}`);\n\n const top = getTopPredicates(query.predicates, topN);\n if (top.length > 0) {\n sections.push(` Top ${top.length} Most Expensive Predicates:`);\n top.forEach((pred, idx) => {\n const sizeStr =\n pred.resultSize !== undefined ? `, ${pred.resultSize} results` : '';\n sections.push(\n ` ${idx + 1}. ${pred.predicateName} (${pred.durationMs.toFixed(2)} ms${sizeStr})`\n );\n });\n }\n }\n\n return sections.join('\\n');\n}\n\n// ---------------------------------------------------------------------------\n// Tool registration\n// ---------------------------------------------------------------------------\n\n/**\n * Register the `profile_codeql_query_from_logs` tool with the MCP server.\n */\nexport function registerProfileCodeQLQueryFromLogsTool(\n server: McpServer\n): void {\n server.tool(\n 'profile_codeql_query_from_logs',\n 'Parse CodeQL query evaluation logs into a performance profile without re-running the query. Works with logs from codeql query run, codeql database analyze, or vscode-codeql query history.',\n {\n evaluatorLog: z\n .string()\n .describe(\n 'Path to evaluator-log.jsonl or evaluator-log.summary.jsonl'\n ),\n outputDir: z\n .string()\n .optional()\n .describe(\n 'Directory to write profile output files (defaults to same directory as log)'\n ),\n topN: z\n .number()\n .optional()\n .describe(\n 'Number of most expensive predicates to highlight (default: 20)'\n ),\n },\n async (params) => {\n try {\n const { evaluatorLog, outputDir, topN } = params;\n const effectiveTopN = topN ?? 20;\n\n // Validate input path\n if (!existsSync(evaluatorLog)) {\n return {\n content: [\n {\n type: 'text' as const,\n text: `Evaluator log not found at: ${evaluatorLog}`,\n },\n ],\n isError: true,\n };\n }\n\n // Parse log\n logger.info(`Parsing evaluator log from: ${evaluatorLog}`);\n const profile = parseEvaluatorLog(evaluatorLog);\n\n // Determine output directory\n const profileOutputDir = outputDir ?? dirname(evaluatorLog);\n mkdirSync(profileOutputDir, { recursive: true });\n\n // Write profile JSON\n const jsonPath = join(\n profileOutputDir,\n 'query-evaluation-profile.json'\n );\n writeFileSync(jsonPath, formatAsJson(profile));\n logger.info(`Profile JSON written to: ${jsonPath}`);\n\n // Write Mermaid diagram\n const mdPath = join(\n profileOutputDir,\n 'query-evaluation-profile.md'\n );\n writeFileSync(mdPath, formatAsMermaid(profile, effectiveTopN));\n logger.info(`Profile Mermaid diagram written to: ${mdPath}`);\n\n // Build response\n const outputFilesList = [\n `Profile JSON: ${jsonPath}`,\n `Profile Mermaid: ${mdPath}`,\n `Evaluator Log: ${evaluatorLog}`,\n ];\n\n const responseText = buildTextSummary(\n profile,\n effectiveTopN,\n outputFilesList\n );\n\n return {\n content: [{ type: 'text' as const, text: responseText }],\n };\n } catch (error) {\n logger.error(\n 'Error profiling CodeQL query from logs:',\n error\n );\n return {\n content: [\n {\n type: 'text' as const,\n text: `Failed to profile query from logs: ${error instanceof Error ? error.message : String(error)}`,\n },\n ],\n isError: true,\n };\n }\n }\n );\n}\n", "/**\n * Reusable parser for CodeQL evaluator log files.\n *\n * Supports two formats:\n * - **Raw** (`evaluator-log.jsonl`): Pretty-printed JSON objects with a `type`\n * field (`LOG_HEADER`, `QUERY_STARTED`, `PREDICATE_STARTED`, etc.)\n * - **Summary** (`evaluator-log.summary.jsonl`): Pretty-printed JSON objects\n * without a `type` field; identified by `summaryLogVersion` or\n * `evaluationStrategy`.\n *\n * Both formats use pretty-printed JSON separated by `}\\n{` boundaries.\n */\n\nimport { readFileSync } from 'fs';\nimport { logger } from '../utils/logger';\n\n// ---------------------------------------------------------------------------\n// Public interfaces\n// ---------------------------------------------------------------------------\n\n/** Performance profile for a single evaluated predicate. */\nexport interface PredicateProfile {\n predicateName: string;\n position?: string;\n durationMs: number;\n resultSize?: number;\n pipelineCount?: number;\n evaluationStrategy?: string;\n dependencies: string[];\n}\n\n/** Performance profile for a single query within a log. */\nexport interface QueryProfile {\n queryName: string;\n totalDurationMs: number;\n predicateCount: number;\n predicates: PredicateProfile[];\n cacheHits: number;\n}\n\n/** Top-level result returned by all parse functions. */\nexport interface ProfileData {\n codeqlVersion?: string;\n logFormat: 'raw' | 'summary';\n queries: QueryProfile[];\n totalEvents: number;\n}\n\n// ---------------------------------------------------------------------------\n// Format detection\n// ---------------------------------------------------------------------------\n\n/**\n * Auto-detect whether the first parsed JSON object comes from a raw\n * evaluator log or a summary log.\n *\n * Raw events always contain a `type` string field.\n * Summary events never have `type`; the header carries `summaryLogVersion`.\n */\nexport function detectLogFormat(firstEvent: Record): 'raw' | 'summary' {\n if (typeof firstEvent.type === 'string') {\n return 'raw';\n }\n return 'summary';\n}\n\n// ---------------------------------------------------------------------------\n// Helpers\n// ---------------------------------------------------------------------------\n\n/**\n * Split a pretty-printed multi-JSON file into individual JSON strings.\n *\n * The log file contains multiple JSON objects that are pretty-printed,\n * separated by the pattern `}\\n\\n{` (closing brace, blank line, opening\n * brace). We split on `\\n}\\n` boundaries and reconstruct valid objects.\n */\nfunction splitJsonObjects(content: string): string[] {\n // Trim leading/trailing whitespace\n const trimmed = content.trim();\n if (trimmed.length === 0) {\n return [];\n }\n\n // Split on closing-brace + newline(s) + opening-brace boundaries.\n // We use a regex that matches `}\\n` followed by optional blank lines\n // then `{` \u2013 capturing the boundary so we can reconstruct.\n const parts = trimmed.split(/\\n\\}\\s*\\n\\s*\\{/);\n\n if (parts.length === 1) {\n // Single object or single-line \u2013 return as-is\n return [trimmed];\n }\n\n // Reconstruct: first part needs closing `}`, middle parts need both,\n // last part needs opening `{`.\n return parts.map((part, idx) => {\n if (idx === 0) {\n return part + '\\n}';\n }\n if (idx === parts.length - 1) {\n return '{\\n' + part;\n }\n return '{\\n' + part + '\\n}';\n });\n}\n\n/**\n * Parse all JSON objects from an evaluator log file.\n */\nfunction parseJsonObjects(logPath: string): Record[] {\n const content = readFileSync(logPath, 'utf-8');\n const objectStrings = splitJsonObjects(content);\n\n const results: Record[] = [];\n for (const objStr of objectStrings) {\n try {\n results.push(JSON.parse(objStr) as Record);\n } catch {\n logger.warn(\n `Failed to parse evaluator log object: ${objStr.substring(0, 120)}...`\n );\n }\n }\n return results;\n}\n\n// ---------------------------------------------------------------------------\n// Raw evaluator log parsing\n// ---------------------------------------------------------------------------\n\n/**\n * Parse a raw `evaluator-log.jsonl` file into {@link ProfileData}.\n *\n * Tracks `QUERY_STARTED`/`QUERY_COMPLETED` pairs, computes predicate\n * durations from `PREDICATE_STARTED`/`PREDICATE_COMPLETED` nanoTime\n * differences, and groups predicates by `queryCausingWork`.\n */\nexport function parseRawEvaluatorLog(logPath: string): ProfileData {\n const events = parseJsonObjects(logPath);\n\n let codeqlVersion: string | undefined;\n\n // Maps: eventId \u2192 event data for lookups\n const queryStartEvents = new Map<\n number,\n { queryName: string; nanoTime: number }\n >();\n const predicateStartEvents = new Map<\n number,\n {\n predicateName: string;\n position?: string;\n predicateType?: string;\n dependencies: string[];\n queryCausingWork?: number;\n nanoTime: number;\n pipelineCount: number;\n }\n >();\n\n // Completed predicate profiles grouped by query eventId\n const queryPredicates = new Map();\n // Query end nanoTimes keyed by query start eventId\n const queryEndNanoTimes = new Map();\n // Track cache lookups per query\n const queryCacheHits = new Map();\n // Fallback query eventId for predicates without queryCausingWork\n let firstQueryEventId: number | undefined;\n\n for (const event of events) {\n const eventType = event.type as string | undefined;\n\n switch (eventType) {\n case 'LOG_HEADER': {\n codeqlVersion = event.codeqlVersion as string | undefined;\n break;\n }\n\n case 'QUERY_STARTED': {\n const eid = event.eventId as number;\n const qName = (event.queryName as string) || 'unknown';\n queryStartEvents.set(eid, {\n queryName: qName,\n nanoTime: event.nanoTime as number,\n });\n queryPredicates.set(eid, []);\n queryCacheHits.set(eid, 0);\n if (firstQueryEventId === undefined) {\n firstQueryEventId = eid;\n }\n break;\n }\n\n case 'QUERY_COMPLETED': {\n const startEid = event.startEvent as number;\n queryEndNanoTimes.set(startEid, event.nanoTime as number);\n break;\n }\n\n case 'PREDICATE_STARTED': {\n const eid = event.eventId as number;\n const deps = event.dependencies as Record | undefined;\n predicateStartEvents.set(eid, {\n predicateName: (event.predicateName as string) || 'unknown',\n position: event.position as string | undefined,\n predicateType: event.predicateType as string | undefined,\n dependencies: deps ? Object.keys(deps) : [],\n queryCausingWork: event.queryCausingWork as number | undefined,\n nanoTime: event.nanoTime as number,\n pipelineCount: 0,\n });\n break;\n }\n\n case 'PIPELINE_COMPLETED': {\n // Count pipelines for the parent predicate\n const pipelineStartEid = event.startEvent as number;\n // Find the pipeline_started event to get predicateStartEvent\n const pipelineStartEvt = events.find(\n (e) =>\n (e.type as string) === 'PIPELINE_STARTED' &&\n (e.eventId as number) === pipelineStartEid\n );\n if (pipelineStartEvt) {\n const predEid = pipelineStartEvt.predicateStartEvent as number;\n const predStart = predicateStartEvents.get(predEid);\n if (predStart) {\n predStart.pipelineCount += 1;\n }\n }\n break;\n }\n\n case 'PREDICATE_COMPLETED': {\n const startEid = event.startEvent as number;\n const predStart = predicateStartEvents.get(startEid);\n if (predStart) {\n const durationNs =\n (event.nanoTime as number) - predStart.nanoTime;\n const durationMs = durationNs / 1_000_000;\n\n const profile: PredicateProfile = {\n predicateName: predStart.predicateName,\n position: predStart.position,\n durationMs,\n resultSize: event.resultSize as number | undefined,\n pipelineCount:\n predStart.pipelineCount > 0\n ? predStart.pipelineCount\n : undefined,\n evaluationStrategy: predStart.predicateType,\n dependencies: predStart.dependencies,\n };\n\n const qEid =\n predStart.queryCausingWork ?? firstQueryEventId;\n if (qEid !== undefined) {\n let arr = queryPredicates.get(qEid);\n if (!arr) {\n arr = [];\n queryPredicates.set(qEid, arr);\n }\n arr.push(profile);\n }\n }\n break;\n }\n\n case 'CACHE_LOOKUP': {\n // Attribute to the most recent query\n const qEid =\n (event.queryCausingWork as number | undefined) ??\n firstQueryEventId;\n if (qEid !== undefined) {\n queryCacheHits.set(qEid, (queryCacheHits.get(qEid) ?? 0) + 1);\n }\n break;\n }\n }\n }\n\n // Build QueryProfile entries\n const queries: QueryProfile[] = [];\n for (const [qEid, startInfo] of queryStartEvents) {\n const predicates = queryPredicates.get(qEid) ?? [];\n const endNano = queryEndNanoTimes.get(qEid);\n const totalDurationMs =\n endNano !== undefined\n ? (endNano - startInfo.nanoTime) / 1_000_000\n : predicates.reduce((sum, p) => sum + p.durationMs, 0);\n\n queries.push({\n queryName: startInfo.queryName,\n totalDurationMs,\n predicateCount: predicates.length,\n predicates,\n cacheHits: queryCacheHits.get(qEid) ?? 0,\n });\n }\n\n return {\n codeqlVersion,\n logFormat: 'raw',\n queries,\n totalEvents: events.length,\n };\n}\n\n// ---------------------------------------------------------------------------\n// Summary log parsing\n// ---------------------------------------------------------------------------\n\n/**\n * Parse an `evaluator-log.summary.jsonl` file into {@link ProfileData}.\n *\n * Summary events carry `millis` directly (already in ms). Predicates are\n * grouped by `queryCausingWork` which is a **string** (query name) in the\n * summary format.\n */\nexport function parseSummaryLog(logPath: string): ProfileData {\n const events = parseJsonObjects(logPath);\n\n let codeqlVersion: string | undefined;\n\n // queryCausingWork (string) \u2192 collected predicates\n const queryPredicatesMap = new Map();\n // Track total millis per query\n const queryTotalMs = new Map();\n // Track cache hits per query\n const queryCacheHits = new Map();\n\n for (const event of events) {\n // Header detection\n if (event.summaryLogVersion !== undefined) {\n codeqlVersion = event.codeqlVersion as string | undefined;\n continue;\n }\n\n const strategy = event.evaluationStrategy as string | undefined;\n\n // Skip sentinel-empty entries (no useful timing data)\n if (strategy === 'SENTINEL_EMPTY') {\n continue;\n }\n\n // Skip events without millis (non-predicate summaries)\n if (event.millis === undefined) {\n continue;\n }\n\n const predicateName =\n (event.predicateName as string) || 'unknown';\n const millis = event.millis as number;\n const queryName =\n (event.queryCausingWork as string) || 'unknown';\n\n const deps = event.dependencies as Record | undefined;\n const pipelineRuns = event.pipelineRuns as number | undefined;\n\n const profile: PredicateProfile = {\n predicateName,\n position: event.position as string | undefined,\n durationMs: millis,\n resultSize: event.resultSize as number | undefined,\n pipelineCount: pipelineRuns,\n evaluationStrategy: strategy,\n dependencies: deps ? Object.keys(deps) : [],\n };\n\n // Check if this is a cached entry\n if (event.isCached === true || strategy === 'CACHEHIT') {\n queryCacheHits.set(\n queryName,\n (queryCacheHits.get(queryName) ?? 0) + 1\n );\n }\n\n let arr = queryPredicatesMap.get(queryName);\n if (!arr) {\n arr = [];\n queryPredicatesMap.set(queryName, arr);\n }\n arr.push(profile);\n\n queryTotalMs.set(\n queryName,\n (queryTotalMs.get(queryName) ?? 0) + millis\n );\n }\n\n // Build QueryProfile entries\n const queries: QueryProfile[] = [];\n for (const [queryName, predicates] of queryPredicatesMap) {\n queries.push({\n queryName,\n totalDurationMs: queryTotalMs.get(queryName) ?? 0,\n predicateCount: predicates.length,\n predicates,\n cacheHits: queryCacheHits.get(queryName) ?? 0,\n });\n }\n\n return {\n codeqlVersion,\n logFormat: 'summary',\n queries,\n totalEvents: events.length,\n };\n}\n\n// ---------------------------------------------------------------------------\n// Auto-detect entry point\n// ---------------------------------------------------------------------------\n\n/**\n * Auto-detect the log format and parse accordingly.\n *\n * @param logPath - Absolute path to `evaluator-log.jsonl` or\n * `evaluator-log.summary.jsonl`.\n * @returns Parsed profile data.\n */\nexport function parseEvaluatorLog(logPath: string): ProfileData {\n const events = parseJsonObjects(logPath);\n\n if (events.length === 0) {\n return {\n logFormat: 'raw',\n queries: [],\n totalEvents: 0,\n };\n }\n\n const format = detectLogFormat(events[0]);\n\n if (format === 'raw') {\n return parseRawEvaluatorLog(logPath);\n }\n return parseSummaryLog(logPath);\n}\n", "/**\n * CodeQL query profiling tool\n */\n\nimport { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport { z } from 'zod';\nimport { executeCodeQLCommand } from '../../lib/cli-executor';\nimport { logger } from '../../utils/logger';\nimport { writeFileSync, readFileSync, existsSync } from 'fs';\nimport { join, dirname, basename } from 'path';\nimport { mkdirSync } from 'fs';\n\ninterface EvaluatorLogEvent {\n time: string;\n type: string;\n eventId: number;\n nanoTime: number;\n [key: string]: unknown;\n}\n\ninterface PipelineNode {\n eventId: number;\n name: string;\n position?: string;\n type?: string;\n startTime: number;\n endTime: number;\n duration: number;\n resultSize?: number;\n tupleCount?: number;\n dependencies: string[];\n dependencyEventIds: number[];\n}\n\ninterface ProfileData {\n queryName: string;\n totalDuration: number;\n totalEvents: number;\n pipelines: PipelineNode[];\n}\n\n/**\n * Parse evaluator log and create profile data\n */\nfunction parseEvaluatorLog(logPath: string): ProfileData {\n const logContent = readFileSync(logPath, 'utf-8');\n \n // Split by empty lines to get each JSON object (handles both JSONL and pretty-printed JSON)\n const jsonObjects = logContent.split('\\n\\n').filter((s) => s.trim());\n const events: EvaluatorLogEvent[] = jsonObjects\n .map((obj) => {\n try {\n return JSON.parse(obj);\n } catch (_error) {\n logger.warn(`Failed to parse evaluator log object: ${obj.substring(0, 100)}...`);\n return null;\n }\n })\n .filter((event): event is EvaluatorLogEvent => event !== null);\n\n // Map to track pipeline nodes by their start event ID\n const pipelineMap = new Map>();\n // Map to track dependency event IDs by predicate name\n const predicateNameToEventId = new Map();\n \n let queryName = '';\n let queryStartTime = 0;\n let queryEndTime = 0;\n\n for (const event of events) {\n switch (event.type) {\n case 'QUERY_STARTED':\n queryName = (event.queryName as string) || '';\n queryStartTime = event.nanoTime;\n break;\n\n case 'QUERY_COMPLETED':\n queryEndTime = event.nanoTime;\n break;\n\n case 'PREDICATE_STARTED': {\n const predicateName = event.predicateName as string;\n const position = event.position as string | undefined;\n const predicateType = event.predicateType as string | undefined;\n const dependencies = event.dependencies as Record | undefined;\n \n // Track this predicate's event ID by name for dependency resolution\n predicateNameToEventId.set(predicateName, event.eventId);\n \n // Get dependency event IDs\n const dependencyEventIds: number[] = [];\n const dependencyNames: string[] = [];\n if (dependencies) {\n for (const depName of Object.keys(dependencies)) {\n dependencyNames.push(depName);\n const depEventId = predicateNameToEventId.get(depName);\n if (depEventId !== undefined) {\n dependencyEventIds.push(depEventId);\n }\n }\n }\n\n pipelineMap.set(event.eventId, {\n eventId: event.eventId,\n name: predicateName,\n position,\n type: predicateType,\n startTime: event.nanoTime,\n dependencies: dependencyNames,\n dependencyEventIds,\n });\n break;\n }\n\n case 'PREDICATE_COMPLETED': {\n const startEventId = event.startEvent as number;\n const pipelineInfo = pipelineMap.get(startEventId);\n if (pipelineInfo) {\n const startEvent = events.find((e) => e.eventId === startEventId);\n if (startEvent) {\n const duration = (event.nanoTime - startEvent.nanoTime) / 1_000_000; // Convert to ms\n pipelineInfo.endTime = event.nanoTime;\n pipelineInfo.duration = duration;\n pipelineInfo.resultSize = event.resultSize as number | undefined;\n pipelineInfo.tupleCount = event.tupleCount as number | undefined;\n }\n }\n break;\n }\n }\n }\n\n // Convert to array and maintain original evaluation order (by eventId)\n const pipelines: PipelineNode[] = Array.from(pipelineMap.values())\n .filter((p): p is PipelineNode => p.duration !== undefined)\n .sort((a, b) => a.eventId - b.eventId);\n\n const totalDuration = queryEndTime > 0 ? (queryEndTime - queryStartTime) / 1_000_000 : 0;\n\n return {\n queryName,\n totalDuration,\n totalEvents: events.length,\n pipelines,\n };\n}\n\n/**\n * Format profile data as JSON\n */\nfunction formatAsJson(profile: ProfileData): string {\n return JSON.stringify(profile, null, 2);\n}\n\n/**\n * Format profile data as Mermaid diagram\n * Creates a graph showing the query evaluation pipelines in order of execution\n * with dependencies as edges, annotated with duration and result sizes\n */\nfunction formatAsMermaid(profile: ProfileData): string {\n const lines: string[] = [];\n\n lines.push('```mermaid');\n lines.push('graph TD');\n lines.push('');\n \n // Add query root node\n lines.push(` QUERY[\"${basename(profile.queryName)}
Total: ${profile.totalDuration.toFixed(2)}ms\"]`);\n lines.push('');\n \n // Create nodes for each pipeline in evaluation order (already sorted by eventId)\n profile.pipelines.forEach((pipeline) => {\n const nodeId = `P${pipeline.eventId}`;\n const duration = pipeline.duration.toFixed(2);\n const resultSize = pipeline.resultSize !== undefined ? pipeline.resultSize : '?';\n // Sanitize predicate name for Mermaid\n const name = pipeline.name.replace(/[<>]/g, '').substring(0, 40);\n lines.push(` ${nodeId}[\"${name}
${duration}ms | ${resultSize} results\"]`);\n });\n \n lines.push('');\n \n // Add edges from QUERY to root pipelines (those with no dependencies)\n const rootPipelines = profile.pipelines.filter((p) => p.dependencies.length === 0);\n \n rootPipelines.forEach((pipeline) => {\n lines.push(` QUERY --> P${pipeline.eventId}`);\n });\n \n lines.push('');\n \n // Add edges between pipelines based on dependencies (using eventIds to preserve links)\n profile.pipelines.forEach((pipeline) => {\n pipeline.dependencyEventIds.forEach((depEventId) => {\n const duration = pipeline.duration.toFixed(2);\n lines.push(` P${depEventId} -->|\"${duration}ms\"| P${pipeline.eventId}`);\n });\n });\n \n lines.push('');\n lines.push(' classDef default fill:#e1f5ff,stroke:#333,stroke-width:2px');\n lines.push(' classDef query fill:#ffe1e1,stroke:#333,stroke-width:3px');\n lines.push(' class QUERY query');\n lines.push('```');\n\n return lines.join('\\n');\n}\n\n/**\n * Register the profile_codeql_query tool\n */\nexport function registerProfileCodeQLQueryTool(server: McpServer): void {\n server.tool(\n 'profile_codeql_query',\n 'Profile the performance of a CodeQL query run against a specific database by analyzing the evaluator log JSON file',\n {\n query: z.string().describe('Path to the .ql query file'),\n database: z.string().describe('Path to the CodeQL database directory'),\n evaluatorLog: z\n .string()\n .optional()\n .describe(\n 'Path to an existing structured JSON log (e.g., evaluator-log.jsonl) file. If not provided, the tool will run the query to generate one.'\n ),\n outputDir: z\n .string()\n .optional()\n .describe('Directory to write profiling data files (defaults to same directory as evaluator log)'),\n },\n async (params) => {\n try {\n const { query, database, evaluatorLog, outputDir } = params;\n let logPath = evaluatorLog;\n let bqrsPath: string | undefined;\n let sarifPath: string | undefined;\n\n // If evaluator log not provided, run the query to generate one\n if (!logPath) {\n logger.info('No evaluator log provided, running query to generate one');\n\n // Determine output directory\n const defaultOutputDir = outputDir || join(dirname(query as string), 'profile-output');\n mkdirSync(defaultOutputDir, { recursive: true });\n\n logPath = join(defaultOutputDir, 'evaluator-log.jsonl');\n bqrsPath = join(defaultOutputDir, 'query-results.bqrs');\n sarifPath = join(defaultOutputDir, 'query-results.sarif');\n\n // Run query with evaluator logging and tuple counting\n const queryResult = await executeCodeQLCommand(\n 'query run',\n {\n database: database as string,\n output: bqrsPath,\n 'evaluator-log': logPath,\n 'tuple-counting': true,\n 'evaluator-log-level': 5,\n },\n [query as string]\n );\n\n if (!queryResult.success) {\n return {\n content: [\n {\n type: 'text' as const,\n text: `Failed to run query: ${queryResult.stderr || queryResult.error}`,\n },\n ],\n isError: true,\n };\n }\n\n // Generate SARIF interpretation\n if (existsSync(bqrsPath)) {\n try {\n const sarifResult = await executeCodeQLCommand(\n 'bqrs interpret',\n { format: 'sarif-latest', output: sarifPath },\n [bqrsPath]\n );\n\n if (sarifResult.success) {\n logger.info(`Generated SARIF interpretation at ${sarifPath}`);\n }\n } catch (error) {\n logger.warn(`Failed to generate SARIF interpretation: ${error}`);\n }\n }\n }\n\n // Verify evaluator log exists\n if (!existsSync(logPath)) {\n return {\n content: [\n {\n type: 'text' as const,\n text: `Evaluator log not found at: ${logPath}`,\n },\n ],\n isError: true,\n };\n }\n\n // Parse the evaluator log\n logger.info(`Parsing evaluator log from: ${logPath}`);\n const profile = parseEvaluatorLog(logPath);\n\n // Determine output directory for profile\n const profileOutputDir = outputDir || dirname(logPath);\n mkdirSync(profileOutputDir, { recursive: true });\n\n // Write profile JSON file\n const jsonPath = join(profileOutputDir, 'query-evaluation-profile.json');\n const jsonContent = formatAsJson(profile);\n writeFileSync(jsonPath, jsonContent);\n logger.info(`Profile JSON written to: ${jsonPath}`);\n\n // Write profile Mermaid diagram file\n const mdPath = join(profileOutputDir, 'query-evaluation-profile.md');\n const mdContent = formatAsMermaid(profile);\n writeFileSync(mdPath, mdContent);\n logger.info(`Profile Mermaid diagram written to: ${mdPath}`);\n\n // Build response message\n const outputFiles: string[] = [\n `Profile JSON: ${jsonPath}`,\n `Profile Mermaid: ${mdPath}`,\n `Evaluator Log: ${logPath}`,\n ];\n\n if (bqrsPath) {\n outputFiles.push(`Query Results (BQRS): ${bqrsPath}`);\n }\n\n if (sarifPath && existsSync(sarifPath)) {\n outputFiles.push(`Query Results (SARIF): ${sarifPath}`);\n }\n\n const responseText = [\n 'Query profiling completed successfully!',\n '',\n 'Output Files:',\n ...outputFiles.map((f) => ` - ${f}`),\n '',\n 'Profile Summary:',\n ` - Query: ${basename(profile.queryName)}`,\n ` - Total Duration: ${profile.totalDuration.toFixed(2)} ms`,\n ` - Total Pipelines: ${profile.pipelines.length}`,\n ` - Total Events: ${profile.totalEvents}`,\n '',\n 'First 5 Pipeline Nodes (in evaluation order):',\n ...profile.pipelines.slice(0, 5).map((p, idx) => {\n return ` ${idx + 1}. ${p.name} (${p.duration.toFixed(2)} ms, ${p.resultSize || '?'} results)`;\n }),\n ].join('\\n');\n\n return {\n content: [\n {\n type: 'text' as const,\n text: responseText,\n },\n ],\n };\n } catch (error) {\n logger.error('Error profiling CodeQL query:', error);\n\n return {\n content: [\n {\n type: 'text' as const,\n text: `Failed to profile query: ${error instanceof Error ? error.message : String(error)}`,\n },\n ],\n isError: true,\n };\n }\n }\n );\n}\n", "/**\n * CodeQL query compile tool\n */\n\nimport { z } from 'zod';\nimport { CLIToolDefinition } from '../../lib/cli-tool-registry';\n\nexport const codeqlQueryCompileTool: CLIToolDefinition = {\n name: 'codeql_query_compile',\n description: 'Compile and validate CodeQL queries',\n command: 'codeql',\n subcommand: 'query compile',\n inputSchema: {\n query: z.string().describe('Path to the CodeQL query file (.ql)'),\n database: z.string().optional().describe('Path to the CodeQL database'),\n library: z.string().optional().describe('Path to query library'),\n output: z.string().optional().describe('Output file path'),\n warnings: z.enum(['hide', 'show', 'error']).optional()\n .describe('How to handle compilation warnings'),\n verbose: z.boolean().optional().describe('Enable verbose output'),\n additionalArgs: z.array(z.string()).optional().describe('Additional command-line arguments')\n },\n examples: [\n 'codeql query compile --database=/path/to/db MyQuery.ql',\n 'codeql query compile --library=/path/to/lib --output=compiled.qlo MyQuery.ql'\n ]\n};", "/**\n * CodeQL query format tool\n */\n\nimport { z } from 'zod';\nimport { CLIToolDefinition, createCodeQLSchemas, defaultCLIResultProcessor, CLIExecutionResult } from '../../lib/cli-tool-registry';\n\n/**\n * Custom result processor for codeql query format tool\n * Exit code 1 with --check-only means \"file would change\" - this is success for format checking\n */\nfunction formatResultProcessor(result: CLIExecutionResult, params: Record): string {\n const isCheckOnly = params['check-only'];\n const hasFormatChanges = result.exitCode === 1;\n \n if (isCheckOnly && hasFormatChanges) {\n // Mark as success for the CLI tool registry since detecting format changes is the intended behavior\n result.success = true;\n return result.stdout || result.stderr || 'File would change by autoformatting.';\n }\n \n return defaultCLIResultProcessor(result, params);\n}\n\nexport const codeqlQueryFormatTool: CLIToolDefinition = {\n name: 'codeql_query_format',\n description: 'Automatically format CodeQL source code files',\n command: 'codeql',\n subcommand: 'query format',\n inputSchema: {\n files: z.array(z.string()).describe('One or more .ql or .qll source files to format'),\n output: z.string().optional().describe('Write formatted code to this file instead of stdout'),\n 'in-place': z.boolean().optional().describe('Overwrite each input file with formatted version'),\n 'check-only': z.boolean().optional().describe('Check formatting without writing output'),\n backup: z.string().optional().describe('Backup extension when overwriting existing files'),\n 'no-syntax-errors': z.boolean().optional().describe('Ignore syntax errors and pretend file is formatted'),\n verbose: createCodeQLSchemas.verbose(),\n additionalArgs: createCodeQLSchemas.additionalArgs()\n },\n examples: [\n 'codeql query format -i -- ExampleQuery.ql',\n 'codeql query format --in-place -- queries/*.ql',\n 'codeql query format --check-only -- queries/*.ql'\n ],\n resultProcessor: formatResultProcessor\n};", "/**\n * CodeQL query run tool\n */\n\nimport { z } from 'zod';\nimport { CLIToolDefinition, createCodeQLSchemas } from '../../lib/cli-tool-registry';\n\nexport const codeqlQueryRunTool: CLIToolDefinition = {\n name: 'codeql_query_run',\n description:\n 'Execute a CodeQL query against a database. Use either \"query\" parameter for direct file path OR \"queryName\" + \"queryLanguage\" for pre-defined tool queries. ' +\n 'Produces evaluator logs and BQRS results in a log directory. ' +\n 'Use list_codeql_databases to discover databases, list_query_run_results to find previous results, and codeql_bqrs_decode to inspect BQRS output.',\n command: 'codeql',\n subcommand: 'query run',\n inputSchema: {\n query: z.string().optional().describe('Path to the CodeQL query file (.ql) - cannot be used with queryName'),\n queryName: z.string().optional().describe('Name of pre-defined query to run (e.g., \"PrintAST\", \"CallGraphFrom\", \"CallGraphTo\") - requires queryLanguage'),\n queryLanguage: z.string().optional().describe('Programming language for tools queries (e.g., \"javascript\", \"java\", \"python\") - required when using queryName'),\n queryPack: z.string().optional().describe('Query pack path (defaults to server/ql//tools/src/ for tool queries)'),\n sourceFiles: z.string().optional().describe('Comma-separated list of source file paths for PrintAST queries (e.g., \"src/main.js,src/utils.js\" or just \"main.js\")'),\n sourceFunction: z.string().optional().describe('Comma-separated list of source function names for CallGraphFrom queries (e.g., \"main,processData\")'),\n targetFunction: z.string().optional().describe('Comma-separated list of target function names for CallGraphTo queries (e.g., \"helper,validateInput\")'),\n database: createCodeQLSchemas.database(),\n output: createCodeQLSchemas.output(),\n external: z.array(z.string()).optional()\n .describe('External predicate data: predicate=file.csv'),\n timeout: createCodeQLSchemas.timeout(),\n logDir: z.string().optional()\n .describe('Custom directory for query execution logs (overrides CODEQL_QUERY_LOG_DIR environment variable). If not provided, uses CODEQL_QUERY_LOG_DIR or defaults to .tmp/query-logs/'),\n 'evaluator-log': z.string().optional().describe('Path to save evaluator log (deprecated: use logDir instead)'),\n 'evaluator-log-minify': z.boolean().optional()\n .describe('Minimize evaluator log for smaller size'),\n 'evaluator-log-level': z.number().min(1).max(5).optional()\n .describe('Evaluator log verbosity level (1-5, default 5)'),\n 'tuple-counting': z.boolean().optional()\n .describe('Display tuple counts for each evaluation step in evaluator logs'),\n format: z.enum(['sarif-latest', 'sarifv2.1.0', 'csv', 'graphtext', 'dgml', 'dot']).optional()\n .describe('Output format for query results via codeql bqrs interpret. Defaults to sarif-latest for @kind problem/path-problem queries, graphtext for @kind graph queries. Graph formats (graphtext, dgml, dot) only work with @kind graph queries.'),\n interpretedOutput: z.string().optional()\n .describe('Output file for interpreted results (e.g., results.sarif, results.txt). If not provided, defaults based on format: .sarif for SARIF, .txt for graphtext/csv, .dgml for dgml, .dot for dot'),\n evaluationFunction: z.string().optional()\n .describe('[DEPRECATED - use format parameter instead] Built-in function for query results evaluation (e.g., \"mermaid-graph\", \"json-decode\", \"csv-decode\") or path to custom evaluation script'),\n evaluationOutput: z.string().optional()\n .describe('[DEPRECATED - use interpretedOutput parameter instead] Output file for evaluation results'),\n verbose: createCodeQLSchemas.verbose(),\n additionalArgs: createCodeQLSchemas.additionalArgs()\n },\n examples: [\n 'codeql query run --database=mydb --output=results.bqrs MyQuery.ql',\n 'codeql query run --database=mydb --query-name=PrintAST --query-language=javascript --source-files=src/index.js --output=results.bqrs --format=graphtext --interpreted-output=results.txt',\n 'codeql query run --database=mydb --external=data=input.csv --output=results.bqrs MyQuery.ql --format=sarif-latest --interpreted-output=results.sarif',\n 'codeql query run --database=mydb --evaluator-log=eval.log --tuple-counting --evaluator-log-level=5 --output=results.bqrs MyQuery.ql',\n 'codeql query run --database=mydb --query-name=PrintAST --query-language=javascript --source-files=\"main.js,utils.js\" --format=graphtext',\n 'codeql query run --database=mydb --log-dir=/custom/log/path --tuple-counting --output=results.bqrs MyQuery.ql'\n ]\n};", "/**\n * CodeQL quick evaluate tool\n * \n * Inspired by JordyZomer/codeql-mcp repository:\n * - https://github.com/JordyZomer/codeql-mcp/blob/main/server.py\n * - https://github.com/JordyZomer/codeql-mcp/blob/main/codeqlclient.py\n */\n\nimport { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport { z } from 'zod';\nimport { join, resolve } from 'path';\nimport { findClassPosition } from './find-class-position';\nimport { findPredicatePosition } from './find-predicate-position';\nimport { logger } from '../../utils/logger';\nimport { getProjectTmpDir } from '../../utils/temp-dir';\n\nexport interface QuickEvaluateParams {\n file: string;\n db: string;\n symbol: string;\n output_path?: string;\n}\n\n/**\n * Quick evaluate either a class or a predicate in a CodeQL query.\n * This allows debugging a select portion of QL code without running the whole query.\n */\nexport async function quickEvaluate({\n file,\n db: _db,\n symbol,\n output_path\n}: QuickEvaluateParams): Promise {\n try {\n // Try to find as a class first, then as a predicate\n try {\n await findClassPosition(file, symbol);\n } catch {\n try {\n await findPredicatePosition(file, symbol);\n } catch {\n throw new Error(`Symbol '${symbol}' not found as class or predicate in file: ${file}`);\n }\n }\n \n const resolvedOutput = resolve(output_path || join(getProjectTmpDir('quickeval'), 'quickeval.bqrs'));\n \n // For now, return the resolved output path\n // In a full implementation, this would use the CodeQL CLI or query server\n // to perform the actual quick evaluation with the position parameters\n return resolvedOutput;\n } catch (error) {\n throw new Error(`CodeQL evaluation failed: ${error instanceof Error ? error.message : 'Unknown error'}`);\n }\n}\n\n/**\n * Register the quick evaluate tool with the MCP server\n */\nexport function registerQuickEvaluateTool(server: McpServer): void {\n server.tool(\n 'quick_evaluate',\n 'Quick evaluate either a class or a predicate in a CodeQL query for debugging',\n {\n file: z.string().describe('Path to the .ql file containing the symbol'),\n db: z.string().describe('Path to the CodeQL database'),\n symbol: z.string().describe('Name of the class or predicate to evaluate'),\n output_path: z.string().optional().describe('Output path for results (defaults to project-local .tmp/quickeval/)'),\n },\n async ({ file, db, symbol, output_path }) => {\n try {\n const result = await quickEvaluate({ file, db, symbol, output_path });\n return {\n content: [{ type: 'text', text: result }],\n };\n } catch (error) {\n logger.error('Error in quick evaluate:', error);\n return {\n content: [\n {\n type: 'text',\n text: `Error: ${error instanceof Error ? error.message : 'Unknown error'}`,\n },\n ],\n isError: true,\n };\n }\n }\n );\n}", "/**\n * CodeQL register database tool\n * \n * Inspired by JordyZomer/codeql-mcp repository:\n * - https://github.com/JordyZomer/codeql-mcp/blob/main/server.py\n * - https://github.com/JordyZomer/codeql-mcp/blob/main/codeqlclient.py\n */\n\nimport { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport { z } from 'zod';\nimport { access, constants } from 'fs/promises';\nimport { resolve } from 'path';\nimport { logger } from '../../utils/logger';\n\nexport interface DatabaseRegistration {\n uri: string;\n content: {\n sourceArchiveZip: string;\n dbDir: string;\n };\n}\n\n/**\n * Register a CodeQL database given a local path to the database directory.\n * Validates that the database exists and has required structure.\n * Supports both full databases (with src.zip) and test databases (with src/ folder).\n */\nexport async function registerDatabase(dbPath: string): Promise {\n try {\n const resolvedPath = resolve(dbPath);\n \n // Check if database directory exists\n await access(resolvedPath, constants.F_OK);\n \n // Check for codeql-database.yml (required for all CodeQL databases)\n const dbYmlPath = resolve(resolvedPath, 'codeql-database.yml');\n await access(dbYmlPath, constants.F_OK);\n \n // Check if src.zip exists (for full databases) OR src/ directory exists (for test databases)\n const srcZipPath = resolve(resolvedPath, 'src.zip');\n const srcDirPath = resolve(resolvedPath, 'src');\n \n let hasSrcZip = false;\n let hasSrcDir = false;\n \n try {\n await access(srcZipPath, constants.F_OK);\n hasSrcZip = true;\n } catch {\n // src.zip not found, check for src/ directory\n }\n \n if (!hasSrcZip) {\n try {\n await access(srcDirPath, constants.F_OK);\n hasSrcDir = true;\n } catch {\n // src directory not found either\n }\n }\n \n if (!hasSrcZip && !hasSrcDir) {\n throw new Error(`Missing required source archive (src.zip) or source directory (src/) in: ${dbPath}`);\n }\n \n // For now, we just validate and return success message\n // In a full implementation, this would register with a query server\n const sourceType = hasSrcZip ? 'src.zip' : 'src/';\n return `Database registered: ${dbPath} (source: ${sourceType})`;\n } catch (error) {\n if (error instanceof Error) {\n const errorCode = (error as { code?: string }).code;\n if (errorCode === 'ENOENT') {\n if (error.message.includes('codeql-database.yml')) {\n throw new Error(`Missing required codeql-database.yml in: ${dbPath}`);\n }\n throw new Error(`Database path does not exist: ${dbPath}`);\n }\n if (errorCode === 'EACCES') {\n throw new Error(`Database path does not exist: ${dbPath}`);\n }\n }\n throw new Error(`Failed to register database: ${error instanceof Error ? error.message : 'Unknown error'}`);\n }\n}\n\n/**\n * Register the register database tool with the MCP server\n */\nexport function registerRegisterDatabaseTool(server: McpServer): void {\n server.tool(\n 'register_database',\n 'Register a CodeQL database given a local path to the database directory',\n {\n db_path: z.string().describe('Path to the CodeQL database directory'),\n },\n async ({ db_path }) => {\n try {\n const result = await registerDatabase(db_path);\n return {\n content: [{ type: 'text', text: result }],\n };\n } catch (error) {\n logger.error('Error registering database:', error);\n return {\n content: [\n {\n type: 'text',\n text: `Error: ${error instanceof Error ? error.message : 'Unknown error'}`,\n },\n ],\n isError: true,\n };\n }\n }\n );\n}", "/**\n * CodeQL resolve database tool\n */\n\nimport { z } from 'zod';\nimport { CLIToolDefinition, createCodeQLSchemas, defaultCLIResultProcessor } from '../../lib/cli-tool-registry';\n\nexport const codeqlResolveDatabaseTool: CLIToolDefinition = {\n name: 'codeql_resolve_database',\n description: 'Resolve database path and validate database structure',\n command: 'codeql',\n subcommand: 'resolve database',\n inputSchema: {\n database: z.string().describe('Database path to resolve'),\n format: z.enum(['text', 'json', 'betterjson']).optional()\n .describe('Output format for database information'),\n verbose: createCodeQLSchemas.verbose(),\n additionalArgs: createCodeQLSchemas.additionalArgs()\n },\n examples: [\n 'codeql resolve database -- /path/to/database',\n 'codeql resolve database --format=json -- my-database',\n 'codeql resolve database --format=betterjson -- database-dir'\n ],\n resultProcessor: defaultCLIResultProcessor\n};", "/**\n * CodeQL resolve languages tool\n */\n\nimport { z } from 'zod';\nimport { CLIToolDefinition, defaultCLIResultProcessor } from '../../lib/cli-tool-registry';\n\nexport const codeqlResolveLanguagesTool: CLIToolDefinition = {\n name: 'codeql_resolve_languages',\n description: 'List installed CodeQL extractor packs',\n command: 'codeql',\n subcommand: 'resolve languages',\n inputSchema: {\n format: z.enum(['text', 'json', 'betterjson']).optional()\n .describe('Output format for language information'),\n verbose: z.boolean().optional().describe('Enable verbose output'),\n additionalArgs: z.array(z.string()).optional().describe('Additional command-line arguments')\n },\n examples: [\n 'codeql resolve languages --format=text',\n 'codeql resolve languages --format=json',\n 'codeql resolve languages --format=betterjson'\n ],\n resultProcessor: defaultCLIResultProcessor\n};", "/**\n * CodeQL resolve library-path tool\n */\n\nimport { z } from 'zod';\nimport { CLIToolDefinition, defaultCLIResultProcessor } from '../../lib/cli-tool-registry';\n\nexport const codeqlResolveLibraryPathTool: CLIToolDefinition = {\n name: 'codeql_resolve_library-path',\n description: 'Resolve library path for CodeQL queries and libraries',\n command: 'codeql',\n subcommand: 'resolve library-path',\n inputSchema: {\n language: z.string().optional().describe('Programming language to resolve library path for'),\n format: z.enum(['text', 'json', 'betterjson']).optional()\n .describe('Output format for library path information'),\n verbose: z.boolean().optional().describe('Enable verbose output'),\n additionalArgs: z.array(z.string()).optional().describe('Additional command-line arguments')\n },\n examples: [\n 'codeql resolve library-path --language=java',\n 'codeql resolve library-path --format=json --language=python',\n 'codeql resolve library-path --format=betterjson'\n ],\n resultProcessor: defaultCLIResultProcessor\n};", "/**\n * CodeQL resolve metadata tool\n */\n\nimport { z } from 'zod';\nimport { CLIToolDefinition, defaultCLIResultProcessor } from '../../lib/cli-tool-registry';\n\nexport const codeqlResolveMetadataTool: CLIToolDefinition = {\n name: 'codeql_resolve_metadata',\n description: 'Resolve and return the key-value metadata pairs from a CodeQL query source file.',\n command: 'codeql',\n subcommand: 'resolve metadata',\n inputSchema: {\n query: z.string().describe('Query file to resolve metadata for'),\n format: z.enum(['json']).optional()\n .describe('Output format for metadata information (always JSON, optional for future compatibility)'),\n verbose: z.boolean().optional().describe('Enable verbose output'),\n additionalArgs: z.array(z.string()).optional().describe('Additional command-line arguments')\n },\n examples: [\n 'codeql resolve metadata -- relative-path/2/MyQuery.ql',\n 'codeql resolve metadata --format=json -- /absolute-plus/relative-path/2/MyQuery.ql'\n ],\n resultProcessor: defaultCLIResultProcessor\n};", "/**\n * CodeQL resolve qlref tool\n */\n\nimport { z } from 'zod';\nimport { CLIToolDefinition, createCodeQLSchemas, defaultCLIResultProcessor } from '../../lib/cli-tool-registry';\n\nexport const codeqlResolveQlrefTool: CLIToolDefinition = {\n name: 'codeql_resolve_qlref',\n description: 'Resolve qlref files to their corresponding query files',\n command: 'codeql',\n subcommand: 'resolve qlref',\n inputSchema: {\n qlref: z.string().describe('Path to the .qlref file to resolve'),\n format: z.enum(['text', 'json', 'betterjson']).optional()\n .describe('Output format for qlref resolution'),\n verbose: createCodeQLSchemas.verbose(),\n additionalArgs: createCodeQLSchemas.additionalArgs()\n },\n examples: [\n 'codeql resolve qlref -- test/MyQuery.qlref',\n 'codeql resolve qlref --format=json -- test/MyQuery.qlref',\n 'codeql resolve qlref --format=betterjson -- test/MyQuery.qlref'\n ],\n resultProcessor: defaultCLIResultProcessor\n};", "/**\n * CodeQL resolve queries tool\n */\n\nimport { z } from 'zod';\nimport { CLIToolDefinition, createCodeQLSchemas, CLIExecutionResult } from '../../lib/cli-tool-registry';\n\n/**\n * Result processor that only returns stdout for JSON formats\n * This prevents warnings/info from stderr from corrupting JSON output\n */\nconst jsonOnlyResultProcessor = (\n result: CLIExecutionResult,\n params: Record\n): string => {\n if (!result.success) {\n return `Command failed (exit code ${result.exitCode || 'unknown'}):\\n${result.error || result.stderr}`;\n }\n\n // For JSON formats (including bylanguage), only return stdout to avoid mixing warnings with JSON\n if (params.format === 'json' || params.format === 'betterjson' || params.format === 'bylanguage') {\n return result.stdout || '[]';\n }\n\n // For text format, include warnings\n let output = '';\n\n if (result.stdout) {\n output += result.stdout;\n }\n\n if (result.stderr) {\n if (output) {\n output += '\\n\\nWarnings/Info:\\n';\n }\n output += result.stderr;\n }\n\n if (!output) {\n output = 'Command executed successfully (no output)';\n }\n\n return output;\n};\n\nexport const codeqlResolveQueriesTool: CLIToolDefinition = {\n name: 'codeql_resolve_queries',\n description: 'List available CodeQL queries found on the local filesystem',\n command: 'codeql',\n subcommand: 'resolve queries',\n inputSchema: {\n directory: z.string().optional().describe('Directory to search for queries'),\n language: z.string().optional().describe('Filter queries by programming language'),\n format: z.enum(['text', 'json', 'betterjson', 'bylanguage']).optional()\n .describe('Output format for query list'),\n 'additional-packs': z.union([z.string(), z.array(z.string())]).optional()\n .describe('Additional pack directories to search for CodeQL packs'),\n verbose: createCodeQLSchemas.verbose(),\n additionalArgs: createCodeQLSchemas.additionalArgs()\n },\n examples: [\n 'codeql resolve queries',\n 'codeql resolve queries --language=java --format=json',\n 'codeql resolve queries --format=betterjson -- /path/to/queries',\n 'codeql resolve queries --additional-packs=/path/to/packs codeql/java-queries'\n ],\n resultProcessor: jsonOnlyResultProcessor\n};", "/**\n * CodeQL resolve tests tool\n */\n\nimport { z } from 'zod';\nimport { CLIToolDefinition, createCodeQLSchemas, defaultCLIResultProcessor } from '../../lib/cli-tool-registry';\n\nexport const codeqlResolveTestsTool: CLIToolDefinition = {\n name: 'codeql_resolve_tests',\n description: 'Resolve the local filesystem paths of unit tests and/or queries under some base directory',\n command: 'codeql',\n subcommand: 'resolve tests',\n inputSchema: {\n tests: z.array(z.string()).optional().describe('One or more tests (.ql, .qlref files, or test directories)'),\n format: z.enum(['text', 'json']).optional()\n .describe('Output format for test list'),\n verbose: createCodeQLSchemas.verbose(),\n additionalArgs: createCodeQLSchemas.additionalArgs()\n },\n examples: [\n 'codeql resolve tests',\n 'codeql resolve tests --format=json -- test-directory',\n 'codeql resolve tests --format=json -- test1.ql test2.ql'\n ],\n resultProcessor: defaultCLIResultProcessor\n};", "/**\n * CodeQL test accept tool\n */\n\nimport { z } from 'zod';\nimport { CLIToolDefinition, createCodeQLSchemas, defaultCLIResultProcessor } from '../../lib/cli-tool-registry';\n\nexport const codeqlTestAcceptTool: CLIToolDefinition = {\n name: 'codeql_test_accept',\n description: 'Accept new test results as the expected baseline',\n command: 'codeql',\n subcommand: 'test accept',\n inputSchema: {\n tests: z.array(z.string()).describe('One or more tests (.ql, .qlref files, or test directories)'),\n verbose: createCodeQLSchemas.verbose(),\n additionalArgs: createCodeQLSchemas.additionalArgs()\n },\n examples: [\n 'codeql test accept -- languages/java/test/MyQuery/MyQuery.qlref',\n 'codeql test accept -- languages/java/test/MyQuery/',\n 'codeql test accept -- languages/java/src/MyQuery/MyQuery.ql'\n ],\n resultProcessor: defaultCLIResultProcessor\n};", "/**\n * CodeQL test extract tool\n */\n\nimport { z } from 'zod';\nimport { CLIToolDefinition, createCodeQLSchemas, defaultCLIResultProcessor } from '../../lib/cli-tool-registry';\n\nexport const codeqlTestExtractTool: CLIToolDefinition = {\n name: 'codeql_test_extract',\n description: 'Extract test databases for CodeQL query tests',\n command: 'codeql',\n subcommand: 'test extract',\n inputSchema: {\n tests: z.array(z.string()).describe('One or more test directories or files'),\n language: z.string().optional().describe('Programming language for extraction'),\n threads: createCodeQLSchemas.threads(),\n ram: createCodeQLSchemas.ram(),\n verbose: createCodeQLSchemas.verbose(),\n additionalArgs: createCodeQLSchemas.additionalArgs()\n },\n examples: [\n 'codeql test extract -- languages/java/test/MyQuery/',\n 'codeql test extract --language=java --threads=4 -- test-directory',\n 'codeql test extract --threads=2 --ram=2048 -- multiple/test/directories'\n ],\n resultProcessor: defaultCLIResultProcessor\n};", "/**\n * CodeQL test run tool\n */\n\nimport { CLIToolDefinition, createCodeQLSchemas } from '../../lib/cli-tool-registry';\nimport { z } from 'zod';\n\nexport const codeqlTestRunTool: CLIToolDefinition = {\n name: 'codeql_test_run',\n description: 'Run CodeQL query tests',\n command: 'codeql',\n subcommand: 'test run',\n inputSchema: {\n tests: z.array(z.string()).describe('One or more tests (.ql, .qlref files, or test directories)'),\n 'show-extractor-output': z.boolean().optional()\n .describe('Show output from extractors during test execution'),\n 'keep-databases': z.boolean().optional()\n .describe('Keep test databases after running tests'),\n 'learn': z.boolean().optional()\n .describe('Accept current output as expected for failing tests'),\n logDir: z.string().optional()\n .describe('Custom directory for test execution logs (overrides CODEQL_QUERY_LOG_DIR environment variable). If not provided, uses CODEQL_QUERY_LOG_DIR or defaults to .tmp/query-logs/'),\n threads: createCodeQLSchemas.threads(),\n ram: createCodeQLSchemas.ram(),\n verbose: createCodeQLSchemas.verbose(),\n additionalArgs: createCodeQLSchemas.additionalArgs()\n },\n examples: [\n 'codeql test run /path/to/tests',\n 'codeql test run --learn /path/to/failing/tests',\n 'codeql test run --threads=4 --keep-databases /path/to/tests',\n 'codeql test run --log-dir=/custom/log/path /path/to/tests'\n ]\n};", "/**\n * CodeQL tools registration for MCP server\n * Includes both high-level helpers and CLI command wrappers\n */\n\nimport { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport { z } from 'zod';\nimport { validateCodeQLSyntax } from '../lib/validation';\nimport { createCodeQLQuery } from '../lib/query-scaffolding';\nimport { registerCLITool } from '../lib/cli-tool-registry';\nimport {\n codeqlBqrsDecodeTool,\n codeqlBqrsInfoTool,\n codeqlBqrsInterpretTool,\n codeqlDatabaseAnalyzeTool,\n codeqlDatabaseCreateTool,\n codeqlGenerateLogSummaryTool,\n codeqlGenerateQueryHelpTool,\n codeqlPackInstallTool,\n codeqlPackLsTool,\n codeqlQueryCompileTool,\n codeqlQueryFormatTool,\n codeqlQueryRunTool,\n codeqlResolveDatabaseTool,\n codeqlResolveLanguagesTool,\n codeqlResolveLibraryPathTool,\n codeqlResolveMetadataTool,\n codeqlResolveQlrefTool,\n codeqlResolveQueriesTool,\n codeqlResolveTestsTool,\n codeqlTestAcceptTool,\n codeqlTestExtractTool,\n codeqlTestRunTool,\n registerFindClassPositionTool,\n registerFindCodeQLQueryFilesTool,\n registerFindPredicatePositionTool,\n registerListDatabasesTool,\n registerListMrvaRunResultsTool,\n registerListQueryRunResultsTool,\n registerProfileCodeQLQueryFromLogsTool,\n registerProfileCodeQLQueryTool,\n registerQuickEvaluateTool,\n registerRegisterDatabaseTool\n} from './codeql';\nimport { logger } from '../utils/logger';\n\n/**\n * Register all CodeQL tools with the MCP server\n */\nexport function registerCodeQLTools(server: McpServer): void {\n // Register high-level helper tools\n \n // Tool: Validate CodeQL Query (heuristic-based)\n server.tool(\n 'validate_codeql_query',\n 'Quick heuristic validation for CodeQL query structure - checks for common patterns like from/where/select clauses and metadata presence. Does NOT compile the query. For authoritative validation with actual compilation, use codeql_lsp_diagnostics instead.',\n {\n query: z.string().describe('The CodeQL query to validate'),\n language: z.string().optional().describe('Target programming language'),\n },\n async ({ query, language }) => {\n try {\n const validation = validateCodeQLSyntax(query, language);\n return {\n content: [{ type: 'text', text: JSON.stringify(validation, null, 2) }],\n };\n } catch (error) {\n logger.error('Error validating CodeQL query:', error);\n return {\n content: [\n {\n type: 'text',\n text: `Error: ${error instanceof Error ? error.message : 'Unknown error'}`,\n },\n ],\n isError: true,\n };\n }\n }\n );\n\n // Tool: Create CodeQL Query\n server.tool(\n 'create_codeql_query',\n 'Create directory structure and files for a new CodeQL query with tests',\n {\n basePath: z.string().describe('Base path where src/ and test/ directories will be created'),\n queryName: z.string().describe('Name of the query (e.g., MySecurityQuery)'),\n language: z.string().describe('Target programming language (e.g., javascript, python, java)'),\n description: z.string().optional().describe('Description of what the query does'),\n queryId: z.string().optional().describe('Custom query ID (defaults to language/example/queryname)'),\n },\n async ({ basePath, queryName, language, description, queryId }) => {\n try {\n const result = createCodeQLQuery({\n basePath,\n queryName,\n language,\n description,\n queryId\n });\n \n const summary = {\n success: true,\n queryPath: result.queryPath,\n testPath: result.testPath,\n qlrefPath: result.qlrefPath,\n testCodePath: result.testCodePath,\n filesCreated: result.filesCreated,\n nextSteps: [\n 'Review and customize the generated query in: ' + result.queryPath,\n 'Add test cases to: ' + result.testCodePath,\n 'Run codeql_pack_install to install dependencies',\n 'Run codeql_test_extract to create test database',\n 'Run codeql_test_run to execute tests'\n ]\n };\n \n return {\n content: [{ type: 'text', text: JSON.stringify(summary, null, 2) }],\n };\n } catch (error) {\n logger.error('Error creating CodeQL query:', error);\n return {\n content: [\n {\n type: 'text',\n text: `Error: ${error instanceof Error ? error.message : 'Unknown error'}`,\n },\n ],\n isError: true,\n };\n }\n }\n );\n\n // Register CLI tools (alphabetically by tool name)\n registerCLITool(server, codeqlBqrsDecodeTool);\n registerCLITool(server, codeqlBqrsInfoTool);\n registerCLITool(server, codeqlBqrsInterpretTool);\n registerCLITool(server, codeqlDatabaseAnalyzeTool);\n registerCLITool(server, codeqlDatabaseCreateTool);\n registerCLITool(server, codeqlGenerateLogSummaryTool);\n registerCLITool(server, codeqlGenerateQueryHelpTool);\n registerCLITool(server, codeqlPackInstallTool);\n registerCLITool(server, codeqlPackLsTool);\n registerCLITool(server, codeqlQueryCompileTool);\n registerCLITool(server, codeqlQueryFormatTool);\n registerCLITool(server, codeqlQueryRunTool);\n registerCLITool(server, codeqlResolveDatabaseTool);\n registerCLITool(server, codeqlResolveLanguagesTool);\n registerCLITool(server, codeqlResolveLibraryPathTool);\n registerCLITool(server, codeqlResolveMetadataTool);\n registerCLITool(server, codeqlResolveQlrefTool);\n registerCLITool(server, codeqlResolveQueriesTool);\n registerCLITool(server, codeqlResolveTestsTool);\n registerCLITool(server, codeqlTestAcceptTool);\n registerCLITool(server, codeqlTestExtractTool);\n registerCLITool(server, codeqlTestRunTool);\n\n // Register new MCP tools (inspired by JordyZomer/codeql-mcp repository)\n registerFindClassPositionTool(server);\n registerFindCodeQLQueryFilesTool(server);\n registerFindPredicatePositionTool(server);\n registerListDatabasesTool(server);\n registerListMrvaRunResultsTool(server);\n registerListQueryRunResultsTool(server);\n registerProfileCodeQLQueryFromLogsTool(server);\n registerProfileCodeQLQueryTool(server);\n registerQuickEvaluateTool(server);\n registerRegisterDatabaseTool(server);\n}\n", "/**\n * CodeQL query validation utilities\n */\n\nimport { resolve, normalize, isAbsolute, relative } from 'path';\n\nexport interface CodeQLValidationResult {\n isValid: boolean;\n errors: string[];\n warnings: string[];\n suggestions: string[];\n}\n\n/**\n * Validates CodeQL query syntax and structure\n */\nexport function validateCodeQLSyntax(query: string, _language?: string): CodeQLValidationResult {\n const validation: CodeQLValidationResult = {\n isValid: true,\n errors: [],\n warnings: [],\n suggestions: [],\n };\n\n if (!query.trim()) {\n validation.isValid = false;\n validation.errors.push('Query cannot be empty');\n return validation;\n }\n\n if (!query.includes('from') && !query.includes('select')) {\n validation.warnings.push('Query should typically include \"from\" and \"select\" clauses');\n }\n\n if (!query.includes('@name') && !query.includes('@description')) {\n validation.suggestions.push('Consider adding @name and @description metadata');\n }\n\n return validation;\n}\n\n/**\n * Validates a file path to prevent path traversal attacks\n * @param filePath - The file path to validate\n * @param workspaceRoot - Optional workspace root directory. If not provided, allows any absolute path but still blocks traversal attempts\n * @returns The validated absolute path\n * @throws Error if the path contains path traversal sequences\n */\nexport function validateFilePath(filePath: string, workspaceRoot?: string): string {\n // Normalize the path to resolve any . or .. segments\n const normalizedPath = normalize(filePath);\n \n // Check for path traversal attempts in the normalized path\n // This blocks paths like \"../../../etc/passwd\" even after normalization\n if (normalizedPath.includes('..')) {\n throw new Error(`Invalid file path: path traversal detected in \"${filePath}\"`);\n }\n \n // Resolve to absolute path\n const absolutePath = isAbsolute(normalizedPath) \n ? normalizedPath \n : resolve(workspaceRoot || process.cwd(), normalizedPath);\n \n // If workspace root is specified, ensure the resolved path is within it\n if (workspaceRoot) {\n const relativePath = relative(workspaceRoot, absolutePath);\n \n // If relative path starts with .. or is absolute, it's outside workspace\n if (relativePath.startsWith('..') || isAbsolute(relativePath)) {\n throw new Error(`Invalid file path: \"${filePath}\" is outside the workspace root`);\n }\n }\n \n return absolutePath;\n}", "/**\n * CodeQL query scaffolding utilities\n * Handles creation of query directory structure and files\n */\n\nimport * as fs from 'fs';\nimport * as path from 'path';\n\nexport interface QueryScaffoldingOptions {\n basePath: string;\n queryName: string;\n language: string;\n description?: string;\n queryId?: string;\n}\n\nexport interface QueryScaffoldingResult {\n queryPath: string;\n testPath: string;\n qlrefPath: string;\n testCodePath: string;\n filesCreated: string[];\n}\n\n/**\n * Get the file extension for test code based on language\n */\nfunction getLanguageExtension(language: string): string {\n const extensions: Record = {\n javascript: 'js',\n typescript: 'ts',\n python: 'py',\n java: 'java',\n csharp: 'cs',\n cpp: 'cpp',\n go: 'go',\n ruby: 'rb',\n actions: 'yml'\n };\n return extensions[language.toLowerCase()] || 'txt';\n}\n\n/**\n * Generate query template content\n */\nfunction generateQueryTemplate(\n queryName: string,\n language: string,\n description?: string,\n queryId?: string\n): string {\n const desc = description || `${queryName} query`;\n const id = queryId || `${language}/example/${queryName.toLowerCase()}`;\n \n return `/**\n * @id ${id}\n * @name ${queryName}\n * @description ${desc}\n * @kind problem\n * @precision medium\n * @problem.severity warning\n */\n\nimport ${language}\n\n// TODO: Implement query logic\nfrom File f\nwhere f.getBaseName() = \"${queryName}.${getLanguageExtension(language)}\"\nselect f, \"TODO: Add query logic\"\n`;\n}\n\n/**\n * Create the directory structure and files for a new CodeQL query\n */\nexport function createCodeQLQuery(options: QueryScaffoldingOptions): QueryScaffoldingResult {\n const { basePath, queryName, language, description, queryId } = options;\n \n // Resolve absolute paths\n const absoluteBasePath = path.resolve(basePath);\n \n // Define paths with intermediate directory\n const srcDir = path.join(absoluteBasePath, 'src', queryName);\n const testDir = path.join(absoluteBasePath, 'test', queryName);\n \n const queryPath = path.join(srcDir, `${queryName}.ql`);\n const qlrefPath = path.join(testDir, `${queryName}.qlref`);\n const testCodePath = path.join(testDir, `${queryName}.${getLanguageExtension(language)}`);\n \n const filesCreated: string[] = [];\n \n try {\n // Create directories (recursive: true is a no-op if they already exist)\n fs.mkdirSync(srcDir, { recursive: true });\n fs.mkdirSync(testDir, { recursive: true });\n \n // Create files atomically using 'wx' flag (exclusive create) to avoid\n // TOCTOU race between existsSync check and writeFileSync (CWE-367).\n // The 'wx' flag fails with EEXIST if the file already exists.\n try {\n const queryContent = generateQueryTemplate(queryName, language, description, queryId);\n fs.writeFileSync(queryPath, queryContent, { encoding: 'utf8', flag: 'wx' });\n filesCreated.push(queryPath);\n } catch (e: unknown) {\n const err = e as { code?: string };\n if (err.code !== 'EEXIST') throw e;\n }\n \n try {\n const qlrefContent = `${queryName}/${queryName}.ql\\n`;\n fs.writeFileSync(qlrefPath, qlrefContent, { encoding: 'utf8', flag: 'wx' });\n filesCreated.push(qlrefPath);\n } catch (e: unknown) {\n const err = e as { code?: string };\n if (err.code !== 'EEXIST') throw e;\n }\n \n try {\n const testCodeContent = `// Test code for ${queryName}\\n// TODO: Add test cases\\n`;\n fs.writeFileSync(testCodePath, testCodeContent, { encoding: 'utf8', flag: 'wx' });\n filesCreated.push(testCodePath);\n } catch (e: unknown) {\n const err = e as { code?: string };\n if (err.code !== 'EEXIST') throw e;\n }\n \n return {\n queryPath,\n testPath: testDir,\n qlrefPath,\n testCodePath,\n filesCreated\n };\n } catch (error) {\n throw new Error(`Failed to create query scaffolding: ${error instanceof Error ? error.message : 'Unknown error'}`);\n }\n}\n", "/**\n * CodeQL learning resources utilities\n */\n\nimport { readFileSync } from 'fs';\nimport { join, dirname } from 'path';\nimport { fileURLToPath } from 'url';\n\nconst __filename = fileURLToPath(import.meta.url);\nconst __dirname = dirname(__filename);\n\n/**\n * Get the getting started guide content\n */\nexport function getGettingStartedGuide(): string {\n try {\n return readFileSync(join(__dirname, '../resources/getting-started.md'), 'utf-8');\n } catch {\n return 'Getting started guide not available';\n }\n}\n\n/**\n * Get the query basics guide content\n */\nexport function getQueryBasicsGuide(): string {\n try {\n return readFileSync(join(__dirname, '../resources/query-basics.md'), 'utf-8');\n } catch {\n return 'Query basics guide not available';\n }\n}\n\n/**\n * Get the security templates content\n */\nexport function getSecurityTemplates(): string {\n try {\n return readFileSync(join(__dirname, '../resources/security-templates.md'), 'utf-8');\n } catch {\n return 'Security templates not available';\n }\n}\n\n/**\n * Get the performance patterns content\n */\nexport function getPerformancePatterns(): string {\n try {\n return readFileSync(join(__dirname, '../resources/performance-patterns.md'), 'utf-8');\n } catch {\n return 'Performance patterns not available';\n }\n}", "/**\n * CodeQL resources registration for MCP server\n */\n\nimport { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport {\n getGettingStartedGuide,\n getQueryBasicsGuide,\n getSecurityTemplates,\n getPerformancePatterns,\n} from '../lib/resources';\n\n/**\n * Register all CodeQL resources with the MCP server\n */\nexport function registerCodeQLResources(server: McpServer): void {\n // Getting Started Guide\n server.resource(\n 'CodeQL Getting Started',\n 'codeql://learning/getting-started',\n {\n description: 'Comprehensive introduction to CodeQL for beginners',\n mimeType: 'text/markdown',\n },\n async () => {\n return {\n contents: [\n {\n uri: 'codeql://learning/getting-started',\n mimeType: 'text/markdown',\n text: getGettingStartedGuide(),\n },\n ],\n };\n }\n );\n\n // Query Basics Guide\n server.resource(\n 'CodeQL Query Basics',\n 'codeql://learning/query-basics',\n {\n description: 'Learn the fundamentals of writing CodeQL queries',\n mimeType: 'text/markdown',\n },\n async () => {\n return {\n contents: [\n {\n uri: 'codeql://learning/query-basics',\n mimeType: 'text/markdown',\n text: getQueryBasicsGuide(),\n },\n ],\n };\n }\n );\n\n // Security Templates\n server.resource(\n 'CodeQL Security Templates',\n 'codeql://templates/security',\n {\n description: 'Ready-to-use security query templates',\n mimeType: 'text/markdown',\n },\n async () => {\n return {\n contents: [\n {\n uri: 'codeql://templates/security',\n mimeType: 'text/markdown',\n text: getSecurityTemplates(),\n },\n ],\n };\n }\n );\n\n // Performance Patterns\n server.resource(\n 'CodeQL Performance Patterns',\n 'codeql://patterns/performance',\n {\n description: 'Best practices for writing efficient CodeQL queries',\n mimeType: 'text/markdown',\n },\n async () => {\n return {\n contents: [\n {\n uri: 'codeql://patterns/performance',\n mimeType: 'text/markdown',\n text: getPerformancePatterns(),\n },\n ],\n };\n }\n );\n}\n", "/**\n * CodeQL LSP Diagnostics tool for MCP server.\n *\n * Provides real-time QL code validation through LSP communication.\n * Renamed from `codeql_language_server_eval` to `codeql_lsp_diagnostics`\n * for consistency with the `codeql_lsp_*` tool naming convention.\n */\n\nimport { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport { z } from 'zod';\nimport { Diagnostic, LanguageServerOptions } from '../../lib/language-server';\nimport { logger } from '../../utils/logger';\nimport { getProjectTmpDir } from '../../utils/temp-dir';\nimport { join } from 'path';\nimport { pathToFileURL } from 'url';\nimport { getInitializedLanguageServer } from './lsp-server-helper';\n\nexport interface LspDiagnosticsParams {\n qlCode: string;\n serverOptions?: LanguageServerOptions;\n workspaceUri?: string;\n}\n\nexport interface LspDiagnosticsResult {\n diagnostics: Diagnostic[];\n formattedOutput: string;\n isValid: boolean;\n summary: {\n errorCount: number;\n hintCount: number;\n infoCount: number;\n warningCount: number;\n };\n}\n\n/**\n * Format diagnostics for human-readable output.\n */\nfunction formatDiagnostics(diagnostics: Diagnostic[]): string {\n if (diagnostics.length === 0) {\n return '\u2705 No issues found in QL code';\n }\n\n const lines: string[] = [];\n lines.push(`Found ${diagnostics.length} issue(s):\\n`);\n\n diagnostics.forEach((diagnostic, index) => {\n const severityIcon = getSeverityIcon(diagnostic.severity);\n const severityName = getSeverityName(diagnostic.severity);\n const location = `Line ${diagnostic.range.start.line + 1}, Column ${diagnostic.range.start.character + 1}`;\n\n lines.push(`${index + 1}. ${severityIcon} ${severityName} at ${location}`);\n lines.push(` ${diagnostic.message}`);\n if (diagnostic.source) {\n lines.push(` Source: ${diagnostic.source}`);\n }\n if (diagnostic.code) {\n lines.push(` Code: ${diagnostic.code}`);\n }\n lines.push('');\n });\n\n return lines.join('\\n');\n}\n\nfunction getSeverityIcon(severity: number): string {\n switch (severity) {\n case 1: return '\u274C'; // Error\n case 2: return '\u26A0\uFE0F'; // Warning\n case 3: return '\u2139\uFE0F'; // Information\n case 4: return '\uD83D\uDCA1'; // Hint\n default: return '\u2753';\n }\n}\n\nfunction getSeverityName(severity: number): string {\n switch (severity) {\n case 1: return 'Error';\n case 2: return 'Warning';\n case 3: return 'Information';\n case 4: return 'Hint';\n default: return 'Unknown';\n }\n}\n\n/**\n * Evaluate QL code using the CodeQL Language Server and return diagnostics.\n */\nexport async function lspDiagnostics({\n qlCode,\n workspaceUri,\n serverOptions = {}\n}: LspDiagnosticsParams): Promise {\n try {\n logger.info('Evaluating QL code via Language Server...');\n\n const languageServer = await getInitializedLanguageServer({\n serverOptions,\n workspaceUri,\n });\n\n // Generate unique URI for this evaluation\n const evalUri = pathToFileURL(join(getProjectTmpDir('lsp-eval'), `eval_${Date.now()}.ql`)).href;\n\n const diagnostics = await languageServer.evaluateQL(qlCode, evalUri);\n\n // Count diagnostics by severity\n const summary = {\n errorCount: diagnostics.filter(d => d.severity === 1).length,\n hintCount: diagnostics.filter(d => d.severity === 4).length,\n infoCount: diagnostics.filter(d => d.severity === 3).length,\n warningCount: diagnostics.filter(d => d.severity === 2).length,\n };\n\n const isValid = summary.errorCount === 0;\n const formattedOutput = formatDiagnostics(diagnostics);\n\n logger.info(`QL evaluation complete. Valid: ${isValid}, Issues: ${diagnostics.length}`);\n\n return {\n diagnostics,\n formattedOutput,\n isValid,\n summary,\n };\n\n } catch (error) {\n logger.error('Error evaluating QL code:', error);\n throw new Error(`QL evaluation failed: ${error instanceof Error ? error.message : 'Unknown error'}`);\n }\n}\n\n/**\n * Shutdown the language server via the server manager.\n */\nexport async function shutdownDiagnosticsServer(): Promise {\n const { getServerManager } = await import('../../lib/server-manager');\n const manager = getServerManager();\n await manager.shutdownServer('language');\n}\n\n/**\n * Register the codeql_lsp_diagnostics tool with the MCP server.\n */\nexport function registerLspDiagnosticsTool(server: McpServer): void {\n server.tool(\n 'codeql_lsp_diagnostics',\n 'Authoritative syntax and semantic validation of CodeQL (QL) code via the CodeQL Language Server. Compiles the query and provides real-time diagnostics with precise error locations. Use this for accurate validation; for quick heuristic checks without compilation, use validate_codeql_query instead. Note: inline ql_code is evaluated as a virtual document and cannot resolve pack imports (e.g. `import javascript`). For validating queries with imports, use codeql_query_compile on the actual file instead.',\n {\n log_level: z.enum(['OFF', 'ERROR', 'WARN', 'INFO', 'DEBUG', 'TRACE', 'ALL']).optional().describe('Language server log level'),\n ql_code: z.string().describe('The CodeQL (QL) code to evaluate for syntax and semantic errors'),\n search_path: z.string().optional().describe('Optional search path for CodeQL libraries'),\n workspace_uri: z.string().optional().describe('Optional workspace URI for context (defaults to ./ql directory)'),\n },\n async ({ ql_code, workspace_uri, search_path, log_level }) => {\n try {\n const serverOptions: LanguageServerOptions = {};\n\n if (search_path) {\n serverOptions.searchPath = search_path;\n }\n if (log_level) {\n serverOptions.loglevel = log_level;\n }\n\n const result = await lspDiagnostics({\n qlCode: ql_code,\n serverOptions,\n workspaceUri: workspace_uri,\n });\n\n // Return structured result\n const responseContent = {\n diagnostics: result.diagnostics.map(d => ({\n code: d.code,\n column: d.range.start.character + 1, // Convert to 1-based column numbers\n line: d.range.start.line + 1, // Convert to 1-based line numbers\n message: d.message,\n severity: getSeverityName(d.severity),\n source: d.source,\n })),\n formattedOutput: result.formattedOutput,\n isValid: result.isValid,\n summary: result.summary,\n };\n\n return {\n content: [\n {\n text: JSON.stringify(responseContent, null, 2),\n type: 'text',\n }\n ],\n };\n\n } catch (error) {\n logger.error('Error in codeql_lsp_diagnostics tool:', error);\n return {\n content: [\n {\n text: `Error: ${error instanceof Error ? error.message : 'Unknown error'}`,\n type: 'text',\n },\n ],\n isError: true,\n };\n }\n }\n );\n\n // NOTE: Cleanup is handled centrally by shutdownServerManager() in\n // codeql-development-mcp-server.ts (setupGracefulShutdown). Registering\n // additional process.on('SIGINT'/'SIGTERM') handlers here would\n // accumulate on repeated calls and is unnecessary.\n}\n", "/**\n * Shared helper for obtaining a running, initialized CodeQL Language Server.\n *\n * Both `lsp-diagnostics.ts` and `lsp-handlers.ts` need to:\n * 1. Build a `LanguageServerConfig` with sensible defaults\n * 2. Obtain a server instance from the `CodeQLServerManager`\n * 3. Resolve a workspace URI (relative \u2192 absolute \u2192 `file://`)\n * 4. Initialize the server with the resolved workspace\n *\n * Centralizing this logic avoids duplication and ensures consistent\n * default behaviour across all LSP tools.\n */\n\nimport { isAbsolute, resolve } from 'path';\nimport { pathToFileURL } from 'url';\n\nimport { CodeQLLanguageServer, LanguageServerOptions } from '../../lib/language-server';\nimport { LanguageServerConfig } from '../../lib/server-config';\nimport { getServerManager } from '../../lib/server-manager';\nimport { logger } from '../../utils/logger';\n\n/**\n * Options accepted by {@link getInitializedLanguageServer}.\n */\nexport interface InitializedServerOptions {\n /** Language-server-level options (loglevel, searchPath, etc.). */\n serverOptions?: LanguageServerOptions;\n /** Workspace URI \u2014 may be a `file://` URI, absolute path, or relative path. */\n workspaceUri?: string;\n}\n\n/**\n * Return a running, initialized `CodeQLLanguageServer`.\n *\n * - Resolves `searchPath` to the bundled `ql` directory when not provided.\n * - Converts relative / bare-directory `workspaceUri` paths to `file://` URIs\n * resolved against `getUserWorkspaceDir()` (respects `CODEQL_MCP_WORKSPACE`).\n * - Falls back to the bundled `ql` directory when no workspace is given.\n * - Delegates lifecycle management to the global `CodeQLServerManager`.\n */\nexport async function getInitializedLanguageServer(\n opts: InitializedServerOptions = {},\n): Promise {\n const { packageRootDir: pkgRoot, getUserWorkspaceDir } = await import('../../utils/package-paths');\n const options = opts.serverOptions ?? {};\n\n const config: LanguageServerConfig = {\n checkErrors: 'ON_CHANGE',\n loglevel: options.loglevel ?? 'WARN',\n searchPath: options.searchPath ?? resolve(pkgRoot, 'ql'),\n synchronous: options.synchronous,\n verbosity: options.verbosity,\n };\n\n const manager = getServerManager();\n const server = await manager.getLanguageServer(config);\n\n // Normalize workspace URI: convert relative / bare directory paths to\n // file:// URIs against getUserWorkspaceDir() (respects CODEQL_MCP_WORKSPACE).\n let effectiveUri = opts.workspaceUri;\n if (effectiveUri && !effectiveUri.startsWith('file://')) {\n const absWorkspace = isAbsolute(effectiveUri)\n ? effectiveUri\n : resolve(getUserWorkspaceDir(), effectiveUri);\n effectiveUri = pathToFileURL(absWorkspace).href;\n }\n effectiveUri = effectiveUri ?? pathToFileURL(resolve(pkgRoot, 'ql')).href;\n\n await server.initialize(effectiveUri);\n logger.debug(`Language server initialized with workspace: ${effectiveUri}`);\n\n return server;\n}\n", "/**\n * CodeQL LSP tool handlers.\n *\n * Bridges MCP tool invocations to LSP requests on the CodeQL Language Server.\n * Each handler acquires a language server via the CodeQLServerManager,\n * opens the requested document, sends the LSP request, and returns the result.\n */\n\nimport { readFile } from 'fs/promises';\nimport { isAbsolute, resolve } from 'path';\nimport { pathToFileURL } from 'url';\n\nimport {\n CompletionItem,\n LSPLocation,\n TextDocumentPositionParams,\n} from '../../lib/language-server';\nimport { logger } from '../../utils/logger';\nimport { getUserWorkspaceDir } from '../../utils/package-paths';\nimport { getInitializedLanguageServer } from './lsp-server-helper';\n\n/**\n * Common parameters for LSP tool invocations.\n */\nexport interface LSPToolParams {\n /** 0-based character offset within the line. */\n character: number;\n /** Optional override for the file content (if not reading from disk). */\n fileContent?: string;\n /**\n * Path to the QL file. May be absolute or relative.\n * Relative paths are resolved against `getUserWorkspaceDir()`\n * (respects the `CODEQL_MCP_WORKSPACE` environment variable).\n */\n filePath: string;\n /** 0-based line number in the document. */\n line: number;\n /** Optional search path for CodeQL libraries. */\n searchPath?: string;\n /** Optional workspace URI for context. */\n workspaceUri?: string;\n}\n\n/**\n * Get a running, initialized language server for the given parameters.\n */\nasync function getInitializedServer(params: LSPToolParams) {\n return getInitializedLanguageServer({\n serverOptions: { searchPath: params.searchPath },\n workspaceUri: params.workspaceUri,\n });\n}\n\n/**\n * Resolve the file path to an absolute path and file:// URI.\n */\nfunction prepareDocumentPosition(\n params: LSPToolParams,\n): { absPath: string; docUri: string } {\n // Resolve relative paths against getUserWorkspaceDir() so that\n // CODEQL_MCP_WORKSPACE is respected and behaviour is consistent across tools.\n const absPath = isAbsolute(params.filePath)\n ? params.filePath\n : resolve(getUserWorkspaceDir(), params.filePath);\n const docUri = pathToFileURL(absPath).href;\n\n return { absPath, docUri };\n}\n\n/**\n * Read file content and open the document in the language server.\n */\nasync function openDocumentForPosition(\n server: Awaited>,\n params: LSPToolParams,\n absPath: string,\n docUri: string,\n): Promise {\n // Read file content from disk or use provided content\n let text: string;\n if (params.fileContent) {\n text = params.fileContent;\n } else {\n try {\n text = await readFile(absPath, 'utf-8');\n } catch (error) {\n throw new Error(`Cannot read file: ${absPath}: ${error instanceof Error ? error.message : error}`);\n }\n }\n\n // Open the document so the language server knows about it\n server.openDocument(docUri, text);\n\n return {\n position: { character: params.character, line: params.line },\n textDocument: { uri: docUri },\n };\n}\n\n/**\n * Get code completions at a position.\n */\nexport async function lspCompletion(params: LSPToolParams): Promise {\n logger.info(`LSP completion at ${params.filePath}:${params.line}:${params.character}`);\n const server = await getInitializedServer(params);\n const { absPath, docUri } = prepareDocumentPosition(params);\n const positionParams = await openDocumentForPosition(server, params, absPath, docUri);\n\n try {\n return await server.getCompletions(positionParams);\n } finally {\n server.closeDocument(docUri);\n }\n}\n\n/**\n * Go to definition of a symbol at a position.\n */\nexport async function lspDefinition(params: LSPToolParams): Promise {\n logger.info(`LSP definition at ${params.filePath}:${params.line}:${params.character}`);\n const server = await getInitializedServer(params);\n const { absPath, docUri } = prepareDocumentPosition(params);\n const positionParams = await openDocumentForPosition(server, params, absPath, docUri);\n\n try {\n return await server.getDefinition(positionParams);\n } finally {\n server.closeDocument(docUri);\n }\n}\n\n/**\n * Find all references to a symbol at a position.\n */\nexport async function lspReferences(params: LSPToolParams): Promise {\n logger.info(`LSP references at ${params.filePath}:${params.line}:${params.character}`);\n const server = await getInitializedServer(params);\n const { absPath, docUri } = prepareDocumentPosition(params);\n const positionParams = await openDocumentForPosition(server, params, absPath, docUri);\n\n try {\n return await server.getReferences({\n ...positionParams,\n context: { includeDeclaration: true },\n });\n } finally {\n server.closeDocument(docUri);\n }\n}\n", "/**\n * CodeQL LSP MCP tool definitions.\n *\n * Registers four LSP-based tools:\n * - codeql_lsp_completion \u2013 code completions at cursor position\n * - codeql_lsp_definition \u2013 go to definition\n * - codeql_lsp_diagnostics \u2013 QL code validation via LSP diagnostics\n * - codeql_lsp_references \u2013 find all references\n */\n\nimport { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport { z } from 'zod';\nimport { registerLspDiagnosticsTool } from './lsp-diagnostics';\nimport {\n lspCompletion,\n lspDefinition,\n lspReferences,\n} from './lsp-handlers';\nimport { logger } from '../../utils/logger';\n\n/**\n * Shared Zod schema for the common LSP tool parameters.\n */\nconst lspParamsSchema = {\n character: z.number().int().min(0).describe('0-based character offset within the line'),\n file_content: z.string().optional().describe('Optional file content override (reads from disk if omitted)'),\n file_path: z.string().describe('Path to the CodeQL (.ql/.qll) file. Relative paths are resolved against the user workspace directory (see CODEQL_MCP_WORKSPACE).'),\n line: z.number().int().min(0).describe('0-based line number in the document'),\n search_path: z.string().optional().describe('Optional search path for CodeQL libraries'),\n workspace_uri: z.string().optional().describe('Optional workspace URI for context (defaults to ./ql directory)'),\n};\n\n/**\n * Helper to build the handler params from the raw MCP tool input.\n */\nfunction toHandlerParams(input: {\n character: number;\n file_content?: string;\n file_path: string;\n line: number;\n search_path?: string;\n workspace_uri?: string;\n}) {\n return {\n character: input.character,\n fileContent: input.file_content,\n filePath: input.file_path,\n line: input.line,\n searchPath: input.search_path,\n workspaceUri: input.workspace_uri,\n };\n}\n\n/**\n * Register all LSP-based tools with the MCP server.\n */\nexport function registerLSPTools(server: McpServer): void {\n // --- codeql_lsp_diagnostics (relocated from codeql_language_server_eval) ---\n registerLspDiagnosticsTool(server);\n\n // --- codeql_lsp_completion ---\n server.tool(\n 'codeql_lsp_completion',\n 'Get code completions at a cursor position in a CodeQL file. Returns completion items with labels, documentation, and insert text. The file must be a .ql or .qll file. IMPORTANT: Set workspace_uri to the pack or workspace root directory for dependency resolution; without it, completions for imported libraries will be empty.',\n lspParamsSchema,\n async (input) => {\n try {\n const items = await lspCompletion(toHandlerParams(input));\n return {\n content: [{\n text: JSON.stringify({\n completionCount: items.length,\n items: items.map((item) => ({\n detail: item.detail,\n documentation: item.documentation,\n insertText: item.insertText,\n kind: item.kind,\n label: item.label,\n })),\n }, null, 2),\n type: 'text' as const,\n }],\n };\n } catch (error) {\n logger.error('codeql_lsp_completion error:', error);\n return {\n content: [{ text: `Error: ${error instanceof Error ? error.message : 'Unknown error'}`, type: 'text' as const }],\n isError: true,\n };\n }\n },\n );\n\n // --- codeql_lsp_definition ---\n server.tool(\n 'codeql_lsp_definition',\n 'Go to the definition of a CodeQL symbol at a given position. Returns one or more file locations where the symbol is defined. Set workspace_uri to the pack root for dependency resolution.',\n lspParamsSchema,\n async (input) => {\n try {\n const locations = await lspDefinition(toHandlerParams(input));\n return {\n content: [{\n text: JSON.stringify({\n definitionCount: locations.length,\n locations: locations.map((loc) => ({\n endCharacter: loc.range.end.character,\n endLine: loc.range.end.line + 1,\n startCharacter: loc.range.start.character,\n startLine: loc.range.start.line + 1,\n uri: loc.uri,\n })),\n }, null, 2),\n type: 'text' as const,\n }],\n };\n } catch (error) {\n logger.error('codeql_lsp_definition error:', error);\n return {\n content: [{ text: `Error: ${error instanceof Error ? error.message : 'Unknown error'}`, type: 'text' as const }],\n isError: true,\n };\n }\n },\n );\n\n // --- codeql_lsp_references ---\n server.tool(\n 'codeql_lsp_references',\n 'Find all references to a CodeQL symbol at a given position. Returns file locations of all usages, including the declaration. Set workspace_uri to the pack root for dependency resolution.',\n lspParamsSchema,\n async (input) => {\n try {\n const locations = await lspReferences(toHandlerParams(input));\n return {\n content: [{\n text: JSON.stringify({\n locations: locations.map((loc) => ({\n endCharacter: loc.range.end.character,\n endLine: loc.range.end.line + 1,\n startCharacter: loc.range.start.character,\n startLine: loc.range.start.line + 1,\n uri: loc.uri,\n })),\n referenceCount: locations.length,\n }, null, 2),\n type: 'text' as const,\n }],\n };\n } catch (error) {\n logger.error('codeql_lsp_references error:', error);\n return {\n content: [{ text: `Error: ${error instanceof Error ? error.message : 'Unknown error'}`, type: 'text' as const }],\n isError: true,\n };\n }\n },\n );\n}\n", "/**\n * Language-specific resources implementation\n * Dynamically loads and serves language-specific AST references and security patterns\n */\n\nimport { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport { readFileSync, existsSync } from 'fs';\nimport { join } from 'path';\nimport { LANGUAGE_RESOURCES } from '../types/language-types';\nimport { workspaceRootDir } from '../utils/package-paths';\nimport { logger } from '../utils/logger';\n\n/**\n * Get the base path for ql resources.\n * Uses the workspace root (monorepo root or package root) so that\n * resource files are found regardless of the server's process.cwd().\n */\nfunction getQLBasePath(): string {\n return workspaceRootDir;\n}\n\n/**\n * Load content from a resource file\n */\nfunction loadResourceContent(relativePath: string): string | null {\n try {\n const fullPath = join(getQLBasePath(), relativePath);\n \n if (!existsSync(fullPath)) {\n logger.warn(`Resource file not found: ${fullPath}`);\n return null;\n }\n \n return readFileSync(fullPath, 'utf-8');\n } catch (error) {\n logger.error(`Error loading resource file ${relativePath}:`, error);\n return null;\n }\n}\n\n/**\n * Register language-specific AST resources\n */\nexport function registerLanguageASTResources(server: McpServer): void {\n for (const langResource of LANGUAGE_RESOURCES) {\n if (!langResource.astFile) continue;\n \n const resourceUri = `codeql://languages/${langResource.language}/ast`;\n \n server.resource(\n `${langResource.language.toUpperCase()} AST Reference`,\n resourceUri,\n {\n description: `CodeQL AST class reference for ${langResource.language} programs`,\n mimeType: 'text/markdown'\n },\n async () => {\n const content = loadResourceContent(langResource.astFile!);\n \n if (!content) {\n return {\n contents: [{\n uri: resourceUri,\n mimeType: 'text/markdown',\n text: `# ${langResource.language.toUpperCase()} AST Reference\\n\\nResource file not found or could not be loaded.`\n }]\n };\n }\n \n return {\n contents: [{\n uri: resourceUri,\n mimeType: 'text/markdown',\n text: content\n }]\n };\n }\n );\n }\n}\n\n/**\n * Register language-specific security pattern resources\n */\nexport function registerLanguageSecurityResources(server: McpServer): void {\n for (const langResource of LANGUAGE_RESOURCES) {\n if (!langResource.securityFile) continue;\n \n const resourceUri = `codeql://languages/${langResource.language}/security`;\n \n server.resource(\n `${langResource.language.toUpperCase()} Security Patterns`,\n resourceUri,\n {\n description: `CodeQL security query patterns and framework modeling for ${langResource.language}`,\n mimeType: 'text/markdown'\n },\n async () => {\n const content = loadResourceContent(langResource.securityFile!);\n \n if (!content) {\n return {\n contents: [{\n uri: resourceUri,\n mimeType: 'text/markdown',\n text: `# ${langResource.language.toUpperCase()} Security Patterns\\n\\nResource file not found or could not be loaded.`\n }]\n };\n }\n \n return {\n contents: [{\n uri: resourceUri,\n mimeType: 'text/markdown',\n text: content\n }]\n };\n }\n );\n }\n}\n\n/**\n * Register additional language-specific resources (like Go's dataflow patterns)\n */\nexport function registerLanguageAdditionalResources(server: McpServer): void {\n for (const langResource of LANGUAGE_RESOURCES) {\n if (!langResource.additionalFiles) continue;\n \n for (const [resourceType, filePath] of Object.entries(langResource.additionalFiles)) {\n const resourceUri = `codeql://languages/${langResource.language}/${resourceType}`;\n \n server.resource(\n `${langResource.language.toUpperCase()} ${resourceType.replace('-', ' ').replace(/\\b\\w/g, l => l.toUpperCase())}`,\n resourceUri,\n {\n description: `CodeQL ${resourceType.replace('-', ' ')} guide for ${langResource.language}`,\n mimeType: 'text/markdown'\n },\n async () => {\n const content = loadResourceContent(filePath);\n \n if (!content) {\n return {\n contents: [{\n uri: resourceUri,\n mimeType: 'text/markdown',\n text: `# ${langResource.language.toUpperCase()} ${resourceType.replace('-', ' ').replace(/\\b\\w/g, l => l.toUpperCase())}\\n\\nResource file not found or could not be loaded.`\n }]\n };\n }\n \n return {\n contents: [{\n uri: resourceUri,\n mimeType: 'text/markdown',\n text: content\n }]\n };\n }\n );\n }\n }\n}\n\n/**\n * Register all language-specific resources\n */\nexport function registerLanguageResources(server: McpServer): void {\n logger.info('Registering language-specific resources...');\n \n // Register AST references for all languages\n registerLanguageASTResources(server);\n \n // Register security patterns for languages that have them\n registerLanguageSecurityResources(server);\n \n // Register additional resources (like Go's dataflow patterns)\n registerLanguageAdditionalResources(server);\n \n logger.info(`Registered resources for ${LANGUAGE_RESOURCES.length} languages`);\n}", "/**\n * Type definitions and constants for language-specific resources\n */\n\n// Language mappings to resource files\nexport interface LanguageResource {\n language: string;\n astFile?: string;\n securityFile?: string;\n additionalFiles?: Record;\n}\n\nexport const LANGUAGE_RESOURCES: LanguageResource[] = [\n {\n language: 'actions',\n astFile: 'ql/languages/actions/tools/dev/actions_ast.prompt.md'\n },\n {\n language: 'cpp',\n astFile: 'ql/languages/cpp/tools/dev/cpp_ast.prompt.md',\n securityFile: 'ql/languages/cpp/tools/dev/cpp_security_query_guide.prompt.md'\n },\n {\n language: 'csharp',\n astFile: 'ql/languages/csharp/tools/dev/csharp_ast.prompt.md',\n securityFile: 'ql/languages/csharp/tools/dev/csharp_security_query_guide.prompt.md'\n },\n {\n language: 'go',\n astFile: 'ql/languages/go/tools/dev/go_ast.prompt.md',\n securityFile: 'ql/languages/go/tools/dev/go_security_query_guide.prompt.md',\n additionalFiles: {\n 'dataflow': 'ql/languages/go/tools/dev/go_dataflow.prompt.md',\n 'library-modeling': 'ql/languages/go/tools/dev/go_library_modeling.prompt.md',\n 'basic-queries': 'ql/languages/go/tools/dev/go_basic_queries.prompt.md'\n }\n },\n {\n language: 'java',\n astFile: 'ql/languages/java/tools/dev/java_ast.prompt.md'\n },\n {\n language: 'javascript',\n astFile: 'ql/languages/javascript/tools/dev/javascript_ast.prompt.md',\n securityFile: 'ql/languages/javascript/tools/dev/javascript_security_query_guide.prompt.md'\n },\n {\n language: 'python',\n astFile: 'ql/languages/python/tools/dev/python_ast.prompt.md',\n securityFile: 'ql/languages/python/tools/dev/python_security_query_guide.prompt.md'\n },\n {\n language: 'ql',\n astFile: 'ql/languages/ql/tools/dev/ql_ast.prompt.md'\n },\n {\n language: 'ruby',\n astFile: 'ql/languages/ruby/tools/dev/ruby_ast.prompt.md'\n }\n];", "/**\n * MCP Server workflow prompts for CodeQL development\n *\n * All prompt content is loaded from .prompt.md files in this directory.\n * This file only handles prompt registration and parameter processing.\n */\n\nimport { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport { z } from 'zod';\nimport { basename } from 'path';\nimport { loadPromptTemplate, processPromptTemplate } from './prompt-loader';\nimport { logger } from '../utils/logger';\n\n/** Supported CodeQL languages for tools queries */\nexport const SUPPORTED_LANGUAGES = [\n 'actions',\n 'cpp',\n 'csharp',\n 'go',\n 'java',\n 'javascript',\n 'python',\n 'ruby',\n 'swift'\n] as const;\n\n// \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n// Exported parameter schemas for each workflow prompt.\n//\n// Extracting the schemas makes it easy to unit-test required vs optional\n// validation independently of the MCP server registration.\n//\n// **Convention for VS Code UX consistency**:\n// Every prompt MUST expose at least one parameter \u2013 even if all parameters\n// are optional \u2013 so that VS Code always displays the parameter input dialog\n// and allows the user to customize the prompt before Copilot Chat processes\n// it. The `description` field on each Zod schema member doubles as the\n// placeholder text shown in the VS Code input box.\n// \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n/**\n * Schema for test_driven_development prompt parameters.\n *\n * - `language` is **required** \u2013 the TDD workflow is language-specific.\n * - `queryName` is optional \u2013 defaults to '[QueryName]' if omitted.\n */\nexport const testDrivenDevelopmentSchema = z.object({\n language: z\n .enum(SUPPORTED_LANGUAGES)\n .describe('Programming language for the query'),\n queryName: z\n .string()\n .optional()\n .describe('Name of the query to develop'),\n});\n\n/**\n * Schema for tools_query_workflow prompt parameters.\n *\n * - `language` and `database` are **required**.\n * - `sourceFiles`, `sourceFunction`, `targetFunction` are optional context.\n */\nexport const toolsQueryWorkflowSchema = z.object({\n database: z\n .string()\n .describe('Path to the CodeQL database'),\n language: z\n .enum(SUPPORTED_LANGUAGES)\n .describe('Programming language for the tools queries'),\n sourceFiles: z\n .string()\n .optional()\n .describe('Comma-separated source file names for PrintAST (e.g., \"main.js,utils.js\")'),\n sourceFunction: z\n .string()\n .optional()\n .describe('Function name for PrintCFG or CallGraphFrom (e.g., \"processData\")'),\n targetFunction: z\n .string()\n .optional()\n .describe('Function name for CallGraphTo (e.g., \"validate\")'),\n});\n\n/**\n * Schema for workshop_creation_workflow prompt parameters.\n * Uses z.coerce.number() for numStages to handle string inputs from VSCode slash commands.\n *\n * - `queryPath` and `language` are **required**.\n * - `workshopName` and `numStages` are optional.\n */\nexport const workshopCreationWorkflowSchema = z.object({\n queryPath: z\n .string()\n .describe('Path to the production-grade CodeQL query (.ql or .qlref)'),\n language: z\n .enum(SUPPORTED_LANGUAGES)\n .describe('Programming language of the query'),\n workshopName: z\n .string()\n .optional()\n .describe('Name for the workshop directory'),\n numStages: z\n .coerce.number()\n .optional()\n .describe('Number of incremental stages (default: 4-8)'),\n});\n\n/**\n * Schema for ql_tdd_basic prompt parameters.\n *\n * All parameters are optional \u2013 but at least one should be present so the\n * VS Code quick-pick dialog appears.\n */\nexport const qlTddBasicSchema = z.object({\n language: z\n .enum(SUPPORTED_LANGUAGES)\n .optional()\n .describe('Programming language for the query (optional)'),\n queryName: z\n .string()\n .optional()\n .describe('Name of the query to develop'),\n});\n\n/**\n * Schema for ql_tdd_advanced prompt parameters.\n *\n * All parameters are optional.\n */\nexport const qlTddAdvancedSchema = z.object({\n database: z\n .string()\n .optional()\n .describe('Path to the CodeQL database for analysis'),\n language: z\n .enum(SUPPORTED_LANGUAGES)\n .optional()\n .describe('Programming language for the query (optional)'),\n queryName: z\n .string()\n .optional()\n .describe('Name of the query to develop'),\n});\n\n/**\n * Schema for sarif_rank_false_positives / sarif_rank_true_positives.\n *\n * Both parameters are optional.\n */\nexport const sarifRankSchema = z.object({\n queryId: z\n .string()\n .optional()\n .describe('CodeQL query/rule identifier'),\n sarifPath: z\n .string()\n .optional()\n .describe('Path to the SARIF file to analyze'),\n});\n\n/**\n * Schema for explain_codeql_query prompt parameters.\n *\n * - `queryPath` and `language` are **required**.\n * - `databasePath` is optional.\n */\nexport const explainCodeqlQuerySchema = z.object({\n databasePath: z\n .string()\n .optional()\n .describe('Optional path to a real CodeQL database for profiling'),\n language: z\n .enum(SUPPORTED_LANGUAGES)\n .describe('Programming language of the query'),\n queryPath: z\n .string()\n .describe('Path to the CodeQL query file (.ql or .qlref)'),\n});\n\n/**\n * Schema for document_codeql_query prompt parameters.\n *\n * - `queryPath` and `language` are **required**.\n */\nexport const documentCodeqlQuerySchema = z.object({\n language: z\n .enum(SUPPORTED_LANGUAGES)\n .describe('Programming language of the query'),\n queryPath: z\n .string()\n .describe('Path to the CodeQL query file (.ql or .qlref)'),\n});\n\n/**\n * Schema for ql_lsp_iterative_development prompt parameters.\n *\n * All parameters are optional.\n */\nexport const qlLspIterativeDevelopmentSchema = z.object({\n language: z\n .enum(SUPPORTED_LANGUAGES)\n .optional()\n .describe('Programming language for the query'),\n queryPath: z\n .string()\n .optional()\n .describe('Path to the query file being developed'),\n workspaceUri: z\n .string()\n .optional()\n .describe('Workspace URI for LSP dependency resolution'),\n});\n\n// \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n// Prompt names (exported for testing)\n// \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n/** Names of every workflow prompt registered with the MCP server. */\nexport const WORKFLOW_PROMPT_NAMES = [\n 'document_codeql_query',\n 'explain_codeql_query',\n 'ql_lsp_iterative_development',\n 'ql_tdd_advanced',\n 'ql_tdd_basic',\n 'sarif_rank_false_positives',\n 'sarif_rank_true_positives',\n 'test_driven_development',\n 'tools_query_workflow',\n 'workshop_creation_workflow',\n] as const;\n\n/**\n * Register MCP workflow prompts\n *\n * Each prompt loads its content from a corresponding .prompt.md file\n * and processes any parameter substitutions.\n *\n * **UX note**: Every prompt schema is passed to `server.prompt()` so that\n * VS Code always displays the parameter-input quick-pick before the prompt\n * is sent to Copilot Chat. This lets users review and customise the values.\n */\nexport function registerWorkflowPrompts(server: McpServer): void {\n // Test-Driven Development Prompt\n server.prompt(\n 'test_driven_development',\n 'Test-driven development workflow for CodeQL queries using MCP tools',\n testDrivenDevelopmentSchema.shape,\n async ({ language, queryName }) => {\n const template = loadPromptTemplate('ql-tdd-basic.prompt.md');\n const content = processPromptTemplate(template, {\n language,\n queryName: queryName || '[QueryName]'\n });\n\n return {\n messages: [\n {\n role: 'user',\n content: {\n type: 'text',\n text: `## Context\\n\\n- **Language**: ${language}\\n${queryName ? `- **Query Name**: ${queryName}\\n` : ''}\\n${content}`\n }\n }\n ]\n };\n }\n );\n\n // Tools Query Workflow Prompt\n server.prompt(\n 'tools_query_workflow',\n 'Guide for using built-in tools queries (PrintAST, PrintCFG, CallGraphFrom, CallGraphTo) to understand code structure',\n toolsQueryWorkflowSchema.shape,\n async ({\n language,\n database,\n sourceFiles,\n sourceFunction,\n targetFunction\n }) => {\n const template = loadPromptTemplate('tools-query-workflow.prompt.md');\n const content = processPromptTemplate(template, {\n language,\n database\n });\n\n const contextSection = buildToolsQueryContext(\n language,\n database,\n sourceFiles,\n sourceFunction,\n targetFunction\n );\n\n return {\n messages: [\n {\n role: 'user',\n content: {\n type: 'text',\n text: contextSection + content\n }\n }\n ]\n };\n }\n );\n\n // Workshop Creation Workflow Prompt\n server.prompt(\n 'workshop_creation_workflow',\n 'Guide for creating CodeQL query development workshops from production-grade queries',\n workshopCreationWorkflowSchema.shape,\n async ({ queryPath, language, workshopName, numStages }) => {\n const template = loadPromptTemplate('workshop-creation-workflow.prompt.md');\n\n // Derive workshop name from query path if not provided\n const derivedName =\n workshopName ||\n basename(queryPath)\n .replace(/\\.(ql|qlref)$/, '')\n .toLowerCase()\n .replace(/[^a-z0-9]+/g, '-') ||\n 'codeql-workshop';\n\n const contextSection = buildWorkshopContext(\n queryPath,\n language,\n derivedName,\n numStages\n );\n\n return {\n messages: [\n {\n role: 'user',\n content: {\n type: 'text',\n text: contextSection + template\n }\n }\n ]\n };\n }\n );\n\n // TDD Basic Prompt - Test-Driven Development Checklist\n server.prompt(\n 'ql_tdd_basic',\n 'Test-driven CodeQL query development checklist - write tests first, implement query, iterate until tests pass',\n qlTddBasicSchema.shape,\n async ({ language, queryName }) => {\n const template = loadPromptTemplate('ql-tdd-basic.prompt.md');\n\n let contextSection = '## Your Development Context\\n\\n';\n if (language) {\n contextSection += `- **Language**: ${language}\\n`;\n }\n if (queryName) {\n contextSection += `- **Query Name**: ${queryName}\\n`;\n }\n if (language || queryName) {\n contextSection += '\\n';\n }\n\n return {\n messages: [\n {\n role: 'user',\n content: {\n type: 'text',\n text: contextSection + template\n }\n }\n ]\n };\n }\n );\n\n // TDD Advanced Prompt - Advanced Techniques with AST/CFG/CallGraph\n server.prompt(\n 'ql_tdd_advanced',\n 'Advanced test-driven CodeQL development with AST visualization, control flow, and call graph analysis',\n qlTddAdvancedSchema.shape,\n async ({ language, queryName, database }) => {\n const template = loadPromptTemplate('ql-tdd-advanced.prompt.md');\n\n let contextSection = '## Your Development Context\\n\\n';\n if (language) {\n contextSection += `- **Language**: ${language}\\n`;\n }\n if (queryName) {\n contextSection += `- **Query Name**: ${queryName}\\n`;\n }\n if (database) {\n contextSection += `- **Database**: ${database}\\n`;\n }\n if (language || queryName || database) {\n contextSection += '\\n';\n }\n\n return {\n messages: [\n {\n role: 'user',\n content: {\n type: 'text',\n text: contextSection + template\n }\n }\n ]\n };\n }\n );\n\n // SARIF Rank False Positives Prompt\n server.prompt(\n 'sarif_rank_false_positives',\n 'Analyze SARIF results to identify likely false positives in CodeQL query results',\n sarifRankSchema.shape,\n async ({ queryId, sarifPath }) => {\n const template = loadPromptTemplate('sarif-rank-false-positives.prompt.md');\n\n let contextSection = '## Analysis Context\\n\\n';\n if (queryId) {\n contextSection += `- **Query ID**: ${queryId}\\n`;\n }\n if (sarifPath) {\n contextSection += `- **SARIF File**: ${sarifPath}\\n`;\n }\n if (queryId || sarifPath) {\n contextSection += '\\n';\n }\n\n return {\n messages: [\n {\n role: 'user',\n content: {\n type: 'text',\n text: contextSection + template\n }\n }\n ]\n };\n }\n );\n\n // SARIF Rank True Positives Prompt\n server.prompt(\n 'sarif_rank_true_positives',\n 'Analyze SARIF results to identify likely true positives in CodeQL query results',\n sarifRankSchema.shape,\n async ({ queryId, sarifPath }) => {\n const template = loadPromptTemplate('sarif-rank-true-positives.prompt.md');\n\n let contextSection = '## Analysis Context\\n\\n';\n if (queryId) {\n contextSection += `- **Query ID**: ${queryId}\\n`;\n }\n if (sarifPath) {\n contextSection += `- **SARIF File**: ${sarifPath}\\n`;\n }\n if (queryId || sarifPath) {\n contextSection += '\\n';\n }\n\n return {\n messages: [\n {\n role: 'user',\n content: {\n type: 'text',\n text: contextSection + template\n }\n }\n ]\n };\n }\n );\n\n // Explain CodeQL Query Prompt (for workshop learning content)\n server.prompt(\n 'explain_codeql_query',\n 'Generate detailed explanation of a CodeQL query for workshop learning content - uses MCP tools to gather context and produces both verbal explanations and mermaid evaluation diagrams',\n explainCodeqlQuerySchema.shape,\n async ({ queryPath, language, databasePath }) => {\n const template = loadPromptTemplate('explain-codeql-query.prompt.md');\n\n let contextSection = '## Query to Explain\\n\\n';\n contextSection += `- **Query Path**: ${queryPath}\\n`;\n contextSection += `- **Language**: ${language}\\n`;\n if (databasePath) {\n contextSection += `- **Database Path**: ${databasePath}\\n`;\n }\n contextSection += '\\n';\n\n return {\n messages: [\n {\n role: 'user',\n content: {\n type: 'text',\n text: contextSection + template\n }\n }\n ]\n };\n }\n );\n\n // Document CodeQL Query Prompt\n server.prompt(\n 'document_codeql_query',\n 'Create or update documentation for a CodeQL query - generates standardized markdown documentation as a sibling file to the query',\n documentCodeqlQuerySchema.shape,\n async ({ queryPath, language }) => {\n const template = loadPromptTemplate('document-codeql-query.prompt.md');\n\n const contextSection = `## Query to Document\n\n- **Query Path**: ${queryPath}\n- **Language**: ${language}\n\n`;\n\n return {\n messages: [\n {\n role: 'user',\n content: {\n type: 'text',\n text: contextSection + template\n }\n }\n ]\n };\n }\n );\n\n // LSP-powered Iterative Development Prompt\n server.prompt(\n 'ql_lsp_iterative_development',\n 'Iterative CodeQL query development using LSP tools for completion, navigation, and validation',\n qlLspIterativeDevelopmentSchema.shape,\n async ({ language, queryPath, workspaceUri }) => {\n const template = loadPromptTemplate('ql-lsp-iterative-development.prompt.md');\n\n let contextSection = '## Your Development Context\\n\\n';\n if (language) {\n contextSection += `- **Language**: ${language}\\n`;\n }\n if (queryPath) {\n contextSection += `- **Query Path**: ${queryPath}\\n`;\n }\n if (workspaceUri) {\n contextSection += `- **Workspace URI**: ${workspaceUri}\\n`;\n }\n if (language || queryPath || workspaceUri) {\n contextSection += '\\n';\n }\n\n return {\n messages: [\n {\n role: 'user',\n content: {\n type: 'text',\n text: contextSection + template,\n },\n },\n ],\n };\n }\n );\n\n logger.info(`Registered ${WORKFLOW_PROMPT_NAMES.length} workflow prompts`);\n}\n\n/**\n * Build context section for tools query workflow\n */\nexport function buildToolsQueryContext(\n language: string,\n database: string,\n sourceFiles?: string,\n sourceFunction?: string,\n targetFunction?: string\n): string {\n const lines = [\n '## Your Context',\n '',\n `- **Language**: ${language}`,\n `- **Database**: ${database}`\n ];\n\n if (sourceFiles) {\n lines.push(`- **Source Files**: ${sourceFiles}`);\n }\n if (sourceFunction) {\n lines.push(`- **Source Function**: ${sourceFunction}`);\n }\n if (targetFunction) {\n lines.push(`- **Target Function**: ${targetFunction}`);\n }\n\n lines.push('', '## Recommended Next Steps', '');\n\n if (sourceFiles) {\n lines.push(\n `1. Run \\`codeql_query_run\\` with queryName=\"PrintAST\", sourceFiles=\"${sourceFiles}\"`\n );\n } else {\n lines.push('1. Identify source files to analyze with PrintAST');\n }\n\n if (sourceFunction) {\n lines.push(\n `2. Run \\`codeql_query_run\\` with queryName=\"PrintCFG\" or \"CallGraphFrom\", sourceFunction=\"${sourceFunction}\"`\n );\n } else {\n lines.push(\n '2. Identify key functions for CFG or call graph analysis'\n );\n }\n\n if (targetFunction) {\n lines.push(\n `3. Run \\`codeql_query_run\\` with queryName=\"CallGraphTo\", targetFunction=\"${targetFunction}\"`\n );\n } else {\n lines.push('3. Identify target functions to find callers');\n }\n\n lines.push('', '');\n return lines.join('\\n');\n}\n\n/**\n * Build context section for workshop creation workflow\n */\nexport function buildWorkshopContext(\n queryPath: string,\n language: string,\n workshopName: string,\n numStages?: number\n): string {\n return `## Your Workshop Context\n\n- **Target Query**: ${queryPath}\n- **Language**: ${language}\n- **Workshop Name**: ${workshopName}\n- **Suggested Stages**: ${numStages || '4-8 (auto-detect based on query complexity)'}\n\n## Immediate Actions\n\n1. **Locate query files**: Use \\`find_codeql_query_files\\` with queryPath=\"${queryPath}\"\n2. **Understand query for learning content**: Use the \\`explain_codeql_query\\` prompt with queryPath=\"${queryPath}\" and language=\"${language}\"\n3. **Document each workshop stage**: Use the \\`document_codeql_query\\` prompt to create/update documentation for each solution query\n4. **Verify tests pass**: Use \\`codeql_test_run\\` on existing tests\n5. **Run tools queries**: Generate AST/CFG understanding for workshop materials\n\n`;\n}\n", "/**\n * Utility functions for loading prompt template files\n */\n\nimport { readFileSync } from 'fs';\nimport { join, dirname } from 'path';\nimport { fileURLToPath } from 'url';\n\nconst __filename = fileURLToPath(import.meta.url);\nconst __dirname = dirname(__filename);\n\n/**\n * Load a prompt template from a .prompt.md file\n */\nexport function loadPromptTemplate(promptFileName: string): string {\n try {\n const promptPath = join(__dirname, promptFileName);\n return readFileSync(promptPath, 'utf-8');\n } catch (error) {\n return `Prompt template '${promptFileName}' not available: ${error instanceof Error ? error.message : 'Unknown error'}`;\n }\n}\n\n/**\n * Process prompt template by replacing placeholders with actual values\n */\nexport function processPromptTemplate(template: string, variables: Record): string {\n let processed = template;\n \n // Replace variables in the format {{variable}} or {variable}\n for (const [key, value] of Object.entries(variables)) {\n const patterns = [\n new RegExp(`\\\\{\\\\{${key}\\\\}\\\\}`, 'g'),\n new RegExp(`\\\\{${key}\\\\}`, 'g')\n ];\n \n for (const pattern of patterns) {\n processed = processed.replace(pattern, value);\n }\n }\n \n return processed;\n}", "/**\n * Monitoring Tools - MCP tool implementations for session management and reporting\n * Provides the MCP Tool APIs specified in the monitoring specification\n */\n\nimport { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport { z } from 'zod';\nimport { randomUUID } from 'crypto';\nimport { sessionDataManager } from '../lib/session-data-manager';\nimport {\n QueryDevelopmentSession,\n SessionFilter,\n QualityScoreRecord,\n ComparisonReport,\n AggregateReport,\n ExportResult,\n FunctionalTestResult,\n} from '../types/monitoring';\nimport { logger } from '../utils/logger';\n\n/**\n * Register all monitoring and reporting tools with the MCP server\n * Note: These tools are opt-in and disabled by default for end-users.\n * Set enableMonitoringTools: true in monitoring config to enable them.\n */\nexport function registerMonitoringTools(server: McpServer): void {\n const config = sessionDataManager.getConfig();\n \n // Check if monitoring tools are enabled (opt-in, disabled by default)\n if (!config.enableMonitoringTools) {\n logger.info('Monitoring tools are disabled (opt-in). Set enableMonitoringTools: true to enable session_* tools.');\n return;\n }\n\n // Session Management Tools - session_start removed per feedback (auto-creation instead)\n registerSessionEndTool(server);\n registerSessionGetTool(server);\n registerSessionListTool(server);\n registerSessionUpdateStateTool(server);\n\n // Session Analytics Tools\n registerSessionGetCallHistoryTool(server);\n registerSessionGetTestHistoryTool(server);\n registerSessionGetScoreHistoryTool(server);\n registerSessionCalculateCurrentScoreTool(server);\n\n // Batch Operations Tools\n registerSessionsCompareTool(server);\n registerSessionsAggregateTool(server);\n registerSessionsExportTool(server);\n\n // Note: Functional Testing Support Tools are internal only, not exposed as MCP tools\n\n logger.info('Registered monitoring and reporting tools');\n}\n\n/**\n * Session Management Tools\n */\n\n// session_start tool removed - sessions are now auto-created when needed\n// Sessions are automatically created when MCP tools are called with queryPath\n// If explicit session creation is needed, provide sessionId=null and it will auto-create\n\nfunction registerSessionEndTool(server: McpServer): void {\n server.tool(\n 'session_end',\n 'End a query development session with final status',\n {\n sessionId: z.string().describe('ID of the session to end'),\n status: z.enum(['completed', 'failed', 'abandoned']).describe('Final status of the session'),\n },\n async ({ sessionId, status }) => {\n try {\n const session = await sessionDataManager.endSession(sessionId, status);\n \n if (!session) {\n return {\n content: [\n {\n type: 'text',\n text: `Session not found: ${sessionId}`,\n },\n ],\n isError: true,\n };\n }\n\n return {\n content: [\n {\n type: 'text',\n text: JSON.stringify(session, null, 2),\n },\n ],\n };\n } catch (error) {\n logger.error('Error ending session:', error);\n return {\n content: [\n {\n type: 'text',\n text: `Error ending session: ${error instanceof Error ? error.message : 'Unknown error'}`,\n },\n ],\n isError: true,\n };\n }\n }\n );\n}\n\nfunction registerSessionGetTool(server: McpServer): void {\n server.tool(\n 'session_get',\n 'Get complete details of a specific query development session',\n {\n sessionId: z.string().describe('ID of the session to retrieve'),\n },\n async ({ sessionId }) => {\n try {\n const session = await sessionDataManager.getSession(sessionId);\n \n if (!session) {\n return {\n content: [\n {\n type: 'text',\n text: `Session not found: ${sessionId}`,\n },\n ],\n isError: true,\n };\n }\n\n return {\n content: [\n {\n type: 'text',\n text: JSON.stringify(session, null, 2),\n },\n ],\n };\n } catch (error) {\n logger.error('Error getting session:', error);\n return {\n content: [\n {\n type: 'text',\n text: `Error getting session: ${error instanceof Error ? error.message : 'Unknown error'}`,\n },\n ],\n isError: true,\n };\n }\n }\n );\n}\n\nfunction registerSessionListTool(server: McpServer): void {\n server.tool(\n 'session_list',\n 'List query development sessions with optional filtering',\n {\n queryPath: z.string().optional().describe('Filter by query path (partial match)'),\n status: z.string().optional().describe('Filter by session status'),\n dateRange: z.array(z.string()).length(2).optional().describe('Filter by date range [start, end] (ISO timestamps)'),\n language: z.string().optional().describe('Filter by programming language'),\n queryType: z.string().optional().describe('Filter by query type'),\n },\n async ({ queryPath, status, dateRange, language, queryType }) => {\n try {\n const filters: SessionFilter = {};\n if (queryPath) filters.queryPath = queryPath;\n if (status) filters.status = status;\n if (dateRange) filters.dateRange = [dateRange[0], dateRange[1]];\n if (language) filters.language = language;\n if (queryType) filters.queryType = queryType;\n\n const sessions = await sessionDataManager.listSessions(\n Object.keys(filters).length > 0 ? filters : undefined\n );\n\n const sessionList = {\n totalSessions: sessions.length,\n sessions: sessions.map(s => ({\n sessionId: s.sessionId,\n queryPath: s.queryPath,\n language: s.language,\n status: s.status,\n startTime: s.startTime,\n endTime: s.endTime,\n mcpCallsCount: s.mcpCalls.length,\n testExecutionsCount: s.testExecutions.length,\n currentScore: s.qualityScores.length > 0 \n ? s.qualityScores[s.qualityScores.length - 1].overallScore \n : null,\n })),\n };\n\n return {\n content: [\n {\n type: 'text',\n text: JSON.stringify(sessionList, null, 2),\n },\n ],\n recommendations: generateListRecommendations(sessions),\n };\n } catch (error) {\n logger.error('Error listing sessions:', error);\n return {\n content: [\n {\n type: 'text',\n text: `Error listing sessions: ${error instanceof Error ? error.message : 'Unknown error'}`,\n },\n ],\n isError: true,\n };\n }\n }\n );\n}\n\nfunction registerSessionUpdateStateTool(server: McpServer): void {\n server.tool(\n 'session_update_state',\n 'Update the current state of a query development session',\n {\n sessionId: z.string().describe('ID of the session to update'),\n filesPresent: z.array(z.string()).optional().describe('List of files present in the query development'),\n compilationStatus: z.enum(['unknown', 'success', 'failed']).optional().describe('Current compilation status'),\n testStatus: z.enum(['unknown', 'passing', 'failing', 'no_tests']).optional().describe('Current test status'),\n documentationStatus: z.enum(['unknown', 'present', 'missing', 'incomplete']).optional().describe('Documentation status'),\n },\n async ({ sessionId, filesPresent, compilationStatus, testStatus, documentationStatus }) => {\n try {\n const stateUpdate: Record = {};\n if (filesPresent !== undefined) stateUpdate.filesPresent = filesPresent;\n if (compilationStatus !== undefined) stateUpdate.compilationStatus = compilationStatus;\n if (testStatus !== undefined) stateUpdate.testStatus = testStatus;\n if (documentationStatus !== undefined) stateUpdate.documentationStatus = documentationStatus;\n\n const session = await sessionDataManager.updateSessionState(sessionId, stateUpdate);\n \n if (!session) {\n return {\n content: [\n {\n type: 'text',\n text: `Session not found: ${sessionId}`,\n },\n ],\n isError: true,\n };\n }\n\n return {\n content: [\n {\n type: 'text',\n text: JSON.stringify(session, null, 2),\n },\n ],\n recommendations: generateRecommendations(session, 'session_update_state'),\n };\n } catch (error) {\n logger.error('Error updating session state:', error);\n return {\n content: [\n {\n type: 'text',\n text: `Error updating session state: ${error instanceof Error ? error.message : 'Unknown error'}`,\n },\n ],\n isError: true,\n };\n }\n }\n );\n}\n\n/**\n * Session Analytics Tools\n */\n\nfunction registerSessionGetCallHistoryTool(server: McpServer): void {\n server.tool(\n 'session_get_call_history',\n 'Get MCP call history for a specific session',\n {\n sessionId: z.string().describe('ID of the session'),\n limit: z.number().optional().describe('Maximum number of calls to return (most recent first)'),\n },\n async ({ sessionId, limit }) => {\n try {\n const session = await sessionDataManager.getSession(sessionId);\n \n if (!session) {\n return {\n content: [\n {\n type: 'text',\n text: `Session not found: ${sessionId}`,\n },\n ],\n isError: true,\n };\n }\n\n let calls = [...session.mcpCalls].reverse(); // Most recent first\n if (limit && limit > 0) {\n calls = calls.slice(0, limit);\n }\n\n return {\n content: [\n {\n type: 'text',\n text: JSON.stringify({\n sessionId,\n totalCalls: session.mcpCalls.length,\n callHistory: calls,\n }, null, 2),\n },\n ],\n };\n } catch (error) {\n logger.error('Error getting call history:', error);\n return {\n content: [\n {\n type: 'text',\n text: `Error getting call history: ${error instanceof Error ? error.message : 'Unknown error'}`,\n },\n ],\n isError: true,\n };\n }\n }\n );\n}\n\nfunction registerSessionGetTestHistoryTool(server: McpServer): void {\n server.tool(\n 'session_get_test_history',\n 'Get test execution history for a specific session',\n {\n sessionId: z.string().describe('ID of the session'),\n limit: z.number().optional().describe('Maximum number of test executions to return (most recent first)'),\n },\n async ({ sessionId, limit }) => {\n try {\n const session = await sessionDataManager.getSession(sessionId);\n \n if (!session) {\n return {\n content: [\n {\n type: 'text',\n text: `Session not found: ${sessionId}`,\n },\n ],\n isError: true,\n };\n }\n\n let tests = [...session.testExecutions].reverse(); // Most recent first\n if (limit && limit > 0) {\n tests = tests.slice(0, limit);\n }\n\n return {\n content: [\n {\n type: 'text',\n text: JSON.stringify({\n sessionId,\n totalTests: session.testExecutions.length,\n testHistory: tests,\n }, null, 2),\n },\n ],\n };\n } catch (error) {\n logger.error('Error getting test history:', error);\n return {\n content: [\n {\n type: 'text',\n text: `Error getting test history: ${error instanceof Error ? error.message : 'Unknown error'}`,\n },\n ],\n isError: true,\n };\n }\n }\n );\n}\n\nfunction registerSessionGetScoreHistoryTool(server: McpServer): void {\n server.tool(\n 'session_get_score_history',\n 'Get quality score history for a specific session',\n {\n sessionId: z.string().describe('ID of the session'),\n limit: z.number().optional().describe('Maximum number of scores to return (most recent first)'),\n },\n async ({ sessionId, limit }) => {\n try {\n const session = await sessionDataManager.getSession(sessionId);\n \n if (!session) {\n return {\n content: [\n {\n type: 'text',\n text: `Session not found: ${sessionId}`,\n },\n ],\n isError: true,\n };\n }\n\n let scores = [...session.qualityScores].reverse(); // Most recent first\n if (limit && limit > 0) {\n scores = scores.slice(0, limit);\n }\n\n return {\n content: [\n {\n type: 'text',\n text: JSON.stringify({\n sessionId,\n totalScores: session.qualityScores.length,\n scoreHistory: scores,\n }, null, 2),\n },\n ],\n };\n } catch (error) {\n logger.error('Error getting score history:', error);\n return {\n content: [\n {\n type: 'text',\n text: `Error getting score history: ${error instanceof Error ? error.message : 'Unknown error'}`,\n },\n ],\n isError: true,\n };\n }\n }\n );\n}\n\nfunction registerSessionCalculateCurrentScoreTool(server: McpServer): void {\n server.tool(\n 'session_calculate_current_score',\n 'Calculate current quality score for a session based on its state',\n {\n sessionId: z.string().describe('ID of the session'),\n },\n async ({ sessionId }) => {\n try {\n const session = await sessionDataManager.getSession(sessionId);\n \n if (!session) {\n return {\n content: [\n {\n type: 'text',\n text: `Session not found: ${sessionId}`,\n },\n ],\n isError: true,\n };\n }\n\n // Calculate quality score based on current state\n const scoreRecord = calculateQualityScore(session);\n \n // Add the score to the session\n await sessionDataManager.addQualityScore(sessionId, scoreRecord);\n \n // Get updated session with new score\n const updatedSession = await sessionDataManager.getSession(sessionId);\n\n return {\n content: [\n {\n type: 'text',\n text: JSON.stringify(scoreRecord, null, 2),\n },\n ],\n recommendations: generateRecommendations(updatedSession, 'session_calculate_current_score'),\n };\n } catch (error) {\n logger.error('Error calculating current score:', error);\n return {\n content: [\n {\n type: 'text',\n text: `Error calculating current score: ${error instanceof Error ? error.message : 'Unknown error'}`,\n },\n ],\n isError: true,\n };\n }\n }\n );\n}\n\n/**\n * Batch Operations Tools\n */\n\nfunction registerSessionsCompareTool(server: McpServer): void {\n server.tool(\n 'sessions_compare',\n 'Compare multiple query development sessions across specified dimensions',\n {\n sessionIds: z.array(z.string()).describe('Array of session IDs to compare'),\n dimensions: z.array(z.string()).optional().describe('Specific dimensions to compare (default: all)'),\n },\n async ({ sessionIds, dimensions }) => {\n try {\n const sessions = await Promise.all(\n sessionIds.map(id => sessionDataManager.getSession(id))\n );\n\n const validSessions = sessions.filter(s => s !== null) as QueryDevelopmentSession[];\n \n if (validSessions.length === 0) {\n return {\n content: [\n {\n type: 'text',\n text: 'No valid sessions found for comparison',\n },\n ],\n isError: true,\n };\n }\n\n const comparison = await compareSessions(validSessions, dimensions);\n\n return {\n content: [\n {\n type: 'text',\n text: JSON.stringify(comparison, null, 2),\n },\n ],\n };\n } catch (error) {\n logger.error('Error comparing sessions:', error);\n return {\n content: [\n {\n type: 'text',\n text: `Error comparing sessions: ${error instanceof Error ? error.message : 'Unknown error'}`,\n },\n ],\n isError: true,\n };\n }\n }\n );\n}\n\nfunction registerSessionsAggregateTool(server: McpServer): void {\n server.tool(\n 'sessions_aggregate',\n 'Generate aggregate insights from multiple sessions based on filters',\n {\n queryPath: z.string().optional().describe('Filter by query path (partial match)'),\n status: z.string().optional().describe('Filter by session status'),\n dateRange: z.array(z.string()).length(2).optional().describe('Filter by date range [start, end] (ISO timestamps)'),\n language: z.string().optional().describe('Filter by programming language'),\n queryType: z.string().optional().describe('Filter by query type'),\n },\n async ({ queryPath, status, dateRange, language, queryType }) => {\n try {\n const filters: SessionFilter = {};\n if (queryPath) filters.queryPath = queryPath;\n if (status) filters.status = status;\n if (dateRange) filters.dateRange = [dateRange[0], dateRange[1]];\n if (language) filters.language = language;\n if (queryType) filters.queryType = queryType;\n\n const sessions = await sessionDataManager.listSessions(\n Object.keys(filters).length > 0 ? filters : undefined\n );\n\n const aggregate = await aggregateSessions(sessions, filters);\n\n return {\n content: [\n {\n type: 'text',\n text: JSON.stringify(aggregate, null, 2),\n },\n ],\n };\n } catch (error) {\n logger.error('Error aggregating sessions:', error);\n return {\n content: [\n {\n type: 'text',\n text: `Error aggregating sessions: ${error instanceof Error ? error.message : 'Unknown error'}`,\n },\n ],\n isError: true,\n };\n }\n }\n );\n}\n\nfunction registerSessionsExportTool(server: McpServer): void {\n server.tool(\n 'sessions_export',\n 'Export session data in specified format for external analysis',\n {\n sessionIds: z.array(z.string()).describe('Array of session IDs to export'),\n format: z.enum(['json', 'html', 'markdown']).optional().default('json').describe('Export format'),\n },\n async ({ sessionIds, format = 'json' }) => {\n try {\n const sessions = await Promise.all(\n sessionIds.map(id => sessionDataManager.getSession(id))\n );\n\n const validSessions = sessions.filter(s => s !== null) as QueryDevelopmentSession[];\n \n if (validSessions.length === 0) {\n return {\n content: [\n {\n type: 'text',\n text: 'No valid sessions found for export',\n },\n ],\n isError: true,\n };\n }\n\n const exportResult = await exportSessions(validSessions, format);\n\n return {\n content: [\n {\n type: 'text',\n text: JSON.stringify(exportResult, null, 2),\n },\n ],\n };\n } catch (error) {\n logger.error('Error exporting sessions:', error);\n return {\n content: [\n {\n type: 'text',\n text: `Error exporting sessions: ${error instanceof Error ? error.message : 'Unknown error'}`,\n },\n ],\n isError: true,\n };\n }\n }\n );\n}\n\n/**\n * Helper Functions\n */\n\n/**\n * Calculate quality score for a session based on current state and history\n */\nfunction calculateQualityScore(session: QueryDevelopmentSession): QualityScoreRecord {\n const timestamp = new Date().toISOString();\n \n // Calculate syntactic correctness (25%)\n const syntacticCorrectness = session.currentState.compilationStatus === 'success' ? 100 :\n session.currentState.compilationStatus === 'failed' ? 0 : 50;\n\n // Calculate test coverage and results (30%)\n const testCoverageResults = session.currentState.testStatus === 'passing' ? 100 :\n session.currentState.testStatus === 'failing' ? 25 :\n session.currentState.testStatus === 'no_tests' ? 0 : 50;\n\n // Calculate documentation quality (20%)\n const documentationQuality = session.currentState.documentationStatus === 'present' ? 100 :\n session.currentState.documentationStatus === 'incomplete' ? 60 :\n session.currentState.documentationStatus === 'missing' ? 0 : 50;\n\n // Calculate functional correctness (25%) - based on successful test runs\n const successfulTests = session.testExecutions.filter(t => t.success && t.type === 'test_run').length;\n const totalTests = session.testExecutions.filter(t => t.type === 'test_run').length;\n const functionalCorrectness = totalTests > 0 ? (successfulTests / totalTests) * 100 : 50;\n\n // Calculate overall score\n const overallScore = Math.round(\n (syntacticCorrectness * 0.25) +\n (testCoverageResults * 0.30) +\n (documentationQuality * 0.20) +\n (functionalCorrectness * 0.25)\n );\n\n // Determine grade\n const grade = overallScore >= 90 ? 'A' :\n overallScore >= 80 ? 'B' :\n overallScore >= 70 ? 'C' :\n overallScore >= 60 ? 'D' : 'F';\n\n // Generate recommendations\n const recommendations: string[] = [];\n if (syntacticCorrectness < 100) {\n recommendations.push('Fix compilation errors to improve syntactic correctness');\n }\n if (testCoverageResults < 70) {\n recommendations.push('Add comprehensive tests and ensure they pass');\n }\n if (documentationQuality < 80) {\n recommendations.push('Add or improve query documentation with examples');\n }\n if (functionalCorrectness < 80) {\n recommendations.push('Improve test pass rate and verify query logic');\n }\n\n return {\n scoreId: randomUUID(),\n timestamp,\n overallScore,\n dimensions: {\n syntacticCorrectness,\n testCoverageResults,\n documentationQuality,\n functionalCorrectness,\n },\n grade,\n recommendations,\n };\n}\n\n/**\n * Compare multiple sessions\n */\nasync function compareSessions(\n sessions: QueryDevelopmentSession[],\n dimensions?: string[]\n): Promise {\n const timestamp = new Date().toISOString();\n const sessionIds = sessions.map(s => s.sessionId);\n \n const results: Record = {\n sessionCount: sessions.length,\n sessionOverview: sessions.map(s => ({\n sessionId: s.sessionId,\n queryPath: s.queryPath,\n status: s.status,\n mcpCallsCount: s.mcpCalls.length,\n duration: s.endTime ? \n new Date(s.endTime).getTime() - new Date(s.startTime).getTime() : \n new Date().getTime() - new Date(s.startTime).getTime(),\n currentScore: s.qualityScores.length > 0 ? \n s.qualityScores[s.qualityScores.length - 1].overallScore : null,\n })),\n };\n\n if (!dimensions || dimensions.includes('quality')) {\n const qualityScores = sessions.map(s => \n s.qualityScores.length > 0 ? s.qualityScores[s.qualityScores.length - 1] : null\n );\n results.qualityComparison = {\n averageScore: qualityScores\n .filter(q => q !== null)\n .reduce((sum, q) => sum + q!.overallScore, 0) / qualityScores.filter(q => q !== null).length,\n scoreRange: {\n min: Math.min(...qualityScores.filter(q => q !== null).map(q => q!.overallScore)),\n max: Math.max(...qualityScores.filter(q => q !== null).map(q => q!.overallScore)),\n },\n };\n }\n\n if (!dimensions || dimensions.includes('activity')) {\n results.activityComparison = {\n totalMCPCalls: sessions.reduce((sum, s) => sum + s.mcpCalls.length, 0),\n averageCallsPerSession: sessions.reduce((sum, s) => sum + s.mcpCalls.length, 0) / sessions.length,\n mostActiveTool: getMostUsedTool(sessions),\n };\n }\n\n return {\n sessionIds,\n dimensions: dimensions || ['all'],\n timestamp,\n results,\n };\n}\n\n/**\n * Aggregate insights from multiple sessions\n */\nasync function aggregateSessions(\n sessions: QueryDevelopmentSession[],\n filters: SessionFilter\n): Promise {\n const timestamp = new Date().toISOString();\n \n const completedSessions = sessions.filter(s => s.status === 'completed');\n const successRate = sessions.length > 0 ? completedSessions.length / sessions.length : 0;\n \n const qualityScores = sessions\n .map(s => s.qualityScores.length > 0 ? s.qualityScores[s.qualityScores.length - 1].overallScore : null)\n .filter(score => score !== null) as number[];\n \n const averageQualityScore = qualityScores.length > 0 ? \n qualityScores.reduce((sum, score) => sum + score, 0) / qualityScores.length : 0;\n\n const commonPatterns = identifyCommonPatterns(sessions);\n const recommendations = generateAggregateRecommendations(sessions);\n\n return {\n filters,\n timestamp,\n totalSessions: sessions.length,\n successRate,\n averageQualityScore,\n commonPatterns,\n recommendations,\n };\n}\n\n/**\n * Export sessions in specified format\n */\nasync function exportSessions(\n sessions: QueryDevelopmentSession[],\n format: 'json' | 'html' | 'markdown'\n): Promise {\n const timestamp = new Date().toISOString();\n const filename = `session-export-${timestamp.replace(/[:.]/g, '-')}.${format}`;\n \n let content: string;\n \n switch (format) {\n case 'json':\n content = JSON.stringify(sessions, null, 2);\n break;\n case 'html':\n content = generateHTMLReport(sessions);\n break;\n case 'markdown':\n content = generateMarkdownReport(sessions);\n break;\n }\n\n return {\n format,\n filename,\n content,\n timestamp,\n };\n}\n\n/**\n * Utility functions\n */\n\nfunction getMostUsedTool(sessions: QueryDevelopmentSession[]): string {\n const toolCounts: Record = {};\n \n sessions.forEach(session => {\n session.mcpCalls.forEach(call => {\n toolCounts[call.toolName] = (toolCounts[call.toolName] || 0) + 1;\n });\n });\n\n return Object.entries(toolCounts)\n .sort(([, a], [, b]) => b - a)[0]?.[0] || 'none';\n}\n\nfunction identifyCommonPatterns(sessions: QueryDevelopmentSession[]): string[] {\n const patterns: string[] = [];\n \n const commonTools = getMostUsedTool(sessions);\n if (commonTools && commonTools !== 'none') {\n patterns.push(`Most commonly used tool: ${commonTools}`);\n }\n\n const completionRate = sessions.filter(s => s.status === 'completed').length / sessions.length;\n if (completionRate > 0.8) {\n patterns.push('High completion rate indicates effective workflow');\n } else if (completionRate < 0.5) {\n patterns.push('Low completion rate suggests workflow issues');\n }\n\n return patterns;\n}\n\nfunction generateAggregateRecommendations(sessions: QueryDevelopmentSession[]): string[] {\n const recommendations: string[] = [];\n \n const failedSessions = sessions.filter(s => s.status === 'failed');\n if (failedSessions.length > sessions.length * 0.3) {\n recommendations.push('High failure rate - consider improving error handling and guidance');\n }\n\n const averageCallsPerSession = sessions.reduce((sum, s) => sum + s.mcpCalls.length, 0) / sessions.length;\n if (averageCallsPerSession > 20) {\n recommendations.push('High number of MCP calls per session - consider workflow optimization');\n }\n\n return recommendations;\n}\n\nfunction generateHTMLReport(sessions: QueryDevelopmentSession[]): string {\n const html = `\n\n\n\n Session Export Report\n \n\n\n

Query Development Sessions Report

\n

Generated: ${new Date().toISOString()}

\n

Total Sessions: ${sessions.length}

\n \n ${sessions.map(session => `\n
\n

Session: ${session.sessionId}

\n

Query Path: ${session.queryPath}

\n

Status: ${session.status}

\n

Language: ${session.language}

\n

Start Time: ${session.startTime}

\n

MCP Calls: ${session.mcpCalls.length}

\n

Test Executions: ${session.testExecutions.length}

\n

Quality Scores: ${session.qualityScores.length}

\n
\n `).join('')}\n\n`;\n \n return html;\n}\n\nfunction generateMarkdownReport(sessions: QueryDevelopmentSession[]): string {\n const md = `# Query Development Sessions Report\n\nGenerated: ${new Date().toISOString()}\nTotal Sessions: ${sessions.length}\n\n## Session Summary\n\n| Session ID | Query Path | Status | Language | MCP Calls | Test Executions |\n|------------|-----------|--------|----------|-----------|-----------------|\n${sessions.map(session => \n `| ${session.sessionId} | ${session.queryPath} | ${session.status} | ${session.language} | ${session.mcpCalls.length} | ${session.testExecutions.length} |`\n).join('\\n')}\n\n## Detailed Sessions\n\n${sessions.map(session => `\n### Session: ${session.sessionId}\n\n- **Query Path:** ${session.queryPath}\n- **Status:** ${session.status}\n- **Language:** ${session.language}\n- **Start Time:** ${session.startTime}\n- **End Time:** ${session.endTime || 'N/A'}\n- **MCP Calls:** ${session.mcpCalls.length}\n- **Test Executions:** ${session.testExecutions.length}\n- **Quality Scores:** ${session.qualityScores.length}\n\n${session.recommendations.length > 0 ? `\n**Current Recommendations:**\n${session.recommendations.map(rec => `- ${rec}`).join('\\n')}\n` : ''}\n`).join('\\n')}`;\n\n return md;\n}\n\nfunction _calculateAverageDuration(sessions: QueryDevelopmentSession[]): number {\n const completedSessions = sessions.filter(s => s.endTime);\n if (completedSessions.length === 0) return 0;\n\n const totalDuration = completedSessions.reduce((sum, session) => {\n return sum + (new Date(session.endTime!).getTime() - new Date(session.startTime).getTime());\n }, 0);\n\n return totalDuration / completedSessions.length;\n}\n\nfunction _identifyFailureReasons(results: FunctionalTestResult[]): string[] {\n const failedResults = results.filter(r => !r.passed);\n const reasons: Record = {};\n\n failedResults.forEach(result => {\n Object.entries(result.criteria).forEach(([criterion, passed]) => {\n if (!passed) {\n reasons[criterion] = (reasons[criterion] || 0) + 1;\n }\n });\n });\n\n return Object.entries(reasons)\n .sort(([, a], [, b]) => b - a)\n .map(([reason, count]) => `${reason}: ${count} sessions`);\n}\n\n/**\n * Generate recommendations for MCP tool responses\n * Returns a map of MCP primitive paths to recommendation reasons\n */\nfunction generateRecommendations(\n session: QueryDevelopmentSession | null,\n currentTool: string\n): Record {\n if (!session) {\n return {};\n }\n\n const recommendations: Record = {};\n\n // Session state-based recommendations\n if (session.currentState.compilationStatus === 'failed') {\n recommendations['codeql_query_format'] = 'Format query to fix potential syntax issues';\n recommendations['codeql_query_compile'] = 'Recompile after fixing syntax errors';\n } else if (session.currentState.compilationStatus === 'success') {\n if (session.currentState.testStatus === 'unknown' || session.currentState.testStatus === 'no_tests') {\n recommendations['codeql_test_run'] = 'Run tests to validate query functionality';\n } else if (session.currentState.testStatus === 'failing') {\n recommendations['session_get_test_history'] = 'Review test failures to identify issues';\n recommendations['codeql_query_compile'] = 'Verify query logic matches test expectations';\n } else if (session.currentState.testStatus === 'passing') {\n recommendations['session_calculate_current_score'] = 'Calculate quality score for completed query';\n }\n }\n\n // Tool-specific follow-up recommendations\n switch (currentTool) {\n case 'session_get':\n if (session.mcpCalls.length === 0) {\n recommendations['codeql_query_compile'] = 'Start development by compiling the query';\n }\n break;\n case 'session_end':\n if (session.status === 'completed') {\n recommendations['sessions_export'] = 'Export session data for analysis';\n }\n break;\n case 'session_calculate_current_score': {\n const latestScore = session.qualityScores[session.qualityScores.length - 1];\n if (latestScore && latestScore.overallScore < 80) {\n if (latestScore.dimensions.syntacticCorrectness < 100) {\n recommendations['codeql_query_format'] = 'Improve syntax and formatting';\n }\n if (latestScore.dimensions.testCoverageResults < 70) {\n recommendations['codeql_test_run'] = 'Improve test coverage and results';\n }\n }\n break;\n }\n case 'session_update_state':\n // Recommend next logical step based on updated state\n if (session.currentState.compilationStatus === 'success' && session.currentState.testStatus === 'unknown') {\n recommendations['codeql_test_run'] = 'Run tests now that compilation is successful';\n }\n break;\n }\n\n return recommendations;\n}\n\n/**\n * Generate recommendations for session list results\n */\nfunction generateListRecommendations(sessions: QueryDevelopmentSession[]): Record {\n const recommendations: Record = {};\n\n const activeSessions = sessions.filter(s => s.status === 'active');\n const completedSessions = sessions.filter(s => s.status === 'completed');\n\n if (activeSessions.length > 0) {\n recommendations['session_get'] = `Review details of ${activeSessions.length} active session(s)`;\n }\n\n if (completedSessions.length > 1) {\n recommendations['sessions_compare'] = 'Compare completed sessions to identify patterns';\n recommendations['sessions_aggregate'] = 'Generate aggregate insights from multiple sessions';\n }\n\n if (sessions.length > 5) {\n recommendations['sessions_export'] = 'Export session data for comprehensive analysis';\n }\n\n return recommendations;\n}", "function checkArgs(adapter, defaultData) {\n if (adapter === undefined)\n throw new Error('lowdb: missing adapter');\n if (defaultData === undefined)\n throw new Error('lowdb: missing default data');\n}\nexport class Low {\n adapter;\n data;\n constructor(adapter, defaultData) {\n checkArgs(adapter, defaultData);\n this.adapter = adapter;\n this.data = defaultData;\n }\n async read() {\n const data = await this.adapter.read();\n if (data)\n this.data = data;\n }\n async write() {\n if (this.data)\n await this.adapter.write(this.data);\n }\n async update(fn) {\n fn(this.data);\n await this.write();\n }\n}\nexport class LowSync {\n adapter;\n data;\n constructor(adapter, defaultData) {\n checkArgs(adapter, defaultData);\n this.adapter = adapter;\n this.data = defaultData;\n }\n read() {\n const data = this.adapter.read();\n if (data)\n this.data = data;\n }\n write() {\n if (this.data)\n this.adapter.write(this.data);\n }\n update(fn) {\n fn(this.data);\n this.write();\n }\n}\n", "import { readFileSync, renameSync, writeFileSync } from 'node:fs';\nimport { readFile } from 'node:fs/promises';\nimport path from 'node:path';\nimport { Writer } from 'steno';\nexport class TextFile {\n #filename;\n #writer;\n constructor(filename) {\n this.#filename = filename;\n this.#writer = new Writer(filename);\n }\n async read() {\n let data;\n try {\n data = await readFile(this.#filename, 'utf-8');\n }\n catch (e) {\n if (e.code === 'ENOENT') {\n return null;\n }\n throw e;\n }\n return data;\n }\n write(str) {\n return this.#writer.write(str);\n }\n}\nexport class TextFileSync {\n #tempFilename;\n #filename;\n constructor(filename) {\n this.#filename = filename;\n const f = filename.toString();\n this.#tempFilename = path.join(path.dirname(f), `.${path.basename(f)}.tmp`);\n }\n read() {\n let data;\n try {\n data = readFileSync(this.#filename, 'utf-8');\n }\n catch (e) {\n if (e.code === 'ENOENT') {\n return null;\n }\n throw e;\n }\n return data;\n }\n write(str) {\n writeFileSync(this.#tempFilename, str);\n renameSync(this.#tempFilename, this.#filename);\n }\n}\n", "import { TextFile, TextFileSync } from './TextFile.js';\nexport class DataFile {\n #adapter;\n #parse;\n #stringify;\n constructor(filename, { parse, stringify, }) {\n this.#adapter = new TextFile(filename);\n this.#parse = parse;\n this.#stringify = stringify;\n }\n async read() {\n const data = await this.#adapter.read();\n if (data === null) {\n return null;\n }\n else {\n return this.#parse(data);\n }\n }\n write(obj) {\n return this.#adapter.write(this.#stringify(obj));\n }\n}\nexport class DataFileSync {\n #adapter;\n #parse;\n #stringify;\n constructor(filename, { parse, stringify, }) {\n this.#adapter = new TextFileSync(filename);\n this.#parse = parse;\n this.#stringify = stringify;\n }\n read() {\n const data = this.#adapter.read();\n if (data === null) {\n return null;\n }\n else {\n return this.#parse(data);\n }\n }\n write(obj) {\n this.#adapter.write(this.#stringify(obj));\n }\n}\n", "import { DataFile, DataFileSync } from './DataFile.js';\nexport class JSONFile extends DataFile {\n constructor(filename) {\n super(filename, {\n parse: JSON.parse,\n stringify: (data) => JSON.stringify(data, null, 2),\n });\n }\n}\nexport class JSONFileSync extends DataFileSync {\n constructor(filename) {\n super(filename, {\n parse: JSON.parse,\n stringify: (data) => JSON.stringify(data, null, 2),\n });\n }\n}\n", "/**\n * Session Data Management\n * Provides unified JSON storage and session lifecycle management using lowdb\n */\n\nimport { Low } from 'lowdb';\nimport { JSONFileSync } from 'lowdb/node';\nimport { mkdirSync, writeFileSync } from 'fs';\nimport { join } from 'path';\nimport { randomUUID } from 'crypto';\nimport { getProjectTmpBase } from '../utils/temp-dir';\nimport {\n QueryDevelopmentSession,\n QueryState,\n MCPCallRecord,\n TestExecutionRecord,\n QualityScoreRecord,\n SessionFilter,\n MonitoringConfig,\n MonitoringConfigSchema,\n} from '../types/monitoring';\nimport { logger } from '../utils/logger';\n\n/**\n * Database schema for lowdb - sessions only\n */\ninterface SessionDatabase {\n sessions: QueryDevelopmentSession[];\n}\n\n/**\n * Session Data Manager - handles all session persistence and lifecycle\n */\nexport class SessionDataManager {\n private db: Low;\n private config: MonitoringConfig;\n private storageDir: string;\n\n constructor(configOverrides: Partial = {}) {\n this.config = MonitoringConfigSchema.parse({\n ...MonitoringConfigSchema.parse({}),\n ...configOverrides,\n });\n\n this.storageDir = this.config.storageLocation;\n this.ensureStorageDirectory();\n\n const adapter = new JSONFileSync(join(this.storageDir, 'sessions.json'));\n this.db = new Low(adapter, {\n sessions: [],\n });\n\n this.initializeDatabase();\n }\n\n /**\n * Initialize the database and ensure it's properly set up\n */\n async initialize(): Promise {\n await this.initializeDatabase();\n }\n\n /**\n * Initialize the database and ensure it's properly set up\n */\n private async initializeDatabase(): Promise {\n try {\n await this.db.read();\n \n logger.info(`Session data manager initialized with ${this.db.data.sessions.length} sessions`);\n } catch (error) {\n logger.error('Failed to initialize session database:', error);\n throw error;\n }\n }\n\n /**\n * Ensure storage directory structure exists\n */\n private ensureStorageDirectory(): void {\n try {\n // mkdirSync with recursive: true is a no-op if directories already exist\n mkdirSync(this.storageDir, { recursive: true });\n\n // Create subdirectories\n const subdirs = ['sessions-archive', 'exports'];\n for (const subdir of subdirs) {\n mkdirSync(join(this.storageDir, subdir), { recursive: true });\n }\n\n // Use 'wx' flag (exclusive create) to atomically create config only\n // if it doesn't exist, avoiding TOCTOU race (CWE-367).\n const configPath = join(this.storageDir, 'config.json');\n try {\n writeFileSync(configPath, JSON.stringify(this.config, null, 2), { flag: 'wx' });\n } catch (e: unknown) {\n const err = e as { code?: string };\n if (err.code !== 'EEXIST') throw e;\n }\n\n logger.debug(`Storage directory initialized: ${this.storageDir}`);\n } catch (error) {\n logger.error('Failed to create storage directory:', error);\n throw error;\n }\n }\n\n /**\n * Start a new query development session\n */\n async startSession(\n queryPath: string,\n language?: string,\n queryType?: string,\n description?: string\n ): Promise {\n const sessionId = randomUUID();\n const startTime = new Date().toISOString();\n\n const session: QueryDevelopmentSession = {\n sessionId,\n queryPath,\n language: language || 'unknown',\n queryType,\n description,\n startTime,\n status: 'active',\n mcpCalls: [],\n testExecutions: [],\n qualityScores: [],\n currentState: {\n filesPresent: [],\n compilationStatus: 'unknown',\n testStatus: 'unknown',\n documentationStatus: 'unknown',\n lastActivity: startTime,\n },\n recommendations: [],\n };\n\n await this.db.read();\n this.db.data.sessions.push(session);\n await this.db.write();\n\n logger.info(`Started new session: ${sessionId} for query: ${queryPath}`);\n return sessionId;\n }\n\n /**\n * End a session with final status\n */\n async endSession(\n sessionId: string,\n status: 'completed' | 'failed' | 'abandoned'\n ): Promise {\n await this.db.read();\n \n const session = this.db.data.sessions.find(s => s.sessionId === sessionId);\n if (!session) {\n logger.warn(`Session not found: ${sessionId}`);\n return null;\n }\n\n session.status = status;\n session.endTime = new Date().toISOString();\n session.currentState.lastActivity = session.endTime;\n\n await this.db.write();\n\n // Archive completed session if enabled\n if (this.config.archiveCompletedSessions && status === 'completed') {\n await this.archiveSession(sessionId);\n }\n\n logger.info(`Ended session: ${sessionId} with status: ${status}`);\n return session;\n }\n\n /**\n * Get a specific session by ID\n */\n async getSession(sessionId: string): Promise {\n await this.db.read();\n const session = this.db.data.sessions.find(s => s.sessionId === sessionId);\n return session || null;\n }\n\n /**\n * List sessions with optional filtering\n */\n async listSessions(filters?: SessionFilter): Promise {\n await this.db.read();\n let sessions = [...this.db.data.sessions];\n\n if (filters) {\n if (filters.queryPath) {\n sessions = sessions.filter(s => s.queryPath.includes(filters.queryPath!));\n }\n if (filters.status) {\n sessions = sessions.filter(s => s.status === filters.status);\n }\n if (filters.language) {\n sessions = sessions.filter(s => s.language === filters.language);\n }\n if (filters.queryType) {\n sessions = sessions.filter(s => s.queryType === filters.queryType);\n }\n if (filters.dateRange) {\n const [start, end] = filters.dateRange;\n sessions = sessions.filter(s => \n s.startTime >= start && s.startTime <= end\n );\n }\n }\n\n return sessions;\n }\n\n /**\n * Update session state\n */\n async updateSessionState(\n sessionId: string,\n stateUpdate: Partial\n ): Promise {\n await this.db.read();\n \n const session = this.db.data.sessions.find(s => s.sessionId === sessionId);\n if (!session) {\n logger.warn(`Session not found: ${sessionId}`);\n return null;\n }\n\n session.currentState = {\n ...session.currentState,\n ...stateUpdate,\n lastActivity: new Date().toISOString(),\n };\n\n await this.db.write();\n return session;\n }\n\n /**\n * Add MCP call record to session\n */\n async addMCPCall(sessionId: string, callRecord: MCPCallRecord): Promise {\n await this.db.read();\n \n const session = this.db.data.sessions.find(s => s.sessionId === sessionId);\n if (!session) {\n logger.warn(`Session not found for MCP call: ${sessionId}`);\n return;\n }\n\n session.mcpCalls.push(callRecord);\n session.currentState.lastActivity = callRecord.timestamp;\n\n // Update next suggested tool if provided\n if (callRecord.nextSuggestedTool) {\n session.nextSuggestedTool = callRecord.nextSuggestedTool;\n }\n\n await this.db.write();\n }\n\n /**\n * Add test execution record to session\n */\n async addTestExecution(sessionId: string, testRecord: TestExecutionRecord): Promise {\n await this.db.read();\n \n const session = this.db.data.sessions.find(s => s.sessionId === sessionId);\n if (!session) {\n logger.warn(`Session not found for test execution: ${sessionId}`);\n return;\n }\n\n session.testExecutions.push(testRecord);\n session.currentState.lastActivity = testRecord.timestamp;\n\n // Update compilation/test status based on execution\n if (testRecord.type === 'compilation') {\n session.currentState.compilationStatus = testRecord.success ? 'success' : 'failed';\n } else if (testRecord.type === 'test_run') {\n session.currentState.testStatus = testRecord.success ? 'passing' : 'failing';\n }\n\n await this.db.write();\n }\n\n /**\n * Add quality score record to session\n */\n async addQualityScore(sessionId: string, scoreRecord: QualityScoreRecord): Promise {\n await this.db.read();\n \n const session = this.db.data.sessions.find(s => s.sessionId === sessionId);\n if (!session) {\n logger.warn(`Session not found for quality score: ${sessionId}`);\n return;\n }\n\n session.qualityScores.push(scoreRecord);\n session.currentState.lastActivity = scoreRecord.timestamp;\n session.recommendations = scoreRecord.recommendations;\n\n await this.db.write();\n }\n\n /**\n * Archive a completed session to monthly file\n */\n private async archiveSession(sessionId: string): Promise {\n try {\n const session = await this.getSession(sessionId);\n if (!session) return;\n\n const date = new Date(session.endTime || session.startTime);\n const monthDir = `${date.getFullYear()}-${String(date.getMonth() + 1).padStart(2, '0')}`;\n const archiveDir = join(this.storageDir, 'sessions-archive', monthDir);\n\n mkdirSync(archiveDir, { recursive: true });\n\n const archiveFile = join(archiveDir, `${sessionId}.json`);\n writeFileSync(archiveFile, JSON.stringify(session, null, 2));\n\n // Remove from active sessions\n await this.db.read();\n this.db.data.sessions = this.db.data.sessions.filter(s => s.sessionId !== sessionId);\n await this.db.write();\n\n logger.info(`Archived session: ${sessionId} to ${archiveFile}`);\n } catch (error) {\n logger.error(`Failed to archive session ${sessionId}:`, error);\n }\n }\n\n /**\n * Get active sessions for a specific query path\n */\n async getActiveSessionsForQuery(queryPath: string): Promise {\n await this.db.read();\n return this.db.data.sessions.filter(s => \n s.queryPath === queryPath && s.status === 'active'\n );\n }\n\n /**\n * Clean up old sessions based on retention policy\n */\n async cleanupOldSessions(): Promise {\n const cutoffDate = new Date();\n cutoffDate.setDate(cutoffDate.getDate() - this.config.retentionDays);\n const cutoffTimestamp = cutoffDate.toISOString();\n\n await this.db.read();\n const sessionsToRemove = this.db.data.sessions.filter(s => \n s.endTime && s.endTime < cutoffTimestamp\n );\n\n if (sessionsToRemove.length > 0) {\n this.db.data.sessions = this.db.data.sessions.filter(s => \n !s.endTime || s.endTime >= cutoffTimestamp\n );\n await this.db.write();\n\n logger.info(`Cleaned up ${sessionsToRemove.length} old sessions`);\n }\n }\n\n /**\n * Get configuration\n */\n getConfig(): MonitoringConfig {\n return this.config;\n }\n\n /**\n * Update configuration\n */\n async updateConfig(configUpdate: Partial): Promise {\n this.config = MonitoringConfigSchema.parse({\n ...this.config,\n ...configUpdate,\n });\n\n // Update config.json file only\n const configPath = join(this.storageDir, 'config.json');\n writeFileSync(configPath, JSON.stringify(this.config, null, 2));\n\n logger.info('Updated monitoring configuration');\n }\n}\n\n/**\n * Parse boolean environment variable\n */\nfunction parseBoolEnv(envVar: string | undefined, defaultValue: boolean): boolean {\n if (envVar === undefined) return defaultValue;\n return envVar.toLowerCase() === 'true' || envVar === '1';\n}\n\n// Export singleton instance with environment variable support\nexport const sessionDataManager = new SessionDataManager({\n storageLocation: process.env.MONITORING_STORAGE_LOCATION || join(getProjectTmpBase(), '.ql-mcp-tracking'),\n enableMonitoringTools: parseBoolEnv(process.env.ENABLE_MONITORING_TOOLS, false),\n});", "import { z } from 'zod';\n\n/**\n * Monitoring and Reporting types for CodeQL Development MCP Server\n * Based on the specification in docs/mcp-server-monitoring-and-reporting.md\n */\n\n/**\n * MCP Call Record - captures individual MCP tool calls\n */\nexport const MCPCallRecordSchema = z.object({\n callId: z.string(),\n timestamp: z.string(), // ISO timestamp\n toolName: z.string(),\n parameters: z.record(z.any()),\n result: z.any(),\n success: z.boolean(),\n duration: z.number(), // milliseconds\n nextSuggestedTool: z.string().optional(),\n});\n\nexport type MCPCallRecord = z.infer;\n\n/**\n * Test Execution Record - captures query compilation and test runs\n */\nexport const TestExecutionRecordSchema = z.object({\n executionId: z.string(),\n timestamp: z.string(),\n type: z.enum(['compilation', 'test_run', 'database_build']),\n success: z.boolean(),\n details: z.record(z.any()),\n metrics: z.object({\n passRate: z.number().optional(),\n coverage: z.number().optional(),\n performance: z.number().optional(),\n }).optional(),\n});\n\nexport type TestExecutionRecord = z.infer;\n\n/**\n * Quality Score Record - multi-dimensional quality assessment\n */\nexport const QualityScoreRecordSchema = z.object({\n scoreId: z.string(),\n timestamp: z.string(),\n overallScore: z.number().min(0).max(100), // 0-100\n dimensions: z.object({\n syntacticCorrectness: z.number().min(0).max(100),\n testCoverageResults: z.number().min(0).max(100),\n documentationQuality: z.number().min(0).max(100),\n functionalCorrectness: z.number().min(0).max(100),\n }),\n grade: z.enum(['A', 'B', 'C', 'D', 'F']),\n recommendations: z.array(z.string()),\n});\n\nexport type QualityScoreRecord = z.infer;\n\n/**\n * Query State - current state of the query development\n */\nexport const QueryStateSchema = z.object({\n filesPresent: z.array(z.string()),\n compilationStatus: z.enum(['unknown', 'success', 'failed']),\n testStatus: z.enum(['unknown', 'passing', 'failing', 'no_tests']),\n documentationStatus: z.enum(['unknown', 'present', 'missing', 'incomplete']),\n lastActivity: z.string(), // ISO timestamp\n});\n\nexport type QueryState = z.infer;\n\n/**\n * Query Development Session - main data structure for tracking\n */\nexport const QueryDevelopmentSessionSchema = z.object({\n // Session Metadata\n sessionId: z.string(),\n queryPath: z.string(),\n language: z.string(),\n queryType: z.string().optional(),\n description: z.string().optional(),\n startTime: z.string(), // ISO timestamp\n endTime: z.string().optional(), // ISO timestamp\n status: z.enum(['active', 'completed', 'failed', 'abandoned']),\n\n // MCP Call History\n mcpCalls: z.array(MCPCallRecordSchema),\n\n // Test Execution Records\n testExecutions: z.array(TestExecutionRecordSchema),\n\n // Quality Metrics\n qualityScores: z.array(QualityScoreRecordSchema),\n\n // Development State\n currentState: QueryStateSchema,\n recommendations: z.array(z.string()),\n nextSuggestedTool: z.string().optional(),\n});\n\nexport type QueryDevelopmentSession = z.infer;\n\n/**\n * Session Filter for listing and searching\n */\nexport const SessionFilterSchema = z.object({\n queryPath: z.string().optional(),\n status: z.string().optional(),\n dateRange: z.tuple([z.string(), z.string()]).optional(),\n language: z.string().optional(),\n queryType: z.string().optional(),\n});\n\nexport type SessionFilter = z.infer;\n\n/**\n * Comparison Report for analyzing multiple sessions\n */\nexport const ComparisonReportSchema = z.object({\n sessionIds: z.array(z.string()),\n dimensions: z.array(z.string()),\n timestamp: z.string(),\n results: z.record(z.any()),\n});\n\nexport type ComparisonReport = z.infer;\n\n/**\n * Aggregate Report for batch analysis\n */\nexport const AggregateReportSchema = z.object({\n filters: SessionFilterSchema,\n timestamp: z.string(),\n totalSessions: z.number(),\n successRate: z.number(),\n averageQualityScore: z.number(),\n commonPatterns: z.array(z.string()),\n recommendations: z.array(z.string()),\n});\n\nexport type AggregateReport = z.infer;\n\n/**\n * Export Result for data export operations\n */\nexport const ExportResultSchema = z.object({\n format: z.enum(['json', 'html', 'markdown']),\n filename: z.string(),\n content: z.string(),\n timestamp: z.string(),\n});\n\nexport type ExportResult = z.infer;\n\n/**\n * Functional Test Result for automated testing\n */\nexport const FunctionalTestResultSchema = z.object({\n sessionId: z.string(),\n queryPath: z.string(),\n passed: z.boolean(),\n criteria: z.record(z.any()),\n details: z.record(z.any()),\n timestamp: z.string(),\n});\n\nexport type FunctionalTestResult = z.infer;\n\n/**\n * Test Report for comprehensive test analysis\n */\nexport const TestReportSchema = z.object({\n sessionIds: z.array(z.string()),\n criteria: z.record(z.any()),\n timestamp: z.string(),\n overallPassRate: z.number(),\n results: z.array(FunctionalTestResultSchema),\n summary: z.record(z.any()),\n});\n\nexport type TestReport = z.infer;\n\n/**\n * Monitoring Configuration\n */\nexport const MonitoringConfigSchema = z.object({\n storageLocation: z.string().default('.ql-mcp-tracking/'),\n autoTrackSessions: z.boolean().default(true),\n retentionDays: z.number().default(90),\n includeCallParameters: z.boolean().default(true),\n includeCallResults: z.boolean().default(true),\n maxActiveSessionsPerQuery: z.number().default(3),\n scoringFrequency: z.enum(['per_call', 'periodic', 'manual']).default('per_call'),\n archiveCompletedSessions: z.boolean().default(true),\n enableRecommendations: z.boolean().default(true),\n enableMonitoringTools: z.boolean().default(false), // Opt-in: session_* tools disabled by default for end-users\n});\n\nexport type MonitoringConfig = z.infer;"], + "mappings": "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", "names": ["type", "resolve", "setTimeout", "resolve", "setTimeout", "clearTimeout", "join", "resolve", "spawn", "delimiter", "EventEmitter", "clearTimeout", "setTimeout", "resolve", "spawn", "delimiter", "EventEmitter", "clearTimeout", "setTimeout", "resolve", "mkdirSync", "join", "type", "packageRootDir", "resolve", "existsSync", "delimiter", "dirname", "isAbsolute", "binary", "getServerManager", "resolve", "pathToFileURL", "z", "readFileSync", "dirname", "isAbsolute", "mkdirSync", "mkdirSync", "existsSync", "join", "resolve", "timestamp", "writeFileSync", "existsSync", "mkdirSync", "basename", "dirname", "isAbsolute", "join", "resolve", "logger", "executeCodeQLCommand", "basename", "mkdirSync", "dirname", "z", "z", "z", "z", "z", "z", "z", "z", "z", "z", "readFile", "z", "exception", "map", "schema", "type", "extend", "str", "string", "z", "z", "z", "z", "z", "existsSync", "readdirSync", "readFileSync", "statSync", "join", "z", "readFileSync", "existsSync", "readdirSync", "join", "statSync", "z", "existsSync", "readdirSync", "readFileSync", "statSync", "join", "z", "existsSync", "readdirSync", "join", "statSync", "timestamp", "readFileSync", "z", "existsSync", "readdirSync", "readFileSync", "statSync", "join", "z", "existsSync", "readdirSync", "join", "statSync", "timestamp", "readFileSync", "z", "z", "z", "z", "z", "existsSync", "mkdirSync", "writeFileSync", "basename", "dirname", "join", "z", "readFileSync", "basename", "z", "existsSync", "dirname", "mkdirSync", "join", "writeFileSync", "z", "writeFileSync", "readFileSync", "existsSync", "join", "dirname", "basename", "mkdirSync", "parseEvaluatorLog", "formatAsJson", "formatAsMermaid", "z", "z", "z", "z", "z", "z", "join", "resolve", "resolve", "join", "z", "z", "resolve", "z", "z", "z", "z", "z", "z", "z", "z", "z", "z", "z", "z", "z", "z", "z", "z", "z", "z", "z", "z", "fs", "path", "getLanguageExtension", "z", "readFileSync", "join", "dirname", "fileURLToPath", "__filename", "__dirname", "z", "join", "pathToFileURL", "isAbsolute", "resolve", "pathToFileURL", "getUserWorkspaceDir", "pathToFileURL", "join", "z", "readFile", "isAbsolute", "resolve", "pathToFileURL", "isAbsolute", "resolve", "pathToFileURL", "readFile", "z", "z", "readFileSync", "existsSync", "join", "join", "existsSync", "readFileSync", "z", "basename", "readFileSync", "join", "dirname", "fileURLToPath", "__filename", "__dirname", "z", "basename", "z", "randomUUID", "readFileSync", "writeFileSync", "path", "path", "readFileSync", "str", "writeFileSync", "parse", "mkdirSync", "writeFileSync", "join", "randomUUID", "z", "join", "mkdirSync", "writeFileSync", "randomUUID", "z", "timestamp", "randomUUID", "resolve", "pathToFileURL"] } diff --git a/server/src/lib/cli-tool-registry.ts b/server/src/lib/cli-tool-registry.ts index 01570089..4b3a7599 100644 --- a/server/src/lib/cli-tool-registry.ts +++ b/server/src/lib/cli-tool-registry.ts @@ -83,8 +83,8 @@ export function registerCLITool(server: McpServer, definition: CLIToolDefinition // Separate positional arguments from named options // Extract tool-specific parameters that should not be passed to CLI // Note: format is extracted for tools that use it internally but not on CLI - // For codeql_bqrs_interpret, codeql_bqrs_decode, codeql_generate_query-help, and codeql_database_analyze, format should be passed to CLI - const formatShouldBePassedToCLI = name === 'codeql_bqrs_interpret' || name === 'codeql_bqrs_decode' || name === 'codeql_generate_query-help' || name === 'codeql_database_analyze'; + // For codeql_bqrs_interpret, codeql_bqrs_decode, codeql_bqrs_info, codeql_generate_query-help, and codeql_database_analyze, format should be passed to CLI + const formatShouldBePassedToCLI = name === 'codeql_bqrs_interpret' || name === 'codeql_bqrs_decode' || name === 'codeql_bqrs_info' || name === 'codeql_generate_query-help' || name === 'codeql_database_analyze'; const extractedParams = formatShouldBePassedToCLI ? { @@ -384,6 +384,12 @@ export function registerCLITool(server: McpServer, definition: CLIToolDefinition options.output = join(queryLogDir, 'results.bqrs'); } } + + // Ensure the parent directory of --output exists (the CLI will not create it) + if (options.output && typeof options.output === 'string') { + const outputDir = dirname(options.output); + mkdirSync(outputDir, { recursive: true }); + } } let result: CLIExecutionResult; @@ -425,24 +431,33 @@ export function registerCLITool(server: McpServer, definition: CLIToolDefinition // Post-execution processing for codeql_query_run if (name === 'codeql_query_run' && result.success && queryLogDir) { - // Generate SARIF interpretation if results.bqrs exists + // Generate SARIF interpretation if results.bqrs exists and query path is known const bqrsPath = options.output as string; - const sarifPath = join(queryLogDir, 'results.sarif'); + const sarifPath = join(queryLogDir, 'results-interpreted.sarif'); + + // The query file path is the last positional argument (set during query resolution) + const queryFilePath = positionalArgs.length > 0 ? positionalArgs[positionalArgs.length - 1] : undefined; - if (existsSync(bqrsPath)) { + if (existsSync(bqrsPath) && queryFilePath) { try { - const sarifResult = await executeCodeQLCommand( - 'bqrs interpret', - { format: 'sarif-latest', output: sarifPath }, - [bqrsPath] + const sarifResult = await interpretBQRSFile( + bqrsPath, + queryFilePath, + 'sarif-latest', + sarifPath, + logger ); if (sarifResult.success) { logger.info(`Generated SARIF interpretation at ${sarifPath}`); + } else { + logger.warn(`SARIF interpretation returned error: ${sarifResult.error || sarifResult.stderr}`); } } catch (error) { logger.warn(`Failed to generate SARIF interpretation: ${error}`); } + } else if (existsSync(bqrsPath) && !queryFilePath) { + logger.warn('Skipping SARIF interpretation: query file path not available'); } // Process evaluation results diff --git a/server/src/tools/codeql/bqrs-decode.ts b/server/src/tools/codeql/bqrs-decode.ts index 206f64e7..568c6a24 100644 --- a/server/src/tools/codeql/bqrs-decode.ts +++ b/server/src/tools/codeql/bqrs-decode.ts @@ -1,5 +1,12 @@ /** * CodeQL BQRS decode tool + * + * Decodes BQRS (Binary Query Result Set) files to human-readable formats. + * Use `list_query_run_results` to discover BQRS files from previous query runs, + * then decode them with this tool. For long-running queries (codeql_query_run) + * or suites (codeql_database_analyze), the BQRS file is located at + * `/results.bqrs`. Use `codeql_bqrs_info` first to discover available + * result sets and column schemas. */ import { z } from 'zod'; @@ -7,22 +14,41 @@ import { CLIToolDefinition, createCodeQLSchemas, createBQRSResultProcessor } fro export const codeqlBqrsDecodeTool: CLIToolDefinition = { name: 'codeql_bqrs_decode', - description: 'Decode BQRS result files to human-readable formats', + description: + 'Decode BQRS result files to human-readable formats (text, csv, json). ' + + 'Typical workflow: (1) use list_query_run_results to find BQRS paths from previous codeql_query_run or codeql_database_analyze runs, ' + + '(2) use codeql_bqrs_info to discover result sets and column schemas, ' + + '(3) decode specific result sets with this tool. ' + + 'For large result sets, use --rows to paginate.', command: 'codeql', subcommand: 'bqrs decode', inputSchema: { files: z.array(z.string()).describe('BQRS file(s) to decode'), output: createCodeQLSchemas.output(), - format: z.enum(['csv', 'json']).optional().describe('Output format'), - 'max-paths': z.number().optional().describe('Maximum number of paths to output'), - 'start-at': z.number().optional().describe('Start output at result number'), - 'max-results': z.number().optional().describe('Maximum number of results'), + format: z.enum(['csv', 'json', 'text', 'bqrs']).optional() + .describe('Output format: text (human-readable table, default), csv, json (streaming JSON), or bqrs (binary, requires --output)'), + 'result-set': z.string().optional() + .describe('Decode a specific result set by name (use codeql_bqrs_info to list available sets). If omitted, all result sets are decoded.'), + 'sort-key': z.string().optional() + .describe('Sort by column(s): comma-separated column indices (0-based)'), + 'sort-direction': z.string().optional() + .describe('Sort direction(s): comma-separated "asc" or "desc" per column'), + 'no-titles': z.boolean().optional() + .describe('Omit column titles for text and csv formats'), + entities: z.string().optional() + .describe('Control entity column display: comma-separated list of url, string, id, all'), + rows: z.number().optional() + .describe('Maximum number of rows to output (for pagination). Use with --start-at for paging.'), + 'start-at': z.number().optional() + .describe('Byte offset to start decoding from (get from codeql_bqrs_info or previous JSON output "next" pointer). Must be used with --rows.'), verbose: createCodeQLSchemas.verbose(), additionalArgs: createCodeQLSchemas.additionalArgs() }, examples: [ 'codeql bqrs decode --format=csv --output=results.csv results.bqrs', - 'codeql bqrs decode --format=json --max-results=100 results.bqrs' + 'codeql bqrs decode --format=json --rows=100 results.bqrs', + 'codeql bqrs decode --result-set=#select --format=csv results.bqrs', + 'codeql bqrs decode --format=json --entities=url,string results.bqrs' ], resultProcessor: createBQRSResultProcessor() }; \ No newline at end of file diff --git a/server/src/tools/codeql/bqrs-info.ts b/server/src/tools/codeql/bqrs-info.ts index 8891da18..c4fa2e4f 100644 --- a/server/src/tools/codeql/bqrs-info.ts +++ b/server/src/tools/codeql/bqrs-info.ts @@ -1,5 +1,10 @@ /** * CodeQL BQRS info tool + * + * Lists result sets, column schemas, and row counts in a BQRS file. + * Use this tool before codeql_bqrs_decode to discover available result + * sets and their column types. BQRS files are produced by codeql_query_run + * and codeql_database_analyze — use list_query_run_results to find them. */ import { z } from 'zod'; @@ -7,17 +12,28 @@ import { CLIToolDefinition, createCodeQLSchemas, createBQRSResultProcessor } fro export const codeqlBqrsInfoTool: CLIToolDefinition = { name: 'codeql_bqrs_info', - description: 'Get metadata and information about BQRS result files', + description: + 'Get metadata about BQRS result files: lists result sets, column names/types, and row counts. ' + + 'Use before codeql_bqrs_decode to discover available result sets (e.g., "#select", "edges", "nodes"). ' + + 'BQRS files are found at /results.bqrs — use list_query_run_results to discover them. ' + + 'Use --format=json with --paginate-rows to get byte offsets for paginated decoding with codeql_bqrs_decode --start-at.', command: 'codeql', subcommand: 'bqrs info', inputSchema: { files: z.array(z.string()).describe('BQRS file(s) to examine'), + format: z.enum(['text', 'json']).optional() + .describe('Output format: text (default) or json. Use json for machine-readable output and pagination offset computation.'), + 'paginate-rows': z.number().optional() + .describe('Compute byte offsets for pagination at intervals of this many rows. Use with --format=json. Offsets can be passed to codeql_bqrs_decode --start-at.'), + 'paginate-result-set': z.string().optional() + .describe('Compute pagination offsets only for this result set name'), verbose: createCodeQLSchemas.verbose(), additionalArgs: createCodeQLSchemas.additionalArgs() }, examples: [ 'codeql bqrs info results.bqrs', - 'codeql bqrs info --verbose results.bqrs' + 'codeql bqrs info --format=json results.bqrs', + 'codeql bqrs info --format=json --paginate-rows=100 --paginate-result-set=#select results.bqrs' ], resultProcessor: createBQRSResultProcessor() }; \ No newline at end of file diff --git a/server/src/tools/codeql/database-analyze.ts b/server/src/tools/codeql/database-analyze.ts index 4c2d5fa7..244fdf45 100644 --- a/server/src/tools/codeql/database-analyze.ts +++ b/server/src/tools/codeql/database-analyze.ts @@ -7,7 +7,11 @@ import { CLIToolDefinition } from '../../lib/cli-tool-registry'; export const codeqlDatabaseAnalyzeTool: CLIToolDefinition = { name: 'codeql_database_analyze', - description: 'Run queries or query suites against CodeQL databases', + description: + 'Run queries or query suites against CodeQL databases. ' + + 'Produces evaluator logs, BQRS results, and optionally SARIF output. ' + + 'Use list_codeql_databases to discover available databases, and register_database to register new ones. ' + + 'After analysis completes, use list_query_run_results to find result artifacts, then codeql_bqrs_info and codeql_bqrs_decode to inspect results.', command: 'codeql', subcommand: 'database analyze', inputSchema: { @@ -29,12 +33,14 @@ export const codeqlDatabaseAnalyzeTool: CLIToolDefinition = { .describe('Display tuple counts for each evaluation step in evaluator logs'), 'evaluator-log-level': z.number().min(1).max(5).optional() .describe('Evaluator log verbosity level (1-5, default 5)'), + rerun: z.boolean().optional() + .describe('Force re-evaluation of queries even if BQRS results already exist in the database. Without this, cached results are reused.'), verbose: z.boolean().optional().describe('Enable verbose output'), additionalArgs: z.array(z.string()).optional().describe('Additional command-line arguments') }, examples: [ 'codeql database analyze mydb queries.qls --format=sarif-latest --output=results.sarif', 'codeql database analyze mydb codeql/java-queries --format=csv', - 'codeql database analyze mydb queries.qls --format=sarif-latest --output=results.sarif --log-dir=/path/to/logs --tuple-counting' + 'codeql database analyze mydb queries.qls --format=sarif-latest --output=results.sarif --rerun --tuple-counting' ] }; \ No newline at end of file diff --git a/server/src/tools/codeql/list-databases.ts b/server/src/tools/codeql/list-databases.ts index f991ab88..0a55ff9a 100644 --- a/server/src/tools/codeql/list-databases.ts +++ b/server/src/tools/codeql/list-databases.ts @@ -127,7 +127,7 @@ export async function discoverDatabases( export function registerListDatabasesTool(server: McpServer): void { server.tool( 'list_codeql_databases', - 'List CodeQL databases discovered in configured base directories (set via CODEQL_DATABASES_BASE_DIRS env var). Returns path, language, CLI version, and creation time for each database.', + 'List CodeQL databases discovered in configured base directories (set via CODEQL_DATABASES_BASE_DIRS env var). Returns path, language, CLI version, and creation time for each database. Use the returned database paths with codeql_query_run or codeql_database_analyze to run queries against them.', { language: z .string() diff --git a/server/src/tools/codeql/list-query-run-results.ts b/server/src/tools/codeql/list-query-run-results.ts index ed612589..90a8d85b 100644 --- a/server/src/tools/codeql/list-query-run-results.ts +++ b/server/src/tools/codeql/list-query-run-results.ts @@ -5,6 +5,11 @@ * Scans each directory in `CODEQL_QUERY_RUN_RESULTS_DIRS` for subdirectories * matching the `.ql-` naming convention used by vscode-codeql. * Reports which artifacts (evaluator logs, BQRS, SARIF) are present in each run. + * + * Supports filtering by: + * - `queryName` — exact match on the query file name (e.g., "UI5Xss.ql") + * - `language` — filter by CodeQL language extracted from query.log db-scheme path + * - `queryPath` — substring or exact match against the full query file path */ import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js'; @@ -15,31 +20,138 @@ import { getQueryRunResultsDirs } from '../../lib/discovery-config'; import { logger } from '../../utils/logger'; export interface QueryRunResult { + databasePath?: string; hasBqrs: boolean; hasEvaluatorLog: boolean; + hasQueryLog: boolean; hasSarif: boolean; + hasSummaryLog: boolean; + language?: string; path: string; queryName: string; + queryPath?: string; runId: string; timestamp?: string; } +/** + * Metadata extracted from a vscode-codeql query.log file. + */ +export interface QueryLogMetadata { + databasePath?: string; + language?: string; + queryPath?: string; +} + +/** + * Filters for narrowing query run results. + */ +export interface QueryRunResultsFilter { + language?: string; + queryName?: string; + queryPath?: string; +} + /** * Pattern matching vscode-codeql query run directory names: `.ql-` */ const QUERY_RUN_DIR_PATTERN = /^(.+\.ql)-(.+)$/; +/** + * Pattern matching the `runQuery called with ` line in query.log. + * Example: `[2026-02-15 12:52:37] [SPAMMY] execute query-server2> runQuery called with /path/to/Query.ql` + */ +const RUN_QUERY_PATTERN = /runQuery called with\s+(\S+)/; + +/** + * Pattern matching the `--dbscheme=` argument in query.log when it + * includes the database root directory with the `db-/` segment. + * Example: `--dbscheme=/databases/my-db/db-javascript/semmlecode.javascript.dbscheme` + */ +const DBSCHEME_DB_PATH_PATTERN = /--dbscheme=(.+?)\/db-(\w+)\//; + +/** + * Fallback pattern matching language from the semmlecode dbscheme filename. + * Matches both `semmlecode..dbscheme` and `semmlecode.dbscheme` + * (the latter is used by Java). Also matches dbscheme paths from QL packs + * like `codeql/-all/`. + * + * Examples: + * - `semmlecode.javascript.dbscheme` → javascript + * - `semmlecode.python.dbscheme` → python + * - `codeql/javascript-all/2.6.20/semmlecode.javascript.dbscheme` → javascript + * - `semmlecode.dbscheme` (Java) → java (from `db-java/` or `codeql/java-all/`) + */ +const DBSCHEME_LANGUAGE_PATTERN = /semmlecode\.(\w+)\.dbscheme/; + +/** + * Fallback pattern to extract language from QL pack path in dbscheme references. + * Example: `codeql/javascript-all/2.6.20/` → javascript + */ +const QLPACK_LANGUAGE_PATTERN = /codeql\/(\w+)-all\//; + +/** + * Parse a vscode-codeql query.log file to extract metadata about the query run. + * + * Extracts: + * - `queryPath` — from the `runQuery called with ` line + * - `databasePath` — the database root from the `--dbscheme=` argument (when available) + * - `language` — from `db-/` segment, or `semmlecode..dbscheme`, + * or `codeql/-all/` QL pack path + * + * @param logContent - Raw content of the query.log file + * @returns Extracted metadata (fields are undefined if not found) + */ +export function parseQueryLogMetadata(logContent: string): QueryLogMetadata { + const metadata: QueryLogMetadata = {}; + + // Extract query path from runQuery line + const runQueryMatch = RUN_QUERY_PATTERN.exec(logContent); + if (runQueryMatch) { + metadata.queryPath = runQueryMatch[1]; + } + + // Try to extract database path and language from --dbscheme=/db-/ + const dbPathMatch = DBSCHEME_DB_PATH_PATTERN.exec(logContent); + if (dbPathMatch) { + metadata.databasePath = dbPathMatch[1]; + metadata.language = dbPathMatch[2]; + } + + // If language wasn't found from db path, try semmlecode..dbscheme + if (!metadata.language) { + const langMatch = DBSCHEME_LANGUAGE_PATTERN.exec(logContent); + if (langMatch) { + metadata.language = langMatch[1]; + } + } + + // Last resort: extract from codeql/-all/ QL pack path + if (!metadata.language) { + const packMatch = QLPACK_LANGUAGE_PATTERN.exec(logContent); + if (packMatch) { + metadata.language = packMatch[1]; + } + } + + return metadata; +} + /** * Discover query run result directories in the given search paths. * * @param resultsDirs - Directories to scan for per-run subdirectories - * @param queryName - Optional query name filter (e.g., "UI5Xss.ql") + * @param filter - Optional filters: queryName, language, queryPath * @returns List of discovered query run results with artifact inventory */ export async function discoverQueryRunResults( resultsDirs: string[], - queryName?: string, + filter?: QueryRunResultsFilter | string, ): Promise { + // Backward-compatible: if filter is a string, treat as queryName + const normalizedFilter: QueryRunResultsFilter | undefined = + typeof filter === 'string' ? { queryName: filter } : filter; + const results: QueryRunResult[] = []; for (const dir of resultsDirs) { @@ -74,8 +186,8 @@ export async function discoverQueryRunResults( const [, name, runId] = match; - // Apply query name filter - if (queryName && name !== queryName) { + // Apply query name filter (cheap, no I/O needed) + if (normalizedFilter?.queryName && name !== normalizedFilter.queryName) { continue; } @@ -83,6 +195,8 @@ export async function discoverQueryRunResults( const hasEvaluatorLog = existsSync(join(entryPath, 'evaluator-log.jsonl')); const hasBqrs = existsSync(join(entryPath, 'results.bqrs')); const hasSarif = existsSync(join(entryPath, 'results-interpreted.sarif')); + const hasQueryLog = existsSync(join(entryPath, 'query.log')); + const hasSummaryLog = existsSync(join(entryPath, 'evaluator-log.summary.jsonl')); // Read timestamp if available let timestamp: string | undefined; @@ -95,12 +209,51 @@ export async function discoverQueryRunResults( } } + // Parse query.log for metadata (queryPath, language, databasePath) + let metadata: QueryLogMetadata = {}; + if (hasQueryLog) { + try { + const logContent = readFileSync(join(entryPath, 'query.log'), 'utf-8'); + metadata = parseQueryLogMetadata(logContent); + } catch { + // Ignore read errors + } + } + + // Apply language filter (requires metadata from query.log) + if (normalizedFilter?.language && metadata.language !== normalizedFilter.language) { + continue; + } + + // Apply queryPath filter (substring or exact match) + if (normalizedFilter?.queryPath) { + if (!metadata.queryPath) { + continue; + } + const filterPath = normalizedFilter.queryPath; + const isExact = filterPath.startsWith('/'); + if (isExact) { + if (metadata.queryPath !== filterPath) { + continue; + } + } else { + if (!metadata.queryPath.toLowerCase().includes(filterPath.toLowerCase())) { + continue; + } + } + } + results.push({ + databasePath: metadata.databasePath, hasBqrs, hasEvaluatorLog, + hasQueryLog, hasSarif, + hasSummaryLog, + language: metadata.language, path: entryPath, queryName: name, + queryPath: metadata.queryPath, runId, timestamp, }); @@ -116,14 +269,26 @@ export async function discoverQueryRunResults( export function registerListQueryRunResultsTool(server: McpServer): void { server.tool( 'list_query_run_results', - 'List discovered query run result directories (set via CODEQL_QUERY_RUN_RESULTS_DIRS env var). Returns path, query name, timestamp, and available artifacts for each run.', + 'List discovered query run result directories (set via CODEQL_QUERY_RUN_RESULTS_DIRS env var). Returns path, query name, timestamp, language, query file path, and available artifacts (evaluator-log, bqrs, sarif, query.log, summary) for each run. Filter by queryName, language, or queryPath to narrow results. Use the returned BQRS paths with codeql_bqrs_decode or codeql_bqrs_info to inspect query results.', { + language: z + .string() + .optional() + .describe( + 'Filter by CodeQL language (e.g., "javascript", "python", "java"). Extracted from the database path in query.log. Runs without a query.log are excluded when this filter is set.', + ), queryName: z .string() .optional() .describe('Filter results by query name (e.g., "UI5Xss.ql")'), + queryPath: z + .string() + .optional() + .describe( + 'Filter by query file path. Absolute paths match exactly; relative paths/substrings match case-insensitively. Requires query.log to be present.', + ), }, - async ({ queryName }) => { + async ({ language, queryName, queryPath }) => { try { const resultsDirs = getQueryRunResultsDirs(); @@ -138,10 +303,22 @@ export function registerListQueryRunResultsTool(server: McpServer): void { }; } - const runs = await discoverQueryRunResults(resultsDirs, queryName); + const filter: QueryRunResultsFilter = {}; + if (queryName) filter.queryName = queryName; + if (language) filter.language = language; + if (queryPath) filter.queryPath = queryPath; + + const runs = await discoverQueryRunResults( + resultsDirs, + Object.keys(filter).length > 0 ? filter : undefined, + ); if (runs.length === 0) { - const filterMsg = queryName ? ` for query "${queryName}"` : ''; + const filterParts: string[] = []; + if (queryName) filterParts.push(`query "${queryName}"`); + if (language) filterParts.push(`language "${language}"`); + if (queryPath) filterParts.push(`path "${queryPath}"`); + const filterMsg = filterParts.length > 0 ? ` for ${filterParts.join(', ')}` : ''; return { content: [ { @@ -158,12 +335,18 @@ export function registerListQueryRunResultsTool(server: McpServer): void { ...runs.map((run) => { const artifacts: string[] = []; if (run.hasEvaluatorLog) artifacts.push('evaluator-log'); + if (run.hasSummaryLog) artifacts.push('summary-log'); if (run.hasBqrs) artifacts.push('bqrs'); if (run.hasSarif) artifacts.push('sarif'); + if (run.hasQueryLog) artifacts.push('query-log'); const parts = [` ${run.queryName} (${run.runId})`]; parts.push(` Path: ${run.path}`); if (run.timestamp) parts.push(` Timestamp: ${run.timestamp}`); + if (run.language) parts.push(` Language: ${run.language}`); + if (run.queryPath) parts.push(` Query: ${run.queryPath}`); + if (run.databasePath) parts.push(` Database: ${run.databasePath}`); parts.push(` Artifacts: ${artifacts.length > 0 ? artifacts.join(', ') : 'none'}`); + if (run.hasBqrs) parts.push(` BQRS: ${join(run.path, 'results.bqrs')}`); return parts.join('\n'); }), ]; diff --git a/server/src/tools/codeql/query-run.ts b/server/src/tools/codeql/query-run.ts index e4cf8437..8018215c 100644 --- a/server/src/tools/codeql/query-run.ts +++ b/server/src/tools/codeql/query-run.ts @@ -7,7 +7,10 @@ import { CLIToolDefinition, createCodeQLSchemas } from '../../lib/cli-tool-regis export const codeqlQueryRunTool: CLIToolDefinition = { name: 'codeql_query_run', - description: 'Execute a CodeQL query against a database. Use either "query" parameter for direct file path OR "queryName" + "queryLanguage" for pre-defined tool queries.', + description: + 'Execute a CodeQL query against a database. Use either "query" parameter for direct file path OR "queryName" + "queryLanguage" for pre-defined tool queries. ' + + 'Produces evaluator logs and BQRS results in a log directory. ' + + 'Use list_codeql_databases to discover databases, list_query_run_results to find previous results, and codeql_bqrs_decode to inspect BQRS output.', command: 'codeql', subcommand: 'query run', inputSchema: { diff --git a/server/test/src/tools/codeql/bqrs-decode.test.ts b/server/test/src/tools/codeql/bqrs-decode.test.ts new file mode 100644 index 00000000..f000db7d --- /dev/null +++ b/server/test/src/tools/codeql/bqrs-decode.test.ts @@ -0,0 +1,75 @@ +/** + * Tests for codeql_bqrs_decode tool definition + * + * Validates that the tool schema matches the actual `codeql bqrs decode` CLI + * options. These tests were written after discovering that the original schema + * contained non-existent CLI options (--max-results, --max-paths) that caused + * runtime failures when passed to the CLI. + */ + +import { describe, expect, it } from 'vitest'; +import { codeqlBqrsDecodeTool } from '../../../../src/tools/codeql/bqrs-decode'; + +describe('codeql_bqrs_decode tool definition', () => { + it('should have correct tool name', () => { + expect(codeqlBqrsDecodeTool.name).toBe('codeql_bqrs_decode'); + }); + + it('should use codeql bqrs decode subcommand', () => { + expect(codeqlBqrsDecodeTool.command).toBe('codeql'); + expect(codeqlBqrsDecodeTool.subcommand).toBe('bqrs decode'); + }); + + it('should have files as required positional input', () => { + expect(codeqlBqrsDecodeTool.inputSchema).toHaveProperty('files'); + }); + + it('should support result-set parameter for selecting specific result sets', () => { + expect(codeqlBqrsDecodeTool.inputSchema).toHaveProperty('result-set'); + }); + + it('should support rows parameter for pagination (not max-results)', () => { + // --rows is the correct CLI option for limiting output rows + expect(codeqlBqrsDecodeTool.inputSchema).toHaveProperty('rows'); + // --max-results does not exist in the codeql bqrs decode CLI + expect(codeqlBqrsDecodeTool.inputSchema).not.toHaveProperty('max-results'); + }); + + it('should support start-at parameter for pagination byte offset', () => { + expect(codeqlBqrsDecodeTool.inputSchema).toHaveProperty('start-at'); + }); + + it('should support entities parameter for controlling entity display', () => { + expect(codeqlBqrsDecodeTool.inputSchema).toHaveProperty('entities'); + }); + + it('should support sort-key and sort-direction parameters', () => { + expect(codeqlBqrsDecodeTool.inputSchema).toHaveProperty('sort-key'); + expect(codeqlBqrsDecodeTool.inputSchema).toHaveProperty('sort-direction'); + }); + + it('should support no-titles parameter', () => { + expect(codeqlBqrsDecodeTool.inputSchema).toHaveProperty('no-titles'); + }); + + it('should support text format in addition to csv and json', () => { + // Format enum should include text (human-readable table, the default) + // and bqrs (binary, requires --output) + expect(codeqlBqrsDecodeTool.inputSchema).toHaveProperty('format'); + }); + + it('should not have non-existent CLI options', () => { + // These options do not exist in codeql bqrs decode + expect(codeqlBqrsDecodeTool.inputSchema).not.toHaveProperty('max-results'); + expect(codeqlBqrsDecodeTool.inputSchema).not.toHaveProperty('max-paths'); + }); + + it('should have examples', () => { + expect(codeqlBqrsDecodeTool.examples).toBeDefined(); + expect(codeqlBqrsDecodeTool.examples!.length).toBeGreaterThan(0); + }); + + it('should have a custom result processor', () => { + expect(codeqlBqrsDecodeTool.resultProcessor).toBeDefined(); + }); +}); diff --git a/server/test/src/tools/codeql/bqrs-info.test.ts b/server/test/src/tools/codeql/bqrs-info.test.ts new file mode 100644 index 00000000..422038fd --- /dev/null +++ b/server/test/src/tools/codeql/bqrs-info.test.ts @@ -0,0 +1,46 @@ +/** + * Tests for codeql_bqrs_info tool definition + * + * Validates that the tool schema matches the actual `codeql bqrs info` CLI + * options, including pagination support for use with codeql_bqrs_decode. + */ + +import { describe, expect, it } from 'vitest'; +import { codeqlBqrsInfoTool } from '../../../../src/tools/codeql/bqrs-info'; + +describe('codeql_bqrs_info tool definition', () => { + it('should have correct tool name', () => { + expect(codeqlBqrsInfoTool.name).toBe('codeql_bqrs_info'); + }); + + it('should use codeql bqrs info subcommand', () => { + expect(codeqlBqrsInfoTool.command).toBe('codeql'); + expect(codeqlBqrsInfoTool.subcommand).toBe('bqrs info'); + }); + + it('should have files as required positional input', () => { + expect(codeqlBqrsInfoTool.inputSchema).toHaveProperty('files'); + }); + + it('should support format parameter (text or json)', () => { + expect(codeqlBqrsInfoTool.inputSchema).toHaveProperty('format'); + }); + + it('should support paginate-rows for computing byte offsets', () => { + expect(codeqlBqrsInfoTool.inputSchema).toHaveProperty('paginate-rows'); + }); + + it('should support paginate-result-set for targeted pagination', () => { + expect(codeqlBqrsInfoTool.inputSchema).toHaveProperty('paginate-result-set'); + }); + + it('should have examples including pagination usage', () => { + expect(codeqlBqrsInfoTool.examples).toBeDefined(); + expect(codeqlBqrsInfoTool.examples!.length).toBeGreaterThan(0); + // At least one example should show pagination + const paginationExample = codeqlBqrsInfoTool.examples!.find( + (e) => e.includes('paginate-rows'), + ); + expect(paginationExample).toBeDefined(); + }); +}); diff --git a/server/test/src/tools/codeql/list-query-run-results.test.ts b/server/test/src/tools/codeql/list-query-run-results.test.ts index b4408268..5918cadd 100644 --- a/server/test/src/tools/codeql/list-query-run-results.test.ts +++ b/server/test/src/tools/codeql/list-query-run-results.test.ts @@ -8,6 +8,7 @@ import { join } from 'path'; import { createTestTempDir, cleanupTestTempDir } from '../../../utils/temp-dir'; import { discoverQueryRunResults, + parseQueryLogMetadata, QueryRunResult, } from '../../../../src/tools/codeql/list-query-run-results'; @@ -99,7 +100,7 @@ describe('list_query_run_results', () => { } // Act - const result = await discoverQueryRunResults([testDir], 'UI5Xss.ql'); + const result = await discoverQueryRunResults([testDir], { queryName: 'UI5Xss.ql' }); // Assert expect(result).toHaveLength(2); @@ -137,5 +138,316 @@ describe('list_query_run_results', () => { expect(result).toHaveLength(1); expect(result[0].timestamp).toBe('2026-02-16T15:30:00.000Z'); }); + + it('should extract queryPath and databasePath from query.log', async () => { + // Arrange: create a run directory with a realistic query.log + const runDir = join(testDir, 'UI5Xss.ql-meta1'); + mkdirSync(runDir, { recursive: true }); + writeFileSync(join(runDir, 'timestamp'), '2026-02-18T10:00:00Z'); + writeFileSync( + join(runDir, 'query.log'), + [ + '[2026-02-15 12:52:37] [SPAMMY] execute query-server2> runQuery called with /path/to/src/UI5Xss/UI5Xss.ql', + '[2026-02-15 12:52:40] Calling plumbing command: codeql resolve upgrades --dbscheme=/path/to/databases/my-db/db-javascript/semmlecode.javascript.dbscheme --format=json', + ].join('\n'), + ); + + // Act + const result = await discoverQueryRunResults([testDir]); + + // Assert + expect(result).toHaveLength(1); + expect(result[0].queryPath).toBe('/path/to/src/UI5Xss/UI5Xss.ql'); + expect(result[0].databasePath).toBe('/path/to/databases/my-db'); + expect(result[0].language).toBe('javascript'); + }); + + it('should filter by language when query.log provides it', async () => { + // Arrange: create runs with different languages + const jsRun = join(testDir, 'XssQuery.ql-js1'); + mkdirSync(jsRun, { recursive: true }); + writeFileSync(join(jsRun, 'timestamp'), 'x'); + writeFileSync( + join(jsRun, 'query.log'), + '[2026-02-15 12:52:40] Calling plumbing command: codeql resolve upgrades --dbscheme=/dbs/my-js-db/db-javascript/semmlecode.javascript.dbscheme --format=json\n', + ); + + const pyRun = join(testDir, 'SqlInjection.ql-py1'); + mkdirSync(pyRun, { recursive: true }); + writeFileSync(join(pyRun, 'timestamp'), 'x'); + writeFileSync( + join(pyRun, 'query.log'), + '[2026-02-15 12:52:40] Calling plumbing command: codeql resolve upgrades --dbscheme=/dbs/my-py-db/db-python/semmlecode.python.dbscheme --format=json\n', + ); + + const noLogRun = join(testDir, 'Other.ql-nolog'); + mkdirSync(noLogRun, { recursive: true }); + writeFileSync(join(noLogRun, 'timestamp'), 'x'); + + // Act: filter by javascript language + const jsResults = await discoverQueryRunResults([testDir], { language: 'javascript' }); + + // Assert: only the javascript run matches + expect(jsResults).toHaveLength(1); + expect(jsResults[0].queryName).toBe('XssQuery.ql'); + expect(jsResults[0].language).toBe('javascript'); + }); + + it('should filter by queryPath substring', async () => { + // Arrange: create runs with query.log containing different query paths + const run1 = join(testDir, 'UI5Xss.ql-qp1'); + mkdirSync(run1, { recursive: true }); + writeFileSync(join(run1, 'timestamp'), 'x'); + writeFileSync( + join(run1, 'query.log'), + '[2026-02-15 12:52:37] [SPAMMY] execute query-server2> runQuery called with /repo/javascript/frameworks/ui5/src/UI5Xss/UI5Xss.ql\n', + ); + + const run2 = join(testDir, 'LogInjection.ql-qp2'); + mkdirSync(run2, { recursive: true }); + writeFileSync(join(run2, 'timestamp'), 'x'); + writeFileSync( + join(run2, 'query.log'), + '[2026-02-15 12:52:37] [SPAMMY] execute query-server2> runQuery called with /repo/javascript/frameworks/cap/src/LogInjection/LogInjection.ql\n', + ); + + // Act: filter by queryPath containing "ui5" + const results = await discoverQueryRunResults([testDir], { queryPath: 'ui5' }); + + // Assert + expect(results).toHaveLength(1); + expect(results[0].queryName).toBe('UI5Xss.ql'); + expect(results[0].queryPath).toBe('/repo/javascript/frameworks/ui5/src/UI5Xss/UI5Xss.ql'); + }); + + it('should filter by exact queryPath', async () => { + // Arrange + const run1 = join(testDir, 'UI5Xss.ql-exact1'); + mkdirSync(run1, { recursive: true }); + writeFileSync(join(run1, 'timestamp'), 'x'); + writeFileSync( + join(run1, 'query.log'), + '[2026-02-15 12:52:37] [SPAMMY] execute query-server2> runQuery called with /repo/src/UI5Xss/UI5Xss.ql\n', + ); + + // Act: filter by exact query path + const results = await discoverQueryRunResults([testDir], { + queryPath: '/repo/src/UI5Xss/UI5Xss.ql', + }); + + // Assert + expect(results).toHaveLength(1); + expect(results[0].queryPath).toBe('/repo/src/UI5Xss/UI5Xss.ql'); + }); + + it('should combine queryName and language filters', async () => { + // Arrange: create multiple runs + const jsXss = join(testDir, 'Xss.ql-combo1'); + mkdirSync(jsXss, { recursive: true }); + writeFileSync(join(jsXss, 'timestamp'), 'x'); + writeFileSync( + join(jsXss, 'query.log'), + '[ts] --dbscheme=/dbs/jsdb/db-javascript/semmlecode.javascript.dbscheme\n', + ); + + const pyXss = join(testDir, 'Xss.ql-combo2'); + mkdirSync(pyXss, { recursive: true }); + writeFileSync(join(pyXss, 'timestamp'), 'x'); + writeFileSync( + join(pyXss, 'query.log'), + '[ts] --dbscheme=/dbs/pydb/db-python/semmlecode.python.dbscheme\n', + ); + + const jsLog = join(testDir, 'LogInjection.ql-combo3'); + mkdirSync(jsLog, { recursive: true }); + writeFileSync(join(jsLog, 'timestamp'), 'x'); + writeFileSync( + join(jsLog, 'query.log'), + '[ts] --dbscheme=/dbs/jsdb2/db-javascript/semmlecode.javascript.dbscheme\n', + ); + + // Act: filter by both queryName=Xss.ql and language=javascript + const results = await discoverQueryRunResults([testDir], { + queryName: 'Xss.ql', + language: 'javascript', + }); + + // Assert: only the JS Xss run matches + expect(results).toHaveLength(1); + expect(results[0].queryName).toBe('Xss.ql'); + expect(results[0].language).toBe('javascript'); + }); + + it('should return runs without metadata when query.log is absent and no filter applied', async () => { + // Arrange: run dir without query.log + const runDir = join(testDir, 'NoLog.ql-nolog1'); + mkdirSync(runDir, { recursive: true }); + writeFileSync(join(runDir, 'timestamp'), '2026-02-18T00:00:00Z'); + + // Act: no filters + const results = await discoverQueryRunResults([testDir]); + + // Assert + expect(results).toHaveLength(1); + expect(results[0].queryPath).toBeUndefined(); + expect(results[0].databasePath).toBeUndefined(); + expect(results[0].language).toBeUndefined(); + }); + + it('should exclude runs without metadata when language filter is applied', async () => { + // Arrange: run without query.log + const runDir = join(testDir, 'NoLog.ql-excl1'); + mkdirSync(runDir, { recursive: true }); + writeFileSync(join(runDir, 'timestamp'), 'x'); + + // Act: filter by language excludes runs where language is unknown + const results = await discoverQueryRunResults([testDir], { language: 'javascript' }); + + // Assert + expect(results).toHaveLength(0); + }); + + it('should detect hasQueryLog and hasSummaryLog artifacts', async () => { + // Arrange: run with query.log and summary log + const runDir = join(testDir, 'Full.ql-artif1'); + mkdirSync(runDir, { recursive: true }); + writeFileSync(join(runDir, 'timestamp'), 'x'); + writeFileSync(join(runDir, 'query.log'), 'log content'); + writeFileSync(join(runDir, 'evaluator-log.summary.jsonl'), '{}'); + writeFileSync(join(runDir, 'evaluator-log.jsonl'), '{}'); + writeFileSync(join(runDir, 'results.bqrs'), ''); + + // Act + const results = await discoverQueryRunResults([testDir]); + + // Assert + expect(results).toHaveLength(1); + expect(results[0].hasQueryLog).toBe(true); + expect(results[0].hasSummaryLog).toBe(true); + expect(results[0].hasEvaluatorLog).toBe(true); + expect(results[0].hasBqrs).toBe(true); + }); + }); + + describe('parseQueryLogMetadata', () => { + it('should extract query path from runQuery line', () => { + // Arrange + const logContent = [ + '[2026-02-15 12:52:37] [SPAMMY] execute query-server2> runQuery called with /path/to/Query.ql', + '[2026-02-15 12:52:38] some other log line', + ].join('\n'); + + // Act + const metadata = parseQueryLogMetadata(logContent); + + // Assert + expect(metadata.queryPath).toBe('/path/to/Query.ql'); + }); + + it('should extract database path and language from dbscheme line', () => { + // Arrange + const logContent = + '[2026-02-15 12:52:40] Calling plumbing command: codeql resolve upgrades --dbscheme=/databases/my-db/db-javascript/semmlecode.javascript.dbscheme --format=json\n'; + + // Act + const metadata = parseQueryLogMetadata(logContent); + + // Assert + expect(metadata.databasePath).toBe('/databases/my-db'); + expect(metadata.language).toBe('javascript'); + }); + + it('should extract python language from dbscheme path', () => { + // Arrange + const logContent = + '[ts] --dbscheme=/dbs/pydb/db-python/semmlecode.python.dbscheme\n'; + + // Act + const metadata = parseQueryLogMetadata(logContent); + + // Assert + expect(metadata.language).toBe('python'); + expect(metadata.databasePath).toBe('/dbs/pydb'); + }); + + it('should extract java language from dbscheme path', () => { + // Arrange + const logContent = + '[ts] --dbscheme=/dbs/javadb/db-java/semmlecode.dbscheme\n'; + + // Act + const metadata = parseQueryLogMetadata(logContent); + + // Assert + expect(metadata.language).toBe('java'); + expect(metadata.databasePath).toBe('/dbs/javadb'); + }); + + it('should return empty metadata when log has no relevant lines', () => { + // Arrange + const logContent = 'some irrelevant log line\nanother line\n'; + + // Act + const metadata = parseQueryLogMetadata(logContent); + + // Assert + expect(metadata.queryPath).toBeUndefined(); + expect(metadata.databasePath).toBeUndefined(); + expect(metadata.language).toBeUndefined(); + }); + + it('should handle empty log content', () => { + // Act + const metadata = parseQueryLogMetadata(''); + + // Assert + expect(metadata.queryPath).toBeUndefined(); + expect(metadata.databasePath).toBeUndefined(); + expect(metadata.language).toBeUndefined(); + }); + + it('should extract language from semmlecode filename when db- path is absent', () => { + // Arrange: QL pack dbscheme path without db-/ segment + // This occurs when query.log only has the "Found dbscheme through QL packs" line + const logContent = [ + '[2026-02-15 12:58:31] [DETAILS] resolve library-path> Found dbscheme through QL packs: /Users/me/.codeql/packages/codeql/javascript-all/2.6.20/semmlecode.javascript.dbscheme.', + ' "dbscheme" : "/Users/me/.codeql/packages/codeql/javascript-all/2.6.20/semmlecode.javascript.dbscheme",', + ].join('\n'); + + // Act + const metadata = parseQueryLogMetadata(logContent); + + // Assert + expect(metadata.language).toBe('javascript'); + // No database path since there's no db-/ segment + expect(metadata.databasePath).toBeUndefined(); + }); + + it('should extract language from codeql/-all/ QL pack path as last resort', () => { + // Arrange: dbscheme reference only via QL pack path, no semmlecode..dbscheme + const logContent = + '[ts] "dbscheme" : "/home/user/.codeql/packages/codeql/python-all/1.2.3/semmlecode.dbscheme"\n'; + + // Act + const metadata = parseQueryLogMetadata(logContent); + + // Assert + expect(metadata.language).toBe('python'); + }); + + it('should prefer db- path over fallback patterns', () => { + // Arrange: log has both db- path AND QL pack path + const logContent = [ + '[ts] --dbscheme=/dbs/mydb/db-javascript/semmlecode.javascript.dbscheme', + '[ts] "dbscheme" : "/home/user/.codeql/packages/codeql/javascript-all/2.6.20/semmlecode.javascript.dbscheme"', + ].join('\n'); + + // Act + const metadata = parseQueryLogMetadata(logContent); + + // Assert + expect(metadata.language).toBe('javascript'); + expect(metadata.databasePath).toBe('/dbs/mydb'); + }); }); -}); +}); \ No newline at end of file From 27c26da8239500e454e6932df6b7aab93dedf966 Mon Sep 17 00:00:00 2001 From: Nathan Randall Date: Wed, 18 Feb 2026 09:22:48 -0700 Subject: [PATCH 04/14] bundle ql-mcp dist in new release-vsix workflow MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Rename the (unreleased) vscode extension: from: codeql-development-mcp-server-vscode to: vscode-codeql-development-mcp-server Make the VSIX self-contained by bundling the MCP server entry point (server/dist/), tool query packs (server/ql/*/tools/src/), and server package.json directly into the extension. The server is now launched via `node` against the bundled JS instead of downloading via `npx` at runtime. Falls back to npx in dev environments where the bundle is absent. New files: - scripts/bundle-server.js — copies server files into extension dir - .github/workflows/build-extension.yml — CI for extension PR/push - .github/workflows/release-vsix.yml — reusable release sub-workflow with release-vsix environment, consistent with release-npm.yml and release-codeql.yml patterns Updated release.yml to call release-vsix.yml and include the VSIX in GitHub Release artifacts as codeql-development-mcp-server.vsix. --- .github/workflows/build-extension.yml | 89 ++++++++++++ .github/workflows/release-vsix.yml | 136 ++++++++++++++++++ .github/workflows/release.yml | 26 +++- docs/vscode/extension.md | 1 + extensions/vscode/.vscodeignore | 5 + extensions/vscode/eslint.config.mjs | 2 +- extensions/vscode/package.json | 12 +- extensions/vscode/scripts/bundle-server.js | 68 +++++++++ extensions/vscode/src/bridge/storage-paths.ts | 2 +- extensions/vscode/src/server/mcp-provider.ts | 5 +- .../vscode/src/server/server-manager.ts | 65 +++++++-- .../vscode/test/bridge/storage-paths.test.ts | 4 +- .../vscode/test/server/server-manager.test.ts | 20 ++- .../test/suite/extension.integration.test.ts | 2 +- 14 files changed, 410 insertions(+), 27 deletions(-) create mode 100644 .github/workflows/build-extension.yml create mode 100644 .github/workflows/release-vsix.yml create mode 100644 extensions/vscode/scripts/bundle-server.js diff --git a/.github/workflows/build-extension.yml b/.github/workflows/build-extension.yml new file mode 100644 index 00000000..829def24 --- /dev/null +++ b/.github/workflows/build-extension.yml @@ -0,0 +1,89 @@ +name: Build Extension - CodeQL Development MCP Server + +on: + pull_request: + branches: ['main'] + paths: + - '.github/workflows/build-extension.yml' + - '.node-version' + - 'extensions/vscode/**' + - 'server/dist/**' + - 'server/ql/*/tools/src/**' + push: + branches: ['main'] + paths: + - '.github/workflows/build-extension.yml' + - '.node-version' + - 'extensions/vscode/**' + - 'server/dist/**' + - 'server/ql/*/tools/src/**' + workflow_dispatch: + +permissions: + contents: read + +jobs: + build-extension: + name: Build Extension + runs-on: ubuntu-latest + + steps: + - name: Build Extension - Checkout repository + uses: actions/checkout@v6 + + - name: Build Extension - Setup Node.js environment + uses: actions/setup-node@v6 + with: + cache: 'npm' + node-version-file: '.node-version' + + - name: Build Extension - Install dependencies + run: npm ci --include=optional + + - name: Build Extension - Build server (dependency) + run: npm run build -w server + + - name: Build Extension - Run extension tests with coverage + working-directory: extensions/vscode + run: npm run test:coverage + + - name: Build Extension - Bundle extension and server + working-directory: extensions/vscode + run: | + npm run clean + npm run lint + npm run bundle + npm run bundle:server + + - name: Build Extension - Verify VSIX packaging + working-directory: extensions/vscode + run: npx @vscode/vsce package --out codeql-development-mcp-server.vsix + + - name: Build Extension - Verify VSIX contents + working-directory: extensions/vscode + run: | + echo "## VSIX Contents" >> $GITHUB_STEP_SUMMARY + echo '```' >> $GITHUB_STEP_SUMMARY + npx @vscode/vsce ls 2>&1 | head -50 >> $GITHUB_STEP_SUMMARY + echo '```' >> $GITHUB_STEP_SUMMARY + + - name: Build Extension - Check for uncommitted changes + run: | + if [ -n "$(git status --porcelain)" ]; then + echo "❌ Uncommitted changes detected after build:" + git status --porcelain + git diff + exit 1 + else + echo "✅ No uncommitted changes after build" + fi + + - name: Build Extension - Summary + run: | + echo "## Build Extension Summary" >> $GITHUB_STEP_SUMMARY + echo "✅ ESLint checks completed" >> $GITHUB_STEP_SUMMARY + echo "✅ All tests passed with coverage" >> $GITHUB_STEP_SUMMARY + echo "✅ Extension bundled successfully" >> $GITHUB_STEP_SUMMARY + echo "✅ Server bundled into extension" >> $GITHUB_STEP_SUMMARY + echo "✅ VSIX packaging verified" >> $GITHUB_STEP_SUMMARY + echo "✅ No uncommitted changes detected" >> $GITHUB_STEP_SUMMARY diff --git a/.github/workflows/release-vsix.yml b/.github/workflows/release-vsix.yml new file mode 100644 index 00000000..76a67d86 --- /dev/null +++ b/.github/workflows/release-vsix.yml @@ -0,0 +1,136 @@ +name: Release VSIX - Build and Package VS Code Extension + +on: + workflow_call: + inputs: + version: + description: 'Release version tag (e.g., vX.Y.Z). Must start with "v".' + required: true + type: string + outputs: + release_name: + description: 'The release name without "v" prefix (e.g., X.Y.Z)' + value: ${{ jobs.publish-vsix.outputs.release_name }} + version: + description: 'The full version string with "v" prefix (e.g., vX.Y.Z)' + value: ${{ jobs.publish-vsix.outputs.version }} + vsix_name: + description: 'The VSIX filename (e.g., codeql-development-mcp-server.vsix)' + value: ${{ jobs.publish-vsix.outputs.vsix_name }} + +# Note: This workflow is called exclusively via workflow_call from release.yml. +# It does NOT have a workflow_dispatch trigger to keep release.yml as the single +# entry point for all release operations. To re-build the VSIX standalone, +# use workflow_dispatch on release.yml with publish_npm=false and +# publish_codeql_packs=false. + +permissions: + contents: read + +jobs: + publish-vsix: + name: Build and Package VSIX Extension + runs-on: ubuntu-latest + + environment: release-vsix + + permissions: + contents: read + + outputs: + release_name: ${{ steps.version.outputs.release_name }} + version: ${{ steps.version.outputs.version }} + vsix_name: ${{ steps.package.outputs.vsix_name }} + + steps: + - name: VSIX - Validate and parse version + id: version + run: | + VERSION="${{ inputs.version }}" + if [[ ! "${VERSION}" =~ ^v ]]; then + echo "::error::Version '${VERSION}' must start with 'v'" + exit 1 + fi + echo "version=${VERSION}" >> $GITHUB_OUTPUT + echo "release_name=${VERSION#v}" >> $GITHUB_OUTPUT + + - name: VSIX - Checkout tag + uses: actions/checkout@v6 + with: + ref: refs/tags/${{ steps.version.outputs.version }} + + - name: VSIX - Setup Node.js + uses: actions/setup-node@v6 + with: + cache: 'npm' + node-version-file: '.node-version' + + - name: VSIX - Install dependencies + run: npm ci --include=optional + + - name: VSIX - Validate version consistency + run: | + RELEASE_NAME="${{ steps.version.outputs.release_name }}" + EXTENSION_VERSION=$(node -e "console.log(require('./extensions/vscode/package.json').version)") + if [ "${EXTENSION_VERSION}" != "${RELEASE_NAME}" ]; then + echo "::error::Extension version (${EXTENSION_VERSION}) does not match release (${RELEASE_NAME})" + exit 1 + fi + echo "✅ Extension version matches release: ${RELEASE_NAME}" + + - name: VSIX - Build server + run: npm run build -w server + + - name: VSIX - Package VSIX + id: package + working-directory: extensions/vscode + run: | + VSIX_NAME="codeql-development-mcp-server.vsix" + npx @vscode/vsce package --out "${VSIX_NAME}" + echo "vsix_name=${VSIX_NAME}" >> $GITHUB_OUTPUT + echo "✅ Packaged ${VSIX_NAME}" + + - name: VSIX - Verify VSIX contents + working-directory: extensions/vscode + run: | + echo "Verifying bundled server and tool query packs..." + npx @vscode/vsce ls 2>&1 | tee /tmp/vsix-contents.txt + + # Verify critical files are included + for required in \ + "dist/extension.cjs" \ + "server/dist/codeql-development-mcp-server.js" \ + "server/package.json" \ + "server/ql/javascript/tools/src/PrintAST/PrintAST.ql"; do + if grep -q "${required}" /tmp/vsix-contents.txt; then + echo " ✅ ${required}" + else + echo " ❌ Missing: ${required}" + exit 1 + fi + done + + - name: VSIX - Upload artifact + uses: actions/upload-artifact@v6 + with: + name: codeql-development-mcp-server-vsix-${{ steps.version.outputs.version }} + path: extensions/vscode/${{ steps.package.outputs.vsix_name }} + + - name: VSIX - Summary + run: | + VERSION="${{ steps.version.outputs.version }}" + VSIX_NAME="${{ steps.package.outputs.vsix_name }}" + VSIX_SIZE=$(du -h "extensions/vscode/${VSIX_NAME}" | cut -f1) + echo "## VSIX Build Summary" >> $GITHUB_STEP_SUMMARY + echo "" >> $GITHUB_STEP_SUMMARY + echo "| Property | Value |" >> $GITHUB_STEP_SUMMARY + echo "| -------- | ----- |" >> $GITHUB_STEP_SUMMARY + echo "| Version | ${VERSION} |" >> $GITHUB_STEP_SUMMARY + echo "| VSIX | \`${VSIX_NAME}\` |" >> $GITHUB_STEP_SUMMARY + echo "| Size | ${VSIX_SIZE} |" >> $GITHUB_STEP_SUMMARY + echo "" >> $GITHUB_STEP_SUMMARY + echo "### Bundled Contents" >> $GITHUB_STEP_SUMMARY + echo "- \`dist/extension.cjs\` — Extension entry point" >> $GITHUB_STEP_SUMMARY + echo "- \`server/dist/\` — Bundled MCP server" >> $GITHUB_STEP_SUMMARY + echo "- \`server/ql/*/tools/src/\` — CodeQL tool query packs" >> $GITHUB_STEP_SUMMARY + echo "- \`server/package.json\` — Server package metadata" >> $GITHUB_STEP_SUMMARY diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index a2bbaf49..7438321d 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -138,6 +138,22 @@ jobs: publish_codeql_packs: ${{ needs.resolve-version.outputs.publish_codeql_packs == 'true' }} version: ${{ needs.resolve-version.outputs.version }} + # ───────────────────────────────────────────────────────────────────────────── + # Step 3c: Build the VS Code extension VSIX + # + # Checks out the clean tag, builds the server and extension (including the + # bundled MCP server), and packages the self-contained VSIX. Runs in parallel + # with npm/CodeQL publishing since it only needs the tag. + # ───────────────────────────────────────────────────────────────────────────── + build-vsix: + name: Build VSIX Extension + needs: [resolve-version, ensure-tag] + permissions: + contents: read + uses: ./.github/workflows/release-vsix.yml + with: + version: ${{ needs.resolve-version.outputs.version }} + # ───────────────────────────────────────────────────────────────────────────── # Step 4: Create GitHub Release # @@ -153,7 +169,7 @@ jobs: always() && !failure() && !cancelled() && needs.resolve-version.outputs.create_github_release == 'true' && needs.resolve-version.outputs.publish_npm == 'true' - needs: [resolve-version, ensure-tag, publish-npm, publish-codeql] + needs: [resolve-version, ensure-tag, publish-npm, publish-codeql, build-vsix] runs-on: ubuntu-latest permissions: @@ -171,6 +187,12 @@ jobs: name: codeql-tool-query-packs-${{ needs.resolve-version.outputs.version }} path: dist-packs + - name: Release - Download VSIX artifact + uses: actions/download-artifact@v6 + with: + name: codeql-development-mcp-server-vsix-${{ needs.resolve-version.outputs.version }} + path: dist-vsix + - name: Release - Create distribution directory run: | mkdir -p dist-package/server @@ -217,6 +239,7 @@ jobs: files: | codeql-development-mcp-server-${{ needs.resolve-version.outputs.version }}.tar.gz dist-packs/*.tar.gz + dist-vsix/codeql-development-mcp-server.vsix generate_release_notes: true tag_name: ${{ needs.resolve-version.outputs.version }} @@ -238,6 +261,7 @@ jobs: echo "| CodeQL pack publish | ⏭️ Skipped (packs bundled only) |" >> $GITHUB_STEP_SUMMARY fi echo "| Distribution archive | ✅ Created |" >> $GITHUB_STEP_SUMMARY + echo "| VSIX extension | ✅ Built |" >> $GITHUB_STEP_SUMMARY echo "| GitHub Release | ✅ Created |" >> $GITHUB_STEP_SUMMARY echo "" >> $GITHUB_STEP_SUMMARY echo "### Package Contents" >> $GITHUB_STEP_SUMMARY diff --git a/docs/vscode/extension.md b/docs/vscode/extension.md index eb172611..1bb583a6 100644 --- a/docs/vscode/extension.md +++ b/docs/vscode/extension.md @@ -54,6 +54,7 @@ On activation the extension: | --------------------------------- | ---------- | -------------------------------------------------------------- | | `codeql-mcp.autoInstall` | `true` | Automatically install/update the MCP server on activation | | `codeql-mcp.serverVersion` | `"latest"` | npm version to install (`"latest"` or a specific version) | +| `codeql-mcp.serverCommand` | `"node"` | Command to launch the MCP server (override for local dev) | | `codeql-mcp.watchCodeqlExtension` | `true` | Discover databases and query results from the CodeQL extension | | `codeql-mcp.additionalEnv` | `{}` | Extra environment variables for the MCP server process | diff --git a/extensions/vscode/.vscodeignore b/extensions/vscode/.vscodeignore index 383a8169..a0ec57ab 100644 --- a/extensions/vscode/.vscodeignore +++ b/extensions/vscode/.vscodeignore @@ -2,6 +2,7 @@ .vscode-test/** src/** test/** +scripts/** node_modules/** .gitignore tsconfig.json @@ -13,3 +14,7 @@ esbuild.config.js **/*.test.js **/*.map coverage/** + +# Include server/ bundle but exclude test/examples content +server/ql/*/tools/test/** +server/ql/*/examples/** diff --git a/extensions/vscode/eslint.config.mjs b/extensions/vscode/eslint.config.mjs index e7eb367f..5a698bd2 100644 --- a/extensions/vscode/eslint.config.mjs +++ b/extensions/vscode/eslint.config.mjs @@ -101,6 +101,6 @@ export default [ }, }, { - ignores: ['dist/', 'node_modules/', 'esbuild.config.js'], + ignores: ['dist/', 'node_modules/', 'esbuild.config.js', 'scripts/'], }, ]; diff --git a/extensions/vscode/package.json b/extensions/vscode/package.json index a35a37bf..50baf0f8 100644 --- a/extensions/vscode/package.json +++ b/extensions/vscode/package.json @@ -1,5 +1,5 @@ { - "name": "codeql-development-mcp-server-vscode", + "name": "vscode-codeql-development-mcp-server", "displayName": "CodeQL Development MCP Server", "description": "Automatically installs, configures, and manages the CodeQL Development MCP Server in VS Code.", "version": "2.24.1", @@ -60,14 +60,14 @@ }, "codeql-mcp.serverCommand": { "type": "string", - "default": "npx", - "description": "Command to launch the MCP server. Override to 'node' for local development builds." + "default": "node", + "description": "Command to launch the MCP server. The default 'node' runs the bundled server. Override to 'npx' to download from npm, or provide a custom path." }, "codeql-mcp.serverArgs": { "type": "array", "items": { "type": "string" }, "default": [], - "description": "Custom arguments for the MCP server command. When empty, defaults to ['-y', 'codeql-development-mcp-server']. Set to e.g. ['/path/to/server/dist/codeql-development-mcp-server.js'] when using serverCommand='node' for local development." + "description": "Custom arguments for the MCP server command. When empty, the bundled server entry point is used automatically. Set to e.g. ['/path/to/server/dist/codeql-development-mcp-server.js'] for local development." }, "codeql-mcp.watchCodeqlExtension": { "type": "boolean", @@ -110,12 +110,15 @@ "scripts": { "build": "npm run clean && npm run lint && npm run bundle", "bundle": "node esbuild.config.js", + "bundle:server": "node scripts/bundle-server.js", "clean": "rm -rf dist", "lint": "eslint src/ test/", "lint:fix": "eslint src/ test/ --fix", + "package": "vsce package --out codeql-development-mcp-server.vsix", "test": "vitest --run", "test:coverage": "vitest --run --coverage", "test:watch": "vitest --watch", + "vscode:prepublish": "npm run clean && npm run lint && npm run bundle && npm run bundle:server", "watch": "node esbuild.config.js --watch" }, "devDependencies": { @@ -124,6 +127,7 @@ "@types/node": "^22.15.0", "@types/vscode": "^1.99.0", "@vitest/coverage-v8": "^4.0.18", + "@vscode/vsce": "^3.3.2", "esbuild": "^0.27.3", "eslint": "^9.39.2", "eslint-config-prettier": "^10.1.8", diff --git a/extensions/vscode/scripts/bundle-server.js b/extensions/vscode/scripts/bundle-server.js new file mode 100644 index 00000000..b3f95dc7 --- /dev/null +++ b/extensions/vscode/scripts/bundle-server.js @@ -0,0 +1,68 @@ +/** + * bundle-server.js + * + * Copies the MCP server bundle, tool query packs, and server package.json + * into the extension's output directory so the VSIX is self-contained. + * + * Run via: npm run bundle:server + * Called automatically by: vscode:prepublish + * + * Resulting layout inside extensions/vscode/: + * server/ + * dist/codeql-development-mcp-server.js (bundled server) + * dist/codeql-development-mcp-server.js.map (source map) + * ql//tools/src/ (tool query packs) + * package.json (server package metadata) + */ + +import { cpSync, existsSync, mkdirSync, rmSync } from 'fs'; +import { dirname, join, resolve } from 'path'; +import { fileURLToPath } from 'url'; + +const __dirname = dirname(fileURLToPath(import.meta.url)); +const extensionRoot = resolve(__dirname, '..'); +const serverRoot = resolve(extensionRoot, '..', '..', 'server'); +const targetServerDir = join(extensionRoot, 'server'); + +// Languages with tool query packs +const LANGUAGES = [ + 'actions', 'cpp', 'csharp', 'go', 'java', + 'javascript', 'python', 'ruby', 'swift', +]; + +// Clean previous bundle +if (existsSync(targetServerDir)) { + rmSync(targetServerDir, { recursive: true, force: true }); +} + +// --- Server dist --- +const serverDist = join(serverRoot, 'dist'); +const targetDist = join(targetServerDir, 'dist'); +if (!existsSync(serverDist)) { + console.error('❌ Server dist/ not found. Run "npm run build -w server" first.'); + process.exit(1); +} +mkdirSync(targetDist, { recursive: true }); +cpSync(serverDist, targetDist, { recursive: true }); +console.log('✅ Copied server/dist/'); + +// --- Server package.json --- +const serverPkg = join(serverRoot, 'package.json'); +cpSync(serverPkg, join(targetServerDir, 'package.json')); +console.log('✅ Copied server/package.json'); + +// --- Tool query packs (ql//tools/src/) --- +for (const lang of LANGUAGES) { + const srcDir = join(serverRoot, 'ql', lang, 'tools', 'src'); + if (!existsSync(srcDir)) { + console.warn(`⚠️ Skipping ql/${lang}/tools/src/ (not found)`); + continue; + } + const targetDir = join(targetServerDir, 'ql', lang, 'tools', 'src'); + mkdirSync(targetDir, { recursive: true }); + cpSync(srcDir, targetDir, { recursive: true }); + console.log(`✅ Copied ql/${lang}/tools/src/`); +} + +console.log(''); +console.log('🎉 Server bundle complete. The extension VSIX will be self-contained.'); diff --git a/extensions/vscode/src/bridge/storage-paths.ts b/extensions/vscode/src/bridge/storage-paths.ts index c843831c..c2dd04d2 100644 --- a/extensions/vscode/src/bridge/storage-paths.ts +++ b/extensions/vscode/src/bridge/storage-paths.ts @@ -23,7 +23,7 @@ export class StoragePaths extends DisposableObject { constructor(private readonly context: vscode.ExtensionContext) { super(); // Our extension's globalStorageUri is something like: - // ...//advanced-security.codeql-development-mcp-server-vscode/ + // ...//advanced-security.vscode-codeql-development-mcp-server/ // The parent directory is the vscode global storage root. this.vsCodeGlobalStorageRoot = dirname(context.globalStorageUri.fsPath); } diff --git a/extensions/vscode/src/server/mcp-provider.ts b/extensions/vscode/src/server/mcp-provider.ts index 1f7d1007..75086655 100644 --- a/extensions/vscode/src/server/mcp-provider.ts +++ b/extensions/vscode/src/server/mcp-provider.ts @@ -8,8 +8,9 @@ import type { EnvironmentBuilder } from '../bridge/environment-builder'; * Implements `McpServerDefinitionProvider` to programmatically register * the `codeql-development-mcp-server` as an MCP server in VS Code. * - * The server is launched via `npx -y codeql-development-mcp-server` by default, - * using the **published** npm package — not any local development build. + * The server is launched from the bundled copy inside the VSIX by default + * (`node server/dist/codeql-development-mcp-server.js`). Falls back to + * `npx -y codeql-development-mcp-server` if the bundle is missing. * Override via `codeql-mcp.serverCommand` / `codeql-mcp.serverArgs` settings. */ export class McpProvider diff --git a/extensions/vscode/src/server/server-manager.ts b/extensions/vscode/src/server/server-manager.ts index 69db37c4..cd90b043 100644 --- a/extensions/vscode/src/server/server-manager.ts +++ b/extensions/vscode/src/server/server-manager.ts @@ -1,7 +1,7 @@ import * as vscode from 'vscode'; import { execFile } from 'child_process'; import { access, readFile, mkdir } from 'fs/promises'; -import { constants } from 'fs'; +import { accessSync, constants } from 'fs'; import { join } from 'path'; import { DisposableObject } from '../common/disposable'; import type { Logger } from '../common/logger'; @@ -9,6 +9,13 @@ import type { Logger } from '../common/logger'; const NPM_PACKAGE_NAME = 'codeql-development-mcp-server'; const SERVER_SUBDIR = 'mcp-server'; +/** + * Relative path from the extension root to the bundled MCP server entry point. + * The `vscode:prepublish` step copies `server/dist/` and `server/ql/` into the + * extension so the VSIX is self-contained. + */ +const BUNDLED_SERVER_ENTRY = 'server/dist/codeql-development-mcp-server.js'; + export interface InstallOptions { /** Force reinstall even if already installed. */ force?: boolean; @@ -23,14 +30,12 @@ export interface InstallOptions { * The local install serves two purposes: * 1. Provides the qlpack source files so PackInstaller can run * `codeql pack install` to fetch their CodeQL library dependencies. - * 2. Provides a fallback entry point if npx is not available. - * - * The MCP server itself is launched via `npx -y codeql-development-mcp-server` - * (the published npm package) — NOT the local install. This keeps a clean - * separation between the extension and the MCP server code. + * 2. Provides a fallback entry point if the bundled server is missing. * - * To test with a local development build of the MCP server instead, - * set `codeql-mcp.serverCommand` and `codeql-mcp.serverArgs` in settings. + * The MCP server is launched from the **bundled** copy inside the VSIX + * (`server/dist/codeql-development-mcp-server.js`) so the extension is + * fully self-contained. Override via `codeql-mcp.serverCommand` / + * `codeql-mcp.serverArgs` settings for local development. */ export class ServerManager extends DisposableObject { private readonly storageRoot: string; @@ -123,20 +128,44 @@ export class ServerManager extends DisposableObject { // Server launch configuration (for McpProvider) // --------------------------------------------------------------------------- + /** + * Absolute path to the bundled MCP server entry point inside the extension. + * Returns `undefined` if the bundled server is not present (e.g. dev build + * that hasn't run `vscode:prepublish` yet). + */ + getBundledServerPath(): string | undefined { + const extensionRoot = this.context.extensionUri.fsPath; + const candidate = join(extensionRoot, BUNDLED_SERVER_ENTRY); + try { + accessSync(candidate, constants.R_OK); + return candidate; + } catch { + return undefined; + } + } + /** * Get the command used to launch the MCP server process. - * Defaults to `"npx"`. Override via `codeql-mcp.serverCommand` setting - * to use a local development build instead. + * + * Default: `"node"` (runs the bundled server JS). Falls back to `"npx"` + * if the bundled server is missing. + * Override via `codeql-mcp.serverCommand` setting for local dev. */ getCommand(): string { const config = vscode.workspace.getConfiguration('codeql-mcp'); - return config.get('serverCommand', 'npx'); + const custom = config.get('serverCommand'); + if (custom && custom !== 'node') { + return custom; + } + // Use 'node' when bundled server exists, 'npx' as fallback + return this.getBundledServerPath() ? 'node' : 'npx'; } /** * Get the arguments for the MCP server launch command. - * Defaults to `["-y", "codeql-development-mcp-server"]` (or with - * `@` if `codeql-mcp.serverVersion` is pinned). + * + * Default: the bundled server entry point inside the VSIX. Falls back to + * `npx -y codeql-development-mcp-server` if the bundle is missing. * Override via `codeql-mcp.serverArgs` for local development. */ getArgs(): string[] { @@ -145,6 +174,16 @@ export class ServerManager extends DisposableObject { if (customArgs && customArgs.length > 0) { return customArgs; } + // Use bundled server if available + const bundled = this.getBundledServerPath(); + if (bundled) { + return [bundled]; + } + // Fallback: npx (for dev environments without a prepublish build) + this.logger.warn( + 'Bundled MCP server not found; falling back to npx. ' + + 'Run "npm run build" from the repo root to bundle the server.', + ); const version = config.get('serverVersion', 'latest'); const pkg = version === 'latest' diff --git a/extensions/vscode/test/bridge/storage-paths.test.ts b/extensions/vscode/test/bridge/storage-paths.test.ts index ed279acc..25af409c 100644 --- a/extensions/vscode/test/bridge/storage-paths.test.ts +++ b/extensions/vscode/test/bridge/storage-paths.test.ts @@ -5,8 +5,8 @@ import { StoragePaths } from '../../src/bridge/storage-paths'; function createMockContext() { return { - globalStorageUri: { fsPath: '/mock/global-storage/advanced-security.codeql-development-mcp-server-vscode' }, - storageUri: { fsPath: '/mock/workspace-storage/advanced-security.codeql-development-mcp-server-vscode' }, + globalStorageUri: { fsPath: '/mock/global-storage/advanced-security.vscode-codeql-development-mcp-server' }, + storageUri: { fsPath: '/mock/workspace-storage/advanced-security.vscode-codeql-development-mcp-server' }, } as any; } diff --git a/extensions/vscode/test/server/server-manager.test.ts b/extensions/vscode/test/server/server-manager.test.ts index 118cae3a..48c6b69d 100644 --- a/extensions/vscode/test/server/server-manager.test.ts +++ b/extensions/vscode/test/server/server-manager.test.ts @@ -11,11 +11,18 @@ vi.mock('fs/promises', () => ({ mkdir: vi.fn(), })); +vi.mock('fs', () => ({ + accessSync: vi.fn(), + constants: { R_OK: 4 }, +})); + import { execFile } from 'child_process'; import { access, readFile } from 'fs/promises'; +import { accessSync } from 'fs'; function createMockContext() { return { + extensionUri: { fsPath: '/mock/extension' }, globalStorageUri: { fsPath: '/mock/global-storage' }, globalState: { get: vi.fn(), @@ -79,20 +86,29 @@ describe('ServerManager', () => { expect(installed).toBe(true); }); - it('should default command to npx', () => { + it('should default command to npx when bundle is missing', () => { + vi.mocked(accessSync).mockImplementation(() => { throw new Error('ENOENT'); }); expect(manager.getCommand()).toBe('npx'); }); - it('should default args to npx -y codeql-development-mcp-server', () => { + it('should default args to npx -y codeql-development-mcp-server when bundle is missing', () => { + vi.mocked(accessSync).mockImplementation(() => { throw new Error('ENOENT'); }); const args = manager.getArgs(); expect(args).toEqual(['-y', 'codeql-development-mcp-server']); }); it('should provide a human-readable description', () => { + vi.mocked(accessSync).mockImplementation(() => { throw new Error('ENOENT'); }); const desc = manager.getDescription(); expect(desc).toBe('npx -y codeql-development-mcp-server'); }); + it('should use node with bundled server path when bundle exists', () => { + vi.mocked(accessSync).mockImplementation(() => undefined); + expect(manager.getCommand()).toBe('node'); + expect(manager.getArgs()).toEqual(['/mock/extension/server/dist/codeql-development-mcp-server.js']); + }); + it('should run npm install when installing', async () => { vi.mocked(execFile).mockImplementation( (_cmd: any, _args: any, _opts: any, callback: any) => { diff --git a/extensions/vscode/test/suite/extension.integration.test.ts b/extensions/vscode/test/suite/extension.integration.test.ts index e0cdd844..8be7ae4f 100644 --- a/extensions/vscode/test/suite/extension.integration.test.ts +++ b/extensions/vscode/test/suite/extension.integration.test.ts @@ -9,7 +9,7 @@ import * as assert from 'assert'; import * as vscode from 'vscode'; -const EXTENSION_ID = 'advanced-security.codeql-development-mcp-server-vscode'; +const EXTENSION_ID = 'advanced-security.vscode-codeql-development-mcp-server'; suite('Extension Integration Tests', () => { test('Extension should be present', () => { From bf95ff6a23f0fbb311d6a54ca02a31d783e14d1f Mon Sep 17 00:00:00 2001 From: Nathan Randall Date: Wed, 18 Feb 2026 18:00:03 -0700 Subject: [PATCH 05/14] Extension integration testing improvements - Include vscode-codeql workspace storage in CODEQL_DATABASES_BASE_DIRS alongside global storage (picks up databases from current workspace) - Add settings: additionalDatabaseDirs, additionalQueryRunResultsDirs, additionalMrvaRunResultsDirs for user-appended discovery directories - Add .gitignore for extension build artifacts (dist/, server/, *.vsix) - Update clean script to remove server/ and *.vsix - Fix launch.json: use npx for vitest (hoisted node_modules), add 5 debug configs (run ext, host tests, unit tests, current file, server) - Export environmentBuilder and serverManager from extension API - Add Extension Host integration tests: bridge env var path validation, MCP server definition tests - Add unit tests: storage paths workspace methods, env var multi-path assembly, user-configured dir appending, discovery var passthrough - Add extension host integration tests for common workspace states: - empty (no folders) vscode workspace; - single-root folder vscode workspace; - multi-root folder vscode workspace. --- .vscode/launch.json | 83 +++++- extensions/vscode/.gitignore | 5 + extensions/vscode/.vscodeignore | 1 - extensions/vscode/esbuild.config.js | 4 + extensions/vscode/package.json | 20 +- .../vscode/src/bridge/environment-builder.ts | 22 +- extensions/vscode/src/bridge/storage-paths.ts | 35 ++- extensions/vscode/src/extension.ts | 2 +- .../vscode/src/server/server-manager.ts | 29 +- .../test/bridge/environment-builder.test.ts | 68 +++++ .../vscode/test/bridge/storage-paths.test.ts | 28 ++ .../test-python-db/codeql-database.yml | 6 + .../queries/SqlInjection.ql-def456/timestamp | 1 + .../multi-root-workspace/folder-b/.gitkeep | 0 .../multi-root-workspace/test.code-workspace | 6 + .../test-javascript-db/codeql-database.yml | 6 + .../queries/ExampleQuery1.ql-abc123/timestamp | 1 + .../variant-analyses/10001/repo_states.json | 1 + .../variant-analyses/10001/timestamp | 1 + .../vscode/test/server/mcp-provider.test.ts | 18 ++ .../vscode/test/server/server-manager.test.ts | 13 + .../test/suite/bridge.integration.test.ts | 164 +++++++++++ .../test/suite/mcp-server.integration.test.ts | 61 +++++ .../suite/mcp-tool-e2e.integration.test.ts | 256 ++++++++++++++++++ .../workspace-scenario.integration.test.ts | 145 ++++++++++ 25 files changed, 951 insertions(+), 25 deletions(-) create mode 100644 extensions/vscode/.gitignore create mode 100644 extensions/vscode/test/fixtures/multi-root-workspace/folder-a/codeql-storage/databases/test-python-db/codeql-database.yml create mode 100644 extensions/vscode/test/fixtures/multi-root-workspace/folder-a/codeql-storage/queries/SqlInjection.ql-def456/timestamp create mode 100644 extensions/vscode/test/fixtures/multi-root-workspace/folder-b/.gitkeep create mode 100644 extensions/vscode/test/fixtures/multi-root-workspace/test.code-workspace create mode 100644 extensions/vscode/test/fixtures/single-folder-workspace/codeql-storage/databases/test-javascript-db/codeql-database.yml create mode 100644 extensions/vscode/test/fixtures/single-folder-workspace/codeql-storage/queries/ExampleQuery1.ql-abc123/timestamp create mode 100644 extensions/vscode/test/fixtures/single-folder-workspace/codeql-storage/variant-analyses/10001/repo_states.json create mode 100644 extensions/vscode/test/fixtures/single-folder-workspace/codeql-storage/variant-analyses/10001/timestamp create mode 100644 extensions/vscode/test/suite/bridge.integration.test.ts create mode 100644 extensions/vscode/test/suite/mcp-server.integration.test.ts create mode 100644 extensions/vscode/test/suite/mcp-tool-e2e.integration.test.ts create mode 100644 extensions/vscode/test/suite/workspace-scenario.integration.test.ts diff --git a/.vscode/launch.json b/.vscode/launch.json index 83509441..d65c4a97 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -2,33 +2,98 @@ "version": "0.2.0", "configurations": [ { - "name": "Run Extension", + "name": "Run Extension (vscode-codeql-development-mcp-server)", "type": "extensionHost", "request": "launch", "args": [ - "--extensionDevelopmentPath=${workspaceFolder}/extensions/vscode" + "--extensionDevelopmentPath=${workspaceFolder:codeql-development-mcp-server}/extensions/vscode" ], "outFiles": [ - "${workspaceFolder}/extensions/vscode/dist/**/*.js", - "${workspaceFolder}/extensions/vscode/dist/**/*.cjs" + "${workspaceFolder:codeql-development-mcp-server}/extensions/vscode/dist/**/*.js", + "${workspaceFolder:codeql-development-mcp-server}/extensions/vscode/dist/**/*.cjs" ], "preLaunchTask": "npm: bundle - extensions/vscode", "sourceMaps": true }, { - "name": "Extension Tests", + "name": "Extension Host Tests - No Workspace (vscode-codeql-development-mcp-server)", "type": "extensionHost", "request": "launch", "args": [ - "--extensionDevelopmentPath=${workspaceFolder}/extensions/vscode", - "--extensionTestsPath=${workspaceFolder}/extensions/vscode/dist/test/suite/index.cjs" + "--extensionDevelopmentPath=${workspaceFolder:codeql-development-mcp-server}/extensions/vscode", + "--extensionTestsPath=${workspaceFolder:codeql-development-mcp-server}/extensions/vscode/dist/test/suite/index.cjs" ], "outFiles": [ - "${workspaceFolder}/extensions/vscode/dist/**/*.js", - "${workspaceFolder}/extensions/vscode/dist/**/*.cjs" + "${workspaceFolder:codeql-development-mcp-server}/extensions/vscode/dist/**/*.js", + "${workspaceFolder:codeql-development-mcp-server}/extensions/vscode/dist/**/*.cjs" ], "preLaunchTask": "npm: bundle - extensions/vscode", "sourceMaps": true + }, + { + "name": "Extension Host Tests - Single Folder (vscode-codeql-development-mcp-server)", + "type": "extensionHost", + "request": "launch", + "args": [ + "--extensionDevelopmentPath=${workspaceFolder:codeql-development-mcp-server}/extensions/vscode", + "--extensionTestsPath=${workspaceFolder:codeql-development-mcp-server}/extensions/vscode/dist/test/suite/index.cjs", + "${workspaceFolder:codeql-development-mcp-server}/extensions/vscode/test/fixtures/single-folder-workspace" + ], + "outFiles": [ + "${workspaceFolder:codeql-development-mcp-server}/extensions/vscode/dist/**/*.js", + "${workspaceFolder:codeql-development-mcp-server}/extensions/vscode/dist/**/*.cjs" + ], + "preLaunchTask": "npm: bundle - extensions/vscode", + "sourceMaps": true + }, + { + "name": "Extension Host Tests - Multi-Root (vscode-codeql-development-mcp-server)", + "type": "extensionHost", + "request": "launch", + "args": [ + "--extensionDevelopmentPath=${workspaceFolder:codeql-development-mcp-server}/extensions/vscode", + "--extensionTestsPath=${workspaceFolder:codeql-development-mcp-server}/extensions/vscode/dist/test/suite/index.cjs", + "${workspaceFolder:codeql-development-mcp-server}/extensions/vscode/test/fixtures/multi-root-workspace/test.code-workspace" + ], + "outFiles": [ + "${workspaceFolder:codeql-development-mcp-server}/extensions/vscode/dist/**/*.js", + "${workspaceFolder:codeql-development-mcp-server}/extensions/vscode/dist/**/*.cjs" + ], + "preLaunchTask": "npm: bundle - extensions/vscode", + "sourceMaps": true + }, + { + "name": "Unit Tests (vscode-codeql-development-mcp-server)", + "type": "node", + "request": "launch", + "runtimeExecutable": "npx", + "runtimeArgs": ["vitest", "--run"], + "cwd": "${workspaceFolder:codeql-development-mcp-server}/extensions/vscode", + "sourceMaps": true, + "console": "integratedTerminal", + "internalConsoleOptions": "neverOpen" + }, + { + "name": "Unit Test - Current File (vscode-codeql-development-mcp-server)", + "type": "node", + "request": "launch", + "runtimeExecutable": "npx", + "runtimeArgs": ["vitest", "--run", "${relativeFile}"], + "cwd": "${workspaceFolder:codeql-development-mcp-server}/extensions/vscode", + "sourceMaps": true, + "console": "integratedTerminal", + "internalConsoleOptions": "neverOpen" + }, + { + "name": "Server Unit Tests (vscode-codeql-development-mcp-server)", + "type": "node", + "request": "launch", + "runtimeExecutable": "npx", + "runtimeArgs": ["vitest", "--run"], + "cwd": "${workspaceFolder:codeql-development-mcp-server}/server", + "sourceMaps": true, + "console": "integratedTerminal", + "internalConsoleOptions": "neverOpen" } ] } diff --git a/extensions/vscode/.gitignore b/extensions/vscode/.gitignore new file mode 100644 index 00000000..bffe25eb --- /dev/null +++ b/extensions/vscode/.gitignore @@ -0,0 +1,5 @@ +# Build artifacts +dist/ +server/ +coverage/ +*.vsix diff --git a/extensions/vscode/.vscodeignore b/extensions/vscode/.vscodeignore index a0ec57ab..7d6d899e 100644 --- a/extensions/vscode/.vscodeignore +++ b/extensions/vscode/.vscodeignore @@ -4,7 +4,6 @@ src/** test/** scripts/** node_modules/** -.gitignore tsconfig.json test/tsconfig.json vitest.config.ts diff --git a/extensions/vscode/esbuild.config.js b/extensions/vscode/esbuild.config.js index e29449af..4e045f90 100644 --- a/extensions/vscode/esbuild.config.js +++ b/extensions/vscode/esbuild.config.js @@ -34,7 +34,11 @@ const testSuiteConfig = { ...shared, entryPoints: [ 'test/suite/index.ts', + 'test/suite/bridge.integration.test.ts', 'test/suite/extension.integration.test.ts', + 'test/suite/mcp-server.integration.test.ts', + 'test/suite/mcp-tool-e2e.integration.test.ts', + 'test/suite/workspace-scenario.integration.test.ts', ], outdir: 'dist/test/suite', outfile: undefined, // outdir and outfile are mutually exclusive diff --git a/extensions/vscode/package.json b/extensions/vscode/package.json index 50baf0f8..f3f3227b 100644 --- a/extensions/vscode/package.json +++ b/extensions/vscode/package.json @@ -81,6 +81,24 @@ "additionalProperties": { "type": "string" } + }, + "codeql-mcp.additionalDatabaseDirs": { + "type": "array", + "items": { "type": "string" }, + "default": [], + "description": "Additional directories to search for CodeQL databases. Appended to CODEQL_DATABASES_BASE_DIRS alongside the vscode-codeql storage paths." + }, + "codeql-mcp.additionalMrvaRunResultsDirs": { + "type": "array", + "items": { "type": "string" }, + "default": [], + "description": "Additional directories containing MRVA run result subdirectories. Appended to CODEQL_MRVA_RUN_RESULTS_DIRS alongside the vscode-codeql variant analysis storage path." + }, + "codeql-mcp.additionalQueryRunResultsDirs": { + "type": "array", + "items": { "type": "string" }, + "default": [], + "description": "Additional directories containing query run result subdirectories. Appended to CODEQL_QUERY_RUN_RESULTS_DIRS alongside the vscode-codeql query storage path." } } }, @@ -111,7 +129,7 @@ "build": "npm run clean && npm run lint && npm run bundle", "bundle": "node esbuild.config.js", "bundle:server": "node scripts/bundle-server.js", - "clean": "rm -rf dist", + "clean": "rm -rf dist server *.vsix", "lint": "eslint src/ test/", "lint:fix": "eslint src/ test/ --fix", "package": "vsce package --out codeql-development-mcp-server.vsix", diff --git a/extensions/vscode/src/bridge/environment-builder.ts b/extensions/vscode/src/bridge/environment-builder.ts index dab0bdaa..f0b778ac 100644 --- a/extensions/vscode/src/bridge/environment-builder.ts +++ b/extensions/vscode/src/bridge/environment-builder.ts @@ -42,6 +42,9 @@ export class EnvironmentBuilder extends DisposableObject { const env: Record = {}; + // User configuration + const config = vscode.workspace.getConfiguration('codeql-mcp'); + // Transport mode is always stdio when launched from VS Code env.TRANSPORT_MODE = 'stdio'; @@ -78,17 +81,26 @@ export class EnvironmentBuilder extends DisposableObject { env.CODEQL_ADDITIONAL_PACKS = additionalPaths.join(':'); - // Database discovery directory for list_codeql_databases - env.CODEQL_DATABASES_BASE_DIRS = this.storagePaths.getDatabaseStoragePath(); + // Database discovery directories for list_codeql_databases + // Includes: global storage, workspace storage, and user-configured dirs + const dbDirs = [...this.storagePaths.getAllDatabaseStoragePaths()]; + const userDbDirs = config.get('additionalDatabaseDirs', []); + dbDirs.push(...userDbDirs); + env.CODEQL_DATABASES_BASE_DIRS = dbDirs.join(':'); // MRVA run results directory for variant analysis discovery - env.CODEQL_MRVA_RUN_RESULTS_DIRS = this.storagePaths.getVariantAnalysisStoragePath(); + const mrvaDirs = [this.storagePaths.getVariantAnalysisStoragePath()]; + const userMrvaDirs = config.get('additionalMrvaRunResultsDirs', []); + mrvaDirs.push(...userMrvaDirs); + env.CODEQL_MRVA_RUN_RESULTS_DIRS = mrvaDirs.join(':'); // Query run results directory for query history discovery - env.CODEQL_QUERY_RUN_RESULTS_DIRS = this.storagePaths.getQueryStoragePath(); + const queryDirs = [this.storagePaths.getQueryStoragePath()]; + const userQueryDirs = config.get('additionalQueryRunResultsDirs', []); + queryDirs.push(...userQueryDirs); + env.CODEQL_QUERY_RUN_RESULTS_DIRS = queryDirs.join(':'); // User-configured additional environment variables - const config = vscode.workspace.getConfiguration('codeql-mcp'); const additionalEnv = config.get>('additionalEnv', {}); for (const [key, value] of Object.entries(additionalEnv)) { env[key] = value; diff --git a/extensions/vscode/src/bridge/storage-paths.ts b/extensions/vscode/src/bridge/storage-paths.ts index c2dd04d2..8207d294 100644 --- a/extensions/vscode/src/bridge/storage-paths.ts +++ b/extensions/vscode/src/bridge/storage-paths.ts @@ -19,6 +19,7 @@ const VSCODE_CODEQL_EXTENSION_ID = 'GitHub.vscode-codeql'; */ export class StoragePaths extends DisposableObject { private readonly vsCodeGlobalStorageRoot: string; + private readonly vsCodeWorkspaceStorageRoot: string | undefined; constructor(private readonly context: vscode.ExtensionContext) { super(); @@ -26,6 +27,13 @@ export class StoragePaths extends DisposableObject { // ...//advanced-security.vscode-codeql-development-mcp-server/ // The parent directory is the vscode global storage root. this.vsCodeGlobalStorageRoot = dirname(context.globalStorageUri.fsPath); + + // Our extension's storageUri (workspace-scoped) is something like: + // ...///advanced-security.vscode-codeql-development-mcp-server/ + // The parent directory is this workspace's storage root. + if (context.storageUri) { + this.vsCodeWorkspaceStorageRoot = dirname(context.storageUri.fsPath); + } } /** Global storage directory for the vscode-codeql extension. */ @@ -34,13 +42,36 @@ export class StoragePaths extends DisposableObject { } /** - * Directory where vscode-codeql stores downloaded/managed databases. - * Databases are stored directly under the global storage path. + * Directory where vscode-codeql stores downloaded/managed databases + * at the global level (e.g. databases added from GitHub). */ getDatabaseStoragePath(): string { return this.getCodeqlGlobalStoragePath(); } + /** + * Directory where vscode-codeql stores workspace-scoped databases + * (e.g. databases created from repos in the current workspace). + * Returns `undefined` if no workspace is open. + */ + getWorkspaceDatabaseStoragePath(): string | undefined { + if (!this.vsCodeWorkspaceStorageRoot) return undefined; + return join(this.vsCodeWorkspaceStorageRoot, VSCODE_CODEQL_EXTENSION_ID); + } + + /** + * All database storage paths: global + workspace-scoped. + * Suitable for colon-joining into `CODEQL_DATABASES_BASE_DIRS`. + */ + getAllDatabaseStoragePaths(): string[] { + const paths = [this.getDatabaseStoragePath()]; + const workspacePath = this.getWorkspaceDatabaseStoragePath(); + if (workspacePath) { + paths.push(workspacePath); + } + return paths; + } + /** * Directory where vscode-codeql stores query results. * Path: `/queries/-/` diff --git a/extensions/vscode/src/extension.ts b/extensions/vscode/src/extension.ts index bf1b7804..bc5a849d 100644 --- a/extensions/vscode/src/extension.ts +++ b/extensions/vscode/src/extension.ts @@ -187,7 +187,7 @@ export async function activate( } logger.info('CodeQL Development MCP Server extension activated.'); - return { mcpProvider }; + return { environmentBuilder: envBuilder, mcpProvider, serverManager }; } export function deactivate(): void { diff --git a/extensions/vscode/src/server/server-manager.ts b/extensions/vscode/src/server/server-manager.ts index cd90b043..1ced2c8c 100644 --- a/extensions/vscode/src/server/server-manager.ts +++ b/extensions/vscode/src/server/server-manager.ts @@ -129,16 +129,33 @@ export class ServerManager extends DisposableObject { // --------------------------------------------------------------------------- /** - * Absolute path to the bundled MCP server entry point inside the extension. - * Returns `undefined` if the bundled server is not present (e.g. dev build - * that hasn't run `vscode:prepublish` yet). + * Absolute path to the MCP server entry point. + * + * Checks two locations: + * 1. **VSIX layout**: `/server/dist/codeql-development-mcp-server.js` + * (created by `bundle:server` during `vscode:prepublish`) + * 2. **Monorepo dev layout**: `/../../server/dist/codeql-development-mcp-server.js` + * (the adjacent server build when running from Extension Development Host) + * + * Returns `undefined` if neither location exists. */ getBundledServerPath(): string | undefined { const extensionRoot = this.context.extensionUri.fsPath; - const candidate = join(extensionRoot, BUNDLED_SERVER_ENTRY); + + // VSIX layout: server files bundled inside the extension + const vsixCandidate = join(extensionRoot, BUNDLED_SERVER_ENTRY); + try { + accessSync(vsixCandidate, constants.R_OK); + return vsixCandidate; + } catch { + // Not in VSIX layout — try monorepo + } + + // Monorepo dev layout: extensions/vscode/../../server/dist/... + const monorepoCandidate = join(extensionRoot, '..', '..', BUNDLED_SERVER_ENTRY); try { - accessSync(candidate, constants.R_OK); - return candidate; + accessSync(monorepoCandidate, constants.R_OK); + return monorepoCandidate; } catch { return undefined; } diff --git a/extensions/vscode/test/bridge/environment-builder.test.ts b/extensions/vscode/test/bridge/environment-builder.test.ts index 7c9342fd..ab3bd791 100644 --- a/extensions/vscode/test/bridge/environment-builder.test.ts +++ b/extensions/vscode/test/bridge/environment-builder.test.ts @@ -23,6 +23,11 @@ function createMockStoragePaths() { return { getCodeqlGlobalStoragePath: vi.fn().mockReturnValue('/mock/global-storage/GitHub.vscode-codeql'), getDatabaseStoragePath: vi.fn().mockReturnValue('/mock/global-storage/GitHub.vscode-codeql'), + getWorkspaceDatabaseStoragePath: vi.fn().mockReturnValue('/mock/workspace-storage/ws-123/GitHub.vscode-codeql'), + getAllDatabaseStoragePaths: vi.fn().mockReturnValue([ + '/mock/global-storage/GitHub.vscode-codeql', + '/mock/workspace-storage/ws-123/GitHub.vscode-codeql', + ]), getQueryStoragePath: vi.fn().mockReturnValue('/mock/global-storage/GitHub.vscode-codeql/queries'), getVariantAnalysisStoragePath: vi.fn().mockReturnValue('/mock/global-storage/GitHub.vscode-codeql/variant-analyses'), getGlobalStorageRoot: vi.fn().mockReturnValue('/mock/global-storage'), @@ -82,6 +87,23 @@ describe('EnvironmentBuilder', () => { expect(env.CODEQL_ADDITIONAL_PACKS).toContain('GitHub.vscode-codeql'); }); + it('should include CODEQL_DATABASES_BASE_DIRS with global and workspace storage paths', async () => { + const env = await builder.build(); + expect(env.CODEQL_DATABASES_BASE_DIRS).toBe( + '/mock/global-storage/GitHub.vscode-codeql:/mock/workspace-storage/ws-123/GitHub.vscode-codeql', + ); + }); + + it('should include CODEQL_QUERY_RUN_RESULTS_DIRS from storage paths', async () => { + const env = await builder.build(); + expect(env.CODEQL_QUERY_RUN_RESULTS_DIRS).toBe('/mock/global-storage/GitHub.vscode-codeql/queries'); + }); + + it('should include CODEQL_MRVA_RUN_RESULTS_DIRS from storage paths', async () => { + const env = await builder.build(); + expect(env.CODEQL_MRVA_RUN_RESULTS_DIRS).toBe('/mock/global-storage/GitHub.vscode-codeql/variant-analyses'); + }); + it('should omit CODEQL_PATH when CLI is not found', async () => { cliResolver.resolve.mockResolvedValue(undefined); builder.invalidate(); @@ -121,6 +143,52 @@ describe('EnvironmentBuilder', () => { expect(cliResolver.resolve).toHaveBeenCalledTimes(2); }); + it('should append user-configured dirs to CODEQL_DATABASES_BASE_DIRS', async () => { + const vscode = await import('vscode'); + const originalGetConfig = vscode.workspace.getConfiguration; + vscode.workspace.getConfiguration = () => ({ + get: (_key: string, defaultVal?: any) => { + if (_key === 'additionalDatabaseDirs') return ['/custom/databases']; + if (_key === 'additionalQueryRunResultsDirs') return []; + if (_key === 'additionalMrvaRunResultsDirs') return []; + return defaultVal; + }, + has: () => false, + inspect: () => undefined as any, + update: () => Promise.resolve(), + }) as any; + + builder.invalidate(); + const env = await builder.build(); + expect(env.CODEQL_DATABASES_BASE_DIRS).toContain('/custom/databases'); + expect(env.CODEQL_DATABASES_BASE_DIRS).toContain('/mock/global-storage/GitHub.vscode-codeql'); + + vscode.workspace.getConfiguration = originalGetConfig; + }); + + it('should append user-configured dirs to CODEQL_QUERY_RUN_RESULTS_DIRS', async () => { + const vscode = await import('vscode'); + const originalGetConfig = vscode.workspace.getConfiguration; + vscode.workspace.getConfiguration = () => ({ + get: (_key: string, defaultVal?: any) => { + if (_key === 'additionalQueryRunResultsDirs') return ['/custom/query-results']; + if (_key === 'additionalDatabaseDirs') return []; + if (_key === 'additionalMrvaRunResultsDirs') return []; + return defaultVal; + }, + has: () => false, + inspect: () => undefined as any, + update: () => Promise.resolve(), + }) as any; + + builder.invalidate(); + const env = await builder.build(); + expect(env.CODEQL_QUERY_RUN_RESULTS_DIRS).toContain('/custom/query-results'); + expect(env.CODEQL_QUERY_RUN_RESULTS_DIRS).toContain('/mock/global-storage/GitHub.vscode-codeql/queries'); + + vscode.workspace.getConfiguration = originalGetConfig; + }); + it('should be disposable', () => { expect(() => builder.dispose()).not.toThrow(); }); diff --git a/extensions/vscode/test/bridge/storage-paths.test.ts b/extensions/vscode/test/bridge/storage-paths.test.ts index 25af409c..ee773f15 100644 --- a/extensions/vscode/test/bridge/storage-paths.test.ts +++ b/extensions/vscode/test/bridge/storage-paths.test.ts @@ -44,6 +44,34 @@ describe('StoragePaths', () => { expect(result).toContain('variant-analyses'); }); + it('should compute the workspace database storage path', () => { + const result = paths.getWorkspaceDatabaseStoragePath(); + expect(result).toBeDefined(); + expect(result).toContain('workspace-storage'); + expect(result).toContain('GitHub.vscode-codeql'); + }); + + it('should return undefined workspace database path when no workspace is open', () => { + const noWorkspaceCtx = { globalStorageUri: ctx.globalStorageUri } as any; + const noWorkspacePaths = new StoragePaths(noWorkspaceCtx); + expect(noWorkspacePaths.getWorkspaceDatabaseStoragePath()).toBeUndefined(); + }); + + it('should return all database storage paths including workspace', () => { + const all = paths.getAllDatabaseStoragePaths(); + expect(all).toHaveLength(2); + expect(all[0]).toContain('global-storage'); + expect(all[1]).toContain('workspace-storage'); + }); + + it('should return only global path in getAllDatabaseStoragePaths when no workspace', () => { + const noWorkspaceCtx = { globalStorageUri: ctx.globalStorageUri } as any; + const noWorkspacePaths = new StoragePaths(noWorkspaceCtx); + const all = noWorkspacePaths.getAllDatabaseStoragePaths(); + expect(all).toHaveLength(1); + expect(all[0]).toContain('global-storage'); + }); + it('should be disposable', () => { expect(() => paths.dispose()).not.toThrow(); }); diff --git a/extensions/vscode/test/fixtures/multi-root-workspace/folder-a/codeql-storage/databases/test-python-db/codeql-database.yml b/extensions/vscode/test/fixtures/multi-root-workspace/folder-a/codeql-storage/databases/test-python-db/codeql-database.yml new file mode 100644 index 00000000..88a367d8 --- /dev/null +++ b/extensions/vscode/test/fixtures/multi-root-workspace/folder-a/codeql-storage/databases/test-python-db/codeql-database.yml @@ -0,0 +1,6 @@ +--- +primaryLanguage: python +creationMetadata: + cliVersion: 2.24.1 + creationTime: 2026-01-20T15:00:00.000Z +finalised: true diff --git a/extensions/vscode/test/fixtures/multi-root-workspace/folder-a/codeql-storage/queries/SqlInjection.ql-def456/timestamp b/extensions/vscode/test/fixtures/multi-root-workspace/folder-a/codeql-storage/queries/SqlInjection.ql-def456/timestamp new file mode 100644 index 00000000..d4bfc282 --- /dev/null +++ b/extensions/vscode/test/fixtures/multi-root-workspace/folder-a/codeql-storage/queries/SqlInjection.ql-def456/timestamp @@ -0,0 +1 @@ +1737100000000 diff --git a/extensions/vscode/test/fixtures/multi-root-workspace/folder-b/.gitkeep b/extensions/vscode/test/fixtures/multi-root-workspace/folder-b/.gitkeep new file mode 100644 index 00000000..e69de29b diff --git a/extensions/vscode/test/fixtures/multi-root-workspace/test.code-workspace b/extensions/vscode/test/fixtures/multi-root-workspace/test.code-workspace new file mode 100644 index 00000000..ba155da6 --- /dev/null +++ b/extensions/vscode/test/fixtures/multi-root-workspace/test.code-workspace @@ -0,0 +1,6 @@ +{ + "folders": [ + { "path": "folder-a" }, + { "path": "folder-b" } + ] +} diff --git a/extensions/vscode/test/fixtures/single-folder-workspace/codeql-storage/databases/test-javascript-db/codeql-database.yml b/extensions/vscode/test/fixtures/single-folder-workspace/codeql-storage/databases/test-javascript-db/codeql-database.yml new file mode 100644 index 00000000..dcea6402 --- /dev/null +++ b/extensions/vscode/test/fixtures/single-folder-workspace/codeql-storage/databases/test-javascript-db/codeql-database.yml @@ -0,0 +1,6 @@ +--- +primaryLanguage: javascript +creationMetadata: + cliVersion: 2.24.1 + creationTime: 2026-01-15T10:00:00.000Z +finalised: true diff --git a/extensions/vscode/test/fixtures/single-folder-workspace/codeql-storage/queries/ExampleQuery1.ql-abc123/timestamp b/extensions/vscode/test/fixtures/single-folder-workspace/codeql-storage/queries/ExampleQuery1.ql-abc123/timestamp new file mode 100644 index 00000000..0f775979 --- /dev/null +++ b/extensions/vscode/test/fixtures/single-folder-workspace/codeql-storage/queries/ExampleQuery1.ql-abc123/timestamp @@ -0,0 +1 @@ +1737000000000 diff --git a/extensions/vscode/test/fixtures/single-folder-workspace/codeql-storage/variant-analyses/10001/repo_states.json b/extensions/vscode/test/fixtures/single-folder-workspace/codeql-storage/variant-analyses/10001/repo_states.json new file mode 100644 index 00000000..c95cfbdb --- /dev/null +++ b/extensions/vscode/test/fixtures/single-folder-workspace/codeql-storage/variant-analyses/10001/repo_states.json @@ -0,0 +1 @@ +{"12345": {"repositoryId": 12345, "downloadStatus": "succeeded"}} diff --git a/extensions/vscode/test/fixtures/single-folder-workspace/codeql-storage/variant-analyses/10001/timestamp b/extensions/vscode/test/fixtures/single-folder-workspace/codeql-storage/variant-analyses/10001/timestamp new file mode 100644 index 00000000..0f775979 --- /dev/null +++ b/extensions/vscode/test/fixtures/single-folder-workspace/codeql-storage/variant-analyses/10001/timestamp @@ -0,0 +1 @@ +1737000000000 diff --git a/extensions/vscode/test/server/mcp-provider.test.ts b/extensions/vscode/test/server/mcp-provider.test.ts index b3bdae45..77c09f69 100644 --- a/extensions/vscode/test/server/mcp-provider.test.ts +++ b/extensions/vscode/test/server/mcp-provider.test.ts @@ -25,6 +25,10 @@ function createMockEnvBuilder() { build: vi.fn().mockResolvedValue({ CODEQL_PATH: '/usr/local/bin/codeql', CODEQL_MCP_WORKSPACE: '/mock/workspace', + CODEQL_DATABASES_BASE_DIRS: '/mock/databases', + CODEQL_QUERY_RUN_RESULTS_DIRS: '/mock/queries', + CODEQL_MRVA_RUN_RESULTS_DIRS: '/mock/variant-analyses', + TRANSPORT_MODE: 'stdio', }), invalidate: vi.fn(), dispose: vi.fn(), @@ -81,9 +85,23 @@ describe('McpProvider', () => { expect(definitions![0].env).toEqual({ CODEQL_PATH: '/usr/local/bin/codeql', CODEQL_MCP_WORKSPACE: '/mock/workspace', + CODEQL_DATABASES_BASE_DIRS: '/mock/databases', + CODEQL_QUERY_RUN_RESULTS_DIRS: '/mock/queries', + CODEQL_MRVA_RUN_RESULTS_DIRS: '/mock/variant-analyses', + TRANSPORT_MODE: 'stdio', }); }); + it('should pass discovery env vars through to the MCP server definition', async () => { + const token = { isCancellationRequested: false, onCancellationRequested: vi.fn() }; + const definitions = await provider.provideMcpServerDefinitions(token as any); + const env = definitions![0].env; + + expect(env.CODEQL_DATABASES_BASE_DIRS).toBe('/mock/databases'); + expect(env.CODEQL_QUERY_RUN_RESULTS_DIRS).toBe('/mock/queries'); + expect(env.CODEQL_MRVA_RUN_RESULTS_DIRS).toBe('/mock/variant-analyses'); + }); + it('should always provide a definition (npx handles download)', async () => { serverManager.isInstalled.mockResolvedValue(false); diff --git a/extensions/vscode/test/server/server-manager.test.ts b/extensions/vscode/test/server/server-manager.test.ts index 48c6b69d..999e2fa9 100644 --- a/extensions/vscode/test/server/server-manager.test.ts +++ b/extensions/vscode/test/server/server-manager.test.ts @@ -109,6 +109,19 @@ describe('ServerManager', () => { expect(manager.getArgs()).toEqual(['/mock/extension/server/dist/codeql-development-mcp-server.js']); }); + it('should fall back to monorepo server path when VSIX bundle is missing', () => { + let callCount = 0; + vi.mocked(accessSync).mockImplementation(() => { + callCount++; + if (callCount === 1) throw new Error('ENOENT'); // VSIX path missing + return undefined; // monorepo path exists + }); + expect(manager.getCommand()).toBe('node'); + // monorepo path: /mock/extension/../../server/dist/... + const args = manager.getArgs(); + expect(args[0]).toContain('server/dist/codeql-development-mcp-server.js'); + }); + it('should run npm install when installing', async () => { vi.mocked(execFile).mockImplementation( (_cmd: any, _args: any, _opts: any, callback: any) => { diff --git a/extensions/vscode/test/suite/bridge.integration.test.ts b/extensions/vscode/test/suite/bridge.integration.test.ts new file mode 100644 index 00000000..3296f3e5 --- /dev/null +++ b/extensions/vscode/test/suite/bridge.integration.test.ts @@ -0,0 +1,164 @@ +/** + * Integration tests for the vscode-codeql bridge. + * + * These run inside the Extension Development Host with the REAL VS Code API. + * They verify that the bridge correctly discovers vscode-codeql storage paths + * and sets discovery environment variables pointing to valid directories. + */ + +import * as assert from 'assert'; +import * as fs from 'fs'; +import * as path from 'path'; +import * as vscode from 'vscode'; + +const EXTENSION_ID = 'advanced-security.vscode-codeql-development-mcp-server'; +const CODEQL_EXTENSION_ID = 'GitHub.vscode-codeql'; + +suite('vscode-codeql Bridge Tests', () => { + let api: any; + + suiteSetup(async () => { + const ext = vscode.extensions.getExtension(EXTENSION_ID); + assert.ok(ext, `Extension ${EXTENSION_ID} not found`); + api = ext.isActive ? ext.exports : await ext.activate(); + }); + + test('Should detect whether vscode-codeql extension is available', () => { + const codeqlExt = vscode.extensions.getExtension(CODEQL_EXTENSION_ID); + // The extension may or may not be present in the Extension Host — both are valid. + // We merely verify the lookup doesn't throw. + if (codeqlExt) { + assert.ok(codeqlExt.id === CODEQL_EXTENSION_ID); + } + }); + + test('Environment builder should produce an object with string values', async () => { + const envBuilder = api.environmentBuilder; + if (!envBuilder) { + return; + } + const env = await envBuilder.build(); + assert.ok(typeof env === 'object', 'Environment is not an object'); + for (const [key, value] of Object.entries(env)) { + assert.ok( + typeof key === 'string', + `Environment key is not a string: ${key}`, + ); + assert.ok( + typeof value === 'string', + `Environment value for ${key} is not a string: ${typeof value}`, + ); + } + }); + + test('CODEQL_DATABASES_BASE_DIRS paths should be valid directories', async () => { + const envBuilder = api.environmentBuilder; + if (!envBuilder) return; + + const env = await envBuilder.build(); + const dirs = env.CODEQL_DATABASES_BASE_DIRS; + assert.ok(dirs, 'CODEQL_DATABASES_BASE_DIRS not set'); + + for (const dir of dirs.split(':')) { + if (dir.length === 0) continue; + // Parent must exist (the leaf directory may not yet exist if no databases + // have been created, but the parent storage root should). + const parent = path.dirname(dir); + assert.ok( + fs.existsSync(parent), + `Parent of CODEQL_DATABASES_BASE_DIRS entry does not exist: ${parent} (from ${dir})`, + ); + } + }); + + test('CODEQL_DATABASES_BASE_DIRS should include workspace storage path when workspace is open', async () => { + const envBuilder = api.environmentBuilder; + if (!envBuilder) return; + + const env = await envBuilder.build(); + const dirs = env.CODEQL_DATABASES_BASE_DIRS; + assert.ok(dirs, 'CODEQL_DATABASES_BASE_DIRS not set'); + + const parts = dirs.split(':'); + + // When a workspace is open, there should be at least 2 paths + // (global + workspace). When no workspace is open (e.g. Extension + // Development Host without --folder-uri), only the global path is present. + const hasWorkspaceStorage = parts.some((p: string) => p.includes('workspaceStorage')); + if (vscode.workspace.workspaceFolders && vscode.workspace.workspaceFolders.length > 0) { + assert.ok( + hasWorkspaceStorage, + `CODEQL_DATABASES_BASE_DIRS should include a workspaceStorage path when a workspace is open: ${dirs}`, + ); + } + // Always should have at least the global storage path + const hasGlobalStorage = parts.some((p: string) => p.includes('globalStorage')); + assert.ok( + hasGlobalStorage, + `CODEQL_DATABASES_BASE_DIRS should include a globalStorage path: ${dirs}`, + ); + }); + + test('CODEQL_QUERY_RUN_RESULTS_DIRS parent should exist', async () => { + const envBuilder = api.environmentBuilder; + if (!envBuilder) return; + + const env = await envBuilder.build(); + const dirs = env.CODEQL_QUERY_RUN_RESULTS_DIRS; + assert.ok(dirs, 'CODEQL_QUERY_RUN_RESULTS_DIRS not set'); + + for (const dir of dirs.split(':')) { + if (dir.length === 0) continue; + const parent = path.dirname(dir); + assert.ok( + fs.existsSync(parent), + `Parent of CODEQL_QUERY_RUN_RESULTS_DIRS entry does not exist: ${parent}`, + ); + } + }); + + test('CODEQL_MRVA_RUN_RESULTS_DIRS parent should exist', async () => { + const envBuilder = api.environmentBuilder; + if (!envBuilder) return; + + const env = await envBuilder.build(); + const dirs = env.CODEQL_MRVA_RUN_RESULTS_DIRS; + assert.ok(dirs, 'CODEQL_MRVA_RUN_RESULTS_DIRS not set'); + + for (const dir of dirs.split(':')) { + if (dir.length === 0) continue; + const parent = path.dirname(dir); + assert.ok( + fs.existsSync(parent), + `Parent of CODEQL_MRVA_RUN_RESULTS_DIRS entry does not exist: ${parent}`, + ); + } + }); + + test('Environment should include discovery env vars when vscode-codeql is present', async () => { + const codeqlExt = vscode.extensions.getExtension(CODEQL_EXTENSION_ID); + if (!codeqlExt) { + // vscode-codeql not installed — skip + return; + } + const envBuilder = api.environmentBuilder; + if (!envBuilder) { + return; + } + const env = await envBuilder.build(); + // When vscode-codeql is present, these should be set + const discoveryVars = [ + 'CODEQL_DATABASES_BASE_DIRS', + 'CODEQL_QUERY_RUN_RESULTS_DIRS', + 'CODEQL_MRVA_RUN_RESULTS_DIRS', + ]; + for (const v of discoveryVars) { + if (env[v]) { + assert.ok( + typeof env[v] === 'string' && env[v].length > 0, + `${v} is set but empty`, + ); + } + } + }); +}); diff --git a/extensions/vscode/test/suite/mcp-server.integration.test.ts b/extensions/vscode/test/suite/mcp-server.integration.test.ts new file mode 100644 index 00000000..9333554a --- /dev/null +++ b/extensions/vscode/test/suite/mcp-server.integration.test.ts @@ -0,0 +1,61 @@ +/** + * Integration tests for the MCP server definition provider. + * + * These run inside the Extension Development Host with the REAL VS Code API. + * They verify that the extension provides a working MCP server definition + * with the correct command, args, and environment variables. + */ + +import * as assert from 'assert'; +import * as vscode from 'vscode'; + +const EXTENSION_ID = 'advanced-security.vscode-codeql-development-mcp-server'; + +suite('MCP Server Definition Tests', () => { + let api: any; + + suiteSetup(async () => { + const ext = vscode.extensions.getExtension(EXTENSION_ID); + assert.ok(ext, `Extension ${EXTENSION_ID} not found`); + api = ext.isActive ? ext.exports : await ext.activate(); + }); + + test('mcpProvider should provide at least one server definition', async () => { + const provider = api.mcpProvider; + assert.ok(provider, 'API missing mcpProvider'); + assert.ok( + typeof provider.provideMcpServerDefinitions === 'function', + 'mcpProvider missing provideMcpServerDefinitions method', + ); + }); + + test('Server definition should use node command when bundled server exists', async () => { + // The serverManager exposes getCommand/getArgs for inspection + const serverManager = api.serverManager; + if (!serverManager) { + // serverManager may not be exported — skip gracefully + return; + } + const command = serverManager.getCommand(); + // In the Extension Development Host, the monorepo server/dist/ should be found + assert.ok( + command === 'node' || command === 'npx', + `Unexpected server command: ${command}`, + ); + }); + + test('Server definition should include CODEQL_PATH in environment when CLI is found', async () => { + const envBuilder = api.environmentBuilder; + if (!envBuilder) { + return; + } + const env = await envBuilder.build(); + // CODEQL_PATH should be set if the CodeQL CLI was found on PATH or via the extension + if (env.CODEQL_PATH) { + assert.ok( + typeof env.CODEQL_PATH === 'string' && env.CODEQL_PATH.length > 0, + 'CODEQL_PATH is set but empty', + ); + } + }); +}); diff --git a/extensions/vscode/test/suite/mcp-tool-e2e.integration.test.ts b/extensions/vscode/test/suite/mcp-tool-e2e.integration.test.ts new file mode 100644 index 00000000..0279d3dd --- /dev/null +++ b/extensions/vscode/test/suite/mcp-tool-e2e.integration.test.ts @@ -0,0 +1,256 @@ +/** + * End-to-end integration tests for MCP server tools. + * + * These run inside the Extension Development Host with the REAL VS Code API. + * They spawn the actual `ql-mcp` server process (using the extension's + * configured command/args/env), connect via the MCP SDK's StdioClientTransport, + * call tools like `list_codeql_databases` and `list_query_run_results`, and + * verify the results match expected fixture data. + * + * The test fixtures under `test/fixtures/single-folder-workspace/codeql-storage/` + * and `test/fixtures/multi-root-workspace/folder-a/codeql-storage/` contain + * representative CodeQL database metadata and query run result directories + * that these tests discover. + */ + +import * as assert from 'assert'; +import * as fs from 'fs'; +import * as path from 'path'; +import * as vscode from 'vscode'; +import { Client } from '@modelcontextprotocol/sdk/client/index.js'; +import { StdioClientTransport } from '@modelcontextprotocol/sdk/client/stdio.js'; + +const EXTENSION_ID = 'advanced-security.vscode-codeql-development-mcp-server'; + +/** + * Resolve the MCP server entry point. Checks: + * 1. Bundled inside extension (VSIX layout) + * 2. Monorepo sibling (dev layout) + */ +function resolveServerPath(): string { + const extPath = vscode.extensions.getExtension(EXTENSION_ID)?.extensionUri.fsPath; + if (!extPath) throw new Error('Extension not found'); + + // Monorepo dev layout: extensions/vscode/../../server/dist/... + const monorepo = path.resolve(extPath, '..', '..', 'server', 'dist', 'codeql-development-mcp-server.js'); + try { + fs.accessSync(monorepo); + return monorepo; + } catch { + // Fall through + } + + // VSIX layout: server/dist/... + const vsix = path.resolve(extPath, 'server', 'dist', 'codeql-development-mcp-server.js'); + try { + fs.accessSync(vsix); + return vsix; + } catch { + throw new Error(`MCP server not found at ${monorepo} or ${vsix}`); + } +} + +/** + * Resolve the fixture storage directory for the current test scenario. + * The fixture `codeql-storage/` directory simulates vscode-codeql storage. + */ +function resolveFixtureStoragePath(): string | undefined { + const extPath = vscode.extensions.getExtension(EXTENSION_ID)?.extensionUri.fsPath; + if (!extPath) return undefined; + + // Check single-folder-workspace fixture + const singleFolder = path.resolve(extPath, 'test', 'fixtures', 'single-folder-workspace', 'codeql-storage'); + try { + fs.accessSync(singleFolder); + return singleFolder; + } catch { + // Fall through + } + + // Check multi-root folder-a fixture + const multiRoot = path.resolve(extPath, 'test', 'fixtures', 'multi-root-workspace', 'folder-a', 'codeql-storage'); + try { + fs.accessSync(multiRoot); + return multiRoot; + } catch { + return undefined; + } +} + +suite('MCP Server Tool Integration Tests', () => { + let client: Client; + let transport: StdioClientTransport; + let fixtureStorage: string | undefined; + + suiteSetup(async function () { + this.timeout(30_000); + + // Ensure extension is activated + const ext = vscode.extensions.getExtension(EXTENSION_ID); + assert.ok(ext, `Extension ${EXTENSION_ID} not found`); + if (!ext.isActive) await ext.activate(); + + // Resolve fixture storage path — must exist + fixtureStorage = resolveFixtureStoragePath(); + assert.ok(fixtureStorage, 'Fixture codeql-storage directory not found. Test fixtures are missing.'); + + // Resolve the MCP server entry point — must exist + const serverPath = resolveServerPath(); + + // Build environment: point discovery vars at fixture storage + const env: Record = { + ...process.env as Record, + TRANSPORT_MODE: 'stdio', + CODEQL_DATABASES_BASE_DIRS: path.join(fixtureStorage, 'databases'), + CODEQL_QUERY_RUN_RESULTS_DIRS: path.join(fixtureStorage, 'queries'), + CODEQL_MRVA_RUN_RESULTS_DIRS: path.join(fixtureStorage, 'variant-analyses'), + }; + + // Spawn the server via StdioClientTransport + transport = new StdioClientTransport({ + command: 'node', + args: [serverPath], + env, + stderr: 'pipe', + }); + + client = new Client({ name: 'extension-host-test', version: '1.0.0' }); + await client.connect(transport); + console.log('[mcp-tool-e2e] Connected to MCP server'); + }); + + suiteTeardown(async function () { + this.timeout(10_000); + try { + if (client) await client.close(); + } catch { + // Best-effort + } + try { + if (transport) await transport.close(); + } catch { + // Best-effort + } + }); + + test('Server should list available tools', async function () { + this.timeout(15_000); + + const response = await client.listTools(); + assert.ok(response.tools, 'Server should return tools'); + assert.ok(response.tools.length > 0, 'Server should have at least one tool'); + + const toolNames = response.tools.map(t => t.name); + assert.ok(toolNames.includes('list_codeql_databases'), 'Should include list_codeql_databases'); + assert.ok(toolNames.includes('list_query_run_results'), 'Should include list_query_run_results'); + assert.ok(toolNames.includes('list_mrva_run_results'), 'Should include list_mrva_run_results'); + + console.log(`[mcp-tool-e2e] Server provides ${response.tools.length} tools`); + }); + + test('list_codeql_databases should find fixture databases', async function () { + this.timeout(15_000); + + const result = await client.callTool({ + name: 'list_codeql_databases', + arguments: {}, + }); + + assert.ok(!result.isError, `Tool returned error: ${JSON.stringify(result.content)}`); + const text = (result.content as Array<{ type: string; text: string }>)[0]?.text ?? ''; + + // Should find the test-javascript-db from the fixture + assert.ok( + text.includes('test-javascript-db'), + `list_codeql_databases should find test-javascript-db in fixture storage. Got: ${text}`, + ); + assert.ok( + text.includes('javascript'), + `Database should be identified as javascript language. Got: ${text}`, + ); + + console.log(`[mcp-tool-e2e] list_codeql_databases result:\n${text}`); + }); + + test('list_codeql_databases with language filter should work', async function () { + this.timeout(15_000); + + const result = await client.callTool({ + name: 'list_codeql_databases', + arguments: { language: 'javascript' }, + }); + + assert.ok(!result.isError, `Tool returned error: ${JSON.stringify(result.content)}`); + const text = (result.content as Array<{ type: string; text: string }>)[0]?.text ?? ''; + + assert.ok( + text.includes('test-javascript-db'), + `Filtered result should include test-javascript-db. Got: ${text}`, + ); + }); + + test('list_query_run_results should find fixture query runs', async function () { + this.timeout(15_000); + + const result = await client.callTool({ + name: 'list_query_run_results', + arguments: {}, + }); + + assert.ok(!result.isError, `Tool returned error: ${JSON.stringify(result.content)}`); + const text = (result.content as Array<{ type: string; text: string }>)[0]?.text ?? ''; + + // Should find ExampleQuery1.ql run from the fixture + assert.ok( + text.includes('ExampleQuery1.ql'), + `list_query_run_results should find ExampleQuery1.ql run in fixture storage. Got: ${text}`, + ); + assert.ok( + text.includes('javascript'), + `Query run should have javascript language extracted from query.log. Got: ${text}`, + ); + + console.log(`[mcp-tool-e2e] list_query_run_results result:\n${text}`); + }); + + test('list_query_run_results with queryName filter should work', async function () { + this.timeout(15_000); + + const result = await client.callTool({ + name: 'list_query_run_results', + arguments: { queryName: 'ExampleQuery1.ql' }, + }); + + assert.ok(!result.isError, `Tool returned error: ${JSON.stringify(result.content)}`); + const text = (result.content as Array<{ type: string; text: string }>)[0]?.text ?? ''; + + assert.ok( + text.includes('ExampleQuery1.ql'), + `Filtered result should include ExampleQuery1.ql. Got: ${text}`, + ); + // Should NOT include other query names + assert.ok( + !text.includes('SqlInjection.ql'), + `Filtered result should NOT include SqlInjection.ql. Got: ${text}`, + ); + }); + + test('list_mrva_run_results should find fixture MRVA runs', async function () { + this.timeout(15_000); + + const result = await client.callTool({ + name: 'list_mrva_run_results', + arguments: {}, + }); + + assert.ok(!result.isError, `Tool returned error: ${JSON.stringify(result.content)}`); + const text = (result.content as Array<{ type: string; text: string }>)[0]?.text ?? ''; + + assert.ok( + text.includes('10001'), + `list_mrva_run_results should find run 10001 from fixture. Got: ${text}`, + ); + + console.log(`[mcp-tool-e2e] list_mrva_run_results result:\n${text}`); + }); +}); diff --git a/extensions/vscode/test/suite/workspace-scenario.integration.test.ts b/extensions/vscode/test/suite/workspace-scenario.integration.test.ts new file mode 100644 index 00000000..a5620ff4 --- /dev/null +++ b/extensions/vscode/test/suite/workspace-scenario.integration.test.ts @@ -0,0 +1,145 @@ +/** + * Integration tests for workspace scenarios. + * + * These run inside the Extension Development Host with the REAL VS Code API. + * The specific workspace configuration (none, single folder, multi-root) + * depends on which launch config is used. + * + * The tests adapt their assertions based on the active workspace state. + */ + +import * as assert from 'assert'; +import * as vscode from 'vscode'; + +const EXTENSION_ID = 'advanced-security.vscode-codeql-development-mcp-server'; + +suite('Workspace Scenario Tests', () => { + let api: any; + + suiteSetup(async () => { + const ext = vscode.extensions.getExtension(EXTENSION_ID); + assert.ok(ext, `Extension ${EXTENSION_ID} not found`); + api = ext.isActive ? ext.exports : await ext.activate(); + }); + + test('Extension should activate regardless of workspace state', () => { + const ext = vscode.extensions.getExtension(EXTENSION_ID); + assert.ok(ext?.isActive, 'Extension should be active'); + }); + + test('Should report correct workspace folder count', () => { + const folders = vscode.workspace.workspaceFolders; + const count = folders?.length ?? 0; + // Log for diagnostic purposes in test output + console.log(`[workspace-scenario] Workspace folders: ${count}`); + if (folders) { + for (const f of folders) { + console.log(` - ${f.name}: ${f.uri.fsPath}`); + } + } + // This test records the state — assertions are in scenario-specific tests below + assert.ok(count >= 0, 'Folder count should be non-negative'); + }); + + test('MCP server definition should always be provided', async () => { + const provider = api.mcpProvider; + assert.ok(provider, 'mcpProvider should be exported'); + + const token = { + isCancellationRequested: false, + onCancellationRequested: () => ({ dispose: () => {} }), + }; + const definitions = await provider.provideMcpServerDefinitions(token as any); + assert.ok(definitions, 'Should return definitions'); + assert.ok(definitions.length >= 1, 'Should provide at least one server definition'); + }); + + test('Environment should include TRANSPORT_MODE', async () => { + const envBuilder = api.environmentBuilder; + if (!envBuilder) return; + + const env = await envBuilder.build(); + assert.strictEqual(env.TRANSPORT_MODE, 'stdio'); + }); + + test('CODEQL_DATABASES_BASE_DIRS should always contain globalStorage path', async () => { + const envBuilder = api.environmentBuilder; + if (!envBuilder) return; + + const env = await envBuilder.build(); + assert.ok(env.CODEQL_DATABASES_BASE_DIRS, 'CODEQL_DATABASES_BASE_DIRS should be set'); + assert.ok( + env.CODEQL_DATABASES_BASE_DIRS.includes('globalStorage'), + `Should include globalStorage path: ${env.CODEQL_DATABASES_BASE_DIRS}`, + ); + }); + + test('CODEQL_MCP_WORKSPACE should match first workspace folder when present', async () => { + const envBuilder = api.environmentBuilder; + if (!envBuilder) return; + + const env = await envBuilder.build(); + const folders = vscode.workspace.workspaceFolders; + + if (folders && folders.length > 0) { + assert.strictEqual( + env.CODEQL_MCP_WORKSPACE, + folders[0].uri.fsPath, + 'CODEQL_MCP_WORKSPACE should equal the first workspace folder path', + ); + } else { + assert.strictEqual( + env.CODEQL_MCP_WORKSPACE, + undefined, + 'CODEQL_MCP_WORKSPACE should be undefined when no workspace is open', + ); + } + }); + + test('CODEQL_DATABASES_BASE_DIRS should include workspaceStorage when workspace is open', async () => { + const envBuilder = api.environmentBuilder; + if (!envBuilder) return; + + const env = await envBuilder.build(); + const folders = vscode.workspace.workspaceFolders; + const dirs = env.CODEQL_DATABASES_BASE_DIRS; + + if (folders && folders.length > 0) { + assert.ok( + dirs.includes('workspaceStorage'), + `With workspace open, CODEQL_DATABASES_BASE_DIRS should include workspaceStorage: ${dirs}`, + ); + } + // Without a workspace, only globalStorage is present — already tested above + }); + + test('CODEQL_ADDITIONAL_PACKS should include workspace folder paths when present', async () => { + const envBuilder = api.environmentBuilder; + if (!envBuilder) return; + + const env = await envBuilder.build(); + const folders = vscode.workspace.workspaceFolders; + + if (folders && folders.length > 0) { + for (const folder of folders) { + assert.ok( + env.CODEQL_ADDITIONAL_PACKS.includes(folder.uri.fsPath), + `CODEQL_ADDITIONAL_PACKS should include workspace folder ${folder.name}: ${env.CODEQL_ADDITIONAL_PACKS}`, + ); + } + } + }); + + test('Server command should be determined (node or npx)', () => { + const serverManager = api.serverManager; + if (!serverManager) return; + + const command = serverManager.getCommand(); + assert.ok( + command === 'node' || command === 'npx', + `Server command should be 'node' or 'npx', got: ${command}`, + ); + console.log(`[workspace-scenario] Server command: ${command}`); + console.log(`[workspace-scenario] Server args: ${JSON.stringify(serverManager.getArgs())}`); + }); +}); From b2f80359c19698fce651b410ee154344eb142afb Mon Sep 17 00:00:00 2001 From: Nathan Randall Date: Wed, 18 Feb 2026 20:44:57 -0700 Subject: [PATCH 06/14] Remove .vscode/mcp.json & update .gitignore --- .gitignore | 1 + .vscode/mcp.json | 12 ------------ 2 files changed, 1 insertion(+), 12 deletions(-) delete mode 100644 .vscode/mcp.json diff --git a/.gitignore b/.gitignore index 4a9a5b89..0ea83704 100644 --- a/.gitignore +++ b/.gitignore @@ -26,6 +26,7 @@ codeql-development-mcp-server.code-workspace *.tar.gz *~ +.vscode/mcp.json .vscode/settings.json # Ignore state tracking for local, integration testing diff --git a/.vscode/mcp.json b/.vscode/mcp.json deleted file mode 100644 index 13c1b1a4..00000000 --- a/.vscode/mcp.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "servers": { - "ql-mcp": { - "type": "stdio", - "command": "node", - "args": [ - "/Users/data-douser/Git/advanced-security/codeql-development-mcp-server/server/dist/codeql-development-mcp-server.js" - ] - } - }, - "inputs": [] -} \ No newline at end of file From 32c93715f942975291cb51255e0115b3c9be666f Mon Sep 17 00:00:00 2001 From: Nathan Randall Date: Wed, 18 Feb 2026 20:52:08 -0700 Subject: [PATCH 07/14] Sync package-lock.json --- package-lock.json | 3271 +++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 3179 insertions(+), 92 deletions(-) diff --git a/package-lock.json b/package-lock.json index 50342dc5..9194eeaa 100644 --- a/package-lock.json +++ b/package-lock.json @@ -142,6 +142,7 @@ "integrity": "sha512-O0piBKY36YSJhlFSG8p9VUdPV/SxxS4FYDWVpr/9GJuMaepzwlf4J8I4ov1b+ySQfDTPhc3DtLaxcT1fN0yqCg==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "@eslint-community/eslint-utils": "^4.8.0", "@eslint-community/regexpp": "^4.12.2", @@ -259,7 +260,7 @@ } }, "extensions/vscode": { - "name": "codeql-development-mcp-server-vscode", + "name": "vscode-codeql-development-mcp-server", "version": "2.24.1", "license": "SEE LICENSE IN LICENSE", "devDependencies": { @@ -268,6 +269,7 @@ "@types/node": "^22.15.0", "@types/vscode": "^1.99.0", "@vitest/coverage-v8": "^4.0.18", + "@vscode/vsce": "^3.3.2", "esbuild": "^0.27.3", "eslint": "^9.39.2", "eslint-config-prettier": "^10.1.8", @@ -301,6 +303,214 @@ "dev": true, "license": "MIT" }, + "node_modules/@azu/format-text": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@azu/format-text/-/format-text-1.0.2.tgz", + "integrity": "sha512-Swi4N7Edy1Eqq82GxgEECXSSLyn6GOb5htRFPzBDdUkECGXtlf12ynO5oJSpWKPwCaUssOu7NfhDcCWpIC6Ywg==", + "dev": true, + "license": "BSD-3-Clause" + }, + "node_modules/@azu/style-format": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@azu/style-format/-/style-format-1.0.1.tgz", + "integrity": "sha512-AHcTojlNBdD/3/KxIKlg8sxIWHfOtQszLvOpagLTO+bjC3u7SAszu1lf//u7JJC50aUSH+BVWDD/KvaA6Gfn5g==", + "dev": true, + "license": "WTFPL", + "dependencies": { + "@azu/format-text": "^1.0.1" + } + }, + "node_modules/@azure/abort-controller": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/@azure/abort-controller/-/abort-controller-2.1.2.tgz", + "integrity": "sha512-nBrLsEWm4J2u5LpAPjxADTlq3trDgVZZXHNKabeXZtpq3d3AbN/KGO82R87rdDz5/lYB024rtEf10/q0urNgsA==", + "dev": true, + "license": "MIT", + "dependencies": { + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@azure/core-auth": { + "version": "1.10.1", + "resolved": "https://registry.npmjs.org/@azure/core-auth/-/core-auth-1.10.1.tgz", + "integrity": "sha512-ykRMW8PjVAn+RS6ww5cmK9U2CyH9p4Q88YJwvUslfuMmN98w/2rdGRLPqJYObapBCdzBVeDgYWdJnFPFb7qzpg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@azure/abort-controller": "^2.1.2", + "@azure/core-util": "^1.13.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@azure/core-client": { + "version": "1.10.1", + "resolved": "https://registry.npmjs.org/@azure/core-client/-/core-client-1.10.1.tgz", + "integrity": "sha512-Nh5PhEOeY6PrnxNPsEHRr9eimxLwgLlpmguQaHKBinFYA/RU9+kOYVOQqOrTsCL+KSxrLLl1gD8Dk5BFW/7l/w==", + "dev": true, + "license": "MIT", + "dependencies": { + "@azure/abort-controller": "^2.1.2", + "@azure/core-auth": "^1.10.0", + "@azure/core-rest-pipeline": "^1.22.0", + "@azure/core-tracing": "^1.3.0", + "@azure/core-util": "^1.13.0", + "@azure/logger": "^1.3.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@azure/core-rest-pipeline": { + "version": "1.22.2", + "resolved": "https://registry.npmjs.org/@azure/core-rest-pipeline/-/core-rest-pipeline-1.22.2.tgz", + "integrity": "sha512-MzHym+wOi8CLUlKCQu12de0nwcq9k9Kuv43j4Wa++CsCpJwps2eeBQwD2Bu8snkxTtDKDx4GwjuR9E8yC8LNrg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@azure/abort-controller": "^2.1.2", + "@azure/core-auth": "^1.10.0", + "@azure/core-tracing": "^1.3.0", + "@azure/core-util": "^1.13.0", + "@azure/logger": "^1.3.0", + "@typespec/ts-http-runtime": "^0.3.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@azure/core-tracing": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/@azure/core-tracing/-/core-tracing-1.3.1.tgz", + "integrity": "sha512-9MWKevR7Hz8kNzzPLfX4EAtGM2b8mr50HPDBvio96bURP/9C+HjdH3sBlLSNNrvRAr5/k/svoH457gB5IKpmwQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@azure/core-util": { + "version": "1.13.1", + "resolved": "https://registry.npmjs.org/@azure/core-util/-/core-util-1.13.1.tgz", + "integrity": "sha512-XPArKLzsvl0Hf0CaGyKHUyVgF7oDnhKoP85Xv6M4StF/1AhfORhZudHtOyf2s+FcbuQ9dPRAjB8J2KvRRMUK2A==", + "dev": true, + "license": "MIT", + "dependencies": { + "@azure/abort-controller": "^2.1.2", + "@typespec/ts-http-runtime": "^0.3.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@azure/identity": { + "version": "4.13.0", + "resolved": "https://registry.npmjs.org/@azure/identity/-/identity-4.13.0.tgz", + "integrity": "sha512-uWC0fssc+hs1TGGVkkghiaFkkS7NkTxfnCH+Hdg+yTehTpMcehpok4PgUKKdyCH+9ldu6FhiHRv84Ntqj1vVcw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@azure/abort-controller": "^2.0.0", + "@azure/core-auth": "^1.9.0", + "@azure/core-client": "^1.9.2", + "@azure/core-rest-pipeline": "^1.17.0", + "@azure/core-tracing": "^1.0.0", + "@azure/core-util": "^1.11.0", + "@azure/logger": "^1.0.0", + "@azure/msal-browser": "^4.2.0", + "@azure/msal-node": "^3.5.0", + "open": "^10.1.0", + "tslib": "^2.2.0" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@azure/logger": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/@azure/logger/-/logger-1.3.0.tgz", + "integrity": "sha512-fCqPIfOcLE+CGqGPd66c8bZpwAji98tZ4JI9i/mlTNTlsIWslCfpg48s/ypyLxZTump5sypjrKn2/kY7q8oAbA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typespec/ts-http-runtime": "^0.3.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@azure/msal-browser": { + "version": "4.28.2", + "resolved": "https://registry.npmjs.org/@azure/msal-browser/-/msal-browser-4.28.2.tgz", + "integrity": "sha512-6vYUMvs6kJxJgxaCmHn/F8VxjLHNh7i9wzfwPGf8kyBJ8Gg2yvBXx175Uev8LdrD1F5C4o7qHa2CC4IrhGE1XQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@azure/msal-common": "15.14.2" + }, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/@azure/msal-common": { + "version": "15.14.2", + "resolved": "https://registry.npmjs.org/@azure/msal-common/-/msal-common-15.14.2.tgz", + "integrity": "sha512-n8RBJEUmd5QotoqbZfd+eGBkzuFI1KX6jw2b3WcpSyGjwmzoeI/Jb99opIBPHpb8y312NB+B6+FGi2ZVSR8yfA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/@azure/msal-node": { + "version": "3.8.7", + "resolved": "https://registry.npmjs.org/@azure/msal-node/-/msal-node-3.8.7.tgz", + "integrity": "sha512-a+Xnrae+uwLnlw68bplS1X4kuJ9F/7K6afuMFyRkNIskhjgDezl5Fhrx+1pmAlDmC0VaaAxjRQMp1OmcqVwkIg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@azure/msal-common": "15.14.2", + "jsonwebtoken": "^9.0.0", + "uuid": "^8.3.0" + }, + "engines": { + "node": ">=16" + } + }, + "node_modules/@babel/code-frame": { + "version": "7.29.0", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.29.0.tgz", + "integrity": "sha512-9NhCeYjq9+3uxgdtp20LSiJXJvN0FeCtNGpJxuMFZ1Kv3cWUNb6DOhJwUvcVCzKGR66cw4njwM6hrJLqgOwbcw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-validator-identifier": "^7.28.5", + "js-tokens": "^4.0.0", + "picocolors": "^1.1.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/code-frame/node_modules/js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "dev": true, + "license": "MIT" + }, "node_modules/@babel/helper-string-parser": { "version": "7.27.1", "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.27.1.tgz", @@ -1134,6 +1344,44 @@ "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", "license": "MIT" }, + "node_modules/@nodelib/fs.scandir": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", + "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@nodelib/fs.stat": "2.0.5", + "run-parallel": "^1.1.9" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.stat": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.walk": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", + "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" + }, + "engines": { + "node": ">= 8" + } + }, "node_modules/@pkgjs/parseargs": { "version": "0.11.0", "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz", @@ -1508,124 +1756,425 @@ "win32" ] }, - "node_modules/@standard-schema/spec": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@standard-schema/spec/-/spec-1.1.0.tgz", - "integrity": "sha512-l2aFy5jALhniG5HgqrD6jXLi/rUWrKvqN/qJx6yoJsgKhblVd+iqqU4RCXavm/jPityDo5TCvKMnpjKnOriy0w==", - "dev": true, - "license": "MIT" - }, - "node_modules/@types/body-parser": { - "version": "1.19.6", - "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.6.tgz", - "integrity": "sha512-HLFeCYgz89uk22N5Qg3dvGvsv46B8GLvKKo1zKG4NybA8U2DiEO3w9lqGg29t/tfLRJpJ6iQxnVw4OnB7MoM9g==", + "node_modules/@secretlint/config-creator": { + "version": "10.2.2", + "resolved": "https://registry.npmjs.org/@secretlint/config-creator/-/config-creator-10.2.2.tgz", + "integrity": "sha512-BynOBe7Hn3LJjb3CqCHZjeNB09s/vgf0baBaHVw67w7gHF0d25c3ZsZ5+vv8TgwSchRdUCRrbbcq5i2B1fJ2QQ==", "dev": true, "license": "MIT", "dependencies": { - "@types/connect": "*", - "@types/node": "*" + "@secretlint/types": "^10.2.2" + }, + "engines": { + "node": ">=20.0.0" } }, - "node_modules/@types/chai": { - "version": "5.2.3", - "resolved": "https://registry.npmjs.org/@types/chai/-/chai-5.2.3.tgz", - "integrity": "sha512-Mw558oeA9fFbv65/y4mHtXDs9bPnFMZAL/jxdPFUpOHHIXX91mcgEHbS5Lahr+pwZFR8A7GQleRWeI6cGFC2UA==", + "node_modules/@secretlint/config-loader": { + "version": "10.2.2", + "resolved": "https://registry.npmjs.org/@secretlint/config-loader/-/config-loader-10.2.2.tgz", + "integrity": "sha512-ndjjQNgLg4DIcMJp4iaRD6xb9ijWQZVbd9694Ol2IszBIbGPPkwZHzJYKICbTBmh6AH/pLr0CiCaWdGJU7RbpQ==", "dev": true, "license": "MIT", "dependencies": { - "@types/deep-eql": "*", - "assertion-error": "^2.0.1" + "@secretlint/profiler": "^10.2.2", + "@secretlint/resolver": "^10.2.2", + "@secretlint/types": "^10.2.2", + "ajv": "^8.17.1", + "debug": "^4.4.1", + "rc-config-loader": "^4.1.3" + }, + "engines": { + "node": ">=20.0.0" } }, - "node_modules/@types/connect": { - "version": "3.4.38", - "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.38.tgz", - "integrity": "sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug==", + "node_modules/@secretlint/config-loader/node_modules/ajv": { + "version": "8.18.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.18.0.tgz", + "integrity": "sha512-PlXPeEWMXMZ7sPYOHqmDyCJzcfNrUr3fGNKtezX14ykXOEIvyK81d+qydx89KY5O71FKMPaQ2vBfBFI5NHR63A==", "dev": true, "license": "MIT", "dependencies": { - "@types/node": "*" + "fast-deep-equal": "^3.1.3", + "fast-uri": "^3.0.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" } }, - "node_modules/@types/cors": { - "version": "2.8.19", - "resolved": "https://registry.npmjs.org/@types/cors/-/cors-2.8.19.tgz", - "integrity": "sha512-mFNylyeyqN93lfe/9CSxOGREz8cpzAhH+E93xJ4xWQf62V8sQ/24reV2nyzUWM6H6Xji+GGHpkbLe7pVoUEskg==", + "node_modules/@secretlint/config-loader/node_modules/json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", + "dev": true, + "license": "MIT" + }, + "node_modules/@secretlint/core": { + "version": "10.2.2", + "resolved": "https://registry.npmjs.org/@secretlint/core/-/core-10.2.2.tgz", + "integrity": "sha512-6rdwBwLP9+TO3rRjMVW1tX+lQeo5gBbxl1I5F8nh8bgGtKwdlCMhMKsBWzWg1ostxx/tIG7OjZI0/BxsP8bUgw==", "dev": true, "license": "MIT", "dependencies": { - "@types/node": "*" + "@secretlint/profiler": "^10.2.2", + "@secretlint/types": "^10.2.2", + "debug": "^4.4.1", + "structured-source": "^4.0.0" + }, + "engines": { + "node": ">=20.0.0" } }, - "node_modules/@types/deep-eql": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/@types/deep-eql/-/deep-eql-4.0.2.tgz", - "integrity": "sha512-c9h9dVVMigMPc4bwTvC5dxqtqJZwQPePsWjPlpSOnojbor6pGqdk541lfA7AqFQr5pB1BRdq0juY9db81BwyFw==", + "node_modules/@secretlint/formatter": { + "version": "10.2.2", + "resolved": "https://registry.npmjs.org/@secretlint/formatter/-/formatter-10.2.2.tgz", + "integrity": "sha512-10f/eKV+8YdGKNQmoDUD1QnYL7TzhI2kzyx95vsJKbEa8akzLAR5ZrWIZ3LbcMmBLzxlSQMMccRmi05yDQ5YDA==", "dev": true, - "license": "MIT" + "license": "MIT", + "dependencies": { + "@secretlint/resolver": "^10.2.2", + "@secretlint/types": "^10.2.2", + "@textlint/linter-formatter": "^15.2.0", + "@textlint/module-interop": "^15.2.0", + "@textlint/types": "^15.2.0", + "chalk": "^5.4.1", + "debug": "^4.4.1", + "pluralize": "^8.0.0", + "strip-ansi": "^7.1.0", + "table": "^6.9.0", + "terminal-link": "^4.0.0" + }, + "engines": { + "node": ">=20.0.0" + } }, - "node_modules/@types/esrecurse": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/@types/esrecurse/-/esrecurse-4.3.1.tgz", - "integrity": "sha512-xJBAbDifo5hpffDBuHl0Y8ywswbiAp/Wi7Y/GtAgSlZyIABppyurxVueOPE8LUQOxdlgi6Zqce7uoEpqNTeiUw==", + "node_modules/@secretlint/formatter/node_modules/ansi-regex": { + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.2.2.tgz", + "integrity": "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==", "dev": true, - "license": "MIT" + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } }, - "node_modules/@types/estree": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.8.tgz", - "integrity": "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==", + "node_modules/@secretlint/formatter/node_modules/chalk": { + "version": "5.6.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.6.2.tgz", + "integrity": "sha512-7NzBL0rN6fMUW+f7A6Io4h40qQlG+xGmtMxfbnH/K7TAtt8JQWVQK+6g0UXKMeVJoyV5EkkNsErQ8pVD3bLHbA==", "dev": true, - "license": "MIT" + "license": "MIT", + "engines": { + "node": "^12.17.0 || ^14.13 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } }, - "node_modules/@types/express": { - "version": "5.0.6", - "resolved": "https://registry.npmjs.org/@types/express/-/express-5.0.6.tgz", - "integrity": "sha512-sKYVuV7Sv9fbPIt/442koC7+IIwK5olP1KWeD88e/idgoJqDm3JV/YUiPwkoKK92ylff2MGxSz1CSjsXelx0YA==", + "node_modules/@secretlint/formatter/node_modules/strip-ansi": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.2.tgz", + "integrity": "sha512-gmBGslpoQJtgnMAvOVqGZpEz9dyoKTCzy2nfz/n8aIFhN/jCE/rCmcxabB6jOOHV+0WNnylOxaxBQPSvcWklhA==", "dev": true, "license": "MIT", "dependencies": { - "@types/body-parser": "*", - "@types/express-serve-static-core": "^5.0.0", - "@types/serve-static": "^2" + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" } }, - "node_modules/@types/express-serve-static-core": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-5.1.1.tgz", - "integrity": "sha512-v4zIMr/cX7/d2BpAEX3KNKL/JrT1s43s96lLvvdTmza1oEvDudCqK9aF/djc/SWgy8Yh0h30TZx5VpzqFCxk5A==", + "node_modules/@secretlint/node": { + "version": "10.2.2", + "resolved": "https://registry.npmjs.org/@secretlint/node/-/node-10.2.2.tgz", + "integrity": "sha512-eZGJQgcg/3WRBwX1bRnss7RmHHK/YlP/l7zOQsrjexYt6l+JJa5YhUmHbuGXS94yW0++3YkEJp0kQGYhiw1DMQ==", "dev": true, "license": "MIT", "dependencies": { - "@types/node": "*", - "@types/qs": "*", - "@types/range-parser": "*", - "@types/send": "*" + "@secretlint/config-loader": "^10.2.2", + "@secretlint/core": "^10.2.2", + "@secretlint/formatter": "^10.2.2", + "@secretlint/profiler": "^10.2.2", + "@secretlint/source-creator": "^10.2.2", + "@secretlint/types": "^10.2.2", + "debug": "^4.4.1", + "p-map": "^7.0.3" + }, + "engines": { + "node": ">=20.0.0" } }, - "node_modules/@types/http-errors": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/@types/http-errors/-/http-errors-2.0.5.tgz", - "integrity": "sha512-r8Tayk8HJnX0FztbZN7oVqGccWgw98T/0neJphO91KkmOzug1KkofZURD4UaD5uH8AqcFLfdPErnBod0u71/qg==", + "node_modules/@secretlint/profiler": { + "version": "10.2.2", + "resolved": "https://registry.npmjs.org/@secretlint/profiler/-/profiler-10.2.2.tgz", + "integrity": "sha512-qm9rWfkh/o8OvzMIfY8a5bCmgIniSpltbVlUVl983zDG1bUuQNd1/5lUEeWx5o/WJ99bXxS7yNI4/KIXfHexig==", "dev": true, "license": "MIT" }, - "node_modules/@types/js-yaml": { - "version": "4.0.9", - "resolved": "https://registry.npmjs.org/@types/js-yaml/-/js-yaml-4.0.9.tgz", - "integrity": "sha512-k4MGaQl5TGo/iipqb2UDG2UwjXziSWkh0uysQelTlJpX1qGlpUZYm8PnO4DxG1qBomtJUdYJ6qR6xdIah10JLg==", + "node_modules/@secretlint/resolver": { + "version": "10.2.2", + "resolved": "https://registry.npmjs.org/@secretlint/resolver/-/resolver-10.2.2.tgz", + "integrity": "sha512-3md0cp12e+Ae5V+crPQYGd6aaO7ahw95s28OlULGyclyyUtf861UoRGS2prnUrKh7MZb23kdDOyGCYb9br5e4w==", "dev": true, "license": "MIT" }, - "node_modules/@types/json-schema": { - "version": "7.0.15", - "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", - "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", + "node_modules/@secretlint/secretlint-formatter-sarif": { + "version": "10.2.2", + "resolved": "https://registry.npmjs.org/@secretlint/secretlint-formatter-sarif/-/secretlint-formatter-sarif-10.2.2.tgz", + "integrity": "sha512-ojiF9TGRKJJw308DnYBucHxkpNovDNu1XvPh7IfUp0A12gzTtxuWDqdpuVezL7/IP8Ua7mp5/VkDMN9OLp1doQ==", "dev": true, - "license": "MIT" + "license": "MIT", + "dependencies": { + "node-sarif-builder": "^3.2.0" + } }, - "node_modules/@types/mocha": { - "version": "10.0.10", + "node_modules/@secretlint/secretlint-rule-no-dotenv": { + "version": "10.2.2", + "resolved": "https://registry.npmjs.org/@secretlint/secretlint-rule-no-dotenv/-/secretlint-rule-no-dotenv-10.2.2.tgz", + "integrity": "sha512-KJRbIShA9DVc5Va3yArtJ6QDzGjg3PRa1uYp9As4RsyKtKSSZjI64jVca57FZ8gbuk4em0/0Jq+uy6485wxIdg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@secretlint/types": "^10.2.2" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@secretlint/secretlint-rule-preset-recommend": { + "version": "10.2.2", + "resolved": "https://registry.npmjs.org/@secretlint/secretlint-rule-preset-recommend/-/secretlint-rule-preset-recommend-10.2.2.tgz", + "integrity": "sha512-K3jPqjva8bQndDKJqctnGfwuAxU2n9XNCPtbXVI5JvC7FnQiNg/yWlQPbMUlBXtBoBGFYp08A94m6fvtc9v+zA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@secretlint/source-creator": { + "version": "10.2.2", + "resolved": "https://registry.npmjs.org/@secretlint/source-creator/-/source-creator-10.2.2.tgz", + "integrity": "sha512-h6I87xJfwfUTgQ7irWq7UTdq/Bm1RuQ/fYhA3dtTIAop5BwSFmZyrchph4WcoEvbN460BWKmk4RYSvPElIIvxw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@secretlint/types": "^10.2.2", + "istextorbinary": "^9.5.0" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@secretlint/types": { + "version": "10.2.2", + "resolved": "https://registry.npmjs.org/@secretlint/types/-/types-10.2.2.tgz", + "integrity": "sha512-Nqc90v4lWCXyakD6xNyNACBJNJ0tNCwj2WNk/7ivyacYHxiITVgmLUFXTBOeCdy79iz6HtN9Y31uw/jbLrdOAg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@sindresorhus/merge-streams": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/@sindresorhus/merge-streams/-/merge-streams-2.3.0.tgz", + "integrity": "sha512-LtoMMhxAlorcGhmFYI+LhPgbPZCkgP6ra1YL604EeF6U98pLlQ3iWIGMdWSC+vWmPBWBNgmDBAhnAobLROJmwg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@standard-schema/spec": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@standard-schema/spec/-/spec-1.1.0.tgz", + "integrity": "sha512-l2aFy5jALhniG5HgqrD6jXLi/rUWrKvqN/qJx6yoJsgKhblVd+iqqU4RCXavm/jPityDo5TCvKMnpjKnOriy0w==", + "dev": true, + "license": "MIT" + }, + "node_modules/@textlint/ast-node-types": { + "version": "15.5.1", + "resolved": "https://registry.npmjs.org/@textlint/ast-node-types/-/ast-node-types-15.5.1.tgz", + "integrity": "sha512-2ABQSaQoM9u9fycXLJKcCv4XQulJWTUSwjo6F0i/ujjqOH8/AZ2A0RDKKbAddqxDhuabVB20lYoEsZZgzehccg==", + "dev": true, + "license": "MIT" + }, + "node_modules/@textlint/linter-formatter": { + "version": "15.5.1", + "resolved": "https://registry.npmjs.org/@textlint/linter-formatter/-/linter-formatter-15.5.1.tgz", + "integrity": "sha512-7wfzpcQtk7TZ3UJO2deTI71mJCm4VvPGUmSwE4iuH6FoaxpdWpwSBiMLcZtjYrt/oIFOtNz0uf5rI+xJiHTFww==", + "dev": true, + "license": "MIT", + "dependencies": { + "@azu/format-text": "^1.0.2", + "@azu/style-format": "^1.0.1", + "@textlint/module-interop": "15.5.1", + "@textlint/resolver": "15.5.1", + "@textlint/types": "15.5.1", + "chalk": "^4.1.2", + "debug": "^4.4.3", + "js-yaml": "^4.1.1", + "lodash": "^4.17.21", + "pluralize": "^2.0.0", + "string-width": "^4.2.3", + "strip-ansi": "^6.0.1", + "table": "^6.9.0", + "text-table": "^0.2.0" + } + }, + "node_modules/@textlint/linter-formatter/node_modules/pluralize": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/pluralize/-/pluralize-2.0.0.tgz", + "integrity": "sha512-TqNZzQCD4S42De9IfnnBvILN7HAW7riLqsCyp8lgjXeysyPlX5HhqKAcJHHHb9XskE4/a+7VGC9zzx8Ls0jOAw==", + "dev": true, + "license": "MIT" + }, + "node_modules/@textlint/module-interop": { + "version": "15.5.1", + "resolved": "https://registry.npmjs.org/@textlint/module-interop/-/module-interop-15.5.1.tgz", + "integrity": "sha512-Y1jcFGCKNSmHxwsLO3mshOfLYX4Wavq2+w5BG6x5lGgZv0XrF1xxURRhbnhns4LzCu0fAcx6W+3V8/1bkyTZCw==", + "dev": true, + "license": "MIT" + }, + "node_modules/@textlint/resolver": { + "version": "15.5.1", + "resolved": "https://registry.npmjs.org/@textlint/resolver/-/resolver-15.5.1.tgz", + "integrity": "sha512-CVHxMIm8iNGccqM12CQ/ycvh+HjJId4RyC6as5ynCcp2E1Uy1TCe0jBWOpmLsbT4Nx15Ke29BmspyByawuIRyA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@textlint/types": { + "version": "15.5.1", + "resolved": "https://registry.npmjs.org/@textlint/types/-/types-15.5.1.tgz", + "integrity": "sha512-IY1OVZZk8LOOrbapYCsaeH7XSJT89HVukixDT8CoiWMrKGCTCZ3/Kzoa3DtMMbY8jtY777QmPOVCNnR+8fF6YQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@textlint/ast-node-types": "15.5.1" + } + }, + "node_modules/@types/body-parser": { + "version": "1.19.6", + "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.6.tgz", + "integrity": "sha512-HLFeCYgz89uk22N5Qg3dvGvsv46B8GLvKKo1zKG4NybA8U2DiEO3w9lqGg29t/tfLRJpJ6iQxnVw4OnB7MoM9g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/connect": "*", + "@types/node": "*" + } + }, + "node_modules/@types/chai": { + "version": "5.2.3", + "resolved": "https://registry.npmjs.org/@types/chai/-/chai-5.2.3.tgz", + "integrity": "sha512-Mw558oeA9fFbv65/y4mHtXDs9bPnFMZAL/jxdPFUpOHHIXX91mcgEHbS5Lahr+pwZFR8A7GQleRWeI6cGFC2UA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/deep-eql": "*", + "assertion-error": "^2.0.1" + } + }, + "node_modules/@types/connect": { + "version": "3.4.38", + "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.38.tgz", + "integrity": "sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/cors": { + "version": "2.8.19", + "resolved": "https://registry.npmjs.org/@types/cors/-/cors-2.8.19.tgz", + "integrity": "sha512-mFNylyeyqN93lfe/9CSxOGREz8cpzAhH+E93xJ4xWQf62V8sQ/24reV2nyzUWM6H6Xji+GGHpkbLe7pVoUEskg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/deep-eql": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@types/deep-eql/-/deep-eql-4.0.2.tgz", + "integrity": "sha512-c9h9dVVMigMPc4bwTvC5dxqtqJZwQPePsWjPlpSOnojbor6pGqdk541lfA7AqFQr5pB1BRdq0juY9db81BwyFw==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/esrecurse": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/@types/esrecurse/-/esrecurse-4.3.1.tgz", + "integrity": "sha512-xJBAbDifo5hpffDBuHl0Y8ywswbiAp/Wi7Y/GtAgSlZyIABppyurxVueOPE8LUQOxdlgi6Zqce7uoEpqNTeiUw==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/estree": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.8.tgz", + "integrity": "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/express": { + "version": "5.0.6", + "resolved": "https://registry.npmjs.org/@types/express/-/express-5.0.6.tgz", + "integrity": "sha512-sKYVuV7Sv9fbPIt/442koC7+IIwK5olP1KWeD88e/idgoJqDm3JV/YUiPwkoKK92ylff2MGxSz1CSjsXelx0YA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/body-parser": "*", + "@types/express-serve-static-core": "^5.0.0", + "@types/serve-static": "^2" + } + }, + "node_modules/@types/express-serve-static-core": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-5.1.1.tgz", + "integrity": "sha512-v4zIMr/cX7/d2BpAEX3KNKL/JrT1s43s96lLvvdTmza1oEvDudCqK9aF/djc/SWgy8Yh0h30TZx5VpzqFCxk5A==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*", + "@types/qs": "*", + "@types/range-parser": "*", + "@types/send": "*" + } + }, + "node_modules/@types/http-errors": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@types/http-errors/-/http-errors-2.0.5.tgz", + "integrity": "sha512-r8Tayk8HJnX0FztbZN7oVqGccWgw98T/0neJphO91KkmOzug1KkofZURD4UaD5uH8AqcFLfdPErnBod0u71/qg==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/js-yaml": { + "version": "4.0.9", + "resolved": "https://registry.npmjs.org/@types/js-yaml/-/js-yaml-4.0.9.tgz", + "integrity": "sha512-k4MGaQl5TGo/iipqb2UDG2UwjXziSWkh0uysQelTlJpX1qGlpUZYm8PnO4DxG1qBomtJUdYJ6qR6xdIah10JLg==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/json-schema": { + "version": "7.0.15", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", + "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/mocha": { + "version": "10.0.10", "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-10.0.10.tgz", "integrity": "sha512-xPyYSz1cMPnJQhl0CLMH68j3gprKZaTjG3s5Vi+fDgx+uhG9NOXwbVt52eFS8ECyXhyKcjDLCBEqBExKuiZb7Q==", "dev": true, @@ -1641,6 +2190,13 @@ "undici-types": "~7.16.0" } }, + "node_modules/@types/normalize-package-data": { + "version": "2.4.4", + "resolved": "https://registry.npmjs.org/@types/normalize-package-data/-/normalize-package-data-2.4.4.tgz", + "integrity": "sha512-37i+OaWTh9qeK4LSHPsyRC7NahnGotNuZvjLSgcPzblpHB3rrCJxAOgI5gCdKm7coonsaX1Of0ILiTcnZjbfxA==", + "dev": true, + "license": "MIT" + }, "node_modules/@types/qs": { "version": "6.14.0", "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.14.0.tgz", @@ -1655,6 +2211,13 @@ "dev": true, "license": "MIT" }, + "node_modules/@types/sarif": { + "version": "2.1.7", + "resolved": "https://registry.npmjs.org/@types/sarif/-/sarif-2.1.7.tgz", + "integrity": "sha512-kRz0VEkJqWLf1LLVN4pT1cg1Z9wAuvI6L97V3m2f5B76Tg8d413ddvLBPTEHAZJlnn4XSvu0FkZtViCQGVyrXQ==", + "dev": true, + "license": "MIT" + }, "node_modules/@types/send": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/@types/send/-/send-1.2.1.tgz", @@ -1728,6 +2291,7 @@ "integrity": "sha512-4z2nCSBfVIMnbuu8uinj+f0o4qOeggYJLbjpPHka3KH1om7e+H9yLKTYgksTaHcGco+NClhhY2vyO3HsMH1RGw==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "@typescript-eslint/scope-manager": "8.55.0", "@typescript-eslint/types": "8.55.0", @@ -1939,6 +2503,21 @@ "url": "https://opencollective.com/typescript-eslint" } }, + "node_modules/@typespec/ts-http-runtime": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/@typespec/ts-http-runtime/-/ts-http-runtime-0.3.3.tgz", + "integrity": "sha512-91fp6CAAJSRtH5ja95T1FHSKa8aPW9/Zw6cta81jlZTUw/+Vq8jM/AfF/14h2b71wwR84JUTW/3Y8QPhDAawFA==", + "dev": true, + "license": "MIT", + "dependencies": { + "http-proxy-agent": "^7.0.0", + "https-proxy-agent": "^7.0.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=20.0.0" + } + }, "node_modules/@vitest/coverage-v8": { "version": "4.0.18", "resolved": "https://registry.npmjs.org/@vitest/coverage-v8/-/coverage-v8-4.0.18.tgz", @@ -2081,6 +2660,198 @@ "url": "https://opencollective.com/vitest" } }, + "node_modules/@vscode/vsce": { + "version": "3.7.1", + "resolved": "https://registry.npmjs.org/@vscode/vsce/-/vsce-3.7.1.tgz", + "integrity": "sha512-OTm2XdMt2YkpSn2Nx7z2EJtSuhRHsTPYsSK59hr3v8jRArK+2UEoju4Jumn1CmpgoBLGI6ReHLJ/czYltNUW3g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@azure/identity": "^4.1.0", + "@secretlint/node": "^10.1.2", + "@secretlint/secretlint-formatter-sarif": "^10.1.2", + "@secretlint/secretlint-rule-no-dotenv": "^10.1.2", + "@secretlint/secretlint-rule-preset-recommend": "^10.1.2", + "@vscode/vsce-sign": "^2.0.0", + "azure-devops-node-api": "^12.5.0", + "chalk": "^4.1.2", + "cheerio": "^1.0.0-rc.9", + "cockatiel": "^3.1.2", + "commander": "^12.1.0", + "form-data": "^4.0.0", + "glob": "^11.0.0", + "hosted-git-info": "^4.0.2", + "jsonc-parser": "^3.2.0", + "leven": "^3.1.0", + "markdown-it": "^14.1.0", + "mime": "^1.3.4", + "minimatch": "^3.0.3", + "parse-semver": "^1.1.1", + "read": "^1.0.7", + "secretlint": "^10.1.2", + "semver": "^7.5.2", + "tmp": "^0.2.3", + "typed-rest-client": "^1.8.4", + "url-join": "^4.0.1", + "xml2js": "^0.5.0", + "yauzl": "^2.3.1", + "yazl": "^2.2.2" + }, + "bin": { + "vsce": "vsce" + }, + "engines": { + "node": ">= 20" + }, + "optionalDependencies": { + "keytar": "^7.7.0" + } + }, + "node_modules/@vscode/vsce-sign": { + "version": "2.0.9", + "resolved": "https://registry.npmjs.org/@vscode/vsce-sign/-/vsce-sign-2.0.9.tgz", + "integrity": "sha512-8IvaRvtFyzUnGGl3f5+1Cnor3LqaUWvhaUjAYO8Y39OUYlOf3cRd+dowuQYLpZcP3uwSG+mURwjEBOSq4SOJ0g==", + "dev": true, + "hasInstallScript": true, + "license": "SEE LICENSE IN LICENSE.txt", + "optionalDependencies": { + "@vscode/vsce-sign-alpine-arm64": "2.0.6", + "@vscode/vsce-sign-alpine-x64": "2.0.6", + "@vscode/vsce-sign-darwin-arm64": "2.0.6", + "@vscode/vsce-sign-darwin-x64": "2.0.6", + "@vscode/vsce-sign-linux-arm": "2.0.6", + "@vscode/vsce-sign-linux-arm64": "2.0.6", + "@vscode/vsce-sign-linux-x64": "2.0.6", + "@vscode/vsce-sign-win32-arm64": "2.0.6", + "@vscode/vsce-sign-win32-x64": "2.0.6" + } + }, + "node_modules/@vscode/vsce-sign-alpine-arm64": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/@vscode/vsce-sign-alpine-arm64/-/vsce-sign-alpine-arm64-2.0.6.tgz", + "integrity": "sha512-wKkJBsvKF+f0GfsUuGT0tSW0kZL87QggEiqNqK6/8hvqsXvpx8OsTEc3mnE1kejkh5r+qUyQ7PtF8jZYN0mo8Q==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "SEE LICENSE IN LICENSE.txt", + "optional": true, + "os": [ + "alpine" + ] + }, + "node_modules/@vscode/vsce-sign-alpine-x64": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/@vscode/vsce-sign-alpine-x64/-/vsce-sign-alpine-x64-2.0.6.tgz", + "integrity": "sha512-YoAGlmdK39vKi9jA18i4ufBbd95OqGJxRvF3n6ZbCyziwy3O+JgOpIUPxv5tjeO6gQfx29qBivQ8ZZTUF2Ba0w==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "SEE LICENSE IN LICENSE.txt", + "optional": true, + "os": [ + "alpine" + ] + }, + "node_modules/@vscode/vsce-sign-darwin-arm64": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/@vscode/vsce-sign-darwin-arm64/-/vsce-sign-darwin-arm64-2.0.6.tgz", + "integrity": "sha512-5HMHaJRIQuozm/XQIiJiA0W9uhdblwwl2ZNDSSAeXGO9YhB9MH5C4KIHOmvyjUnKy4UCuiP43VKpIxW1VWP4tQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "SEE LICENSE IN LICENSE.txt", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@vscode/vsce-sign-darwin-x64": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/@vscode/vsce-sign-darwin-x64/-/vsce-sign-darwin-x64-2.0.6.tgz", + "integrity": "sha512-25GsUbTAiNfHSuRItoQafXOIpxlYj+IXb4/qarrXu7kmbH94jlm5sdWSCKrrREs8+GsXF1b+l3OB7VJy5jsykw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "SEE LICENSE IN LICENSE.txt", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@vscode/vsce-sign-linux-arm": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/@vscode/vsce-sign-linux-arm/-/vsce-sign-linux-arm-2.0.6.tgz", + "integrity": "sha512-UndEc2Xlq4HsuMPnwu7420uqceXjs4yb5W8E2/UkaHBB9OWCwMd3/bRe/1eLe3D8kPpxzcaeTyXiK3RdzS/1CA==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "SEE LICENSE IN LICENSE.txt", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@vscode/vsce-sign-linux-arm64": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/@vscode/vsce-sign-linux-arm64/-/vsce-sign-linux-arm64-2.0.6.tgz", + "integrity": "sha512-cfb1qK7lygtMa4NUl2582nP7aliLYuDEVpAbXJMkDq1qE+olIw/es+C8j1LJwvcRq1I2yWGtSn3EkDp9Dq5FdA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "SEE LICENSE IN LICENSE.txt", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@vscode/vsce-sign-linux-x64": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/@vscode/vsce-sign-linux-x64/-/vsce-sign-linux-x64-2.0.6.tgz", + "integrity": "sha512-/olerl1A4sOqdP+hjvJ1sbQjKN07Y3DVnxO4gnbn/ahtQvFrdhUi0G1VsZXDNjfqmXw57DmPi5ASnj/8PGZhAA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "SEE LICENSE IN LICENSE.txt", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@vscode/vsce-sign-win32-arm64": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/@vscode/vsce-sign-win32-arm64/-/vsce-sign-win32-arm64-2.0.6.tgz", + "integrity": "sha512-ivM/MiGIY0PJNZBoGtlRBM/xDpwbdlCWomUWuLmIxbi1Cxe/1nooYrEQoaHD8ojVRgzdQEUzMsRbyF5cJJgYOg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "SEE LICENSE IN LICENSE.txt", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@vscode/vsce-sign-win32-x64": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/@vscode/vsce-sign-win32-x64/-/vsce-sign-win32-x64-2.0.6.tgz", + "integrity": "sha512-mgth9Kvze+u8CruYMmhHw6Zgy3GRX2S+Ed5oSokDEK5vPEwGGKnmuXua9tmFhomeAnhgJnL4DCna3TiNuGrBTQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "SEE LICENSE IN LICENSE.txt", + "optional": true, + "os": [ + "win32" + ] + }, "node_modules/accepts": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/accepts/-/accepts-2.0.0.tgz", @@ -2100,6 +2871,7 @@ "integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==", "dev": true, "license": "MIT", + "peer": true, "bin": { "acorn": "bin/acorn" }, @@ -2117,6 +2889,16 @@ "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" } }, + "node_modules/agent-base": { + "version": "7.1.4", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.4.tgz", + "integrity": "sha512-MnA+YT8fwfJPgBx3m60MNqakm30XOkyIoH1y6huTQvC0PwZG7ki8NacLBcrPbNoo8vEZy7Jpuk7+jMO+CUovTQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 14" + } + }, "node_modules/ajv": { "version": "6.12.6", "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", @@ -2173,6 +2955,22 @@ "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", "license": "MIT" }, + "node_modules/ansi-escapes": { + "version": "7.3.0", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-7.3.0.tgz", + "integrity": "sha512-BvU8nYgGQBxcmMuEeUEmNTvrMVjJNSH7RgW24vXexN4Ven6qCvy4TntnvlnwnMLTVlcRQQdbRY8NKnaIoeWDNg==", + "dev": true, + "license": "MIT", + "dependencies": { + "environment": "^1.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/ansi-regex": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", @@ -2227,6 +3025,34 @@ "js-tokens": "^10.0.0" } }, + "node_modules/astral-regex": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz", + "integrity": "sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", + "dev": true, + "license": "MIT" + }, + "node_modules/azure-devops-node-api": { + "version": "12.5.0", + "resolved": "https://registry.npmjs.org/azure-devops-node-api/-/azure-devops-node-api-12.5.0.tgz", + "integrity": "sha512-R5eFskGvOm3U/GzeAuxRkUsAl0hrAwGgWn6zAd2KrZmrEhWZVqLew4OOupbQlXUuojUzpGtq62SmdhJ06N88og==", + "dev": true, + "license": "MIT", + "dependencies": { + "tunnel": "0.0.6", + "typed-rest-client": "^1.8.4" + } + }, "node_modules/balanced-match": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", @@ -2234,6 +3060,57 @@ "dev": true, "license": "MIT" }, + "node_modules/base64-js": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", + "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT", + "optional": true + }, + "node_modules/binaryextensions": { + "version": "6.11.0", + "resolved": "https://registry.npmjs.org/binaryextensions/-/binaryextensions-6.11.0.tgz", + "integrity": "sha512-sXnYK/Ij80TO3lcqZVV2YgfKN5QjUWIRk/XSm2J/4bd/lPko3lvk0O4ZppH6m+6hB2/GTu+ptNwVFe1xh+QLQw==", + "dev": true, + "license": "Artistic-2.0", + "dependencies": { + "editions": "^6.21.0" + }, + "engines": { + "node": ">=4" + }, + "funding": { + "url": "https://bevry.me/fund" + } + }, + "node_modules/bl": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz", + "integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "buffer": "^5.5.0", + "inherits": "^2.0.4", + "readable-stream": "^3.4.0" + } + }, "node_modules/body-parser": { "version": "2.2.2", "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-2.2.2.tgz", @@ -2258,6 +3135,20 @@ "url": "https://opencollective.com/express" } }, + "node_modules/boolbase": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz", + "integrity": "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==", + "dev": true, + "license": "ISC" + }, + "node_modules/boundary": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/boundary/-/boundary-2.0.0.tgz", + "integrity": "sha512-rJKn5ooC9u8q13IMCrW0RSp31pxBCHE3y9V/tp3TdWSLf8Em3p6Di4NBpfzbJge9YjjFEsD0RtFEjtvHL5VyEA==", + "dev": true, + "license": "BSD-2-Clause" + }, "node_modules/brace-expansion": { "version": "1.1.12", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", @@ -2269,6 +3160,19 @@ "concat-map": "0.0.1" } }, + "node_modules/braces": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", + "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", + "dev": true, + "license": "MIT", + "dependencies": { + "fill-range": "^7.1.1" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/browser-stdout": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz", @@ -2276,6 +3180,65 @@ "dev": true, "license": "ISC" }, + "node_modules/buffer": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", + "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT", + "optional": true, + "dependencies": { + "base64-js": "^1.3.1", + "ieee754": "^1.1.13" + } + }, + "node_modules/buffer-crc32": { + "version": "0.2.13", + "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz", + "integrity": "sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": "*" + } + }, + "node_modules/buffer-equal-constant-time": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz", + "integrity": "sha512-zRpUiDwd/xk6ADqPMATG8vc9VPrkck7T07OIx0gnjmJAnHnTVXNQG3vfvWNuiZIkwu9KrKdA1iJKfsfTVxE6NA==", + "dev": true, + "license": "BSD-3-Clause" + }, + "node_modules/bundle-name": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/bundle-name/-/bundle-name-4.1.0.tgz", + "integrity": "sha512-tjwM5exMg6BGRI+kNmTntNsvdZS1X8BFYS6tnJ2hdH0kVxM6/eVZ2xy+FqStSWvYmtfFMDLIxurorHwDKfDz5Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "run-applescript": "^7.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/bytes": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", @@ -2364,6 +3327,50 @@ "url": "https://github.com/chalk/chalk?sponsor=1" } }, + "node_modules/cheerio": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/cheerio/-/cheerio-1.2.0.tgz", + "integrity": "sha512-WDrybc/gKFpTYQutKIK6UvfcuxijIZfMfXaYm8NMsPQxSYvf+13fXUJ4rztGGbJcBQ/GF55gvrZ0Bc0bj/mqvg==", + "dev": true, + "license": "MIT", + "dependencies": { + "cheerio-select": "^2.1.0", + "dom-serializer": "^2.0.0", + "domhandler": "^5.0.3", + "domutils": "^3.2.2", + "encoding-sniffer": "^0.2.1", + "htmlparser2": "^10.1.0", + "parse5": "^7.3.0", + "parse5-htmlparser2-tree-adapter": "^7.1.0", + "parse5-parser-stream": "^7.1.2", + "undici": "^7.19.0", + "whatwg-mimetype": "^4.0.0" + }, + "engines": { + "node": ">=20.18.1" + }, + "funding": { + "url": "https://github.com/cheeriojs/cheerio?sponsor=1" + } + }, + "node_modules/cheerio-select": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/cheerio-select/-/cheerio-select-2.1.0.tgz", + "integrity": "sha512-9v9kG0LvzrlcungtnJtpGNxY+fzECQKhK4EGJX2vByejiMX84MFNQw4UxPJl3bFbTMw+Dfs37XaIkCwTZfLh4g==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "boolbase": "^1.0.0", + "css-select": "^5.1.0", + "css-what": "^6.1.0", + "domelementtype": "^2.3.0", + "domhandler": "^5.0.3", + "domutils": "^3.0.1" + }, + "funding": { + "url": "https://github.com/sponsors/fb55" + } + }, "node_modules/chokidar": { "version": "4.0.3", "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-4.0.3.tgz", @@ -2380,6 +3387,14 @@ "url": "https://paulmillr.com/funding/" } }, + "node_modules/chownr": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz", + "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==", + "dev": true, + "license": "ISC", + "optional": true + }, "node_modules/cliui": { "version": "8.0.1", "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", @@ -2395,6 +3410,16 @@ "node": ">=12" } }, + "node_modules/cockatiel": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/cockatiel/-/cockatiel-3.2.1.tgz", + "integrity": "sha512-gfrHV6ZPkquExvMh9IOkKsBzNDk6sDuZ6DdBGUBkvFnTCqCxzpuq48RySgP0AnaqQkw2zynOFj9yly6T1Q2G5Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=16" + } + }, "node_modules/codeql-development-mcp-server": { "resolved": "server", "link": true @@ -2403,10 +3428,6 @@ "resolved": "client", "link": true }, - "node_modules/codeql-development-mcp-server-vscode": { - "resolved": "extensions/vscode", - "link": true - }, "node_modules/color-convert": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", @@ -2427,6 +3448,29 @@ "dev": true, "license": "MIT" }, + "node_modules/combined-stream": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "dev": true, + "license": "MIT", + "dependencies": { + "delayed-stream": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/commander": { + "version": "12.1.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-12.1.0.tgz", + "integrity": "sha512-Vw8qHK3bZM9y/P10u3Vib8o/DdkvA2OtPtZvD871QKjy74Wj1WSKFILMPRPSdUSx5RFK1arlJzEtA4PkFgnbuA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + } + }, "node_modules/concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", @@ -2505,6 +3549,36 @@ "node": ">= 8" } }, + "node_modules/css-select": { + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/css-select/-/css-select-5.2.2.tgz", + "integrity": "sha512-TizTzUddG/xYLA3NXodFM0fSbNizXjOKhqiQQwvhlspadZokn1KDy0NZFS0wuEubIYAV5/c1/lAr0TaaFXEXzw==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "boolbase": "^1.0.0", + "css-what": "^6.1.0", + "domhandler": "^5.0.2", + "domutils": "^3.0.1", + "nth-check": "^2.0.1" + }, + "funding": { + "url": "https://github.com/sponsors/fb55" + } + }, + "node_modules/css-what": { + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/css-what/-/css-what-6.2.2.tgz", + "integrity": "sha512-u/O3vwbptzhMs3L1fQE82ZSLHQQfto5gyZzwteVIEyeaY5Fc7R4dapF/BvRoSYFeqfBk4m0V1Vafq5Pjv25wvA==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">= 6" + }, + "funding": { + "url": "https://github.com/sponsors/fb55" + } + }, "node_modules/debug": { "version": "4.4.3", "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", @@ -2535,6 +3609,34 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/decompress-response": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-6.0.0.tgz", + "integrity": "sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "mimic-response": "^3.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/deep-extend": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", + "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==", + "dev": true, + "license": "MIT", + "optional": true, + "engines": { + "node": ">=4.0.0" + } + }, "node_modules/deep-is": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", @@ -2542,6 +3644,59 @@ "dev": true, "license": "MIT" }, + "node_modules/default-browser": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/default-browser/-/default-browser-5.5.0.tgz", + "integrity": "sha512-H9LMLr5zwIbSxrmvikGuI/5KGhZ8E2zH3stkMgM5LpOWDutGM2JZaj460Udnf1a+946zc7YBgrqEWwbk7zHvGw==", + "dev": true, + "license": "MIT", + "dependencies": { + "bundle-name": "^4.1.0", + "default-browser-id": "^5.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/default-browser-id": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/default-browser-id/-/default-browser-id-5.0.1.tgz", + "integrity": "sha512-x1VCxdX4t+8wVfd1so/9w+vQ4vx7lKd2Qp5tDRutErwmR85OgmfX7RlLRMWafRMY7hbEiXIbudNrjOAPa/hL8Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/define-lazy-prop": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/define-lazy-prop/-/define-lazy-prop-3.0.0.tgz", + "integrity": "sha512-N+MeXYoqr3pOgn8xfyRPREN7gHakLYjhsHhWGT3fWAiL4IkAt0iDw14QiiEm2bE30c5XX5q0FtAA3CK5f9/BUg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.4.0" + } + }, "node_modules/depd": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", @@ -2551,6 +3706,17 @@ "node": ">= 0.8" } }, + "node_modules/detect-libc": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.1.2.tgz", + "integrity": "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==", + "dev": true, + "license": "Apache-2.0", + "optional": true, + "engines": { + "node": ">=8" + } + }, "node_modules/diff": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/diff/-/diff-7.0.0.tgz", @@ -2561,6 +3727,65 @@ "node": ">=0.3.1" } }, + "node_modules/dom-serializer": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-2.0.0.tgz", + "integrity": "sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==", + "dev": true, + "license": "MIT", + "dependencies": { + "domelementtype": "^2.3.0", + "domhandler": "^5.0.2", + "entities": "^4.2.0" + }, + "funding": { + "url": "https://github.com/cheeriojs/dom-serializer?sponsor=1" + } + }, + "node_modules/domelementtype": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz", + "integrity": "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fb55" + } + ], + "license": "BSD-2-Clause" + }, + "node_modules/domhandler": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-5.0.3.tgz", + "integrity": "sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "domelementtype": "^2.3.0" + }, + "engines": { + "node": ">= 4" + }, + "funding": { + "url": "https://github.com/fb55/domhandler?sponsor=1" + } + }, + "node_modules/domutils": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/domutils/-/domutils-3.2.2.tgz", + "integrity": "sha512-6kZKyUajlDuqlHKVX1w7gyslj9MPIXzIFiz/rGu35uC1wMi+kMhQwGhl4lt9unC9Vb9INnY9Z3/ZA3+FhASLaw==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "dom-serializer": "^2.0.0", + "domelementtype": "^2.3.0", + "domhandler": "^5.0.3" + }, + "funding": { + "url": "https://github.com/fb55/domutils?sponsor=1" + } + }, "node_modules/dotenv": { "version": "17.3.0", "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-17.3.0.tgz", @@ -2594,6 +3819,33 @@ "dev": true, "license": "MIT" }, + "node_modules/ecdsa-sig-formatter": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz", + "integrity": "sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "safe-buffer": "^5.0.1" + } + }, + "node_modules/editions": { + "version": "6.22.0", + "resolved": "https://registry.npmjs.org/editions/-/editions-6.22.0.tgz", + "integrity": "sha512-UgGlf8IW75je7HZjNDpJdCv4cGJWIi6yumFdZ0R7A8/CIhQiWUjyGLCxdHpd8bmyD1gnkfUNK0oeOXqUS2cpfQ==", + "dev": true, + "license": "Artistic-2.0", + "dependencies": { + "version-range": "^4.15.0" + }, + "engines": { + "ecmascript": ">= es5", + "node": ">=4" + }, + "funding": { + "url": "https://bevry.me/fund" + } + }, "node_modules/ee-first": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", @@ -2616,6 +3868,70 @@ "node": ">= 0.8" } }, + "node_modules/encoding-sniffer": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/encoding-sniffer/-/encoding-sniffer-0.2.1.tgz", + "integrity": "sha512-5gvq20T6vfpekVtqrYQsSCFZ1wEg5+wW0/QaZMWkFr6BqD3NfKs0rLCx4rrVlSWJeZb5NBJgVLswK/w2MWU+Gw==", + "dev": true, + "license": "MIT", + "dependencies": { + "iconv-lite": "^0.6.3", + "whatwg-encoding": "^3.1.1" + }, + "funding": { + "url": "https://github.com/fb55/encoding-sniffer?sponsor=1" + } + }, + "node_modules/encoding-sniffer/node_modules/iconv-lite": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", + "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", + "dev": true, + "license": "MIT", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/end-of-stream": { + "version": "1.4.5", + "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.5.tgz", + "integrity": "sha512-ooEGc6HP26xXq/N+GCGOT0JKCLDGrq2bQUZrQ7gyrJiZANJ/8YDTxTpQBXGMn+WbIQXNVpyWymm7KYVICQnyOg==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "once": "^1.4.0" + } + }, + "node_modules/entities": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", + "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.12" + }, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, + "node_modules/environment": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/environment/-/environment-1.1.0.tgz", + "integrity": "sha512-xUtoPkMggbz0MPyPiIWr1Kp4aeWJjDZ6SMvURhimjdZgsRuDplF5/s9hcgGhyXMhs+6vpnuoiZ2kFiu3FMnS8Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/es-define-property": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz", @@ -2653,6 +3969,22 @@ "node": ">= 0.4" } }, + "node_modules/es-set-tostringtag": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.1.0.tgz", + "integrity": "sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.6", + "has-tostringtag": "^1.0.2", + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/esbuild": { "version": "0.27.3", "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.27.3.tgz", @@ -2965,6 +4297,17 @@ "node": ">=18.0.0" } }, + "node_modules/expand-template": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/expand-template/-/expand-template-2.0.3.tgz", + "integrity": "sha512-XYfuKMvj4O35f/pOXLObndIRvyQ+/+6AhODh+OKWj9S9498pHHn/IMszH+gt0fBCRWMNfk1ZSp5x3AifmnI2vg==", + "dev": true, + "license": "(MIT OR WTFPL)", + "optional": true, + "engines": { + "node": ">=6" + } + }, "node_modules/expect-type": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/expect-type/-/expect-type-1.3.0.tgz", @@ -2980,6 +4323,7 @@ "resolved": "https://registry.npmjs.org/express/-/express-5.2.1.tgz", "integrity": "sha512-hIS4idWWai69NezIdRt2xFVofaF4j+6INOpJlVOLDO8zXGpUVEVzIYk12UUi2JzjEzWL3IOAxcTubgz9Po0yXw==", "license": "MIT", + "peer": true, "dependencies": { "accepts": "^2.0.0", "body-parser": "^2.2.1", @@ -3049,6 +4393,36 @@ "dev": true, "license": "Apache-2.0" }, + "node_modules/fast-glob": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.3.tgz", + "integrity": "sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.2", + "merge2": "^1.3.0", + "micromatch": "^4.0.8" + }, + "engines": { + "node": ">=8.6.0" + } + }, + "node_modules/fast-glob/node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "license": "ISC", + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, "node_modules/fast-json-stable-stringify": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", @@ -3079,6 +4453,26 @@ ], "license": "BSD-3-Clause" }, + "node_modules/fastq": { + "version": "1.20.1", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.20.1.tgz", + "integrity": "sha512-GGToxJ/w1x32s/D2EKND7kTil4n8OVk/9mycTc4VDza13lOvpUZTGX3mFSCtV9ksdGBVzvsyAVLM6mHFThxXxw==", + "dev": true, + "license": "ISC", + "dependencies": { + "reusify": "^1.0.4" + } + }, + "node_modules/fd-slicer": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.1.0.tgz", + "integrity": "sha512-cE1qsB/VwyQozZ+q1dGxR8LBYNZeofhEdUNGSMbQD3Gw2lAzX9Zb3uIU6Ebc/Fmyjo9AWWfnn0AUCHqtevs/8g==", + "dev": true, + "license": "MIT", + "dependencies": { + "pend": "~1.2.0" + } + }, "node_modules/fdir": { "version": "6.5.0", "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz", @@ -3110,6 +4504,19 @@ "node": ">=16.0.0" } }, + "node_modules/fill-range": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", + "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", + "dev": true, + "license": "MIT", + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/finalhandler": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-2.1.1.tgz", @@ -3196,6 +4603,46 @@ "url": "https://github.com/sponsors/isaacs" } }, + "node_modules/form-data": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.5.tgz", + "integrity": "sha512-8RipRLol37bNs2bhoV67fiTEvdTrbMUYcFTiy3+wuuOnUog2QBHCZWXDRijWQfAkhBj2Uf5UnVaiWwA5vdd82w==", + "dev": true, + "license": "MIT", + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "es-set-tostringtag": "^2.1.0", + "hasown": "^2.0.2", + "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/form-data/node_modules/mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/form-data/node_modules/mime-types": { + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "dev": true, + "license": "MIT", + "dependencies": { + "mime-db": "1.52.0" + }, + "engines": { + "node": ">= 0.6" + } + }, "node_modules/forwarded": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", @@ -3214,6 +4661,29 @@ "node": ">= 0.8" } }, + "node_modules/fs-constants": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz", + "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==", + "dev": true, + "license": "MIT", + "optional": true + }, + "node_modules/fs-extra": { + "version": "11.3.3", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.3.3.tgz", + "integrity": "sha512-VWSRii4t0AFm6ixFFmLLx1t7wS1gh+ckoa84aOeapGum0h+EZd1EhEumSB+ZdDLnEPuucsVB9oB7cxJHap6Afg==", + "dev": true, + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, + "engines": { + "node": ">=14.14" + } + }, "node_modules/fsevents": { "version": "2.3.3", "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", @@ -3285,6 +4755,14 @@ "node": ">= 0.4" } }, + "node_modules/github-from-package": { + "version": "0.0.0", + "resolved": "https://registry.npmjs.org/github-from-package/-/github-from-package-0.0.0.tgz", + "integrity": "sha512-SyHy3T1v2NUXn29OsWdxmK6RwHD+vkj3v8en8AOBZ1wBQ/hCAQ5bAQTD02kW4W9tUp/3Qh6J8r9EvntiyCmOOw==", + "dev": true, + "license": "MIT", + "optional": true + }, "node_modules/glob": { "version": "11.1.0", "resolved": "https://registry.npmjs.org/glob/-/glob-11.1.0.tgz", @@ -3378,6 +4856,37 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/globby": { + "version": "14.1.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-14.1.0.tgz", + "integrity": "sha512-0Ia46fDOaT7k4og1PDW4YbodWWr3scS2vAr2lTbsplOt2WkKp0vQbkI9wKis/T5LV/dqPjO3bpS/z6GTJB82LA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@sindresorhus/merge-streams": "^2.1.0", + "fast-glob": "^3.3.3", + "ignore": "^7.0.3", + "path-type": "^6.0.0", + "slash": "^5.1.0", + "unicorn-magic": "^0.3.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/globby/node_modules/ignore": { + "version": "7.0.5", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-7.0.5.tgz", + "integrity": "sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 4" + } + }, "node_modules/gopd": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz", @@ -3390,6 +4899,13 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/graceful-fs": { + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", + "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", + "dev": true, + "license": "ISC" + }, "node_modules/has-flag": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", @@ -3412,6 +4928,22 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/has-tostringtag": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz", + "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-symbols": "^1.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/hasown": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", @@ -3439,10 +4971,37 @@ "resolved": "https://registry.npmjs.org/hono/-/hono-4.11.9.tgz", "integrity": "sha512-Eaw2YTGM6WOxA6CXbckaEvslr2Ne4NFsKrvc0v97JD5awbmeBLO5w9Ho9L9kmKonrwF9RJlW6BxT1PVv/agBHQ==", "license": "MIT", + "peer": true, "engines": { "node": ">=16.9.0" } }, + "node_modules/hosted-git-info": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-4.1.0.tgz", + "integrity": "sha512-kyCuEOWjJqZuDbRHzL8V93NzQhwIB71oFWSyzVo+KPZI+pnQPPxucdkrOZvkLRnrf5URsQM+IJ09Dw29cRALIA==", + "dev": true, + "license": "ISC", + "dependencies": { + "lru-cache": "^6.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/hosted-git-info/node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, + "license": "ISC", + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, "node_modules/html-escaper": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz", @@ -3450,6 +5009,39 @@ "dev": true, "license": "MIT" }, + "node_modules/htmlparser2": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-10.1.0.tgz", + "integrity": "sha512-VTZkM9GWRAtEpveh7MSF6SjjrpNVNNVJfFup7xTY3UpFtm67foy9HDVXneLtFVt4pMz5kZtgNcvCniNFb1hlEQ==", + "dev": true, + "funding": [ + "https://github.com/fb55/htmlparser2?sponsor=1", + { + "type": "github", + "url": "https://github.com/sponsors/fb55" + } + ], + "license": "MIT", + "dependencies": { + "domelementtype": "^2.3.0", + "domhandler": "^5.0.3", + "domutils": "^3.2.2", + "entities": "^7.0.1" + } + }, + "node_modules/htmlparser2/node_modules/entities": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/entities/-/entities-7.0.1.tgz", + "integrity": "sha512-TWrgLOFUQTH994YUyl1yT4uyavY5nNB5muff+RtWaqNVCAK408b5ZnnbNAUEWLTCpum9w6arT70i1XdQ4UeOPA==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.12" + }, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, "node_modules/http-errors": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.1.tgz", @@ -3470,6 +5062,34 @@ "url": "https://opencollective.com/express" } }, + "node_modules/http-proxy-agent": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-7.0.2.tgz", + "integrity": "sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig==", + "dev": true, + "license": "MIT", + "dependencies": { + "agent-base": "^7.1.0", + "debug": "^4.3.4" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/https-proxy-agent": { + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.6.tgz", + "integrity": "sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw==", + "dev": true, + "license": "MIT", + "dependencies": { + "agent-base": "^7.1.2", + "debug": "4" + }, + "engines": { + "node": ">= 14" + } + }, "node_modules/iconv-lite": { "version": "0.7.2", "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.7.2.tgz", @@ -3486,6 +5106,28 @@ "url": "https://opencollective.com/express" } }, + "node_modules/ieee754": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", + "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "BSD-3-Clause", + "optional": true + }, "node_modules/ignore": { "version": "5.3.2", "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", @@ -3523,12 +5165,33 @@ "node": ">=0.8.19" } }, + "node_modules/index-to-position": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/index-to-position/-/index-to-position-1.2.0.tgz", + "integrity": "sha512-Yg7+ztRkqslMAS2iFaU+Oa4KTSidr63OsFGlOrJoW981kIYO3CGCS3wA95P1mUi/IVSJkn0D479KTJpVpvFNuw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/inherits": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", "license": "ISC" }, + "node_modules/ini": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", + "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==", + "dev": true, + "license": "ISC", + "optional": true + }, "node_modules/ip-address": { "version": "10.0.1", "resolved": "https://registry.npmjs.org/ip-address/-/ip-address-10.0.1.tgz", @@ -3547,6 +5210,22 @@ "node": ">= 0.10" } }, + "node_modules/is-docker": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-3.0.0.tgz", + "integrity": "sha512-eljcgEDlEns/7AXFosB5K/2nCM4P7FQPkGc/DWLy5rmFEWvZayGrik1d9/QIY5nJ4f9YsVvBkA6kJpHn9rISdQ==", + "dev": true, + "license": "MIT", + "bin": { + "is-docker": "cli.js" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/is-extglob": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", @@ -3580,6 +5259,35 @@ "node": ">=0.10.0" } }, + "node_modules/is-inside-container": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-inside-container/-/is-inside-container-1.0.0.tgz", + "integrity": "sha512-KIYLCCJghfHZxqjYBE7rEy0OBuTd5xCHS7tHVgvCLkx7StIoaxwNW3hCALgEUjFfeRk+MG/Qxmp/vtETEF3tRA==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-docker": "^3.0.0" + }, + "bin": { + "is-inside-container": "cli.js" + }, + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.12.0" + } + }, "node_modules/is-path-inside": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", @@ -3619,6 +5327,22 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/is-wsl": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-3.1.1.tgz", + "integrity": "sha512-e6rvdUCiQCAuumZslxRJWR/Doq4VpPR82kqclvcS0efgt430SlGIk05vdCN58+VrzgtIcfNODjozVielycD4Sw==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-inside-container": "^1.0.0" + }, + "engines": { + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/isexe": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", @@ -3664,6 +5388,24 @@ "node": ">=8" } }, + "node_modules/istextorbinary": { + "version": "9.5.0", + "resolved": "https://registry.npmjs.org/istextorbinary/-/istextorbinary-9.5.0.tgz", + "integrity": "sha512-5mbUj3SiZXCuRf9fT3ibzbSSEWiy63gFfksmGfdOzujPjW3k+z8WvIBxcJHBoQNlaZaiyB25deviif2+osLmLw==", + "dev": true, + "license": "Artistic-2.0", + "dependencies": { + "binaryextensions": "^6.11.0", + "editions": "^6.21.0", + "textextensions": "^6.11.0" + }, + "engines": { + "node": ">=4" + }, + "funding": { + "url": "https://bevry.me/fund" + } + }, "node_modules/jackspeak": { "version": "4.2.3", "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-4.2.3.tgz", @@ -3720,20 +5462,112 @@ "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", "dev": true, - "license": "MIT" + "license": "MIT" + }, + "node_modules/json-schema-typed": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/json-schema-typed/-/json-schema-typed-8.0.2.tgz", + "integrity": "sha512-fQhoXdcvc3V28x7C7BMs4P5+kNlgUURe2jmUT1T//oBRMDrqy1QPelJimwZGo7Hg9VPV3EQV5Bnq4hbFy2vetA==", + "license": "BSD-2-Clause" + }, + "node_modules/json-stable-stringify-without-jsonify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", + "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", + "dev": true, + "license": "MIT" + }, + "node_modules/json5": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", + "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", + "dev": true, + "license": "MIT", + "bin": { + "json5": "lib/cli.js" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/jsonc-parser": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-3.3.1.tgz", + "integrity": "sha512-HUgH65KyejrUFPvHFPbqOY0rsFip3Bo5wb4ngvdi1EpCYWUQDC5V+Y7mZws+DLkr4M//zQJoanu1SP+87Dv1oQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/jsonfile": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.2.0.tgz", + "integrity": "sha512-FGuPw30AdOIUTRMC2OMRtQV+jkVj2cfPqSeWXv1NEAJ1qZ5zb1X6z1mFhbfOB/iy3ssJCD+3KuZ8r8C3uVFlAg==", + "dev": true, + "license": "MIT", + "dependencies": { + "universalify": "^2.0.0" + }, + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/jsonwebtoken": { + "version": "9.0.3", + "resolved": "https://registry.npmjs.org/jsonwebtoken/-/jsonwebtoken-9.0.3.tgz", + "integrity": "sha512-MT/xP0CrubFRNLNKvxJ2BYfy53Zkm++5bX9dtuPbqAeQpTVe0MQTFhao8+Cp//EmJp244xt6Drw/GVEGCUj40g==", + "dev": true, + "license": "MIT", + "dependencies": { + "jws": "^4.0.1", + "lodash.includes": "^4.3.0", + "lodash.isboolean": "^3.0.3", + "lodash.isinteger": "^4.0.4", + "lodash.isnumber": "^3.0.3", + "lodash.isplainobject": "^4.0.6", + "lodash.isstring": "^4.0.1", + "lodash.once": "^4.0.0", + "ms": "^2.1.1", + "semver": "^7.5.4" + }, + "engines": { + "node": ">=12", + "npm": ">=6" + } + }, + "node_modules/jwa": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/jwa/-/jwa-2.0.1.tgz", + "integrity": "sha512-hRF04fqJIP8Abbkq5NKGN0Bbr3JxlQ+qhZufXVr0DvujKy93ZCbXZMHDL4EOtodSbCWxOqR8MS1tXA5hwqCXDg==", + "dev": true, + "license": "MIT", + "dependencies": { + "buffer-equal-constant-time": "^1.0.1", + "ecdsa-sig-formatter": "1.0.11", + "safe-buffer": "^5.0.1" + } }, - "node_modules/json-schema-typed": { - "version": "8.0.2", - "resolved": "https://registry.npmjs.org/json-schema-typed/-/json-schema-typed-8.0.2.tgz", - "integrity": "sha512-fQhoXdcvc3V28x7C7BMs4P5+kNlgUURe2jmUT1T//oBRMDrqy1QPelJimwZGo7Hg9VPV3EQV5Bnq4hbFy2vetA==", - "license": "BSD-2-Clause" + "node_modules/jws": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/jws/-/jws-4.0.1.tgz", + "integrity": "sha512-EKI/M/yqPncGUUh44xz0PxSidXFr/+r0pA70+gIYhjv+et7yxM+s29Y+VGDkovRofQem0fs7Uvf4+YmAdyRduA==", + "dev": true, + "license": "MIT", + "dependencies": { + "jwa": "^2.0.1", + "safe-buffer": "^5.0.1" + } }, - "node_modules/json-stable-stringify-without-jsonify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", - "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", + "node_modules/keytar": { + "version": "7.9.0", + "resolved": "https://registry.npmjs.org/keytar/-/keytar-7.9.0.tgz", + "integrity": "sha512-VPD8mtVtm5JNtA2AErl6Chp06JBfy7diFQ7TQQhdpWOl6MrCRB+eRbvAZUsbGQS9kiMq0coJsy0W0vHpDCkWsQ==", "dev": true, - "license": "MIT" + "hasInstallScript": true, + "license": "MIT", + "optional": true, + "dependencies": { + "node-addon-api": "^4.3.0", + "prebuild-install": "^7.0.1" + } }, "node_modules/keyv": { "version": "4.5.4", @@ -3745,6 +5579,16 @@ "json-buffer": "3.0.1" } }, + "node_modules/leven": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz", + "integrity": "sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, "node_modules/levn": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", @@ -3759,6 +5603,16 @@ "node": ">= 0.8.0" } }, + "node_modules/linkify-it": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/linkify-it/-/linkify-it-5.0.0.tgz", + "integrity": "sha512-5aHCbzQRADcdP+ATqnDuhhJ/MRIqDkZX5pyjFHRRysS8vZ5AbqGEoFIb6pYHPZ+L/OC2Lc+xT8uHVVR5CAK/wQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "uc.micro": "^2.0.0" + } + }, "node_modules/locate-path": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", @@ -3775,6 +5629,55 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/lodash": { + "version": "4.17.23", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.23.tgz", + "integrity": "sha512-LgVTMpQtIopCi79SJeDiP0TfWi5CNEc/L/aRdTh3yIvmZXTnheWpKjSZhnvMl8iXbC1tFg9gdHHDMLoV7CnG+w==", + "dev": true, + "license": "MIT" + }, + "node_modules/lodash.includes": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/lodash.includes/-/lodash.includes-4.3.0.tgz", + "integrity": "sha512-W3Bx6mdkRTGtlJISOvVD/lbqjTlPPUDTMnlXZFnVwi9NKJ6tiAk6LVdlhZMm17VZisqhKcgzpO5Wz91PCt5b0w==", + "dev": true, + "license": "MIT" + }, + "node_modules/lodash.isboolean": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/lodash.isboolean/-/lodash.isboolean-3.0.3.tgz", + "integrity": "sha512-Bz5mupy2SVbPHURB98VAcw+aHh4vRV5IPNhILUCsOzRmsTmSQ17jIuqopAentWoehktxGd9e/hbIXq980/1QJg==", + "dev": true, + "license": "MIT" + }, + "node_modules/lodash.isinteger": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/lodash.isinteger/-/lodash.isinteger-4.0.4.tgz", + "integrity": "sha512-DBwtEWN2caHQ9/imiNeEA5ys1JoRtRfY3d7V9wkqtbycnAmTvRRmbHKDV4a0EYc678/dia0jrte4tjYwVBaZUA==", + "dev": true, + "license": "MIT" + }, + "node_modules/lodash.isnumber": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/lodash.isnumber/-/lodash.isnumber-3.0.3.tgz", + "integrity": "sha512-QYqzpfwO3/CWf3XP+Z+tkQsfaLL/EnUlXWVkIk5FUPc4sBdTehEqZONuyRt2P67PXAk+NXmTBcc97zw9t1FQrw==", + "dev": true, + "license": "MIT" + }, + "node_modules/lodash.isplainobject": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz", + "integrity": "sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA==", + "dev": true, + "license": "MIT" + }, + "node_modules/lodash.isstring": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/lodash.isstring/-/lodash.isstring-4.0.1.tgz", + "integrity": "sha512-0wJxfxH1wgO3GrbuP+dTTk7op+6L41QCXbGINEmD+ny/G/eCqGzxyCsh7159S+mgDDcoarnBw6PC1PS5+wUGgw==", + "dev": true, + "license": "MIT" + }, "node_modules/lodash.merge": { "version": "4.6.2", "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", @@ -3782,6 +5685,20 @@ "dev": true, "license": "MIT" }, + "node_modules/lodash.once": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/lodash.once/-/lodash.once-4.1.1.tgz", + "integrity": "sha512-Sb487aTOCr9drQVL8pIxOzVhafOjZN9UU54hiN8PU3uAiSV7lx1yYNpbNmex2PK6dSJoNTSJUUswT651yww3Mg==", + "dev": true, + "license": "MIT" + }, + "node_modules/lodash.truncate": { + "version": "4.4.2", + "resolved": "https://registry.npmjs.org/lodash.truncate/-/lodash.truncate-4.4.2.tgz", + "integrity": "sha512-jttmRe7bRse52OsWIMDLaXxWqRAmtIUccAQ3garviCqJjafXOfNMO0yMfNpdD6zbGaTU0P5Nz7e7gAT6cKmJRw==", + "dev": true, + "license": "MIT" + }, "node_modules/log-symbols": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz", @@ -3862,6 +5779,24 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/markdown-it": { + "version": "14.1.1", + "resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-14.1.1.tgz", + "integrity": "sha512-BuU2qnTti9YKgK5N+IeMubp14ZUKUUw7yeJbkjtosvHiP0AZ5c8IAgEMk79D0eC8F23r4Ac/q8cAIFdm2FtyoA==", + "dev": true, + "license": "MIT", + "dependencies": { + "argparse": "^2.0.1", + "entities": "^4.4.0", + "linkify-it": "^5.0.0", + "mdurl": "^2.0.0", + "punycode.js": "^2.3.1", + "uc.micro": "^2.1.0" + }, + "bin": { + "markdown-it": "bin/markdown-it.mjs" + } + }, "node_modules/math-intrinsics": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz", @@ -3871,6 +5806,13 @@ "node": ">= 0.4" } }, + "node_modules/mdurl": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/mdurl/-/mdurl-2.0.0.tgz", + "integrity": "sha512-Lf+9+2r+Tdp5wXDXC4PcIBjTDtq4UKjCPMQhKIuzpJNW0b96kVqSwW0bT7FhRSfmAiFYgP+SCRvdrDozfh0U5w==", + "dev": true, + "license": "MIT" + }, "node_modules/media-typer": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-1.1.0.tgz", @@ -3892,6 +5834,56 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/merge2": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 8" + } + }, + "node_modules/micromatch": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz", + "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==", + "dev": true, + "license": "MIT", + "dependencies": { + "braces": "^3.0.3", + "picomatch": "^2.3.1" + }, + "engines": { + "node": ">=8.6" + } + }, + "node_modules/micromatch/node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/mime": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", + "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", + "dev": true, + "license": "MIT", + "bin": { + "mime": "cli.js" + }, + "engines": { + "node": ">=4" + } + }, "node_modules/mime-db": { "version": "1.54.0", "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.54.0.tgz", @@ -3917,6 +5909,20 @@ "url": "https://opencollective.com/express" } }, + "node_modules/mimic-response": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-3.1.0.tgz", + "integrity": "sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==", + "dev": true, + "license": "MIT", + "optional": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/minimatch": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", @@ -3930,6 +5936,17 @@ "node": "*" } }, + "node_modules/minimist": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", + "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", + "dev": true, + "license": "MIT", + "optional": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/minipass": { "version": "7.1.2", "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz", @@ -3940,6 +5957,14 @@ "node": ">=16 || 14 >=14.17" } }, + "node_modules/mkdirp-classic": { + "version": "0.5.3", + "resolved": "https://registry.npmjs.org/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz", + "integrity": "sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==", + "dev": true, + "license": "MIT", + "optional": true + }, "node_modules/mocha": { "version": "11.7.5", "resolved": "https://registry.npmjs.org/mocha/-/mocha-11.7.5.tgz", @@ -4190,6 +6215,13 @@ "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", "license": "MIT" }, + "node_modules/mute-stream": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.8.tgz", + "integrity": "sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==", + "dev": true, + "license": "ISC" + }, "node_modules/nanoid": { "version": "3.3.11", "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.11.tgz", @@ -4209,6 +6241,14 @@ "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" } }, + "node_modules/napi-build-utils": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/napi-build-utils/-/napi-build-utils-2.0.0.tgz", + "integrity": "sha512-GEbrYkbfF7MoNaoh2iGG84Mnf/WZfB0GdGEsM8wz7Expx/LlWf5U8t9nvJKXSp3qr5IsEbK04cBGhol/KwOsWA==", + "dev": true, + "license": "MIT", + "optional": true + }, "node_modules/natural-compare": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", @@ -4225,6 +6265,90 @@ "node": ">= 0.6" } }, + "node_modules/node-abi": { + "version": "3.87.0", + "resolved": "https://registry.npmjs.org/node-abi/-/node-abi-3.87.0.tgz", + "integrity": "sha512-+CGM1L1CgmtheLcBuleyYOn7NWPVu0s0EJH2C4puxgEZb9h8QpR9G2dBfZJOAUhi7VQxuBPMd0hiISWcTyiYyQ==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "semver": "^7.3.5" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/node-addon-api": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-4.3.0.tgz", + "integrity": "sha512-73sE9+3UaLYYFmDsFZnqCInzPyh3MqIwZO9cw58yIqAZhONrrabrYyYe3TuIqtIiOuTXVhsGau8hcrhhwSsDIQ==", + "dev": true, + "license": "MIT", + "optional": true + }, + "node_modules/node-sarif-builder": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/node-sarif-builder/-/node-sarif-builder-3.4.0.tgz", + "integrity": "sha512-tGnJW6OKRii9u/b2WiUViTJS+h7Apxx17qsMUjsUeNDiMMX5ZFf8F8Fcz7PAQ6omvOxHZtvDTmOYKJQwmfpjeg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/sarif": "^2.1.7", + "fs-extra": "^11.1.1" + }, + "engines": { + "node": ">=20" + } + }, + "node_modules/normalize-package-data": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-6.0.2.tgz", + "integrity": "sha512-V6gygoYb/5EmNI+MEGrWkC+e6+Rr7mTmfHrxDbLzxQogBkgzo76rkok0Am6thgSF7Mv2nLOajAJj5vDJZEFn7g==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "hosted-git-info": "^7.0.0", + "semver": "^7.3.5", + "validate-npm-package-license": "^3.0.4" + }, + "engines": { + "node": "^16.14.0 || >=18.0.0" + } + }, + "node_modules/normalize-package-data/node_modules/hosted-git-info": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-7.0.2.tgz", + "integrity": "sha512-puUZAUKT5m8Zzvs72XWy3HtvVbTWljRE66cP60bxJzAqf2DgICo7lYTY2IHUmLnNpjYvw5bvmoHvPc0QO2a62w==", + "dev": true, + "license": "ISC", + "dependencies": { + "lru-cache": "^10.0.1" + }, + "engines": { + "node": "^16.14.0 || >=18.0.0" + } + }, + "node_modules/normalize-package-data/node_modules/lru-cache": { + "version": "10.4.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", + "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/nth-check": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.1.1.tgz", + "integrity": "sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "boolbase": "^1.0.0" + }, + "funding": { + "url": "https://github.com/fb55/nth-check?sponsor=1" + } + }, "node_modules/object-assign": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", @@ -4278,6 +6402,25 @@ "wrappy": "1" } }, + "node_modules/open": { + "version": "10.2.0", + "resolved": "https://registry.npmjs.org/open/-/open-10.2.0.tgz", + "integrity": "sha512-YgBpdJHPyQ2UE5x+hlSXcnejzAvD0b22U2OuAP+8OnlJT+PjWPxtgmGqKKc+RgTM63U9gN0YzrYc71R2WT/hTA==", + "dev": true, + "license": "MIT", + "dependencies": { + "default-browser": "^5.2.1", + "define-lazy-prop": "^3.0.0", + "is-inside-container": "^1.0.0", + "wsl-utils": "^0.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/optionator": { "version": "0.9.4", "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz", @@ -4328,6 +6471,19 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/p-map": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/p-map/-/p-map-7.0.4.tgz", + "integrity": "sha512-tkAQEw8ysMzmkhgw8k+1U/iPhWNhykKnSk4Rd5zLoPJCuJaGRPo6YposrZgaxHKzDHdDWWZvE/Sk7hsL2X/CpQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/package-json-from-dist": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/package-json-from-dist/-/package-json-from-dist-1.0.1.tgz", @@ -4342,10 +6498,101 @@ "dev": true, "license": "MIT", "dependencies": { - "callsites": "^3.0.0" + "callsites": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/parse-json": { + "version": "8.3.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-8.3.0.tgz", + "integrity": "sha512-ybiGyvspI+fAoRQbIPRddCcSTV9/LsJbf0e/S85VLowVGzRmokfneg2kwVW/KU5rOXrPSbF1qAKPMgNTqqROQQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.26.2", + "index-to-position": "^1.1.0", + "type-fest": "^4.39.1" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/parse-semver": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/parse-semver/-/parse-semver-1.1.1.tgz", + "integrity": "sha512-Eg1OuNntBMH0ojvEKSrvDSnwLmvVuUOSdylH/pSCPNMIspLlweJyIWXCE+k/5hm3cj/EBUYwmWkjhBALNP4LXQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "semver": "^5.1.0" + } + }, + "node_modules/parse-semver/node_modules/semver": { + "version": "5.7.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", + "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver" + } + }, + "node_modules/parse5": { + "version": "7.3.0", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-7.3.0.tgz", + "integrity": "sha512-IInvU7fabl34qmi9gY8XOVxhYyMyuH2xUNpb2q8/Y+7552KlejkRvqvD19nMoUW/uQGGbqNpA6Tufu5FL5BZgw==", + "dev": true, + "license": "MIT", + "dependencies": { + "entities": "^6.0.0" + }, + "funding": { + "url": "https://github.com/inikulin/parse5?sponsor=1" + } + }, + "node_modules/parse5-htmlparser2-tree-adapter": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/parse5-htmlparser2-tree-adapter/-/parse5-htmlparser2-tree-adapter-7.1.0.tgz", + "integrity": "sha512-ruw5xyKs6lrpo9x9rCZqZZnIUntICjQAd0Wsmp396Ul9lN/h+ifgVV1x1gZHi8euej6wTfpqX8j+BFQxF0NS/g==", + "dev": true, + "license": "MIT", + "dependencies": { + "domhandler": "^5.0.3", + "parse5": "^7.0.0" + }, + "funding": { + "url": "https://github.com/inikulin/parse5?sponsor=1" + } + }, + "node_modules/parse5-parser-stream": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/parse5-parser-stream/-/parse5-parser-stream-7.1.2.tgz", + "integrity": "sha512-JyeQc9iwFLn5TbvvqACIF/VXG6abODeB3Fwmv/TGdLk2LfbWkaySGY72at4+Ty7EkPZj854u4CrICqNk2qIbow==", + "dev": true, + "license": "MIT", + "dependencies": { + "parse5": "^7.0.0" }, + "funding": { + "url": "https://github.com/inikulin/parse5?sponsor=1" + } + }, + "node_modules/parse5/node_modules/entities": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/entities/-/entities-6.0.1.tgz", + "integrity": "sha512-aN97NXWF6AWBTahfVOIrB/NShkzi5H7F9r1s9mD3cDj4Ko5f2qhhVoYMibXF7GlLveb/D2ioWay8lxI97Ven3g==", + "dev": true, + "license": "BSD-2-Clause", "engines": { - "node": ">=6" + "node": ">=0.12" + }, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" } }, "node_modules/parseurl": { @@ -4403,6 +6650,19 @@ "url": "https://opencollective.com/express" } }, + "node_modules/path-type": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-6.0.0.tgz", + "integrity": "sha512-Vj7sf++t5pBD637NSfkxpHSMfWaeig5+DKWLhcqIYx6mWQz5hdJTGDVMQiJcw1ZYkhs7AazKDGpRVji1LJCZUQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/pathe": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/pathe/-/pathe-2.0.3.tgz", @@ -4410,6 +6670,13 @@ "dev": true, "license": "MIT" }, + "node_modules/pend": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz", + "integrity": "sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg==", + "dev": true, + "license": "MIT" + }, "node_modules/picocolors": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", @@ -4439,6 +6706,16 @@ "node": ">=16.20.0" } }, + "node_modules/pluralize": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/pluralize/-/pluralize-8.0.0.tgz", + "integrity": "sha512-Nc3IT5yHzflTfbjgqWcCPpo7DaKy4FnpB0l/zCAW0Tc7jxAiuqSxHasntB3D7887LSrA93kDJ9IXovxJYxyLCA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, "node_modules/postcss": { "version": "8.5.6", "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.6.tgz", @@ -4468,6 +6745,34 @@ "node": "^10 || ^12 || >=14" } }, + "node_modules/prebuild-install": { + "version": "7.1.3", + "resolved": "https://registry.npmjs.org/prebuild-install/-/prebuild-install-7.1.3.tgz", + "integrity": "sha512-8Mf2cbV7x1cXPUILADGI3wuhfqWvtiLA1iclTDbFRZkgRQS0NqsPZphna9V+HyTEadheuPmjaJMsbzKQFOzLug==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "detect-libc": "^2.0.0", + "expand-template": "^2.0.3", + "github-from-package": "0.0.0", + "minimist": "^1.2.3", + "mkdirp-classic": "^0.5.3", + "napi-build-utils": "^2.0.0", + "node-abi": "^3.3.0", + "pump": "^3.0.0", + "rc": "^1.2.7", + "simple-get": "^4.0.0", + "tar-fs": "^2.0.0", + "tunnel-agent": "^0.6.0" + }, + "bin": { + "prebuild-install": "bin.js" + }, + "engines": { + "node": ">=10" + } + }, "node_modules/prelude-ls": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", @@ -4484,6 +6789,7 @@ "integrity": "sha512-UOnG6LftzbdaHZcKoPFtOcCKztrQ57WkHDeRD9t/PTQtmT0NHSeWWepj6pS0z/N7+08BHFDQVUrfmfMRcZwbMg==", "dev": true, "license": "MIT", + "peer": true, "bin": { "prettier": "bin/prettier.cjs" }, @@ -4520,6 +6826,18 @@ "node": ">= 0.10" } }, + "node_modules/pump": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.3.tgz", + "integrity": "sha512-todwxLMY7/heScKmntwQG8CXVkWUOdYxIvY2s0VWAAMh/nd8SoYiRaKjlr7+iCs984f2P8zvrfWcDDYVb73NfA==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + }, "node_modules/punycode": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", @@ -4530,6 +6848,16 @@ "node": ">=6" } }, + "node_modules/punycode.js": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/punycode.js/-/punycode.js-2.3.1.tgz", + "integrity": "sha512-uxFIHU0YlHYhDQtV4R9J6a52SLx28BCjT+4ieh7IGbgwVJWO+km431c4yRlREUAsAmt/uMjQUyQHNEPf0M39CA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, "node_modules/qs": { "version": "6.14.1", "resolved": "https://registry.npmjs.org/qs/-/qs-6.14.1.tgz", @@ -4545,6 +6873,27 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/queue-microtask": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, "node_modules/randombytes": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", @@ -4579,6 +6928,109 @@ "node": ">= 0.10" } }, + "node_modules/rc": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", + "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==", + "dev": true, + "license": "(BSD-2-Clause OR MIT OR Apache-2.0)", + "optional": true, + "dependencies": { + "deep-extend": "^0.6.0", + "ini": "~1.3.0", + "minimist": "^1.2.0", + "strip-json-comments": "~2.0.1" + }, + "bin": { + "rc": "cli.js" + } + }, + "node_modules/rc-config-loader": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/rc-config-loader/-/rc-config-loader-4.1.3.tgz", + "integrity": "sha512-kD7FqML7l800i6pS6pvLyIE2ncbk9Du8Q0gp/4hMPhJU6ZxApkoLcGD8ZeqgiAlfwZ6BlETq6qqe+12DUL207w==", + "dev": true, + "license": "MIT", + "dependencies": { + "debug": "^4.3.4", + "js-yaml": "^4.1.0", + "json5": "^2.2.2", + "require-from-string": "^2.0.2" + } + }, + "node_modules/rc/node_modules/strip-json-comments": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", + "integrity": "sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==", + "dev": true, + "license": "MIT", + "optional": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/read": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/read/-/read-1.0.7.tgz", + "integrity": "sha512-rSOKNYUmaxy0om1BNjMN4ezNT6VKK+2xF4GBhc81mkH7L60i6dp8qPYrkndNLT3QPphoII3maL9PVC9XmhHwVQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "mute-stream": "~0.0.4" + }, + "engines": { + "node": ">=0.8" + } + }, + "node_modules/read-pkg": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-9.0.1.tgz", + "integrity": "sha512-9viLL4/n1BJUCT1NXVTdS1jtm80yDEgR5T4yCelII49Mbj0v1rZdKqj7zCiYdbB0CuCgdrvHcNogAKTFPBocFA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/normalize-package-data": "^2.4.3", + "normalize-package-data": "^6.0.0", + "parse-json": "^8.0.0", + "type-fest": "^4.6.0", + "unicorn-magic": "^0.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/read-pkg/node_modules/unicorn-magic": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/unicorn-magic/-/unicorn-magic-0.1.0.tgz", + "integrity": "sha512-lRfVq8fE8gz6QMBuDM6a+LO3IAzTi05H6gCVaUpir2E1Rwpo4ZUog45KpNXKC/Mn3Yb9UDuHumeFTo9iV/D9FQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/readable-stream": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", + "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, "node_modules/readdirp": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-4.1.2.tgz", @@ -4622,6 +7074,17 @@ "node": ">=4" } }, + "node_modules/reusify": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.1.0.tgz", + "integrity": "sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==", + "dev": true, + "license": "MIT", + "engines": { + "iojs": ">=1.0.0", + "node": ">=0.10.0" + } + }, "node_modules/rollup": { "version": "4.57.1", "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.57.1.tgz", @@ -4683,6 +7146,43 @@ "node": ">= 18" } }, + "node_modules/run-applescript": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/run-applescript/-/run-applescript-7.1.0.tgz", + "integrity": "sha512-DPe5pVFaAsinSaV6QjQ6gdiedWDcRCbUuiQfQa2wmWV7+xC9bGulGI8+TdRmoFkAPaBXk8CrAbnlY2ISniJ47Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/run-parallel": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", + "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT", + "dependencies": { + "queue-microtask": "^1.2.2" + } + }, "node_modules/safe-buffer": { "version": "5.2.1", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", @@ -4710,6 +7210,38 @@ "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", "license": "MIT" }, + "node_modules/sax": { + "version": "1.4.4", + "resolved": "https://registry.npmjs.org/sax/-/sax-1.4.4.tgz", + "integrity": "sha512-1n3r/tGXO6b6VXMdFT54SHzT9ytu9yr7TaELowdYpMqY/Ao7EnlQGmAQ1+RatX7Tkkdm6hONI2owqNx2aZj5Sw==", + "dev": true, + "license": "BlueOak-1.0.0", + "engines": { + "node": ">=11.0.0" + } + }, + "node_modules/secretlint": { + "version": "10.2.2", + "resolved": "https://registry.npmjs.org/secretlint/-/secretlint-10.2.2.tgz", + "integrity": "sha512-xVpkeHV/aoWe4vP4TansF622nBEImzCY73y/0042DuJ29iKIaqgoJ8fGxre3rVSHHbxar4FdJobmTnLp9AU0eg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@secretlint/config-creator": "^10.2.2", + "@secretlint/formatter": "^10.2.2", + "@secretlint/node": "^10.2.2", + "@secretlint/profiler": "^10.2.2", + "debug": "^4.4.1", + "globby": "^14.1.0", + "read-pkg": "^9.0.1" + }, + "bin": { + "secretlint": "bin/secretlint.js" + }, + "engines": { + "node": ">=20.0.0" + } + }, "node_modules/semver": { "version": "7.7.4", "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.4.tgz", @@ -4897,6 +7429,86 @@ "url": "https://github.com/sponsors/isaacs" } }, + "node_modules/simple-concat": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/simple-concat/-/simple-concat-1.0.1.tgz", + "integrity": "sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT", + "optional": true + }, + "node_modules/simple-get": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/simple-get/-/simple-get-4.0.1.tgz", + "integrity": "sha512-brv7p5WgH0jmQJr1ZDDfKDOSeWWg+OVypG99A/5vYGPqJ6pxiaHLy8nxtFjBA7oMa01ebA9gfh1uMCFqOuXxvA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT", + "optional": true, + "dependencies": { + "decompress-response": "^6.0.0", + "once": "^1.3.1", + "simple-concat": "^1.0.0" + } + }, + "node_modules/slash": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-5.1.0.tgz", + "integrity": "sha512-ZA6oR3T/pEyuqwMgAKT0/hAv8oAXckzbkmR0UkUosQ+Mc4RxGoJkRmwHgHufaenlyAgE1Mxgpdcrf75y6XcnDg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/slice-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-4.0.0.tgz", + "integrity": "sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.0.0", + "astral-regex": "^2.0.0", + "is-fullwidth-code-point": "^3.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/slice-ansi?sponsor=1" + } + }, "node_modules/source-map-js": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", @@ -4907,6 +7519,42 @@ "node": ">=0.10.0" } }, + "node_modules/spdx-correct": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.2.0.tgz", + "integrity": "sha512-kN9dJbvnySHULIluDHy32WHRUu3Og7B9sbY7tsFLctQkIqnMh3hErYgdMjTYuqmcXX+lK5T1lnUt3G7zNswmZA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "spdx-expression-parse": "^3.0.0", + "spdx-license-ids": "^3.0.0" + } + }, + "node_modules/spdx-exceptions": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.5.0.tgz", + "integrity": "sha512-PiU42r+xO4UbUS1buo3LPJkjlO7430Xn5SVAhdpzzsPHsjbYVflnnFdATgabnLude+Cqu25p6N+g2lw/PFsa4w==", + "dev": true, + "license": "CC-BY-3.0" + }, + "node_modules/spdx-expression-parse": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz", + "integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "spdx-exceptions": "^2.1.0", + "spdx-license-ids": "^3.0.0" + } + }, + "node_modules/spdx-license-ids": { + "version": "3.0.22", + "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.22.tgz", + "integrity": "sha512-4PRT4nh1EImPbt2jASOKHX7PB7I+e4IWNLvkKFDxNhJlfjbYlleYQh285Z/3mPTHSAK/AvdMmw5BNNuYH8ShgQ==", + "dev": true, + "license": "CC0-1.0" + }, "node_modules/stackback": { "version": "0.0.2", "resolved": "https://registry.npmjs.org/stackback/-/stackback-0.0.2.tgz", @@ -4942,6 +7590,17 @@ "url": "https://github.com/sponsors/typicode" } }, + "node_modules/string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "safe-buffer": "~5.2.0" + } + }, "node_modules/string-width": { "version": "4.2.3", "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", @@ -5013,6 +7672,16 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/structured-source": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/structured-source/-/structured-source-4.0.0.tgz", + "integrity": "sha512-qGzRFNJDjFieQkl/sVOI2dUjHKRyL9dAJi2gCPGJLbJHBIkyOHxjuocpIEfbLioX+qSJpvbYdT49/YCdMznKxA==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "boundary": "^2.0.0" + } + }, "node_modules/supports-color": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", @@ -5026,6 +7695,23 @@ "node": ">=8" } }, + "node_modules/supports-hyperlinks": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/supports-hyperlinks/-/supports-hyperlinks-3.2.0.tgz", + "integrity": "sha512-zFObLMyZeEwzAoKCyu1B91U79K2t7ApXuQfo8OuxwXLDgcKxuwM+YvcbIhm6QWqz7mHUH1TVytR1PwVVjEuMig==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0", + "supports-color": "^7.0.0" + }, + "engines": { + "node": ">=14.18" + }, + "funding": { + "url": "https://github.com/chalk/supports-hyperlinks?sponsor=1" + } + }, "node_modules/synckit": { "version": "0.11.12", "resolved": "https://registry.npmjs.org/synckit/-/synckit-0.11.12.tgz", @@ -5042,6 +7728,119 @@ "url": "https://opencollective.com/synckit" } }, + "node_modules/table": { + "version": "6.9.0", + "resolved": "https://registry.npmjs.org/table/-/table-6.9.0.tgz", + "integrity": "sha512-9kY+CygyYM6j02t5YFHbNz2FN5QmYGv9zAjVp4lCDjlCw7amdckXlEt/bjMhUIfj4ThGRE4gCUH5+yGnNuPo5A==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "ajv": "^8.0.1", + "lodash.truncate": "^4.4.2", + "slice-ansi": "^4.0.0", + "string-width": "^4.2.3", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/table/node_modules/ajv": { + "version": "8.18.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.18.0.tgz", + "integrity": "sha512-PlXPeEWMXMZ7sPYOHqmDyCJzcfNrUr3fGNKtezX14ykXOEIvyK81d+qydx89KY5O71FKMPaQ2vBfBFI5NHR63A==", + "dev": true, + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.3", + "fast-uri": "^3.0.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/table/node_modules/json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", + "dev": true, + "license": "MIT" + }, + "node_modules/tar-fs": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-2.1.4.tgz", + "integrity": "sha512-mDAjwmZdh7LTT6pNleZ05Yt65HC3E+NiQzl672vQG38jIrehtJk/J3mNwIg+vShQPcLF/LV7CMnDW6vjj6sfYQ==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "chownr": "^1.1.1", + "mkdirp-classic": "^0.5.2", + "pump": "^3.0.0", + "tar-stream": "^2.1.4" + } + }, + "node_modules/tar-stream": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.2.0.tgz", + "integrity": "sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "bl": "^4.0.3", + "end-of-stream": "^1.4.1", + "fs-constants": "^1.0.0", + "inherits": "^2.0.3", + "readable-stream": "^3.1.1" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/terminal-link": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/terminal-link/-/terminal-link-4.0.0.tgz", + "integrity": "sha512-lk+vH+MccxNqgVqSnkMVKx4VLJfnLjDBGzH16JVZjKE2DoxP57s6/vt6JmXV5I3jBcfGrxNrYtC+mPtU7WJztA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-escapes": "^7.0.0", + "supports-hyperlinks": "^3.2.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/text-table": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", + "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", + "dev": true, + "license": "MIT" + }, + "node_modules/textextensions": { + "version": "6.11.0", + "resolved": "https://registry.npmjs.org/textextensions/-/textextensions-6.11.0.tgz", + "integrity": "sha512-tXJwSr9355kFJI3lbCkPpUH5cP8/M0GGy2xLO34aZCjMXBaK3SoPnZwr/oWmo1FdCnELcs4npdCIOFtq9W3ruQ==", + "dev": true, + "license": "Artistic-2.0", + "dependencies": { + "editions": "^6.21.0" + }, + "engines": { + "node": ">=4" + }, + "funding": { + "url": "https://bevry.me/fund" + } + }, "node_modules/tinybench": { "version": "2.9.0", "resolved": "https://registry.npmjs.org/tinybench/-/tinybench-2.9.0.tgz", @@ -5086,6 +7885,29 @@ "node": ">=14.0.0" } }, + "node_modules/tmp": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.5.tgz", + "integrity": "sha512-voyz6MApa1rQGUxT3E+BK7/ROe8itEx7vD8/HEvt4xwXucvQ5G5oeEiHkmHZJuBO21RpOf+YYm9MOivj709jow==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14.14" + } + }, + "node_modules/to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } + }, "node_modules/toidentifier": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", @@ -5108,6 +7930,37 @@ "typescript": ">=4.8.4" } }, + "node_modules/tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", + "dev": true, + "license": "0BSD" + }, + "node_modules/tunnel": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/tunnel/-/tunnel-0.0.6.tgz", + "integrity": "sha512-1h/Lnq9yajKY2PEbBadPXj3VxsDDu844OnaAo52UVmIzIvwwtBPIuNvkjuzBlTWpfJyUbG3ez0KSBibQkj4ojg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.6.11 <=0.7.0 || >=0.7.3" + } + }, + "node_modules/tunnel-agent": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", + "integrity": "sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==", + "dev": true, + "license": "Apache-2.0", + "optional": true, + "dependencies": { + "safe-buffer": "^5.0.1" + }, + "engines": { + "node": "*" + } + }, "node_modules/type-check": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", @@ -5121,6 +7974,19 @@ "node": ">= 0.8.0" } }, + "node_modules/type-fest": { + "version": "4.41.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-4.41.0.tgz", + "integrity": "sha512-TeTSQ6H5YHvpqVwBRcnLDCBnDOHWYu7IvGbHT6N8AOymcr9PJGjc1GTtiWZTYg0NCgYwvnYWEkVChQAr9bjfwA==", + "dev": true, + "license": "(MIT OR CC0-1.0)", + "engines": { + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/type-is": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/type-is/-/type-is-2.0.1.tgz", @@ -5135,12 +8001,25 @@ "node": ">= 0.6" } }, + "node_modules/typed-rest-client": { + "version": "1.8.11", + "resolved": "https://registry.npmjs.org/typed-rest-client/-/typed-rest-client-1.8.11.tgz", + "integrity": "sha512-5UvfMpd1oelmUPRbbaVnq+rHP7ng2cE4qoQkQeAqxRL6PklkxsM0g32/HL0yfvruK6ojQ5x8EE+HF4YV6DtuCA==", + "dev": true, + "license": "MIT", + "dependencies": { + "qs": "^6.9.1", + "tunnel": "0.0.6", + "underscore": "^1.12.1" + } + }, "node_modules/typescript": { "version": "5.9.3", "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.3.tgz", "integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==", "dev": true, "license": "Apache-2.0", + "peer": true, "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" @@ -5173,6 +8052,30 @@ "typescript": ">=4.8.4 <6.0.0" } }, + "node_modules/uc.micro": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/uc.micro/-/uc.micro-2.1.0.tgz", + "integrity": "sha512-ARDJmphmdvUk6Glw7y9DQ2bFkKBHwQHLi2lsaH6PPmz/Ka9sFOBsBluozhDltWmnv9u/cF6Rt87znRTPV+yp/A==", + "dev": true, + "license": "MIT" + }, + "node_modules/underscore": { + "version": "1.13.7", + "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.13.7.tgz", + "integrity": "sha512-GMXzWtsc57XAtguZgaQViUOzs0KTkk8ojr3/xAxXLITqf/3EMwxC0inyETfDFjH/Krbhuep0HNbbjI9i/q3F3g==", + "dev": true, + "license": "MIT" + }, + "node_modules/undici": { + "version": "7.22.0", + "resolved": "https://registry.npmjs.org/undici/-/undici-7.22.0.tgz", + "integrity": "sha512-RqslV2Us5BrllB+JeiZnK4peryVTndy9Dnqq62S3yYRRTj0tFQCwEniUy2167skdGOy3vqRzEvl1Dm4sV2ReDg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=20.18.1" + } + }, "node_modules/undici-types": { "version": "7.16.0", "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.16.0.tgz", @@ -5180,6 +8083,29 @@ "dev": true, "license": "MIT" }, + "node_modules/unicorn-magic": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/unicorn-magic/-/unicorn-magic-0.3.0.tgz", + "integrity": "sha512-+QBBXBCvifc56fsbuxZQ6Sic3wqqc3WWaqxs58gvJrcOuN83HGTCwz3oS5phzU9LthRNE9VrJCFCLUgHeeFnfA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/universalify": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz", + "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 10.0.0" + } + }, "node_modules/unpipe": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", @@ -5199,6 +8125,42 @@ "punycode": "^2.1.0" } }, + "node_modules/url-join": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/url-join/-/url-join-4.0.1.tgz", + "integrity": "sha512-jk1+QP6ZJqyOiuEI9AEWQfju/nB2Pw466kbA0LEZljHwKeMgd9WrAEgEGxjPDD2+TNbbb37rTyhEfrCXfuKXnA==", + "dev": true, + "license": "MIT" + }, + "node_modules/util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", + "dev": true, + "license": "MIT", + "optional": true + }, + "node_modules/uuid": { + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", + "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", + "dev": true, + "license": "MIT", + "bin": { + "uuid": "dist/bin/uuid" + } + }, + "node_modules/validate-npm-package-license": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", + "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "spdx-correct": "^3.0.0", + "spdx-expression-parse": "^3.0.0" + } + }, "node_modules/vary": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", @@ -5208,12 +8170,26 @@ "node": ">= 0.8" } }, + "node_modules/version-range": { + "version": "4.15.0", + "resolved": "https://registry.npmjs.org/version-range/-/version-range-4.15.0.tgz", + "integrity": "sha512-Ck0EJbAGxHwprkzFO966t4/5QkRuzh+/I1RxhLgUKKwEn+Cd8NwM60mE3AqBZg5gYODoXW0EFsQvbZjRlvdqbg==", + "dev": true, + "license": "Artistic-2.0", + "engines": { + "node": ">=4" + }, + "funding": { + "url": "https://bevry.me/fund" + } + }, "node_modules/vite": { "version": "7.3.1", "resolved": "https://registry.npmjs.org/vite/-/vite-7.3.1.tgz", "integrity": "sha512-w+N7Hifpc3gRjZ63vYBXA56dvvRlNWRczTdmCBBa+CotUzAPf5b7YMdMR/8CQoeYE5LX3W4wj6RYTgonm1b9DA==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "esbuild": "^0.27.0", "fdir": "^6.5.0", @@ -5289,6 +8265,7 @@ "integrity": "sha512-hOQuK7h0FGKgBAas7v0mSAsnvrIgAvWmRFjmzpJ7SwFHH3g1k2u37JtYwOwmEKhK6ZO3v9ggDBBm0La1LCK4uQ==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "@vitest/expect": "4.0.18", "@vitest/mocker": "4.0.18", @@ -5361,6 +8338,47 @@ } } }, + "node_modules/vscode-codeql-development-mcp-server": { + "resolved": "extensions/vscode", + "link": true + }, + "node_modules/whatwg-encoding": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-3.1.1.tgz", + "integrity": "sha512-6qN4hJdMwfYBtE3YBTTHhoeuUrDBPZmbQaxWAqSALV/MeEnR5z1xd8UKud2RAkFoPkmB+hli1TZSnyi84xz1vQ==", + "deprecated": "Use @exodus/bytes instead for a more spec-conformant and faster implementation", + "dev": true, + "license": "MIT", + "dependencies": { + "iconv-lite": "0.6.3" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/whatwg-encoding/node_modules/iconv-lite": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", + "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", + "dev": true, + "license": "MIT", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/whatwg-mimetype": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-4.0.0.tgz", + "integrity": "sha512-QaKxh0eNIi2mE9p2vEdzfagOKHCcj1pJ56EEHGQOVxp8r9/iszLUUV7v89x9O1p/T+NlTM5W7jW6+cz4Fq1YVg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + } + }, "node_modules/which": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", @@ -5453,6 +8471,46 @@ "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", "license": "ISC" }, + "node_modules/wsl-utils": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/wsl-utils/-/wsl-utils-0.1.0.tgz", + "integrity": "sha512-h3Fbisa2nKGPxCpm89Hk33lBLsnaGBvctQopaBSOW/uIs6FTe1ATyAnKFJrzVs9vpGdsTe73WF3V4lIsk4Gacw==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-wsl": "^3.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/xml2js": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.5.0.tgz", + "integrity": "sha512-drPFnkQJik/O+uPKpqSgr22mpuFHqKdbS835iAQrUC73L2F5WkboIRd63ai/2Yg6I1jzifPFKH2NTK+cfglkIA==", + "dev": true, + "license": "MIT", + "dependencies": { + "sax": ">=0.6.0", + "xmlbuilder": "~11.0.0" + }, + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/xmlbuilder": { + "version": "11.0.1", + "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-11.0.1.tgz", + "integrity": "sha512-fDlsI/kFEx7gLvbecc0/ohLG50fugQp8ryHzMTuW9vSa1GJ0XYWKnhsUx7oie3G98+r56aTQIUB4kht42R3JvA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4.0" + } + }, "node_modules/y18n": { "version": "5.0.8", "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", @@ -5463,6 +8521,13 @@ "node": ">=10" } }, + "node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true, + "license": "ISC" + }, "node_modules/yargs": { "version": "17.7.2", "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", @@ -5508,6 +8573,27 @@ "node": ">=10" } }, + "node_modules/yauzl": { + "version": "2.10.0", + "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.10.0.tgz", + "integrity": "sha512-p4a9I6X6nu6IhoGmBqAcbJy1mlC4j27vEPZX9F4L4/vZT3Lyq1VkFHw/V/PUcB9Buo+DG3iHkT0x3Qya58zc3g==", + "dev": true, + "license": "MIT", + "dependencies": { + "buffer-crc32": "~0.2.3", + "fd-slicer": "~1.1.0" + } + }, + "node_modules/yazl": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/yazl/-/yazl-2.5.1.tgz", + "integrity": "sha512-phENi2PLiHnHb6QBVot+dJnaAZ0xosj7p3fWl+znIjBDlnMI2PsZCJZ306BPTFOaHf5qdDEI8x5qFrSOBN5vrw==", + "dev": true, + "license": "MIT", + "dependencies": { + "buffer-crc32": "~0.2.3" + } + }, "node_modules/yocto-queue": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", @@ -5526,6 +8612,7 @@ "resolved": "https://registry.npmjs.org/zod/-/zod-3.25.76.tgz", "integrity": "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==", "license": "MIT", + "peer": true, "funding": { "url": "https://github.com/sponsors/colinhacks" } From e544b3db827fe8ff3ca5d24c8bdc703d14a70f6a Mon Sep 17 00:00:00 2001 From: Nathan Randall Date: Wed, 18 Feb 2026 20:54:52 -0700 Subject: [PATCH 08/14] Add extensions/vscode/LICENSE --- extensions/vscode/LICENSE | 178 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 178 insertions(+) create mode 100644 extensions/vscode/LICENSE diff --git a/extensions/vscode/LICENSE b/extensions/vscode/LICENSE new file mode 100644 index 00000000..457fc86f --- /dev/null +++ b/extensions/vscode/LICENSE @@ -0,0 +1,178 @@ +# GitHub CodeQL Terms and Conditions + +These GitHub CodeQL Terms and Conditions ("**Terms**") are a legal +agreement between you (either as an individual or on behalf of an +entity) and GitHub, Inc. regarding your use of the GitHub CodeQL +software and associated documentation (collectively, the +"**Software**"). By using the Software, you accept these Terms. +**Please read all of these Terms;** in many cases, provisions set +forth later in the Terms limit and qualify provisions set forth +earlier in the Terms. If you do not accept these Terms, do not +download, install, use, or copy the Software. + +## Definitions + +In these Terms: + +- "OSI-approved License" means an Open Source Initiative + (OSI)-approved open source software license. + +- "Open Source Codebase" means a codebase that is released under an + OSI-approved License. + +## Use Rights; Scope of License + +The Software is licensed on a per user basis. Here's what you may do +with the Software, but subject to License Restrictions provisions +below: + +- Use the Software to perform academic research. + +- Use the Software to demonstrate the Software. + +- Test CodeQL queries that are released under an OSI-approved + License to confirm that new versions of those queries continue to + find the right vulnerabilities. + +Here's what you may also do with the Software, but only with an Open +Source Codebase and subject to the License Restrictions provisions +below: + +- Perform analysis on the Open Source Codebase. + +- If the Open Source Codebase is hosted and maintained on + GitHub.com, generate CodeQL databases for or during automated + analysis, CI, or CD. + +## License Restrictions + +These Terms do not authorize, and the Software may not be used for any +purpose not expressly set forth above, including: + +- To otherwise or in any other context generate any CodeQL database + for or during automated analysis, CI or CD, whether as part of + normal engineering processes or another context. + +- To otherwise or in any other context use the Software in + connection with any codebase that is not an Open Source Codebase + (e.g., code in a private repo in GitHub). + +_**Please note:** if your use of the Software is under a paid customer +license for GitHub Advanced Security, the restrictions with respect to +automated analysis, CI, and CD and use in connection with non-Open +Source Codebases do not apply._ + +At all times, except (and only to the extent) permitted by applicable +law or applicable third-party license, you will not (and have no right +to): + +- work around any technical limitations in the Software that only + allow you to use it in certain ways; + +- reverse engineer, decompile or disassemble the Software; + +- remove, minimize, block, or modify any notices of GitHub or its + suppliers in the Software; + +- use the Software in any way that is against the law; or + +- share, publish, distribute or lend the Software, provide or make + available the Software as a hosted solution (whether on a + standalone basis or combined, incorporated or integrated with + other software or services) for others to use, or transfer the + Software or these Terms to any third party. + +The Software is licensed, not sold. GitHub reserves all rights not +expressly granted in these Terms. + +## Open Source Software + +The Software may include components licensed under open source +software licenses. Any such licenses are included in the "Open Source +Notices" documentation that is included with the Software. Such +documentation also includes copies of all applicable open source +licenses. + +To the extent the terms of the licenses applicable to open source +components require GitHub to make an offer to provide source code in +connection with the Software, such offer is hereby made, and you may +exercise it by contacting GitHub: https://github.com/contact. + +Unless otherwise agreed to in writing with GitHub, your agreement with +GitHub will always include, at a minimum, these Terms. Open source +software licenses for the Software's source code constitute separate +written agreements. To the limited extent that any open source +software license expressly supersedes these Terms, such open source +license governs your use of the applicable component(s) of the +Software subject to such license. + +## GitHub Trademarks + +These Terms do not grant any right or license to use any of GitHub's +trademarks or logos, including, without limitation, the names GitHub +and CodeQL and any Software logo designs in the "logos" folder of the +Software. You agree not to display or use any of these trademarks or +logos in any manner without GitHub's prior written permission, except +as allowed by GitHub's Logos and Usage Policy located at +https://github.com/logos. GitHub reserves all right, title and +interest in and to all GitHub trademarks and logos. + +## Additional Services + +Auto-Updates: The Software may include an auto-update service. If the +Software automatically enables such service (or, if it is not +automatically enabled and you choose to use it), GitHub will +automatically update the Software when a new version is available. + +## Support + +Because the Software is "as-is," GitHub may not provide support for it. + +## Export Control + +Customer will comply with all applicable export and import laws and +regulations that apply to the Software. + +## Disclaimer; Limitations of Liability + +THE SOFTWARE, INCLUDING ANY ADDITIONAL SERVICES, IS PROVIDED ON AN +"AS-IS" BASIS, AND GITHUB GIVES NO EXPRESS WARRANTIES, GUARANTEES OR +CONDITIONS. TO THE EXTENT PERMITTED BY APPLICABLE LAW, GITHUB +DISCLAIMS THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +PARTICULAR PURPOSE AND NON-INFRINGEMENT. YOUR USE OF THE SOFTWARE IS +AT YOUR SOLE RISK. + +TO THE EXTENT PERMITTED BY APPLICABLE LAW, YOU EXPRESSLY UNDERSTAND +AND AGREE THAT (1) YOU CAN RECOVER DIRECT DAMAGES RELATING TO THE +SOFTWARE, INCLUDING ANY ADDITIONAL SERVICES, UP TO U.S. $5.00 FROM +GITHUB AND ITS SUPPLIERS, AND (2) GITHUB WILL NOT BE LIABLE FOR ANY +INDIRECT, INCIDENTAL, SPECIAL, CONSEQUENTIAL OR EXEMPLARY DAMAGES, +INCLUDING, WITHOUT LIMITATION, ANY DAMAGES FOR LOSS OF PROFITS, +GOODWILL, USE, OR DATA OR OTHER INTANGIBLE LOSSES (EVEN IF GITHUB HAS +BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES) RELATING TO THE +SOFTWARE, INCLUDING ANY ADDITIONAL SERVICES. + +## Miscellaneous + +_No Waiver._ The failure of GitHub to exercise or enforce any right or +provision of these Terms will not constitute a waiver of such right or +provision. + +_Entire Agreement._ These Terms, together with any open source +software licenses referenced above, constitute the entire agreement +between you and GitHub regarding your use of the Software, superseding +any prior agreements between you and GitHub (including, but not +limited to, any prior versions of these Terms) regarding such use. + +_Governing Law._ You agree that these Terms and your use of the +Software are governed by the laws of the State of California and any +dispute relating to the Software or your use thereof must be brought +in a tribunal of competent jurisdiction located in or near San +Francisco, California. + +_Modifications._ These Terms may only be modified by a written +amendment signed by an authorized representative of GitHub, or by the +posting by GitHub of a revised version. + +_Contact Us._ Questions about these Terms? Contact us at +https://support.github.com/contact. From fdd6722c376215f25a6006cf3c835dc3c4f52be0 Mon Sep 17 00:00:00 2001 From: Nathan Randall Date: Wed, 18 Feb 2026 21:10:51 -0700 Subject: [PATCH 09/14] Address PR review comments & fix vsix archive --- .github/workflows/build-extension.yml | 4 ++-- .github/workflows/release-vsix.yml | 4 ++-- extensions/vscode/.vscodeignore | 11 +++++++++-- extensions/vscode/package.json | 5 ++--- extensions/vscode/scripts/bundle-server.js | 9 ++++++--- extensions/vscode/tsconfig.json | 3 +-- tsconfig.json | 3 --- 7 files changed, 22 insertions(+), 17 deletions(-) diff --git a/.github/workflows/build-extension.yml b/.github/workflows/build-extension.yml index 829def24..cd5bbf17 100644 --- a/.github/workflows/build-extension.yml +++ b/.github/workflows/build-extension.yml @@ -57,14 +57,14 @@ jobs: - name: Build Extension - Verify VSIX packaging working-directory: extensions/vscode - run: npx @vscode/vsce package --out codeql-development-mcp-server.vsix + run: npx @vscode/vsce package --no-dependencies --out codeql-development-mcp-server.vsix - name: Build Extension - Verify VSIX contents working-directory: extensions/vscode run: | echo "## VSIX Contents" >> $GITHUB_STEP_SUMMARY echo '```' >> $GITHUB_STEP_SUMMARY - npx @vscode/vsce ls 2>&1 | head -50 >> $GITHUB_STEP_SUMMARY + npx @vscode/vsce ls --no-dependencies --tree 2>&1 | head -50 >> $GITHUB_STEP_SUMMARY echo '```' >> $GITHUB_STEP_SUMMARY - name: Build Extension - Check for uncommitted changes diff --git a/.github/workflows/release-vsix.yml b/.github/workflows/release-vsix.yml index 76a67d86..15950a06 100644 --- a/.github/workflows/release-vsix.yml +++ b/.github/workflows/release-vsix.yml @@ -86,7 +86,7 @@ jobs: working-directory: extensions/vscode run: | VSIX_NAME="codeql-development-mcp-server.vsix" - npx @vscode/vsce package --out "${VSIX_NAME}" + npx @vscode/vsce package --no-dependencies --out "${VSIX_NAME}" echo "vsix_name=${VSIX_NAME}" >> $GITHUB_OUTPUT echo "✅ Packaged ${VSIX_NAME}" @@ -94,7 +94,7 @@ jobs: working-directory: extensions/vscode run: | echo "Verifying bundled server and tool query packs..." - npx @vscode/vsce ls 2>&1 | tee /tmp/vsix-contents.txt + npx @vscode/vsce ls --no-dependencies 2>&1 | tee /tmp/vsix-contents.txt # Verify critical files are included for required in \ diff --git a/extensions/vscode/.vscodeignore b/extensions/vscode/.vscodeignore index 7d6d899e..cc742dc5 100644 --- a/extensions/vscode/.vscodeignore +++ b/extensions/vscode/.vscodeignore @@ -1,19 +1,26 @@ +# Source and config (not needed at runtime) .vscode/** .vscode-test/** src/** test/** scripts/** +__mocks__/** node_modules/** tsconfig.json test/tsconfig.json vitest.config.ts eslint.config.mjs esbuild.config.js +.gitignore +coverage/** + +# Build artifacts that shouldn't be in the VSIX **/*.test.ts **/*.test.js +**/*.test.cjs **/*.map -coverage/** +dist/test/** -# Include server/ bundle but exclude test/examples content +# Bundled server: exclude test/examples content server/ql/*/tools/test/** server/ql/*/examples/** diff --git a/extensions/vscode/package.json b/extensions/vscode/package.json index f3f3227b..9d5a53b1 100644 --- a/extensions/vscode/package.json +++ b/extensions/vscode/package.json @@ -7,8 +7,7 @@ "license": "SEE LICENSE IN LICENSE", "repository": { "type": "git", - "url": "git+https://github.com/advanced-security/codeql-development-mcp-server.git", - "directory": "extensions/vscode" + "url": "git+https://github.com/advanced-security/codeql-development-mcp-server.git" }, "type": "module", "homepage": "https://github.com/advanced-security/codeql-development-mcp-server#readme", @@ -132,7 +131,7 @@ "clean": "rm -rf dist server *.vsix", "lint": "eslint src/ test/", "lint:fix": "eslint src/ test/ --fix", - "package": "vsce package --out codeql-development-mcp-server.vsix", + "package": "vsce package --no-dependencies --out codeql-development-mcp-server.vsix", "test": "vitest --run", "test:coverage": "vitest --run --coverage", "test:watch": "vitest --watch", diff --git a/extensions/vscode/scripts/bundle-server.js b/extensions/vscode/scripts/bundle-server.js index b3f95dc7..7665ea95 100644 --- a/extensions/vscode/scripts/bundle-server.js +++ b/extensions/vscode/scripts/bundle-server.js @@ -35,7 +35,7 @@ if (existsSync(targetServerDir)) { rmSync(targetServerDir, { recursive: true, force: true }); } -// --- Server dist --- +// --- Server dist (JS only, no source maps) --- const serverDist = join(serverRoot, 'dist'); const targetDist = join(targetServerDir, 'dist'); if (!existsSync(serverDist)) { @@ -43,8 +43,11 @@ if (!existsSync(serverDist)) { process.exit(1); } mkdirSync(targetDist, { recursive: true }); -cpSync(serverDist, targetDist, { recursive: true }); -console.log('✅ Copied server/dist/'); +// Copy only the JS bundle, not the source map (which contains ../../ paths +// that cause vsce to traverse the entire monorepo) +const serverJs = join(serverDist, 'codeql-development-mcp-server.js'); +cpSync(serverJs, join(targetDist, 'codeql-development-mcp-server.js')); +console.log('✅ Copied server/dist/codeql-development-mcp-server.js'); // --- Server package.json --- const serverPkg = join(serverRoot, 'package.json'); diff --git a/extensions/vscode/tsconfig.json b/extensions/vscode/tsconfig.json index bec27d2f..452cdae1 100644 --- a/extensions/vscode/tsconfig.json +++ b/extensions/vscode/tsconfig.json @@ -11,8 +11,7 @@ "declaration": true, "outDir": "./dist", "rootDir": "./src", - "resolveJsonModule": true, - "composite": true + "resolveJsonModule": true }, "include": [ "src/**/*" diff --git a/tsconfig.json b/tsconfig.json index 3039d554..c927b521 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -15,9 +15,6 @@ "references": [ { "path": "./server" - }, - { - "path": "./extensions/vscode" } ] } \ No newline at end of file From 08066fb6b436428f311a41f40941c60df35f1ae8 Mon Sep 17 00:00:00 2001 From: Nathan Randall Date: Thu, 19 Feb 2026 10:52:30 -0700 Subject: [PATCH 10/14] Update dependabot.yaml config for extension --- .github/dependabot.yaml | 5 +++++ .github/workflows/release.yml | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/.github/dependabot.yaml b/.github/dependabot.yaml index 4d9e7abc..bc874fb3 100644 --- a/.github/dependabot.yaml +++ b/.github/dependabot.yaml @@ -31,3 +31,8 @@ updates: ignore: - dependency-name: 'zod' versioning-strategy: 'increase' + - package-ecosystem: 'npm' + directory: '/extensions/vscode/' + schedule: + interval: 'weekly' + versioning-strategy: 'increase' diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 0b731aad..1a5fb152 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -188,7 +188,7 @@ jobs: path: dist-packs - name: Release - Download VSIX artifact - uses: actions/download-artifact@v6 + uses: actions/download-artifact@v7 with: name: codeql-development-mcp-server-vsix-${{ needs.resolve-version.outputs.version }} path: dist-vsix From 70dd490efb7fa4bbc06dfdb45659e1e47b9a4be9 Mon Sep 17 00:00:00 2001 From: Nathan Randall Date: Thu, 19 Feb 2026 11:43:34 -0700 Subject: [PATCH 11/14] Upgrade NodeJS deps to latest & fix server lint This commit upgrades the NodeJS dependencies to latest available versions for all npm workspaces and fixes server code, as needed, for compatibility with (upgraded) eslint 10.x. --- client/package.json | 2 +- extensions/vscode/package.json | 16 +- package-lock.json | 803 +++++++----------- package.json | 4 +- server/dist/codeql-development-mcp-server.js | 25 +- .../dist/codeql-development-mcp-server.js.map | 4 +- server/package.json | 10 +- server/src/lib/cli-executor.ts | 3 +- server/src/lib/cli-tool-registry.ts | 2 +- server/src/lib/query-scaffolding.ts | 2 +- server/src/lib/session-tracking.ts | 10 +- .../src/tools/codeql/find-class-position.ts | 2 +- .../tools/codeql/find-predicate-position.ts | 2 +- server/src/tools/codeql/quick-evaluate.ts | 2 +- server/src/tools/codeql/register-database.ts | 8 +- server/src/tools/lsp/lsp-diagnostics.ts | 2 +- server/src/tools/lsp/lsp-handlers.ts | 2 +- 17 files changed, 347 insertions(+), 552 deletions(-) diff --git a/client/package.json b/client/package.json index d79dcf2d..9703670c 100644 --- a/client/package.json +++ b/client/package.json @@ -28,7 +28,7 @@ }, "dependencies": { "@modelcontextprotocol/sdk": "^1.26.0", - "dotenv": "^17.3.0", + "dotenv": "^17.3.1", "js-yaml": "^4.1.1" }, "devDependencies": { diff --git a/extensions/vscode/package.json b/extensions/vscode/package.json index 9d5a53b1..504a2b08 100644 --- a/extensions/vscode/package.json +++ b/extensions/vscode/package.json @@ -139,21 +139,21 @@ "watch": "node esbuild.config.js --watch" }, "devDependencies": { - "@eslint/js": "^9.39.2", + "@eslint/js": "^10.0.1", "@types/mocha": "^10.0.10", - "@types/node": "^22.15.0", - "@types/vscode": "^1.99.0", + "@types/node": "^25.3.0", + "@types/vscode": "^1.109.0", "@vitest/coverage-v8": "^4.0.18", - "@vscode/vsce": "^3.3.2", + "@vscode/vsce": "^3.7.1", "esbuild": "^0.27.3", - "eslint": "^9.39.2", + "eslint": "^10.0.0", "eslint-config-prettier": "^10.1.8", "eslint-plugin-prettier": "^5.5.5", - "glob": "^11.0.2", - "mocha": "^11.2.2", + "glob": "^13.0.6", + "mocha": "^11.7.5", "prettier": "^3.8.1", "typescript": "^5.9.3", - "typescript-eslint": "^8.54.0", + "typescript-eslint": "^8.56.0", "vitest": "^4.0.18" } } diff --git a/package-lock.json b/package-lock.json index 9194eeaa..918d0446 100644 --- a/package-lock.json +++ b/package-lock.json @@ -14,12 +14,12 @@ "extensions/vscode" ], "devDependencies": { - "eslint": "^9.39.2", + "eslint": "^10.0.0", "eslint-config-prettier": "^10.1.8", "eslint-plugin-prettier": "^5.5.5", "prettier": "^3.8.1", "typescript": "^5.9.3", - "typescript-eslint": "^8.55.0" + "typescript-eslint": "^8.56.0" }, "engines": { "node": ">=24.13.0", @@ -32,7 +32,7 @@ "license": "SEE LICENSE IN LICENSE", "dependencies": { "@modelcontextprotocol/sdk": "^1.26.0", - "dotenv": "^17.3.0", + "dotenv": "^17.3.1", "js-yaml": "^4.1.1" }, "bin": { @@ -50,259 +50,90 @@ "npm": ">=11.6.2" } }, - "client/node_modules/@eslint/config-array": { - "version": "0.23.1", - "resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.23.1.tgz", - "integrity": "sha512-uVSdg/V4dfQmTjJzR0szNczjOH/J+FyUMMjYtr07xFRXR7EDf9i1qdxrD0VusZH9knj1/ecxzCQQxyic5NzAiA==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "@eslint/object-schema": "^3.0.1", - "debug": "^4.3.1", - "minimatch": "^10.1.1" - }, - "engines": { - "node": "^20.19.0 || ^22.13.0 || >=24" - } - }, - "client/node_modules/@eslint/config-helpers": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/@eslint/config-helpers/-/config-helpers-0.5.2.tgz", - "integrity": "sha512-a5MxrdDXEvqnIq+LisyCX6tQMPF/dSJpCfBgBauY+pNZ28yCtSsTvyTYrMhaI+LK26bVyCJfJkT0u8KIj2i1dQ==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "@eslint/core": "^1.1.0" - }, - "engines": { - "node": "^20.19.0 || ^22.13.0 || >=24" - } - }, - "client/node_modules/@eslint/core": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@eslint/core/-/core-1.1.0.tgz", - "integrity": "sha512-/nr9K9wkr3P1EzFTdFdMoLuo1PmIxjmwvPozwoSodjNBdefGujXQUF93u1DDZpEaTuDvMsIQddsd35BwtrW9Xw==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "@types/json-schema": "^7.0.15" + "extensions/vscode": { + "name": "vscode-codeql-development-mcp-server", + "version": "2.24.1", + "license": "SEE LICENSE IN LICENSE", + "devDependencies": { + "@eslint/js": "^10.0.1", + "@types/mocha": "^10.0.10", + "@types/node": "^25.3.0", + "@types/vscode": "^1.109.0", + "@vitest/coverage-v8": "^4.0.18", + "@vscode/vsce": "^3.7.1", + "esbuild": "^0.27.3", + "eslint": "^10.0.0", + "eslint-config-prettier": "^10.1.8", + "eslint-plugin-prettier": "^5.5.5", + "glob": "^13.0.6", + "mocha": "^11.7.5", + "prettier": "^3.8.1", + "typescript": "^5.9.3", + "typescript-eslint": "^8.56.0", + "vitest": "^4.0.18" }, "engines": { - "node": "^20.19.0 || ^22.13.0 || >=24" + "node": ">=24.13.0", + "vscode": "^1.99.0" } }, - "client/node_modules/@eslint/js": { - "version": "10.0.1", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-10.0.1.tgz", - "integrity": "sha512-zeR9k5pd4gxjZ0abRoIaxdc7I3nDktoXZk2qOv9gCNWx3mVwEn32VRhyLaRsDiJjTs0xq/T8mfPtyuXu7GWBcA==", + "extensions/vscode/node_modules/balanced-match": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-4.0.3.tgz", + "integrity": "sha512-1pHv8LX9CpKut1Zp4EXey7Z8OfH11ONNH6Dhi2WDUt31VVZFXZzKwXcysBgqSumFCmR+0dqjMK5v5JiFHzi0+g==", "dev": true, "license": "MIT", "engines": { - "node": "^20.19.0 || ^22.13.0 || >=24" - }, - "funding": { - "url": "https://eslint.org/donate" - }, - "peerDependencies": { - "eslint": "^10.0.0" - }, - "peerDependenciesMeta": { - "eslint": { - "optional": true - } - } - }, - "client/node_modules/@eslint/object-schema": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/@eslint/object-schema/-/object-schema-3.0.1.tgz", - "integrity": "sha512-P9cq2dpr+LU8j3qbLygLcSZrl2/ds/pUpfnHNNuk5HW7mnngHs+6WSq5C9mO3rqRX8A1poxqLTC9cu0KOyJlBg==", - "dev": true, - "license": "Apache-2.0", - "engines": { - "node": "^20.19.0 || ^22.13.0 || >=24" - } - }, - "client/node_modules/@eslint/plugin-kit": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.6.0.tgz", - "integrity": "sha512-bIZEUzOI1jkhviX2cp5vNyXQc6olzb2ohewQubuYlMXZ2Q/XjBO0x0XhGPvc9fjSIiUN0vw+0hq53BJ4eQSJKQ==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "@eslint/core": "^1.1.0", - "levn": "^0.4.1" - }, - "engines": { - "node": "^20.19.0 || ^22.13.0 || >=24" + "node": "20 || >=22" } }, - "client/node_modules/eslint": { - "version": "10.0.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-10.0.0.tgz", - "integrity": "sha512-O0piBKY36YSJhlFSG8p9VUdPV/SxxS4FYDWVpr/9GJuMaepzwlf4J8I4ov1b+ySQfDTPhc3DtLaxcT1fN0yqCg==", + "extensions/vscode/node_modules/brace-expansion": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.2.tgz", + "integrity": "sha512-Pdk8c9poy+YhOgVWw1JNN22/HcivgKWwpxKq04M/jTmHyCZn12WPJebZxdjSa5TmBqISrUSgNYU3eRORljfCCw==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { - "@eslint-community/eslint-utils": "^4.8.0", - "@eslint-community/regexpp": "^4.12.2", - "@eslint/config-array": "^0.23.0", - "@eslint/config-helpers": "^0.5.2", - "@eslint/core": "^1.1.0", - "@eslint/plugin-kit": "^0.6.0", - "@humanfs/node": "^0.16.6", - "@humanwhocodes/module-importer": "^1.0.1", - "@humanwhocodes/retry": "^0.4.2", - "@types/estree": "^1.0.6", - "ajv": "^6.12.4", - "cross-spawn": "^7.0.6", - "debug": "^4.3.2", - "escape-string-regexp": "^4.0.0", - "eslint-scope": "^9.1.0", - "eslint-visitor-keys": "^5.0.0", - "espree": "^11.1.0", - "esquery": "^1.7.0", - "esutils": "^2.0.2", - "fast-deep-equal": "^3.1.3", - "file-entry-cache": "^8.0.0", - "find-up": "^5.0.0", - "glob-parent": "^6.0.2", - "ignore": "^5.2.0", - "imurmurhash": "^0.1.4", - "is-glob": "^4.0.0", - "json-stable-stringify-without-jsonify": "^1.0.1", - "minimatch": "^10.1.1", - "natural-compare": "^1.4.0", - "optionator": "^0.9.3" - }, - "bin": { - "eslint": "bin/eslint.js" - }, - "engines": { - "node": "^20.19.0 || ^22.13.0 || >=24" - }, - "funding": { - "url": "https://eslint.org/donate" - }, - "peerDependencies": { - "jiti": "*" - }, - "peerDependenciesMeta": { - "jiti": { - "optional": true - } - } - }, - "client/node_modules/eslint-scope": { - "version": "9.1.0", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-9.1.0.tgz", - "integrity": "sha512-CkWE42hOJsNj9FJRaoMX9waUFYhqY4jmyLFdAdzZr6VaCg3ynLYx4WnOdkaIifGfH4gsUcBTn4OZbHXkpLD0FQ==", - "dev": true, - "license": "BSD-2-Clause", - "dependencies": { - "@types/esrecurse": "^4.3.1", - "@types/estree": "^1.0.8", - "esrecurse": "^4.3.0", - "estraverse": "^5.2.0" - }, - "engines": { - "node": "^20.19.0 || ^22.13.0 || >=24" + "balanced-match": "^4.0.2" }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "client/node_modules/eslint-visitor-keys": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-5.0.0.tgz", - "integrity": "sha512-A0XeIi7CXU7nPlfHS9loMYEKxUaONu/hTEzHTGba9Huu94Cq1hPivf+DE5erJozZOky0LfvXAyrV/tcswpLI0Q==", - "dev": true, - "license": "Apache-2.0", "engines": { - "node": "^20.19.0 || ^22.13.0 || >=24" - }, - "funding": { - "url": "https://opencollective.com/eslint" + "node": "20 || >=22" } }, - "client/node_modules/espree": { - "version": "11.1.0", - "resolved": "https://registry.npmjs.org/espree/-/espree-11.1.0.tgz", - "integrity": "sha512-WFWYhO1fV4iYkqOOvq8FbqIhr2pYfoDY0kCotMkDeNtGpiGGkZ1iov2u8ydjtgM8yF8rzK7oaTbw2NAzbAbehw==", + "extensions/vscode/node_modules/glob": { + "version": "13.0.6", + "resolved": "https://registry.npmjs.org/glob/-/glob-13.0.6.tgz", + "integrity": "sha512-Wjlyrolmm8uDpm/ogGyXZXb1Z+Ca2B8NbJwqBVg0axK9GbBeoS7yGV6vjXnYdGm6X53iehEuxxbyiKp8QmN4Vw==", "dev": true, - "license": "BSD-2-Clause", + "license": "BlueOak-1.0.0", "dependencies": { - "acorn": "^8.15.0", - "acorn-jsx": "^5.3.2", - "eslint-visitor-keys": "^5.0.0" + "minimatch": "^10.2.2", + "minipass": "^7.1.3", + "path-scurry": "^2.0.2" }, "engines": { - "node": "^20.19.0 || ^22.13.0 || >=24" + "node": "18 || 20 || >=22" }, "funding": { - "url": "https://opencollective.com/eslint" + "url": "https://github.com/sponsors/isaacs" } }, - "client/node_modules/minimatch": { - "version": "10.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.1.2.tgz", - "integrity": "sha512-fu656aJ0n2kcXwsnwnv9g24tkU5uSmOlTjd6WyyaKm2Z+h1qmY6bAjrcaIxF/BslFqbZ8UBtbJi7KgQOZD2PTw==", + "extensions/vscode/node_modules/minimatch": { + "version": "10.2.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.2.tgz", + "integrity": "sha512-+G4CpNBxa5MprY+04MbgOw1v7So6n5JY166pFi9KfYwT78fxScCeSNQSNzp6dpPSW2rONOps6Ocam1wFhCgoVw==", "dev": true, "license": "BlueOak-1.0.0", "dependencies": { - "@isaacs/brace-expansion": "^5.0.1" + "brace-expansion": "^5.0.2" }, "engines": { - "node": "20 || >=22" + "node": "18 || 20 || >=22" }, "funding": { "url": "https://github.com/sponsors/isaacs" } }, - "extensions/vscode": { - "name": "vscode-codeql-development-mcp-server", - "version": "2.24.1", - "license": "SEE LICENSE IN LICENSE", - "devDependencies": { - "@eslint/js": "^9.39.2", - "@types/mocha": "^10.0.10", - "@types/node": "^22.15.0", - "@types/vscode": "^1.99.0", - "@vitest/coverage-v8": "^4.0.18", - "@vscode/vsce": "^3.3.2", - "esbuild": "^0.27.3", - "eslint": "^9.39.2", - "eslint-config-prettier": "^10.1.8", - "eslint-plugin-prettier": "^5.5.5", - "glob": "^11.0.2", - "mocha": "^11.2.2", - "prettier": "^3.8.1", - "typescript": "^5.9.3", - "typescript-eslint": "^8.54.0", - "vitest": "^4.0.18" - }, - "engines": { - "node": ">=24.13.0", - "vscode": "^1.99.0" - } - }, - "extensions/vscode/node_modules/@types/node": { - "version": "22.19.11", - "resolved": "https://registry.npmjs.org/@types/node/-/node-22.19.11.tgz", - "integrity": "sha512-BH7YwL6rA93ReqeQS1c4bsPpcfOmJasG+Fkr6Y59q83f9M1WcBRHR2vM+P9eOisYRcN3ujQoiZY8uk5W+1WL8w==", - "dev": true, - "license": "MIT", - "dependencies": { - "undici-types": "~6.21.0" - } - }, - "extensions/vscode/node_modules/undici-types": { - "version": "6.21.0", - "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.21.0.tgz", - "integrity": "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==", - "dev": true, - "license": "MIT" - }, "node_modules/@azu/format-text": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/@azu/format-text/-/format-text-1.0.2.tgz", @@ -1056,105 +887,128 @@ } }, "node_modules/@eslint/config-array": { - "version": "0.21.1", - "resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.21.1.tgz", - "integrity": "sha512-aw1gNayWpdI/jSYVgzN5pL0cfzU02GT3NBpeT/DXbx1/1x7ZKxFPd9bwrzygx/qiwIQiJ1sw/zD8qY/kRvlGHA==", + "version": "0.23.1", + "resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.23.1.tgz", + "integrity": "sha512-uVSdg/V4dfQmTjJzR0szNczjOH/J+FyUMMjYtr07xFRXR7EDf9i1qdxrD0VusZH9knj1/ecxzCQQxyic5NzAiA==", "dev": true, "license": "Apache-2.0", "dependencies": { - "@eslint/object-schema": "^2.1.7", + "@eslint/object-schema": "^3.0.1", "debug": "^4.3.1", - "minimatch": "^3.1.2" + "minimatch": "^10.1.1" }, "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + "node": "^20.19.0 || ^22.13.0 || >=24" } }, - "node_modules/@eslint/config-helpers": { - "version": "0.4.2", - "resolved": "https://registry.npmjs.org/@eslint/config-helpers/-/config-helpers-0.4.2.tgz", - "integrity": "sha512-gBrxN88gOIf3R7ja5K9slwNayVcZgK6SOUORm2uBzTeIEfeVaIhOpCtTox3P6R7o2jLFwLFTLnC7kU/RGcYEgw==", + "node_modules/@eslint/config-array/node_modules/balanced-match": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-4.0.3.tgz", + "integrity": "sha512-1pHv8LX9CpKut1Zp4EXey7Z8OfH11ONNH6Dhi2WDUt31VVZFXZzKwXcysBgqSumFCmR+0dqjMK5v5JiFHzi0+g==", "dev": true, - "license": "Apache-2.0", + "license": "MIT", + "engines": { + "node": "20 || >=22" + } + }, + "node_modules/@eslint/config-array/node_modules/brace-expansion": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.2.tgz", + "integrity": "sha512-Pdk8c9poy+YhOgVWw1JNN22/HcivgKWwpxKq04M/jTmHyCZn12WPJebZxdjSa5TmBqISrUSgNYU3eRORljfCCw==", + "dev": true, + "license": "MIT", "dependencies": { - "@eslint/core": "^0.17.0" + "balanced-match": "^4.0.2" }, "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + "node": "20 || >=22" } }, - "node_modules/@eslint/core": { - "version": "0.17.0", - "resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.17.0.tgz", - "integrity": "sha512-yL/sLrpmtDaFEiUj1osRP4TI2MDz1AddJL+jZ7KSqvBuliN4xqYY54IfdN8qD8Toa6g1iloph1fxQNkjOxrrpQ==", + "node_modules/@eslint/config-array/node_modules/minimatch": { + "version": "10.2.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.2.tgz", + "integrity": "sha512-+G4CpNBxa5MprY+04MbgOw1v7So6n5JY166pFi9KfYwT78fxScCeSNQSNzp6dpPSW2rONOps6Ocam1wFhCgoVw==", "dev": true, - "license": "Apache-2.0", + "license": "BlueOak-1.0.0", "dependencies": { - "@types/json-schema": "^7.0.15" + "brace-expansion": "^5.0.2" }, "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + "node": "18 || 20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/@eslint/eslintrc": { - "version": "3.3.3", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-3.3.3.tgz", - "integrity": "sha512-Kr+LPIUVKz2qkx1HAMH8q1q6azbqBAsXJUxBl/ODDuVPX45Z9DfwB8tPjTi6nNZ8BuM3nbJxC5zCAg5elnBUTQ==", + "node_modules/@eslint/config-helpers": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/@eslint/config-helpers/-/config-helpers-0.5.2.tgz", + "integrity": "sha512-a5MxrdDXEvqnIq+LisyCX6tQMPF/dSJpCfBgBauY+pNZ28yCtSsTvyTYrMhaI+LK26bVyCJfJkT0u8KIj2i1dQ==", "dev": true, - "license": "MIT", + "license": "Apache-2.0", "dependencies": { - "ajv": "^6.12.4", - "debug": "^4.3.2", - "espree": "^10.0.1", - "globals": "^14.0.0", - "ignore": "^5.2.0", - "import-fresh": "^3.2.1", - "js-yaml": "^4.1.1", - "minimatch": "^3.1.2", - "strip-json-comments": "^3.1.1" + "@eslint/core": "^1.1.0" }, "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + "node": "^20.19.0 || ^22.13.0 || >=24" + } + }, + "node_modules/@eslint/core": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@eslint/core/-/core-1.1.0.tgz", + "integrity": "sha512-/nr9K9wkr3P1EzFTdFdMoLuo1PmIxjmwvPozwoSodjNBdefGujXQUF93u1DDZpEaTuDvMsIQddsd35BwtrW9Xw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@types/json-schema": "^7.0.15" }, - "funding": { - "url": "https://opencollective.com/eslint" + "engines": { + "node": "^20.19.0 || ^22.13.0 || >=24" } }, "node_modules/@eslint/js": { - "version": "9.39.2", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.39.2.tgz", - "integrity": "sha512-q1mjIoW1VX4IvSocvM/vbTiveKC4k9eLrajNEuSsmjymSDEbpGddtpfOoN7YGAqBK3NG+uqo8ia4PDTt8buCYA==", + "version": "10.0.1", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-10.0.1.tgz", + "integrity": "sha512-zeR9k5pd4gxjZ0abRoIaxdc7I3nDktoXZk2qOv9gCNWx3mVwEn32VRhyLaRsDiJjTs0xq/T8mfPtyuXu7GWBcA==", "dev": true, "license": "MIT", "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + "node": "^20.19.0 || ^22.13.0 || >=24" }, "funding": { "url": "https://eslint.org/donate" + }, + "peerDependencies": { + "eslint": "^10.0.0" + }, + "peerDependenciesMeta": { + "eslint": { + "optional": true + } } }, "node_modules/@eslint/object-schema": { - "version": "2.1.7", - "resolved": "https://registry.npmjs.org/@eslint/object-schema/-/object-schema-2.1.7.tgz", - "integrity": "sha512-VtAOaymWVfZcmZbp6E2mympDIHvyjXs/12LqWYjVw6qjrfF+VK+fyG33kChz3nnK+SU5/NeHOqrTEHS8sXO3OA==", + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@eslint/object-schema/-/object-schema-3.0.1.tgz", + "integrity": "sha512-P9cq2dpr+LU8j3qbLygLcSZrl2/ds/pUpfnHNNuk5HW7mnngHs+6WSq5C9mO3rqRX8A1poxqLTC9cu0KOyJlBg==", "dev": true, "license": "Apache-2.0", "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + "node": "^20.19.0 || ^22.13.0 || >=24" } }, "node_modules/@eslint/plugin-kit": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.4.1.tgz", - "integrity": "sha512-43/qtrDUokr7LJqoF2c3+RInu/t4zfrpYdoSDfYyhg52rwLV6TnOvdG4fXm7IkSB3wErkcmJS9iEhjVtOSEjjA==", + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.6.0.tgz", + "integrity": "sha512-bIZEUzOI1jkhviX2cp5vNyXQc6olzb2ohewQubuYlMXZ2Q/XjBO0x0XhGPvc9fjSIiUN0vw+0hq53BJ4eQSJKQ==", "dev": true, "license": "Apache-2.0", "dependencies": { - "@eslint/core": "^0.17.0", + "@eslint/core": "^1.1.0", "levn": "^0.4.1" }, "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + "node": "^20.19.0 || ^22.13.0 || >=24" } }, "node_modules/@hono/node-server": { @@ -1221,29 +1075,6 @@ "url": "https://github.com/sponsors/nzakas" } }, - "node_modules/@isaacs/balanced-match": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/@isaacs/balanced-match/-/balanced-match-4.0.1.tgz", - "integrity": "sha512-yzMTt9lEb8Gv7zRioUilSglI0c0smZ9k5D65677DLWLtWJaXIS3CqcGyUFByYKlnUj6TkjLVs54fBl6+TiGQDQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": "20 || >=22" - } - }, - "node_modules/@isaacs/brace-expansion": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/@isaacs/brace-expansion/-/brace-expansion-5.0.1.tgz", - "integrity": "sha512-WMz71T1JS624nWj2n2fnYAuPovhv7EUhk69R6i9dsVyzxt5eM3bjwvgk9L+APE1TRscGysAVMANkB0jh0LQZrQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@isaacs/balanced-match": "^4.0.1" - }, - "engines": { - "node": "20 || >=22" - } - }, "node_modules/@isaacs/cliui": { "version": "9.0.0", "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-9.0.0.tgz", @@ -1323,9 +1154,9 @@ } }, "node_modules/@modelcontextprotocol/sdk/node_modules/ajv": { - "version": "8.17.1", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz", - "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==", + "version": "8.18.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.18.0.tgz", + "integrity": "sha512-PlXPeEWMXMZ7sPYOHqmDyCJzcfNrUr3fGNKtezX14ykXOEIvyK81d+qydx89KY5O71FKMPaQ2vBfBFI5NHR63A==", "license": "MIT", "dependencies": { "fast-deep-equal": "^3.1.3", @@ -2181,13 +2012,13 @@ "license": "MIT" }, "node_modules/@types/node": { - "version": "25.2.2", - "resolved": "https://registry.npmjs.org/@types/node/-/node-25.2.2.tgz", - "integrity": "sha512-BkmoP5/FhRYek5izySdkOneRyXYN35I860MFAGupTdebyE66uZaR+bXLHq8k4DirE5DwQi3NuhvRU1jqTVwUrQ==", + "version": "25.3.0", + "resolved": "https://registry.npmjs.org/@types/node/-/node-25.3.0.tgz", + "integrity": "sha512-4K3bqJpXpqfg2XKGK9bpDTc6xO/xoUP/RBWS7AtRMug6zZFaRekiLzjVtAoZMquxoAbzBvy5nxQ7veS5eYzf8A==", "dev": true, "license": "MIT", "dependencies": { - "undici-types": "~7.16.0" + "undici-types": "~7.18.0" } }, "node_modules/@types/normalize-package-data": { @@ -2247,17 +2078,17 @@ "license": "MIT" }, "node_modules/@typescript-eslint/eslint-plugin": { - "version": "8.55.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.55.0.tgz", - "integrity": "sha512-1y/MVSz0NglV1ijHC8OT49mPJ4qhPYjiK08YUQVbIOyu+5k862LKUHFkpKHWu//zmr7hDR2rhwUm6gnCGNmGBQ==", + "version": "8.56.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.56.0.tgz", + "integrity": "sha512-lRyPDLzNCuae71A3t9NEINBiTn7swyOhvUj3MyUOxb8x6g6vPEFoOU+ZRmGMusNC3X3YMhqMIX7i8ShqhT74Pw==", "dev": true, "license": "MIT", "dependencies": { "@eslint-community/regexpp": "^4.12.2", - "@typescript-eslint/scope-manager": "8.55.0", - "@typescript-eslint/type-utils": "8.55.0", - "@typescript-eslint/utils": "8.55.0", - "@typescript-eslint/visitor-keys": "8.55.0", + "@typescript-eslint/scope-manager": "8.56.0", + "@typescript-eslint/type-utils": "8.56.0", + "@typescript-eslint/utils": "8.56.0", + "@typescript-eslint/visitor-keys": "8.56.0", "ignore": "^7.0.5", "natural-compare": "^1.4.0", "ts-api-utils": "^2.4.0" @@ -2270,8 +2101,8 @@ "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "@typescript-eslint/parser": "^8.55.0", - "eslint": "^8.57.0 || ^9.0.0", + "@typescript-eslint/parser": "^8.56.0", + "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", "typescript": ">=4.8.4 <6.0.0" } }, @@ -2286,17 +2117,17 @@ } }, "node_modules/@typescript-eslint/parser": { - "version": "8.55.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.55.0.tgz", - "integrity": "sha512-4z2nCSBfVIMnbuu8uinj+f0o4qOeggYJLbjpPHka3KH1om7e+H9yLKTYgksTaHcGco+NClhhY2vyO3HsMH1RGw==", + "version": "8.56.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.56.0.tgz", + "integrity": "sha512-IgSWvLobTDOjnaxAfDTIHaECbkNlAlKv2j5SjpB2v7QHKv1FIfjwMy8FsDbVfDX/KjmCmYICcw7uGaXLhtsLNg==", "dev": true, "license": "MIT", "peer": true, "dependencies": { - "@typescript-eslint/scope-manager": "8.55.0", - "@typescript-eslint/types": "8.55.0", - "@typescript-eslint/typescript-estree": "8.55.0", - "@typescript-eslint/visitor-keys": "8.55.0", + "@typescript-eslint/scope-manager": "8.56.0", + "@typescript-eslint/types": "8.56.0", + "@typescript-eslint/typescript-estree": "8.56.0", + "@typescript-eslint/visitor-keys": "8.56.0", "debug": "^4.4.3" }, "engines": { @@ -2307,19 +2138,19 @@ "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "eslint": "^8.57.0 || ^9.0.0", + "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", "typescript": ">=4.8.4 <6.0.0" } }, "node_modules/@typescript-eslint/project-service": { - "version": "8.55.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.55.0.tgz", - "integrity": "sha512-zRcVVPFUYWa3kNnjaZGXSu3xkKV1zXy8M4nO/pElzQhFweb7PPtluDLQtKArEOGmjXoRjnUZ29NjOiF0eCDkcQ==", + "version": "8.56.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.56.0.tgz", + "integrity": "sha512-M3rnyL1vIQOMeWxTWIW096/TtVP+8W3p/XnaFflhmcFp+U4zlxUxWj4XwNs6HbDeTtN4yun0GNTTDBw/SvufKg==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/tsconfig-utils": "^8.55.0", - "@typescript-eslint/types": "^8.55.0", + "@typescript-eslint/tsconfig-utils": "^8.56.0", + "@typescript-eslint/types": "^8.56.0", "debug": "^4.4.3" }, "engines": { @@ -2334,14 +2165,14 @@ } }, "node_modules/@typescript-eslint/scope-manager": { - "version": "8.55.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.55.0.tgz", - "integrity": "sha512-fVu5Omrd3jeqeQLiB9f1YsuK/iHFOwb04bCtY4BSCLgjNbOD33ZdV6KyEqplHr+IlpgT0QTZ/iJ+wT7hvTx49Q==", + "version": "8.56.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.56.0.tgz", + "integrity": "sha512-7UiO/XwMHquH+ZzfVCfUNkIXlp/yQjjnlYUyYz7pfvlK3/EyyN6BK+emDmGNyQLBtLGaYrTAI6KOw8tFucWL2w==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.55.0", - "@typescript-eslint/visitor-keys": "8.55.0" + "@typescript-eslint/types": "8.56.0", + "@typescript-eslint/visitor-keys": "8.56.0" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -2352,9 +2183,9 @@ } }, "node_modules/@typescript-eslint/tsconfig-utils": { - "version": "8.55.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.55.0.tgz", - "integrity": "sha512-1R9cXqY7RQd7WuqSN47PK9EDpgFUK3VqdmbYrvWJZYDd0cavROGn+74ktWBlmJ13NXUQKlZ/iAEQHI/V0kKe0Q==", + "version": "8.56.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.56.0.tgz", + "integrity": "sha512-bSJoIIt4o3lKXD3xmDh9chZcjCz5Lk8xS7Rxn+6l5/pKrDpkCwtQNQQwZ2qRPk7TkUYhrq3WPIHXOXlbXP0itg==", "dev": true, "license": "MIT", "engines": { @@ -2369,15 +2200,15 @@ } }, "node_modules/@typescript-eslint/type-utils": { - "version": "8.55.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.55.0.tgz", - "integrity": "sha512-x1iH2unH4qAt6I37I2CGlsNs+B9WGxurP2uyZLRz6UJoZWDBx9cJL1xVN/FiOmHEONEg6RIufdvyT0TEYIgC5g==", + "version": "8.56.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.56.0.tgz", + "integrity": "sha512-qX2L3HWOU2nuDs6GzglBeuFXviDODreS58tLY/BALPC7iu3Fa+J7EOTwnX9PdNBxUI7Uh0ntP0YWGnxCkXzmfA==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.55.0", - "@typescript-eslint/typescript-estree": "8.55.0", - "@typescript-eslint/utils": "8.55.0", + "@typescript-eslint/types": "8.56.0", + "@typescript-eslint/typescript-estree": "8.56.0", + "@typescript-eslint/utils": "8.56.0", "debug": "^4.4.3", "ts-api-utils": "^2.4.0" }, @@ -2389,14 +2220,14 @@ "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "eslint": "^8.57.0 || ^9.0.0", + "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", "typescript": ">=4.8.4 <6.0.0" } }, "node_modules/@typescript-eslint/types": { - "version": "8.55.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.55.0.tgz", - "integrity": "sha512-ujT0Je8GI5BJWi+/mMoR0wxwVEQaxM+pi30xuMiJETlX80OPovb2p9E8ss87gnSVtYXtJoU9U1Cowcr6w2FE0w==", + "version": "8.56.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.56.0.tgz", + "integrity": "sha512-DBsLPs3GsWhX5HylbP9HNG15U0bnwut55Lx12bHB9MpXxQ+R5GC8MwQe+N1UFXxAeQDvEsEDY6ZYwX03K7Z6HQ==", "dev": true, "license": "MIT", "engines": { @@ -2408,16 +2239,16 @@ } }, "node_modules/@typescript-eslint/typescript-estree": { - "version": "8.55.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.55.0.tgz", - "integrity": "sha512-EwrH67bSWdx/3aRQhCoxDaHM+CrZjotc2UCCpEDVqfCE+7OjKAGWNY2HsCSTEVvWH2clYQK8pdeLp42EVs+xQw==", + "version": "8.56.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.56.0.tgz", + "integrity": "sha512-ex1nTUMWrseMltXUHmR2GAQ4d+WjkZCT4f+4bVsps8QEdh0vlBsaCokKTPlnqBFqqGaxilDNJG7b8dolW2m43Q==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/project-service": "8.55.0", - "@typescript-eslint/tsconfig-utils": "8.55.0", - "@typescript-eslint/types": "8.55.0", - "@typescript-eslint/visitor-keys": "8.55.0", + "@typescript-eslint/project-service": "8.56.0", + "@typescript-eslint/tsconfig-utils": "8.56.0", + "@typescript-eslint/types": "8.56.0", + "@typescript-eslint/visitor-keys": "8.56.0", "debug": "^4.4.3", "minimatch": "^9.0.5", "semver": "^7.7.3", @@ -2462,16 +2293,16 @@ } }, "node_modules/@typescript-eslint/utils": { - "version": "8.55.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.55.0.tgz", - "integrity": "sha512-BqZEsnPGdYpgyEIkDC1BadNY8oMwckftxBT+C8W0g1iKPdeqKZBtTfnvcq0nf60u7MkjFO8RBvpRGZBPw4L2ow==", + "version": "8.56.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.56.0.tgz", + "integrity": "sha512-RZ3Qsmi2nFGsS+n+kjLAYDPVlrzf7UhTffrDIKr+h2yzAlYP/y5ZulU0yeDEPItos2Ph46JAL5P/On3pe7kDIQ==", "dev": true, "license": "MIT", "dependencies": { "@eslint-community/eslint-utils": "^4.9.1", - "@typescript-eslint/scope-manager": "8.55.0", - "@typescript-eslint/types": "8.55.0", - "@typescript-eslint/typescript-estree": "8.55.0" + "@typescript-eslint/scope-manager": "8.56.0", + "@typescript-eslint/types": "8.56.0", + "@typescript-eslint/typescript-estree": "8.56.0" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -2481,19 +2312,19 @@ "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "eslint": "^8.57.0 || ^9.0.0", + "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", "typescript": ">=4.8.4 <6.0.0" } }, "node_modules/@typescript-eslint/visitor-keys": { - "version": "8.55.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.55.0.tgz", - "integrity": "sha512-AxNRwEie8Nn4eFS1FzDMJWIISMGoXMb037sgCBJ3UR6o0fQTzr2tqN9WT+DkWJPhIdQCfV7T6D387566VtnCJA==", + "version": "8.56.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.56.0.tgz", + "integrity": "sha512-q+SL+b+05Ud6LbEE35qe4A99P+htKTKVbyiNEe45eCbJFyh/HVK9QXwlrbz+Q4L8SOW4roxSVwXYj4DMBT7Ieg==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.55.0", - "eslint-visitor-keys": "^4.2.1" + "@typescript-eslint/types": "8.56.0", + "eslint-visitor-keys": "^5.0.0" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -2866,9 +2697,9 @@ } }, "node_modules/acorn": { - "version": "8.15.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.15.0.tgz", - "integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==", + "version": "8.16.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.16.0.tgz", + "integrity": "sha512-UVJyE9MttOsBQIDKw1skb9nAwQuR5wuGD3+82K6JgJlm/Y+KI92oNsMNGZCYdDsVtRHSak0pcV5Dno5+4jh9sw==", "dev": true, "license": "MIT", "peer": true, @@ -2934,9 +2765,9 @@ } }, "node_modules/ajv-formats/node_modules/ajv": { - "version": "8.17.1", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz", - "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==", + "version": "8.18.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.18.0.tgz", + "integrity": "sha512-PlXPeEWMXMZ7sPYOHqmDyCJzcfNrUr3fGNKtezX14ykXOEIvyK81d+qydx89KY5O71FKMPaQ2vBfBFI5NHR63A==", "license": "MIT", "dependencies": { "fast-deep-equal": "^3.1.3", @@ -3277,16 +3108,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/callsites": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", - "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" - } - }, "node_modules/camelcase": { "version": "6.3.0", "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", @@ -3787,9 +3608,9 @@ } }, "node_modules/dotenv": { - "version": "17.3.0", - "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-17.3.0.tgz", - "integrity": "sha512-i3z5dx/8F45f+Dj0B/qG8oKip9luzyHz6dfJMOKG7zQW/12tT7CrIjs/0J10uNK/Z5O7O0UtfEmx6yFKRQCl4g==", + "version": "17.3.1", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-17.3.1.tgz", + "integrity": "sha512-IO8C/dzEb6O3F9/twg6ZLXz164a2fhTnEWb95H23Dm4OuN+92NmEAlTrupP9VW6Jm3sO26tQlqyvyi4CsnY9GA==", "license": "BSD-2-Clause", "engines": { "node": ">=12" @@ -4057,33 +3878,31 @@ } }, "node_modules/eslint": { - "version": "9.39.2", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.39.2.tgz", - "integrity": "sha512-LEyamqS7W5HB3ujJyvi0HQK/dtVINZvd5mAAp9eT5S/ujByGjiZLCzPcHVzuXbpJDJF/cxwHlfceVUDZ2lnSTw==", + "version": "10.0.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-10.0.0.tgz", + "integrity": "sha512-O0piBKY36YSJhlFSG8p9VUdPV/SxxS4FYDWVpr/9GJuMaepzwlf4J8I4ov1b+ySQfDTPhc3DtLaxcT1fN0yqCg==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "@eslint-community/eslint-utils": "^4.8.0", - "@eslint-community/regexpp": "^4.12.1", - "@eslint/config-array": "^0.21.1", - "@eslint/config-helpers": "^0.4.2", - "@eslint/core": "^0.17.0", - "@eslint/eslintrc": "^3.3.1", - "@eslint/js": "9.39.2", - "@eslint/plugin-kit": "^0.4.1", + "@eslint-community/regexpp": "^4.12.2", + "@eslint/config-array": "^0.23.0", + "@eslint/config-helpers": "^0.5.2", + "@eslint/core": "^1.1.0", + "@eslint/plugin-kit": "^0.6.0", "@humanfs/node": "^0.16.6", "@humanwhocodes/module-importer": "^1.0.1", "@humanwhocodes/retry": "^0.4.2", "@types/estree": "^1.0.6", "ajv": "^6.12.4", - "chalk": "^4.0.0", "cross-spawn": "^7.0.6", "debug": "^4.3.2", "escape-string-regexp": "^4.0.0", - "eslint-scope": "^8.4.0", - "eslint-visitor-keys": "^4.2.1", - "espree": "^10.4.0", - "esquery": "^1.5.0", + "eslint-scope": "^9.1.0", + "eslint-visitor-keys": "^5.0.0", + "espree": "^11.1.0", + "esquery": "^1.7.0", "esutils": "^2.0.2", "fast-deep-equal": "^3.1.3", "file-entry-cache": "^8.0.0", @@ -4093,8 +3912,7 @@ "imurmurhash": "^0.1.4", "is-glob": "^4.0.0", "json-stable-stringify-without-jsonify": "^1.0.1", - "lodash.merge": "^4.6.2", - "minimatch": "^3.1.2", + "minimatch": "^10.1.1", "natural-compare": "^1.4.0", "optionator": "^0.9.3" }, @@ -4102,7 +3920,7 @@ "eslint": "bin/eslint.js" }, "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + "node": "^20.19.0 || ^22.13.0 || >=24" }, "funding": { "url": "https://eslint.org/donate" @@ -4164,48 +3982,89 @@ } }, "node_modules/eslint-scope": { - "version": "8.4.0", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-8.4.0.tgz", - "integrity": "sha512-sNXOfKCn74rt8RICKMvJS7XKV/Xk9kA7DyJr8mJik3S7Cwgy3qlkkmyS2uQB3jiJg6VNdZd/pDBJu0nvG2NlTg==", + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-9.1.0.tgz", + "integrity": "sha512-CkWE42hOJsNj9FJRaoMX9waUFYhqY4jmyLFdAdzZr6VaCg3ynLYx4WnOdkaIifGfH4gsUcBTn4OZbHXkpLD0FQ==", "dev": true, "license": "BSD-2-Clause", "dependencies": { + "@types/esrecurse": "^4.3.1", + "@types/estree": "^1.0.8", "esrecurse": "^4.3.0", "estraverse": "^5.2.0" }, "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + "node": "^20.19.0 || ^22.13.0 || >=24" }, "funding": { "url": "https://opencollective.com/eslint" } }, "node_modules/eslint-visitor-keys": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.1.tgz", - "integrity": "sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ==", + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-5.0.0.tgz", + "integrity": "sha512-A0XeIi7CXU7nPlfHS9loMYEKxUaONu/hTEzHTGba9Huu94Cq1hPivf+DE5erJozZOky0LfvXAyrV/tcswpLI0Q==", "dev": true, "license": "Apache-2.0", "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + "node": "^20.19.0 || ^22.13.0 || >=24" }, "funding": { "url": "https://opencollective.com/eslint" } }, + "node_modules/eslint/node_modules/balanced-match": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-4.0.3.tgz", + "integrity": "sha512-1pHv8LX9CpKut1Zp4EXey7Z8OfH11ONNH6Dhi2WDUt31VVZFXZzKwXcysBgqSumFCmR+0dqjMK5v5JiFHzi0+g==", + "dev": true, + "license": "MIT", + "engines": { + "node": "20 || >=22" + } + }, + "node_modules/eslint/node_modules/brace-expansion": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.2.tgz", + "integrity": "sha512-Pdk8c9poy+YhOgVWw1JNN22/HcivgKWwpxKq04M/jTmHyCZn12WPJebZxdjSa5TmBqISrUSgNYU3eRORljfCCw==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^4.0.2" + }, + "engines": { + "node": "20 || >=22" + } + }, + "node_modules/eslint/node_modules/minimatch": { + "version": "10.2.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.2.tgz", + "integrity": "sha512-+G4CpNBxa5MprY+04MbgOw1v7So6n5JY166pFi9KfYwT78fxScCeSNQSNzp6dpPSW2rONOps6Ocam1wFhCgoVw==", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "brace-expansion": "^5.0.2" + }, + "engines": { + "node": "18 || 20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "node_modules/espree": { - "version": "10.4.0", - "resolved": "https://registry.npmjs.org/espree/-/espree-10.4.0.tgz", - "integrity": "sha512-j6PAQ2uUr79PZhBjP5C5fhl8e39FmRnOjsD5lGnWrFU8i2G776tBK7+nP8KuQUTTyAZUwfQqXAgrVH5MbH9CYQ==", + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/espree/-/espree-11.1.0.tgz", + "integrity": "sha512-WFWYhO1fV4iYkqOOvq8FbqIhr2pYfoDY0kCotMkDeNtGpiGGkZ1iov2u8ydjtgM8yF8rzK7oaTbw2NAzbAbehw==", "dev": true, "license": "BSD-2-Clause", "dependencies": { "acorn": "^8.15.0", "acorn-jsx": "^5.3.2", - "eslint-visitor-keys": "^4.2.1" + "eslint-visitor-keys": "^5.0.0" }, "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + "node": "^20.19.0 || ^22.13.0 || >=24" }, "funding": { "url": "https://opencollective.com/eslint" @@ -4828,34 +4687,21 @@ } }, "node_modules/glob/node_modules/minimatch": { - "version": "10.2.0", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.0.tgz", - "integrity": "sha512-ugkC31VaVg9cF0DFVoADH12k6061zNZkZON+aX8AWsR9GhPcErkcMBceb6znR8wLERM2AkkOxy2nWRLpT9Jq5w==", + "version": "10.2.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.2.tgz", + "integrity": "sha512-+G4CpNBxa5MprY+04MbgOw1v7So6n5JY166pFi9KfYwT78fxScCeSNQSNzp6dpPSW2rONOps6Ocam1wFhCgoVw==", "dev": true, "license": "BlueOak-1.0.0", "dependencies": { "brace-expansion": "^5.0.2" }, "engines": { - "node": "20 || >=22" + "node": "18 || 20 || >=22" }, "funding": { "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/globals": { - "version": "14.0.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-14.0.0.tgz", - "integrity": "sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/globby": { "version": "14.1.0", "resolved": "https://registry.npmjs.org/globby/-/globby-14.1.0.tgz", @@ -5138,23 +4984,6 @@ "node": ">= 4" } }, - "node_modules/import-fresh": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.1.tgz", - "integrity": "sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "parent-module": "^1.0.0", - "resolve-from": "^4.0.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/imurmurhash": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", @@ -5678,13 +5507,6 @@ "dev": true, "license": "MIT" }, - "node_modules/lodash.merge": { - "version": "4.6.2", - "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", - "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", - "dev": true, - "license": "MIT" - }, "node_modules/lodash.once": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/lodash.once/-/lodash.once-4.1.1.tgz", @@ -5948,11 +5770,11 @@ } }, "node_modules/minipass": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz", - "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==", + "version": "7.1.3", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.3.tgz", + "integrity": "sha512-tEBHqDnIoM/1rXME1zgka9g6Q2lcoCkxHLuc7ODJ5BxbP5d4c2Z5cGgtXAku59200Cx7diuHTOYfSBD8n6mm8A==", "dev": true, - "license": "ISC", + "license": "BlueOak-1.0.0", "engines": { "node": ">=16 || 14 >=14.17" } @@ -6491,19 +6313,6 @@ "dev": true, "license": "BlueOak-1.0.0" }, - "node_modules/parent-module": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", - "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", - "dev": true, - "license": "MIT", - "dependencies": { - "callsites": "^3.0.0" - }, - "engines": { - "node": ">=6" - } - }, "node_modules/parse-json": { "version": "8.3.0", "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-8.3.0.tgz", @@ -6624,9 +6433,9 @@ } }, "node_modules/path-scurry": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-2.0.1.tgz", - "integrity": "sha512-oWyT4gICAu+kaA7QWk/jvCHWarMKNs6pXOGWKDTr7cw4IGcUbW+PeTfbaQiLGheFRpjo6O9J0PmyMfQPjH71oA==", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-2.0.2.tgz", + "integrity": "sha512-3O/iVVsJAPsOnpwWIeD+d6z/7PmqApyQePUtCndjatj/9I5LylHvt5qluFaBT3I5h3r1ejfR056c+FCv+NnNXg==", "dev": true, "license": "BlueOak-1.0.0", "dependencies": { @@ -6634,7 +6443,7 @@ "minipass": "^7.1.2" }, "engines": { - "node": "20 || >=22" + "node": "18 || 20 || >=22" }, "funding": { "url": "https://github.com/sponsors/isaacs" @@ -6859,9 +6668,9 @@ } }, "node_modules/qs": { - "version": "6.14.1", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.14.1.tgz", - "integrity": "sha512-4EK3+xJl8Ts67nLYNwqw/dsFVnCf+qR7RgXSK9jEEm9unao3njwMDdmsdvoKBKHzxd7tCYz5e5M+SnMjdtXGQQ==", + "version": "6.15.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.15.0.tgz", + "integrity": "sha512-mAZTtNCeetKMH+pSjrb76NAM8V9a05I9aBZOHztWy/UqcJdQYNsf59vrRKWnojAT9Y+GbIvoTBC++CPHqpDBhQ==", "license": "BSD-3-Clause", "dependencies": { "side-channel": "^1.1.0" @@ -7064,16 +6873,6 @@ "node": ">=0.10.0" } }, - "node_modules/resolve-from": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", - "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=4" - } - }, "node_modules/reusify": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.1.0.tgz", @@ -8029,16 +7828,16 @@ } }, "node_modules/typescript-eslint": { - "version": "8.55.0", - "resolved": "https://registry.npmjs.org/typescript-eslint/-/typescript-eslint-8.55.0.tgz", - "integrity": "sha512-HE4wj+r5lmDVS9gdaN0/+iqNvPZwGfnJ5lZuz7s5vLlg9ODw0bIiiETaios9LvFI1U94/VBXGm3CB2Y5cNFMpw==", + "version": "8.56.0", + "resolved": "https://registry.npmjs.org/typescript-eslint/-/typescript-eslint-8.56.0.tgz", + "integrity": "sha512-c7toRLrotJ9oixgdW7liukZpsnq5CZ7PuKztubGYlNppuTqhIoWfhgHo/7EU0v06gS2l/x0i2NEFK1qMIf0rIg==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/eslint-plugin": "8.55.0", - "@typescript-eslint/parser": "8.55.0", - "@typescript-eslint/typescript-estree": "8.55.0", - "@typescript-eslint/utils": "8.55.0" + "@typescript-eslint/eslint-plugin": "8.56.0", + "@typescript-eslint/parser": "8.56.0", + "@typescript-eslint/typescript-estree": "8.56.0", + "@typescript-eslint/utils": "8.56.0" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -8048,7 +7847,7 @@ "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "eslint": "^8.57.0 || ^9.0.0", + "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", "typescript": ">=4.8.4 <6.0.0" } }, @@ -8077,9 +7876,9 @@ } }, "node_modules/undici-types": { - "version": "7.16.0", - "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.16.0.tgz", - "integrity": "sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw==", + "version": "7.18.2", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.18.2.tgz", + "integrity": "sha512-AsuCzffGHJybSaRrmr5eHr81mwJU3kjw6M+uprWvCXiNeN9SOGwQ3Jn8jb8m3Z6izVgknn1R0FTCEAP2QrLY/w==", "dev": true, "license": "MIT" }, @@ -8633,7 +8432,7 @@ "dependencies": { "@modelcontextprotocol/sdk": "^1.26.0", "cors": "^2.8.6", - "dotenv": "^17.3.0", + "dotenv": "^17.3.1", "express": "^5.2.1", "js-yaml": "^4.1.1", "lowdb": "^7.0.1", @@ -8644,19 +8443,19 @@ "codeql-development-mcp-server-setup-packs": "scripts/setup-packs.sh" }, "devDependencies": { - "@eslint/js": "^9.39.2", + "@eslint/js": "^10.0.1", "@types/cors": "^2.8.19", "@types/express": "^5.0.6", "@types/js-yaml": "^4.0.9", - "@types/node": "^25.2.1", + "@types/node": "^25.3.0", "@vitest/coverage-v8": "^4.0.18", "esbuild": "^0.27.3", - "eslint": "^9.39.2", + "eslint": "^10.0.0", "eslint-config-prettier": "^10.1.8", "eslint-plugin-prettier": "^5.5.5", "prettier": "^3.8.1", "typescript": "^5.9.3", - "typescript-eslint": "^8.54.0", + "typescript-eslint": "^8.56.0", "vitest": "^4.0.18" }, "engines": { diff --git a/package.json b/package.json index 1727761e..cc532b6e 100644 --- a/package.json +++ b/package.json @@ -23,12 +23,12 @@ "npm": ">=11.6.2" }, "devDependencies": { - "eslint": "^9.39.2", + "eslint": "^10.0.0", "eslint-config-prettier": "^10.1.8", "eslint-plugin-prettier": "^5.5.5", "prettier": "^3.8.1", "typescript": "^5.9.3", - "typescript-eslint": "^8.55.0" + "typescript-eslint": "^8.56.0" }, "scripts": { "build": "npm run build -w server && npm run build -w extensions/vscode", diff --git a/server/dist/codeql-development-mcp-server.js b/server/dist/codeql-development-mcp-server.js index 4e62510d..105fad44 100755 --- a/server/dist/codeql-development-mcp-server.js +++ b/server/dist/codeql-development-mcp-server.js @@ -1455,7 +1455,8 @@ async function validateCodeQLBinaryReachable() { } catch (err) { const message = err instanceof Error ? err.message : String(err); throw new Error( - `CodeQL CLI is not reachable (binary: ${binary2}). Ensure codeql is on PATH or set the CODEQL_PATH environment variable to the absolute path of the CodeQL CLI binary. Details: ${message}` + `CodeQL CLI is not reachable (binary: ${binary2}). Ensure codeql is on PATH or set the CODEQL_PATH environment variable to the absolute path of the CodeQL CLI binary. Details: ${message}`, + { cause: err } ); } } @@ -2472,7 +2473,7 @@ async function resolveQueryPath(params, logger2) { resolvedQueries = JSON.parse(resolveResult.stdout); } catch (parseError) { logger2.error("Failed to parse resolve queries output:", parseError); - throw new Error("Failed to parse resolve queries output"); + throw new Error("Failed to parse resolve queries output", { cause: parseError }); } const matchingQuery = resolvedQueries.find((queryPath) => { const fileName = basename2(queryPath); @@ -2843,7 +2844,7 @@ async function findClassPosition(filepath, className) { if (error instanceof Error && error.message.includes("not found in file")) { throw error; } - throw new Error(`Failed to read or parse file ${filepath}: ${error instanceof Error ? error.message : "Unknown error"}`); + throw new Error(`Failed to read or parse file ${filepath}: ${error instanceof Error ? error.message : "Unknown error"}`, { cause: error }); } } function registerFindClassPositionTool(server) { @@ -2911,7 +2912,7 @@ async function findPredicatePosition(filepath, predicateName) { if (error instanceof Error && error.message.includes("not found in file")) { throw error; } - throw new Error(`Failed to read or parse file ${filepath}: ${error instanceof Error ? error.message : "Unknown error"}`); + throw new Error(`Failed to read or parse file ${filepath}: ${error instanceof Error ? error.message : "Unknown error"}`, { cause: error }); } } function registerFindPredicatePositionTool(server) { @@ -7284,7 +7285,7 @@ async function quickEvaluate({ const resolvedOutput = resolve6(output_path || join12(getProjectTmpDir("quickeval"), "quickeval.bqrs")); return resolvedOutput; } catch (error) { - throw new Error(`CodeQL evaluation failed: ${error instanceof Error ? error.message : "Unknown error"}`); + throw new Error(`CodeQL evaluation failed: ${error instanceof Error ? error.message : "Unknown error"}`, { cause: error }); } } function registerQuickEvaluateTool(server) { @@ -7356,15 +7357,15 @@ async function registerDatabase(dbPath) { const errorCode = error.code; if (errorCode === "ENOENT") { if (error.message.includes("codeql-database.yml")) { - throw new Error(`Missing required codeql-database.yml in: ${dbPath}`); + throw new Error(`Missing required codeql-database.yml in: ${dbPath}`, { cause: error }); } - throw new Error(`Database path does not exist: ${dbPath}`); + throw new Error(`Database path does not exist: ${dbPath}`, { cause: error }); } if (errorCode === "EACCES") { - throw new Error(`Database path does not exist: ${dbPath}`); + throw new Error(`Database path does not exist: ${dbPath}`, { cause: error }); } } - throw new Error(`Failed to register database: ${error instanceof Error ? error.message : "Unknown error"}`); + throw new Error(`Failed to register database: ${error instanceof Error ? error.message : "Unknown error"}`, { cause: error }); } } function registerRegisterDatabaseTool(server) { @@ -7745,7 +7746,7 @@ function createCodeQLQuery(options) { filesCreated }; } catch (error) { - throw new Error(`Failed to create query scaffolding: ${error instanceof Error ? error.message : "Unknown error"}`); + throw new Error(`Failed to create query scaffolding: ${error instanceof Error ? error.message : "Unknown error"}`, { cause: error }); } } @@ -8100,7 +8101,7 @@ async function lspDiagnostics({ }; } catch (error) { logger.error("Error evaluating QL code:", error); - throw new Error(`QL evaluation failed: ${error instanceof Error ? error.message : "Unknown error"}`); + throw new Error(`QL evaluation failed: ${error instanceof Error ? error.message : "Unknown error"}`, { cause: error }); } } function registerLspDiagnosticsTool(server) { @@ -8191,7 +8192,7 @@ async function openDocumentForPosition(server, params, absPath, docUri) { try { text = await readFile3(absPath, "utf-8"); } catch (error) { - throw new Error(`Cannot read file: ${absPath}: ${error instanceof Error ? error.message : error}`); + throw new Error(`Cannot read file: ${absPath}: ${error instanceof Error ? error.message : error}`, { cause: error }); } } server.openDocument(docUri, text); diff --git a/server/dist/codeql-development-mcp-server.js.map b/server/dist/codeql-development-mcp-server.js.map index d7719e6e..6dc39d84 100644 --- a/server/dist/codeql-development-mcp-server.js.map +++ b/server/dist/codeql-development-mcp-server.js.map @@ -1,7 +1,7 @@ { "version": 3, "sources": ["../src/utils/logger.ts", "../src/lib/server-config.ts", "../src/utils/package-paths.ts", "../src/utils/temp-dir.ts", "../src/utils/process-ready.ts", "../src/lib/language-server.ts", "../src/lib/query-server.ts", "../src/lib/cli-server.ts", "../src/lib/server-manager.ts", "../src/lib/cli-executor.ts", "../src/codeql-development-mcp-server.ts", "../src/tools/codeql/bqrs-decode.ts", "../src/lib/cli-tool-registry.ts", "../src/lib/query-results-evaluator.ts", "../src/lib/log-directory-manager.ts", "../src/tools/codeql/bqrs-info.ts", "../src/tools/codeql/bqrs-interpret.ts", "../src/tools/codeql/database-analyze.ts", "../src/tools/codeql/database-create.ts", "../src/tools/codeql/find-class-position.ts", "../src/tools/codeql/find-predicate-position.ts", "../src/tools/codeql/find-query-files.ts", "../src/lib/query-file-finder.ts", "../../node_modules/js-yaml/dist/js-yaml.mjs", "../src/lib/metadata-resolver.ts", "../src/tools/codeql/generate-log-summary.ts", "../src/tools/codeql/generate-query-help.ts", "../src/tools/codeql/list-databases.ts", "../src/lib/discovery-config.ts", "../src/tools/codeql/list-mrva-run-results.ts", "../src/tools/codeql/list-query-run-results.ts", "../src/tools/codeql/pack-install.ts", "../src/tools/codeql/pack-ls.ts", "../src/tools/codeql/profile-codeql-query-from-logs.ts", "../src/lib/evaluator-log-parser.ts", "../src/tools/codeql/profile-codeql-query.ts", "../src/tools/codeql/query-compile.ts", "../src/tools/codeql/query-format.ts", "../src/tools/codeql/query-run.ts", "../src/tools/codeql/quick-evaluate.ts", "../src/tools/codeql/register-database.ts", "../src/tools/codeql/resolve-database.ts", "../src/tools/codeql/resolve-languages.ts", "../src/tools/codeql/resolve-library-path.ts", "../src/tools/codeql/resolve-metadata.ts", "../src/tools/codeql/resolve-qlref.ts", "../src/tools/codeql/resolve-queries.ts", "../src/tools/codeql/resolve-tests.ts", "../src/tools/codeql/test-accept.ts", "../src/tools/codeql/test-extract.ts", "../src/tools/codeql/test-run.ts", "../src/tools/codeql-tools.ts", "../src/lib/validation.ts", "../src/lib/query-scaffolding.ts", "../src/lib/resources.ts", "../src/tools/codeql-resources.ts", "../src/tools/lsp/lsp-diagnostics.ts", "../src/tools/lsp/lsp-server-helper.ts", "../src/tools/lsp/lsp-handlers.ts", "../src/tools/lsp/lsp-tools.ts", "../src/resources/language-resources.ts", "../src/types/language-types.ts", "../src/prompts/workflow-prompts.ts", "../src/prompts/prompt-loader.ts", "../src/tools/monitoring-tools.ts", "../../node_modules/lowdb/lib/core/Low.js", "../../node_modules/lowdb/lib/adapters/node/TextFile.js", "../../node_modules/lowdb/lib/adapters/node/DataFile.js", "../../node_modules/lowdb/lib/adapters/node/JSONFile.js", "../src/lib/session-data-manager.ts", "../src/types/monitoring.ts"], - "sourcesContent": ["/**\n * Simple logger utility.\n *\n * All log output is written to stderr. In stdio transport mode, stdout is\n * reserved exclusively for the MCP JSON-RPC protocol \u2014 any non-protocol\n * bytes on stdout would corrupt the message stream.\n */\nexport const logger = {\n info: (message: string, ...args: unknown[]) => {\n console.error(`[INFO] ${new Date().toISOString()} ${message}`, ...args);\n },\n error: (message: string, ...args: unknown[]) => {\n console.error(`[ERROR] ${new Date().toISOString()} ${message}`, ...args);\n },\n warn: (message: string, ...args: unknown[]) => {\n console.error(`[WARN] ${new Date().toISOString()} ${message}`, ...args);\n },\n debug: (message: string, ...args: unknown[]) => {\n if (process.env.DEBUG) {\n console.error(`[DEBUG] ${new Date().toISOString()} ${message}`, ...args);\n }\n },\n};\n", "/**\n * Configuration types for CodeQL background server processes.\n *\n * CodeQL provides three background server types:\n * 1. language-server \u2013 LSP-based QL validation (JSON-RPC over stdio)\n * 2. query-server2 \u2013 Query evaluation (custom protocol over stdio)\n * 3. cli-server \u2013 JVM reuse for CLI commands (custom protocol over stdio)\n *\n * Each server type has its own configuration options, but they share common\n * settings like searchPath and commonCaches.\n */\n\nimport { createHash } from 'crypto';\n\n/**\n * Server types supported by CodeQL.\n */\nexport type CodeQLServerType = 'cli' | 'language' | 'query';\n\n/**\n * Common configuration shared across all server types.\n */\nexport interface BaseServerConfig {\n /** Path to QL packs (like `codeql query compile --search-path`). */\n searchPath?: string;\n /** Location for cached data (compilation plans, downloaded packs). */\n commonCaches?: string;\n /** Directory for detailed logs. */\n logdir?: string;\n}\n\n/**\n * Configuration for the CodeQL Language Server.\n */\nexport interface LanguageServerConfig extends BaseServerConfig {\n /** Error checking mode. Default: ON_CHANGE */\n checkErrors?: 'EXPLICIT' | 'ON_CHANGE';\n /** Log level for the language server. */\n loglevel?: 'ALL' | 'DEBUG' | 'ERROR' | 'INFO' | 'OFF' | 'TRACE' | 'WARN';\n /** Single-threaded execution. */\n synchronous?: boolean;\n /** Verbosity level for progress. */\n verbosity?: 'errors' | 'progress' | 'progress+' | 'progress++' | 'progress+++' | 'warnings';\n}\n\n/**\n * Configuration for the CodeQL Query Server (query-server2).\n */\nexport interface QueryServerConfig extends BaseServerConfig {\n /** Thread count. 0 = one per core, -N = leave N cores free. */\n threads?: number;\n /** Query evaluation timeout in seconds. */\n timeout?: number;\n /** Maximum disk cache size in MB for intermediate results. */\n maxDiskCache?: number;\n /** Path for structured evaluator performance logs. */\n evaluatorLog?: string;\n /** Include tuple counts in evaluation logs. */\n tupleCounting?: boolean;\n /** Enable debug mode. */\n debug?: boolean;\n}\n\n/**\n * Configuration for the CodeQL CLI Server.\n */\nexport interface CLIServerConfig extends BaseServerConfig {\n // cli-server has fewer options \u2014 just commonCaches and logdir.\n}\n\n/**\n * Union of all server configurations (discriminated by usage context).\n */\nexport type ServerConfig = CLIServerConfig | LanguageServerConfig | QueryServerConfig;\n\n/**\n * Compute a deterministic hash for a server configuration.\n * Used to detect configuration changes that require a server restart.\n *\n * @param type - The server type.\n * @param config - The server configuration.\n * @returns A hex-encoded SHA-256 hash of the canonical JSON representation.\n */\nexport function computeConfigHash(type: CodeQLServerType, config: ServerConfig): string {\n // Deep-sort all keys to ensure deterministic serialization regardless of\n // property insertion order.\n const sortKeys = (_key: string, value: unknown): unknown => {\n if (value && typeof value === 'object' && !Array.isArray(value)) {\n const sorted: Record = {};\n for (const k of Object.keys(value as Record).sort()) {\n sorted[k] = (value as Record)[k];\n }\n return sorted;\n }\n return value;\n };\n const canonical = JSON.stringify({ config, type }, sortKeys);\n return createHash('sha256').update(canonical).digest('hex');\n}\n\n/**\n * Build command-line arguments for a language server from its configuration.\n */\nexport function buildLanguageServerArgs(config: LanguageServerConfig): string[] {\n const args: string[] = [\n 'execute', 'language-server',\n `--check-errors=${config.checkErrors ?? 'ON_CHANGE'}`,\n ];\n\n if (config.searchPath) {\n args.push(`--search-path=${config.searchPath}`);\n }\n if (config.commonCaches) {\n args.push(`--common-caches=${config.commonCaches}`);\n }\n if (config.logdir) {\n args.push(`--logdir=${config.logdir}`);\n }\n if (config.loglevel) {\n args.push(`--loglevel=${config.loglevel}`);\n }\n if (config.synchronous) {\n args.push('--synchronous');\n }\n if (config.verbosity) {\n args.push(`--verbosity=${config.verbosity}`);\n }\n\n return args;\n}\n\n/**\n * Build command-line arguments for a query server from its configuration.\n */\nexport function buildQueryServerArgs(config: QueryServerConfig): string[] {\n const args: string[] = [\n 'execute', 'query-server2',\n ];\n\n if (config.searchPath) {\n args.push(`--search-path=${config.searchPath}`);\n }\n if (config.commonCaches) {\n args.push(`--common-caches=${config.commonCaches}`);\n }\n if (config.logdir) {\n args.push(`--logdir=${config.logdir}`);\n }\n if (config.threads !== undefined) {\n args.push(`--threads=${config.threads}`);\n }\n if (config.timeout !== undefined) {\n args.push(`--timeout=${config.timeout}`);\n }\n if (config.maxDiskCache !== undefined) {\n args.push(`--max-disk-cache=${config.maxDiskCache}`);\n }\n if (config.evaluatorLog) {\n args.push(`--evaluator-log=${config.evaluatorLog}`);\n }\n if (config.debug) {\n args.push('--debug');\n args.push('--tuple-counting');\n } else if (config.tupleCounting) {\n args.push('--tuple-counting');\n }\n\n return args;\n}\n\n/**\n * Build command-line arguments for a CLI server from its configuration.\n */\nexport function buildCLIServerArgs(config: CLIServerConfig): string[] {\n const args: string[] = [\n 'execute', 'cli-server',\n ];\n\n if (config.commonCaches) {\n args.push(`--common-caches=${config.commonCaches}`);\n }\n if (config.logdir) {\n args.push(`--logdir=${config.logdir}`);\n }\n\n return args;\n}\n", "/**\n * Utilities for resolving filesystem paths relative to the server package root.\n *\n * The server can run from three different directory layouts:\n *\n * 1. **Source** (dev): `server/src/lib/` \u2192 packageRoot = `server/`\n * 2. **Bundle in monorepo** (dev/CI): `server/dist/` \u2192 packageRoot = `server/`\n * 3. **Bundle via npm** (production): `/dist/` \u2192 packageRoot = `/`\n *\n * In all three cases, the bundled QL tool query packs live at\n * `/ql//tools/src/`.\n *\n * The \"workspace root\" (monorepo root) is one level above packageRoot when\n * running from the monorepo checkout, and the packageRoot itself when running\n * from an npm install (no parent monorepo).\n */\n\nimport { dirname, resolve } from 'path';\nimport { existsSync, readFileSync } from 'fs';\nimport { fileURLToPath } from 'url';\n\nconst __filename = fileURLToPath(import.meta.url);\nconst __dirname = dirname(__filename);\n\n/**\n * Detect whether the current __dirname looks like source code (`src/lib` or\n * `src/utils`) vs a bundled flat output directory (`dist/`).\n *\n * Uses a tail-of-path check so that unrelated `/src/` segments earlier in the\n * install path (e.g. `~/src/project/node_modules/.../dist`) don't cause a\n * false positive.\n */\nfunction isRunningFromSource(dir: string): boolean {\n const normalized = dir.replace(/\\\\/g, '/');\n return /\\/src(\\/[^/]+)?$/.test(normalized);\n}\n\n/**\n * Get the server package root directory.\n *\n * - From source (`server/src/utils/`): up 2 levels \u2192 `server/`\n * - From bundle (`server/dist/` or `/dist/`): up 1 level \u2192 package root\n */\nexport function getPackageRootDir(currentDir: string = __dirname): string {\n return isRunningFromSource(currentDir)\n ? resolve(currentDir, '..', '..') // src/utils \u2192 server/\n : resolve(currentDir, '..'); // dist/ \u2192 package root\n}\n\n/**\n * Get the workspace root directory (monorepo root when applicable).\n *\n * If a `package.json` with `workspaces` exists one level above the package\n * root, we're in a monorepo and that parent is the workspace root. Otherwise,\n * the packageRoot itself is the workspace root (npm install scenario).\n */\nexport function getWorkspaceRootDir(packageRoot?: string): string {\n const pkgRoot = packageRoot ?? getPackageRootDir();\n const parentDir = resolve(pkgRoot, '..');\n\n // In the monorepo, the parent directory contains a package.json with workspaces\n try {\n const parentPkgPath = resolve(parentDir, 'package.json');\n if (existsSync(parentPkgPath)) {\n const parentPkg = JSON.parse(readFileSync(parentPkgPath, 'utf8'));\n if (parentPkg.workspaces) {\n return parentDir;\n }\n }\n } catch {\n // Not in a monorepo \u2014 fall through\n }\n\n return pkgRoot;\n}\n\n/**\n * Resolve the path to a tool query pack's source directory.\n *\n * @param language - CodeQL language identifier (e.g., \"javascript\", \"cpp\")\n * @param packageRoot - Override the package root (for testing)\n * @returns Absolute path to `ql//tools/src/`\n */\nexport function resolveToolQueryPackPath(language: string, packageRoot?: string): string {\n const pkgRoot = packageRoot ?? getPackageRootDir();\n return resolve(pkgRoot, 'ql', language, 'tools', 'src');\n}\n\n/**\n * Read the package version from the nearest package.json.\n *\n * Cached at first call so the file is read at most once per process.\n */\nlet _cachedVersion: string | undefined;\nexport function getPackageVersion(): string {\n if (_cachedVersion !== undefined) return _cachedVersion;\n try {\n const pkgPath = resolve(getPackageRootDir(), 'package.json');\n const pkg = JSON.parse(readFileSync(pkgPath, 'utf8'));\n _cachedVersion = pkg.version ?? '0.0.0';\n } catch {\n _cachedVersion = '0.0.0';\n }\n return _cachedVersion as string;\n}\n\n/**\n * Get the effective workspace directory for resolving user-supplied relative\n * paths (test directories, database paths, pack dirs, etc.).\n *\n * In a monorepo checkout the workspace root is the monorepo parent. In an\n * npm-installed layout, `workspaceRootDir` falls back to `packageRootDir`\n * which may be read-only and is not the user's project. In that case we\n * fall back to `process.cwd()` so that relative paths resolve against the\n * directory the user actually invoked the server from.\n *\n * Override with `CODEQL_MCP_WORKSPACE` for deterministic behavior.\n */\nexport function getUserWorkspaceDir(): string {\n if (process.env.CODEQL_MCP_WORKSPACE) {\n return process.env.CODEQL_MCP_WORKSPACE;\n }\n // When workspaceRootDir === packageRootDir we are NOT in a monorepo\n // (npm-installed), so fall back to process.cwd().\n if (workspaceRootDir === packageRootDir) {\n return process.cwd();\n }\n return workspaceRootDir;\n}\n\n// Pre-computed values for use throughout the server\nexport const packageRootDir = getPackageRootDir();\nexport const workspaceRootDir = getWorkspaceRootDir(packageRootDir);\n", "/**\n * Secure project-local temporary directory utilities.\n *\n * All temporary files are created under `/.tmp/` which is\n * `.gitignore`d. This avoids writing to the OS temp directory\n * (`os.tmpdir()` / `/tmp`), which is world-readable and triggers\n * CWE-377 / CWE-378 (js/insecure-temporary-file).\n */\n\nimport { mkdirSync, mkdtempSync } from 'fs';\nimport { isAbsolute, join, resolve } from 'path';\nimport { getPackageRootDir } from './package-paths';\n\n/**\n * Base directory for all project-local temporary data.\n *\n * Resolution order:\n * 1. `CODEQL_MCP_TMP_DIR` environment variable \u2014 for read-only package root\n * scenarios (e.g., npm global installs where the package directory is not\n * writable). Relative paths are resolved against process.cwd().\n * 2. `/.tmp` \u2014 default; excluded from version control.\n */\nconst PROJECT_TMP_BASE = process.env.CODEQL_MCP_TMP_DIR\n ? (isAbsolute(process.env.CODEQL_MCP_TMP_DIR) \n ? process.env.CODEQL_MCP_TMP_DIR \n : resolve(process.cwd(), process.env.CODEQL_MCP_TMP_DIR))\n : join(getPackageRootDir(), '.tmp');\n\n/**\n * Return the project-local `.tmp` base directory, creating it if needed.\n */\nexport function getProjectTmpBase(): string {\n mkdirSync(PROJECT_TMP_BASE, { recursive: true });\n return PROJECT_TMP_BASE;\n}\n\n/**\n * Create a unique temporary directory under the project `.tmp` root.\n *\n * Works identically to `fs.mkdtempSync(os.tmpdir(), prefix)` but is\n * scoped to the repository.\n *\n * @param prefix - Directory name prefix (e.g. `'codeql-external-'`).\n * @returns Absolute path to the newly created directory.\n */\nexport function createProjectTempDir(prefix: string): string {\n const base = getProjectTmpBase();\n return mkdtempSync(join(base, prefix));\n}\n\n/**\n * Return a deterministic subdirectory under `.tmp/`, creating it\n * if it does not already exist.\n *\n * Useful for well-known scratch areas such as `query-logs` or `quickeval`.\n *\n * @param name - Subdirectory name (e.g. `'query-logs'`).\n * @returns Absolute path to the subdirectory.\n */\nexport function getProjectTmpDir(name: string): string {\n const dir = join(getProjectTmpBase(), name);\n mkdirSync(dir, { recursive: true });\n return dir;\n}\n", "/**\n * Utility for waiting until a spawned child process is ready.\n *\n * CodeQL background servers (cli-server, query-server2, language-server) run\n * on the JVM and emit stderr log output once the JVM has initialised. Rather\n * than sleeping for a hard-coded duration \u2014 which is fragile on both fast and\n * slow machines \u2014 this helper resolves as soon as the first stderr output\n * arrives (indicating the JVM is alive), or when the maximum timeout expires.\n * It also rejects immediately if the process exits or errors before becoming\n * ready, giving callers a clear error instead of a silent hang.\n */\n\nimport { ChildProcess } from 'child_process';\nimport { clearTimeout, setTimeout } from 'timers';\nimport { logger } from './logger';\n\n/** Default maximum wait for a CodeQL server to become ready (30 s). */\nconst DEFAULT_READY_TIMEOUT_MS = 30_000;\n\n/**\n * Options for {@link waitForProcessReady}.\n */\nexport interface ProcessReadyOptions {\n /**\n * Maximum time in milliseconds to wait for the process to emit its first\n * stderr output. If the timeout is reached without a signal the promise\n * still resolves (best-effort) so the caller can attempt communication.\n *\n * Default: 30 000 ms.\n */\n timeoutMs?: number;\n}\n\n/**\n * Wait until a child process signals readiness.\n *\n * \"Ready\" is defined as any of:\n * 1. The process emits data on **stderr** (JVM startup log line).\n * 2. The process emits data on **stdout** (initial protocol message).\n * 3. The maximum timeout elapses (best-effort resolve).\n *\n * The promise **rejects** if the process emits an `error` event or exits\n * before any of the above conditions are met.\n *\n * @param child - The spawned child process.\n * @param name - A human-readable label for log messages.\n * @param opts - Optional configuration.\n */\nexport function waitForProcessReady(\n child: ChildProcess,\n name: string,\n opts?: ProcessReadyOptions,\n): Promise {\n const timeoutMs = opts?.timeoutMs ?? DEFAULT_READY_TIMEOUT_MS;\n\n return new Promise((resolve, reject) => {\n let settled = false;\n\n const cleanup = () => {\n settled = true;\n child.stderr?.removeListener('data', onStderr);\n child.stdout?.removeListener('data', onStdout);\n child.removeListener('error', onError);\n child.removeListener('exit', onExit);\n clearTimeout(timer);\n };\n\n const onStderr = () => {\n if (settled) return;\n logger.debug(`${name}: ready (stderr output detected)`);\n cleanup();\n resolve();\n };\n\n const onStdout = () => {\n if (settled) return;\n logger.debug(`${name}: ready (stdout output detected)`);\n cleanup();\n resolve();\n };\n\n const onError = (error: Error) => {\n if (settled) return;\n cleanup();\n reject(new Error(`${name} failed to start: ${error.message}`));\n };\n\n const onExit = (code: number | null) => {\n if (settled) return;\n cleanup();\n reject(new Error(`${name} exited before becoming ready (code: ${code})`));\n };\n\n const timer = setTimeout(() => {\n if (settled) return;\n logger.warn(`${name}: readiness timeout (${timeoutMs} ms) \u2014 proceeding anyway`);\n cleanup();\n resolve(); // best-effort: let the caller attempt communication\n }, timeoutMs);\n\n child.stderr?.on('data', onStderr);\n child.stdout?.on('data', onStdout);\n child.on('error', onError);\n child.on('exit', onExit);\n\n // If the process was dead before we even attached listeners, reject now\n if (child.killed || child.exitCode !== null) {\n cleanup();\n reject(new Error(`${name} is not running (exitCode: ${child.exitCode})`));\n }\n });\n}\n", "/**\n * CodeQL Language Server manager for LSP communication\n * Manages the lifecycle and communication with the CodeQL language server process\n */\n\nimport { spawn, ChildProcess } from 'child_process';\nimport { EventEmitter } from 'events';\nimport { setTimeout, clearTimeout } from 'timers';\nimport { pathToFileURL } from 'url';\nimport { delimiter, join } from 'path';\nimport { logger } from '../utils/logger';\nimport { getPackageVersion } from '../utils/package-paths';\nimport { getProjectTmpDir } from '../utils/temp-dir';\nimport { getResolvedCodeQLDir } from './cli-executor';\nimport { waitForProcessReady } from '../utils/process-ready';\n\nexport interface LSPMessage {\n jsonrpc: '2.0';\n id?: number | string;\n method: string;\n params?: unknown;\n result?: unknown;\n error?: {\n code: number;\n message: string;\n data?: unknown;\n };\n}\n\nexport interface Diagnostic {\n range: {\n start: { line: number; character: number };\n end: { line: number; character: number };\n };\n severity: number; // 1=Error, 2=Warning, 3=Information, 4=Hint\n source?: string;\n message: string;\n code?: string | number;\n}\n\nexport interface PublishDiagnosticsParams {\n uri: string;\n diagnostics: Diagnostic[];\n}\n\nexport interface LanguageServerOptions {\n searchPath?: string;\n logdir?: string;\n loglevel?: 'ALL' | 'DEBUG' | 'ERROR' | 'INFO' | 'OFF' | 'TRACE' | 'WARN';\n synchronous?: boolean;\n verbosity?: 'errors' | 'progress' | 'progress+' | 'progress++' | 'progress+++' | 'warnings';\n}\n\n/**\n * Position in a text document (0-based line and character).\n */\nexport interface LSPPosition {\n character: number;\n line: number;\n}\n\n/**\n * A range in a text document.\n */\nexport interface LSPRange {\n end: LSPPosition;\n start: LSPPosition;\n}\n\n/**\n * A location in a resource (file URI + range).\n */\nexport interface LSPLocation {\n range: LSPRange;\n uri: string;\n}\n\n/**\n * Identifies a text document by its URI.\n */\nexport interface TextDocumentIdentifier {\n uri: string;\n}\n\n/**\n * A text document position (document + position within it).\n */\nexport interface TextDocumentPositionParams {\n position: LSPPosition;\n textDocument: TextDocumentIdentifier;\n}\n\n/**\n * A completion item returned by the language server.\n */\nexport interface CompletionItem {\n detail?: string;\n documentation?: string | { kind: string; value: string };\n insertText?: string;\n kind?: number;\n label: string;\n sortText?: string;\n}\n\nexport class CodeQLLanguageServer extends EventEmitter {\n private server: ChildProcess | null = null;\n private messageId = 1;\n private pendingResponses = new Map void; reject: (_error: Error) => void }>();\n private isInitialized = false;\n private currentWorkspaceUri: string | undefined;\n private messageBuffer = '';\n\n constructor(private _options: LanguageServerOptions = {}) {\n super();\n }\n\n async start(): Promise {\n if (this.server) {\n throw new Error('Language server is already running');\n }\n\n logger.info('Starting CodeQL Language Server...');\n\n const args = [\n 'execute', 'language-server',\n '--check-errors=ON_CHANGE'\n ];\n\n // Add optional arguments\n if (this._options.searchPath) {\n args.push(`--search-path=${this._options.searchPath}`);\n }\n if (this._options.logdir) {\n args.push(`--logdir=${this._options.logdir}`);\n }\n if (this._options.loglevel) {\n args.push(`--loglevel=${this._options.loglevel}`);\n }\n if (this._options.synchronous) {\n args.push('--synchronous');\n }\n if (this._options.verbosity) {\n args.push(`--verbosity=${this._options.verbosity}`);\n }\n\n // Build environment with CODEQL_PATH directory prepended to PATH\n // (mirrors the approach in cli-executor.ts getSafeEnvironment).\n const spawnEnv = { ...process.env };\n const codeqlDir = getResolvedCodeQLDir();\n if (codeqlDir && spawnEnv.PATH) {\n spawnEnv.PATH = `${codeqlDir}${delimiter}${spawnEnv.PATH}`;\n } else if (codeqlDir) {\n spawnEnv.PATH = codeqlDir;\n }\n\n this.server = spawn('codeql', args, {\n stdio: ['pipe', 'pipe', 'pipe'],\n env: spawnEnv\n });\n\n this.server.stderr?.on('data', (data) => {\n logger.debug('CodeQL LS stderr:', data.toString());\n });\n\n this.server.stdout?.on('data', (data) => {\n this.handleStdout(data);\n });\n\n this.server.on('error', (error) => {\n logger.error('CodeQL Language Server error:', error);\n this.emit('error', error);\n });\n\n this.server.on('exit', (code) => {\n logger.info('CodeQL Language Server exited with code:', code);\n this.server = null;\n this.isInitialized = false;\n this.emit('exit', code);\n });\n\n // Wait for the JVM to initialise (resolves on first stderr/stdout output)\n await waitForProcessReady(this.server, 'CodeQL Language Server');\n }\n\n private handleStdout(data: Buffer): void {\n this.messageBuffer += data.toString();\n \n let headerEnd = this.messageBuffer.indexOf('\\r\\n\\r\\n');\n while (headerEnd !== -1) {\n const header = this.messageBuffer.substring(0, headerEnd);\n const contentLengthMatch = header.match(/Content-Length: (\\d+)/);\n \n if (contentLengthMatch) {\n const contentLength = parseInt(contentLengthMatch[1]);\n const messageStart = headerEnd + 4;\n const messageEnd = messageStart + contentLength;\n \n if (this.messageBuffer.length >= messageEnd) {\n const messageContent = this.messageBuffer.substring(messageStart, messageEnd);\n this.messageBuffer = this.messageBuffer.substring(messageEnd);\n \n try {\n const message: LSPMessage = JSON.parse(messageContent);\n this.handleMessage(message);\n } catch (error) {\n logger.error('Failed to parse LSP message:', error, messageContent);\n }\n \n headerEnd = this.messageBuffer.indexOf('\\r\\n\\r\\n');\n } else {\n break;\n }\n } else {\n logger.error('Invalid LSP header:', header);\n this.messageBuffer = '';\n break;\n }\n }\n }\n\n private handleMessage(message: LSPMessage): void {\n logger.debug('Received LSP message:', message);\n\n // Handle responses to our requests\n if (message.id !== undefined && this.pendingResponses.has(Number(message.id))) {\n const pending = this.pendingResponses.get(Number(message.id))!;\n this.pendingResponses.delete(Number(message.id));\n \n if (message.error) {\n pending.reject(new Error(`LSP Error: ${message.error.message}`));\n } else {\n pending.resolve(message.result);\n }\n return;\n }\n\n // Handle notifications from server\n if (message.method === 'textDocument/publishDiagnostics') {\n this.emit('diagnostics', message.params as PublishDiagnosticsParams);\n }\n }\n\n private sendMessage(message: LSPMessage): void {\n if (!this.server?.stdin) {\n throw new Error('Language server is not running');\n }\n\n const messageStr = JSON.stringify(message);\n const contentLength = Buffer.byteLength(messageStr, 'utf8');\n const header = `Content-Length: ${contentLength}\\r\\n\\r\\n`;\n const fullMessage = header + messageStr;\n\n logger.debug('Sending LSP message:', fullMessage);\n this.server.stdin.write(fullMessage);\n }\n\n private sendRequest(method: string, params?: unknown): Promise {\n const id = this.messageId++;\n const message: LSPMessage = {\n jsonrpc: '2.0',\n id,\n method,\n params\n };\n\n return new Promise((resolve, reject) => {\n // Wrap resolve/reject to clear the timer when the promise settles.\n const timer = setTimeout(() => {\n if (this.pendingResponses.has(id)) {\n this.pendingResponses.delete(id);\n reject(new Error(`LSP request timeout for method: ${method}`));\n }\n }, 60_000); // 60 second timeout (Windows CI cold JVM can exceed 30s)\n\n this.pendingResponses.set(id, {\n reject: (err: Error) => { clearTimeout(timer); reject(err); },\n resolve: (val: unknown) => { clearTimeout(timer); resolve(val); },\n });\n this.sendMessage(message);\n });\n }\n\n private sendNotification(method: string, params?: unknown): void {\n const message: LSPMessage = {\n jsonrpc: '2.0',\n method,\n params\n };\n this.sendMessage(message);\n }\n\n /**\n * Initialize the language server with an optional workspace URI.\n *\n * If the server is already initialized with a different workspace, a\n * `workspace/didChangeWorkspaceFolders` notification is sent to update\n * the workspace context instead of requiring a full restart.\n */\n async initialize(workspaceUri?: string): Promise {\n if (this.isInitialized) {\n // If workspace changed, notify the server\n if (workspaceUri && workspaceUri !== this.currentWorkspaceUri) {\n await this.updateWorkspace(workspaceUri);\n }\n return;\n }\n\n logger.info('Initializing CodeQL Language Server...');\n\n const initParams = {\n processId: process.pid,\n clientInfo: {\n name: 'codeql-development-mcp-server',\n version: getPackageVersion()\n },\n capabilities: {\n textDocument: {\n completion: { completionItem: { snippetSupport: false } },\n definition: {},\n publishDiagnostics: {},\n references: {},\n synchronization: {\n didClose: true,\n didChange: true,\n didOpen: true,\n },\n },\n workspace: {\n workspaceFolders: true,\n },\n }\n };\n\n if (workspaceUri) {\n (initParams as unknown as { workspaceFolders: unknown[] }).workspaceFolders = [{\n uri: workspaceUri,\n name: 'codeql-workspace'\n }];\n }\n\n await this.sendRequest('initialize', initParams);\n this.sendNotification('initialized', {});\n\n this.currentWorkspaceUri = workspaceUri;\n this.isInitialized = true;\n logger.info('CodeQL Language Server initialized successfully');\n }\n\n /**\n * Update the workspace folders on a running, initialized server.\n */\n private async updateWorkspace(newUri: string): Promise {\n logger.info(`Updating workspace from ${this.currentWorkspaceUri} to ${newUri}`);\n\n const removed = this.currentWorkspaceUri\n ? [{ uri: this.currentWorkspaceUri, name: 'codeql-workspace' }]\n : [];\n\n this.sendNotification('workspace/didChangeWorkspaceFolders', {\n event: {\n added: [{ uri: newUri, name: 'codeql-workspace' }],\n removed,\n },\n });\n\n this.currentWorkspaceUri = newUri;\n }\n\n /**\n * Get the current workspace URI.\n */\n getWorkspaceUri(): string | undefined {\n return this.currentWorkspaceUri;\n }\n\n async evaluateQL(qlCode: string, uri?: string): Promise {\n if (!this.isInitialized) {\n throw new Error('Language server is not initialized');\n }\n\n // Default to a project-local virtual URI rather than /tmp\n const documentUri = uri || pathToFileURL(join(getProjectTmpDir('lsp-eval'), 'eval.ql')).href;\n\n return new Promise((resolve, reject) => {\n let diagnosticsReceived = false;\n const timeout = setTimeout(() => {\n if (!diagnosticsReceived) {\n this.removeListener('diagnostics', diagnosticsHandler);\n reject(new Error('Timeout waiting for diagnostics'));\n }\n }, 90_000); // 90s \u2014 first call triggers JVM start + compilation; Windows CI is slow\n\n // Listen for diagnostics\n const diagnosticsHandler = (params: PublishDiagnosticsParams) => {\n if (params.uri === documentUri) {\n diagnosticsReceived = true;\n clearTimeout(timeout);\n this.removeListener('diagnostics', diagnosticsHandler);\n\n // Close the document\n this.sendNotification('textDocument/didClose', {\n textDocument: { uri: documentUri }\n });\n\n resolve(params.diagnostics);\n }\n };\n\n this.on('diagnostics', diagnosticsHandler);\n\n // Open the document with the QL code\n this.sendNotification('textDocument/didOpen', {\n textDocument: {\n uri: documentUri,\n languageId: 'ql',\n version: 1,\n text: qlCode\n }\n });\n });\n }\n\n // ---- LSP feature methods (issue #1) ----\n\n /**\n * Get code completions at a position in a document.\n */\n async getCompletions(params: TextDocumentPositionParams): Promise {\n if (!this.isInitialized) {\n throw new Error('Language server is not initialized');\n }\n if (!this.isRunning()) {\n throw new Error('Language server process is not running');\n }\n const result = await this.sendRequest('textDocument/completion', params);\n // The result may be a CompletionList or CompletionItem[]\n if (result && typeof result === 'object' && 'items' in (result as object)) {\n return (result as { items: CompletionItem[] }).items;\n }\n return (result as CompletionItem[]) || [];\n }\n\n /**\n * Find the definition(s) of a symbol at a position.\n */\n async getDefinition(params: TextDocumentPositionParams): Promise {\n if (!this.isInitialized) {\n throw new Error('Language server is not initialized');\n }\n if (!this.isRunning()) {\n throw new Error('Language server process is not running');\n }\n const result = await this.sendRequest('textDocument/definition', params);\n return this.normalizeLocations(result);\n }\n\n /**\n * Find all references to a symbol at a position.\n */\n async getReferences(params: TextDocumentPositionParams & { context?: { includeDeclaration: boolean } }): Promise {\n if (!this.isInitialized) {\n throw new Error('Language server is not initialized');\n }\n if (!this.isRunning()) {\n throw new Error('Language server process is not running');\n }\n const result = await this.sendRequest('textDocument/references', {\n ...params,\n context: params.context ?? { includeDeclaration: true },\n });\n return this.normalizeLocations(result);\n }\n\n /**\n * Open a text document in the language server.\n * The document must be opened before requesting completions, definitions, etc.\n */\n openDocument(uri: string, text: string, languageId = 'ql', version = 1): void {\n if (!this.isInitialized) {\n throw new Error('Language server is not initialized');\n }\n this.sendNotification('textDocument/didOpen', {\n textDocument: { uri, languageId, version, text },\n });\n }\n\n /**\n * Close a text document in the language server.\n */\n closeDocument(uri: string): void {\n if (!this.isInitialized) {\n throw new Error('Language server is not initialized');\n }\n this.sendNotification('textDocument/didClose', {\n textDocument: { uri },\n });\n }\n\n /**\n * Normalize a definition/references/implementation result to Location[].\n * The LSP spec allows Location | Location[] | LocationLink[].\n */\n private normalizeLocations(result: unknown): LSPLocation[] {\n if (!result) return [];\n if (Array.isArray(result)) {\n return result.map((item) => {\n // LocationLink has targetUri/targetRange\n if ('targetUri' in item) {\n return { uri: item.targetUri, range: item.targetRange } as LSPLocation;\n }\n return item as LSPLocation;\n });\n }\n // Single Location\n if (typeof result === 'object' && 'uri' in (result as object)) {\n return [result as LSPLocation];\n }\n return [];\n }\n\n async shutdown(): Promise {\n if (!this.server) {\n return;\n }\n\n logger.info('Shutting down CodeQL Language Server...');\n\n try {\n await this.sendRequest('shutdown', {});\n if (this.server) {\n this.sendNotification('exit', {});\n }\n } catch (error) {\n logger.warn('Error during graceful shutdown:', error);\n }\n\n // Force kill if needed\n await new Promise((resolve) => {\n const timer = setTimeout(() => {\n if (this.server) {\n this.server.kill('SIGTERM');\n }\n resolve();\n }, 1000);\n\n if (this.server) {\n this.server.once('exit', () => {\n clearTimeout(timer);\n this.server = null;\n resolve();\n });\n } else {\n clearTimeout(timer);\n resolve();\n }\n });\n\n this.isInitialized = false;\n }\n\n isRunning(): boolean {\n return this.server !== null && !this.server.killed;\n }\n}", "/**\n * CodeQL Query Server (query-server2) client.\n *\n * Manages a long-lived `codeql execute query-server2` process that evaluates\n * queries using a custom JSON-RPC protocol over stdio. Reusing the server\n * avoids repeated JVM startup for each query evaluation.\n *\n * Protocol: The query-server2 uses JSON-RPC with Content-Length headers\n * (same framing as LSP) over stdin/stdout.\n */\n\nimport { ChildProcess, spawn } from 'child_process';\nimport { delimiter } from 'path';\nimport { EventEmitter } from 'events';\nimport { clearTimeout, setTimeout } from 'timers';\nimport { buildQueryServerArgs, QueryServerConfig } from './server-config';\nimport { getResolvedCodeQLDir } from './cli-executor';\nimport { logger } from '../utils/logger';\nimport { waitForProcessReady } from '../utils/process-ready';\n\n/**\n * A pending request awaiting a response from the query server.\n */\ninterface PendingRequest {\n reject: (_error: Error) => void;\n resolve: (_value: unknown) => void;\n}\n\n/**\n * Client for the CodeQL query-server2 process.\n *\n * Spawns `codeql execute query-server2` and communicates over stdin/stdout\n * using JSON-RPC with Content-Length framing.\n */\nexport class CodeQLQueryServer extends EventEmitter {\n private messageBuffer = '';\n private messageId = 1;\n private pendingRequests = new Map();\n private process: ChildProcess | null = null;\n private readonly config: QueryServerConfig;\n\n constructor(config: QueryServerConfig) {\n super();\n this.config = config;\n }\n\n /**\n * Start the query-server2 process.\n */\n async start(): Promise {\n if (this.process) {\n throw new Error('Query server is already running');\n }\n\n logger.info('Starting CodeQL Query Server (query-server2)...');\n\n const args = buildQueryServerArgs(this.config);\n\n // Build environment with CODEQL_PATH directory prepended to PATH\n const spawnEnv = { ...process.env };\n const codeqlDir = getResolvedCodeQLDir();\n if (codeqlDir && spawnEnv.PATH) {\n spawnEnv.PATH = `${codeqlDir}${delimiter}${spawnEnv.PATH}`;\n } else if (codeqlDir) {\n spawnEnv.PATH = codeqlDir;\n }\n\n this.process = spawn('codeql', args, {\n stdio: ['pipe', 'pipe', 'pipe'],\n env: spawnEnv,\n });\n\n this.process.stderr?.on('data', (data: Buffer) => {\n logger.debug('QueryServer2 stderr:', data.toString());\n });\n\n this.process.stdout?.on('data', (data: Buffer) => {\n this.handleStdout(data);\n });\n\n this.process.on('error', (error: Error) => {\n logger.error('Query server process error:', error);\n this.emit('error', error);\n });\n\n this.process.on('exit', (code: number | null) => {\n logger.info(`Query server exited with code: ${code}`);\n this.rejectAllPending(new Error(`Query server exited with code: ${code}`));\n this.process = null;\n this.emit('exit', code);\n });\n\n // Wait for the JVM to initialise (resolves on first stderr/stdout output)\n await waitForProcessReady(this.process, 'CodeQL Query Server');\n logger.info('CodeQL Query Server started');\n }\n\n /**\n * Send a request to the query server and await the response.\n *\n * @param method - The JSON-RPC method name.\n * @param params - The method parameters.\n * @param timeoutMs - Request timeout in milliseconds (default: 300000 = 5 min).\n * @returns The result from the server.\n */\n sendRequest(method: string, params?: unknown, timeoutMs = 300_000): Promise {\n const id = this.messageId++;\n const message = {\n id,\n jsonrpc: '2.0' as const,\n method,\n params,\n };\n\n return new Promise((resolve, reject) => {\n this.pendingRequests.set(id, { reject, resolve });\n\n try {\n this.sendRaw(message);\n } catch (error) {\n // Clean up immediately \u2014 sendRaw() failed so no response will arrive.\n this.pendingRequests.delete(id);\n reject(error instanceof Error ? error : new Error(String(error)));\n return;\n }\n\n const timer = setTimeout(() => {\n if (this.pendingRequests.has(id)) {\n this.pendingRequests.delete(id);\n reject(new Error(`Query server request timeout for method: ${method}`));\n }\n }, timeoutMs);\n\n // Clear the timeout when the promise settles\n const originalResolve = resolve;\n const originalReject = reject;\n const wrapped = {\n reject: (err: Error) => { clearTimeout(timer); originalReject(err); },\n resolve: (val: unknown) => { clearTimeout(timer); originalResolve(val); },\n };\n this.pendingRequests.set(id, wrapped);\n });\n }\n\n /**\n * Gracefully shut down the query server.\n */\n async shutdown(): Promise {\n if (!this.process) {\n return;\n }\n\n logger.info('Shutting down CodeQL Query Server...');\n\n try {\n await this.sendRequest('shutdown', {}, 5000);\n } catch (error) {\n logger.warn('Error during query server graceful shutdown:', error);\n }\n\n // Force kill if process lingers\n await new Promise((resolve) => {\n const timer = setTimeout(() => {\n if (this.process) {\n this.process.kill('SIGTERM');\n this.process = null;\n }\n resolve();\n }, 2000);\n\n if (this.process) {\n this.process.once('exit', () => {\n clearTimeout(timer);\n this.process = null;\n resolve();\n });\n } else {\n clearTimeout(timer);\n resolve();\n }\n });\n }\n\n /**\n * Whether the query server process is running.\n */\n isRunning(): boolean {\n return this.process !== null && !this.process.killed;\n }\n\n // ---- private helpers ----\n\n private handleStdout(data: Buffer): void {\n this.messageBuffer += data.toString();\n\n let headerEnd = this.messageBuffer.indexOf('\\r\\n\\r\\n');\n while (headerEnd !== -1) {\n const header = this.messageBuffer.substring(0, headerEnd);\n const contentLengthMatch = header.match(/Content-Length: (\\d+)/);\n\n if (contentLengthMatch) {\n const contentLength = parseInt(contentLengthMatch[1]);\n const messageStart = headerEnd + 4;\n const messageEnd = messageStart + contentLength;\n\n if (this.messageBuffer.length >= messageEnd) {\n const messageContent = this.messageBuffer.substring(messageStart, messageEnd);\n this.messageBuffer = this.messageBuffer.substring(messageEnd);\n\n try {\n const message = JSON.parse(messageContent);\n this.handleMessage(message);\n } catch (error) {\n logger.error('Failed to parse query server message:', error);\n }\n\n headerEnd = this.messageBuffer.indexOf('\\r\\n\\r\\n');\n } else {\n break;\n }\n } else {\n logger.error('Invalid query server header:', header);\n this.messageBuffer = '';\n break;\n }\n }\n }\n\n private handleMessage(message: { error?: { message: string }; id?: number; method?: string; params?: unknown; result?: unknown }): void {\n logger.debug('QueryServer2 message:', message);\n\n // Handle responses\n if (message.id !== undefined && this.pendingRequests.has(Number(message.id))) {\n const pending = this.pendingRequests.get(Number(message.id))!;\n this.pendingRequests.delete(Number(message.id));\n\n if (message.error) {\n pending.reject(new Error(`Query server error: ${message.error.message}`));\n } else {\n pending.resolve(message.result);\n }\n return;\n }\n\n // Handle notifications (progress, etc.)\n if (message.method) {\n this.emit('notification', { method: message.method, params: message.params });\n }\n }\n\n private rejectAllPending(error: Error): void {\n for (const [id, pending] of this.pendingRequests) {\n pending.reject(error);\n this.pendingRequests.delete(id);\n }\n }\n\n private sendRaw(message: object): void {\n if (!this.process?.stdin) {\n throw new Error('Query server is not running');\n }\n\n const body = JSON.stringify(message);\n const contentLength = Buffer.byteLength(body, 'utf8');\n const frame = `Content-Length: ${contentLength}\\r\\n\\r\\n${body}`;\n this.process.stdin.write(frame);\n }\n}\n", "/**\n * CodeQL CLI Server client.\n *\n * Manages a long-lived `codeql execute cli-server` process that executes CLI\n * commands without repeated JVM startup overhead. Commands are serialized as\n * JSON arrays followed by a NUL byte, and responses are NUL-terminated JSON.\n *\n * Inspired by the `CodeQLCliServer` class in github/vscode-codeql.\n */\n\nimport { ChildProcess, spawn } from 'child_process';\nimport { delimiter } from 'path';\nimport { EventEmitter } from 'events';\nimport { clearTimeout, setTimeout } from 'timers';\nimport { buildCLIServerArgs, CLIServerConfig } from './server-config';\nimport { getResolvedCodeQLDir } from './cli-executor';\nimport { logger } from '../utils/logger';\nimport { waitForProcessReady } from '../utils/process-ready';\n\n/**\n * A queued command waiting to be sent to the CLI server.\n */\ninterface QueuedCommand {\n args: string[];\n reject: (_error: Error) => void;\n resolve: (_value: string) => void;\n}\n\n/**\n * Client for the CodeQL CLI Server process.\n *\n * The cli-server uses a simple NUL-delimited protocol:\n * - **Request**: JSON array of command arguments, followed by a NUL byte.\n * - **Response**: command stdout, terminated by a NUL byte on stdout.\n * stderr is forwarded as-is.\n */\nexport class CodeQLCLIServer extends EventEmitter {\n private commandInProgress = false;\n private commandQueue: Array<() => void> = [];\n private readonly config: CLIServerConfig;\n private currentReject: ((_error: Error) => void) | null = null;\n private currentResolve: ((_value: string) => void) | null = null;\n private nullBuffer = Buffer.alloc(1);\n private process: ChildProcess | null = null;\n private stdoutBuffer = '';\n\n constructor(config: CLIServerConfig) {\n super();\n this.config = config;\n }\n\n /**\n * Start the cli-server process.\n */\n async start(): Promise {\n if (this.process) {\n throw new Error('CLI server is already running');\n }\n\n logger.info('Starting CodeQL CLI Server...');\n\n const args = buildCLIServerArgs(this.config);\n\n const spawnEnv = { ...process.env };\n const codeqlDir = getResolvedCodeQLDir();\n if (codeqlDir && spawnEnv.PATH) {\n spawnEnv.PATH = `${codeqlDir}${delimiter}${spawnEnv.PATH}`;\n } else if (codeqlDir) {\n spawnEnv.PATH = codeqlDir;\n }\n\n this.process = spawn('codeql', args, {\n stdio: ['pipe', 'pipe', 'pipe'],\n env: spawnEnv,\n });\n\n this.process.stdout?.on('data', (data: Buffer) => {\n this.handleStdout(data);\n });\n\n this.process.stderr?.on('data', (data: Buffer) => {\n logger.debug('CLIServer stderr:', data.toString());\n });\n\n this.process.on('error', (error: Error) => {\n logger.error('CLI server process error:', error);\n if (this.currentReject) {\n this.currentReject(error);\n this.currentReject = null;\n this.currentResolve = null;\n }\n this.emit('error', error);\n });\n\n this.process.on('exit', (code: number | null) => {\n logger.info(`CLI server exited with code: ${code}`);\n if (this.currentReject) {\n this.currentReject(new Error(`CLI server exited unexpectedly with code: ${code}`));\n this.currentReject = null;\n this.currentResolve = null;\n }\n this.process = null;\n this.emit('exit', code);\n });\n\n // Wait for the JVM to initialise (resolves on first stderr/stdout output)\n await waitForProcessReady(this.process, 'CodeQL CLI Server');\n logger.info('CodeQL CLI Server started');\n }\n\n /**\n * Run a CodeQL CLI command through the persistent server.\n *\n * Commands are serialized and queued; only one command runs at a time.\n *\n * @param args - The full command arguments (e.g. `['resolve', 'qlpacks']`).\n * @returns The stdout output from the command.\n */\n runCommand(args: string[]): Promise {\n return new Promise((resolve, reject) => {\n const execute = () => {\n this.executeCommand({ args, reject, resolve });\n };\n\n if (this.commandInProgress) {\n this.commandQueue.push(execute);\n } else {\n execute();\n }\n });\n }\n\n /**\n * Gracefully shut down the CLI server.\n */\n async shutdown(): Promise {\n if (!this.process) {\n return;\n }\n\n logger.info('Shutting down CodeQL CLI Server...');\n\n try {\n // Send shutdown command\n this.process.stdin?.write(JSON.stringify(['shutdown']), 'utf8');\n this.process.stdin?.write(this.nullBuffer);\n } catch (error) {\n logger.warn('Error during CLI server shutdown request:', error);\n }\n\n // Give it a moment, then force kill\n await new Promise((resolve) => {\n const timer = setTimeout(() => {\n if (this.process) {\n this.process.kill('SIGTERM');\n this.process = null;\n }\n resolve();\n }, 2000);\n\n if (this.process) {\n this.process.once('exit', () => {\n clearTimeout(timer);\n this.process = null;\n resolve();\n });\n } else {\n clearTimeout(timer);\n resolve();\n }\n });\n\n this.commandInProgress = false;\n this.commandQueue = [];\n logger.info('CodeQL CLI Server stopped');\n }\n\n /**\n * Whether the CLI server process is running.\n */\n isRunning(): boolean {\n return this.process !== null && !this.process.killed;\n }\n\n // ---- private helpers ----\n\n private executeCommand(cmd: QueuedCommand): void {\n if (!this.process?.stdin) {\n cmd.reject(new Error('CLI server is not running'));\n return;\n }\n\n this.commandInProgress = true;\n this.currentResolve = cmd.resolve;\n this.currentReject = cmd.reject;\n\n try {\n this.process.stdin.write(JSON.stringify(cmd.args), 'utf8');\n this.process.stdin.write(this.nullBuffer);\n } catch (error) {\n this.commandInProgress = false;\n this.currentResolve = null;\n this.currentReject = null;\n cmd.reject(error instanceof Error ? error : new Error(String(error)));\n this.runNext();\n }\n }\n\n private handleStdout(data: Buffer): void {\n this.stdoutBuffer += data.toString();\n\n // Process all NUL-delimited responses in the buffer\n let nulIndex = this.stdoutBuffer.indexOf('\\0');\n while (nulIndex !== -1) {\n const result = this.stdoutBuffer.substring(0, nulIndex);\n this.stdoutBuffer = this.stdoutBuffer.substring(nulIndex + 1);\n\n if (this.currentResolve) {\n this.currentResolve(result);\n this.currentResolve = null;\n this.currentReject = null;\n }\n\n this.commandInProgress = false;\n this.runNext();\n\n nulIndex = this.stdoutBuffer.indexOf('\\0');\n }\n }\n\n private runNext(): void {\n const next = this.commandQueue.shift();\n if (next) {\n next();\n }\n }\n}\n", "/**\n * CodeQL Server Manager\n *\n * Manages the lifecycle of CodeQL background server processes:\n * - language-server (LSP-based QL validation)\n * - query-server2 (query evaluation)\n * - cli-server (JVM reuse for CLI commands)\n *\n * Servers are keyed by a hash of their configuration. When a caller requests\n * a server with a different configuration, the old server is shut down and a\n * new one is started. Session-specific cache directories provide isolation.\n */\n\nimport { mkdirSync } from 'fs';\nimport { join } from 'path';\nimport { randomUUID } from 'crypto';\nimport {\n CLIServerConfig,\n CodeQLServerType,\n computeConfigHash,\n LanguageServerConfig,\n QueryServerConfig,\n ServerConfig,\n} from './server-config';\nimport { CodeQLLanguageServer } from './language-server';\nimport { CodeQLQueryServer } from './query-server';\nimport { CodeQLCLIServer } from './cli-server';\nimport { getProjectTmpDir } from '../utils/temp-dir';\nimport { logger } from '../utils/logger';\n\n/**\n * Entry in the managed servers map.\n */\ninterface ManagedServer {\n configHash: string;\n server: CodeQLCLIServer | CodeQLLanguageServer | CodeQLQueryServer;\n sessionId: string;\n type: CodeQLServerType;\n}\n\n/**\n * Options for creating a session-specific cache layout.\n */\nexport interface SessionCacheOptions {\n /** Override the session ID (defaults to a random UUID). */\n sessionId?: string;\n}\n\n/**\n * Manages CodeQL background server processes with config-aware caching.\n *\n * Callers should use `getLanguageServer()`, `getQueryServer()`, or\n * `getCLIServer()` to obtain a running server. If the requested\n * configuration differs from the currently running server of that type, the\n * old server is stopped and replaced.\n */\nexport class CodeQLServerManager {\n /** Keyed by `CodeQLServerType` \u2014 at most one per type at a time. */\n private servers = new Map();\n\n /** In-flight `getOrRestart` promises, keyed by server type, to serialize concurrent calls. */\n private pendingStarts = new Map>();\n\n /** The session ID used for cache isolation. */\n private sessionId: string;\n\n /** Root directory for session-specific caches. */\n private sessionCacheDir: string;\n\n constructor(options?: SessionCacheOptions) {\n this.sessionId = options?.sessionId ?? randomUUID();\n this.sessionCacheDir = join(\n getProjectTmpDir('codeql-cache'),\n this.sessionId,\n );\n // Pre-create the cache directory tree\n for (const subdir of ['compilation-cache', 'logs', 'query-cache']) {\n mkdirSync(join(this.sessionCacheDir, subdir), { recursive: true });\n }\n logger.info(`CodeQLServerManager initialized (session: ${this.sessionId})`);\n }\n\n // ---- Public API ----\n\n /**\n * Get the current session ID.\n */\n getSessionId(): string {\n return this.sessionId;\n }\n\n /**\n * Get the session-specific cache directory.\n */\n getCacheDir(): string {\n return this.sessionCacheDir;\n }\n\n /**\n * Return the session-specific log directory.\n */\n getLogDir(): string {\n return join(this.sessionCacheDir, 'logs');\n }\n\n /**\n * Get or create a Language Server with the given configuration.\n *\n * If a language server is already running with the same config it is reused.\n * If the config has changed the old server is shut down first.\n */\n async getLanguageServer(config: LanguageServerConfig): Promise {\n const enriched = this.enrichConfig(config) as LanguageServerConfig;\n return this.getOrRestart('language', enriched, () => {\n // Convert LanguageServerConfig to the LanguageServerOptions the existing class expects\n return new CodeQLLanguageServer({\n loglevel: enriched.loglevel,\n logdir: enriched.logdir,\n searchPath: enriched.searchPath,\n synchronous: enriched.synchronous,\n verbosity: enriched.verbosity,\n });\n }) as Promise;\n }\n\n /**\n * Get or create a Query Server with the given configuration.\n */\n async getQueryServer(config: QueryServerConfig): Promise {\n const enriched = this.enrichConfig(config) as QueryServerConfig;\n return this.getOrRestart('query', enriched, () => {\n return new CodeQLQueryServer(enriched);\n }) as Promise;\n }\n\n /**\n * Get or create a CLI Server with the given configuration.\n */\n async getCLIServer(config: CLIServerConfig): Promise {\n const enriched = this.enrichConfig(config) as CLIServerConfig;\n return this.getOrRestart('cli', enriched, () => {\n return new CodeQLCLIServer(enriched);\n }) as Promise;\n }\n\n /**\n * Shut down a specific server type.\n */\n async shutdownServer(type: CodeQLServerType): Promise {\n const managed = this.servers.get(type);\n if (!managed) return;\n\n logger.info(`Shutting down ${type} server (session: ${managed.sessionId})`);\n await this.stopServer(managed);\n this.servers.delete(type);\n }\n\n /**\n * Shut down all managed servers.\n */\n async shutdownAll(): Promise {\n logger.info(`Shutting down all servers for session: ${this.sessionId}`);\n const shutdownPromises = Array.from(this.servers.entries()).map(\n async ([type, managed]) => {\n try {\n await this.stopServer(managed);\n } catch (error) {\n logger.error(`Error shutting down ${type} server:`, error);\n }\n },\n );\n await Promise.all(shutdownPromises);\n this.servers.clear();\n logger.info('All servers shut down');\n }\n\n /**\n * Check whether a server of the given type is currently running.\n */\n isRunning(type: CodeQLServerType): boolean {\n const managed = this.servers.get(type);\n if (!managed) return false;\n return managed.server.isRunning();\n }\n\n /**\n * Get status information for all managed servers.\n */\n getStatus(): Record {\n const status: Record = {\n cli: null,\n language: null,\n query: null,\n };\n for (const [type, managed] of this.servers) {\n status[type] = {\n configHash: managed.configHash,\n running: managed.server.isRunning(),\n sessionId: managed.sessionId,\n };\n }\n return status as Record;\n }\n\n // ---- Private helpers ----\n\n /**\n * Eagerly start the language server so the JVM is warm when the first\n * LSP tool call arrives. Uses the default configuration that\n * `lsp-handlers.ts` / `lsp-diagnostics.ts` would create on the first\n * `getLanguageServer()` call. The server is stored in the managed-servers\n * map and reused by subsequent tool invocations.\n *\n * This is fire-and-forget: errors are logged but do not prevent the MCP\n * server from starting.\n */\n async warmUpLanguageServer(): Promise {\n try {\n // Lazy-import to avoid circular dependency at module level\n const { packageRootDir } = await import('../utils/package-paths');\n const { resolve } = await import('path');\n\n const config: LanguageServerConfig = {\n checkErrors: 'ON_CHANGE',\n loglevel: 'WARN',\n searchPath: resolve(packageRootDir, 'ql'),\n };\n logger.info('Warming up language server (background JVM start)...');\n await this.getLanguageServer(config);\n logger.info('Language server warm-up complete');\n } catch (error) {\n logger.warn('Language server warm-up failed (will retry on first tool call):', error);\n }\n }\n\n /**\n * Eagerly start the CLI server so the JVM is warm when the first\n * `executeCodeQLCommand()` call routes through it.\n *\n * The CLI server uses only session-scoped `commonCaches` and `logdir`,\n * both injected by `enrichConfig()`. Passing an empty config is\n * intentional \u2014 it matches what `executeCodeQLCommand()` will request.\n *\n * Fire-and-forget: errors are logged but do not block startup.\n */\n async warmUpCLIServer(): Promise {\n try {\n logger.info('Warming up CLI server (background JVM start)...');\n await this.getCLIServer({});\n logger.info('CLI server warm-up complete');\n } catch (error) {\n logger.warn('CLI server warm-up failed (will retry on first tool call):', error);\n }\n }\n\n /**\n * Enrich a config with session-specific defaults for commonCaches and logdir.\n */\n private enrichConfig(config: T): T {\n return {\n ...config,\n commonCaches: config.commonCaches ?? this.sessionCacheDir,\n logdir: config.logdir ?? this.getLogDir(),\n };\n }\n\n /**\n * Get an existing server if its config matches, otherwise stop the old\n * one and start a new server.\n *\n * Concurrent calls for the same server type are serialized via\n * `pendingStarts` to avoid spawning duplicate server processes.\n */\n private async getOrRestart(\n type: CodeQLServerType,\n config: ServerConfig,\n factory: () => CodeQLCLIServer | CodeQLLanguageServer | CodeQLQueryServer,\n ): Promise {\n // If another call is already starting a server of this type, wait for it\n // to settle (success or failure) and then re-check whether the result is\n // still usable.\n const inflight = this.pendingStarts.get(type);\n if (inflight) {\n try { await inflight; } catch { /* swallow \u2014 original caller handles the rejection */ }\n }\n\n const work = this.doGetOrRestart(type, config, factory);\n this.pendingStarts.set(type, work);\n try {\n return await work;\n } finally {\n // Ensure `work` has settled before removing the pendingStarts entry so\n // that concurrent callers waiting on the same promise see a consistent\n // map state. The try/catch avoids re-throwing a rejection that the\n // outer `try` block already handles.\n try { await work; } catch { /* already handled */ }\n if (this.pendingStarts.get(type) === work) {\n this.pendingStarts.delete(type);\n }\n }\n }\n\n /**\n * Core logic for getOrRestart, separated to allow serialization.\n */\n private async doGetOrRestart(\n type: CodeQLServerType,\n config: ServerConfig,\n factory: () => CodeQLCLIServer | CodeQLLanguageServer | CodeQLQueryServer,\n ): Promise {\n const hash = computeConfigHash(type, config);\n const existing = this.servers.get(type);\n\n // Reuse if config matches and server is still running\n if (existing && existing.configHash === hash && existing.server.isRunning()) {\n logger.debug(`Reusing existing ${type} server (hash: ${hash.substring(0, 8)})`);\n return existing.server;\n }\n\n // Config changed or server died \u2014 stop the old one\n if (existing) {\n logger.info(`${type} server config changed or dead, restarting...`);\n await this.stopServer(existing);\n this.servers.delete(type);\n }\n\n // Start a new server\n const server = factory();\n await server.start();\n\n this.servers.set(type, {\n configHash: hash,\n server,\n sessionId: this.sessionId,\n type,\n });\n\n logger.info(`${type} server started (hash: ${hash.substring(0, 8)})`);\n return server;\n }\n\n /**\n * Stop a managed server, ignoring errors.\n */\n private async stopServer(managed: ManagedServer): Promise {\n try {\n await managed.server.shutdown();\n } catch (error) {\n logger.warn(`Error stopping ${managed.type} server:`, error);\n // Best-effort \u2014 don't propagate\n }\n }\n}\n\n/**\n * Global server manager singleton.\n *\n * Initialized lazily by `getServerManager()`. The MCP server entry point\n * should call `initServerManager()` at startup and `shutdownServerManager()`\n * at graceful shutdown.\n */\nlet globalServerManager: CodeQLServerManager | null = null;\n\n/**\n * Initialize the global server manager (idempotent).\n */\nexport function initServerManager(options?: SessionCacheOptions): CodeQLServerManager {\n if (!globalServerManager) {\n globalServerManager = new CodeQLServerManager(options);\n }\n return globalServerManager;\n}\n\n/**\n * Get the global server manager, creating it if needed.\n */\nexport function getServerManager(): CodeQLServerManager {\n if (!globalServerManager) {\n globalServerManager = new CodeQLServerManager();\n }\n return globalServerManager;\n}\n\n/**\n * Shut down the global server manager and all its servers.\n */\nexport async function shutdownServerManager(): Promise {\n if (globalServerManager) {\n await globalServerManager.shutdownAll();\n globalServerManager = null;\n }\n}\n\n/**\n * Reset the global server manager (for testing only).\n */\nexport function resetServerManager(): void {\n globalServerManager = null;\n}\n", "/**\n * Generic CLI command execution utilities for CodeQL and QLT commands\n */\n\nimport { execFile } from 'child_process';\nimport { existsSync } from 'fs';\nimport { basename, delimiter, dirname, isAbsolute } from 'path';\nimport { promisify } from 'util';\nimport { logger } from '../utils/logger';\n\nconst execFileAsync = promisify(execFile);\n\nexport interface CLIExecutionResult {\n stdout: string;\n stderr: string;\n success: boolean;\n error?: string;\n exitCode?: number;\n}\n\nexport interface CLIExecutionOptions {\n command: string;\n args: string[];\n cwd?: string;\n timeout?: number;\n env?: Record;\n}\n\n// Whitelist of allowed commands to prevent arbitrary command execution\nconst ALLOWED_COMMANDS = new Set([\n 'codeql',\n 'git',\n 'node',\n 'npm',\n 'qlt',\n 'which'\n]);\n\n// Additional commands allowed in test environments\nlet testCommands: Set | null = null;\n\n// Whitelist of safe environment variables to pass to child processes\n// This prevents potentially malicious environment variables from being passed through\nconst SAFE_ENV_VARS = [\n 'HOME', // User home directory\n 'LANG', // Locale setting\n 'LC_ALL', // Locale setting\n 'LC_CTYPE', // Locale setting\n 'PATH', // Required to find executables\n 'SHELL', // User's shell (Unix)\n 'TEMP', // Temporary directory (Windows)\n 'TERM', // Terminal type (Unix)\n 'TMP', // Temporary directory (Windows)\n 'TMPDIR', // Temporary directory (Unix)\n 'USER', // Current user (Unix)\n 'USERNAME', // Current user (Windows)\n] as const;\n\n// Whitelist of safe environment variable prefixes\n// These are needed for CodeQL and Node.js functionality\nconst SAFE_ENV_PREFIXES = [\n 'CODEQL_', // CodeQL-specific variables\n 'NODE_', // Node.js-specific variables (for npm, etc.)\n] as const;\n\n// Pattern for dangerous control characters in CLI arguments\n// Rejected characters:\n// \\x01-\\x08: SOH through BS (start of heading, text, null control chars, backspace)\n// \\x0B: Vertical tab - rarely used legitimately, can cause display issues\n// \\x0C: Form feed - can cause unexpected page breaks in output\n// \\x0E-\\x1F: SO through US (shift out/in, device controls, separators)\n// Allowed characters:\n// \\x00: Null byte - handled separately for clearer error messaging\n// \\x09: Horizontal tab - commonly used in file paths and arguments\n// \\x0A: Newline (LF) - may appear in multi-line arguments\n// \\x0D: Carriage return (CR) - may appear with newlines on Windows\n// eslint-disable-next-line no-control-regex\nconst DANGEROUS_CONTROL_CHARS = /[\\x01-\\x08\\x0B\\x0C\\x0E-\\x1F]/;\n\n/**\n * Enable test-specific commands for testing purposes\n * This should only be called in test environments\n */\nexport function enableTestCommands(): void {\n testCommands = new Set([\n 'cat',\n 'echo',\n 'ls',\n 'sh',\n 'sleep'\n ]);\n}\n\n/**\n * Disable test-specific commands\n */\nexport function disableTestCommands(): void {\n testCommands = null;\n}\n\n/**\n * Check if a command is allowed\n */\nfunction isCommandAllowed(command: string): boolean {\n return ALLOWED_COMMANDS.has(command) || (testCommands !== null && testCommands.has(command));\n}\n\n// Resolved CodeQL binary directory from CODEQL_PATH.\n// When set, this directory is prepended to PATH for all child processes\n// so that `execFile('codeql', ...)` finds the correct binary via execvp().\n// Using PATH lookup (rather than an absolute path) is essential because\n// execvp() handles shell-script shebangs correctly, whereas passing an\n// absolute path to execFile() can fail with ENOENT for shell scripts.\nlet resolvedCodeQLDir: string | null = null;\n\n// Cached result from resolveCodeQLBinary(). `undefined` means not yet resolved.\nlet resolvedBinaryResult: string | undefined;\n\n/**\n * Resolve the CodeQL CLI binary path.\n *\n * Resolution order:\n * 1. `CODEQL_PATH` environment variable \u2014 must point to an existing file whose\n * basename is `codeql` (or `codeql.exe` / `codeql.cmd` on Windows).\n * The parent directory is prepended to PATH for child processes.\n * 2. Falls back to the bare `codeql` command (resolved via PATH at exec time).\n *\n * The resolved value is cached for the lifetime of the process. Call this once\n * at startup; subsequent calls are a no-op and return the cached value.\n */\nexport function resolveCodeQLBinary(): string {\n // Short-circuit if already resolved\n if (resolvedBinaryResult !== undefined) {\n return resolvedBinaryResult;\n }\n\n const envPath = process.env.CODEQL_PATH;\n\n if (!envPath) {\n resolvedCodeQLDir = null;\n resolvedBinaryResult = 'codeql';\n return resolvedBinaryResult;\n }\n\n // Validate the path points to a plausible CodeQL binary\n const base = basename(envPath).toLowerCase();\n const validBaseNames = ['codeql', 'codeql.exe', 'codeql.cmd'];\n if (!validBaseNames.includes(base)) {\n throw new Error(\n `CODEQL_PATH must point to a CodeQL CLI binary (expected basename: codeql), got: ${base}`\n );\n }\n\n // Require an absolute path to avoid ambiguity\n if (!isAbsolute(envPath)) {\n throw new Error(\n `CODEQL_PATH must be an absolute path, got: ${envPath}`\n );\n }\n\n // Verify the file exists\n if (!existsSync(envPath)) {\n throw new Error(\n `CODEQL_PATH points to a file that does not exist: ${envPath}`\n );\n }\n\n resolvedCodeQLDir = dirname(envPath);\n resolvedBinaryResult = 'codeql';\n logger.info(`CodeQL CLI resolved via CODEQL_PATH: ${envPath} (dir: ${resolvedCodeQLDir})`);\n return resolvedBinaryResult;\n}\n\n/**\n * Get the currently resolved CodeQL binary directory, or null if using PATH.\n */\nexport function getResolvedCodeQLDir(): string | null {\n return resolvedCodeQLDir;\n}\n\n/**\n * Reset the resolved CodeQL binary to the default (for testing only).\n */\nexport function resetResolvedCodeQLBinary(): void {\n resolvedCodeQLDir = null;\n resolvedBinaryResult = undefined;\n}\n\n/**\n * Validate that the resolved CodeQL binary is actually callable.\n *\n * Runs `codeql version --format=terse` and verifies the process exits\n * successfully. This catches the case where `CODEQL_PATH` is unset and\n * `codeql` is not on PATH \u2014 the server would otherwise start normally\n * but every tool invocation would fail.\n *\n * @returns The version string reported by the CodeQL CLI.\n * @throws Error if the binary is not reachable or returns a non-zero exit code.\n */\nexport async function validateCodeQLBinaryReachable(): Promise {\n const binary = resolvedBinaryResult ?? 'codeql';\n const env = { ...process.env };\n if (resolvedCodeQLDir) {\n env.PATH = resolvedCodeQLDir + delimiter + (env.PATH || '');\n }\n\n try {\n const { stdout } = await execFileAsync(binary, ['version', '--format=terse'], {\n env,\n timeout: 15_000,\n });\n return stdout.trim();\n } catch (err: unknown) {\n const message = err instanceof Error ? err.message : String(err);\n throw new Error(\n `CodeQL CLI is not reachable (binary: ${binary}). ` +\n `Ensure codeql is on PATH or set the CODEQL_PATH environment variable ` +\n `to the absolute path of the CodeQL CLI binary. Details: ${message}`\n );\n }\n}\n\n/**\n * Sanitize a CLI argument to prevent potential issues with special characters.\n * \n * While execFile() does not spawn a shell (preventing shell injection), we still\n * validate arguments to:\n * 1. Reject null bytes that could truncate strings in C-based commands\n * 2. Reject control characters that could cause unexpected behavior\n * 3. Provide defense-in-depth against potential issues\n * \n * @param arg - The argument to sanitize\n * @returns The sanitized argument\n * @throws Error if the argument contains dangerous characters\n */\nexport function sanitizeCLIArgument(arg: string): string {\n // Reject null bytes - these can truncate strings in C-based commands\n // Error message intentionally excludes argument content to avoid logging potentially sensitive data\n if (arg.includes('\\0')) {\n throw new Error(`CLI argument contains null byte: argument rejected for security`);\n }\n \n // Reject control characters using the module-level constant pattern\n if (DANGEROUS_CONTROL_CHARS.test(arg)) {\n // Error message intentionally excludes argument content to avoid logging potentially sensitive data\n throw new Error(`CLI argument contains control characters: argument rejected for security`);\n }\n \n return arg;\n}\n\n/**\n * Sanitize an array of CLI arguments\n * @param args - The arguments to sanitize\n * @returns The sanitized arguments\n * @throws Error if any argument contains dangerous characters\n */\nexport function sanitizeCLIArguments(args: string[]): string[] {\n return args.map(sanitizeCLIArgument);\n}\n\n/**\n * Filter environment variables to only include safe ones\n * This prevents potentially malicious environment variables from being passed to child processes\n */\nfunction getSafeEnvironment(additionalEnv?: Record): Record {\n const safeEnv: Record = {};\n \n // Copy whitelisted environment variables from process.env\n for (const key of SAFE_ENV_VARS) {\n if (process.env[key] !== undefined) {\n safeEnv[key] = process.env[key]!;\n }\n }\n \n // Copy environment variables with whitelisted prefixes\n for (const [key, value] of Object.entries(process.env)) {\n if (value !== undefined && SAFE_ENV_PREFIXES.some(prefix => key.startsWith(prefix))) {\n safeEnv[key] = value;\n }\n }\n \n // When CODEQL_PATH was set, prepend the resolved directory to PATH so that\n // `execFile('codeql', ...)` finds the user-specified binary via execvp().\n // This approach (PATH manipulation + bare command name) is essential because\n // execvp() handles shell-script shebangs correctly, whereas passing an\n // absolute path to execFile() fails with ENOENT for shell-script launchers.\n if (resolvedCodeQLDir && safeEnv.PATH) {\n safeEnv.PATH = `${resolvedCodeQLDir}${delimiter}${safeEnv.PATH}`;\n } else if (resolvedCodeQLDir) {\n safeEnv.PATH = resolvedCodeQLDir;\n }\n \n // Merge with explicitly provided environment variables\n // These are trusted as they come from the application code, not external sources\n if (additionalEnv) {\n Object.assign(safeEnv, additionalEnv);\n }\n \n return safeEnv;\n}\n\n/**\n * Execute a CLI command and return the result.\n * \n * Security: This function uses execFile() instead of exec() to avoid shell interpretation.\n * Arguments are passed directly to the executable as an array, preventing shell injection.\n * Additional security measures include:\n * - Command whitelist validation\n * - Shell metacharacter detection in command names\n * - CLI argument sanitization (null bytes, control characters)\n * - Environment variable filtering\n */\nexport async function executeCLICommand(options: CLIExecutionOptions): Promise {\n try {\n const { command, args, cwd, timeout = 300000, env } = options; // 5 minute default timeout\n \n // Validate command is in the whitelist to prevent arbitrary command execution\n if (!isCommandAllowed(command)) {\n throw new Error(`Command not allowed: ${command}. Only whitelisted commands can be executed.`);\n }\n \n // Validate command to ensure it doesn't contain shell metacharacters\n if (command.includes(';') || command.includes('|') || command.includes('&') || \n command.includes('$') || command.includes('`') || command.includes('\\n') ||\n command.includes('\\r')) {\n throw new Error(`Invalid command: contains shell metacharacters: ${command}`);\n }\n \n // Sanitize CLI arguments to prevent issues with special characters\n // This provides defense-in-depth even though execFile() doesn't use a shell\n const sanitizedArgs = sanitizeCLIArguments(args);\n \n logger.info(`Executing CLI command: ${command}`, { args: sanitizedArgs, cwd, timeout });\n \n const execOptions = {\n cwd,\n timeout,\n env: getSafeEnvironment(env),\n };\n \n // execFile() is used instead of exec() to avoid shell interpretation\n // Arguments are passed as an array, not interpolated into a command string\n const { stdout, stderr } = await execFileAsync(command, sanitizedArgs, execOptions);\n\n return {\n stdout,\n stderr,\n success: true,\n exitCode: 0\n };\n\n } catch (error: unknown) {\n logger.error('CLI command execution failed:', error);\n \n const err = error as Error & { code?: number; stdout?: string; stderr?: string };\n const errorMessage = err instanceof Error ? err.message : String(error);\n const exitCode = err.code || 1;\n \n return {\n stdout: err.stdout || '',\n stderr: err.stderr || errorMessage,\n success: false,\n error: errorMessage,\n exitCode\n };\n }\n}\n\n/**\n * Build CodeQL command arguments with proper escaping\n */\nexport function buildCodeQLArgs(subcommand: string, options: Record): string[] {\n const args = [subcommand];\n \n // Single-letter parameters that should use -key=value format (with equals sign)\n // Note: CodeQL CLI uses -t=key=value format for metadata, not -t key=value\n const singleLetterParams = new Set(['t', 'o', 'v', 'q', 'h', 'J']);\n \n for (const [key, value] of Object.entries(options)) {\n if (value === undefined || value === null) {\n continue;\n }\n \n const isSingleLetter = key.length === 1 && singleLetterParams.has(key);\n \n if (typeof value === 'boolean') {\n if (value) {\n args.push(isSingleLetter ? `-${key}` : `--${key}`);\n }\n } else if (Array.isArray(value)) {\n // Handle array values (e.g., multiple -t flags for metadata)\n for (const item of value) {\n if (isSingleLetter) {\n // For single-letter params like -t, use -key=value format\n args.push(`-${key}=${String(item)}`);\n } else {\n // For long params, use --key=value format\n args.push(`--${key}=${String(item)}`);\n }\n }\n } else {\n // Handle string, number, and other values\n if (isSingleLetter) {\n // For single-letter params, use -key=value format\n args.push(`-${key}=${String(value)}`);\n } else {\n args.push(`--${key}=${String(value)}`);\n }\n }\n }\n \n return args;\n}\n\n/**\n * Build QLT command arguments with proper escaping\n */\nexport function buildQLTArgs(subcommand: string, options: Record): string[] {\n const args = [subcommand];\n \n for (const [key, value] of Object.entries(options)) {\n if (value === undefined || value === null) {\n continue;\n }\n \n if (typeof value === 'boolean') {\n if (value) {\n args.push(`--${key}`);\n }\n } else if (Array.isArray(value)) {\n // Handle array values\n for (const item of value) {\n args.push(`--${key}`, String(item));\n }\n } else {\n // Handle string, number, and other values\n args.push(`--${key}`, String(value));\n }\n }\n \n return args;\n}\n\n/**\n * CodeQL subcommands that MUST run as fresh processes.\n *\n * These cannot use the cli-server because they:\n * - Spawn extractors or other long-running child processes (database create, test extract)\n * - Produce multi-event NUL-delimited streams (test run)\n * - Are compound orchestration commands (database analyze)\n *\n * Everything else is routed through the persistent cli-server JVM for\n * sub-second execution instead of 2-5 s JVM cold-start per invocation.\n */\nconst FRESH_PROCESS_SUBCOMMANDS = new Set([\n 'database analyze',\n 'database create',\n 'test extract',\n 'test run',\n]);\n\n/**\n * Execute a CodeQL command.\n *\n * By default, commands are routed through the persistent `codeql execute\n * cli-server` process managed by {@link CodeQLServerManager}, eliminating\n * repeated JVM startup overhead (~2-5 s savings per call).\n *\n * Commands listed in {@link FRESH_PROCESS_SUBCOMMANDS} (e.g. `database create`,\n * `test run`) are always executed as fresh processes because they either spawn\n * child extractors, produce streaming output, or require a dedicated working\n * directory.\n *\n * If the cli-server is not available (e.g. during early startup before\n * `initServerManager()` is called), the function falls back transparently to\n * a fresh process.\n */\nexport async function executeCodeQLCommand(\n subcommand: string,\n options: Record,\n additionalArgs: string[] = [],\n cwd?: string\n): Promise {\n const args = buildCodeQLArgs(subcommand, options);\n args.push(...additionalArgs);\n\n // Determine whether this subcommand can use the persistent cli-server.\n // Commands that need a specific CWD also must use a fresh process because\n // the cli-server's CWD is fixed at startup.\n const canUseCLIServer = !FRESH_PROCESS_SUBCOMMANDS.has(subcommand) && !cwd;\n\n if (canUseCLIServer) {\n try {\n // Lazy-import to avoid circular dependency at module level.\n // Use getServerManager() (not initServerManager()) \u2014 if the manager\n // hasn't been initialized yet (e.g. during tests or early startup),\n // this creates one, but we only attempt to *use* the cli-server if\n // it is already running (warmed up at MCP server startup). We never\n // block on starting a new cli-server here \u2014 that would add JVM\n // startup latency to the first fresh-process-fallback call.\n const { getServerManager } = await import('./server-manager');\n const manager = getServerManager();\n\n if (manager.isRunning('cli')) {\n const cliServer = await manager.getCLIServer({});\n const sanitizedArgs = sanitizeCLIArguments(args);\n\n logger.info(`Executing CodeQL command via cli-server: ${subcommand}`, { args: sanitizedArgs });\n\n const stdout = await cliServer.runCommand(sanitizedArgs);\n\n return {\n stdout,\n stderr: '',\n success: true,\n exitCode: 0,\n };\n } else {\n logger.debug(`cli-server not yet running for \"${subcommand}\", using fresh process`);\n }\n } catch (error) {\n // If the cli-server call fails, check whether it's a command-level\n // error (the CLI returned non-zero) or a transport/startup error.\n // For transport errors we fall back to a fresh process; for command\n // errors we return the failure directly.\n const message = error instanceof Error ? error.message : String(error);\n\n // Transport-level errors that warrant a fallback:\n if (message.includes('CLI server is not running') ||\n message.includes('CLI server exited') ||\n message.includes('failed to start')) {\n logger.warn(`cli-server unavailable for \"${subcommand}\", falling back to fresh process: ${message}`);\n // Fall through to fresh-process execution below\n } else {\n // Command-level error \u2014 return it as a failed result\n logger.error(`cli-server command failed for \"${subcommand}\": ${message}`);\n return {\n stdout: '',\n stderr: message,\n success: false,\n error: message,\n exitCode: 1,\n };\n }\n }\n }\n\n // Fresh-process execution (for FRESH_PROCESS_SUBCOMMANDS, CWD-specific\n // calls, or as a fallback when the cli-server is unavailable).\n // Use 0 (no timeout) because CodeQL operations such as query evaluation,\n // database analysis, profiling, and test runs are inherently long-running\n // and should not be killed by a process timeout.\n return executeCLICommand({\n command: 'codeql',\n args,\n cwd,\n timeout: 0\n });\n}\n\n/**\n * Execute a QLT command\n */\nexport async function executeQLTCommand(\n subcommand: string, \n options: Record, \n additionalArgs: string[] = []\n): Promise {\n const args = buildQLTArgs(subcommand, options);\n args.push(...additionalArgs);\n \n return executeCLICommand({\n command: 'qlt',\n args\n });\n}\n\n/**\n * Get help text for a CLI command\n */\nexport async function getCommandHelp(command: string, subcommand?: string): Promise {\n const args = subcommand ? [subcommand, '--help'] : ['--help'];\n \n const result = await executeCLICommand({\n command,\n args\n });\n \n return result.stdout || result.stderr || 'No help available';\n}\n\n/**\n * Validate that a command exists on the system.\n */\nexport async function validateCommandExists(command: string): Promise {\n try {\n const result = await executeCLICommand({\n command: 'which',\n args: [command]\n });\n return result.success;\n } catch {\n return false;\n }\n}", "/**\n * CodeQL Development MCP McpServer\n * Main entry point for the server\n */\n\nimport { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';\nimport { StreamableHTTPServerTransport } from '@modelcontextprotocol/sdk/server/streamableHttp.js';\nimport express from 'express';\nimport cors from 'cors';\nimport dotenv from 'dotenv';\nimport { realpathSync } from 'fs';\nimport { resolve } from 'path';\nimport { pathToFileURL } from 'url';\nimport { registerCodeQLTools, registerCodeQLResources } from './tools';\nimport { registerLSPTools } from './tools/lsp';\nimport { registerLanguageResources } from './resources/language-resources';\nimport { registerWorkflowPrompts } from './prompts/workflow-prompts';\nimport { registerMonitoringTools } from './tools/monitoring-tools';\nimport { sessionDataManager } from './lib/session-data-manager';\nimport { resolveCodeQLBinary, validateCodeQLBinaryReachable } from './lib/cli-executor';\nimport { initServerManager, shutdownServerManager } from './lib/server-manager';\nimport { packageRootDir } from './utils/package-paths';\nimport { logger } from './utils/logger';\n\n// Load environment variables from a .env file co-located with the package root.\n// Uses the package directory (not CWD) so that npm-installed users don't\n// accidentally inherit a .env from their project.\n// Set DOTENV_CONFIG_QUIET to suppress the dotenv banner that would otherwise\n// leak to stdout and corrupt the MCP stdio JSON-RPC channel.\ndotenv.config({ path: resolve(packageRootDir, '.env'), quiet: true });\n\nconst PACKAGE_NAME = 'codeql-development-mcp-server';\nconst VERSION = '2.24.1';\n\n/**\n * Start the MCP server\n */\nexport async function startServer(mode: 'stdio' | 'http' = 'stdio'): Promise {\n logger.info(`Starting CodeQL Development MCP McpServer v${VERSION} in ${mode} mode`);\n\n // Resolve the CodeQL CLI binary path (honors CODEQL_PATH env var).\n // This must happen before any tool registration so that all CodeQL commands\n // use the user-specified binary.\n const codeqlBinary = resolveCodeQLBinary();\n logger.info(`CodeQL CLI binary: ${codeqlBinary}`);\n\n // Validate that the resolved binary is actually callable. This catches\n // misconfigurations early (e.g. codeql not on PATH and CODEQL_PATH unset)\n // instead of failing silently and producing confusing tool-level errors.\n const codeqlVersion = await validateCodeQLBinaryReachable();\n logger.info(`CodeQL CLI version: ${codeqlVersion}`);\n\n const server = new McpServer({\n name: PACKAGE_NAME,\n version: VERSION,\n });\n\n // Register CodeQL tools (legacy high-level helpers)\n registerCodeQLTools(server);\n\n // Register LSP-based tools (diagnostics, completion, definition, references)\n registerLSPTools(server);\n\n // Register CodeQL resources (static guides)\n registerCodeQLResources(server);\n\n // Register language-specific resources (AST references, security patterns)\n registerLanguageResources(server);\n\n // Register high-level workflow prompts (complete development workflows)\n registerWorkflowPrompts(server);\n\n // Register monitoring and reporting tools\n registerMonitoringTools(server);\n\n // Initialize session data manager\n await sessionDataManager.initialize();\n\n // Initialize the CodeQL background server manager and eagerly start the\n // language server and CLI server JVMs so they are warm when the first tool\n // calls arrive. This avoids 2-60 s cold-start penalties per JVM.\n const manager = initServerManager();\n Promise.all([\n manager.warmUpLanguageServer(),\n manager.warmUpCLIServer(),\n ]).catch(() => { /* individual errors logged inside each warm-up method */ });\n\n if (mode === 'stdio') {\n const transport = new StdioServerTransport();\n await server.connect(transport);\n logger.info('McpServer started successfully on STDIO transport');\n } else {\n // HTTP mode\n const app = express();\n app.use(cors());\n app.use(express.json());\n\n const transport = new StreamableHTTPServerTransport({\n sessionIdGenerator: () => Math.random().toString(36).substring(7),\n });\n await server.connect(transport);\n\n app.all('/mcp', (req, res) => {\n transport.handleRequest(req, res, req.body).catch((err) => {\n logger.error('Error handling MCP request:', err);\n if (!res.headersSent) {\n res.status(500).json({ error: 'Internal McpServer Error' });\n }\n });\n });\n\n app.get('/', (_req, res) => {\n res.json({\n name: PACKAGE_NAME,\n version: VERSION,\n description: 'CodeQL Development MCP McpServer',\n status: 'running',\n });\n });\n\n const host = process.env.HTTP_HOST || 'localhost';\n const port = Number(process.env.HTTP_PORT || process.env.PORT) || 3000;\n \n // Return a promise that keeps the process alive\n return new Promise((resolve, reject) => {\n const httpServer = app.listen(port, host, () => {\n logger.info(`HTTP server listening on http://${host}:${port}/mcp`);\n resolve();\n });\n \n httpServer.on('error', (error) => {\n logger.error('HTTP server error:', error);\n reject(error);\n });\n });\n }\n\n setupGracefulShutdown(server);\n return server;\n}\n\n/**\n * Set up graceful shutdown handling\n */\nfunction setupGracefulShutdown(server: McpServer): void {\n const shutdown = async () => {\n logger.info('Shutting down server...');\n try {\n // Shut down all CodeQL background servers first\n await shutdownServerManager();\n await server.close();\n logger.info('McpServer closed gracefully');\n process.exit(0);\n } catch (error) {\n logger.error('Error during shutdown:', error);\n process.exit(1);\n }\n };\n\n process.on('SIGINT', shutdown);\n process.on('SIGTERM', shutdown);\n}\n\n/**\n * Main function to start the server\n */\nasync function main(): Promise {\n try {\n const transportMode = (process.env.TRANSPORT_MODE || 'stdio').toLowerCase();\n const mode: 'stdio' | 'http' = transportMode === 'http' ? 'http' : 'stdio';\n await startServer(mode);\n } catch (error) {\n logger.error('Failed to start server:', error);\n process.exit(1);\n }\n}\n\n// Start the server if this file is run directly.\n// Use realpathSync to resolve npm/npx symlinks so the guard works for both\n// direct invocation and globally-installed npm bin entries.\nconst scriptPath = process.argv[1] ? realpathSync(resolve(process.argv[1])) : undefined;\nif (scriptPath && import.meta.url === pathToFileURL(scriptPath).href) {\n main();\n}\n", "/**\n * CodeQL BQRS decode tool\n *\n * Decodes BQRS (Binary Query Result Set) files to human-readable formats.\n * Use `list_query_run_results` to discover BQRS files from previous query runs,\n * then decode them with this tool. For long-running queries (codeql_query_run)\n * or suites (codeql_database_analyze), the BQRS file is located at\n * `/results.bqrs`. Use `codeql_bqrs_info` first to discover available\n * result sets and column schemas.\n */\n\nimport { z } from 'zod';\nimport { CLIToolDefinition, createCodeQLSchemas, createBQRSResultProcessor } from '../../lib/cli-tool-registry';\n\nexport const codeqlBqrsDecodeTool: CLIToolDefinition = {\n name: 'codeql_bqrs_decode',\n description:\n 'Decode BQRS result files to human-readable formats (text, csv, json). ' +\n 'Typical workflow: (1) use list_query_run_results to find BQRS paths from previous codeql_query_run or codeql_database_analyze runs, ' +\n '(2) use codeql_bqrs_info to discover result sets and column schemas, ' +\n '(3) decode specific result sets with this tool. ' +\n 'For large result sets, use --rows to paginate.',\n command: 'codeql',\n subcommand: 'bqrs decode',\n inputSchema: {\n files: z.array(z.string()).describe('BQRS file(s) to decode'),\n output: createCodeQLSchemas.output(),\n format: z.enum(['csv', 'json', 'text', 'bqrs']).optional()\n .describe('Output format: text (human-readable table, default), csv, json (streaming JSON), or bqrs (binary, requires --output)'),\n 'result-set': z.string().optional()\n .describe('Decode a specific result set by name (use codeql_bqrs_info to list available sets). If omitted, all result sets are decoded.'),\n 'sort-key': z.string().optional()\n .describe('Sort by column(s): comma-separated column indices (0-based)'),\n 'sort-direction': z.string().optional()\n .describe('Sort direction(s): comma-separated \"asc\" or \"desc\" per column'),\n 'no-titles': z.boolean().optional()\n .describe('Omit column titles for text and csv formats'),\n entities: z.string().optional()\n .describe('Control entity column display: comma-separated list of url, string, id, all'),\n rows: z.number().optional()\n .describe('Maximum number of rows to output (for pagination). Use with --start-at for paging.'),\n 'start-at': z.number().optional()\n .describe('Byte offset to start decoding from (get from codeql_bqrs_info or previous JSON output \"next\" pointer). Must be used with --rows.'),\n verbose: createCodeQLSchemas.verbose(),\n additionalArgs: createCodeQLSchemas.additionalArgs()\n },\n examples: [\n 'codeql bqrs decode --format=csv --output=results.csv results.bqrs',\n 'codeql bqrs decode --format=json --rows=100 results.bqrs',\n 'codeql bqrs decode --result-set=#select --format=csv results.bqrs',\n 'codeql bqrs decode --format=json --entities=url,string results.bqrs'\n ],\n resultProcessor: createBQRSResultProcessor()\n};", "/**\n * Generic tool registry for creating MCP tools from CLI command definitions\n */\n\nimport { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport { z } from 'zod';\nimport { executeCodeQLCommand, executeQLTCommand, CLIExecutionResult } from './cli-executor';\nimport { logger } from '../utils/logger';\nimport { evaluateQueryResults, QueryEvaluationResult, extractQueryMetadata } from './query-results-evaluator';\nimport { getOrCreateLogDirectory } from './log-directory-manager';\nimport { getUserWorkspaceDir, packageRootDir, resolveToolQueryPackPath } from '../utils/package-paths';\nimport { writeFileSync, rmSync, existsSync, mkdirSync } from 'fs';\nimport { basename, dirname, isAbsolute, join, resolve } from 'path';\nimport { createProjectTempDir } from '../utils/temp-dir';\n\nexport type { CLIExecutionResult } from './cli-executor';\n\nexport interface CLIToolDefinition {\n name: string;\n description: string;\n command: 'codeql' | 'qlt';\n subcommand: string;\n inputSchema: Record;\n examples?: string[];\n resultProcessor?: (_result: CLIExecutionResult, _params: Record) => string;\n}\n\n/**\n * Default result processor that formats CLI output appropriately\n */\nexport const defaultCLIResultProcessor = (\n result: CLIExecutionResult, \n _params: Record\n): string => {\n if (!result.success) {\n return `Command failed (exit code ${result.exitCode || 'unknown'}):\\n${result.error || result.stderr}`;\n }\n \n let output = '';\n \n if (result.stdout) {\n output += result.stdout;\n }\n \n if (result.stderr) {\n if (output) {\n output += '\\n\\nWarnings/Info:\\n';\n }\n output += result.stderr;\n }\n \n if (!output) {\n output = 'Command executed successfully (no output)';\n }\n \n return output;\n};\n\n/**\n * Register a CLI tool with the MCP server\n */\nexport function registerCLITool(server: McpServer, definition: CLIToolDefinition): void {\n const {\n name,\n description,\n command,\n subcommand,\n inputSchema,\n resultProcessor = defaultCLIResultProcessor\n } = definition;\n\n server.tool(\n name,\n description,\n inputSchema,\n async (params: Record) => {\n // Track temporary directories for cleanup\n const tempDirsToCleanup: string[] = [];\n \n try {\n logger.info(`Executing CLI tool: ${name}`, { command, subcommand, params });\n\n // Separate positional arguments from named options\n // Extract tool-specific parameters that should not be passed to CLI\n // Note: format is extracted for tools that use it internally but not on CLI\n // For codeql_bqrs_interpret, codeql_bqrs_decode, codeql_bqrs_info, codeql_generate_query-help, and codeql_database_analyze, format should be passed to CLI\n const formatShouldBePassedToCLI = name === 'codeql_bqrs_interpret' || name === 'codeql_bqrs_decode' || name === 'codeql_bqrs_info' || name === 'codeql_generate_query-help' || name === 'codeql_database_analyze';\n \n const extractedParams = formatShouldBePassedToCLI\n ? {\n _positional: params._positional || [],\n files: params.files,\n file: params.file,\n dir: params.dir,\n packDir: params.packDir,\n tests: params.tests,\n query: params.query,\n queryName: params.queryName,\n queryLanguage: params.queryLanguage,\n queryPack: params.queryPack,\n sourceFiles: params.sourceFiles,\n sourceFunction: params.sourceFunction,\n targetFunction: params.targetFunction,\n interpretedOutput: params.interpretedOutput,\n evaluationFunction: params.evaluationFunction,\n evaluationOutput: params.evaluationOutput,\n directory: params.directory,\n logDir: params.logDir,\n qlref: params.qlref\n }\n : {\n _positional: params._positional || [],\n files: params.files,\n file: params.file,\n dir: params.dir,\n packDir: params.packDir,\n tests: params.tests,\n query: params.query,\n queryName: params.queryName,\n queryLanguage: params.queryLanguage,\n queryPack: params.queryPack, \n sourceFiles: params.sourceFiles,\n sourceFunction: params.sourceFunction,\n targetFunction: params.targetFunction,\n format: params.format,\n interpretedOutput: params.interpretedOutput,\n evaluationFunction: params.evaluationFunction,\n evaluationOutput: params.evaluationOutput,\n directory: params.directory,\n logDir: params.logDir,\n qlref: params.qlref\n };\n\n const {\n _positional = [],\n files,\n file,\n dir,\n packDir,\n tests,\n query,\n queryName,\n queryLanguage: _queryLanguage,\n queryPack: _queryPack,\n sourceFiles,\n sourceFunction,\n targetFunction,\n format: _format,\n interpretedOutput: _interpretedOutput,\n evaluationFunction: _evaluationFunction,\n evaluationOutput: _evaluationOutput,\n directory,\n logDir: customLogDir,\n qlref,\n } = extractedParams;\n\n // Get remaining options (everything not extracted above)\n const options = {...params};\n Object.keys(extractedParams).forEach(key => delete options[key]);\n let positionalArgs = Array.isArray(_positional) ? _positional as string[] : [_positional as string];\n\n // Handle files parameter as positional arguments for certain tools\n if (files && Array.isArray(files)) {\n positionalArgs = [...positionalArgs, ...files as string[]];\n }\n\n // Handle file parameter as positional argument for BQRS tools\n if (file && name.startsWith('codeql_bqrs_')) {\n positionalArgs = [...positionalArgs, file as string];\n }\n\n // Handle qlref parameter as positional argument for resolve qlref tool\n if (qlref && name === 'codeql_resolve_qlref') {\n positionalArgs = [...positionalArgs, qlref as string];\n }\n\n // Handle database parameter as positional argument for resolve database tool\n if (options.database && name === 'codeql_resolve_database') {\n positionalArgs = [...positionalArgs, options.database as string];\n delete options.database;\n }\n\n // Handle database parameter as positional argument for database create tool\n if (options.database && name === 'codeql_database_create') {\n positionalArgs = [...positionalArgs, options.database as string];\n delete options.database;\n }\n\n // Handle database and queries parameters as positional arguments for database analyze tool\n if (name === 'codeql_database_analyze') {\n if (options.database) {\n positionalArgs = [...positionalArgs, options.database as string];\n delete options.database;\n }\n if (options.queries) {\n positionalArgs = [...positionalArgs, options.queries as string];\n delete options.queries;\n }\n }\n\n // Handle query parameter as positional argument for generate query-help tool\n if (query && name === 'codeql_generate_query-help') {\n positionalArgs = [...positionalArgs, query as string];\n }\n\n // Handle dir parameter as positional argument for pack tools\n if (dir && (name === 'codeql_pack_ls')) {\n positionalArgs = [...positionalArgs, dir as string];\n }\n \n // Handle tool-specific parameters using switch pattern for better maintainability\n switch (name) {\n case 'codeql_test_accept':\n case 'codeql_test_extract':\n case 'codeql_test_run':\n case 'codeql_resolve_tests':\n // Handle tests parameter as positional arguments for test tools.\n // Resolve relative paths against the user's effective workspace\n // directory. In monorepo layouts this is the repo root; in npm-\n // installed layouts it falls back to process.cwd().\n if (tests && Array.isArray(tests)) {\n const userDir = getUserWorkspaceDir();\n positionalArgs = [...positionalArgs, ...(tests as string[]).map(\n t => isAbsolute(t) ? t : resolve(userDir, t)\n )];\n }\n break;\n \n case 'codeql_query_run': {\n // Resolve database path to absolute path if it's relative\n if (options.database && typeof options.database === 'string' && !isAbsolute(options.database)) {\n options.database = resolve(getUserWorkspaceDir(), options.database);\n logger.info(`Resolved database path to: ${options.database}`);\n }\n \n // Implement query resolution logic with enhanced results processing\n const resolvedQuery = await resolveQueryPath(params, logger);\n if (resolvedQuery) {\n positionalArgs = [...positionalArgs, resolvedQuery];\n } else if (query) {\n positionalArgs = [...positionalArgs, query as string];\n }\n \n // Handle external predicates for tool queries\n if (queryName === 'PrintAST' && sourceFiles) {\n // Create a CSV file with the source file paths for the external predicate\n // The external predicate expects a CSV file with one column containing file paths\n const filePaths = (sourceFiles as string).split(',').map((f: string) => f.trim());\n let tempDir: string;\n let csvPath: string;\n try {\n tempDir = createProjectTempDir('codeql-external-');\n tempDirsToCleanup.push(tempDir); // Track for cleanup\n csvPath = join(tempDir, 'selectedSourceFiles.csv');\n\n // Create CSV content\n const csvContent = filePaths.join('\\n') + '\\n';\n\n writeFileSync(csvPath, csvContent, 'utf8');\n } catch (err) {\n logger.error(`Failed to create external predicate CSV for PrintAST query at path ${csvPath || '[unknown]'}: ${err instanceof Error ? err.message : String(err)}`);\n throw err;\n }\n \n // Add the external predicate with the CSV file path\n const currentExternal = options.external || [];\n const externalArray = Array.isArray(currentExternal) ? currentExternal : [currentExternal];\n externalArray.push(`selectedSourceFiles=${csvPath}`);\n options.external = externalArray;\n \n logger.info(`Created external predicate CSV at ${csvPath} for files: ${filePaths.join(', ')}`);\n }\n \n // Handle external predicates for CallGraphFrom queries\n if (queryName === 'CallGraphFrom' && sourceFunction) {\n const functionNames = (sourceFunction as string).split(',').map((f: string) => f.trim());\n let tempDir: string;\n let csvPath: string;\n try {\n tempDir = createProjectTempDir('codeql-external-');\n tempDirsToCleanup.push(tempDir);\n csvPath = join(tempDir, 'sourceFunction.csv');\n\n // Create CSV content\n const csvContent = functionNames.join('\\n') + '\\n';\n\n writeFileSync(csvPath, csvContent, 'utf8');\n } catch (err) {\n logger.error(`Failed to create external predicate CSV for CallGraphFrom query at path ${csvPath || '[unknown]'}: ${err instanceof Error ? err.message : String(err)}`);\n throw err;\n }\n \n // Add the external predicate with the CSV file path\n const currentExternal = options.external || [];\n const externalArray = Array.isArray(currentExternal) ? currentExternal : [currentExternal];\n externalArray.push(`sourceFunction=${csvPath}`);\n options.external = externalArray;\n \n logger.info(`Created external predicate CSV at ${csvPath} for functions: ${functionNames.join(', ')}`);\n }\n \n // Handle external predicates for CallGraphTo queries\n if (queryName === 'CallGraphTo' && targetFunction) {\n const functionNames = (targetFunction as string).split(',').map((f: string) => f.trim());\n let tempDir: string;\n let csvPath: string;\n try {\n tempDir = createProjectTempDir('codeql-external-');\n tempDirsToCleanup.push(tempDir);\n csvPath = join(tempDir, 'targetFunction.csv');\n\n // Create CSV content\n const csvContent = functionNames.join('\\n') + '\\n';\n\n writeFileSync(csvPath, csvContent, 'utf8');\n } catch (err) {\n logger.error(`Failed to create external predicate CSV for CallGraphTo query at path ${csvPath || '[unknown]'}: ${err instanceof Error ? err.message : String(err)}`);\n throw err;\n }\n \n // Add the external predicate with the CSV file path\n const currentExternal = options.external || [];\n const externalArray = Array.isArray(currentExternal) ? currentExternal : [currentExternal];\n externalArray.push(`targetFunction=${csvPath}`);\n options.external = externalArray;\n \n logger.info(`Created external predicate CSV at ${csvPath} for functions: ${functionNames.join(', ')}`);\n }\n break;\n }\n \n case 'codeql_query_compile':\n case 'codeql_resolve_metadata':\n // Handle query parameter as positional argument for query compilation and metadata tools\n if (query) {\n positionalArgs = [...positionalArgs, query as string];\n }\n break;\n \n case 'codeql_resolve_queries':\n // Handle directory parameter as positional argument\n if (directory) {\n positionalArgs = [...positionalArgs, directory as string];\n }\n break;\n \n default:\n // No special parameter handling needed for other tools\n break;\n }\n\n // Set up logging directory for query/test/analyze runs\n let queryLogDir: string | undefined;\n if (name === 'codeql_query_run' || name === 'codeql_test_run' || name === 'codeql_database_analyze') {\n queryLogDir = getOrCreateLogDirectory(customLogDir as string | undefined);\n logger.info(`Using log directory for ${name}: ${queryLogDir}`);\n\n // Create timestamp file to track when query/test run started\n const timestampPath = join(queryLogDir, 'timestamp');\n writeFileSync(timestampPath, Date.now().toString(), 'utf8');\n\n // Set the --logdir option for CodeQL CLI\n options.logdir = queryLogDir;\n\n // Set verbosity to progress+ to generate detailed query.log/test.log\n if (!options.verbosity) {\n options.verbosity = 'progress+';\n }\n\n // Set evaluator-log if not explicitly provided\n if (!options['evaluator-log']) {\n options['evaluator-log'] = join(queryLogDir, 'evaluator-log.jsonl');\n }\n\n // Enable --tuple-counting by default for evaluator logging\n if (options['tuple-counting'] === undefined) {\n options['tuple-counting'] = true;\n }\n\n // For query run, also handle default output\n if (name === 'codeql_query_run') {\n // If output was not explicitly provided, set it to the log directory\n if (!options.output) {\n options.output = join(queryLogDir, 'results.bqrs');\n }\n }\n\n // Ensure the parent directory of --output exists (the CLI will not create it)\n if (options.output && typeof options.output === 'string') {\n const outputDir = dirname(options.output);\n mkdirSync(outputDir, { recursive: true });\n }\n }\n\n let result: CLIExecutionResult;\n \n if (command === 'codeql') {\n // For pack commands, set the working directory to where qlpack.yml is located.\n // Resolve to absolute path since the MCP server's cwd may differ from\n // the workspace root (especially when launched by VS Code).\n let cwd: string | undefined;\n if ((name === 'codeql_pack_install' || name === 'codeql_pack_ls') && (dir || packDir)) {\n const rawCwd = (dir || packDir) as string;\n // Resolve relative paths against the user's effective workspace\n // directory rather than a potentially read-only package root.\n cwd = isAbsolute(rawCwd) ? rawCwd : resolve(getUserWorkspaceDir(), rawCwd);\n }\n \n // Add --additional-packs for commands that need to access local test packs.\n // Only set the default examples path when it actually exists on disk\n // (it may be absent in npm-installed layouts where ql/javascript/examples/\n // is not included in the published package).\n const defaultExamplesPath = resolve(packageRootDir, 'ql', 'javascript', 'examples');\n const additionalPacksPath = process.env.CODEQL_ADDITIONAL_PACKS\n || (existsSync(defaultExamplesPath) ? defaultExamplesPath : undefined);\n if (additionalPacksPath && (name === 'codeql_test_run' || name === 'codeql_query_run' || name === 'codeql_query_compile' || name === 'codeql_database_analyze')) {\n options['additional-packs'] = additionalPacksPath;\n }\n \n // Keep test databases for codeql_test_run to allow subsequent query runs\n if (name === 'codeql_test_run') {\n options['keep-databases'] = true;\n }\n \n result = await executeCodeQLCommand(subcommand, options, positionalArgs, cwd);\n } else if (command === 'qlt') {\n result = await executeQLTCommand(subcommand, options, positionalArgs);\n } else {\n throw new Error(`Unsupported command: ${command}`);\n }\n\n // Post-execution processing for codeql_query_run\n if (name === 'codeql_query_run' && result.success && queryLogDir) {\n // Generate SARIF interpretation if results.bqrs exists and query path is known\n const bqrsPath = options.output as string;\n const sarifPath = join(queryLogDir, 'results-interpreted.sarif');\n\n // The query file path is the last positional argument (set during query resolution)\n const queryFilePath = positionalArgs.length > 0 ? positionalArgs[positionalArgs.length - 1] : undefined;\n\n if (existsSync(bqrsPath) && queryFilePath) {\n try {\n const sarifResult = await interpretBQRSFile(\n bqrsPath,\n queryFilePath,\n 'sarif-latest',\n sarifPath,\n logger\n );\n\n if (sarifResult.success) {\n logger.info(`Generated SARIF interpretation at ${sarifPath}`);\n } else {\n logger.warn(`SARIF interpretation returned error: ${sarifResult.error || sarifResult.stderr}`);\n }\n } catch (error) {\n logger.warn(`Failed to generate SARIF interpretation: ${error}`);\n }\n } else if (existsSync(bqrsPath) && !queryFilePath) {\n logger.warn('Skipping SARIF interpretation: query file path not available');\n }\n\n // Process evaluation results\n result = await processQueryRunResults(result, params, logger);\n }\n\n // Post-execution: generate evaluator log summary for query run / database analyze\n if ((name === 'codeql_query_run' || name === 'codeql_database_analyze') && result.success && queryLogDir) {\n const evalLogPath = options['evaluator-log'] as string | undefined;\n if (evalLogPath && existsSync(evalLogPath)) {\n try {\n const summaryPath = evalLogPath.replace(/\\.jsonl$/, '.summary.jsonl');\n // codeql generate log-summary takes positional args: []\n const summaryResult = await executeCodeQLCommand(\n 'generate log-summary',\n { format: 'predicates' },\n [evalLogPath, summaryPath]\n );\n\n if (summaryResult.success) {\n logger.info(`Generated evaluator log summary at ${summaryPath}`);\n }\n } catch (error) {\n logger.warn(`Failed to generate evaluator log summary: ${error}`);\n }\n }\n }\n\n // Process the result\n const processedResult = resultProcessor(result, params);\n\n return {\n content: [{\n type: 'text' as const,\n text: processedResult\n }],\n isError: !result.success\n };\n\n } catch (error) {\n logger.error(`Error in CLI tool ${name}:`, error);\n \n return {\n content: [{\n type: 'text' as const,\n text: `Failed to execute CLI tool: ${error instanceof Error ? error.message : String(error)}`\n }],\n isError: true\n };\n } finally {\n // Clean up temporary directories\n for (const tempDir of tempDirsToCleanup) {\n try {\n rmSync(tempDir, { recursive: true, force: true });\n logger.info(`Cleaned up temporary directory: ${tempDir}`);\n } catch (cleanupError) {\n logger.error(`Failed to clean up temporary directory ${tempDir}:`, cleanupError);\n }\n }\n }\n }\n );\n}\n\n/**\n * Helper function to create common CodeQL input schemas\n */\nexport const createCodeQLSchemas = {\n database: () => z.string().describe('Path to the CodeQL database'),\n \n query: () => z.string().describe('Path to the CodeQL query file (.ql)'),\n \n output: () => z.string().optional().describe('Output file path'),\n \n outputFormat: () => z.enum(['csv', 'json', 'bqrs', 'sarif-latest', 'sarifv2.1.0']).optional()\n .describe('Output format for results'),\n \n language: () => z.string().optional().describe('Programming language'),\n \n threads: () => z.number().optional().describe('Number of threads to use'),\n \n ram: () => z.number().optional().describe('Amount of RAM to use (MB)'),\n \n timeout: () => z.number().optional().describe('Timeout in seconds'),\n \n verbose: () => z.boolean().optional().describe('Enable verbose output'),\n \n additionalArgs: () => z.array(z.string()).optional().describe('Additional command-line arguments'),\n \n positionalArgs: () => z.array(z.string()).optional().describe('Positional arguments')\n .transform((val) => ({ _positional: val }))\n};\n\n/**\n * Helper function to create common QLT input schemas\n */\nexport const createQLTSchemas = {\n language: () => z.string().describe('Programming language'),\n \n output: () => z.string().optional().describe('Output directory or file path'),\n \n template: () => z.string().optional().describe('Template to use'),\n \n name: () => z.string().optional().describe('Name for generated query'),\n \n description: () => z.string().optional().describe('Description for generated query'),\n \n verbose: () => z.boolean().optional().describe('Enable verbose output'),\n \n force: () => z.boolean().optional().describe('Force overwrite existing files'),\n \n additionalArgs: () => z.array(z.string()).optional().describe('Additional command-line arguments')\n};\n\n/**\n * Create a result processor that formats BQRS output specially\n */\nexport const createBQRSResultProcessor = () => (\n result: CLIExecutionResult, \n params: Record\n): string => {\n if (!result.success) {\n return defaultCLIResultProcessor(result, params);\n }\n \n // For BQRS commands, provide more context about the output\n let output = result.stdout;\n \n if (params.output) {\n output += `\\n\\nResults saved to: ${params.output}`;\n }\n \n if (result.stderr) {\n output += `\\n\\nAdditional information:\\n${result.stderr}`;\n }\n \n return output;\n};\n\n/**\n * Create a result processor that formats database creation output\n */\nexport const createDatabaseResultProcessor = () => (\n result: CLIExecutionResult, \n params: Record\n): string => {\n if (!result.success) {\n return defaultCLIResultProcessor(result, params);\n }\n \n let output = 'Database creation completed successfully';\n \n if (params.database || params._positional) {\n const dbPath = params.database || (Array.isArray(params._positional) ? params._positional[0] : params._positional);\n output += `\\n\\nDatabase location: ${dbPath}`;\n }\n \n if (result.stdout) {\n output += `\\n\\nOutput:\\n${result.stdout}`;\n }\n \n if (result.stderr) {\n output += `\\n\\nAdditional information:\\n${result.stderr}`;\n }\n \n return output;\n};\n\n/**\n * Resolve query path for codeql_query_run tool\n * If queryName and queryLanguage are provided, resolve using codeql resolve queries\n */\nasync function resolveQueryPath(\n params: Record, \n logger: { info: (_message: string, ..._args: unknown[]) => void; error: (_message: string, ..._args: unknown[]) => void }\n): Promise {\n const { queryName, queryLanguage, queryPack, query } = params;\n \n // Validate parameter usage - queryName and query are mutually exclusive\n if (queryName && query) {\n logger.error('Cannot use both \"query\" and \"queryName\" parameters simultaneously. Use either \"query\" for direct file path OR \"queryName\" + \"queryLanguage\" for tool queries.');\n throw new Error('Cannot use both \"query\" and \"queryName\" parameters simultaneously. Use either \"query\" for direct file path OR \"queryName\" + \"queryLanguage\" for tool queries.');\n }\n \n // If no queryName provided, fall back to direct query parameter\n if (!queryName) {\n return query as string || null;\n }\n \n // If queryName provided but no language, we can't resolve\n if (!queryLanguage) {\n logger.error('queryLanguage is required when using queryName parameter. Supported languages: actions, cpp, csharp, go, java, javascript, python, ruby, swift');\n throw new Error('queryLanguage is required when using queryName parameter. Supported languages: actions, cpp, csharp, go, java, javascript, python, ruby, swift');\n }\n \n try {\n // Determine the query pack path - use absolute path to ensure it works regardless of cwd\n const defaultPackPath = resolveToolQueryPackPath(queryLanguage as string);\n const packPath = queryPack as string || defaultPackPath;\n \n logger.info(`Resolving query: ${queryName} for language: ${queryLanguage} in pack: ${packPath}`);\n \n // Execute codeql resolve queries to get available queries\n const { executeCodeQLCommand } = await import('./cli-executor');\n const resolveResult = await executeCodeQLCommand(\n 'resolve queries',\n { format: 'json' },\n [packPath]\n );\n \n if (!resolveResult.success) {\n logger.error('Failed to resolve queries:', resolveResult.stderr || resolveResult.error);\n throw new Error(`Failed to resolve queries: ${resolveResult.stderr || resolveResult.error}`);\n }\n \n // Parse the JSON output to find matching queries\n let resolvedQueries: string[];\n try {\n resolvedQueries = JSON.parse(resolveResult.stdout);\n } catch (parseError) {\n logger.error('Failed to parse resolve queries output:', parseError);\n throw new Error('Failed to parse resolve queries output');\n }\n \n // Find the query that matches the requested name exactly\n const matchingQuery = resolvedQueries.find(queryPath => {\n const fileName = basename(queryPath);\n // Match exact query name: \"PrintAST\" should match \"PrintAST.ql\" only\n return fileName === `${queryName}.ql`;\n });\n\n if (!matchingQuery) {\n logger.error(`Query \"${queryName}.ql\" not found in pack \"${packPath}\". Available queries:`, resolvedQueries.map(q => basename(q)));\n throw new Error(`Query \"${queryName}.ql\" not found in pack \"${packPath}\"`);\n }\n \n logger.info(`Resolved query \"${queryName}\" to: ${matchingQuery}`);\n return matchingQuery;\n \n } catch (error) {\n logger.error('Error resolving query path:', error);\n throw error;\n }\n}\n\n/**\n * Interpret BQRS file using codeql bqrs interpret\n */\nasync function interpretBQRSFile(\n bqrsPath: string,\n queryPath: string,\n format: string,\n outputPath: string,\n logger: { info: (_message: string, ..._args: unknown[]) => void; error: (_message: string, ..._args: unknown[]) => void }\n): Promise {\n try {\n // Extract query metadata to get id and kind\n const metadata = await extractQueryMetadata(queryPath);\n \n // Validate required metadata fields\n const missingFields = [];\n if (!metadata.id) missingFields.push('id');\n if (!metadata.kind) missingFields.push('kind');\n \n if (missingFields.length > 0) {\n return {\n success: false,\n exitCode: 1,\n stdout: '',\n stderr: '',\n error: `Query metadata is incomplete. Missing required field(s): ${missingFields.join(', ')}. Ensure the query file contains @id and @kind metadata.`\n };\n }\n \n // Sanitize metadata values to prevent command injection\n const sanitizedKind = (metadata.kind || '').replace(/[^a-zA-Z0-9_-]/g, '');\n const sanitizedId = (metadata.id || '').replace(/[^a-zA-Z0-9_/:-]/g, '');\n \n // Validate format for query kind\n const graphFormats = ['graphtext', 'dgml', 'dot'];\n if (graphFormats.includes(format) && metadata.kind !== 'graph') {\n return {\n success: false,\n exitCode: 1,\n stdout: '',\n stderr: '',\n error: `Format '${format}' is only compatible with @kind graph queries, but this query has @kind ${metadata.kind}`\n };\n }\n \n // Ensure output directory exists\n mkdirSync(dirname(outputPath), { recursive: true });\n \n // Build the codeql bqrs interpret command\n const params: Record = {\n format: format,\n output: outputPath,\n t: [`kind=${sanitizedKind}`, `id=${sanitizedId}`]\n };\n \n logger.info(`Interpreting BQRS file ${bqrsPath} with format ${format} to ${outputPath}`);\n \n // Execute codeql bqrs interpret\n const result = await executeCodeQLCommand(\n 'bqrs interpret',\n params,\n [bqrsPath]\n );\n \n return result;\n } catch (error) {\n return {\n success: false,\n exitCode: 1,\n stdout: '',\n stderr: '',\n error: `Failed to interpret BQRS file: ${error}`\n };\n }\n}\n\n/**\n * Get default output extension based on format\n */\nfunction getDefaultExtension(format: string): string {\n switch (format) {\n case 'sarif-latest':\n case 'sarifv2.1.0':\n return '.sarif';\n case 'csv':\n return '.csv';\n case 'graphtext':\n return '.txt';\n case 'dgml':\n return '.dgml';\n case 'dot':\n return '.dot';\n default:\n return '.txt';\n }\n}\n\n/**\n * Process query run results with optional interpretation or evaluation\n */\nasync function processQueryRunResults(\n result: CLIExecutionResult,\n params: Record,\n logger: { info: (_message: string, ..._args: unknown[]) => void; error: (_message: string, ..._args: unknown[]) => void }\n): Promise {\n try {\n const { format, interpretedOutput, evaluationFunction, evaluationOutput, output, query, queryName, queryLanguage } = params;\n \n // If no format or evaluationFunction specified, return as-is\n if (!format && !evaluationFunction) {\n return result;\n }\n \n // Ensure output (bqrs file) was generated\n if (!output) {\n return result;\n }\n \n const bqrsPath = output as string;\n \n // Determine the query path for metadata extraction\n let queryPath: string | null = null;\n \n if (query) {\n queryPath = query as string;\n } else if (queryName && queryLanguage) {\n // Try to resolve the query path again for evaluation\n queryPath = await resolveQueryPath(params, logger);\n }\n \n if (!queryPath) {\n logger.error('Cannot determine query path for interpretation/evaluation');\n return {\n ...result,\n stdout: result.stdout + '\\n\\nWarning: Query interpretation skipped - could not determine query path'\n };\n }\n \n // Handle new format parameter (preferred approach)\n if (format) {\n const outputFormat = format as string;\n \n // Determine output path\n let outputFilePath = interpretedOutput as string | undefined;\n if (!outputFilePath) {\n const ext = getDefaultExtension(outputFormat);\n outputFilePath = bqrsPath.replace('.bqrs', ext);\n }\n \n logger.info(`Interpreting query results from ${bqrsPath} with format: ${outputFormat}`);\n \n // Interpret the BQRS file\n const interpretResult = await interpretBQRSFile(\n bqrsPath,\n queryPath,\n outputFormat,\n outputFilePath,\n logger\n );\n \n if (interpretResult.success) {\n let enhancedOutput = result.stdout;\n enhancedOutput += `\\n\\nQuery results interpreted successfully with format: ${outputFormat}`;\n enhancedOutput += `\\nInterpreted output saved to: ${outputFilePath}`;\n \n return {\n ...result,\n stdout: enhancedOutput\n };\n } else {\n logger.error('Query interpretation failed:', interpretResult.error);\n return {\n ...result,\n stdout: result.stdout + `\\n\\nWarning: Query interpretation failed - ${interpretResult.error || interpretResult.stderr}`\n };\n }\n }\n \n // Handle legacy evaluationFunction parameter (deprecated)\n if (evaluationFunction) {\n logger.info(`Using deprecated evaluationFunction parameter. Consider using format parameter instead.`);\n logger.info(`Evaluating query results from ${bqrsPath} using function: ${evaluationFunction}`);\n \n // Perform the evaluation\n const evaluationResult: QueryEvaluationResult = await evaluateQueryResults(\n bqrsPath,\n queryPath,\n evaluationFunction as string,\n evaluationOutput as string | undefined\n );\n \n if (evaluationResult.success) {\n // Append evaluation results to the command output\n let enhancedOutput = result.stdout;\n \n if (evaluationResult.outputPath) {\n enhancedOutput += `\\n\\nQuery evaluation completed successfully.`;\n enhancedOutput += `\\nEvaluation output saved to: ${evaluationResult.outputPath}`;\n }\n \n if (evaluationResult.content) {\n enhancedOutput += `\\n\\n=== Query Results Evaluation ===\\n`;\n enhancedOutput += evaluationResult.content;\n }\n \n return {\n ...result,\n stdout: enhancedOutput\n };\n } else {\n // Evaluation failed, but don't fail the whole operation\n logger.error('Query evaluation failed:', evaluationResult.error);\n return {\n ...result,\n stdout: result.stdout + `\\n\\nWarning: Query evaluation failed - ${evaluationResult.error}`\n };\n }\n }\n \n return result;\n } catch (error) {\n logger.error('Error in query results processing:', error);\n return {\n ...result,\n stdout: result.stdout + `\\n\\nWarning: Query processing error - ${error}`\n };\n }\n}", "/**\n * Query results evaluation functions for processing .bqrs files\n */\n\nimport { executeCodeQLCommand } from './cli-executor';\nimport { logger } from '../utils/logger';\nimport { writeFileSync, readFileSync } from 'fs';\nimport { dirname, isAbsolute } from 'path';\nimport { mkdirSync } from 'fs';\n\nexport interface QueryEvaluationResult {\n success: boolean;\n outputPath?: string;\n content?: string;\n error?: string;\n}\n\nexport interface QueryMetadata {\n kind?: string;\n name?: string;\n description?: string;\n id?: string;\n tags?: string[];\n}\n\n/**\n * Built-in evaluation functions\n */\nexport const BUILT_IN_EVALUATORS = {\n 'json-decode': 'JSON format decoder for query results',\n 'csv-decode': 'CSV format decoder for query results', \n 'mermaid-graph': 'Mermaid diagram generator for @kind graph queries (like PrintAST)',\n} as const;\n\nexport type BuiltInEvaluator = keyof typeof BUILT_IN_EVALUATORS;\n\n/**\n * Extract metadata from a CodeQL query file\n */\nexport async function extractQueryMetadata(queryPath: string): Promise {\n try {\n const queryContent = readFileSync(queryPath, 'utf-8');\n const metadata: QueryMetadata = {};\n \n // Extract metadata from comments using regex patterns\n const kindMatch = queryContent.match(/@kind\\s+([^\\s]+)/);\n if (kindMatch) metadata.kind = kindMatch[1];\n \n const nameMatch = queryContent.match(/@name\\s+(.+)/);\n if (nameMatch) metadata.name = nameMatch[1].trim();\n \n const descMatch = queryContent.match(/@description\\s+(.+)/);\n if (descMatch) metadata.description = descMatch[1].trim();\n \n const idMatch = queryContent.match(/@id\\s+(.+)/);\n if (idMatch) metadata.id = idMatch[1].trim();\n \n const tagsMatch = queryContent.match(/@tags\\s+(.+)/);\n if (tagsMatch) {\n metadata.tags = tagsMatch[1].split(/\\s+/).filter(t => t.length > 0);\n }\n \n return metadata;\n } catch (error) {\n logger.error('Failed to extract query metadata:', error);\n return {};\n }\n}\n\n/**\n * JSON decoder - converts .bqrs to JSON format\n */\nexport async function evaluateWithJsonDecoder(\n bqrsPath: string, \n outputPath?: string\n): Promise {\n try {\n const result = await executeCodeQLCommand(\n 'bqrs decode',\n { format: 'json' },\n [bqrsPath]\n );\n \n if (!result.success) {\n return {\n success: false,\n error: `Failed to decode BQRS file: ${result.stderr || result.error}`\n };\n }\n \n const defaultOutputPath = outputPath || bqrsPath.replace('.bqrs', '.json');\n \n // Ensure output directory exists\n mkdirSync(dirname(defaultOutputPath), { recursive: true });\n \n // Write JSON results\n writeFileSync(defaultOutputPath, result.stdout);\n \n return {\n success: true,\n outputPath: defaultOutputPath,\n content: result.stdout\n };\n } catch (error) {\n return {\n success: false,\n error: `JSON evaluation failed: ${error}`\n };\n }\n}\n\n/**\n * CSV decoder - converts .bqrs to CSV format\n */\nexport async function evaluateWithCsvDecoder(\n bqrsPath: string,\n outputPath?: string\n): Promise {\n try {\n const result = await executeCodeQLCommand(\n 'bqrs decode',\n { format: 'csv' },\n [bqrsPath]\n );\n \n if (!result.success) {\n return {\n success: false,\n error: `Failed to decode BQRS file: ${result.stderr || result.error}`\n };\n }\n \n const defaultOutputPath = outputPath || bqrsPath.replace('.bqrs', '.csv');\n \n // Ensure output directory exists\n mkdirSync(dirname(defaultOutputPath), { recursive: true });\n \n // Write CSV results\n writeFileSync(defaultOutputPath, result.stdout);\n \n return {\n success: true,\n outputPath: defaultOutputPath,\n content: result.stdout\n };\n } catch (error) {\n return {\n success: false,\n error: `CSV evaluation failed: ${error}`\n };\n }\n}\n\n/**\n * Mermaid graph generator - converts @kind graph query results to mermaid diagrams\n */\nexport async function evaluateWithMermaidGraph(\n bqrsPath: string,\n queryPath: string,\n outputPath?: string\n): Promise {\n try {\n // First extract query metadata to confirm this is a graph query\n const metadata = await extractQueryMetadata(queryPath);\n \n if (metadata.kind !== 'graph') {\n logger.error(`Query is not a graph query (kind: ${metadata.kind}), mermaid-graph evaluation is only for @kind graph queries`);\n return {\n success: false,\n error: `Query is not a graph query (kind: ${metadata.kind}), mermaid-graph evaluation is only for @kind graph queries`\n };\n }\n \n // Decode the BQRS file to JSON first\n const jsonResult = await executeCodeQLCommand(\n 'bqrs decode',\n { format: 'json' },\n [bqrsPath]\n );\n \n if (!jsonResult.success) {\n return {\n success: false,\n error: `Failed to decode BQRS file: ${jsonResult.stderr || jsonResult.error}`\n };\n }\n \n // Parse the JSON results\n let queryResults;\n try {\n queryResults = JSON.parse(jsonResult.stdout);\n } catch (parseError) {\n return {\n success: false,\n error: `Failed to parse query results JSON: ${parseError}`\n };\n }\n \n // Generate mermaid diagram from graph results\n const mermaidContent = generateMermaidFromGraphResults(queryResults, metadata);\n \n const defaultOutputPath = outputPath || bqrsPath.replace('.bqrs', '.md');\n \n // Ensure output directory exists\n mkdirSync(dirname(defaultOutputPath), { recursive: true });\n \n // Write markdown file with mermaid diagram\n writeFileSync(defaultOutputPath, mermaidContent);\n \n return {\n success: true,\n outputPath: defaultOutputPath,\n content: mermaidContent\n };\n } catch (error) {\n return {\n success: false,\n error: `Mermaid graph evaluation failed: ${error}`\n };\n }\n}\n\n/**\n * Generate mermaid diagram from CodeQL graph query results\n */\nfunction generateMermaidFromGraphResults(queryResults: unknown, metadata: QueryMetadata): string {\n const queryName = sanitizeMarkdown(metadata.name || 'CodeQL Query Results');\n const queryDesc = sanitizeMarkdown(metadata.description || 'Graph visualization of CodeQL query results');\n \n let mermaidContent = `# ${queryName}\\n\\n${queryDesc}\\n\\n`;\n \n // Handle different result structures that CodeQL graph queries can produce\n if (!queryResults || typeof queryResults !== 'object') {\n mermaidContent += '```mermaid\\ngraph TD\\n A[No Results]\\n```\\n';\n return mermaidContent;\n }\n \n // Check if results have the expected structure for graph queries\n const tuples = queryResults.tuples || queryResults;\n \n if (!Array.isArray(tuples) || tuples.length === 0) {\n mermaidContent += '```mermaid\\ngraph TD\\n A[No Graph Data]\\n```\\n';\n return mermaidContent;\n }\n \n mermaidContent += '```mermaid\\ngraph TD\\n';\n \n // Track nodes and edges to avoid duplicates\n const nodes = new Set();\n const edges = new Set();\n \n // Process each tuple in the results\n tuples.forEach((tuple: unknown, index: number) => {\n if (Array.isArray(tuple) && tuple.length >= 2) {\n // Extract source and target from tuple\n const source = sanitizeNodeId(tuple[0]?.toString() || `node_${index}_0`);\n const target = sanitizeNodeId(tuple[1]?.toString() || `node_${index}_1`);\n const label = tuple[2]?.toString() || '';\n \n // Add nodes\n nodes.add(source);\n nodes.add(target);\n \n // Add edge\n const edgeId = `${source}_${target}`;\n if (!edges.has(edgeId)) {\n if (label) {\n mermaidContent += ` ${source} -->|${sanitizeLabel(label)}| ${target}\\n`;\n } else {\n mermaidContent += ` ${source} --> ${target}\\n`;\n }\n edges.add(edgeId);\n }\n } else if (typeof tuple === 'object' && tuple !== null) {\n // Handle object-based results\n const source = sanitizeNodeId(tuple.source?.toString() || tuple.from?.toString() || `node_${index}_src`);\n const target = sanitizeNodeId(tuple.target?.toString() || tuple.to?.toString() || `node_${index}_tgt`);\n const label = tuple.label?.toString() || tuple.relation?.toString() || '';\n \n nodes.add(source);\n nodes.add(target);\n \n const edgeId = `${source}_${target}`;\n if (!edges.has(edgeId)) {\n if (label) {\n mermaidContent += ` ${source} -->|${sanitizeLabel(label)}| ${target}\\n`;\n } else {\n mermaidContent += ` ${source} --> ${target}\\n`;\n }\n edges.add(edgeId);\n }\n }\n });\n \n // If no edges were created, create a simple diagram showing the first few nodes\n if (edges.size === 0 && nodes.size > 0) {\n const nodeArray = Array.from(nodes).slice(0, 10); // Limit to avoid clutter\n nodeArray.forEach((node, index) => {\n if (index === 0) {\n mermaidContent += ` ${node}[${sanitizeLabel(node)}]\\n`;\n } else {\n mermaidContent += ` ${nodeArray[0]} --> ${node}\\n`;\n }\n });\n }\n \n mermaidContent += '```\\n\\n';\n \n // Add statistics\n mermaidContent += `## Query Statistics\\n\\n`;\n mermaidContent += `- Total nodes: ${nodes.size}\\n`;\n mermaidContent += `- Total edges: ${edges.size}\\n`;\n mermaidContent += `- Total tuples processed: ${tuples.length}\\n`;\n \n return mermaidContent;\n}\n\n/**\n * Sanitize node IDs for mermaid compatibility\n */\nfunction sanitizeNodeId(id: string): string {\n return id\n .replace(/[^a-zA-Z0-9_]/g, '_')\n .replace(/^(\\d)/, 'n$1') // Prefix with 'n' if starts with number\n .substring(0, 50); // Limit length\n}\n\n/**\n * Sanitize labels for mermaid compatibility\n */\nfunction sanitizeLabel(label: string): string {\n return label\n .replace(/[|\"`<>\\n\\r\\t]/g, '') // Remove problematic characters including backticks, newlines, angle brackets\n .replace(/\\s+/g, ' ') // Normalize whitespace\n .trim()\n .substring(0, 30); // Limit length for readability\n}\n\n/**\n * Sanitize markdown content to prevent injection\n */\nfunction sanitizeMarkdown(content: string): string {\n return content\n .replace(/[<>\"`]/g, '') // Remove potentially dangerous characters\n .replace(/\\n/g, ' ') // Convert newlines to spaces\n .replace(/\\s+/g, ' ') // Normalize whitespace\n .trim()\n .substring(0, 100); // Limit length\n}\n\n/**\n * Main evaluation function that determines which evaluator to use\n */\nexport async function evaluateQueryResults(\n bqrsPath: string,\n queryPath: string,\n evaluationFunction?: string,\n outputPath?: string\n): Promise {\n try {\n // If no evaluation function specified, default to json-decode\n const evalFunc = evaluationFunction || 'json-decode';\n \n logger.info(`Evaluating query results with function: ${evalFunc}`);\n \n // Handle built-in evaluation functions\n switch (evalFunc) {\n case 'json-decode':\n return await evaluateWithJsonDecoder(bqrsPath, outputPath);\n \n case 'csv-decode':\n return await evaluateWithCsvDecoder(bqrsPath, outputPath);\n \n case 'mermaid-graph':\n return await evaluateWithMermaidGraph(bqrsPath, queryPath, outputPath);\n \n default:\n // Check if it's a path to a custom evaluation script\n if (isAbsolute(evalFunc)) {\n return await evaluateWithCustomScript(bqrsPath, queryPath, evalFunc, outputPath);\n } else {\n return {\n success: false,\n error: `Unknown evaluation function: ${evalFunc}. Available built-in functions: ${Object.keys(BUILT_IN_EVALUATORS).join(', ')}`\n };\n }\n }\n } catch (error) {\n return {\n success: false,\n error: `Query evaluation failed: ${error}`\n };\n }\n}\n\n/**\n * Execute custom evaluation script\n */\nasync function evaluateWithCustomScript(\n _bqrsPath: string,\n _queryPath: string,\n _scriptPath: string,\n _outputPath?: string\n): Promise {\n // TODO: Implement custom script execution\n // This would need to execute the script with bqrsPath and queryPath as arguments\n // and capture the output\n return {\n success: false,\n error: 'Custom evaluation scripts are not yet implemented'\n };\n}", "/**\n * Log directory management utilities for CodeQL query and test runs\n */\n\nimport { mkdirSync, existsSync } from 'fs';\nimport { join, resolve } from 'path';\nimport { randomBytes } from 'crypto';\nimport { getProjectTmpDir } from '../utils/temp-dir';\n\n/**\n * Ensure that a given path is within a base directory.\n * Throws an error if the path is outside the base directory.\n */\nfunction ensurePathWithinBase(baseDir: string, targetPath: string): string {\n const absBase = resolve(baseDir);\n const absTarget = resolve(targetPath);\n if (!absTarget.startsWith(absBase + '/') && absTarget !== absBase) {\n throw new Error(`Provided log directory is outside the allowed base directory: ${absBase}`);\n }\n return absTarget;\n}\n\n/**\n * Get or create a unique log directory for query/test runs\n * \n * @param logDir - Optional custom log directory from parameters\n * @returns Absolute path to the log directory\n */\nexport function getOrCreateLogDirectory(logDir?: string): string {\n // Use CODEQL_QUERY_LOG_DIR env var or default base\n const baseLogDir = process.env.CODEQL_QUERY_LOG_DIR || getProjectTmpDir('query-logs');\n\n // If logDir is explicitly provided, validate it is within baseLogDir\n if (logDir) {\n const absLogDir = ensurePathWithinBase(baseLogDir, logDir);\n if (!existsSync(absLogDir)) {\n mkdirSync(absLogDir, { recursive: true });\n }\n return absLogDir;\n }\n \n // Otherwise, use baseLogDir and create a unique subdirectory\n \n // Create base directory if it doesn't exist\n if (!existsSync(baseLogDir)) {\n mkdirSync(baseLogDir, { recursive: true });\n }\n \n // Generate unique subdirectory with timestamp and random ID\n const timestamp = new Date().toISOString().replace(/[:.]/g, '-');\n const uniqueId = randomBytes(4).toString('hex');\n const uniqueLogDir = join(baseLogDir, `query-run-${timestamp}-${uniqueId}`);\n \n mkdirSync(uniqueLogDir, { recursive: true });\n \n return uniqueLogDir;\n}\n", "/**\n * CodeQL BQRS info tool\n *\n * Lists result sets, column schemas, and row counts in a BQRS file.\n * Use this tool before codeql_bqrs_decode to discover available result\n * sets and their column types. BQRS files are produced by codeql_query_run\n * and codeql_database_analyze \u2014 use list_query_run_results to find them.\n */\n\nimport { z } from 'zod';\nimport { CLIToolDefinition, createCodeQLSchemas, createBQRSResultProcessor } from '../../lib/cli-tool-registry';\n\nexport const codeqlBqrsInfoTool: CLIToolDefinition = {\n name: 'codeql_bqrs_info',\n description:\n 'Get metadata about BQRS result files: lists result sets, column names/types, and row counts. ' +\n 'Use before codeql_bqrs_decode to discover available result sets (e.g., \"#select\", \"edges\", \"nodes\"). ' +\n 'BQRS files are found at /results.bqrs \u2014 use list_query_run_results to discover them. ' +\n 'Use --format=json with --paginate-rows to get byte offsets for paginated decoding with codeql_bqrs_decode --start-at.',\n command: 'codeql',\n subcommand: 'bqrs info',\n inputSchema: {\n files: z.array(z.string()).describe('BQRS file(s) to examine'),\n format: z.enum(['text', 'json']).optional()\n .describe('Output format: text (default) or json. Use json for machine-readable output and pagination offset computation.'),\n 'paginate-rows': z.number().optional()\n .describe('Compute byte offsets for pagination at intervals of this many rows. Use with --format=json. Offsets can be passed to codeql_bqrs_decode --start-at.'),\n 'paginate-result-set': z.string().optional()\n .describe('Compute pagination offsets only for this result set name'),\n verbose: createCodeQLSchemas.verbose(),\n additionalArgs: createCodeQLSchemas.additionalArgs()\n },\n examples: [\n 'codeql bqrs info results.bqrs',\n 'codeql bqrs info --format=json results.bqrs',\n 'codeql bqrs info --format=json --paginate-rows=100 --paginate-result-set=#select results.bqrs'\n ],\n resultProcessor: createBQRSResultProcessor()\n};", "/**\n * CodeQL BQRS interpret tool\n */\n\nimport { z } from 'zod';\nimport { CLIToolDefinition, createCodeQLSchemas, createBQRSResultProcessor } from '../../lib/cli-tool-registry';\n\nexport const codeqlBqrsInterpretTool: CLIToolDefinition = {\n name: 'codeql_bqrs_interpret',\n description: 'Interpret BQRS result files according to query metadata and generate output in specified formats (CSV, SARIF, graph formats)',\n command: 'codeql',\n subcommand: 'bqrs interpret',\n inputSchema: {\n file: z.string().describe('The BQRS file to interpret'),\n format: z.enum(['csv', 'sarif-latest', 'sarifv2.1.0', 'graphtext', 'dgml', 'dot'])\n .describe('Output format: csv (comma-separated), sarif-latest/sarifv2.1.0 (SARIF), graphtext/dgml/dot (graph formats, only for @kind graph queries)'),\n output: createCodeQLSchemas.output(),\n t: z.array(z.string())\n .describe('Query metadata key=value pairs. At least \"kind\" and \"id\" must be specified (e.g., [\"kind=graph\", \"id=js/print-ast\"])'),\n 'max-paths': z.number().optional()\n .describe('Maximum number of paths to produce for each alert with paths (default: 4)'),\n 'sarif-add-file-contents': z.boolean().optional()\n .describe('[SARIF only] Include full file contents for all files referenced in results'),\n 'sarif-add-snippets': z.boolean().optional()\n .describe('[SARIF only] Include code snippets for each location with context'),\n 'sarif-group-rules-by-pack': z.boolean().optional()\n .describe('[SARIF only] Place rule objects under their QL pack in tool.extensions property'),\n 'sarif-multicause-markdown': z.boolean().optional()\n .describe('[SARIF only] Include multi-cause alerts as Markdown-formatted lists'),\n 'sarif-category': z.string().optional()\n .describe('[SARIF only] Category for this analysis (distinguishes multiple analyses on same code)'),\n 'csv-location-format': z.enum(['uri', 'line-column', 'offset-length']).optional()\n .describe('[CSV only] Format for locations in CSV output (default: line-column)'),\n 'dot-location-url-format': z.string().optional()\n .describe('[DOT only] Format string for file location URLs (placeholders: {path}, {start:line}, {start:column}, {end:line}, {end:column}, {offset}, {length})'),\n threads: z.number().optional()\n .describe('Number of threads for computing paths (0 = one per core, -N = leave N cores unused)'),\n 'column-kind': z.enum(['utf8', 'utf16', 'utf32', 'bytes']).optional()\n .describe('[SARIF only] Column kind for interpreting location columns'),\n 'unicode-new-lines': z.boolean().optional()\n .describe('[SARIF only] Whether unicode newlines (U+2028, U+2029) are considered as newlines'),\n verbose: createCodeQLSchemas.verbose(),\n additionalArgs: createCodeQLSchemas.additionalArgs()\n },\n examples: [\n 'codeql bqrs interpret --format=sarif-latest --output=results.sarif -t kind=problem -t id=js/sql-injection results.bqrs',\n 'codeql bqrs interpret --format=graphtext --output=ast.txt -t kind=graph -t id=js/print-ast results.bqrs',\n 'codeql bqrs interpret --format=csv --csv-location-format=line-column --output=results.csv -t kind=problem -t id=js/xss results.bqrs',\n 'codeql bqrs interpret --format=dot --output=graph.dot -t kind=graph -t id=java/call-graph results.bqrs',\n 'codeql bqrs interpret --format=sarif-latest --sarif-add-snippets --sarif-category=security --output=results.sarif -t kind=path-problem -t id=go/path-injection results.bqrs'\n ],\n resultProcessor: createBQRSResultProcessor()\n};\n", "/**\n * CodeQL database analyze tool\n */\n\nimport { z } from 'zod';\nimport { CLIToolDefinition } from '../../lib/cli-tool-registry';\n\nexport const codeqlDatabaseAnalyzeTool: CLIToolDefinition = {\n name: 'codeql_database_analyze',\n description:\n 'Run queries or query suites against CodeQL databases. ' +\n 'Produces evaluator logs, BQRS results, and optionally SARIF output. ' +\n 'Use list_codeql_databases to discover available databases, and register_database to register new ones. ' +\n 'After analysis completes, use list_query_run_results to find result artifacts, then codeql_bqrs_info and codeql_bqrs_decode to inspect results.',\n command: 'codeql',\n subcommand: 'database analyze',\n inputSchema: {\n database: z.string().describe('Path to the CodeQL database'),\n queries: z.string().describe('Queries or query suite to run'),\n output: z.string().optional().describe('Output file path'),\n format: z.enum(['csv', 'json', 'sarif-latest', 'sarifv2.1.0']).optional()\n .describe('Output format for results'),\n 'download-location': z.string().optional()\n .describe('Location to download missing dependencies'),\n threads: z.number().optional().describe('Number of threads to use'),\n ram: z.number().optional().describe('Amount of RAM to use (MB)'),\n timeout: z.number().optional().describe('Timeout in seconds'),\n logDir: z.string().optional()\n .describe('Custom directory for analysis execution logs (overrides CODEQL_QUERY_LOG_DIR environment variable). If not provided, uses CODEQL_QUERY_LOG_DIR or defaults to .tmp/query-logs/'),\n 'evaluator-log': z.string().optional()\n .describe('Path to save evaluator log. If not provided and logDir is set, defaults to /evaluator-log.jsonl'),\n 'tuple-counting': z.boolean().optional()\n .describe('Display tuple counts for each evaluation step in evaluator logs'),\n 'evaluator-log-level': z.number().min(1).max(5).optional()\n .describe('Evaluator log verbosity level (1-5, default 5)'),\n rerun: z.boolean().optional()\n .describe('Force re-evaluation of queries even if BQRS results already exist in the database. Without this, cached results are reused.'),\n verbose: z.boolean().optional().describe('Enable verbose output'),\n additionalArgs: z.array(z.string()).optional().describe('Additional command-line arguments')\n },\n examples: [\n 'codeql database analyze mydb queries.qls --format=sarif-latest --output=results.sarif',\n 'codeql database analyze mydb codeql/java-queries --format=csv',\n 'codeql database analyze mydb queries.qls --format=sarif-latest --output=results.sarif --rerun --tuple-counting'\n ]\n};", "/**\n * CodeQL database create tool\n */\n\nimport { z } from 'zod';\nimport { CLIToolDefinition, createDatabaseResultProcessor } from '../../lib/cli-tool-registry';\n\nexport const codeqlDatabaseCreateTool: CLIToolDefinition = {\n name: 'codeql_database_create',\n description: 'Create a CodeQL database from source code',\n command: 'codeql',\n subcommand: 'database create',\n inputSchema: {\n database: z.string().describe('Database path/name to create'),\n language: z.string().optional().describe('Programming language(s) to extract'),\n 'source-root': z.string().optional().describe('Root directory of source code'),\n command: z.string().optional().describe('Build command for compiled languages'),\n 'build-mode': z.enum(['none', 'autobuild', 'manual']).optional()\n .describe('Build mode: none (interpreted langs), autobuild, or manual'),\n threads: z.number().optional().describe('Number of threads to use'),\n ram: z.number().optional().describe('Amount of RAM to use (MB)'),\n verbose: z.boolean().optional().describe('Enable verbose output'),\n overwrite: z.boolean().optional().describe('Overwrite existing database if it exists'),\n 'no-cleanup': z.boolean().optional().describe('Skip database cleanup after finalization'),\n additionalArgs: z.array(z.string()).optional().describe('Additional command-line arguments')\n },\n examples: [\n 'codeql database create --language=java --source-root=/path/to/project mydb',\n 'codeql database create --language=cpp --command=\"make all\" mydb',\n 'codeql database create --language=python,javascript mydb'\n ],\n resultProcessor: createDatabaseResultProcessor()\n};", "/**\n * CodeQL find class position tool\n * \n * Inspired by JordyZomer/codeql-mcp repository:\n * - https://github.com/JordyZomer/codeql-mcp/blob/main/server.py\n * - https://github.com/JordyZomer/codeql-mcp/blob/main/codeqlclient.py\n */\n\nimport { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport { z } from 'zod';\nimport { readFile } from 'fs/promises';\nimport { logger } from '../../utils/logger';\n\nexport interface ClassPosition {\n start_line: number;\n start_col: number;\n end_line: number;\n end_col: number;\n}\n\n/**\n * Find the 1-based position of a class name identifier in a QL file.\n * Returns: { start_line, start_col, end_line, end_col }\n */\nexport async function findClassPosition(filepath: string, className: string): Promise {\n try {\n const content = await readFile(filepath, 'utf-8');\n const lines = content.split('\\n');\n\n for (let i = 0; i < lines.length; i++) {\n const line = lines[i];\n // Match class definition with the specific class name\n const classNameRegex = new RegExp(`\\\\bclass\\\\s+(${className.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&')})\\\\b`);\n const match = classNameRegex.exec(line);\n \n if (match) {\n const start_line = i + 1; // 1-based line numbering\n // The class name is in capture group 1\n const classNameStart = match.index + match[0].indexOf(match[1]);\n const start_col = classNameStart + 1; // 1-based column numbering\n const end_col = start_col + className.length - 1; // end_col is inclusive\n \n return {\n start_line,\n start_col,\n end_line: start_line,\n end_col\n };\n }\n }\n\n throw new Error(`Class name '${className}' not found in file: ${filepath}`);\n } catch (error) {\n if (error instanceof Error && error.message.includes('not found in file')) {\n throw error;\n }\n throw new Error(`Failed to read or parse file ${filepath}: ${error instanceof Error ? error.message : 'Unknown error'}`);\n }\n}\n\n/**\n * Register the find class position tool with the MCP server\n */\nexport function registerFindClassPositionTool(server: McpServer): void {\n server.tool(\n 'find_class_position',\n 'Finds startline, startcol, endline endcol of a class for quickeval',\n {\n file: z.string().describe('Path to the .ql file to search'),\n name: z.string().describe('Name of the class to find'),\n },\n async ({ file, name }) => {\n try {\n const position = await findClassPosition(file, name);\n return {\n content: [{ type: 'text', text: JSON.stringify(position, null, 2) }],\n };\n } catch (error) {\n logger.error('Error finding class position:', error);\n return {\n content: [\n {\n type: 'text',\n text: `Error: ${error instanceof Error ? error.message : 'Unknown error'}`,\n },\n ],\n isError: true,\n };\n }\n }\n );\n}", "/**\n * CodeQL find predicate position tool\n * \n * Inspired by JordyZomer/codeql-mcp repository:\n * - https://github.com/JordyZomer/codeql-mcp/blob/main/server.py\n * - https://github.com/JordyZomer/codeql-mcp/blob/main/codeqlclient.py\n */\n\nimport { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport { z } from 'zod';\nimport { readFile } from 'fs/promises';\nimport { logger } from '../../utils/logger';\n\nexport interface PredicatePosition {\n start_line: number;\n start_col: number;\n end_line: number;\n end_col: number;\n}\n\n/**\n * Find the 1-based position of a predicate name in a QL file.\n * Supports: \n * - predicate name(...) - predicates with no return type\n * - Type name(...) - predicates with return type (e.g., string foo())\n * - name(...) (inside class) - member predicates\n * Returns: { start_line, start_col, end_line, end_col }\n */\nexport async function findPredicatePosition(filepath: string, predicateName: string): Promise {\n try {\n const content = await readFile(filepath, 'utf-8');\n const lines = content.split('\\n');\n const escapedName = predicateName.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&');\n\n for (let i = 0; i < lines.length; i++) {\n const line = lines[i];\n \n // Match predicate definition with the specific predicate name\n // Pattern 1: predicate name(...)\n const predicateKeywordRegex = new RegExp(`\\\\bpredicate\\\\s+(${escapedName})\\\\s*\\\\(`);\n let match = predicateKeywordRegex.exec(line);\n \n // Pattern 2: Type name(...) - predicates with return type\n // Matches: string foo(), int bar(), MyClass baz(), etc.\n // Must start at beginning of line (with optional whitespace) or after certain keywords\n if (!match) {\n const returnTypeRegex = new RegExp(`(?:^|\\\\s)(?:abstract\\\\s+)?(?:cached\\\\s+)?(?:private\\\\s+)?(?:deprecated\\\\s+)?(?:\\\\w+)\\\\s+(${escapedName})\\\\s*\\\\(`);\n match = returnTypeRegex.exec(line);\n }\n \n if (match) {\n const start_line = i + 1; // 1-based line numbering\n // The predicate name is in capture group 1\n const predicateNameStart = match.index + match[0].indexOf(match[1]);\n const start_col = predicateNameStart + 1; // 1-based column numbering\n const end_col = start_col + predicateName.length - 1; // end_col is inclusive\n \n return {\n start_line,\n start_col,\n end_line: start_line,\n end_col\n };\n }\n }\n\n throw new Error(`Predicate name '${predicateName}' not found in file: ${filepath}`);\n } catch (error) {\n if (error instanceof Error && error.message.includes('not found in file')) {\n throw error;\n }\n throw new Error(`Failed to read or parse file ${filepath}: ${error instanceof Error ? error.message : 'Unknown error'}`);\n }\n}\n\n/**\n * Register the find predicate position tool with the MCP server\n */\nexport function registerFindPredicatePositionTool(server: McpServer): void {\n server.tool(\n 'find_predicate_position',\n 'Finds startline, startcol, endline endcol of a predicate for quickeval',\n {\n file: z.string().describe('Path to the .ql file to search'),\n name: z.string().describe('Name of the predicate to find'),\n },\n async ({ file, name }) => {\n try {\n const position = await findPredicatePosition(file, name);\n return {\n content: [{ type: 'text', text: JSON.stringify(position, null, 2) }],\n };\n } catch (error) {\n logger.error('Error finding predicate position:', error);\n return {\n content: [\n {\n type: 'text',\n text: `Error: ${error instanceof Error ? error.message : 'Unknown error'}`,\n },\n ],\n isError: true,\n };\n }\n }\n );\n}", "/**\n * CodeQL find query files tool\n * Discovers and tracks all files related to a CodeQL query\n */\n\nimport { z } from 'zod';\nimport { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport { findCodeQLQueryFiles } from '../../lib/query-file-finder';\nimport { logger } from '../../utils/logger';\n\n/**\n * Register the find_codeql_query_files tool\n */\nexport function registerFindCodeQLQueryFilesTool(server: McpServer): void {\n server.tool(\n 'find_codeql_query_files',\n 'Find and track all files and directories related to a CodeQL query, including resolved metadata',\n {\n queryPath: z.string().describe('Path to the CodeQL query file (.ql)'),\n language: z.string().optional().describe('Programming language (optional, will be inferred if not provided)'),\n resolveMetadata: z.boolean().optional().describe('Whether to resolve query metadata (default: true)')\n },\n async ({ queryPath, language, resolveMetadata }) => {\n try {\n const result = await findCodeQLQueryFiles(\n queryPath,\n language,\n resolveMetadata !== false // Default to true if not specified\n );\n\n return {\n content: [{ type: 'text', text: JSON.stringify(result, null, 2) }]\n };\n } catch (error) {\n logger.error('Error finding CodeQL query files:', error);\n return {\n content: [\n {\n type: 'text',\n text: `Error: ${error instanceof Error ? error.message : 'Unknown error'}`\n }\n ],\n isError: true\n };\n }\n }\n );\n}\n", "/**\n * CodeQL query file finder utilities\n * Handles discovery and tracking of query-related files and directories\n */\n\nimport * as fs from 'fs';\nimport * as path from 'path';\nimport * as yaml from 'js-yaml';\nimport { QueryFileInfo, QueryFilesResult } from '../types/codeql';\nimport { resolveQueryMetadata } from './metadata-resolver';\n\n// Supported CodeQL languages and their file extensions (alphabetically ordered)\nconst LANGUAGE_EXTENSIONS: Record = {\n actions: 'yml',\n cpp: 'cpp',\n csharp: 'cs',\n go: 'go',\n java: 'java',\n javascript: 'js',\n python: 'py',\n ruby: 'rb',\n swift: 'swift',\n typescript: 'ts'\n};\n\nconst KNOWN_LANGUAGES = Object.keys(LANGUAGE_EXTENSIONS);\n\n/**\n * Get the file extension for test code based on language\n */\nfunction getLanguageExtension(language: string): string {\n return LANGUAGE_EXTENSIONS[language.toLowerCase()] || 'txt';\n}\n\n/**\n * Infer the language from the query file's directory structure\n */\nfunction inferLanguageFromPath(queryPath: string): string {\n const parts = queryPath.split(path.sep);\n\n for (const part of parts) {\n if (KNOWN_LANGUAGES.includes(part.toLowerCase())) {\n return part.toLowerCase();\n }\n }\n\n // Default fallback\n return 'unknown';\n}\n\n/**\n * Find the nearest qlpack.yml or codeql-pack.yml file by walking up the directory tree\n */\nfunction findNearestQlpack(startPath: string): string | null {\n let currentPath = startPath;\n const root = path.parse(currentPath).root;\n\n while (currentPath !== root) {\n // Check for codeql-pack.yml first (newer format), then qlpack.yml\n for (const packFile of ['codeql-pack.yml', 'qlpack.yml']) {\n const packPath = path.join(currentPath, packFile);\n if (fs.existsSync(packPath) && fs.statSync(packPath).isFile()) {\n return packPath;\n }\n }\n currentPath = path.dirname(currentPath);\n }\n\n return null;\n}\n\n/**\n * Read and parse qlpack.yml file\n */\nfunction readQlpackMetadata(qlpackPath: string): Record | null {\n try {\n const content = fs.readFileSync(qlpackPath, 'utf-8');\n const parsed = yaml.load(content) as Record;\n return parsed;\n } catch (_error) {\n // If we can't parse it, return null rather than failing\n return null;\n }\n}\n\n/**\n * Check if a file exists and return QueryFileInfo\n */\nfunction checkFile(filePath: string): QueryFileInfo {\n try {\n const exists = fs.existsSync(filePath) && fs.statSync(filePath).isFile();\n return {\n exists,\n path: filePath // Always return path, whether it exists or not\n };\n } catch {\n return {\n exists: false,\n path: filePath // Return the path even on error\n };\n }\n}\n\n/**\n * Check if a directory exists and return QueryFileInfo\n */\nfunction checkDirectory(dirPath: string): QueryFileInfo {\n try {\n const exists = fs.existsSync(dirPath) && fs.statSync(dirPath).isDirectory();\n return {\n exists,\n path: dirPath // Always return path, whether it exists or not\n };\n } catch {\n return {\n exists: false,\n path: dirPath // Return the path even on error\n };\n }\n}\n\n/**\n * Find all test code files in the test directory\n */\nfunction findTestCodeFiles(testDir: string, queryName: string, language: string): string[] {\n if (!fs.existsSync(testDir)) {\n return [];\n }\n\n try {\n const files = fs.readdirSync(testDir);\n const languageExt = getLanguageExtension(language);\n const testFiles: string[] = [];\n\n // Look for files matching the query name or other test code files\n const allValidExtensions = [...new Set([...Object.values(LANGUAGE_EXTENSIONS), 'yaml'])]; // Include yaml as alias for yml\n\n for (const file of files) {\n const filePath = path.join(testDir, file);\n const stat = fs.statSync(filePath);\n\n if (stat.isFile()) {\n // Include the primary test file matching query name\n if (file === `${queryName}.${languageExt}`) {\n testFiles.push(filePath);\n }\n // Include other code files (but not .qlref, .expected, .actual files)\n else if (!file.endsWith('.qlref') && !file.endsWith('.expected') && !file.endsWith('.actual')) {\n const ext = path.extname(file).slice(1);\n if (ext === languageExt || allValidExtensions.includes(ext)) {\n testFiles.push(filePath);\n }\n }\n }\n }\n\n return testFiles;\n } catch {\n return [];\n }\n}\n\n/**\n * Find CodeQL query files and directories based on a query file path\n * Optionally resolves metadata if the query file exists\n */\nexport async function findCodeQLQueryFiles(\n queryFilePath: string,\n language?: string,\n resolveMetadata: boolean = true\n): Promise {\n // Resolve absolute path\n const absoluteQueryPath = path.resolve(queryFilePath);\n\n // Extract query name and directory\n const queryName = path.basename(absoluteQueryPath, '.ql');\n const queryDir = path.dirname(absoluteQueryPath);\n\n // Infer language if not provided\n const detectedLanguage = language || inferLanguageFromPath(absoluteQueryPath);\n\n // Check query file itself\n const queryPath = checkFile(absoluteQueryPath);\n const queryDirectory = checkDirectory(queryDir);\n\n // Check for documentation files\n const mdPath = path.join(queryDir, `${queryName}.md`);\n const qhelpPath = path.join(queryDir, `${queryName}.qhelp`);\n const mdInfo = checkFile(mdPath);\n const qhelpInfo = checkFile(qhelpPath);\n\n const documentationPath: QueryFileInfo = mdInfo.exists ? mdInfo : (qhelpInfo.exists ? qhelpInfo : {\n exists: false,\n path: mdPath // Suggest .md as the default\n });\n\n // Check for specification file\n const qspecPath = path.join(queryDir, `${queryName}.qspec`);\n const specificationPath = checkFile(qspecPath);\n\n // Determine test directory\n // Pattern: if query is in .../src/QueryName/, test should be in .../test/QueryName/\n let testDir: string;\n if (queryDir.includes(`${path.sep}src${path.sep}`)) {\n // Find the last occurrence of /src/ and replace it with /test/\n const parts = queryDir.split(path.sep);\n const srcIndex = parts.lastIndexOf('src');\n if (srcIndex !== -1) {\n parts[srcIndex] = 'test';\n testDir = parts.join(path.sep);\n } else {\n // Fallback in case split didn't find it\n testDir = path.join(path.dirname(queryDir), 'test', queryName);\n }\n } else {\n // Fallback: if not in src directory, construct test dir based on parent\n testDir = path.join(path.dirname(queryDir), 'test', queryName);\n }\n const testDirectory = checkDirectory(testDir);\n\n // Check for .qlref file\n const qlrefPath = path.join(testDir, `${queryName}.qlref`);\n const qlrefInfo = checkFile(qlrefPath);\n\n // Find test code files\n const testCodePaths = findTestCodeFiles(testDir, queryName, detectedLanguage);\n\n // Check for expected results\n const expectedPath = path.join(testDir, `${queryName}.expected`);\n const expectedResultsPath = checkFile(expectedPath);\n\n // Check for actual results\n const actualPath = path.join(testDir, `${queryName}.actual`);\n const actualResultsPath = checkFile(actualPath);\n\n // Check for test database\n const testprojPath = path.join(testDir, `${queryName}.testproj`);\n const testDatabasePath = checkDirectory(testprojPath);\n\n // Determine missing files\n const missingFiles: string[] = [];\n if (!queryPath.exists) missingFiles.push(queryPath.path);\n if (!documentationPath.exists) missingFiles.push(documentationPath.path);\n if (!specificationPath.exists) missingFiles.push(specificationPath.path);\n if (!testDirectory.exists) missingFiles.push(testDirectory.path);\n if (!qlrefInfo.exists) missingFiles.push(qlrefInfo.path);\n if (testCodePaths.length === 0) missingFiles.push(path.join(testDir, `${queryName}.${getLanguageExtension(detectedLanguage)}`));\n if (!expectedResultsPath.exists) missingFiles.push(expectedResultsPath.path);\n\n const allFilesExist = missingFiles.length === 0;\n\n // Resolve metadata if requested and query file exists\n let metadata: { [key: string]: string | string[] } | undefined;\n if (resolveMetadata && queryPath.exists) {\n const resolvedMetadata = await resolveQueryMetadata(absoluteQueryPath);\n if (resolvedMetadata) {\n metadata = resolvedMetadata;\n }\n }\n\n // Resolve pack metadata and directories by finding the nearest qlpack.yml files\n let packMetadata: Record | undefined;\n const queryPackPath = findNearestQlpack(queryDir);\n const queryPackDir = queryPackPath ? path.dirname(queryPackPath) : queryDir;\n if (queryPackPath) {\n const parsed = readQlpackMetadata(queryPackPath);\n if (parsed) {\n packMetadata = parsed;\n }\n }\n\n // Find pack directory for test files\n const testPackPath = findNearestQlpack(testDir);\n const testPackDir = testPackPath ? path.dirname(testPackPath) : testDir;\n\n return {\n queryName,\n language: detectedLanguage,\n\n allFilesExist,\n\n files: {\n query: {\n dir: queryDirectory.path,\n doc: path.basename(documentationPath.path),\n packDir: queryPackDir,\n query: path.basename(queryPath.path),\n spec: path.basename(specificationPath.path)\n },\n test: {\n actual: path.basename(actualResultsPath.path),\n dir: testDirectory.path,\n expected: path.basename(expectedResultsPath.path),\n packDir: testPackDir,\n qlref: path.basename(qlrefInfo.path),\n testCode: testCodePaths,\n testDatabaseDir: testDatabasePath.path\n }\n },\n\n metadata,\n\n missingFiles,\n\n packMetadata,\n\n status: {\n actualResultsExist: actualResultsPath.exists,\n documentationExists: documentationPath.exists,\n expectedResultsExist: expectedResultsPath.exists,\n hasTestCode: testCodePaths.length > 0,\n qlrefExists: qlrefInfo.exists,\n queryExists: queryPath.exists,\n specificationExists: specificationPath.exists,\n testDatabaseDirExists: testDatabasePath.exists,\n testDirectoryExists: testDirectory.exists\n }\n };\n}\n", "\n/*! js-yaml 4.1.1 https://github.com/nodeca/js-yaml @license MIT */\nfunction isNothing(subject) {\n return (typeof subject === 'undefined') || (subject === null);\n}\n\n\nfunction isObject(subject) {\n return (typeof subject === 'object') && (subject !== null);\n}\n\n\nfunction toArray(sequence) {\n if (Array.isArray(sequence)) return sequence;\n else if (isNothing(sequence)) return [];\n\n return [ sequence ];\n}\n\n\nfunction extend(target, source) {\n var index, length, key, sourceKeys;\n\n if (source) {\n sourceKeys = Object.keys(source);\n\n for (index = 0, length = sourceKeys.length; index < length; index += 1) {\n key = sourceKeys[index];\n target[key] = source[key];\n }\n }\n\n return target;\n}\n\n\nfunction repeat(string, count) {\n var result = '', cycle;\n\n for (cycle = 0; cycle < count; cycle += 1) {\n result += string;\n }\n\n return result;\n}\n\n\nfunction isNegativeZero(number) {\n return (number === 0) && (Number.NEGATIVE_INFINITY === 1 / number);\n}\n\n\nvar isNothing_1 = isNothing;\nvar isObject_1 = isObject;\nvar toArray_1 = toArray;\nvar repeat_1 = repeat;\nvar isNegativeZero_1 = isNegativeZero;\nvar extend_1 = extend;\n\nvar common = {\n\tisNothing: isNothing_1,\n\tisObject: isObject_1,\n\ttoArray: toArray_1,\n\trepeat: repeat_1,\n\tisNegativeZero: isNegativeZero_1,\n\textend: extend_1\n};\n\n// YAML error class. http://stackoverflow.com/questions/8458984\n\n\nfunction formatError(exception, compact) {\n var where = '', message = exception.reason || '(unknown reason)';\n\n if (!exception.mark) return message;\n\n if (exception.mark.name) {\n where += 'in \"' + exception.mark.name + '\" ';\n }\n\n where += '(' + (exception.mark.line + 1) + ':' + (exception.mark.column + 1) + ')';\n\n if (!compact && exception.mark.snippet) {\n where += '\\n\\n' + exception.mark.snippet;\n }\n\n return message + ' ' + where;\n}\n\n\nfunction YAMLException$1(reason, mark) {\n // Super constructor\n Error.call(this);\n\n this.name = 'YAMLException';\n this.reason = reason;\n this.mark = mark;\n this.message = formatError(this, false);\n\n // Include stack trace in error object\n if (Error.captureStackTrace) {\n // Chrome and NodeJS\n Error.captureStackTrace(this, this.constructor);\n } else {\n // FF, IE 10+ and Safari 6+. Fallback for others\n this.stack = (new Error()).stack || '';\n }\n}\n\n\n// Inherit from Error\nYAMLException$1.prototype = Object.create(Error.prototype);\nYAMLException$1.prototype.constructor = YAMLException$1;\n\n\nYAMLException$1.prototype.toString = function toString(compact) {\n return this.name + ': ' + formatError(this, compact);\n};\n\n\nvar exception = YAMLException$1;\n\n// get snippet for a single line, respecting maxLength\nfunction getLine(buffer, lineStart, lineEnd, position, maxLineLength) {\n var head = '';\n var tail = '';\n var maxHalfLength = Math.floor(maxLineLength / 2) - 1;\n\n if (position - lineStart > maxHalfLength) {\n head = ' ... ';\n lineStart = position - maxHalfLength + head.length;\n }\n\n if (lineEnd - position > maxHalfLength) {\n tail = ' ...';\n lineEnd = position + maxHalfLength - tail.length;\n }\n\n return {\n str: head + buffer.slice(lineStart, lineEnd).replace(/\\t/g, '\u2192') + tail,\n pos: position - lineStart + head.length // relative position\n };\n}\n\n\nfunction padStart(string, max) {\n return common.repeat(' ', max - string.length) + string;\n}\n\n\nfunction makeSnippet(mark, options) {\n options = Object.create(options || null);\n\n if (!mark.buffer) return null;\n\n if (!options.maxLength) options.maxLength = 79;\n if (typeof options.indent !== 'number') options.indent = 1;\n if (typeof options.linesBefore !== 'number') options.linesBefore = 3;\n if (typeof options.linesAfter !== 'number') options.linesAfter = 2;\n\n var re = /\\r?\\n|\\r|\\0/g;\n var lineStarts = [ 0 ];\n var lineEnds = [];\n var match;\n var foundLineNo = -1;\n\n while ((match = re.exec(mark.buffer))) {\n lineEnds.push(match.index);\n lineStarts.push(match.index + match[0].length);\n\n if (mark.position <= match.index && foundLineNo < 0) {\n foundLineNo = lineStarts.length - 2;\n }\n }\n\n if (foundLineNo < 0) foundLineNo = lineStarts.length - 1;\n\n var result = '', i, line;\n var lineNoLength = Math.min(mark.line + options.linesAfter, lineEnds.length).toString().length;\n var maxLineLength = options.maxLength - (options.indent + lineNoLength + 3);\n\n for (i = 1; i <= options.linesBefore; i++) {\n if (foundLineNo - i < 0) break;\n line = getLine(\n mark.buffer,\n lineStarts[foundLineNo - i],\n lineEnds[foundLineNo - i],\n mark.position - (lineStarts[foundLineNo] - lineStarts[foundLineNo - i]),\n maxLineLength\n );\n result = common.repeat(' ', options.indent) + padStart((mark.line - i + 1).toString(), lineNoLength) +\n ' | ' + line.str + '\\n' + result;\n }\n\n line = getLine(mark.buffer, lineStarts[foundLineNo], lineEnds[foundLineNo], mark.position, maxLineLength);\n result += common.repeat(' ', options.indent) + padStart((mark.line + 1).toString(), lineNoLength) +\n ' | ' + line.str + '\\n';\n result += common.repeat('-', options.indent + lineNoLength + 3 + line.pos) + '^' + '\\n';\n\n for (i = 1; i <= options.linesAfter; i++) {\n if (foundLineNo + i >= lineEnds.length) break;\n line = getLine(\n mark.buffer,\n lineStarts[foundLineNo + i],\n lineEnds[foundLineNo + i],\n mark.position - (lineStarts[foundLineNo] - lineStarts[foundLineNo + i]),\n maxLineLength\n );\n result += common.repeat(' ', options.indent) + padStart((mark.line + i + 1).toString(), lineNoLength) +\n ' | ' + line.str + '\\n';\n }\n\n return result.replace(/\\n$/, '');\n}\n\n\nvar snippet = makeSnippet;\n\nvar TYPE_CONSTRUCTOR_OPTIONS = [\n 'kind',\n 'multi',\n 'resolve',\n 'construct',\n 'instanceOf',\n 'predicate',\n 'represent',\n 'representName',\n 'defaultStyle',\n 'styleAliases'\n];\n\nvar YAML_NODE_KINDS = [\n 'scalar',\n 'sequence',\n 'mapping'\n];\n\nfunction compileStyleAliases(map) {\n var result = {};\n\n if (map !== null) {\n Object.keys(map).forEach(function (style) {\n map[style].forEach(function (alias) {\n result[String(alias)] = style;\n });\n });\n }\n\n return result;\n}\n\nfunction Type$1(tag, options) {\n options = options || {};\n\n Object.keys(options).forEach(function (name) {\n if (TYPE_CONSTRUCTOR_OPTIONS.indexOf(name) === -1) {\n throw new exception('Unknown option \"' + name + '\" is met in definition of \"' + tag + '\" YAML type.');\n }\n });\n\n // TODO: Add tag format check.\n this.options = options; // keep original options in case user wants to extend this type later\n this.tag = tag;\n this.kind = options['kind'] || null;\n this.resolve = options['resolve'] || function () { return true; };\n this.construct = options['construct'] || function (data) { return data; };\n this.instanceOf = options['instanceOf'] || null;\n this.predicate = options['predicate'] || null;\n this.represent = options['represent'] || null;\n this.representName = options['representName'] || null;\n this.defaultStyle = options['defaultStyle'] || null;\n this.multi = options['multi'] || false;\n this.styleAliases = compileStyleAliases(options['styleAliases'] || null);\n\n if (YAML_NODE_KINDS.indexOf(this.kind) === -1) {\n throw new exception('Unknown kind \"' + this.kind + '\" is specified for \"' + tag + '\" YAML type.');\n }\n}\n\nvar type = Type$1;\n\n/*eslint-disable max-len*/\n\n\n\n\n\nfunction compileList(schema, name) {\n var result = [];\n\n schema[name].forEach(function (currentType) {\n var newIndex = result.length;\n\n result.forEach(function (previousType, previousIndex) {\n if (previousType.tag === currentType.tag &&\n previousType.kind === currentType.kind &&\n previousType.multi === currentType.multi) {\n\n newIndex = previousIndex;\n }\n });\n\n result[newIndex] = currentType;\n });\n\n return result;\n}\n\n\nfunction compileMap(/* lists... */) {\n var result = {\n scalar: {},\n sequence: {},\n mapping: {},\n fallback: {},\n multi: {\n scalar: [],\n sequence: [],\n mapping: [],\n fallback: []\n }\n }, index, length;\n\n function collectType(type) {\n if (type.multi) {\n result.multi[type.kind].push(type);\n result.multi['fallback'].push(type);\n } else {\n result[type.kind][type.tag] = result['fallback'][type.tag] = type;\n }\n }\n\n for (index = 0, length = arguments.length; index < length; index += 1) {\n arguments[index].forEach(collectType);\n }\n return result;\n}\n\n\nfunction Schema$1(definition) {\n return this.extend(definition);\n}\n\n\nSchema$1.prototype.extend = function extend(definition) {\n var implicit = [];\n var explicit = [];\n\n if (definition instanceof type) {\n // Schema.extend(type)\n explicit.push(definition);\n\n } else if (Array.isArray(definition)) {\n // Schema.extend([ type1, type2, ... ])\n explicit = explicit.concat(definition);\n\n } else if (definition && (Array.isArray(definition.implicit) || Array.isArray(definition.explicit))) {\n // Schema.extend({ explicit: [ type1, type2, ... ], implicit: [ type1, type2, ... ] })\n if (definition.implicit) implicit = implicit.concat(definition.implicit);\n if (definition.explicit) explicit = explicit.concat(definition.explicit);\n\n } else {\n throw new exception('Schema.extend argument should be a Type, [ Type ], ' +\n 'or a schema definition ({ implicit: [...], explicit: [...] })');\n }\n\n implicit.forEach(function (type$1) {\n if (!(type$1 instanceof type)) {\n throw new exception('Specified list of YAML types (or a single Type object) contains a non-Type object.');\n }\n\n if (type$1.loadKind && type$1.loadKind !== 'scalar') {\n throw new exception('There is a non-scalar type in the implicit list of a schema. Implicit resolving of such types is not supported.');\n }\n\n if (type$1.multi) {\n throw new exception('There is a multi type in the implicit list of a schema. Multi tags can only be listed as explicit.');\n }\n });\n\n explicit.forEach(function (type$1) {\n if (!(type$1 instanceof type)) {\n throw new exception('Specified list of YAML types (or a single Type object) contains a non-Type object.');\n }\n });\n\n var result = Object.create(Schema$1.prototype);\n\n result.implicit = (this.implicit || []).concat(implicit);\n result.explicit = (this.explicit || []).concat(explicit);\n\n result.compiledImplicit = compileList(result, 'implicit');\n result.compiledExplicit = compileList(result, 'explicit');\n result.compiledTypeMap = compileMap(result.compiledImplicit, result.compiledExplicit);\n\n return result;\n};\n\n\nvar schema = Schema$1;\n\nvar str = new type('tag:yaml.org,2002:str', {\n kind: 'scalar',\n construct: function (data) { return data !== null ? data : ''; }\n});\n\nvar seq = new type('tag:yaml.org,2002:seq', {\n kind: 'sequence',\n construct: function (data) { return data !== null ? data : []; }\n});\n\nvar map = new type('tag:yaml.org,2002:map', {\n kind: 'mapping',\n construct: function (data) { return data !== null ? data : {}; }\n});\n\nvar failsafe = new schema({\n explicit: [\n str,\n seq,\n map\n ]\n});\n\nfunction resolveYamlNull(data) {\n if (data === null) return true;\n\n var max = data.length;\n\n return (max === 1 && data === '~') ||\n (max === 4 && (data === 'null' || data === 'Null' || data === 'NULL'));\n}\n\nfunction constructYamlNull() {\n return null;\n}\n\nfunction isNull(object) {\n return object === null;\n}\n\nvar _null = new type('tag:yaml.org,2002:null', {\n kind: 'scalar',\n resolve: resolveYamlNull,\n construct: constructYamlNull,\n predicate: isNull,\n represent: {\n canonical: function () { return '~'; },\n lowercase: function () { return 'null'; },\n uppercase: function () { return 'NULL'; },\n camelcase: function () { return 'Null'; },\n empty: function () { return ''; }\n },\n defaultStyle: 'lowercase'\n});\n\nfunction resolveYamlBoolean(data) {\n if (data === null) return false;\n\n var max = data.length;\n\n return (max === 4 && (data === 'true' || data === 'True' || data === 'TRUE')) ||\n (max === 5 && (data === 'false' || data === 'False' || data === 'FALSE'));\n}\n\nfunction constructYamlBoolean(data) {\n return data === 'true' ||\n data === 'True' ||\n data === 'TRUE';\n}\n\nfunction isBoolean(object) {\n return Object.prototype.toString.call(object) === '[object Boolean]';\n}\n\nvar bool = new type('tag:yaml.org,2002:bool', {\n kind: 'scalar',\n resolve: resolveYamlBoolean,\n construct: constructYamlBoolean,\n predicate: isBoolean,\n represent: {\n lowercase: function (object) { return object ? 'true' : 'false'; },\n uppercase: function (object) { return object ? 'TRUE' : 'FALSE'; },\n camelcase: function (object) { return object ? 'True' : 'False'; }\n },\n defaultStyle: 'lowercase'\n});\n\nfunction isHexCode(c) {\n return ((0x30/* 0 */ <= c) && (c <= 0x39/* 9 */)) ||\n ((0x41/* A */ <= c) && (c <= 0x46/* F */)) ||\n ((0x61/* a */ <= c) && (c <= 0x66/* f */));\n}\n\nfunction isOctCode(c) {\n return ((0x30/* 0 */ <= c) && (c <= 0x37/* 7 */));\n}\n\nfunction isDecCode(c) {\n return ((0x30/* 0 */ <= c) && (c <= 0x39/* 9 */));\n}\n\nfunction resolveYamlInteger(data) {\n if (data === null) return false;\n\n var max = data.length,\n index = 0,\n hasDigits = false,\n ch;\n\n if (!max) return false;\n\n ch = data[index];\n\n // sign\n if (ch === '-' || ch === '+') {\n ch = data[++index];\n }\n\n if (ch === '0') {\n // 0\n if (index + 1 === max) return true;\n ch = data[++index];\n\n // base 2, base 8, base 16\n\n if (ch === 'b') {\n // base 2\n index++;\n\n for (; index < max; index++) {\n ch = data[index];\n if (ch === '_') continue;\n if (ch !== '0' && ch !== '1') return false;\n hasDigits = true;\n }\n return hasDigits && ch !== '_';\n }\n\n\n if (ch === 'x') {\n // base 16\n index++;\n\n for (; index < max; index++) {\n ch = data[index];\n if (ch === '_') continue;\n if (!isHexCode(data.charCodeAt(index))) return false;\n hasDigits = true;\n }\n return hasDigits && ch !== '_';\n }\n\n\n if (ch === 'o') {\n // base 8\n index++;\n\n for (; index < max; index++) {\n ch = data[index];\n if (ch === '_') continue;\n if (!isOctCode(data.charCodeAt(index))) return false;\n hasDigits = true;\n }\n return hasDigits && ch !== '_';\n }\n }\n\n // base 10 (except 0)\n\n // value should not start with `_`;\n if (ch === '_') return false;\n\n for (; index < max; index++) {\n ch = data[index];\n if (ch === '_') continue;\n if (!isDecCode(data.charCodeAt(index))) {\n return false;\n }\n hasDigits = true;\n }\n\n // Should have digits and should not end with `_`\n if (!hasDigits || ch === '_') return false;\n\n return true;\n}\n\nfunction constructYamlInteger(data) {\n var value = data, sign = 1, ch;\n\n if (value.indexOf('_') !== -1) {\n value = value.replace(/_/g, '');\n }\n\n ch = value[0];\n\n if (ch === '-' || ch === '+') {\n if (ch === '-') sign = -1;\n value = value.slice(1);\n ch = value[0];\n }\n\n if (value === '0') return 0;\n\n if (ch === '0') {\n if (value[1] === 'b') return sign * parseInt(value.slice(2), 2);\n if (value[1] === 'x') return sign * parseInt(value.slice(2), 16);\n if (value[1] === 'o') return sign * parseInt(value.slice(2), 8);\n }\n\n return sign * parseInt(value, 10);\n}\n\nfunction isInteger(object) {\n return (Object.prototype.toString.call(object)) === '[object Number]' &&\n (object % 1 === 0 && !common.isNegativeZero(object));\n}\n\nvar int = new type('tag:yaml.org,2002:int', {\n kind: 'scalar',\n resolve: resolveYamlInteger,\n construct: constructYamlInteger,\n predicate: isInteger,\n represent: {\n binary: function (obj) { return obj >= 0 ? '0b' + obj.toString(2) : '-0b' + obj.toString(2).slice(1); },\n octal: function (obj) { return obj >= 0 ? '0o' + obj.toString(8) : '-0o' + obj.toString(8).slice(1); },\n decimal: function (obj) { return obj.toString(10); },\n /* eslint-disable max-len */\n hexadecimal: function (obj) { return obj >= 0 ? '0x' + obj.toString(16).toUpperCase() : '-0x' + obj.toString(16).toUpperCase().slice(1); }\n },\n defaultStyle: 'decimal',\n styleAliases: {\n binary: [ 2, 'bin' ],\n octal: [ 8, 'oct' ],\n decimal: [ 10, 'dec' ],\n hexadecimal: [ 16, 'hex' ]\n }\n});\n\nvar YAML_FLOAT_PATTERN = new RegExp(\n // 2.5e4, 2.5 and integers\n '^(?:[-+]?(?:[0-9][0-9_]*)(?:\\\\.[0-9_]*)?(?:[eE][-+]?[0-9]+)?' +\n // .2e4, .2\n // special case, seems not from spec\n '|\\\\.[0-9_]+(?:[eE][-+]?[0-9]+)?' +\n // .inf\n '|[-+]?\\\\.(?:inf|Inf|INF)' +\n // .nan\n '|\\\\.(?:nan|NaN|NAN))$');\n\nfunction resolveYamlFloat(data) {\n if (data === null) return false;\n\n if (!YAML_FLOAT_PATTERN.test(data) ||\n // Quick hack to not allow integers end with `_`\n // Probably should update regexp & check speed\n data[data.length - 1] === '_') {\n return false;\n }\n\n return true;\n}\n\nfunction constructYamlFloat(data) {\n var value, sign;\n\n value = data.replace(/_/g, '').toLowerCase();\n sign = value[0] === '-' ? -1 : 1;\n\n if ('+-'.indexOf(value[0]) >= 0) {\n value = value.slice(1);\n }\n\n if (value === '.inf') {\n return (sign === 1) ? Number.POSITIVE_INFINITY : Number.NEGATIVE_INFINITY;\n\n } else if (value === '.nan') {\n return NaN;\n }\n return sign * parseFloat(value, 10);\n}\n\n\nvar SCIENTIFIC_WITHOUT_DOT = /^[-+]?[0-9]+e/;\n\nfunction representYamlFloat(object, style) {\n var res;\n\n if (isNaN(object)) {\n switch (style) {\n case 'lowercase': return '.nan';\n case 'uppercase': return '.NAN';\n case 'camelcase': return '.NaN';\n }\n } else if (Number.POSITIVE_INFINITY === object) {\n switch (style) {\n case 'lowercase': return '.inf';\n case 'uppercase': return '.INF';\n case 'camelcase': return '.Inf';\n }\n } else if (Number.NEGATIVE_INFINITY === object) {\n switch (style) {\n case 'lowercase': return '-.inf';\n case 'uppercase': return '-.INF';\n case 'camelcase': return '-.Inf';\n }\n } else if (common.isNegativeZero(object)) {\n return '-0.0';\n }\n\n res = object.toString(10);\n\n // JS stringifier can build scientific format without dots: 5e-100,\n // while YAML requres dot: 5.e-100. Fix it with simple hack\n\n return SCIENTIFIC_WITHOUT_DOT.test(res) ? res.replace('e', '.e') : res;\n}\n\nfunction isFloat(object) {\n return (Object.prototype.toString.call(object) === '[object Number]') &&\n (object % 1 !== 0 || common.isNegativeZero(object));\n}\n\nvar float = new type('tag:yaml.org,2002:float', {\n kind: 'scalar',\n resolve: resolveYamlFloat,\n construct: constructYamlFloat,\n predicate: isFloat,\n represent: representYamlFloat,\n defaultStyle: 'lowercase'\n});\n\nvar json = failsafe.extend({\n implicit: [\n _null,\n bool,\n int,\n float\n ]\n});\n\nvar core = json;\n\nvar YAML_DATE_REGEXP = new RegExp(\n '^([0-9][0-9][0-9][0-9])' + // [1] year\n '-([0-9][0-9])' + // [2] month\n '-([0-9][0-9])$'); // [3] day\n\nvar YAML_TIMESTAMP_REGEXP = new RegExp(\n '^([0-9][0-9][0-9][0-9])' + // [1] year\n '-([0-9][0-9]?)' + // [2] month\n '-([0-9][0-9]?)' + // [3] day\n '(?:[Tt]|[ \\\\t]+)' + // ...\n '([0-9][0-9]?)' + // [4] hour\n ':([0-9][0-9])' + // [5] minute\n ':([0-9][0-9])' + // [6] second\n '(?:\\\\.([0-9]*))?' + // [7] fraction\n '(?:[ \\\\t]*(Z|([-+])([0-9][0-9]?)' + // [8] tz [9] tz_sign [10] tz_hour\n '(?::([0-9][0-9]))?))?$'); // [11] tz_minute\n\nfunction resolveYamlTimestamp(data) {\n if (data === null) return false;\n if (YAML_DATE_REGEXP.exec(data) !== null) return true;\n if (YAML_TIMESTAMP_REGEXP.exec(data) !== null) return true;\n return false;\n}\n\nfunction constructYamlTimestamp(data) {\n var match, year, month, day, hour, minute, second, fraction = 0,\n delta = null, tz_hour, tz_minute, date;\n\n match = YAML_DATE_REGEXP.exec(data);\n if (match === null) match = YAML_TIMESTAMP_REGEXP.exec(data);\n\n if (match === null) throw new Error('Date resolve error');\n\n // match: [1] year [2] month [3] day\n\n year = +(match[1]);\n month = +(match[2]) - 1; // JS month starts with 0\n day = +(match[3]);\n\n if (!match[4]) { // no hour\n return new Date(Date.UTC(year, month, day));\n }\n\n // match: [4] hour [5] minute [6] second [7] fraction\n\n hour = +(match[4]);\n minute = +(match[5]);\n second = +(match[6]);\n\n if (match[7]) {\n fraction = match[7].slice(0, 3);\n while (fraction.length < 3) { // milli-seconds\n fraction += '0';\n }\n fraction = +fraction;\n }\n\n // match: [8] tz [9] tz_sign [10] tz_hour [11] tz_minute\n\n if (match[9]) {\n tz_hour = +(match[10]);\n tz_minute = +(match[11] || 0);\n delta = (tz_hour * 60 + tz_minute) * 60000; // delta in mili-seconds\n if (match[9] === '-') delta = -delta;\n }\n\n date = new Date(Date.UTC(year, month, day, hour, minute, second, fraction));\n\n if (delta) date.setTime(date.getTime() - delta);\n\n return date;\n}\n\nfunction representYamlTimestamp(object /*, style*/) {\n return object.toISOString();\n}\n\nvar timestamp = new type('tag:yaml.org,2002:timestamp', {\n kind: 'scalar',\n resolve: resolveYamlTimestamp,\n construct: constructYamlTimestamp,\n instanceOf: Date,\n represent: representYamlTimestamp\n});\n\nfunction resolveYamlMerge(data) {\n return data === '<<' || data === null;\n}\n\nvar merge = new type('tag:yaml.org,2002:merge', {\n kind: 'scalar',\n resolve: resolveYamlMerge\n});\n\n/*eslint-disable no-bitwise*/\n\n\n\n\n\n// [ 64, 65, 66 ] -> [ padding, CR, LF ]\nvar BASE64_MAP = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=\\n\\r';\n\n\nfunction resolveYamlBinary(data) {\n if (data === null) return false;\n\n var code, idx, bitlen = 0, max = data.length, map = BASE64_MAP;\n\n // Convert one by one.\n for (idx = 0; idx < max; idx++) {\n code = map.indexOf(data.charAt(idx));\n\n // Skip CR/LF\n if (code > 64) continue;\n\n // Fail on illegal characters\n if (code < 0) return false;\n\n bitlen += 6;\n }\n\n // If there are any bits left, source was corrupted\n return (bitlen % 8) === 0;\n}\n\nfunction constructYamlBinary(data) {\n var idx, tailbits,\n input = data.replace(/[\\r\\n=]/g, ''), // remove CR/LF & padding to simplify scan\n max = input.length,\n map = BASE64_MAP,\n bits = 0,\n result = [];\n\n // Collect by 6*4 bits (3 bytes)\n\n for (idx = 0; idx < max; idx++) {\n if ((idx % 4 === 0) && idx) {\n result.push((bits >> 16) & 0xFF);\n result.push((bits >> 8) & 0xFF);\n result.push(bits & 0xFF);\n }\n\n bits = (bits << 6) | map.indexOf(input.charAt(idx));\n }\n\n // Dump tail\n\n tailbits = (max % 4) * 6;\n\n if (tailbits === 0) {\n result.push((bits >> 16) & 0xFF);\n result.push((bits >> 8) & 0xFF);\n result.push(bits & 0xFF);\n } else if (tailbits === 18) {\n result.push((bits >> 10) & 0xFF);\n result.push((bits >> 2) & 0xFF);\n } else if (tailbits === 12) {\n result.push((bits >> 4) & 0xFF);\n }\n\n return new Uint8Array(result);\n}\n\nfunction representYamlBinary(object /*, style*/) {\n var result = '', bits = 0, idx, tail,\n max = object.length,\n map = BASE64_MAP;\n\n // Convert every three bytes to 4 ASCII characters.\n\n for (idx = 0; idx < max; idx++) {\n if ((idx % 3 === 0) && idx) {\n result += map[(bits >> 18) & 0x3F];\n result += map[(bits >> 12) & 0x3F];\n result += map[(bits >> 6) & 0x3F];\n result += map[bits & 0x3F];\n }\n\n bits = (bits << 8) + object[idx];\n }\n\n // Dump tail\n\n tail = max % 3;\n\n if (tail === 0) {\n result += map[(bits >> 18) & 0x3F];\n result += map[(bits >> 12) & 0x3F];\n result += map[(bits >> 6) & 0x3F];\n result += map[bits & 0x3F];\n } else if (tail === 2) {\n result += map[(bits >> 10) & 0x3F];\n result += map[(bits >> 4) & 0x3F];\n result += map[(bits << 2) & 0x3F];\n result += map[64];\n } else if (tail === 1) {\n result += map[(bits >> 2) & 0x3F];\n result += map[(bits << 4) & 0x3F];\n result += map[64];\n result += map[64];\n }\n\n return result;\n}\n\nfunction isBinary(obj) {\n return Object.prototype.toString.call(obj) === '[object Uint8Array]';\n}\n\nvar binary = new type('tag:yaml.org,2002:binary', {\n kind: 'scalar',\n resolve: resolveYamlBinary,\n construct: constructYamlBinary,\n predicate: isBinary,\n represent: representYamlBinary\n});\n\nvar _hasOwnProperty$3 = Object.prototype.hasOwnProperty;\nvar _toString$2 = Object.prototype.toString;\n\nfunction resolveYamlOmap(data) {\n if (data === null) return true;\n\n var objectKeys = [], index, length, pair, pairKey, pairHasKey,\n object = data;\n\n for (index = 0, length = object.length; index < length; index += 1) {\n pair = object[index];\n pairHasKey = false;\n\n if (_toString$2.call(pair) !== '[object Object]') return false;\n\n for (pairKey in pair) {\n if (_hasOwnProperty$3.call(pair, pairKey)) {\n if (!pairHasKey) pairHasKey = true;\n else return false;\n }\n }\n\n if (!pairHasKey) return false;\n\n if (objectKeys.indexOf(pairKey) === -1) objectKeys.push(pairKey);\n else return false;\n }\n\n return true;\n}\n\nfunction constructYamlOmap(data) {\n return data !== null ? data : [];\n}\n\nvar omap = new type('tag:yaml.org,2002:omap', {\n kind: 'sequence',\n resolve: resolveYamlOmap,\n construct: constructYamlOmap\n});\n\nvar _toString$1 = Object.prototype.toString;\n\nfunction resolveYamlPairs(data) {\n if (data === null) return true;\n\n var index, length, pair, keys, result,\n object = data;\n\n result = new Array(object.length);\n\n for (index = 0, length = object.length; index < length; index += 1) {\n pair = object[index];\n\n if (_toString$1.call(pair) !== '[object Object]') return false;\n\n keys = Object.keys(pair);\n\n if (keys.length !== 1) return false;\n\n result[index] = [ keys[0], pair[keys[0]] ];\n }\n\n return true;\n}\n\nfunction constructYamlPairs(data) {\n if (data === null) return [];\n\n var index, length, pair, keys, result,\n object = data;\n\n result = new Array(object.length);\n\n for (index = 0, length = object.length; index < length; index += 1) {\n pair = object[index];\n\n keys = Object.keys(pair);\n\n result[index] = [ keys[0], pair[keys[0]] ];\n }\n\n return result;\n}\n\nvar pairs = new type('tag:yaml.org,2002:pairs', {\n kind: 'sequence',\n resolve: resolveYamlPairs,\n construct: constructYamlPairs\n});\n\nvar _hasOwnProperty$2 = Object.prototype.hasOwnProperty;\n\nfunction resolveYamlSet(data) {\n if (data === null) return true;\n\n var key, object = data;\n\n for (key in object) {\n if (_hasOwnProperty$2.call(object, key)) {\n if (object[key] !== null) return false;\n }\n }\n\n return true;\n}\n\nfunction constructYamlSet(data) {\n return data !== null ? data : {};\n}\n\nvar set = new type('tag:yaml.org,2002:set', {\n kind: 'mapping',\n resolve: resolveYamlSet,\n construct: constructYamlSet\n});\n\nvar _default = core.extend({\n implicit: [\n timestamp,\n merge\n ],\n explicit: [\n binary,\n omap,\n pairs,\n set\n ]\n});\n\n/*eslint-disable max-len,no-use-before-define*/\n\n\n\n\n\n\n\nvar _hasOwnProperty$1 = Object.prototype.hasOwnProperty;\n\n\nvar CONTEXT_FLOW_IN = 1;\nvar CONTEXT_FLOW_OUT = 2;\nvar CONTEXT_BLOCK_IN = 3;\nvar CONTEXT_BLOCK_OUT = 4;\n\n\nvar CHOMPING_CLIP = 1;\nvar CHOMPING_STRIP = 2;\nvar CHOMPING_KEEP = 3;\n\n\nvar PATTERN_NON_PRINTABLE = /[\\x00-\\x08\\x0B\\x0C\\x0E-\\x1F\\x7F-\\x84\\x86-\\x9F\\uFFFE\\uFFFF]|[\\uD800-\\uDBFF](?![\\uDC00-\\uDFFF])|(?:[^\\uD800-\\uDBFF]|^)[\\uDC00-\\uDFFF]/;\nvar PATTERN_NON_ASCII_LINE_BREAKS = /[\\x85\\u2028\\u2029]/;\nvar PATTERN_FLOW_INDICATORS = /[,\\[\\]\\{\\}]/;\nvar PATTERN_TAG_HANDLE = /^(?:!|!!|![a-z\\-]+!)$/i;\nvar PATTERN_TAG_URI = /^(?:!|[^,\\[\\]\\{\\}])(?:%[0-9a-f]{2}|[0-9a-z\\-#;\\/\\?:@&=\\+\\$,_\\.!~\\*'\\(\\)\\[\\]])*$/i;\n\n\nfunction _class(obj) { return Object.prototype.toString.call(obj); }\n\nfunction is_EOL(c) {\n return (c === 0x0A/* LF */) || (c === 0x0D/* CR */);\n}\n\nfunction is_WHITE_SPACE(c) {\n return (c === 0x09/* Tab */) || (c === 0x20/* Space */);\n}\n\nfunction is_WS_OR_EOL(c) {\n return (c === 0x09/* Tab */) ||\n (c === 0x20/* Space */) ||\n (c === 0x0A/* LF */) ||\n (c === 0x0D/* CR */);\n}\n\nfunction is_FLOW_INDICATOR(c) {\n return c === 0x2C/* , */ ||\n c === 0x5B/* [ */ ||\n c === 0x5D/* ] */ ||\n c === 0x7B/* { */ ||\n c === 0x7D/* } */;\n}\n\nfunction fromHexCode(c) {\n var lc;\n\n if ((0x30/* 0 */ <= c) && (c <= 0x39/* 9 */)) {\n return c - 0x30;\n }\n\n /*eslint-disable no-bitwise*/\n lc = c | 0x20;\n\n if ((0x61/* a */ <= lc) && (lc <= 0x66/* f */)) {\n return lc - 0x61 + 10;\n }\n\n return -1;\n}\n\nfunction escapedHexLen(c) {\n if (c === 0x78/* x */) { return 2; }\n if (c === 0x75/* u */) { return 4; }\n if (c === 0x55/* U */) { return 8; }\n return 0;\n}\n\nfunction fromDecimalCode(c) {\n if ((0x30/* 0 */ <= c) && (c <= 0x39/* 9 */)) {\n return c - 0x30;\n }\n\n return -1;\n}\n\nfunction simpleEscapeSequence(c) {\n /* eslint-disable indent */\n return (c === 0x30/* 0 */) ? '\\x00' :\n (c === 0x61/* a */) ? '\\x07' :\n (c === 0x62/* b */) ? '\\x08' :\n (c === 0x74/* t */) ? '\\x09' :\n (c === 0x09/* Tab */) ? '\\x09' :\n (c === 0x6E/* n */) ? '\\x0A' :\n (c === 0x76/* v */) ? '\\x0B' :\n (c === 0x66/* f */) ? '\\x0C' :\n (c === 0x72/* r */) ? '\\x0D' :\n (c === 0x65/* e */) ? '\\x1B' :\n (c === 0x20/* Space */) ? ' ' :\n (c === 0x22/* \" */) ? '\\x22' :\n (c === 0x2F/* / */) ? '/' :\n (c === 0x5C/* \\ */) ? '\\x5C' :\n (c === 0x4E/* N */) ? '\\x85' :\n (c === 0x5F/* _ */) ? '\\xA0' :\n (c === 0x4C/* L */) ? '\\u2028' :\n (c === 0x50/* P */) ? '\\u2029' : '';\n}\n\nfunction charFromCodepoint(c) {\n if (c <= 0xFFFF) {\n return String.fromCharCode(c);\n }\n // Encode UTF-16 surrogate pair\n // https://en.wikipedia.org/wiki/UTF-16#Code_points_U.2B010000_to_U.2B10FFFF\n return String.fromCharCode(\n ((c - 0x010000) >> 10) + 0xD800,\n ((c - 0x010000) & 0x03FF) + 0xDC00\n );\n}\n\n// set a property of a literal object, while protecting against prototype pollution,\n// see https://github.com/nodeca/js-yaml/issues/164 for more details\nfunction setProperty(object, key, value) {\n // used for this specific key only because Object.defineProperty is slow\n if (key === '__proto__') {\n Object.defineProperty(object, key, {\n configurable: true,\n enumerable: true,\n writable: true,\n value: value\n });\n } else {\n object[key] = value;\n }\n}\n\nvar simpleEscapeCheck = new Array(256); // integer, for fast access\nvar simpleEscapeMap = new Array(256);\nfor (var i = 0; i < 256; i++) {\n simpleEscapeCheck[i] = simpleEscapeSequence(i) ? 1 : 0;\n simpleEscapeMap[i] = simpleEscapeSequence(i);\n}\n\n\nfunction State$1(input, options) {\n this.input = input;\n\n this.filename = options['filename'] || null;\n this.schema = options['schema'] || _default;\n this.onWarning = options['onWarning'] || null;\n // (Hidden) Remove? makes the loader to expect YAML 1.1 documents\n // if such documents have no explicit %YAML directive\n this.legacy = options['legacy'] || false;\n\n this.json = options['json'] || false;\n this.listener = options['listener'] || null;\n\n this.implicitTypes = this.schema.compiledImplicit;\n this.typeMap = this.schema.compiledTypeMap;\n\n this.length = input.length;\n this.position = 0;\n this.line = 0;\n this.lineStart = 0;\n this.lineIndent = 0;\n\n // position of first leading tab in the current line,\n // used to make sure there are no tabs in the indentation\n this.firstTabInLine = -1;\n\n this.documents = [];\n\n /*\n this.version;\n this.checkLineBreaks;\n this.tagMap;\n this.anchorMap;\n this.tag;\n this.anchor;\n this.kind;\n this.result;*/\n\n}\n\n\nfunction generateError(state, message) {\n var mark = {\n name: state.filename,\n buffer: state.input.slice(0, -1), // omit trailing \\0\n position: state.position,\n line: state.line,\n column: state.position - state.lineStart\n };\n\n mark.snippet = snippet(mark);\n\n return new exception(message, mark);\n}\n\nfunction throwError(state, message) {\n throw generateError(state, message);\n}\n\nfunction throwWarning(state, message) {\n if (state.onWarning) {\n state.onWarning.call(null, generateError(state, message));\n }\n}\n\n\nvar directiveHandlers = {\n\n YAML: function handleYamlDirective(state, name, args) {\n\n var match, major, minor;\n\n if (state.version !== null) {\n throwError(state, 'duplication of %YAML directive');\n }\n\n if (args.length !== 1) {\n throwError(state, 'YAML directive accepts exactly one argument');\n }\n\n match = /^([0-9]+)\\.([0-9]+)$/.exec(args[0]);\n\n if (match === null) {\n throwError(state, 'ill-formed argument of the YAML directive');\n }\n\n major = parseInt(match[1], 10);\n minor = parseInt(match[2], 10);\n\n if (major !== 1) {\n throwError(state, 'unacceptable YAML version of the document');\n }\n\n state.version = args[0];\n state.checkLineBreaks = (minor < 2);\n\n if (minor !== 1 && minor !== 2) {\n throwWarning(state, 'unsupported YAML version of the document');\n }\n },\n\n TAG: function handleTagDirective(state, name, args) {\n\n var handle, prefix;\n\n if (args.length !== 2) {\n throwError(state, 'TAG directive accepts exactly two arguments');\n }\n\n handle = args[0];\n prefix = args[1];\n\n if (!PATTERN_TAG_HANDLE.test(handle)) {\n throwError(state, 'ill-formed tag handle (first argument) of the TAG directive');\n }\n\n if (_hasOwnProperty$1.call(state.tagMap, handle)) {\n throwError(state, 'there is a previously declared suffix for \"' + handle + '\" tag handle');\n }\n\n if (!PATTERN_TAG_URI.test(prefix)) {\n throwError(state, 'ill-formed tag prefix (second argument) of the TAG directive');\n }\n\n try {\n prefix = decodeURIComponent(prefix);\n } catch (err) {\n throwError(state, 'tag prefix is malformed: ' + prefix);\n }\n\n state.tagMap[handle] = prefix;\n }\n};\n\n\nfunction captureSegment(state, start, end, checkJson) {\n var _position, _length, _character, _result;\n\n if (start < end) {\n _result = state.input.slice(start, end);\n\n if (checkJson) {\n for (_position = 0, _length = _result.length; _position < _length; _position += 1) {\n _character = _result.charCodeAt(_position);\n if (!(_character === 0x09 ||\n (0x20 <= _character && _character <= 0x10FFFF))) {\n throwError(state, 'expected valid JSON character');\n }\n }\n } else if (PATTERN_NON_PRINTABLE.test(_result)) {\n throwError(state, 'the stream contains non-printable characters');\n }\n\n state.result += _result;\n }\n}\n\nfunction mergeMappings(state, destination, source, overridableKeys) {\n var sourceKeys, key, index, quantity;\n\n if (!common.isObject(source)) {\n throwError(state, 'cannot merge mappings; the provided source object is unacceptable');\n }\n\n sourceKeys = Object.keys(source);\n\n for (index = 0, quantity = sourceKeys.length; index < quantity; index += 1) {\n key = sourceKeys[index];\n\n if (!_hasOwnProperty$1.call(destination, key)) {\n setProperty(destination, key, source[key]);\n overridableKeys[key] = true;\n }\n }\n}\n\nfunction storeMappingPair(state, _result, overridableKeys, keyTag, keyNode, valueNode,\n startLine, startLineStart, startPos) {\n\n var index, quantity;\n\n // The output is a plain object here, so keys can only be strings.\n // We need to convert keyNode to a string, but doing so can hang the process\n // (deeply nested arrays that explode exponentially using aliases).\n if (Array.isArray(keyNode)) {\n keyNode = Array.prototype.slice.call(keyNode);\n\n for (index = 0, quantity = keyNode.length; index < quantity; index += 1) {\n if (Array.isArray(keyNode[index])) {\n throwError(state, 'nested arrays are not supported inside keys');\n }\n\n if (typeof keyNode === 'object' && _class(keyNode[index]) === '[object Object]') {\n keyNode[index] = '[object Object]';\n }\n }\n }\n\n // Avoid code execution in load() via toString property\n // (still use its own toString for arrays, timestamps,\n // and whatever user schema extensions happen to have @@toStringTag)\n if (typeof keyNode === 'object' && _class(keyNode) === '[object Object]') {\n keyNode = '[object Object]';\n }\n\n\n keyNode = String(keyNode);\n\n if (_result === null) {\n _result = {};\n }\n\n if (keyTag === 'tag:yaml.org,2002:merge') {\n if (Array.isArray(valueNode)) {\n for (index = 0, quantity = valueNode.length; index < quantity; index += 1) {\n mergeMappings(state, _result, valueNode[index], overridableKeys);\n }\n } else {\n mergeMappings(state, _result, valueNode, overridableKeys);\n }\n } else {\n if (!state.json &&\n !_hasOwnProperty$1.call(overridableKeys, keyNode) &&\n _hasOwnProperty$1.call(_result, keyNode)) {\n state.line = startLine || state.line;\n state.lineStart = startLineStart || state.lineStart;\n state.position = startPos || state.position;\n throwError(state, 'duplicated mapping key');\n }\n\n setProperty(_result, keyNode, valueNode);\n delete overridableKeys[keyNode];\n }\n\n return _result;\n}\n\nfunction readLineBreak(state) {\n var ch;\n\n ch = state.input.charCodeAt(state.position);\n\n if (ch === 0x0A/* LF */) {\n state.position++;\n } else if (ch === 0x0D/* CR */) {\n state.position++;\n if (state.input.charCodeAt(state.position) === 0x0A/* LF */) {\n state.position++;\n }\n } else {\n throwError(state, 'a line break is expected');\n }\n\n state.line += 1;\n state.lineStart = state.position;\n state.firstTabInLine = -1;\n}\n\nfunction skipSeparationSpace(state, allowComments, checkIndent) {\n var lineBreaks = 0,\n ch = state.input.charCodeAt(state.position);\n\n while (ch !== 0) {\n while (is_WHITE_SPACE(ch)) {\n if (ch === 0x09/* Tab */ && state.firstTabInLine === -1) {\n state.firstTabInLine = state.position;\n }\n ch = state.input.charCodeAt(++state.position);\n }\n\n if (allowComments && ch === 0x23/* # */) {\n do {\n ch = state.input.charCodeAt(++state.position);\n } while (ch !== 0x0A/* LF */ && ch !== 0x0D/* CR */ && ch !== 0);\n }\n\n if (is_EOL(ch)) {\n readLineBreak(state);\n\n ch = state.input.charCodeAt(state.position);\n lineBreaks++;\n state.lineIndent = 0;\n\n while (ch === 0x20/* Space */) {\n state.lineIndent++;\n ch = state.input.charCodeAt(++state.position);\n }\n } else {\n break;\n }\n }\n\n if (checkIndent !== -1 && lineBreaks !== 0 && state.lineIndent < checkIndent) {\n throwWarning(state, 'deficient indentation');\n }\n\n return lineBreaks;\n}\n\nfunction testDocumentSeparator(state) {\n var _position = state.position,\n ch;\n\n ch = state.input.charCodeAt(_position);\n\n // Condition state.position === state.lineStart is tested\n // in parent on each call, for efficiency. No needs to test here again.\n if ((ch === 0x2D/* - */ || ch === 0x2E/* . */) &&\n ch === state.input.charCodeAt(_position + 1) &&\n ch === state.input.charCodeAt(_position + 2)) {\n\n _position += 3;\n\n ch = state.input.charCodeAt(_position);\n\n if (ch === 0 || is_WS_OR_EOL(ch)) {\n return true;\n }\n }\n\n return false;\n}\n\nfunction writeFoldedLines(state, count) {\n if (count === 1) {\n state.result += ' ';\n } else if (count > 1) {\n state.result += common.repeat('\\n', count - 1);\n }\n}\n\n\nfunction readPlainScalar(state, nodeIndent, withinFlowCollection) {\n var preceding,\n following,\n captureStart,\n captureEnd,\n hasPendingContent,\n _line,\n _lineStart,\n _lineIndent,\n _kind = state.kind,\n _result = state.result,\n ch;\n\n ch = state.input.charCodeAt(state.position);\n\n if (is_WS_OR_EOL(ch) ||\n is_FLOW_INDICATOR(ch) ||\n ch === 0x23/* # */ ||\n ch === 0x26/* & */ ||\n ch === 0x2A/* * */ ||\n ch === 0x21/* ! */ ||\n ch === 0x7C/* | */ ||\n ch === 0x3E/* > */ ||\n ch === 0x27/* ' */ ||\n ch === 0x22/* \" */ ||\n ch === 0x25/* % */ ||\n ch === 0x40/* @ */ ||\n ch === 0x60/* ` */) {\n return false;\n }\n\n if (ch === 0x3F/* ? */ || ch === 0x2D/* - */) {\n following = state.input.charCodeAt(state.position + 1);\n\n if (is_WS_OR_EOL(following) ||\n withinFlowCollection && is_FLOW_INDICATOR(following)) {\n return false;\n }\n }\n\n state.kind = 'scalar';\n state.result = '';\n captureStart = captureEnd = state.position;\n hasPendingContent = false;\n\n while (ch !== 0) {\n if (ch === 0x3A/* : */) {\n following = state.input.charCodeAt(state.position + 1);\n\n if (is_WS_OR_EOL(following) ||\n withinFlowCollection && is_FLOW_INDICATOR(following)) {\n break;\n }\n\n } else if (ch === 0x23/* # */) {\n preceding = state.input.charCodeAt(state.position - 1);\n\n if (is_WS_OR_EOL(preceding)) {\n break;\n }\n\n } else if ((state.position === state.lineStart && testDocumentSeparator(state)) ||\n withinFlowCollection && is_FLOW_INDICATOR(ch)) {\n break;\n\n } else if (is_EOL(ch)) {\n _line = state.line;\n _lineStart = state.lineStart;\n _lineIndent = state.lineIndent;\n skipSeparationSpace(state, false, -1);\n\n if (state.lineIndent >= nodeIndent) {\n hasPendingContent = true;\n ch = state.input.charCodeAt(state.position);\n continue;\n } else {\n state.position = captureEnd;\n state.line = _line;\n state.lineStart = _lineStart;\n state.lineIndent = _lineIndent;\n break;\n }\n }\n\n if (hasPendingContent) {\n captureSegment(state, captureStart, captureEnd, false);\n writeFoldedLines(state, state.line - _line);\n captureStart = captureEnd = state.position;\n hasPendingContent = false;\n }\n\n if (!is_WHITE_SPACE(ch)) {\n captureEnd = state.position + 1;\n }\n\n ch = state.input.charCodeAt(++state.position);\n }\n\n captureSegment(state, captureStart, captureEnd, false);\n\n if (state.result) {\n return true;\n }\n\n state.kind = _kind;\n state.result = _result;\n return false;\n}\n\nfunction readSingleQuotedScalar(state, nodeIndent) {\n var ch,\n captureStart, captureEnd;\n\n ch = state.input.charCodeAt(state.position);\n\n if (ch !== 0x27/* ' */) {\n return false;\n }\n\n state.kind = 'scalar';\n state.result = '';\n state.position++;\n captureStart = captureEnd = state.position;\n\n while ((ch = state.input.charCodeAt(state.position)) !== 0) {\n if (ch === 0x27/* ' */) {\n captureSegment(state, captureStart, state.position, true);\n ch = state.input.charCodeAt(++state.position);\n\n if (ch === 0x27/* ' */) {\n captureStart = state.position;\n state.position++;\n captureEnd = state.position;\n } else {\n return true;\n }\n\n } else if (is_EOL(ch)) {\n captureSegment(state, captureStart, captureEnd, true);\n writeFoldedLines(state, skipSeparationSpace(state, false, nodeIndent));\n captureStart = captureEnd = state.position;\n\n } else if (state.position === state.lineStart && testDocumentSeparator(state)) {\n throwError(state, 'unexpected end of the document within a single quoted scalar');\n\n } else {\n state.position++;\n captureEnd = state.position;\n }\n }\n\n throwError(state, 'unexpected end of the stream within a single quoted scalar');\n}\n\nfunction readDoubleQuotedScalar(state, nodeIndent) {\n var captureStart,\n captureEnd,\n hexLength,\n hexResult,\n tmp,\n ch;\n\n ch = state.input.charCodeAt(state.position);\n\n if (ch !== 0x22/* \" */) {\n return false;\n }\n\n state.kind = 'scalar';\n state.result = '';\n state.position++;\n captureStart = captureEnd = state.position;\n\n while ((ch = state.input.charCodeAt(state.position)) !== 0) {\n if (ch === 0x22/* \" */) {\n captureSegment(state, captureStart, state.position, true);\n state.position++;\n return true;\n\n } else if (ch === 0x5C/* \\ */) {\n captureSegment(state, captureStart, state.position, true);\n ch = state.input.charCodeAt(++state.position);\n\n if (is_EOL(ch)) {\n skipSeparationSpace(state, false, nodeIndent);\n\n // TODO: rework to inline fn with no type cast?\n } else if (ch < 256 && simpleEscapeCheck[ch]) {\n state.result += simpleEscapeMap[ch];\n state.position++;\n\n } else if ((tmp = escapedHexLen(ch)) > 0) {\n hexLength = tmp;\n hexResult = 0;\n\n for (; hexLength > 0; hexLength--) {\n ch = state.input.charCodeAt(++state.position);\n\n if ((tmp = fromHexCode(ch)) >= 0) {\n hexResult = (hexResult << 4) + tmp;\n\n } else {\n throwError(state, 'expected hexadecimal character');\n }\n }\n\n state.result += charFromCodepoint(hexResult);\n\n state.position++;\n\n } else {\n throwError(state, 'unknown escape sequence');\n }\n\n captureStart = captureEnd = state.position;\n\n } else if (is_EOL(ch)) {\n captureSegment(state, captureStart, captureEnd, true);\n writeFoldedLines(state, skipSeparationSpace(state, false, nodeIndent));\n captureStart = captureEnd = state.position;\n\n } else if (state.position === state.lineStart && testDocumentSeparator(state)) {\n throwError(state, 'unexpected end of the document within a double quoted scalar');\n\n } else {\n state.position++;\n captureEnd = state.position;\n }\n }\n\n throwError(state, 'unexpected end of the stream within a double quoted scalar');\n}\n\nfunction readFlowCollection(state, nodeIndent) {\n var readNext = true,\n _line,\n _lineStart,\n _pos,\n _tag = state.tag,\n _result,\n _anchor = state.anchor,\n following,\n terminator,\n isPair,\n isExplicitPair,\n isMapping,\n overridableKeys = Object.create(null),\n keyNode,\n keyTag,\n valueNode,\n ch;\n\n ch = state.input.charCodeAt(state.position);\n\n if (ch === 0x5B/* [ */) {\n terminator = 0x5D;/* ] */\n isMapping = false;\n _result = [];\n } else if (ch === 0x7B/* { */) {\n terminator = 0x7D;/* } */\n isMapping = true;\n _result = {};\n } else {\n return false;\n }\n\n if (state.anchor !== null) {\n state.anchorMap[state.anchor] = _result;\n }\n\n ch = state.input.charCodeAt(++state.position);\n\n while (ch !== 0) {\n skipSeparationSpace(state, true, nodeIndent);\n\n ch = state.input.charCodeAt(state.position);\n\n if (ch === terminator) {\n state.position++;\n state.tag = _tag;\n state.anchor = _anchor;\n state.kind = isMapping ? 'mapping' : 'sequence';\n state.result = _result;\n return true;\n } else if (!readNext) {\n throwError(state, 'missed comma between flow collection entries');\n } else if (ch === 0x2C/* , */) {\n // \"flow collection entries can never be completely empty\", as per YAML 1.2, section 7.4\n throwError(state, \"expected the node content, but found ','\");\n }\n\n keyTag = keyNode = valueNode = null;\n isPair = isExplicitPair = false;\n\n if (ch === 0x3F/* ? */) {\n following = state.input.charCodeAt(state.position + 1);\n\n if (is_WS_OR_EOL(following)) {\n isPair = isExplicitPair = true;\n state.position++;\n skipSeparationSpace(state, true, nodeIndent);\n }\n }\n\n _line = state.line; // Save the current line.\n _lineStart = state.lineStart;\n _pos = state.position;\n composeNode(state, nodeIndent, CONTEXT_FLOW_IN, false, true);\n keyTag = state.tag;\n keyNode = state.result;\n skipSeparationSpace(state, true, nodeIndent);\n\n ch = state.input.charCodeAt(state.position);\n\n if ((isExplicitPair || state.line === _line) && ch === 0x3A/* : */) {\n isPair = true;\n ch = state.input.charCodeAt(++state.position);\n skipSeparationSpace(state, true, nodeIndent);\n composeNode(state, nodeIndent, CONTEXT_FLOW_IN, false, true);\n valueNode = state.result;\n }\n\n if (isMapping) {\n storeMappingPair(state, _result, overridableKeys, keyTag, keyNode, valueNode, _line, _lineStart, _pos);\n } else if (isPair) {\n _result.push(storeMappingPair(state, null, overridableKeys, keyTag, keyNode, valueNode, _line, _lineStart, _pos));\n } else {\n _result.push(keyNode);\n }\n\n skipSeparationSpace(state, true, nodeIndent);\n\n ch = state.input.charCodeAt(state.position);\n\n if (ch === 0x2C/* , */) {\n readNext = true;\n ch = state.input.charCodeAt(++state.position);\n } else {\n readNext = false;\n }\n }\n\n throwError(state, 'unexpected end of the stream within a flow collection');\n}\n\nfunction readBlockScalar(state, nodeIndent) {\n var captureStart,\n folding,\n chomping = CHOMPING_CLIP,\n didReadContent = false,\n detectedIndent = false,\n textIndent = nodeIndent,\n emptyLines = 0,\n atMoreIndented = false,\n tmp,\n ch;\n\n ch = state.input.charCodeAt(state.position);\n\n if (ch === 0x7C/* | */) {\n folding = false;\n } else if (ch === 0x3E/* > */) {\n folding = true;\n } else {\n return false;\n }\n\n state.kind = 'scalar';\n state.result = '';\n\n while (ch !== 0) {\n ch = state.input.charCodeAt(++state.position);\n\n if (ch === 0x2B/* + */ || ch === 0x2D/* - */) {\n if (CHOMPING_CLIP === chomping) {\n chomping = (ch === 0x2B/* + */) ? CHOMPING_KEEP : CHOMPING_STRIP;\n } else {\n throwError(state, 'repeat of a chomping mode identifier');\n }\n\n } else if ((tmp = fromDecimalCode(ch)) >= 0) {\n if (tmp === 0) {\n throwError(state, 'bad explicit indentation width of a block scalar; it cannot be less than one');\n } else if (!detectedIndent) {\n textIndent = nodeIndent + tmp - 1;\n detectedIndent = true;\n } else {\n throwError(state, 'repeat of an indentation width identifier');\n }\n\n } else {\n break;\n }\n }\n\n if (is_WHITE_SPACE(ch)) {\n do { ch = state.input.charCodeAt(++state.position); }\n while (is_WHITE_SPACE(ch));\n\n if (ch === 0x23/* # */) {\n do { ch = state.input.charCodeAt(++state.position); }\n while (!is_EOL(ch) && (ch !== 0));\n }\n }\n\n while (ch !== 0) {\n readLineBreak(state);\n state.lineIndent = 0;\n\n ch = state.input.charCodeAt(state.position);\n\n while ((!detectedIndent || state.lineIndent < textIndent) &&\n (ch === 0x20/* Space */)) {\n state.lineIndent++;\n ch = state.input.charCodeAt(++state.position);\n }\n\n if (!detectedIndent && state.lineIndent > textIndent) {\n textIndent = state.lineIndent;\n }\n\n if (is_EOL(ch)) {\n emptyLines++;\n continue;\n }\n\n // End of the scalar.\n if (state.lineIndent < textIndent) {\n\n // Perform the chomping.\n if (chomping === CHOMPING_KEEP) {\n state.result += common.repeat('\\n', didReadContent ? 1 + emptyLines : emptyLines);\n } else if (chomping === CHOMPING_CLIP) {\n if (didReadContent) { // i.e. only if the scalar is not empty.\n state.result += '\\n';\n }\n }\n\n // Break this `while` cycle and go to the funciton's epilogue.\n break;\n }\n\n // Folded style: use fancy rules to handle line breaks.\n if (folding) {\n\n // Lines starting with white space characters (more-indented lines) are not folded.\n if (is_WHITE_SPACE(ch)) {\n atMoreIndented = true;\n // except for the first content line (cf. Example 8.1)\n state.result += common.repeat('\\n', didReadContent ? 1 + emptyLines : emptyLines);\n\n // End of more-indented block.\n } else if (atMoreIndented) {\n atMoreIndented = false;\n state.result += common.repeat('\\n', emptyLines + 1);\n\n // Just one line break - perceive as the same line.\n } else if (emptyLines === 0) {\n if (didReadContent) { // i.e. only if we have already read some scalar content.\n state.result += ' ';\n }\n\n // Several line breaks - perceive as different lines.\n } else {\n state.result += common.repeat('\\n', emptyLines);\n }\n\n // Literal style: just add exact number of line breaks between content lines.\n } else {\n // Keep all line breaks except the header line break.\n state.result += common.repeat('\\n', didReadContent ? 1 + emptyLines : emptyLines);\n }\n\n didReadContent = true;\n detectedIndent = true;\n emptyLines = 0;\n captureStart = state.position;\n\n while (!is_EOL(ch) && (ch !== 0)) {\n ch = state.input.charCodeAt(++state.position);\n }\n\n captureSegment(state, captureStart, state.position, false);\n }\n\n return true;\n}\n\nfunction readBlockSequence(state, nodeIndent) {\n var _line,\n _tag = state.tag,\n _anchor = state.anchor,\n _result = [],\n following,\n detected = false,\n ch;\n\n // there is a leading tab before this token, so it can't be a block sequence/mapping;\n // it can still be flow sequence/mapping or a scalar\n if (state.firstTabInLine !== -1) return false;\n\n if (state.anchor !== null) {\n state.anchorMap[state.anchor] = _result;\n }\n\n ch = state.input.charCodeAt(state.position);\n\n while (ch !== 0) {\n if (state.firstTabInLine !== -1) {\n state.position = state.firstTabInLine;\n throwError(state, 'tab characters must not be used in indentation');\n }\n\n if (ch !== 0x2D/* - */) {\n break;\n }\n\n following = state.input.charCodeAt(state.position + 1);\n\n if (!is_WS_OR_EOL(following)) {\n break;\n }\n\n detected = true;\n state.position++;\n\n if (skipSeparationSpace(state, true, -1)) {\n if (state.lineIndent <= nodeIndent) {\n _result.push(null);\n ch = state.input.charCodeAt(state.position);\n continue;\n }\n }\n\n _line = state.line;\n composeNode(state, nodeIndent, CONTEXT_BLOCK_IN, false, true);\n _result.push(state.result);\n skipSeparationSpace(state, true, -1);\n\n ch = state.input.charCodeAt(state.position);\n\n if ((state.line === _line || state.lineIndent > nodeIndent) && (ch !== 0)) {\n throwError(state, 'bad indentation of a sequence entry');\n } else if (state.lineIndent < nodeIndent) {\n break;\n }\n }\n\n if (detected) {\n state.tag = _tag;\n state.anchor = _anchor;\n state.kind = 'sequence';\n state.result = _result;\n return true;\n }\n return false;\n}\n\nfunction readBlockMapping(state, nodeIndent, flowIndent) {\n var following,\n allowCompact,\n _line,\n _keyLine,\n _keyLineStart,\n _keyPos,\n _tag = state.tag,\n _anchor = state.anchor,\n _result = {},\n overridableKeys = Object.create(null),\n keyTag = null,\n keyNode = null,\n valueNode = null,\n atExplicitKey = false,\n detected = false,\n ch;\n\n // there is a leading tab before this token, so it can't be a block sequence/mapping;\n // it can still be flow sequence/mapping or a scalar\n if (state.firstTabInLine !== -1) return false;\n\n if (state.anchor !== null) {\n state.anchorMap[state.anchor] = _result;\n }\n\n ch = state.input.charCodeAt(state.position);\n\n while (ch !== 0) {\n if (!atExplicitKey && state.firstTabInLine !== -1) {\n state.position = state.firstTabInLine;\n throwError(state, 'tab characters must not be used in indentation');\n }\n\n following = state.input.charCodeAt(state.position + 1);\n _line = state.line; // Save the current line.\n\n //\n // Explicit notation case. There are two separate blocks:\n // first for the key (denoted by \"?\") and second for the value (denoted by \":\")\n //\n if ((ch === 0x3F/* ? */ || ch === 0x3A/* : */) && is_WS_OR_EOL(following)) {\n\n if (ch === 0x3F/* ? */) {\n if (atExplicitKey) {\n storeMappingPair(state, _result, overridableKeys, keyTag, keyNode, null, _keyLine, _keyLineStart, _keyPos);\n keyTag = keyNode = valueNode = null;\n }\n\n detected = true;\n atExplicitKey = true;\n allowCompact = true;\n\n } else if (atExplicitKey) {\n // i.e. 0x3A/* : */ === character after the explicit key.\n atExplicitKey = false;\n allowCompact = true;\n\n } else {\n throwError(state, 'incomplete explicit mapping pair; a key node is missed; or followed by a non-tabulated empty line');\n }\n\n state.position += 1;\n ch = following;\n\n //\n // Implicit notation case. Flow-style node as the key first, then \":\", and the value.\n //\n } else {\n _keyLine = state.line;\n _keyLineStart = state.lineStart;\n _keyPos = state.position;\n\n if (!composeNode(state, flowIndent, CONTEXT_FLOW_OUT, false, true)) {\n // Neither implicit nor explicit notation.\n // Reading is done. Go to the epilogue.\n break;\n }\n\n if (state.line === _line) {\n ch = state.input.charCodeAt(state.position);\n\n while (is_WHITE_SPACE(ch)) {\n ch = state.input.charCodeAt(++state.position);\n }\n\n if (ch === 0x3A/* : */) {\n ch = state.input.charCodeAt(++state.position);\n\n if (!is_WS_OR_EOL(ch)) {\n throwError(state, 'a whitespace character is expected after the key-value separator within a block mapping');\n }\n\n if (atExplicitKey) {\n storeMappingPair(state, _result, overridableKeys, keyTag, keyNode, null, _keyLine, _keyLineStart, _keyPos);\n keyTag = keyNode = valueNode = null;\n }\n\n detected = true;\n atExplicitKey = false;\n allowCompact = false;\n keyTag = state.tag;\n keyNode = state.result;\n\n } else if (detected) {\n throwError(state, 'can not read an implicit mapping pair; a colon is missed');\n\n } else {\n state.tag = _tag;\n state.anchor = _anchor;\n return true; // Keep the result of `composeNode`.\n }\n\n } else if (detected) {\n throwError(state, 'can not read a block mapping entry; a multiline key may not be an implicit key');\n\n } else {\n state.tag = _tag;\n state.anchor = _anchor;\n return true; // Keep the result of `composeNode`.\n }\n }\n\n //\n // Common reading code for both explicit and implicit notations.\n //\n if (state.line === _line || state.lineIndent > nodeIndent) {\n if (atExplicitKey) {\n _keyLine = state.line;\n _keyLineStart = state.lineStart;\n _keyPos = state.position;\n }\n\n if (composeNode(state, nodeIndent, CONTEXT_BLOCK_OUT, true, allowCompact)) {\n if (atExplicitKey) {\n keyNode = state.result;\n } else {\n valueNode = state.result;\n }\n }\n\n if (!atExplicitKey) {\n storeMappingPair(state, _result, overridableKeys, keyTag, keyNode, valueNode, _keyLine, _keyLineStart, _keyPos);\n keyTag = keyNode = valueNode = null;\n }\n\n skipSeparationSpace(state, true, -1);\n ch = state.input.charCodeAt(state.position);\n }\n\n if ((state.line === _line || state.lineIndent > nodeIndent) && (ch !== 0)) {\n throwError(state, 'bad indentation of a mapping entry');\n } else if (state.lineIndent < nodeIndent) {\n break;\n }\n }\n\n //\n // Epilogue.\n //\n\n // Special case: last mapping's node contains only the key in explicit notation.\n if (atExplicitKey) {\n storeMappingPair(state, _result, overridableKeys, keyTag, keyNode, null, _keyLine, _keyLineStart, _keyPos);\n }\n\n // Expose the resulting mapping.\n if (detected) {\n state.tag = _tag;\n state.anchor = _anchor;\n state.kind = 'mapping';\n state.result = _result;\n }\n\n return detected;\n}\n\nfunction readTagProperty(state) {\n var _position,\n isVerbatim = false,\n isNamed = false,\n tagHandle,\n tagName,\n ch;\n\n ch = state.input.charCodeAt(state.position);\n\n if (ch !== 0x21/* ! */) return false;\n\n if (state.tag !== null) {\n throwError(state, 'duplication of a tag property');\n }\n\n ch = state.input.charCodeAt(++state.position);\n\n if (ch === 0x3C/* < */) {\n isVerbatim = true;\n ch = state.input.charCodeAt(++state.position);\n\n } else if (ch === 0x21/* ! */) {\n isNamed = true;\n tagHandle = '!!';\n ch = state.input.charCodeAt(++state.position);\n\n } else {\n tagHandle = '!';\n }\n\n _position = state.position;\n\n if (isVerbatim) {\n do { ch = state.input.charCodeAt(++state.position); }\n while (ch !== 0 && ch !== 0x3E/* > */);\n\n if (state.position < state.length) {\n tagName = state.input.slice(_position, state.position);\n ch = state.input.charCodeAt(++state.position);\n } else {\n throwError(state, 'unexpected end of the stream within a verbatim tag');\n }\n } else {\n while (ch !== 0 && !is_WS_OR_EOL(ch)) {\n\n if (ch === 0x21/* ! */) {\n if (!isNamed) {\n tagHandle = state.input.slice(_position - 1, state.position + 1);\n\n if (!PATTERN_TAG_HANDLE.test(tagHandle)) {\n throwError(state, 'named tag handle cannot contain such characters');\n }\n\n isNamed = true;\n _position = state.position + 1;\n } else {\n throwError(state, 'tag suffix cannot contain exclamation marks');\n }\n }\n\n ch = state.input.charCodeAt(++state.position);\n }\n\n tagName = state.input.slice(_position, state.position);\n\n if (PATTERN_FLOW_INDICATORS.test(tagName)) {\n throwError(state, 'tag suffix cannot contain flow indicator characters');\n }\n }\n\n if (tagName && !PATTERN_TAG_URI.test(tagName)) {\n throwError(state, 'tag name cannot contain such characters: ' + tagName);\n }\n\n try {\n tagName = decodeURIComponent(tagName);\n } catch (err) {\n throwError(state, 'tag name is malformed: ' + tagName);\n }\n\n if (isVerbatim) {\n state.tag = tagName;\n\n } else if (_hasOwnProperty$1.call(state.tagMap, tagHandle)) {\n state.tag = state.tagMap[tagHandle] + tagName;\n\n } else if (tagHandle === '!') {\n state.tag = '!' + tagName;\n\n } else if (tagHandle === '!!') {\n state.tag = 'tag:yaml.org,2002:' + tagName;\n\n } else {\n throwError(state, 'undeclared tag handle \"' + tagHandle + '\"');\n }\n\n return true;\n}\n\nfunction readAnchorProperty(state) {\n var _position,\n ch;\n\n ch = state.input.charCodeAt(state.position);\n\n if (ch !== 0x26/* & */) return false;\n\n if (state.anchor !== null) {\n throwError(state, 'duplication of an anchor property');\n }\n\n ch = state.input.charCodeAt(++state.position);\n _position = state.position;\n\n while (ch !== 0 && !is_WS_OR_EOL(ch) && !is_FLOW_INDICATOR(ch)) {\n ch = state.input.charCodeAt(++state.position);\n }\n\n if (state.position === _position) {\n throwError(state, 'name of an anchor node must contain at least one character');\n }\n\n state.anchor = state.input.slice(_position, state.position);\n return true;\n}\n\nfunction readAlias(state) {\n var _position, alias,\n ch;\n\n ch = state.input.charCodeAt(state.position);\n\n if (ch !== 0x2A/* * */) return false;\n\n ch = state.input.charCodeAt(++state.position);\n _position = state.position;\n\n while (ch !== 0 && !is_WS_OR_EOL(ch) && !is_FLOW_INDICATOR(ch)) {\n ch = state.input.charCodeAt(++state.position);\n }\n\n if (state.position === _position) {\n throwError(state, 'name of an alias node must contain at least one character');\n }\n\n alias = state.input.slice(_position, state.position);\n\n if (!_hasOwnProperty$1.call(state.anchorMap, alias)) {\n throwError(state, 'unidentified alias \"' + alias + '\"');\n }\n\n state.result = state.anchorMap[alias];\n skipSeparationSpace(state, true, -1);\n return true;\n}\n\nfunction composeNode(state, parentIndent, nodeContext, allowToSeek, allowCompact) {\n var allowBlockStyles,\n allowBlockScalars,\n allowBlockCollections,\n indentStatus = 1, // 1: this>parent, 0: this=parent, -1: this parentIndent) {\n indentStatus = 1;\n } else if (state.lineIndent === parentIndent) {\n indentStatus = 0;\n } else if (state.lineIndent < parentIndent) {\n indentStatus = -1;\n }\n }\n }\n\n if (indentStatus === 1) {\n while (readTagProperty(state) || readAnchorProperty(state)) {\n if (skipSeparationSpace(state, true, -1)) {\n atNewLine = true;\n allowBlockCollections = allowBlockStyles;\n\n if (state.lineIndent > parentIndent) {\n indentStatus = 1;\n } else if (state.lineIndent === parentIndent) {\n indentStatus = 0;\n } else if (state.lineIndent < parentIndent) {\n indentStatus = -1;\n }\n } else {\n allowBlockCollections = false;\n }\n }\n }\n\n if (allowBlockCollections) {\n allowBlockCollections = atNewLine || allowCompact;\n }\n\n if (indentStatus === 1 || CONTEXT_BLOCK_OUT === nodeContext) {\n if (CONTEXT_FLOW_IN === nodeContext || CONTEXT_FLOW_OUT === nodeContext) {\n flowIndent = parentIndent;\n } else {\n flowIndent = parentIndent + 1;\n }\n\n blockIndent = state.position - state.lineStart;\n\n if (indentStatus === 1) {\n if (allowBlockCollections &&\n (readBlockSequence(state, blockIndent) ||\n readBlockMapping(state, blockIndent, flowIndent)) ||\n readFlowCollection(state, flowIndent)) {\n hasContent = true;\n } else {\n if ((allowBlockScalars && readBlockScalar(state, flowIndent)) ||\n readSingleQuotedScalar(state, flowIndent) ||\n readDoubleQuotedScalar(state, flowIndent)) {\n hasContent = true;\n\n } else if (readAlias(state)) {\n hasContent = true;\n\n if (state.tag !== null || state.anchor !== null) {\n throwError(state, 'alias node should not have any properties');\n }\n\n } else if (readPlainScalar(state, flowIndent, CONTEXT_FLOW_IN === nodeContext)) {\n hasContent = true;\n\n if (state.tag === null) {\n state.tag = '?';\n }\n }\n\n if (state.anchor !== null) {\n state.anchorMap[state.anchor] = state.result;\n }\n }\n } else if (indentStatus === 0) {\n // Special case: block sequences are allowed to have same indentation level as the parent.\n // http://www.yaml.org/spec/1.2/spec.html#id2799784\n hasContent = allowBlockCollections && readBlockSequence(state, blockIndent);\n }\n }\n\n if (state.tag === null) {\n if (state.anchor !== null) {\n state.anchorMap[state.anchor] = state.result;\n }\n\n } else if (state.tag === '?') {\n // Implicit resolving is not allowed for non-scalar types, and '?'\n // non-specific tag is only automatically assigned to plain scalars.\n //\n // We only need to check kind conformity in case user explicitly assigns '?'\n // tag, for example like this: \"! [0]\"\n //\n if (state.result !== null && state.kind !== 'scalar') {\n throwError(state, 'unacceptable node kind for ! tag; it should be \"scalar\", not \"' + state.kind + '\"');\n }\n\n for (typeIndex = 0, typeQuantity = state.implicitTypes.length; typeIndex < typeQuantity; typeIndex += 1) {\n type = state.implicitTypes[typeIndex];\n\n if (type.resolve(state.result)) { // `state.result` updated in resolver if matched\n state.result = type.construct(state.result);\n state.tag = type.tag;\n if (state.anchor !== null) {\n state.anchorMap[state.anchor] = state.result;\n }\n break;\n }\n }\n } else if (state.tag !== '!') {\n if (_hasOwnProperty$1.call(state.typeMap[state.kind || 'fallback'], state.tag)) {\n type = state.typeMap[state.kind || 'fallback'][state.tag];\n } else {\n // looking for multi type\n type = null;\n typeList = state.typeMap.multi[state.kind || 'fallback'];\n\n for (typeIndex = 0, typeQuantity = typeList.length; typeIndex < typeQuantity; typeIndex += 1) {\n if (state.tag.slice(0, typeList[typeIndex].tag.length) === typeList[typeIndex].tag) {\n type = typeList[typeIndex];\n break;\n }\n }\n }\n\n if (!type) {\n throwError(state, 'unknown tag !<' + state.tag + '>');\n }\n\n if (state.result !== null && type.kind !== state.kind) {\n throwError(state, 'unacceptable node kind for !<' + state.tag + '> tag; it should be \"' + type.kind + '\", not \"' + state.kind + '\"');\n }\n\n if (!type.resolve(state.result, state.tag)) { // `state.result` updated in resolver if matched\n throwError(state, 'cannot resolve a node with !<' + state.tag + '> explicit tag');\n } else {\n state.result = type.construct(state.result, state.tag);\n if (state.anchor !== null) {\n state.anchorMap[state.anchor] = state.result;\n }\n }\n }\n\n if (state.listener !== null) {\n state.listener('close', state);\n }\n return state.tag !== null || state.anchor !== null || hasContent;\n}\n\nfunction readDocument(state) {\n var documentStart = state.position,\n _position,\n directiveName,\n directiveArgs,\n hasDirectives = false,\n ch;\n\n state.version = null;\n state.checkLineBreaks = state.legacy;\n state.tagMap = Object.create(null);\n state.anchorMap = Object.create(null);\n\n while ((ch = state.input.charCodeAt(state.position)) !== 0) {\n skipSeparationSpace(state, true, -1);\n\n ch = state.input.charCodeAt(state.position);\n\n if (state.lineIndent > 0 || ch !== 0x25/* % */) {\n break;\n }\n\n hasDirectives = true;\n ch = state.input.charCodeAt(++state.position);\n _position = state.position;\n\n while (ch !== 0 && !is_WS_OR_EOL(ch)) {\n ch = state.input.charCodeAt(++state.position);\n }\n\n directiveName = state.input.slice(_position, state.position);\n directiveArgs = [];\n\n if (directiveName.length < 1) {\n throwError(state, 'directive name must not be less than one character in length');\n }\n\n while (ch !== 0) {\n while (is_WHITE_SPACE(ch)) {\n ch = state.input.charCodeAt(++state.position);\n }\n\n if (ch === 0x23/* # */) {\n do { ch = state.input.charCodeAt(++state.position); }\n while (ch !== 0 && !is_EOL(ch));\n break;\n }\n\n if (is_EOL(ch)) break;\n\n _position = state.position;\n\n while (ch !== 0 && !is_WS_OR_EOL(ch)) {\n ch = state.input.charCodeAt(++state.position);\n }\n\n directiveArgs.push(state.input.slice(_position, state.position));\n }\n\n if (ch !== 0) readLineBreak(state);\n\n if (_hasOwnProperty$1.call(directiveHandlers, directiveName)) {\n directiveHandlers[directiveName](state, directiveName, directiveArgs);\n } else {\n throwWarning(state, 'unknown document directive \"' + directiveName + '\"');\n }\n }\n\n skipSeparationSpace(state, true, -1);\n\n if (state.lineIndent === 0 &&\n state.input.charCodeAt(state.position) === 0x2D/* - */ &&\n state.input.charCodeAt(state.position + 1) === 0x2D/* - */ &&\n state.input.charCodeAt(state.position + 2) === 0x2D/* - */) {\n state.position += 3;\n skipSeparationSpace(state, true, -1);\n\n } else if (hasDirectives) {\n throwError(state, 'directives end mark is expected');\n }\n\n composeNode(state, state.lineIndent - 1, CONTEXT_BLOCK_OUT, false, true);\n skipSeparationSpace(state, true, -1);\n\n if (state.checkLineBreaks &&\n PATTERN_NON_ASCII_LINE_BREAKS.test(state.input.slice(documentStart, state.position))) {\n throwWarning(state, 'non-ASCII line breaks are interpreted as content');\n }\n\n state.documents.push(state.result);\n\n if (state.position === state.lineStart && testDocumentSeparator(state)) {\n\n if (state.input.charCodeAt(state.position) === 0x2E/* . */) {\n state.position += 3;\n skipSeparationSpace(state, true, -1);\n }\n return;\n }\n\n if (state.position < (state.length - 1)) {\n throwError(state, 'end of the stream or a document separator is expected');\n } else {\n return;\n }\n}\n\n\nfunction loadDocuments(input, options) {\n input = String(input);\n options = options || {};\n\n if (input.length !== 0) {\n\n // Add tailing `\\n` if not exists\n if (input.charCodeAt(input.length - 1) !== 0x0A/* LF */ &&\n input.charCodeAt(input.length - 1) !== 0x0D/* CR */) {\n input += '\\n';\n }\n\n // Strip BOM\n if (input.charCodeAt(0) === 0xFEFF) {\n input = input.slice(1);\n }\n }\n\n var state = new State$1(input, options);\n\n var nullpos = input.indexOf('\\0');\n\n if (nullpos !== -1) {\n state.position = nullpos;\n throwError(state, 'null byte is not allowed in input');\n }\n\n // Use 0 as string terminator. That significantly simplifies bounds check.\n state.input += '\\0';\n\n while (state.input.charCodeAt(state.position) === 0x20/* Space */) {\n state.lineIndent += 1;\n state.position += 1;\n }\n\n while (state.position < (state.length - 1)) {\n readDocument(state);\n }\n\n return state.documents;\n}\n\n\nfunction loadAll$1(input, iterator, options) {\n if (iterator !== null && typeof iterator === 'object' && typeof options === 'undefined') {\n options = iterator;\n iterator = null;\n }\n\n var documents = loadDocuments(input, options);\n\n if (typeof iterator !== 'function') {\n return documents;\n }\n\n for (var index = 0, length = documents.length; index < length; index += 1) {\n iterator(documents[index]);\n }\n}\n\n\nfunction load$1(input, options) {\n var documents = loadDocuments(input, options);\n\n if (documents.length === 0) {\n /*eslint-disable no-undefined*/\n return undefined;\n } else if (documents.length === 1) {\n return documents[0];\n }\n throw new exception('expected a single document in the stream, but found more');\n}\n\n\nvar loadAll_1 = loadAll$1;\nvar load_1 = load$1;\n\nvar loader = {\n\tloadAll: loadAll_1,\n\tload: load_1\n};\n\n/*eslint-disable no-use-before-define*/\n\n\n\n\n\nvar _toString = Object.prototype.toString;\nvar _hasOwnProperty = Object.prototype.hasOwnProperty;\n\nvar CHAR_BOM = 0xFEFF;\nvar CHAR_TAB = 0x09; /* Tab */\nvar CHAR_LINE_FEED = 0x0A; /* LF */\nvar CHAR_CARRIAGE_RETURN = 0x0D; /* CR */\nvar CHAR_SPACE = 0x20; /* Space */\nvar CHAR_EXCLAMATION = 0x21; /* ! */\nvar CHAR_DOUBLE_QUOTE = 0x22; /* \" */\nvar CHAR_SHARP = 0x23; /* # */\nvar CHAR_PERCENT = 0x25; /* % */\nvar CHAR_AMPERSAND = 0x26; /* & */\nvar CHAR_SINGLE_QUOTE = 0x27; /* ' */\nvar CHAR_ASTERISK = 0x2A; /* * */\nvar CHAR_COMMA = 0x2C; /* , */\nvar CHAR_MINUS = 0x2D; /* - */\nvar CHAR_COLON = 0x3A; /* : */\nvar CHAR_EQUALS = 0x3D; /* = */\nvar CHAR_GREATER_THAN = 0x3E; /* > */\nvar CHAR_QUESTION = 0x3F; /* ? */\nvar CHAR_COMMERCIAL_AT = 0x40; /* @ */\nvar CHAR_LEFT_SQUARE_BRACKET = 0x5B; /* [ */\nvar CHAR_RIGHT_SQUARE_BRACKET = 0x5D; /* ] */\nvar CHAR_GRAVE_ACCENT = 0x60; /* ` */\nvar CHAR_LEFT_CURLY_BRACKET = 0x7B; /* { */\nvar CHAR_VERTICAL_LINE = 0x7C; /* | */\nvar CHAR_RIGHT_CURLY_BRACKET = 0x7D; /* } */\n\nvar ESCAPE_SEQUENCES = {};\n\nESCAPE_SEQUENCES[0x00] = '\\\\0';\nESCAPE_SEQUENCES[0x07] = '\\\\a';\nESCAPE_SEQUENCES[0x08] = '\\\\b';\nESCAPE_SEQUENCES[0x09] = '\\\\t';\nESCAPE_SEQUENCES[0x0A] = '\\\\n';\nESCAPE_SEQUENCES[0x0B] = '\\\\v';\nESCAPE_SEQUENCES[0x0C] = '\\\\f';\nESCAPE_SEQUENCES[0x0D] = '\\\\r';\nESCAPE_SEQUENCES[0x1B] = '\\\\e';\nESCAPE_SEQUENCES[0x22] = '\\\\\"';\nESCAPE_SEQUENCES[0x5C] = '\\\\\\\\';\nESCAPE_SEQUENCES[0x85] = '\\\\N';\nESCAPE_SEQUENCES[0xA0] = '\\\\_';\nESCAPE_SEQUENCES[0x2028] = '\\\\L';\nESCAPE_SEQUENCES[0x2029] = '\\\\P';\n\nvar DEPRECATED_BOOLEANS_SYNTAX = [\n 'y', 'Y', 'yes', 'Yes', 'YES', 'on', 'On', 'ON',\n 'n', 'N', 'no', 'No', 'NO', 'off', 'Off', 'OFF'\n];\n\nvar DEPRECATED_BASE60_SYNTAX = /^[-+]?[0-9_]+(?::[0-9_]+)+(?:\\.[0-9_]*)?$/;\n\nfunction compileStyleMap(schema, map) {\n var result, keys, index, length, tag, style, type;\n\n if (map === null) return {};\n\n result = {};\n keys = Object.keys(map);\n\n for (index = 0, length = keys.length; index < length; index += 1) {\n tag = keys[index];\n style = String(map[tag]);\n\n if (tag.slice(0, 2) === '!!') {\n tag = 'tag:yaml.org,2002:' + tag.slice(2);\n }\n type = schema.compiledTypeMap['fallback'][tag];\n\n if (type && _hasOwnProperty.call(type.styleAliases, style)) {\n style = type.styleAliases[style];\n }\n\n result[tag] = style;\n }\n\n return result;\n}\n\nfunction encodeHex(character) {\n var string, handle, length;\n\n string = character.toString(16).toUpperCase();\n\n if (character <= 0xFF) {\n handle = 'x';\n length = 2;\n } else if (character <= 0xFFFF) {\n handle = 'u';\n length = 4;\n } else if (character <= 0xFFFFFFFF) {\n handle = 'U';\n length = 8;\n } else {\n throw new exception('code point within a string may not be greater than 0xFFFFFFFF');\n }\n\n return '\\\\' + handle + common.repeat('0', length - string.length) + string;\n}\n\n\nvar QUOTING_TYPE_SINGLE = 1,\n QUOTING_TYPE_DOUBLE = 2;\n\nfunction State(options) {\n this.schema = options['schema'] || _default;\n this.indent = Math.max(1, (options['indent'] || 2));\n this.noArrayIndent = options['noArrayIndent'] || false;\n this.skipInvalid = options['skipInvalid'] || false;\n this.flowLevel = (common.isNothing(options['flowLevel']) ? -1 : options['flowLevel']);\n this.styleMap = compileStyleMap(this.schema, options['styles'] || null);\n this.sortKeys = options['sortKeys'] || false;\n this.lineWidth = options['lineWidth'] || 80;\n this.noRefs = options['noRefs'] || false;\n this.noCompatMode = options['noCompatMode'] || false;\n this.condenseFlow = options['condenseFlow'] || false;\n this.quotingType = options['quotingType'] === '\"' ? QUOTING_TYPE_DOUBLE : QUOTING_TYPE_SINGLE;\n this.forceQuotes = options['forceQuotes'] || false;\n this.replacer = typeof options['replacer'] === 'function' ? options['replacer'] : null;\n\n this.implicitTypes = this.schema.compiledImplicit;\n this.explicitTypes = this.schema.compiledExplicit;\n\n this.tag = null;\n this.result = '';\n\n this.duplicates = [];\n this.usedDuplicates = null;\n}\n\n// Indents every line in a string. Empty lines (\\n only) are not indented.\nfunction indentString(string, spaces) {\n var ind = common.repeat(' ', spaces),\n position = 0,\n next = -1,\n result = '',\n line,\n length = string.length;\n\n while (position < length) {\n next = string.indexOf('\\n', position);\n if (next === -1) {\n line = string.slice(position);\n position = length;\n } else {\n line = string.slice(position, next + 1);\n position = next + 1;\n }\n\n if (line.length && line !== '\\n') result += ind;\n\n result += line;\n }\n\n return result;\n}\n\nfunction generateNextLine(state, level) {\n return '\\n' + common.repeat(' ', state.indent * level);\n}\n\nfunction testImplicitResolving(state, str) {\n var index, length, type;\n\n for (index = 0, length = state.implicitTypes.length; index < length; index += 1) {\n type = state.implicitTypes[index];\n\n if (type.resolve(str)) {\n return true;\n }\n }\n\n return false;\n}\n\n// [33] s-white ::= s-space | s-tab\nfunction isWhitespace(c) {\n return c === CHAR_SPACE || c === CHAR_TAB;\n}\n\n// Returns true if the character can be printed without escaping.\n// From YAML 1.2: \"any allowed characters known to be non-printable\n// should also be escaped. [However,] This isn\u2019t mandatory\"\n// Derived from nb-char - \\t - #x85 - #xA0 - #x2028 - #x2029.\nfunction isPrintable(c) {\n return (0x00020 <= c && c <= 0x00007E)\n || ((0x000A1 <= c && c <= 0x00D7FF) && c !== 0x2028 && c !== 0x2029)\n || ((0x0E000 <= c && c <= 0x00FFFD) && c !== CHAR_BOM)\n || (0x10000 <= c && c <= 0x10FFFF);\n}\n\n// [34] ns-char ::= nb-char - s-white\n// [27] nb-char ::= c-printable - b-char - c-byte-order-mark\n// [26] b-char ::= b-line-feed | b-carriage-return\n// Including s-white (for some reason, examples doesn't match specs in this aspect)\n// ns-char ::= c-printable - b-line-feed - b-carriage-return - c-byte-order-mark\nfunction isNsCharOrWhitespace(c) {\n return isPrintable(c)\n && c !== CHAR_BOM\n // - b-char\n && c !== CHAR_CARRIAGE_RETURN\n && c !== CHAR_LINE_FEED;\n}\n\n// [127] ns-plain-safe(c) ::= c = flow-out \u21D2 ns-plain-safe-out\n// c = flow-in \u21D2 ns-plain-safe-in\n// c = block-key \u21D2 ns-plain-safe-out\n// c = flow-key \u21D2 ns-plain-safe-in\n// [128] ns-plain-safe-out ::= ns-char\n// [129] ns-plain-safe-in ::= ns-char - c-flow-indicator\n// [130] ns-plain-char(c) ::= ( ns-plain-safe(c) - \u201C:\u201D - \u201C#\u201D )\n// | ( /* An ns-char preceding */ \u201C#\u201D )\n// | ( \u201C:\u201D /* Followed by an ns-plain-safe(c) */ )\nfunction isPlainSafe(c, prev, inblock) {\n var cIsNsCharOrWhitespace = isNsCharOrWhitespace(c);\n var cIsNsChar = cIsNsCharOrWhitespace && !isWhitespace(c);\n return (\n // ns-plain-safe\n inblock ? // c = flow-in\n cIsNsCharOrWhitespace\n : cIsNsCharOrWhitespace\n // - c-flow-indicator\n && c !== CHAR_COMMA\n && c !== CHAR_LEFT_SQUARE_BRACKET\n && c !== CHAR_RIGHT_SQUARE_BRACKET\n && c !== CHAR_LEFT_CURLY_BRACKET\n && c !== CHAR_RIGHT_CURLY_BRACKET\n )\n // ns-plain-char\n && c !== CHAR_SHARP // false on '#'\n && !(prev === CHAR_COLON && !cIsNsChar) // false on ': '\n || (isNsCharOrWhitespace(prev) && !isWhitespace(prev) && c === CHAR_SHARP) // change to true on '[^ ]#'\n || (prev === CHAR_COLON && cIsNsChar); // change to true on ':[^ ]'\n}\n\n// Simplified test for values allowed as the first character in plain style.\nfunction isPlainSafeFirst(c) {\n // Uses a subset of ns-char - c-indicator\n // where ns-char = nb-char - s-white.\n // No support of ( ( \u201C?\u201D | \u201C:\u201D | \u201C-\u201D ) /* Followed by an ns-plain-safe(c)) */ ) part\n return isPrintable(c) && c !== CHAR_BOM\n && !isWhitespace(c) // - s-white\n // - (c-indicator ::=\n // \u201C-\u201D | \u201C?\u201D | \u201C:\u201D | \u201C,\u201D | \u201C[\u201D | \u201C]\u201D | \u201C{\u201D | \u201C}\u201D\n && c !== CHAR_MINUS\n && c !== CHAR_QUESTION\n && c !== CHAR_COLON\n && c !== CHAR_COMMA\n && c !== CHAR_LEFT_SQUARE_BRACKET\n && c !== CHAR_RIGHT_SQUARE_BRACKET\n && c !== CHAR_LEFT_CURLY_BRACKET\n && c !== CHAR_RIGHT_CURLY_BRACKET\n // | \u201C#\u201D | \u201C&\u201D | \u201C*\u201D | \u201C!\u201D | \u201C|\u201D | \u201C=\u201D | \u201C>\u201D | \u201C'\u201D | \u201C\"\u201D\n && c !== CHAR_SHARP\n && c !== CHAR_AMPERSAND\n && c !== CHAR_ASTERISK\n && c !== CHAR_EXCLAMATION\n && c !== CHAR_VERTICAL_LINE\n && c !== CHAR_EQUALS\n && c !== CHAR_GREATER_THAN\n && c !== CHAR_SINGLE_QUOTE\n && c !== CHAR_DOUBLE_QUOTE\n // | \u201C%\u201D | \u201C@\u201D | \u201C`\u201D)\n && c !== CHAR_PERCENT\n && c !== CHAR_COMMERCIAL_AT\n && c !== CHAR_GRAVE_ACCENT;\n}\n\n// Simplified test for values allowed as the last character in plain style.\nfunction isPlainSafeLast(c) {\n // just not whitespace or colon, it will be checked to be plain character later\n return !isWhitespace(c) && c !== CHAR_COLON;\n}\n\n// Same as 'string'.codePointAt(pos), but works in older browsers.\nfunction codePointAt(string, pos) {\n var first = string.charCodeAt(pos), second;\n if (first >= 0xD800 && first <= 0xDBFF && pos + 1 < string.length) {\n second = string.charCodeAt(pos + 1);\n if (second >= 0xDC00 && second <= 0xDFFF) {\n // https://mathiasbynens.be/notes/javascript-encoding#surrogate-formulae\n return (first - 0xD800) * 0x400 + second - 0xDC00 + 0x10000;\n }\n }\n return first;\n}\n\n// Determines whether block indentation indicator is required.\nfunction needIndentIndicator(string) {\n var leadingSpaceRe = /^\\n* /;\n return leadingSpaceRe.test(string);\n}\n\nvar STYLE_PLAIN = 1,\n STYLE_SINGLE = 2,\n STYLE_LITERAL = 3,\n STYLE_FOLDED = 4,\n STYLE_DOUBLE = 5;\n\n// Determines which scalar styles are possible and returns the preferred style.\n// lineWidth = -1 => no limit.\n// Pre-conditions: str.length > 0.\n// Post-conditions:\n// STYLE_PLAIN or STYLE_SINGLE => no \\n are in the string.\n// STYLE_LITERAL => no lines are suitable for folding (or lineWidth is -1).\n// STYLE_FOLDED => a line > lineWidth and can be folded (and lineWidth != -1).\nfunction chooseScalarStyle(string, singleLineOnly, indentPerLevel, lineWidth,\n testAmbiguousType, quotingType, forceQuotes, inblock) {\n\n var i;\n var char = 0;\n var prevChar = null;\n var hasLineBreak = false;\n var hasFoldableLine = false; // only checked if shouldTrackWidth\n var shouldTrackWidth = lineWidth !== -1;\n var previousLineBreak = -1; // count the first line correctly\n var plain = isPlainSafeFirst(codePointAt(string, 0))\n && isPlainSafeLast(codePointAt(string, string.length - 1));\n\n if (singleLineOnly || forceQuotes) {\n // Case: no block styles.\n // Check for disallowed characters to rule out plain and single.\n for (i = 0; i < string.length; char >= 0x10000 ? i += 2 : i++) {\n char = codePointAt(string, i);\n if (!isPrintable(char)) {\n return STYLE_DOUBLE;\n }\n plain = plain && isPlainSafe(char, prevChar, inblock);\n prevChar = char;\n }\n } else {\n // Case: block styles permitted.\n for (i = 0; i < string.length; char >= 0x10000 ? i += 2 : i++) {\n char = codePointAt(string, i);\n if (char === CHAR_LINE_FEED) {\n hasLineBreak = true;\n // Check if any line can be folded.\n if (shouldTrackWidth) {\n hasFoldableLine = hasFoldableLine ||\n // Foldable line = too long, and not more-indented.\n (i - previousLineBreak - 1 > lineWidth &&\n string[previousLineBreak + 1] !== ' ');\n previousLineBreak = i;\n }\n } else if (!isPrintable(char)) {\n return STYLE_DOUBLE;\n }\n plain = plain && isPlainSafe(char, prevChar, inblock);\n prevChar = char;\n }\n // in case the end is missing a \\n\n hasFoldableLine = hasFoldableLine || (shouldTrackWidth &&\n (i - previousLineBreak - 1 > lineWidth &&\n string[previousLineBreak + 1] !== ' '));\n }\n // Although every style can represent \\n without escaping, prefer block styles\n // for multiline, since they're more readable and they don't add empty lines.\n // Also prefer folding a super-long line.\n if (!hasLineBreak && !hasFoldableLine) {\n // Strings interpretable as another type have to be quoted;\n // e.g. the string 'true' vs. the boolean true.\n if (plain && !forceQuotes && !testAmbiguousType(string)) {\n return STYLE_PLAIN;\n }\n return quotingType === QUOTING_TYPE_DOUBLE ? STYLE_DOUBLE : STYLE_SINGLE;\n }\n // Edge case: block indentation indicator can only have one digit.\n if (indentPerLevel > 9 && needIndentIndicator(string)) {\n return STYLE_DOUBLE;\n }\n // At this point we know block styles are valid.\n // Prefer literal style unless we want to fold.\n if (!forceQuotes) {\n return hasFoldableLine ? STYLE_FOLDED : STYLE_LITERAL;\n }\n return quotingType === QUOTING_TYPE_DOUBLE ? STYLE_DOUBLE : STYLE_SINGLE;\n}\n\n// Note: line breaking/folding is implemented for only the folded style.\n// NB. We drop the last trailing newline (if any) of a returned block scalar\n// since the dumper adds its own newline. This always works:\n// \u2022 No ending newline => unaffected; already using strip \"-\" chomping.\n// \u2022 Ending newline => removed then restored.\n// Importantly, this keeps the \"+\" chomp indicator from gaining an extra line.\nfunction writeScalar(state, string, level, iskey, inblock) {\n state.dump = (function () {\n if (string.length === 0) {\n return state.quotingType === QUOTING_TYPE_DOUBLE ? '\"\"' : \"''\";\n }\n if (!state.noCompatMode) {\n if (DEPRECATED_BOOLEANS_SYNTAX.indexOf(string) !== -1 || DEPRECATED_BASE60_SYNTAX.test(string)) {\n return state.quotingType === QUOTING_TYPE_DOUBLE ? ('\"' + string + '\"') : (\"'\" + string + \"'\");\n }\n }\n\n var indent = state.indent * Math.max(1, level); // no 0-indent scalars\n // As indentation gets deeper, let the width decrease monotonically\n // to the lower bound min(state.lineWidth, 40).\n // Note that this implies\n // state.lineWidth \u2264 40 + state.indent: width is fixed at the lower bound.\n // state.lineWidth > 40 + state.indent: width decreases until the lower bound.\n // This behaves better than a constant minimum width which disallows narrower options,\n // or an indent threshold which causes the width to suddenly increase.\n var lineWidth = state.lineWidth === -1\n ? -1 : Math.max(Math.min(state.lineWidth, 40), state.lineWidth - indent);\n\n // Without knowing if keys are implicit/explicit, assume implicit for safety.\n var singleLineOnly = iskey\n // No block styles in flow mode.\n || (state.flowLevel > -1 && level >= state.flowLevel);\n function testAmbiguity(string) {\n return testImplicitResolving(state, string);\n }\n\n switch (chooseScalarStyle(string, singleLineOnly, state.indent, lineWidth,\n testAmbiguity, state.quotingType, state.forceQuotes && !iskey, inblock)) {\n\n case STYLE_PLAIN:\n return string;\n case STYLE_SINGLE:\n return \"'\" + string.replace(/'/g, \"''\") + \"'\";\n case STYLE_LITERAL:\n return '|' + blockHeader(string, state.indent)\n + dropEndingNewline(indentString(string, indent));\n case STYLE_FOLDED:\n return '>' + blockHeader(string, state.indent)\n + dropEndingNewline(indentString(foldString(string, lineWidth), indent));\n case STYLE_DOUBLE:\n return '\"' + escapeString(string) + '\"';\n default:\n throw new exception('impossible error: invalid scalar style');\n }\n }());\n}\n\n// Pre-conditions: string is valid for a block scalar, 1 <= indentPerLevel <= 9.\nfunction blockHeader(string, indentPerLevel) {\n var indentIndicator = needIndentIndicator(string) ? String(indentPerLevel) : '';\n\n // note the special case: the string '\\n' counts as a \"trailing\" empty line.\n var clip = string[string.length - 1] === '\\n';\n var keep = clip && (string[string.length - 2] === '\\n' || string === '\\n');\n var chomp = keep ? '+' : (clip ? '' : '-');\n\n return indentIndicator + chomp + '\\n';\n}\n\n// (See the note for writeScalar.)\nfunction dropEndingNewline(string) {\n return string[string.length - 1] === '\\n' ? string.slice(0, -1) : string;\n}\n\n// Note: a long line without a suitable break point will exceed the width limit.\n// Pre-conditions: every char in str isPrintable, str.length > 0, width > 0.\nfunction foldString(string, width) {\n // In folded style, $k$ consecutive newlines output as $k+1$ newlines\u2014\n // unless they're before or after a more-indented line, or at the very\n // beginning or end, in which case $k$ maps to $k$.\n // Therefore, parse each chunk as newline(s) followed by a content line.\n var lineRe = /(\\n+)([^\\n]*)/g;\n\n // first line (possibly an empty line)\n var result = (function () {\n var nextLF = string.indexOf('\\n');\n nextLF = nextLF !== -1 ? nextLF : string.length;\n lineRe.lastIndex = nextLF;\n return foldLine(string.slice(0, nextLF), width);\n }());\n // If we haven't reached the first content line yet, don't add an extra \\n.\n var prevMoreIndented = string[0] === '\\n' || string[0] === ' ';\n var moreIndented;\n\n // rest of the lines\n var match;\n while ((match = lineRe.exec(string))) {\n var prefix = match[1], line = match[2];\n moreIndented = (line[0] === ' ');\n result += prefix\n + (!prevMoreIndented && !moreIndented && line !== ''\n ? '\\n' : '')\n + foldLine(line, width);\n prevMoreIndented = moreIndented;\n }\n\n return result;\n}\n\n// Greedy line breaking.\n// Picks the longest line under the limit each time,\n// otherwise settles for the shortest line over the limit.\n// NB. More-indented lines *cannot* be folded, as that would add an extra \\n.\nfunction foldLine(line, width) {\n if (line === '' || line[0] === ' ') return line;\n\n // Since a more-indented line adds a \\n, breaks can't be followed by a space.\n var breakRe = / [^ ]/g; // note: the match index will always be <= length-2.\n var match;\n // start is an inclusive index. end, curr, and next are exclusive.\n var start = 0, end, curr = 0, next = 0;\n var result = '';\n\n // Invariants: 0 <= start <= length-1.\n // 0 <= curr <= next <= max(0, length-2). curr - start <= width.\n // Inside the loop:\n // A match implies length >= 2, so curr and next are <= length-2.\n while ((match = breakRe.exec(line))) {\n next = match.index;\n // maintain invariant: curr - start <= width\n if (next - start > width) {\n end = (curr > start) ? curr : next; // derive end <= length-2\n result += '\\n' + line.slice(start, end);\n // skip the space that was output as \\n\n start = end + 1; // derive start <= length-1\n }\n curr = next;\n }\n\n // By the invariants, start <= length-1, so there is something left over.\n // It is either the whole string or a part starting from non-whitespace.\n result += '\\n';\n // Insert a break if the remainder is too long and there is a break available.\n if (line.length - start > width && curr > start) {\n result += line.slice(start, curr) + '\\n' + line.slice(curr + 1);\n } else {\n result += line.slice(start);\n }\n\n return result.slice(1); // drop extra \\n joiner\n}\n\n// Escapes a double-quoted string.\nfunction escapeString(string) {\n var result = '';\n var char = 0;\n var escapeSeq;\n\n for (var i = 0; i < string.length; char >= 0x10000 ? i += 2 : i++) {\n char = codePointAt(string, i);\n escapeSeq = ESCAPE_SEQUENCES[char];\n\n if (!escapeSeq && isPrintable(char)) {\n result += string[i];\n if (char >= 0x10000) result += string[i + 1];\n } else {\n result += escapeSeq || encodeHex(char);\n }\n }\n\n return result;\n}\n\nfunction writeFlowSequence(state, level, object) {\n var _result = '',\n _tag = state.tag,\n index,\n length,\n value;\n\n for (index = 0, length = object.length; index < length; index += 1) {\n value = object[index];\n\n if (state.replacer) {\n value = state.replacer.call(object, String(index), value);\n }\n\n // Write only valid elements, put null instead of invalid elements.\n if (writeNode(state, level, value, false, false) ||\n (typeof value === 'undefined' &&\n writeNode(state, level, null, false, false))) {\n\n if (_result !== '') _result += ',' + (!state.condenseFlow ? ' ' : '');\n _result += state.dump;\n }\n }\n\n state.tag = _tag;\n state.dump = '[' + _result + ']';\n}\n\nfunction writeBlockSequence(state, level, object, compact) {\n var _result = '',\n _tag = state.tag,\n index,\n length,\n value;\n\n for (index = 0, length = object.length; index < length; index += 1) {\n value = object[index];\n\n if (state.replacer) {\n value = state.replacer.call(object, String(index), value);\n }\n\n // Write only valid elements, put null instead of invalid elements.\n if (writeNode(state, level + 1, value, true, true, false, true) ||\n (typeof value === 'undefined' &&\n writeNode(state, level + 1, null, true, true, false, true))) {\n\n if (!compact || _result !== '') {\n _result += generateNextLine(state, level);\n }\n\n if (state.dump && CHAR_LINE_FEED === state.dump.charCodeAt(0)) {\n _result += '-';\n } else {\n _result += '- ';\n }\n\n _result += state.dump;\n }\n }\n\n state.tag = _tag;\n state.dump = _result || '[]'; // Empty sequence if no valid values.\n}\n\nfunction writeFlowMapping(state, level, object) {\n var _result = '',\n _tag = state.tag,\n objectKeyList = Object.keys(object),\n index,\n length,\n objectKey,\n objectValue,\n pairBuffer;\n\n for (index = 0, length = objectKeyList.length; index < length; index += 1) {\n\n pairBuffer = '';\n if (_result !== '') pairBuffer += ', ';\n\n if (state.condenseFlow) pairBuffer += '\"';\n\n objectKey = objectKeyList[index];\n objectValue = object[objectKey];\n\n if (state.replacer) {\n objectValue = state.replacer.call(object, objectKey, objectValue);\n }\n\n if (!writeNode(state, level, objectKey, false, false)) {\n continue; // Skip this pair because of invalid key;\n }\n\n if (state.dump.length > 1024) pairBuffer += '? ';\n\n pairBuffer += state.dump + (state.condenseFlow ? '\"' : '') + ':' + (state.condenseFlow ? '' : ' ');\n\n if (!writeNode(state, level, objectValue, false, false)) {\n continue; // Skip this pair because of invalid value.\n }\n\n pairBuffer += state.dump;\n\n // Both key and value are valid.\n _result += pairBuffer;\n }\n\n state.tag = _tag;\n state.dump = '{' + _result + '}';\n}\n\nfunction writeBlockMapping(state, level, object, compact) {\n var _result = '',\n _tag = state.tag,\n objectKeyList = Object.keys(object),\n index,\n length,\n objectKey,\n objectValue,\n explicitPair,\n pairBuffer;\n\n // Allow sorting keys so that the output file is deterministic\n if (state.sortKeys === true) {\n // Default sorting\n objectKeyList.sort();\n } else if (typeof state.sortKeys === 'function') {\n // Custom sort function\n objectKeyList.sort(state.sortKeys);\n } else if (state.sortKeys) {\n // Something is wrong\n throw new exception('sortKeys must be a boolean or a function');\n }\n\n for (index = 0, length = objectKeyList.length; index < length; index += 1) {\n pairBuffer = '';\n\n if (!compact || _result !== '') {\n pairBuffer += generateNextLine(state, level);\n }\n\n objectKey = objectKeyList[index];\n objectValue = object[objectKey];\n\n if (state.replacer) {\n objectValue = state.replacer.call(object, objectKey, objectValue);\n }\n\n if (!writeNode(state, level + 1, objectKey, true, true, true)) {\n continue; // Skip this pair because of invalid key.\n }\n\n explicitPair = (state.tag !== null && state.tag !== '?') ||\n (state.dump && state.dump.length > 1024);\n\n if (explicitPair) {\n if (state.dump && CHAR_LINE_FEED === state.dump.charCodeAt(0)) {\n pairBuffer += '?';\n } else {\n pairBuffer += '? ';\n }\n }\n\n pairBuffer += state.dump;\n\n if (explicitPair) {\n pairBuffer += generateNextLine(state, level);\n }\n\n if (!writeNode(state, level + 1, objectValue, true, explicitPair)) {\n continue; // Skip this pair because of invalid value.\n }\n\n if (state.dump && CHAR_LINE_FEED === state.dump.charCodeAt(0)) {\n pairBuffer += ':';\n } else {\n pairBuffer += ': ';\n }\n\n pairBuffer += state.dump;\n\n // Both key and value are valid.\n _result += pairBuffer;\n }\n\n state.tag = _tag;\n state.dump = _result || '{}'; // Empty mapping if no valid pairs.\n}\n\nfunction detectType(state, object, explicit) {\n var _result, typeList, index, length, type, style;\n\n typeList = explicit ? state.explicitTypes : state.implicitTypes;\n\n for (index = 0, length = typeList.length; index < length; index += 1) {\n type = typeList[index];\n\n if ((type.instanceOf || type.predicate) &&\n (!type.instanceOf || ((typeof object === 'object') && (object instanceof type.instanceOf))) &&\n (!type.predicate || type.predicate(object))) {\n\n if (explicit) {\n if (type.multi && type.representName) {\n state.tag = type.representName(object);\n } else {\n state.tag = type.tag;\n }\n } else {\n state.tag = '?';\n }\n\n if (type.represent) {\n style = state.styleMap[type.tag] || type.defaultStyle;\n\n if (_toString.call(type.represent) === '[object Function]') {\n _result = type.represent(object, style);\n } else if (_hasOwnProperty.call(type.represent, style)) {\n _result = type.represent[style](object, style);\n } else {\n throw new exception('!<' + type.tag + '> tag resolver accepts not \"' + style + '\" style');\n }\n\n state.dump = _result;\n }\n\n return true;\n }\n }\n\n return false;\n}\n\n// Serializes `object` and writes it to global `result`.\n// Returns true on success, or false on invalid object.\n//\nfunction writeNode(state, level, object, block, compact, iskey, isblockseq) {\n state.tag = null;\n state.dump = object;\n\n if (!detectType(state, object, false)) {\n detectType(state, object, true);\n }\n\n var type = _toString.call(state.dump);\n var inblock = block;\n var tagStr;\n\n if (block) {\n block = (state.flowLevel < 0 || state.flowLevel > level);\n }\n\n var objectOrArray = type === '[object Object]' || type === '[object Array]',\n duplicateIndex,\n duplicate;\n\n if (objectOrArray) {\n duplicateIndex = state.duplicates.indexOf(object);\n duplicate = duplicateIndex !== -1;\n }\n\n if ((state.tag !== null && state.tag !== '?') || duplicate || (state.indent !== 2 && level > 0)) {\n compact = false;\n }\n\n if (duplicate && state.usedDuplicates[duplicateIndex]) {\n state.dump = '*ref_' + duplicateIndex;\n } else {\n if (objectOrArray && duplicate && !state.usedDuplicates[duplicateIndex]) {\n state.usedDuplicates[duplicateIndex] = true;\n }\n if (type === '[object Object]') {\n if (block && (Object.keys(state.dump).length !== 0)) {\n writeBlockMapping(state, level, state.dump, compact);\n if (duplicate) {\n state.dump = '&ref_' + duplicateIndex + state.dump;\n }\n } else {\n writeFlowMapping(state, level, state.dump);\n if (duplicate) {\n state.dump = '&ref_' + duplicateIndex + ' ' + state.dump;\n }\n }\n } else if (type === '[object Array]') {\n if (block && (state.dump.length !== 0)) {\n if (state.noArrayIndent && !isblockseq && level > 0) {\n writeBlockSequence(state, level - 1, state.dump, compact);\n } else {\n writeBlockSequence(state, level, state.dump, compact);\n }\n if (duplicate) {\n state.dump = '&ref_' + duplicateIndex + state.dump;\n }\n } else {\n writeFlowSequence(state, level, state.dump);\n if (duplicate) {\n state.dump = '&ref_' + duplicateIndex + ' ' + state.dump;\n }\n }\n } else if (type === '[object String]') {\n if (state.tag !== '?') {\n writeScalar(state, state.dump, level, iskey, inblock);\n }\n } else if (type === '[object Undefined]') {\n return false;\n } else {\n if (state.skipInvalid) return false;\n throw new exception('unacceptable kind of an object to dump ' + type);\n }\n\n if (state.tag !== null && state.tag !== '?') {\n // Need to encode all characters except those allowed by the spec:\n //\n // [35] ns-dec-digit ::= [#x30-#x39] /* 0-9 */\n // [36] ns-hex-digit ::= ns-dec-digit\n // | [#x41-#x46] /* A-F */ | [#x61-#x66] /* a-f */\n // [37] ns-ascii-letter ::= [#x41-#x5A] /* A-Z */ | [#x61-#x7A] /* a-z */\n // [38] ns-word-char ::= ns-dec-digit | ns-ascii-letter | \u201C-\u201D\n // [39] ns-uri-char ::= \u201C%\u201D ns-hex-digit ns-hex-digit | ns-word-char | \u201C#\u201D\n // | \u201C;\u201D | \u201C/\u201D | \u201C?\u201D | \u201C:\u201D | \u201C@\u201D | \u201C&\u201D | \u201C=\u201D | \u201C+\u201D | \u201C$\u201D | \u201C,\u201D\n // | \u201C_\u201D | \u201C.\u201D | \u201C!\u201D | \u201C~\u201D | \u201C*\u201D | \u201C'\u201D | \u201C(\u201D | \u201C)\u201D | \u201C[\u201D | \u201C]\u201D\n //\n // Also need to encode '!' because it has special meaning (end of tag prefix).\n //\n tagStr = encodeURI(\n state.tag[0] === '!' ? state.tag.slice(1) : state.tag\n ).replace(/!/g, '%21');\n\n if (state.tag[0] === '!') {\n tagStr = '!' + tagStr;\n } else if (tagStr.slice(0, 18) === 'tag:yaml.org,2002:') {\n tagStr = '!!' + tagStr.slice(18);\n } else {\n tagStr = '!<' + tagStr + '>';\n }\n\n state.dump = tagStr + ' ' + state.dump;\n }\n }\n\n return true;\n}\n\nfunction getDuplicateReferences(object, state) {\n var objects = [],\n duplicatesIndexes = [],\n index,\n length;\n\n inspectNode(object, objects, duplicatesIndexes);\n\n for (index = 0, length = duplicatesIndexes.length; index < length; index += 1) {\n state.duplicates.push(objects[duplicatesIndexes[index]]);\n }\n state.usedDuplicates = new Array(length);\n}\n\nfunction inspectNode(object, objects, duplicatesIndexes) {\n var objectKeyList,\n index,\n length;\n\n if (object !== null && typeof object === 'object') {\n index = objects.indexOf(object);\n if (index !== -1) {\n if (duplicatesIndexes.indexOf(index) === -1) {\n duplicatesIndexes.push(index);\n }\n } else {\n objects.push(object);\n\n if (Array.isArray(object)) {\n for (index = 0, length = object.length; index < length; index += 1) {\n inspectNode(object[index], objects, duplicatesIndexes);\n }\n } else {\n objectKeyList = Object.keys(object);\n\n for (index = 0, length = objectKeyList.length; index < length; index += 1) {\n inspectNode(object[objectKeyList[index]], objects, duplicatesIndexes);\n }\n }\n }\n }\n}\n\nfunction dump$1(input, options) {\n options = options || {};\n\n var state = new State(options);\n\n if (!state.noRefs) getDuplicateReferences(input, state);\n\n var value = input;\n\n if (state.replacer) {\n value = state.replacer.call({ '': value }, '', value);\n }\n\n if (writeNode(state, 0, value, true, true)) return state.dump + '\\n';\n\n return '';\n}\n\nvar dump_1 = dump$1;\n\nvar dumper = {\n\tdump: dump_1\n};\n\nfunction renamed(from, to) {\n return function () {\n throw new Error('Function yaml.' + from + ' is removed in js-yaml 4. ' +\n 'Use yaml.' + to + ' instead, which is now safe by default.');\n };\n}\n\n\nvar Type = type;\nvar Schema = schema;\nvar FAILSAFE_SCHEMA = failsafe;\nvar JSON_SCHEMA = json;\nvar CORE_SCHEMA = core;\nvar DEFAULT_SCHEMA = _default;\nvar load = loader.load;\nvar loadAll = loader.loadAll;\nvar dump = dumper.dump;\nvar YAMLException = exception;\n\n// Re-export all types in case user wants to create custom schema\nvar types = {\n binary: binary,\n float: float,\n map: map,\n null: _null,\n pairs: pairs,\n set: set,\n timestamp: timestamp,\n bool: bool,\n int: int,\n merge: merge,\n omap: omap,\n seq: seq,\n str: str\n};\n\n// Removed functions from JS-YAML 3.0.x\nvar safeLoad = renamed('safeLoad', 'load');\nvar safeLoadAll = renamed('safeLoadAll', 'loadAll');\nvar safeDump = renamed('safeDump', 'dump');\n\nvar jsYaml = {\n\tType: Type,\n\tSchema: Schema,\n\tFAILSAFE_SCHEMA: FAILSAFE_SCHEMA,\n\tJSON_SCHEMA: JSON_SCHEMA,\n\tCORE_SCHEMA: CORE_SCHEMA,\n\tDEFAULT_SCHEMA: DEFAULT_SCHEMA,\n\tload: load,\n\tloadAll: loadAll,\n\tdump: dump,\n\tYAMLException: YAMLException,\n\ttypes: types,\n\tsafeLoad: safeLoad,\n\tsafeLoadAll: safeLoadAll,\n\tsafeDump: safeDump\n};\n\nexport { CORE_SCHEMA, DEFAULT_SCHEMA, FAILSAFE_SCHEMA, JSON_SCHEMA, Schema, Type, YAMLException, jsYaml as default, dump, load, loadAll, safeDump, safeLoad, safeLoadAll, types };\n", "/**\n * CodeQL metadata resolver utilities\n * Handles resolution of query metadata using the CodeQL CLI\n */\n\nimport { executeCodeQLCommand } from './cli-executor';\nimport { logger } from '../utils/logger';\n\n/**\n * Query metadata structure returned by codeql resolve metadata\n */\nexport interface QueryMetadata {\n [key: string]: string | string[];\n}\n\n/**\n * Resolve metadata for a CodeQL query file\n * @param queryPath - Absolute or relative path to the .ql query file\n * @returns Parsed metadata object or null if resolution fails\n */\nexport async function resolveQueryMetadata(queryPath: string): Promise {\n try {\n logger.info(`Resolving metadata for query: ${queryPath}`);\n\n const result = await executeCodeQLCommand(\n 'resolve metadata',\n { format: 'json' },\n [queryPath]\n );\n\n if (!result.success) {\n logger.error(`Failed to resolve metadata for ${queryPath}:`, result.stderr || result.error);\n return null;\n }\n\n // Parse the JSON output\n try {\n const metadata = JSON.parse(result.stdout);\n return metadata;\n } catch (parseError) {\n logger.error(`Failed to parse metadata JSON for ${queryPath}:`, parseError);\n return null;\n }\n } catch (error) {\n logger.error(`Error resolving metadata for ${queryPath}:`, error);\n return null;\n }\n}\n", "/**\n * CodeQL generate log-summary tool\n */\n\nimport { z } from 'zod';\nimport { CLIToolDefinition, createCodeQLSchemas, defaultCLIResultProcessor } from '../../lib/cli-tool-registry';\n\nexport const codeqlGenerateLogSummaryTool: CLIToolDefinition = {\n name: 'codeql_generate_log-summary',\n description: 'Create a summary of a structured JSON evaluator event log file',\n command: 'codeql',\n subcommand: 'generate log-summary',\n inputSchema: {\n inputLog: z.string().describe('Path to the evaluator log file to summarize'),\n outputFile: z.string().optional().describe('Path to write the summary (optional, defaults to stdout)'),\n format: z.enum(['text', 'predicates', 'overall']).optional()\n .describe('Output format: text (human-readable), predicates (JSON), or overall (stats)'),\n 'minify-output': z.boolean().optional().describe('Minify JSON output'),\n utc: z.boolean().optional().describe('Force UTC timestamps'),\n 'deduplicate-stage-summaries': z.boolean().optional().describe('Deduplicate stage summaries'),\n verbose: createCodeQLSchemas.verbose(),\n additionalArgs: createCodeQLSchemas.additionalArgs()\n },\n examples: [\n 'codeql generate log-summary --format=text -- evaluator-log.json.txt summary.txt',\n 'codeql generate log-summary --format=predicates --minify-output -- evaluator-log.json.txt',\n 'codeql generate log-summary --format=overall -- evaluator-log.json.txt overall-stats.json'\n ],\n resultProcessor: defaultCLIResultProcessor\n};", "/**\n * CodeQL generate query-help tool\n */\n\nimport { z } from 'zod';\nimport { CLIToolDefinition, createCodeQLSchemas, defaultCLIResultProcessor } from '../../lib/cli-tool-registry';\n\nexport const codeqlGenerateQueryHelpTool: CLIToolDefinition = {\n name: 'codeql_generate_query-help',\n description: 'Generate query help documentation from QLDoc comments',\n command: 'codeql',\n subcommand: 'generate query-help',\n inputSchema: {\n query: z.string().describe('Path to the query file to generate help for'),\n outputFile: z.string().optional().describe('Path to write the help documentation'),\n format: z.enum(['markdown', 'text', 'html']).optional()\n .describe('Output format for the help documentation'),\n verbose: createCodeQLSchemas.verbose(),\n additionalArgs: createCodeQLSchemas.additionalArgs()\n },\n examples: [\n 'codeql generate query-help -- MyQuery.ql',\n 'codeql generate query-help --format=markdown -- MyQuery.ql help.md',\n 'codeql generate query-help --format=html -- MyQuery.ql help.html'\n ],\n resultProcessor: defaultCLIResultProcessor\n};", "/**\n * list_codeql_databases tool\n *\n * Discovers CodeQL databases in configured base directories.\n * Scans each directory in `CODEQL_DATABASES_BASE_DIRS` for subdirectories\n * containing `codeql-database.yml`, extracts metadata (language, CLI version,\n * creation time), and returns the list.\n */\n\nimport { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport { existsSync, readdirSync, readFileSync, statSync } from 'fs';\nimport { join } from 'path';\nimport { z } from 'zod';\nimport { getDatabaseBaseDirs } from '../../lib/discovery-config';\nimport { logger } from '../../utils/logger';\n\nexport interface DatabaseInfo {\n cliVersion?: string;\n creationTime?: string;\n language?: string;\n name: string;\n path: string;\n}\n\n/**\n * Parse `codeql-database.yml` to extract metadata.\n * Uses simple line-based parsing to avoid a YAML dependency.\n */\nfunction parseDatabaseYml(ymlPath: string): Partial {\n try {\n const content = readFileSync(ymlPath, 'utf-8');\n const info: Partial = {};\n\n for (const line of content.split('\\n')) {\n const trimmed = line.trim();\n const colonIdx = trimmed.indexOf(':');\n if (colonIdx === -1) continue;\n\n const key = trimmed.substring(0, colonIdx).trim();\n const value = trimmed.substring(colonIdx + 1).trim().replace(/^[\"']|[\"']$/g, '');\n\n switch (key) {\n case 'primaryLanguage':\n info.language = value;\n break;\n case 'cliVersion':\n info.cliVersion = value;\n break;\n case 'creationTime':\n info.creationTime = value;\n break;\n }\n }\n\n return info;\n } catch {\n return {};\n }\n}\n\n/**\n * Discover CodeQL databases in the given base directories.\n *\n * @param baseDirs - Directories to scan for database subdirectories\n * @param language - Optional language filter\n * @returns List of discovered databases with metadata\n */\nexport async function discoverDatabases(\n baseDirs: string[],\n language?: string,\n): Promise {\n const databases: DatabaseInfo[] = [];\n\n for (const baseDir of baseDirs) {\n if (!existsSync(baseDir)) {\n continue;\n }\n\n let entries: string[];\n try {\n entries = readdirSync(baseDir);\n } catch {\n continue;\n }\n\n for (const entry of entries) {\n const entryPath = join(baseDir, entry);\n\n // Skip non-directories\n try {\n if (!statSync(entryPath).isDirectory()) {\n continue;\n }\n } catch {\n continue;\n }\n\n // Check for codeql-database.yml\n const ymlPath = join(entryPath, 'codeql-database.yml');\n if (!existsSync(ymlPath)) {\n continue;\n }\n\n const metadata = parseDatabaseYml(ymlPath);\n\n // Apply language filter\n if (language && metadata.language !== language) {\n continue;\n }\n\n databases.push({\n cliVersion: metadata.cliVersion,\n creationTime: metadata.creationTime,\n language: metadata.language,\n name: entry,\n path: entryPath,\n });\n }\n }\n\n return databases;\n}\n\n/**\n * Register the list_codeql_databases tool with the MCP server.\n */\nexport function registerListDatabasesTool(server: McpServer): void {\n server.tool(\n 'list_codeql_databases',\n 'List CodeQL databases discovered in configured base directories (set via CODEQL_DATABASES_BASE_DIRS env var). Returns path, language, CLI version, and creation time for each database. Use the returned database paths with codeql_query_run or codeql_database_analyze to run queries against them.',\n {\n language: z\n .string()\n .optional()\n .describe('Filter databases by language (e.g., \"javascript\", \"python\")'),\n },\n async ({ language }) => {\n try {\n const baseDirs = getDatabaseBaseDirs();\n\n if (baseDirs.length === 0) {\n return {\n content: [\n {\n type: 'text' as const,\n text: 'No database base directories configured. Set the CODEQL_DATABASES_BASE_DIRS environment variable to a colon-separated list of directories to search.',\n },\n ],\n };\n }\n\n const databases = await discoverDatabases(baseDirs, language);\n\n if (databases.length === 0) {\n const filterMsg = language ? ` for language \"${language}\"` : '';\n return {\n content: [\n {\n type: 'text' as const,\n text: `No CodeQL databases found${filterMsg} in: ${baseDirs.join(', ')}`,\n },\n ],\n };\n }\n\n const lines = [\n `Found ${databases.length} CodeQL database(s):`,\n '',\n ...databases.map((db) => {\n const parts = [` ${db.name}`];\n parts.push(` Path: ${db.path}`);\n if (db.language) parts.push(` Language: ${db.language}`);\n if (db.cliVersion) parts.push(` CLI Version: ${db.cliVersion}`);\n if (db.creationTime) parts.push(` Created: ${db.creationTime}`);\n return parts.join('\\n');\n }),\n ];\n\n return {\n content: [{ type: 'text' as const, text: lines.join('\\n') }],\n };\n } catch (error) {\n logger.error('Error listing databases:', error);\n return {\n content: [\n {\n type: 'text' as const,\n text: `Error: ${error instanceof Error ? error.message : 'Unknown error'}`,\n },\n ],\n isError: true,\n };\n }\n },\n );\n}\n", "/**\n * Discovery configuration for locating CodeQL databases, query run results,\n * and MRVA (Multi-Repository Variant Analysis) run results.\n *\n * Reads colon-separated directory lists from environment variables:\n * - `CODEQL_DATABASES_BASE_DIRS` \u2014 directories to search for CodeQL databases\n * - `CODEQL_MRVA_RUN_RESULTS_DIRS` \u2014 directories containing MRVA run result subdirectories\n * - `CODEQL_QUERY_RUN_RESULTS_DIRS` \u2014 directories containing per-run query result subdirectories\n *\n * The VS Code extension sets these automatically from vscode-codeql storage paths.\n * CLI users can set them manually.\n */\n\n/**\n * Parse a colon-separated list of directories from an environment variable.\n */\nfunction parsePathList(envValue: string | undefined): string[] {\n if (!envValue) {\n return [];\n }\n return envValue\n .split(':')\n .map((p) => p.trim())\n .filter((p) => p.length > 0);\n}\n\n/**\n * Get the list of base directories to search for CodeQL databases.\n *\n * Each directory is expected to contain one or more CodeQL database directories\n * (each with a `codeql-database.yml` file).\n *\n * Set via `CODEQL_DATABASES_BASE_DIRS` (colon-separated).\n */\nexport function getDatabaseBaseDirs(): string[] {\n return parsePathList(process.env.CODEQL_DATABASES_BASE_DIRS);\n}\n\n/**\n * Get the list of directories containing MRVA run result subdirectories.\n *\n * Each directory is expected to contain numeric subdirectories (run IDs),\n * each holding `timestamp`, `repo_states.json`, and per-repository\n * subdirectories with `repo_task.json`, `results/results.sarif`, and\n * `results/results.bqrs`.\n *\n * Set via `CODEQL_MRVA_RUN_RESULTS_DIRS` (colon-separated).\n */\nexport function getMrvaRunResultsDirs(): string[] {\n return parsePathList(process.env.CODEQL_MRVA_RUN_RESULTS_DIRS);\n}\n\n/**\n * Get the list of directories containing per-run query result subdirectories.\n *\n * Each directory is expected to contain subdirectories named like\n * `.ql-/`, each holding artifacts such as\n * `evaluator-log.jsonl`, `results.bqrs`, and `results-interpreted.sarif`.\n *\n * Set via `CODEQL_QUERY_RUN_RESULTS_DIRS` (colon-separated).\n */\nexport function getQueryRunResultsDirs(): string[] {\n return parsePathList(process.env.CODEQL_QUERY_RUN_RESULTS_DIRS);\n}\n", "/**\n * list_mrva_run_results tool\n *\n * Discovers MRVA (Multi-Repository Variant Analysis) run result directories\n * in configured search paths.\n * Scans each directory in `CODEQL_MRVA_RUN_RESULTS_DIRS` for numeric\n * subdirectories representing variant analysis runs created by vscode-codeql.\n * Reports run ID, timestamp, repositories scanned, analysis status, and\n * available artifacts for each run.\n */\n\nimport { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport { existsSync, readdirSync, readFileSync, statSync } from 'fs';\nimport { join } from 'path';\nimport { z } from 'zod';\nimport { getMrvaRunResultsDirs } from '../../lib/discovery-config';\nimport { logger } from '../../utils/logger';\n\nexport interface MrvaRepoResult {\n analysisStatus?: string;\n fullName: string;\n hasBqrs: boolean;\n hasSarif: boolean;\n resultCount?: number;\n}\n\nexport interface MrvaRunResult {\n path: string;\n repositories: MrvaRepoResult[];\n runId: string;\n timestamp?: string;\n}\n\n/**\n * Pattern matching numeric MRVA run directory names.\n */\nconst NUMERIC_DIR_PATTERN = /^\\d+$/;\n\n/**\n * Directory names to skip when walking repository subdirectories.\n */\nconst SKIP_DIRS = new Set(['.DS_Store', 'exported-results']);\n\n/**\n * Discover MRVA run result directories in the given search paths.\n *\n * @param resultsDirs - Directories to scan for MRVA run subdirectories\n * @param runId - Optional run ID filter (e.g., \"20442\")\n * @returns List of discovered MRVA run results with repository inventory\n */\nexport async function discoverMrvaRunResults(\n resultsDirs: string[],\n runId?: string,\n): Promise {\n const results: MrvaRunResult[] = [];\n\n for (const dir of resultsDirs) {\n if (!existsSync(dir)) {\n continue;\n }\n\n let entries: string[];\n try {\n entries = readdirSync(dir);\n } catch {\n continue;\n }\n\n for (const entry of entries) {\n const entryPath = join(dir, entry);\n\n // Skip non-directories\n try {\n if (!statSync(entryPath).isDirectory()) {\n continue;\n }\n } catch {\n continue;\n }\n\n // Match numeric directory names\n if (!NUMERIC_DIR_PATTERN.test(entry)) {\n continue;\n }\n\n // Apply run ID filter\n if (runId && entry !== runId) {\n continue;\n }\n\n // Read timestamp if available\n let timestamp: string | undefined;\n const timestampPath = join(entryPath, 'timestamp');\n if (existsSync(timestampPath)) {\n try {\n timestamp = readFileSync(timestampPath, 'utf-8').trim();\n } catch {\n // Ignore read errors\n }\n }\n\n // Discover repository subdirectories\n const repositories = discoverRepoResults(entryPath);\n\n results.push({\n path: entryPath,\n repositories,\n runId: entry,\n timestamp,\n });\n }\n }\n\n return results;\n}\n\n/**\n * Walk a single MRVA run directory to discover per-repository results.\n *\n * The directory structure is `//` containing `repo_task.json`\n * and optionally `results/results.sarif` and `results/results.bqrs`.\n */\nfunction discoverRepoResults(runPath: string): MrvaRepoResult[] {\n const repos: MrvaRepoResult[] = [];\n\n let ownerEntries: string[];\n try {\n ownerEntries = readdirSync(runPath);\n } catch {\n return repos;\n }\n\n for (const ownerEntry of ownerEntries) {\n if (SKIP_DIRS.has(ownerEntry)) {\n continue;\n }\n\n // Skip non-directory entries (timestamp, repo_states.json, etc.)\n const ownerPath = join(runPath, ownerEntry);\n try {\n if (!statSync(ownerPath).isDirectory()) {\n continue;\n }\n } catch {\n continue;\n }\n\n let repoEntries: string[];\n try {\n repoEntries = readdirSync(ownerPath);\n } catch {\n continue;\n }\n\n for (const repoEntry of repoEntries) {\n const repoPath = join(ownerPath, repoEntry);\n try {\n if (!statSync(repoPath).isDirectory()) {\n continue;\n }\n } catch {\n continue;\n }\n\n const fullName = `${ownerEntry}/${repoEntry}`;\n\n // Parse repo_task.json if present\n let analysisStatus: string | undefined;\n let resultCount: number | undefined;\n const repoTaskPath = join(repoPath, 'repo_task.json');\n if (existsSync(repoTaskPath)) {\n try {\n const raw = readFileSync(repoTaskPath, 'utf-8');\n const task = JSON.parse(raw);\n if (typeof task.analysisStatus === 'string') {\n analysisStatus = task.analysisStatus;\n }\n if (typeof task.resultCount === 'number') {\n resultCount = task.resultCount;\n }\n } catch {\n // Ignore parse errors\n }\n }\n\n // Check for SARIF and BQRS artifacts\n const hasSarif = existsSync(join(repoPath, 'results', 'results.sarif'));\n const hasBqrs = existsSync(join(repoPath, 'results', 'results.bqrs'));\n\n repos.push({\n analysisStatus,\n fullName,\n hasBqrs,\n hasSarif,\n resultCount,\n });\n }\n }\n\n return repos;\n}\n\n/**\n * Register the list_mrva_run_results tool with the MCP server.\n */\nexport function registerListMrvaRunResultsTool(server: McpServer): void {\n server.tool(\n 'list_mrva_run_results',\n 'List discovered MRVA (Multi-Repository Variant Analysis) run results (set via CODEQL_MRVA_RUN_RESULTS_DIRS env var). Returns run ID, timestamp, repositories scanned, analysis status, and available artifacts for each run.',\n {\n runId: z\n .string()\n .optional()\n .describe('Filter results by run ID (e.g., \"20442\")'),\n },\n async ({ runId }) => {\n try {\n const resultsDirs = getMrvaRunResultsDirs();\n\n if (resultsDirs.length === 0) {\n return {\n content: [\n {\n type: 'text' as const,\n text: 'No MRVA run results directories configured. Set the CODEQL_MRVA_RUN_RESULTS_DIRS environment variable to a colon-separated list of directories to search.',\n },\n ],\n };\n }\n\n const runs = await discoverMrvaRunResults(resultsDirs, runId);\n\n if (runs.length === 0) {\n const filterMsg = runId ? ` for run ID \"${runId}\"` : '';\n return {\n content: [\n {\n type: 'text' as const,\n text: `No MRVA run results found${filterMsg} in: ${resultsDirs.join(', ')}`,\n },\n ],\n };\n }\n\n const lines = [\n `Found ${runs.length} MRVA run result(s):`,\n '',\n ...runs.map((run) => {\n const parts = [` Run ${run.runId}`];\n parts.push(` Path: ${run.path}`);\n if (run.timestamp) parts.push(` Timestamp: ${run.timestamp}`);\n parts.push(` Repositories: ${run.repositories.length}`);\n for (const repo of run.repositories) {\n const artifacts: string[] = [];\n if (repo.hasSarif) artifacts.push('sarif');\n if (repo.hasBqrs) artifacts.push('bqrs');\n const status = repo.analysisStatus ?? 'unknown';\n const count = repo.resultCount !== undefined ? `, ${repo.resultCount} result(s)` : '';\n parts.push(` ${repo.fullName} [${status}${count}] artifacts: ${artifacts.length > 0 ? artifacts.join(', ') : 'none'}`);\n }\n return parts.join('\\n');\n }),\n ];\n\n return {\n content: [{ type: 'text' as const, text: lines.join('\\n') }],\n };\n } catch (error) {\n logger.error('Error listing MRVA run results:', error);\n return {\n content: [\n {\n type: 'text' as const,\n text: `Error: ${error instanceof Error ? error.message : 'Unknown error'}`,\n },\n ],\n isError: true,\n };\n }\n },\n );\n}\n", "/**\n * list_query_run_results tool\n *\n * Discovers per-query-run result directories in configured search paths.\n * Scans each directory in `CODEQL_QUERY_RUN_RESULTS_DIRS` for subdirectories\n * matching the `.ql-` naming convention used by vscode-codeql.\n * Reports which artifacts (evaluator logs, BQRS, SARIF) are present in each run.\n *\n * Supports filtering by:\n * - `queryName` \u2014 exact match on the query file name (e.g., \"UI5Xss.ql\")\n * - `language` \u2014 filter by CodeQL language extracted from query.log db-scheme path\n * - `queryPath` \u2014 substring or exact match against the full query file path\n */\n\nimport { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport { existsSync, readdirSync, readFileSync, statSync } from 'fs';\nimport { join } from 'path';\nimport { z } from 'zod';\nimport { getQueryRunResultsDirs } from '../../lib/discovery-config';\nimport { logger } from '../../utils/logger';\n\nexport interface QueryRunResult {\n databasePath?: string;\n hasBqrs: boolean;\n hasEvaluatorLog: boolean;\n hasQueryLog: boolean;\n hasSarif: boolean;\n hasSummaryLog: boolean;\n language?: string;\n path: string;\n queryName: string;\n queryPath?: string;\n runId: string;\n timestamp?: string;\n}\n\n/**\n * Metadata extracted from a vscode-codeql query.log file.\n */\nexport interface QueryLogMetadata {\n databasePath?: string;\n language?: string;\n queryPath?: string;\n}\n\n/**\n * Filters for narrowing query run results.\n */\nexport interface QueryRunResultsFilter {\n language?: string;\n queryName?: string;\n queryPath?: string;\n}\n\n/**\n * Pattern matching vscode-codeql query run directory names: `.ql-`\n */\nconst QUERY_RUN_DIR_PATTERN = /^(.+\\.ql)-(.+)$/;\n\n/**\n * Pattern matching the `runQuery called with ` line in query.log.\n * Example: `[2026-02-15 12:52:37] [SPAMMY] execute query-server2> runQuery called with /path/to/Query.ql`\n */\nconst RUN_QUERY_PATTERN = /runQuery called with\\s+(\\S+)/;\n\n/**\n * Pattern matching the `--dbscheme=` argument in query.log when it\n * includes the database root directory with the `db-/` segment.\n * Example: `--dbscheme=/databases/my-db/db-javascript/semmlecode.javascript.dbscheme`\n */\nconst DBSCHEME_DB_PATH_PATTERN = /--dbscheme=(.+?)\\/db-(\\w+)\\//;\n\n/**\n * Fallback pattern matching language from the semmlecode dbscheme filename.\n * Matches both `semmlecode..dbscheme` and `semmlecode.dbscheme`\n * (the latter is used by Java). Also matches dbscheme paths from QL packs\n * like `codeql/-all/`.\n *\n * Examples:\n * - `semmlecode.javascript.dbscheme` \u2192 javascript\n * - `semmlecode.python.dbscheme` \u2192 python\n * - `codeql/javascript-all/2.6.20/semmlecode.javascript.dbscheme` \u2192 javascript\n * - `semmlecode.dbscheme` (Java) \u2192 java (from `db-java/` or `codeql/java-all/`)\n */\nconst DBSCHEME_LANGUAGE_PATTERN = /semmlecode\\.(\\w+)\\.dbscheme/;\n\n/**\n * Fallback pattern to extract language from QL pack path in dbscheme references.\n * Example: `codeql/javascript-all/2.6.20/` \u2192 javascript\n */\nconst QLPACK_LANGUAGE_PATTERN = /codeql\\/(\\w+)-all\\//;\n\n/**\n * Parse a vscode-codeql query.log file to extract metadata about the query run.\n *\n * Extracts:\n * - `queryPath` \u2014 from the `runQuery called with ` line\n * - `databasePath` \u2014 the database root from the `--dbscheme=` argument (when available)\n * - `language` \u2014 from `db-/` segment, or `semmlecode..dbscheme`,\n * or `codeql/-all/` QL pack path\n *\n * @param logContent - Raw content of the query.log file\n * @returns Extracted metadata (fields are undefined if not found)\n */\nexport function parseQueryLogMetadata(logContent: string): QueryLogMetadata {\n const metadata: QueryLogMetadata = {};\n\n // Extract query path from runQuery line\n const runQueryMatch = RUN_QUERY_PATTERN.exec(logContent);\n if (runQueryMatch) {\n metadata.queryPath = runQueryMatch[1];\n }\n\n // Try to extract database path and language from --dbscheme=/db-/\n const dbPathMatch = DBSCHEME_DB_PATH_PATTERN.exec(logContent);\n if (dbPathMatch) {\n metadata.databasePath = dbPathMatch[1];\n metadata.language = dbPathMatch[2];\n }\n\n // If language wasn't found from db path, try semmlecode..dbscheme\n if (!metadata.language) {\n const langMatch = DBSCHEME_LANGUAGE_PATTERN.exec(logContent);\n if (langMatch) {\n metadata.language = langMatch[1];\n }\n }\n\n // Last resort: extract from codeql/-all/ QL pack path\n if (!metadata.language) {\n const packMatch = QLPACK_LANGUAGE_PATTERN.exec(logContent);\n if (packMatch) {\n metadata.language = packMatch[1];\n }\n }\n\n return metadata;\n}\n\n/**\n * Discover query run result directories in the given search paths.\n *\n * @param resultsDirs - Directories to scan for per-run subdirectories\n * @param filter - Optional filters: queryName, language, queryPath\n * @returns List of discovered query run results with artifact inventory\n */\nexport async function discoverQueryRunResults(\n resultsDirs: string[],\n filter?: QueryRunResultsFilter | string,\n): Promise {\n // Backward-compatible: if filter is a string, treat as queryName\n const normalizedFilter: QueryRunResultsFilter | undefined =\n typeof filter === 'string' ? { queryName: filter } : filter;\n\n const results: QueryRunResult[] = [];\n\n for (const dir of resultsDirs) {\n if (!existsSync(dir)) {\n continue;\n }\n\n let entries: string[];\n try {\n entries = readdirSync(dir);\n } catch {\n continue;\n }\n\n for (const entry of entries) {\n const entryPath = join(dir, entry);\n\n // Skip non-directories\n try {\n if (!statSync(entryPath).isDirectory()) {\n continue;\n }\n } catch {\n continue;\n }\n\n // Match the naming pattern\n const match = QUERY_RUN_DIR_PATTERN.exec(entry);\n if (!match) {\n continue;\n }\n\n const [, name, runId] = match;\n\n // Apply query name filter (cheap, no I/O needed)\n if (normalizedFilter?.queryName && name !== normalizedFilter.queryName) {\n continue;\n }\n\n // Check which artifacts are present\n const hasEvaluatorLog = existsSync(join(entryPath, 'evaluator-log.jsonl'));\n const hasBqrs = existsSync(join(entryPath, 'results.bqrs'));\n const hasSarif = existsSync(join(entryPath, 'results-interpreted.sarif'));\n const hasQueryLog = existsSync(join(entryPath, 'query.log'));\n const hasSummaryLog = existsSync(join(entryPath, 'evaluator-log.summary.jsonl'));\n\n // Read timestamp if available\n let timestamp: string | undefined;\n const timestampPath = join(entryPath, 'timestamp');\n if (existsSync(timestampPath)) {\n try {\n timestamp = readFileSync(timestampPath, 'utf-8').trim();\n } catch {\n // Ignore read errors\n }\n }\n\n // Parse query.log for metadata (queryPath, language, databasePath)\n let metadata: QueryLogMetadata = {};\n if (hasQueryLog) {\n try {\n const logContent = readFileSync(join(entryPath, 'query.log'), 'utf-8');\n metadata = parseQueryLogMetadata(logContent);\n } catch {\n // Ignore read errors\n }\n }\n\n // Apply language filter (requires metadata from query.log)\n if (normalizedFilter?.language && metadata.language !== normalizedFilter.language) {\n continue;\n }\n\n // Apply queryPath filter (substring or exact match)\n if (normalizedFilter?.queryPath) {\n if (!metadata.queryPath) {\n continue;\n }\n const filterPath = normalizedFilter.queryPath;\n const isExact = filterPath.startsWith('/');\n if (isExact) {\n if (metadata.queryPath !== filterPath) {\n continue;\n }\n } else {\n if (!metadata.queryPath.toLowerCase().includes(filterPath.toLowerCase())) {\n continue;\n }\n }\n }\n\n results.push({\n databasePath: metadata.databasePath,\n hasBqrs,\n hasEvaluatorLog,\n hasQueryLog,\n hasSarif,\n hasSummaryLog,\n language: metadata.language,\n path: entryPath,\n queryName: name,\n queryPath: metadata.queryPath,\n runId,\n timestamp,\n });\n }\n }\n\n return results;\n}\n\n/**\n * Register the list_query_run_results tool with the MCP server.\n */\nexport function registerListQueryRunResultsTool(server: McpServer): void {\n server.tool(\n 'list_query_run_results',\n 'List discovered query run result directories (set via CODEQL_QUERY_RUN_RESULTS_DIRS env var). Returns path, query name, timestamp, language, query file path, and available artifacts (evaluator-log, bqrs, sarif, query.log, summary) for each run. Filter by queryName, language, or queryPath to narrow results. Use the returned BQRS paths with codeql_bqrs_decode or codeql_bqrs_info to inspect query results.',\n {\n language: z\n .string()\n .optional()\n .describe(\n 'Filter by CodeQL language (e.g., \"javascript\", \"python\", \"java\"). Extracted from the database path in query.log. Runs without a query.log are excluded when this filter is set.',\n ),\n queryName: z\n .string()\n .optional()\n .describe('Filter results by query name (e.g., \"UI5Xss.ql\")'),\n queryPath: z\n .string()\n .optional()\n .describe(\n 'Filter by query file path. Absolute paths match exactly; relative paths/substrings match case-insensitively. Requires query.log to be present.',\n ),\n },\n async ({ language, queryName, queryPath }) => {\n try {\n const resultsDirs = getQueryRunResultsDirs();\n\n if (resultsDirs.length === 0) {\n return {\n content: [\n {\n type: 'text' as const,\n text: 'No query run results directories configured. Set the CODEQL_QUERY_RUN_RESULTS_DIRS environment variable to a colon-separated list of directories to search.',\n },\n ],\n };\n }\n\n const filter: QueryRunResultsFilter = {};\n if (queryName) filter.queryName = queryName;\n if (language) filter.language = language;\n if (queryPath) filter.queryPath = queryPath;\n\n const runs = await discoverQueryRunResults(\n resultsDirs,\n Object.keys(filter).length > 0 ? filter : undefined,\n );\n\n if (runs.length === 0) {\n const filterParts: string[] = [];\n if (queryName) filterParts.push(`query \"${queryName}\"`);\n if (language) filterParts.push(`language \"${language}\"`);\n if (queryPath) filterParts.push(`path \"${queryPath}\"`);\n const filterMsg = filterParts.length > 0 ? ` for ${filterParts.join(', ')}` : '';\n return {\n content: [\n {\n type: 'text' as const,\n text: `No query run results found${filterMsg} in: ${resultsDirs.join(', ')}`,\n },\n ],\n };\n }\n\n const lines = [\n `Found ${runs.length} query run result(s):`,\n '',\n ...runs.map((run) => {\n const artifacts: string[] = [];\n if (run.hasEvaluatorLog) artifacts.push('evaluator-log');\n if (run.hasSummaryLog) artifacts.push('summary-log');\n if (run.hasBqrs) artifacts.push('bqrs');\n if (run.hasSarif) artifacts.push('sarif');\n if (run.hasQueryLog) artifacts.push('query-log');\n const parts = [` ${run.queryName} (${run.runId})`];\n parts.push(` Path: ${run.path}`);\n if (run.timestamp) parts.push(` Timestamp: ${run.timestamp}`);\n if (run.language) parts.push(` Language: ${run.language}`);\n if (run.queryPath) parts.push(` Query: ${run.queryPath}`);\n if (run.databasePath) parts.push(` Database: ${run.databasePath}`);\n parts.push(` Artifacts: ${artifacts.length > 0 ? artifacts.join(', ') : 'none'}`);\n if (run.hasBqrs) parts.push(` BQRS: ${join(run.path, 'results.bqrs')}`);\n return parts.join('\\n');\n }),\n ];\n\n return {\n content: [{ type: 'text' as const, text: lines.join('\\n') }],\n };\n } catch (error) {\n logger.error('Error listing query run results:', error);\n return {\n content: [\n {\n type: 'text' as const,\n text: `Error: ${error instanceof Error ? error.message : 'Unknown error'}`,\n },\n ],\n isError: true,\n };\n }\n },\n );\n}\n", "/**\n * CodeQL pack install tool\n */\n\nimport { z } from 'zod';\nimport { CLIToolDefinition, createCodeQLSchemas } from '../../lib/cli-tool-registry';\n\nexport const codeqlPackInstallTool: CLIToolDefinition = {\n name: 'codeql_pack_install',\n description: 'Install CodeQL pack dependencies',\n command: 'codeql',\n subcommand: 'pack install',\n inputSchema: {\n packDir: z.string().optional().describe('Directory containing qlpack.yml (default: current)'),\n force: z.boolean().optional().describe('Force reinstall of dependencies'),\n 'no-strict-mode': z.boolean().optional()\n .describe('Allow non-strict dependency resolution'),\n verbose: createCodeQLSchemas.verbose(),\n additionalArgs: createCodeQLSchemas.additionalArgs()\n },\n examples: [\n 'codeql pack install',\n 'codeql pack install --force /path/to/pack',\n 'codeql pack install --no-strict-mode'\n ]\n};", "/**\n * CodeQL pack ls tool\n */\n\nimport { z } from 'zod';\nimport { CLIToolDefinition, createCodeQLSchemas, defaultCLIResultProcessor } from '../../lib/cli-tool-registry';\n\nexport const codeqlPackLsTool: CLIToolDefinition = {\n name: 'codeql_pack_ls',\n description: 'List CodeQL packs under some local directory path',\n command: 'codeql',\n subcommand: 'pack ls',\n inputSchema: {\n dir: z.string().optional().describe('The root directory of the package or workspace, defaults to the current working directory'),\n format: z.enum(['text', 'json']).optional()\n .describe('Output format: text (default) or json'),\n groups: z.string().optional()\n .describe('List of CodeQL pack groups to include or exclude'),\n verbose: createCodeQLSchemas.verbose(),\n additionalArgs: createCodeQLSchemas.additionalArgs()\n },\n examples: [\n 'codeql pack ls -- .',\n 'codeql pack ls --format=json -- /path/to/pack-directory',\n 'codeql pack ls --format=json --groups=queries,tests -- .'\n ],\n resultProcessor: defaultCLIResultProcessor\n};", "/**\n * MCP tool: profile_codeql_query_from_logs\n *\n * Parses CodeQL query evaluation logs into a performance profile WITHOUT\n * running the query. Works with logs from `codeql query run`,\n * `codeql database analyze`, or vscode-codeql query history.\n */\n\nimport { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport { existsSync, mkdirSync, writeFileSync } from 'fs';\nimport { basename, dirname, join } from 'path';\nimport { z } from 'zod';\nimport {\n parseEvaluatorLog,\n type PredicateProfile,\n type ProfileData,\n} from '../../lib/evaluator-log-parser';\nimport { logger } from '../../utils/logger';\n\n// ---------------------------------------------------------------------------\n// Formatting helpers\n// ---------------------------------------------------------------------------\n\n/**\n * Format the full profile data as pretty-printed JSON.\n */\nfunction formatAsJson(profile: ProfileData): string {\n return JSON.stringify(profile, null, 2);\n}\n\n/**\n * Format profile data as a Mermaid diagram.\n *\n * For single-query logs the diagram has one query root node with sub-nodes\n * for the top-N most expensive predicates. For multi-query logs each query\n * gets its own sub-graph.\n */\nfunction formatAsMermaid(profile: ProfileData, topN: number): string {\n const lines: string[] = [];\n\n lines.push('```mermaid');\n lines.push('graph TD');\n lines.push('');\n\n if (profile.queries.length <= 1) {\n // Single query layout\n const query = profile.queries[0] ?? {\n queryName: 'unknown',\n totalDurationMs: 0,\n predicates: [],\n predicateCount: 0,\n cacheHits: 0,\n };\n const qLabel = sanitizeMermaid(basename(query.queryName));\n lines.push(\n ` QUERY[\"${qLabel}
Total: ${query.totalDurationMs.toFixed(2)}ms
Predicates: ${query.predicateCount}\"]`\n );\n lines.push('');\n\n const topPredicates = getTopPredicates(query.predicates, topN);\n topPredicates.forEach((pred, idx) => {\n const nodeId = `P${idx}`;\n const name = sanitizeMermaid(pred.predicateName).substring(0, 50);\n const dur = pred.durationMs.toFixed(2);\n const size =\n pred.resultSize !== undefined ? String(pred.resultSize) : '?';\n lines.push(\n ` ${nodeId}[\"${name}
${dur}ms | ${size} results\"]`\n );\n });\n\n lines.push('');\n\n topPredicates.forEach((_pred, idx) => {\n lines.push(` QUERY --> P${idx}`);\n });\n } else {\n // Multi-query layout\n lines.push(\n ` ROOT[\"Evaluation Log
${profile.queries.length} queries\"]`\n );\n lines.push('');\n\n profile.queries.forEach((query, qIdx) => {\n const qNodeId = `Q${qIdx}`;\n const qLabel = sanitizeMermaid(basename(query.queryName));\n lines.push(\n ` ${qNodeId}[\"${qLabel}
${query.totalDurationMs.toFixed(2)}ms
Predicates: ${query.predicateCount}\"]`\n );\n lines.push(` ROOT --> ${qNodeId}`);\n\n const topPredicates = getTopPredicates(query.predicates, topN);\n topPredicates.forEach((pred, pIdx) => {\n const nodeId = `Q${qIdx}P${pIdx}`;\n const name = sanitizeMermaid(pred.predicateName).substring(0, 50);\n const dur = pred.durationMs.toFixed(2);\n const size =\n pred.resultSize !== undefined ? String(pred.resultSize) : '?';\n lines.push(\n ` ${nodeId}[\"${name}
${dur}ms | ${size} results\"]`\n );\n lines.push(` ${qNodeId} --> ${nodeId}`);\n });\n lines.push('');\n });\n }\n\n lines.push('');\n lines.push(\n ' classDef default fill:#e1f5ff,stroke:#333,stroke-width:2px'\n );\n lines.push(\n ' classDef query fill:#ffe1e1,stroke:#333,stroke-width:3px'\n );\n lines.push(' class QUERY query');\n lines.push('```');\n\n return lines.join('\\n');\n}\n\n/**\n * Sanitize a string for safe inclusion in a Mermaid node label.\n */\nfunction sanitizeMermaid(text: string): string {\n return text.replace(/[<>\"]/g, '');\n}\n\n/**\n * Return the top-N most expensive predicates sorted by descending duration.\n */\nfunction getTopPredicates(\n predicates: PredicateProfile[],\n topN: number\n): PredicateProfile[] {\n return [...predicates]\n .sort((a, b) => b.durationMs - a.durationMs)\n .slice(0, topN);\n}\n\n// ---------------------------------------------------------------------------\n// Text summary\n// ---------------------------------------------------------------------------\n\nfunction buildTextSummary(\n profile: ProfileData,\n topN: number,\n outputFiles: string[]\n): string {\n const sections: string[] = [];\n\n sections.push('Query log profiling completed successfully!');\n sections.push('');\n sections.push('Output Files:');\n for (const f of outputFiles) {\n sections.push(` - ${f}`);\n }\n\n sections.push('');\n sections.push(`Log Format: ${profile.logFormat}`);\n if (profile.codeqlVersion) {\n sections.push(`CodeQL Version: ${profile.codeqlVersion}`);\n }\n sections.push(`Total Events: ${profile.totalEvents}`);\n sections.push(`Queries: ${profile.queries.length}`);\n\n for (const query of profile.queries) {\n sections.push('');\n sections.push(`--- ${basename(query.queryName)} ---`);\n sections.push(` Total Duration: ${query.totalDurationMs.toFixed(2)} ms`);\n sections.push(` Predicates Evaluated: ${query.predicateCount}`);\n sections.push(` Cache Hits: ${query.cacheHits}`);\n\n const top = getTopPredicates(query.predicates, topN);\n if (top.length > 0) {\n sections.push(` Top ${top.length} Most Expensive Predicates:`);\n top.forEach((pred, idx) => {\n const sizeStr =\n pred.resultSize !== undefined ? `, ${pred.resultSize} results` : '';\n sections.push(\n ` ${idx + 1}. ${pred.predicateName} (${pred.durationMs.toFixed(2)} ms${sizeStr})`\n );\n });\n }\n }\n\n return sections.join('\\n');\n}\n\n// ---------------------------------------------------------------------------\n// Tool registration\n// ---------------------------------------------------------------------------\n\n/**\n * Register the `profile_codeql_query_from_logs` tool with the MCP server.\n */\nexport function registerProfileCodeQLQueryFromLogsTool(\n server: McpServer\n): void {\n server.tool(\n 'profile_codeql_query_from_logs',\n 'Parse CodeQL query evaluation logs into a performance profile without re-running the query. Works with logs from codeql query run, codeql database analyze, or vscode-codeql query history.',\n {\n evaluatorLog: z\n .string()\n .describe(\n 'Path to evaluator-log.jsonl or evaluator-log.summary.jsonl'\n ),\n outputDir: z\n .string()\n .optional()\n .describe(\n 'Directory to write profile output files (defaults to same directory as log)'\n ),\n topN: z\n .number()\n .optional()\n .describe(\n 'Number of most expensive predicates to highlight (default: 20)'\n ),\n },\n async (params) => {\n try {\n const { evaluatorLog, outputDir, topN } = params;\n const effectiveTopN = topN ?? 20;\n\n // Validate input path\n if (!existsSync(evaluatorLog)) {\n return {\n content: [\n {\n type: 'text' as const,\n text: `Evaluator log not found at: ${evaluatorLog}`,\n },\n ],\n isError: true,\n };\n }\n\n // Parse log\n logger.info(`Parsing evaluator log from: ${evaluatorLog}`);\n const profile = parseEvaluatorLog(evaluatorLog);\n\n // Determine output directory\n const profileOutputDir = outputDir ?? dirname(evaluatorLog);\n mkdirSync(profileOutputDir, { recursive: true });\n\n // Write profile JSON\n const jsonPath = join(\n profileOutputDir,\n 'query-evaluation-profile.json'\n );\n writeFileSync(jsonPath, formatAsJson(profile));\n logger.info(`Profile JSON written to: ${jsonPath}`);\n\n // Write Mermaid diagram\n const mdPath = join(\n profileOutputDir,\n 'query-evaluation-profile.md'\n );\n writeFileSync(mdPath, formatAsMermaid(profile, effectiveTopN));\n logger.info(`Profile Mermaid diagram written to: ${mdPath}`);\n\n // Build response\n const outputFilesList = [\n `Profile JSON: ${jsonPath}`,\n `Profile Mermaid: ${mdPath}`,\n `Evaluator Log: ${evaluatorLog}`,\n ];\n\n const responseText = buildTextSummary(\n profile,\n effectiveTopN,\n outputFilesList\n );\n\n return {\n content: [{ type: 'text' as const, text: responseText }],\n };\n } catch (error) {\n logger.error(\n 'Error profiling CodeQL query from logs:',\n error\n );\n return {\n content: [\n {\n type: 'text' as const,\n text: `Failed to profile query from logs: ${error instanceof Error ? error.message : String(error)}`,\n },\n ],\n isError: true,\n };\n }\n }\n );\n}\n", "/**\n * Reusable parser for CodeQL evaluator log files.\n *\n * Supports two formats:\n * - **Raw** (`evaluator-log.jsonl`): Pretty-printed JSON objects with a `type`\n * field (`LOG_HEADER`, `QUERY_STARTED`, `PREDICATE_STARTED`, etc.)\n * - **Summary** (`evaluator-log.summary.jsonl`): Pretty-printed JSON objects\n * without a `type` field; identified by `summaryLogVersion` or\n * `evaluationStrategy`.\n *\n * Both formats use pretty-printed JSON separated by `}\\n{` boundaries.\n */\n\nimport { readFileSync } from 'fs';\nimport { logger } from '../utils/logger';\n\n// ---------------------------------------------------------------------------\n// Public interfaces\n// ---------------------------------------------------------------------------\n\n/** Performance profile for a single evaluated predicate. */\nexport interface PredicateProfile {\n predicateName: string;\n position?: string;\n durationMs: number;\n resultSize?: number;\n pipelineCount?: number;\n evaluationStrategy?: string;\n dependencies: string[];\n}\n\n/** Performance profile for a single query within a log. */\nexport interface QueryProfile {\n queryName: string;\n totalDurationMs: number;\n predicateCount: number;\n predicates: PredicateProfile[];\n cacheHits: number;\n}\n\n/** Top-level result returned by all parse functions. */\nexport interface ProfileData {\n codeqlVersion?: string;\n logFormat: 'raw' | 'summary';\n queries: QueryProfile[];\n totalEvents: number;\n}\n\n// ---------------------------------------------------------------------------\n// Format detection\n// ---------------------------------------------------------------------------\n\n/**\n * Auto-detect whether the first parsed JSON object comes from a raw\n * evaluator log or a summary log.\n *\n * Raw events always contain a `type` string field.\n * Summary events never have `type`; the header carries `summaryLogVersion`.\n */\nexport function detectLogFormat(firstEvent: Record): 'raw' | 'summary' {\n if (typeof firstEvent.type === 'string') {\n return 'raw';\n }\n return 'summary';\n}\n\n// ---------------------------------------------------------------------------\n// Helpers\n// ---------------------------------------------------------------------------\n\n/**\n * Split a pretty-printed multi-JSON file into individual JSON strings.\n *\n * The log file contains multiple JSON objects that are pretty-printed,\n * separated by the pattern `}\\n\\n{` (closing brace, blank line, opening\n * brace). We split on `\\n}\\n` boundaries and reconstruct valid objects.\n */\nfunction splitJsonObjects(content: string): string[] {\n // Trim leading/trailing whitespace\n const trimmed = content.trim();\n if (trimmed.length === 0) {\n return [];\n }\n\n // Split on closing-brace + newline(s) + opening-brace boundaries.\n // We use a regex that matches `}\\n` followed by optional blank lines\n // then `{` \u2013 capturing the boundary so we can reconstruct.\n const parts = trimmed.split(/\\n\\}\\s*\\n\\s*\\{/);\n\n if (parts.length === 1) {\n // Single object or single-line \u2013 return as-is\n return [trimmed];\n }\n\n // Reconstruct: first part needs closing `}`, middle parts need both,\n // last part needs opening `{`.\n return parts.map((part, idx) => {\n if (idx === 0) {\n return part + '\\n}';\n }\n if (idx === parts.length - 1) {\n return '{\\n' + part;\n }\n return '{\\n' + part + '\\n}';\n });\n}\n\n/**\n * Parse all JSON objects from an evaluator log file.\n */\nfunction parseJsonObjects(logPath: string): Record[] {\n const content = readFileSync(logPath, 'utf-8');\n const objectStrings = splitJsonObjects(content);\n\n const results: Record[] = [];\n for (const objStr of objectStrings) {\n try {\n results.push(JSON.parse(objStr) as Record);\n } catch {\n logger.warn(\n `Failed to parse evaluator log object: ${objStr.substring(0, 120)}...`\n );\n }\n }\n return results;\n}\n\n// ---------------------------------------------------------------------------\n// Raw evaluator log parsing\n// ---------------------------------------------------------------------------\n\n/**\n * Parse a raw `evaluator-log.jsonl` file into {@link ProfileData}.\n *\n * Tracks `QUERY_STARTED`/`QUERY_COMPLETED` pairs, computes predicate\n * durations from `PREDICATE_STARTED`/`PREDICATE_COMPLETED` nanoTime\n * differences, and groups predicates by `queryCausingWork`.\n */\nexport function parseRawEvaluatorLog(logPath: string): ProfileData {\n const events = parseJsonObjects(logPath);\n\n let codeqlVersion: string | undefined;\n\n // Maps: eventId \u2192 event data for lookups\n const queryStartEvents = new Map<\n number,\n { queryName: string; nanoTime: number }\n >();\n const predicateStartEvents = new Map<\n number,\n {\n predicateName: string;\n position?: string;\n predicateType?: string;\n dependencies: string[];\n queryCausingWork?: number;\n nanoTime: number;\n pipelineCount: number;\n }\n >();\n\n // Completed predicate profiles grouped by query eventId\n const queryPredicates = new Map();\n // Query end nanoTimes keyed by query start eventId\n const queryEndNanoTimes = new Map();\n // Track cache lookups per query\n const queryCacheHits = new Map();\n // Fallback query eventId for predicates without queryCausingWork\n let firstQueryEventId: number | undefined;\n\n for (const event of events) {\n const eventType = event.type as string | undefined;\n\n switch (eventType) {\n case 'LOG_HEADER': {\n codeqlVersion = event.codeqlVersion as string | undefined;\n break;\n }\n\n case 'QUERY_STARTED': {\n const eid = event.eventId as number;\n const qName = (event.queryName as string) || 'unknown';\n queryStartEvents.set(eid, {\n queryName: qName,\n nanoTime: event.nanoTime as number,\n });\n queryPredicates.set(eid, []);\n queryCacheHits.set(eid, 0);\n if (firstQueryEventId === undefined) {\n firstQueryEventId = eid;\n }\n break;\n }\n\n case 'QUERY_COMPLETED': {\n const startEid = event.startEvent as number;\n queryEndNanoTimes.set(startEid, event.nanoTime as number);\n break;\n }\n\n case 'PREDICATE_STARTED': {\n const eid = event.eventId as number;\n const deps = event.dependencies as Record | undefined;\n predicateStartEvents.set(eid, {\n predicateName: (event.predicateName as string) || 'unknown',\n position: event.position as string | undefined,\n predicateType: event.predicateType as string | undefined,\n dependencies: deps ? Object.keys(deps) : [],\n queryCausingWork: event.queryCausingWork as number | undefined,\n nanoTime: event.nanoTime as number,\n pipelineCount: 0,\n });\n break;\n }\n\n case 'PIPELINE_COMPLETED': {\n // Count pipelines for the parent predicate\n const pipelineStartEid = event.startEvent as number;\n // Find the pipeline_started event to get predicateStartEvent\n const pipelineStartEvt = events.find(\n (e) =>\n (e.type as string) === 'PIPELINE_STARTED' &&\n (e.eventId as number) === pipelineStartEid\n );\n if (pipelineStartEvt) {\n const predEid = pipelineStartEvt.predicateStartEvent as number;\n const predStart = predicateStartEvents.get(predEid);\n if (predStart) {\n predStart.pipelineCount += 1;\n }\n }\n break;\n }\n\n case 'PREDICATE_COMPLETED': {\n const startEid = event.startEvent as number;\n const predStart = predicateStartEvents.get(startEid);\n if (predStart) {\n const durationNs =\n (event.nanoTime as number) - predStart.nanoTime;\n const durationMs = durationNs / 1_000_000;\n\n const profile: PredicateProfile = {\n predicateName: predStart.predicateName,\n position: predStart.position,\n durationMs,\n resultSize: event.resultSize as number | undefined,\n pipelineCount:\n predStart.pipelineCount > 0\n ? predStart.pipelineCount\n : undefined,\n evaluationStrategy: predStart.predicateType,\n dependencies: predStart.dependencies,\n };\n\n const qEid =\n predStart.queryCausingWork ?? firstQueryEventId;\n if (qEid !== undefined) {\n let arr = queryPredicates.get(qEid);\n if (!arr) {\n arr = [];\n queryPredicates.set(qEid, arr);\n }\n arr.push(profile);\n }\n }\n break;\n }\n\n case 'CACHE_LOOKUP': {\n // Attribute to the most recent query\n const qEid =\n (event.queryCausingWork as number | undefined) ??\n firstQueryEventId;\n if (qEid !== undefined) {\n queryCacheHits.set(qEid, (queryCacheHits.get(qEid) ?? 0) + 1);\n }\n break;\n }\n }\n }\n\n // Build QueryProfile entries\n const queries: QueryProfile[] = [];\n for (const [qEid, startInfo] of queryStartEvents) {\n const predicates = queryPredicates.get(qEid) ?? [];\n const endNano = queryEndNanoTimes.get(qEid);\n const totalDurationMs =\n endNano !== undefined\n ? (endNano - startInfo.nanoTime) / 1_000_000\n : predicates.reduce((sum, p) => sum + p.durationMs, 0);\n\n queries.push({\n queryName: startInfo.queryName,\n totalDurationMs,\n predicateCount: predicates.length,\n predicates,\n cacheHits: queryCacheHits.get(qEid) ?? 0,\n });\n }\n\n return {\n codeqlVersion,\n logFormat: 'raw',\n queries,\n totalEvents: events.length,\n };\n}\n\n// ---------------------------------------------------------------------------\n// Summary log parsing\n// ---------------------------------------------------------------------------\n\n/**\n * Parse an `evaluator-log.summary.jsonl` file into {@link ProfileData}.\n *\n * Summary events carry `millis` directly (already in ms). Predicates are\n * grouped by `queryCausingWork` which is a **string** (query name) in the\n * summary format.\n */\nexport function parseSummaryLog(logPath: string): ProfileData {\n const events = parseJsonObjects(logPath);\n\n let codeqlVersion: string | undefined;\n\n // queryCausingWork (string) \u2192 collected predicates\n const queryPredicatesMap = new Map();\n // Track total millis per query\n const queryTotalMs = new Map();\n // Track cache hits per query\n const queryCacheHits = new Map();\n\n for (const event of events) {\n // Header detection\n if (event.summaryLogVersion !== undefined) {\n codeqlVersion = event.codeqlVersion as string | undefined;\n continue;\n }\n\n const strategy = event.evaluationStrategy as string | undefined;\n\n // Skip sentinel-empty entries (no useful timing data)\n if (strategy === 'SENTINEL_EMPTY') {\n continue;\n }\n\n // Skip events without millis (non-predicate summaries)\n if (event.millis === undefined) {\n continue;\n }\n\n const predicateName =\n (event.predicateName as string) || 'unknown';\n const millis = event.millis as number;\n const queryName =\n (event.queryCausingWork as string) || 'unknown';\n\n const deps = event.dependencies as Record | undefined;\n const pipelineRuns = event.pipelineRuns as number | undefined;\n\n const profile: PredicateProfile = {\n predicateName,\n position: event.position as string | undefined,\n durationMs: millis,\n resultSize: event.resultSize as number | undefined,\n pipelineCount: pipelineRuns,\n evaluationStrategy: strategy,\n dependencies: deps ? Object.keys(deps) : [],\n };\n\n // Check if this is a cached entry\n if (event.isCached === true || strategy === 'CACHEHIT') {\n queryCacheHits.set(\n queryName,\n (queryCacheHits.get(queryName) ?? 0) + 1\n );\n }\n\n let arr = queryPredicatesMap.get(queryName);\n if (!arr) {\n arr = [];\n queryPredicatesMap.set(queryName, arr);\n }\n arr.push(profile);\n\n queryTotalMs.set(\n queryName,\n (queryTotalMs.get(queryName) ?? 0) + millis\n );\n }\n\n // Build QueryProfile entries\n const queries: QueryProfile[] = [];\n for (const [queryName, predicates] of queryPredicatesMap) {\n queries.push({\n queryName,\n totalDurationMs: queryTotalMs.get(queryName) ?? 0,\n predicateCount: predicates.length,\n predicates,\n cacheHits: queryCacheHits.get(queryName) ?? 0,\n });\n }\n\n return {\n codeqlVersion,\n logFormat: 'summary',\n queries,\n totalEvents: events.length,\n };\n}\n\n// ---------------------------------------------------------------------------\n// Auto-detect entry point\n// ---------------------------------------------------------------------------\n\n/**\n * Auto-detect the log format and parse accordingly.\n *\n * @param logPath - Absolute path to `evaluator-log.jsonl` or\n * `evaluator-log.summary.jsonl`.\n * @returns Parsed profile data.\n */\nexport function parseEvaluatorLog(logPath: string): ProfileData {\n const events = parseJsonObjects(logPath);\n\n if (events.length === 0) {\n return {\n logFormat: 'raw',\n queries: [],\n totalEvents: 0,\n };\n }\n\n const format = detectLogFormat(events[0]);\n\n if (format === 'raw') {\n return parseRawEvaluatorLog(logPath);\n }\n return parseSummaryLog(logPath);\n}\n", "/**\n * CodeQL query profiling tool\n */\n\nimport { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport { z } from 'zod';\nimport { executeCodeQLCommand } from '../../lib/cli-executor';\nimport { logger } from '../../utils/logger';\nimport { writeFileSync, readFileSync, existsSync } from 'fs';\nimport { join, dirname, basename } from 'path';\nimport { mkdirSync } from 'fs';\n\ninterface EvaluatorLogEvent {\n time: string;\n type: string;\n eventId: number;\n nanoTime: number;\n [key: string]: unknown;\n}\n\ninterface PipelineNode {\n eventId: number;\n name: string;\n position?: string;\n type?: string;\n startTime: number;\n endTime: number;\n duration: number;\n resultSize?: number;\n tupleCount?: number;\n dependencies: string[];\n dependencyEventIds: number[];\n}\n\ninterface ProfileData {\n queryName: string;\n totalDuration: number;\n totalEvents: number;\n pipelines: PipelineNode[];\n}\n\n/**\n * Parse evaluator log and create profile data\n */\nfunction parseEvaluatorLog(logPath: string): ProfileData {\n const logContent = readFileSync(logPath, 'utf-8');\n \n // Split by empty lines to get each JSON object (handles both JSONL and pretty-printed JSON)\n const jsonObjects = logContent.split('\\n\\n').filter((s) => s.trim());\n const events: EvaluatorLogEvent[] = jsonObjects\n .map((obj) => {\n try {\n return JSON.parse(obj);\n } catch (_error) {\n logger.warn(`Failed to parse evaluator log object: ${obj.substring(0, 100)}...`);\n return null;\n }\n })\n .filter((event): event is EvaluatorLogEvent => event !== null);\n\n // Map to track pipeline nodes by their start event ID\n const pipelineMap = new Map>();\n // Map to track dependency event IDs by predicate name\n const predicateNameToEventId = new Map();\n \n let queryName = '';\n let queryStartTime = 0;\n let queryEndTime = 0;\n\n for (const event of events) {\n switch (event.type) {\n case 'QUERY_STARTED':\n queryName = (event.queryName as string) || '';\n queryStartTime = event.nanoTime;\n break;\n\n case 'QUERY_COMPLETED':\n queryEndTime = event.nanoTime;\n break;\n\n case 'PREDICATE_STARTED': {\n const predicateName = event.predicateName as string;\n const position = event.position as string | undefined;\n const predicateType = event.predicateType as string | undefined;\n const dependencies = event.dependencies as Record | undefined;\n \n // Track this predicate's event ID by name for dependency resolution\n predicateNameToEventId.set(predicateName, event.eventId);\n \n // Get dependency event IDs\n const dependencyEventIds: number[] = [];\n const dependencyNames: string[] = [];\n if (dependencies) {\n for (const depName of Object.keys(dependencies)) {\n dependencyNames.push(depName);\n const depEventId = predicateNameToEventId.get(depName);\n if (depEventId !== undefined) {\n dependencyEventIds.push(depEventId);\n }\n }\n }\n\n pipelineMap.set(event.eventId, {\n eventId: event.eventId,\n name: predicateName,\n position,\n type: predicateType,\n startTime: event.nanoTime,\n dependencies: dependencyNames,\n dependencyEventIds,\n });\n break;\n }\n\n case 'PREDICATE_COMPLETED': {\n const startEventId = event.startEvent as number;\n const pipelineInfo = pipelineMap.get(startEventId);\n if (pipelineInfo) {\n const startEvent = events.find((e) => e.eventId === startEventId);\n if (startEvent) {\n const duration = (event.nanoTime - startEvent.nanoTime) / 1_000_000; // Convert to ms\n pipelineInfo.endTime = event.nanoTime;\n pipelineInfo.duration = duration;\n pipelineInfo.resultSize = event.resultSize as number | undefined;\n pipelineInfo.tupleCount = event.tupleCount as number | undefined;\n }\n }\n break;\n }\n }\n }\n\n // Convert to array and maintain original evaluation order (by eventId)\n const pipelines: PipelineNode[] = Array.from(pipelineMap.values())\n .filter((p): p is PipelineNode => p.duration !== undefined)\n .sort((a, b) => a.eventId - b.eventId);\n\n const totalDuration = queryEndTime > 0 ? (queryEndTime - queryStartTime) / 1_000_000 : 0;\n\n return {\n queryName,\n totalDuration,\n totalEvents: events.length,\n pipelines,\n };\n}\n\n/**\n * Format profile data as JSON\n */\nfunction formatAsJson(profile: ProfileData): string {\n return JSON.stringify(profile, null, 2);\n}\n\n/**\n * Format profile data as Mermaid diagram\n * Creates a graph showing the query evaluation pipelines in order of execution\n * with dependencies as edges, annotated with duration and result sizes\n */\nfunction formatAsMermaid(profile: ProfileData): string {\n const lines: string[] = [];\n\n lines.push('```mermaid');\n lines.push('graph TD');\n lines.push('');\n \n // Add query root node\n lines.push(` QUERY[\"${basename(profile.queryName)}
Total: ${profile.totalDuration.toFixed(2)}ms\"]`);\n lines.push('');\n \n // Create nodes for each pipeline in evaluation order (already sorted by eventId)\n profile.pipelines.forEach((pipeline) => {\n const nodeId = `P${pipeline.eventId}`;\n const duration = pipeline.duration.toFixed(2);\n const resultSize = pipeline.resultSize !== undefined ? pipeline.resultSize : '?';\n // Sanitize predicate name for Mermaid\n const name = pipeline.name.replace(/[<>]/g, '').substring(0, 40);\n lines.push(` ${nodeId}[\"${name}
${duration}ms | ${resultSize} results\"]`);\n });\n \n lines.push('');\n \n // Add edges from QUERY to root pipelines (those with no dependencies)\n const rootPipelines = profile.pipelines.filter((p) => p.dependencies.length === 0);\n \n rootPipelines.forEach((pipeline) => {\n lines.push(` QUERY --> P${pipeline.eventId}`);\n });\n \n lines.push('');\n \n // Add edges between pipelines based on dependencies (using eventIds to preserve links)\n profile.pipelines.forEach((pipeline) => {\n pipeline.dependencyEventIds.forEach((depEventId) => {\n const duration = pipeline.duration.toFixed(2);\n lines.push(` P${depEventId} -->|\"${duration}ms\"| P${pipeline.eventId}`);\n });\n });\n \n lines.push('');\n lines.push(' classDef default fill:#e1f5ff,stroke:#333,stroke-width:2px');\n lines.push(' classDef query fill:#ffe1e1,stroke:#333,stroke-width:3px');\n lines.push(' class QUERY query');\n lines.push('```');\n\n return lines.join('\\n');\n}\n\n/**\n * Register the profile_codeql_query tool\n */\nexport function registerProfileCodeQLQueryTool(server: McpServer): void {\n server.tool(\n 'profile_codeql_query',\n 'Profile the performance of a CodeQL query run against a specific database by analyzing the evaluator log JSON file',\n {\n query: z.string().describe('Path to the .ql query file'),\n database: z.string().describe('Path to the CodeQL database directory'),\n evaluatorLog: z\n .string()\n .optional()\n .describe(\n 'Path to an existing structured JSON log (e.g., evaluator-log.jsonl) file. If not provided, the tool will run the query to generate one.'\n ),\n outputDir: z\n .string()\n .optional()\n .describe('Directory to write profiling data files (defaults to same directory as evaluator log)'),\n },\n async (params) => {\n try {\n const { query, database, evaluatorLog, outputDir } = params;\n let logPath = evaluatorLog;\n let bqrsPath: string | undefined;\n let sarifPath: string | undefined;\n\n // If evaluator log not provided, run the query to generate one\n if (!logPath) {\n logger.info('No evaluator log provided, running query to generate one');\n\n // Determine output directory\n const defaultOutputDir = outputDir || join(dirname(query as string), 'profile-output');\n mkdirSync(defaultOutputDir, { recursive: true });\n\n logPath = join(defaultOutputDir, 'evaluator-log.jsonl');\n bqrsPath = join(defaultOutputDir, 'query-results.bqrs');\n sarifPath = join(defaultOutputDir, 'query-results.sarif');\n\n // Run query with evaluator logging and tuple counting\n const queryResult = await executeCodeQLCommand(\n 'query run',\n {\n database: database as string,\n output: bqrsPath,\n 'evaluator-log': logPath,\n 'tuple-counting': true,\n 'evaluator-log-level': 5,\n },\n [query as string]\n );\n\n if (!queryResult.success) {\n return {\n content: [\n {\n type: 'text' as const,\n text: `Failed to run query: ${queryResult.stderr || queryResult.error}`,\n },\n ],\n isError: true,\n };\n }\n\n // Generate SARIF interpretation\n if (existsSync(bqrsPath)) {\n try {\n const sarifResult = await executeCodeQLCommand(\n 'bqrs interpret',\n { format: 'sarif-latest', output: sarifPath },\n [bqrsPath]\n );\n\n if (sarifResult.success) {\n logger.info(`Generated SARIF interpretation at ${sarifPath}`);\n }\n } catch (error) {\n logger.warn(`Failed to generate SARIF interpretation: ${error}`);\n }\n }\n }\n\n // Verify evaluator log exists\n if (!existsSync(logPath)) {\n return {\n content: [\n {\n type: 'text' as const,\n text: `Evaluator log not found at: ${logPath}`,\n },\n ],\n isError: true,\n };\n }\n\n // Parse the evaluator log\n logger.info(`Parsing evaluator log from: ${logPath}`);\n const profile = parseEvaluatorLog(logPath);\n\n // Determine output directory for profile\n const profileOutputDir = outputDir || dirname(logPath);\n mkdirSync(profileOutputDir, { recursive: true });\n\n // Write profile JSON file\n const jsonPath = join(profileOutputDir, 'query-evaluation-profile.json');\n const jsonContent = formatAsJson(profile);\n writeFileSync(jsonPath, jsonContent);\n logger.info(`Profile JSON written to: ${jsonPath}`);\n\n // Write profile Mermaid diagram file\n const mdPath = join(profileOutputDir, 'query-evaluation-profile.md');\n const mdContent = formatAsMermaid(profile);\n writeFileSync(mdPath, mdContent);\n logger.info(`Profile Mermaid diagram written to: ${mdPath}`);\n\n // Build response message\n const outputFiles: string[] = [\n `Profile JSON: ${jsonPath}`,\n `Profile Mermaid: ${mdPath}`,\n `Evaluator Log: ${logPath}`,\n ];\n\n if (bqrsPath) {\n outputFiles.push(`Query Results (BQRS): ${bqrsPath}`);\n }\n\n if (sarifPath && existsSync(sarifPath)) {\n outputFiles.push(`Query Results (SARIF): ${sarifPath}`);\n }\n\n const responseText = [\n 'Query profiling completed successfully!',\n '',\n 'Output Files:',\n ...outputFiles.map((f) => ` - ${f}`),\n '',\n 'Profile Summary:',\n ` - Query: ${basename(profile.queryName)}`,\n ` - Total Duration: ${profile.totalDuration.toFixed(2)} ms`,\n ` - Total Pipelines: ${profile.pipelines.length}`,\n ` - Total Events: ${profile.totalEvents}`,\n '',\n 'First 5 Pipeline Nodes (in evaluation order):',\n ...profile.pipelines.slice(0, 5).map((p, idx) => {\n return ` ${idx + 1}. ${p.name} (${p.duration.toFixed(2)} ms, ${p.resultSize || '?'} results)`;\n }),\n ].join('\\n');\n\n return {\n content: [\n {\n type: 'text' as const,\n text: responseText,\n },\n ],\n };\n } catch (error) {\n logger.error('Error profiling CodeQL query:', error);\n\n return {\n content: [\n {\n type: 'text' as const,\n text: `Failed to profile query: ${error instanceof Error ? error.message : String(error)}`,\n },\n ],\n isError: true,\n };\n }\n }\n );\n}\n", "/**\n * CodeQL query compile tool\n */\n\nimport { z } from 'zod';\nimport { CLIToolDefinition } from '../../lib/cli-tool-registry';\n\nexport const codeqlQueryCompileTool: CLIToolDefinition = {\n name: 'codeql_query_compile',\n description: 'Compile and validate CodeQL queries',\n command: 'codeql',\n subcommand: 'query compile',\n inputSchema: {\n query: z.string().describe('Path to the CodeQL query file (.ql)'),\n database: z.string().optional().describe('Path to the CodeQL database'),\n library: z.string().optional().describe('Path to query library'),\n output: z.string().optional().describe('Output file path'),\n warnings: z.enum(['hide', 'show', 'error']).optional()\n .describe('How to handle compilation warnings'),\n verbose: z.boolean().optional().describe('Enable verbose output'),\n additionalArgs: z.array(z.string()).optional().describe('Additional command-line arguments')\n },\n examples: [\n 'codeql query compile --database=/path/to/db MyQuery.ql',\n 'codeql query compile --library=/path/to/lib --output=compiled.qlo MyQuery.ql'\n ]\n};", "/**\n * CodeQL query format tool\n */\n\nimport { z } from 'zod';\nimport { CLIToolDefinition, createCodeQLSchemas, defaultCLIResultProcessor, CLIExecutionResult } from '../../lib/cli-tool-registry';\n\n/**\n * Custom result processor for codeql query format tool\n * Exit code 1 with --check-only means \"file would change\" - this is success for format checking\n */\nfunction formatResultProcessor(result: CLIExecutionResult, params: Record): string {\n const isCheckOnly = params['check-only'];\n const hasFormatChanges = result.exitCode === 1;\n \n if (isCheckOnly && hasFormatChanges) {\n // Mark as success for the CLI tool registry since detecting format changes is the intended behavior\n result.success = true;\n return result.stdout || result.stderr || 'File would change by autoformatting.';\n }\n \n return defaultCLIResultProcessor(result, params);\n}\n\nexport const codeqlQueryFormatTool: CLIToolDefinition = {\n name: 'codeql_query_format',\n description: 'Automatically format CodeQL source code files',\n command: 'codeql',\n subcommand: 'query format',\n inputSchema: {\n files: z.array(z.string()).describe('One or more .ql or .qll source files to format'),\n output: z.string().optional().describe('Write formatted code to this file instead of stdout'),\n 'in-place': z.boolean().optional().describe('Overwrite each input file with formatted version'),\n 'check-only': z.boolean().optional().describe('Check formatting without writing output'),\n backup: z.string().optional().describe('Backup extension when overwriting existing files'),\n 'no-syntax-errors': z.boolean().optional().describe('Ignore syntax errors and pretend file is formatted'),\n verbose: createCodeQLSchemas.verbose(),\n additionalArgs: createCodeQLSchemas.additionalArgs()\n },\n examples: [\n 'codeql query format -i -- ExampleQuery.ql',\n 'codeql query format --in-place -- queries/*.ql',\n 'codeql query format --check-only -- queries/*.ql'\n ],\n resultProcessor: formatResultProcessor\n};", "/**\n * CodeQL query run tool\n */\n\nimport { z } from 'zod';\nimport { CLIToolDefinition, createCodeQLSchemas } from '../../lib/cli-tool-registry';\n\nexport const codeqlQueryRunTool: CLIToolDefinition = {\n name: 'codeql_query_run',\n description:\n 'Execute a CodeQL query against a database. Use either \"query\" parameter for direct file path OR \"queryName\" + \"queryLanguage\" for pre-defined tool queries. ' +\n 'Produces evaluator logs and BQRS results in a log directory. ' +\n 'Use list_codeql_databases to discover databases, list_query_run_results to find previous results, and codeql_bqrs_decode to inspect BQRS output.',\n command: 'codeql',\n subcommand: 'query run',\n inputSchema: {\n query: z.string().optional().describe('Path to the CodeQL query file (.ql) - cannot be used with queryName'),\n queryName: z.string().optional().describe('Name of pre-defined query to run (e.g., \"PrintAST\", \"CallGraphFrom\", \"CallGraphTo\") - requires queryLanguage'),\n queryLanguage: z.string().optional().describe('Programming language for tools queries (e.g., \"javascript\", \"java\", \"python\") - required when using queryName'),\n queryPack: z.string().optional().describe('Query pack path (defaults to server/ql//tools/src/ for tool queries)'),\n sourceFiles: z.string().optional().describe('Comma-separated list of source file paths for PrintAST queries (e.g., \"src/main.js,src/utils.js\" or just \"main.js\")'),\n sourceFunction: z.string().optional().describe('Comma-separated list of source function names for CallGraphFrom queries (e.g., \"main,processData\")'),\n targetFunction: z.string().optional().describe('Comma-separated list of target function names for CallGraphTo queries (e.g., \"helper,validateInput\")'),\n database: createCodeQLSchemas.database(),\n output: createCodeQLSchemas.output(),\n external: z.array(z.string()).optional()\n .describe('External predicate data: predicate=file.csv'),\n timeout: createCodeQLSchemas.timeout(),\n logDir: z.string().optional()\n .describe('Custom directory for query execution logs (overrides CODEQL_QUERY_LOG_DIR environment variable). If not provided, uses CODEQL_QUERY_LOG_DIR or defaults to .tmp/query-logs/'),\n 'evaluator-log': z.string().optional().describe('Path to save evaluator log (deprecated: use logDir instead)'),\n 'evaluator-log-minify': z.boolean().optional()\n .describe('Minimize evaluator log for smaller size'),\n 'evaluator-log-level': z.number().min(1).max(5).optional()\n .describe('Evaluator log verbosity level (1-5, default 5)'),\n 'tuple-counting': z.boolean().optional()\n .describe('Display tuple counts for each evaluation step in evaluator logs'),\n format: z.enum(['sarif-latest', 'sarifv2.1.0', 'csv', 'graphtext', 'dgml', 'dot']).optional()\n .describe('Output format for query results via codeql bqrs interpret. Defaults to sarif-latest for @kind problem/path-problem queries, graphtext for @kind graph queries. Graph formats (graphtext, dgml, dot) only work with @kind graph queries.'),\n interpretedOutput: z.string().optional()\n .describe('Output file for interpreted results (e.g., results.sarif, results.txt). If not provided, defaults based on format: .sarif for SARIF, .txt for graphtext/csv, .dgml for dgml, .dot for dot'),\n evaluationFunction: z.string().optional()\n .describe('[DEPRECATED - use format parameter instead] Built-in function for query results evaluation (e.g., \"mermaid-graph\", \"json-decode\", \"csv-decode\") or path to custom evaluation script'),\n evaluationOutput: z.string().optional()\n .describe('[DEPRECATED - use interpretedOutput parameter instead] Output file for evaluation results'),\n verbose: createCodeQLSchemas.verbose(),\n additionalArgs: createCodeQLSchemas.additionalArgs()\n },\n examples: [\n 'codeql query run --database=mydb --output=results.bqrs MyQuery.ql',\n 'codeql query run --database=mydb --query-name=PrintAST --query-language=javascript --source-files=src/index.js --output=results.bqrs --format=graphtext --interpreted-output=results.txt',\n 'codeql query run --database=mydb --external=data=input.csv --output=results.bqrs MyQuery.ql --format=sarif-latest --interpreted-output=results.sarif',\n 'codeql query run --database=mydb --evaluator-log=eval.log --tuple-counting --evaluator-log-level=5 --output=results.bqrs MyQuery.ql',\n 'codeql query run --database=mydb --query-name=PrintAST --query-language=javascript --source-files=\"main.js,utils.js\" --format=graphtext',\n 'codeql query run --database=mydb --log-dir=/custom/log/path --tuple-counting --output=results.bqrs MyQuery.ql'\n ]\n};", "/**\n * CodeQL quick evaluate tool\n * \n * Inspired by JordyZomer/codeql-mcp repository:\n * - https://github.com/JordyZomer/codeql-mcp/blob/main/server.py\n * - https://github.com/JordyZomer/codeql-mcp/blob/main/codeqlclient.py\n */\n\nimport { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport { z } from 'zod';\nimport { join, resolve } from 'path';\nimport { findClassPosition } from './find-class-position';\nimport { findPredicatePosition } from './find-predicate-position';\nimport { logger } from '../../utils/logger';\nimport { getProjectTmpDir } from '../../utils/temp-dir';\n\nexport interface QuickEvaluateParams {\n file: string;\n db: string;\n symbol: string;\n output_path?: string;\n}\n\n/**\n * Quick evaluate either a class or a predicate in a CodeQL query.\n * This allows debugging a select portion of QL code without running the whole query.\n */\nexport async function quickEvaluate({\n file,\n db: _db,\n symbol,\n output_path\n}: QuickEvaluateParams): Promise {\n try {\n // Try to find as a class first, then as a predicate\n try {\n await findClassPosition(file, symbol);\n } catch {\n try {\n await findPredicatePosition(file, symbol);\n } catch {\n throw new Error(`Symbol '${symbol}' not found as class or predicate in file: ${file}`);\n }\n }\n \n const resolvedOutput = resolve(output_path || join(getProjectTmpDir('quickeval'), 'quickeval.bqrs'));\n \n // For now, return the resolved output path\n // In a full implementation, this would use the CodeQL CLI or query server\n // to perform the actual quick evaluation with the position parameters\n return resolvedOutput;\n } catch (error) {\n throw new Error(`CodeQL evaluation failed: ${error instanceof Error ? error.message : 'Unknown error'}`);\n }\n}\n\n/**\n * Register the quick evaluate tool with the MCP server\n */\nexport function registerQuickEvaluateTool(server: McpServer): void {\n server.tool(\n 'quick_evaluate',\n 'Quick evaluate either a class or a predicate in a CodeQL query for debugging',\n {\n file: z.string().describe('Path to the .ql file containing the symbol'),\n db: z.string().describe('Path to the CodeQL database'),\n symbol: z.string().describe('Name of the class or predicate to evaluate'),\n output_path: z.string().optional().describe('Output path for results (defaults to project-local .tmp/quickeval/)'),\n },\n async ({ file, db, symbol, output_path }) => {\n try {\n const result = await quickEvaluate({ file, db, symbol, output_path });\n return {\n content: [{ type: 'text', text: result }],\n };\n } catch (error) {\n logger.error('Error in quick evaluate:', error);\n return {\n content: [\n {\n type: 'text',\n text: `Error: ${error instanceof Error ? error.message : 'Unknown error'}`,\n },\n ],\n isError: true,\n };\n }\n }\n );\n}", "/**\n * CodeQL register database tool\n * \n * Inspired by JordyZomer/codeql-mcp repository:\n * - https://github.com/JordyZomer/codeql-mcp/blob/main/server.py\n * - https://github.com/JordyZomer/codeql-mcp/blob/main/codeqlclient.py\n */\n\nimport { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport { z } from 'zod';\nimport { access, constants } from 'fs/promises';\nimport { resolve } from 'path';\nimport { logger } from '../../utils/logger';\n\nexport interface DatabaseRegistration {\n uri: string;\n content: {\n sourceArchiveZip: string;\n dbDir: string;\n };\n}\n\n/**\n * Register a CodeQL database given a local path to the database directory.\n * Validates that the database exists and has required structure.\n * Supports both full databases (with src.zip) and test databases (with src/ folder).\n */\nexport async function registerDatabase(dbPath: string): Promise {\n try {\n const resolvedPath = resolve(dbPath);\n \n // Check if database directory exists\n await access(resolvedPath, constants.F_OK);\n \n // Check for codeql-database.yml (required for all CodeQL databases)\n const dbYmlPath = resolve(resolvedPath, 'codeql-database.yml');\n await access(dbYmlPath, constants.F_OK);\n \n // Check if src.zip exists (for full databases) OR src/ directory exists (for test databases)\n const srcZipPath = resolve(resolvedPath, 'src.zip');\n const srcDirPath = resolve(resolvedPath, 'src');\n \n let hasSrcZip = false;\n let hasSrcDir = false;\n \n try {\n await access(srcZipPath, constants.F_OK);\n hasSrcZip = true;\n } catch {\n // src.zip not found, check for src/ directory\n }\n \n if (!hasSrcZip) {\n try {\n await access(srcDirPath, constants.F_OK);\n hasSrcDir = true;\n } catch {\n // src directory not found either\n }\n }\n \n if (!hasSrcZip && !hasSrcDir) {\n throw new Error(`Missing required source archive (src.zip) or source directory (src/) in: ${dbPath}`);\n }\n \n // For now, we just validate and return success message\n // In a full implementation, this would register with a query server\n const sourceType = hasSrcZip ? 'src.zip' : 'src/';\n return `Database registered: ${dbPath} (source: ${sourceType})`;\n } catch (error) {\n if (error instanceof Error) {\n const errorCode = (error as { code?: string }).code;\n if (errorCode === 'ENOENT') {\n if (error.message.includes('codeql-database.yml')) {\n throw new Error(`Missing required codeql-database.yml in: ${dbPath}`);\n }\n throw new Error(`Database path does not exist: ${dbPath}`);\n }\n if (errorCode === 'EACCES') {\n throw new Error(`Database path does not exist: ${dbPath}`);\n }\n }\n throw new Error(`Failed to register database: ${error instanceof Error ? error.message : 'Unknown error'}`);\n }\n}\n\n/**\n * Register the register database tool with the MCP server\n */\nexport function registerRegisterDatabaseTool(server: McpServer): void {\n server.tool(\n 'register_database',\n 'Register a CodeQL database given a local path to the database directory',\n {\n db_path: z.string().describe('Path to the CodeQL database directory'),\n },\n async ({ db_path }) => {\n try {\n const result = await registerDatabase(db_path);\n return {\n content: [{ type: 'text', text: result }],\n };\n } catch (error) {\n logger.error('Error registering database:', error);\n return {\n content: [\n {\n type: 'text',\n text: `Error: ${error instanceof Error ? error.message : 'Unknown error'}`,\n },\n ],\n isError: true,\n };\n }\n }\n );\n}", "/**\n * CodeQL resolve database tool\n */\n\nimport { z } from 'zod';\nimport { CLIToolDefinition, createCodeQLSchemas, defaultCLIResultProcessor } from '../../lib/cli-tool-registry';\n\nexport const codeqlResolveDatabaseTool: CLIToolDefinition = {\n name: 'codeql_resolve_database',\n description: 'Resolve database path and validate database structure',\n command: 'codeql',\n subcommand: 'resolve database',\n inputSchema: {\n database: z.string().describe('Database path to resolve'),\n format: z.enum(['text', 'json', 'betterjson']).optional()\n .describe('Output format for database information'),\n verbose: createCodeQLSchemas.verbose(),\n additionalArgs: createCodeQLSchemas.additionalArgs()\n },\n examples: [\n 'codeql resolve database -- /path/to/database',\n 'codeql resolve database --format=json -- my-database',\n 'codeql resolve database --format=betterjson -- database-dir'\n ],\n resultProcessor: defaultCLIResultProcessor\n};", "/**\n * CodeQL resolve languages tool\n */\n\nimport { z } from 'zod';\nimport { CLIToolDefinition, defaultCLIResultProcessor } from '../../lib/cli-tool-registry';\n\nexport const codeqlResolveLanguagesTool: CLIToolDefinition = {\n name: 'codeql_resolve_languages',\n description: 'List installed CodeQL extractor packs',\n command: 'codeql',\n subcommand: 'resolve languages',\n inputSchema: {\n format: z.enum(['text', 'json', 'betterjson']).optional()\n .describe('Output format for language information'),\n verbose: z.boolean().optional().describe('Enable verbose output'),\n additionalArgs: z.array(z.string()).optional().describe('Additional command-line arguments')\n },\n examples: [\n 'codeql resolve languages --format=text',\n 'codeql resolve languages --format=json',\n 'codeql resolve languages --format=betterjson'\n ],\n resultProcessor: defaultCLIResultProcessor\n};", "/**\n * CodeQL resolve library-path tool\n */\n\nimport { z } from 'zod';\nimport { CLIToolDefinition, defaultCLIResultProcessor } from '../../lib/cli-tool-registry';\n\nexport const codeqlResolveLibraryPathTool: CLIToolDefinition = {\n name: 'codeql_resolve_library-path',\n description: 'Resolve library path for CodeQL queries and libraries',\n command: 'codeql',\n subcommand: 'resolve library-path',\n inputSchema: {\n language: z.string().optional().describe('Programming language to resolve library path for'),\n format: z.enum(['text', 'json', 'betterjson']).optional()\n .describe('Output format for library path information'),\n verbose: z.boolean().optional().describe('Enable verbose output'),\n additionalArgs: z.array(z.string()).optional().describe('Additional command-line arguments')\n },\n examples: [\n 'codeql resolve library-path --language=java',\n 'codeql resolve library-path --format=json --language=python',\n 'codeql resolve library-path --format=betterjson'\n ],\n resultProcessor: defaultCLIResultProcessor\n};", "/**\n * CodeQL resolve metadata tool\n */\n\nimport { z } from 'zod';\nimport { CLIToolDefinition, defaultCLIResultProcessor } from '../../lib/cli-tool-registry';\n\nexport const codeqlResolveMetadataTool: CLIToolDefinition = {\n name: 'codeql_resolve_metadata',\n description: 'Resolve and return the key-value metadata pairs from a CodeQL query source file.',\n command: 'codeql',\n subcommand: 'resolve metadata',\n inputSchema: {\n query: z.string().describe('Query file to resolve metadata for'),\n format: z.enum(['json']).optional()\n .describe('Output format for metadata information (always JSON, optional for future compatibility)'),\n verbose: z.boolean().optional().describe('Enable verbose output'),\n additionalArgs: z.array(z.string()).optional().describe('Additional command-line arguments')\n },\n examples: [\n 'codeql resolve metadata -- relative-path/2/MyQuery.ql',\n 'codeql resolve metadata --format=json -- /absolute-plus/relative-path/2/MyQuery.ql'\n ],\n resultProcessor: defaultCLIResultProcessor\n};", "/**\n * CodeQL resolve qlref tool\n */\n\nimport { z } from 'zod';\nimport { CLIToolDefinition, createCodeQLSchemas, defaultCLIResultProcessor } from '../../lib/cli-tool-registry';\n\nexport const codeqlResolveQlrefTool: CLIToolDefinition = {\n name: 'codeql_resolve_qlref',\n description: 'Resolve qlref files to their corresponding query files',\n command: 'codeql',\n subcommand: 'resolve qlref',\n inputSchema: {\n qlref: z.string().describe('Path to the .qlref file to resolve'),\n format: z.enum(['text', 'json', 'betterjson']).optional()\n .describe('Output format for qlref resolution'),\n verbose: createCodeQLSchemas.verbose(),\n additionalArgs: createCodeQLSchemas.additionalArgs()\n },\n examples: [\n 'codeql resolve qlref -- test/MyQuery.qlref',\n 'codeql resolve qlref --format=json -- test/MyQuery.qlref',\n 'codeql resolve qlref --format=betterjson -- test/MyQuery.qlref'\n ],\n resultProcessor: defaultCLIResultProcessor\n};", "/**\n * CodeQL resolve queries tool\n */\n\nimport { z } from 'zod';\nimport { CLIToolDefinition, createCodeQLSchemas, CLIExecutionResult } from '../../lib/cli-tool-registry';\n\n/**\n * Result processor that only returns stdout for JSON formats\n * This prevents warnings/info from stderr from corrupting JSON output\n */\nconst jsonOnlyResultProcessor = (\n result: CLIExecutionResult,\n params: Record\n): string => {\n if (!result.success) {\n return `Command failed (exit code ${result.exitCode || 'unknown'}):\\n${result.error || result.stderr}`;\n }\n\n // For JSON formats (including bylanguage), only return stdout to avoid mixing warnings with JSON\n if (params.format === 'json' || params.format === 'betterjson' || params.format === 'bylanguage') {\n return result.stdout || '[]';\n }\n\n // For text format, include warnings\n let output = '';\n\n if (result.stdout) {\n output += result.stdout;\n }\n\n if (result.stderr) {\n if (output) {\n output += '\\n\\nWarnings/Info:\\n';\n }\n output += result.stderr;\n }\n\n if (!output) {\n output = 'Command executed successfully (no output)';\n }\n\n return output;\n};\n\nexport const codeqlResolveQueriesTool: CLIToolDefinition = {\n name: 'codeql_resolve_queries',\n description: 'List available CodeQL queries found on the local filesystem',\n command: 'codeql',\n subcommand: 'resolve queries',\n inputSchema: {\n directory: z.string().optional().describe('Directory to search for queries'),\n language: z.string().optional().describe('Filter queries by programming language'),\n format: z.enum(['text', 'json', 'betterjson', 'bylanguage']).optional()\n .describe('Output format for query list'),\n 'additional-packs': z.union([z.string(), z.array(z.string())]).optional()\n .describe('Additional pack directories to search for CodeQL packs'),\n verbose: createCodeQLSchemas.verbose(),\n additionalArgs: createCodeQLSchemas.additionalArgs()\n },\n examples: [\n 'codeql resolve queries',\n 'codeql resolve queries --language=java --format=json',\n 'codeql resolve queries --format=betterjson -- /path/to/queries',\n 'codeql resolve queries --additional-packs=/path/to/packs codeql/java-queries'\n ],\n resultProcessor: jsonOnlyResultProcessor\n};", "/**\n * CodeQL resolve tests tool\n */\n\nimport { z } from 'zod';\nimport { CLIToolDefinition, createCodeQLSchemas, defaultCLIResultProcessor } from '../../lib/cli-tool-registry';\n\nexport const codeqlResolveTestsTool: CLIToolDefinition = {\n name: 'codeql_resolve_tests',\n description: 'Resolve the local filesystem paths of unit tests and/or queries under some base directory',\n command: 'codeql',\n subcommand: 'resolve tests',\n inputSchema: {\n tests: z.array(z.string()).optional().describe('One or more tests (.ql, .qlref files, or test directories)'),\n format: z.enum(['text', 'json']).optional()\n .describe('Output format for test list'),\n verbose: createCodeQLSchemas.verbose(),\n additionalArgs: createCodeQLSchemas.additionalArgs()\n },\n examples: [\n 'codeql resolve tests',\n 'codeql resolve tests --format=json -- test-directory',\n 'codeql resolve tests --format=json -- test1.ql test2.ql'\n ],\n resultProcessor: defaultCLIResultProcessor\n};", "/**\n * CodeQL test accept tool\n */\n\nimport { z } from 'zod';\nimport { CLIToolDefinition, createCodeQLSchemas, defaultCLIResultProcessor } from '../../lib/cli-tool-registry';\n\nexport const codeqlTestAcceptTool: CLIToolDefinition = {\n name: 'codeql_test_accept',\n description: 'Accept new test results as the expected baseline',\n command: 'codeql',\n subcommand: 'test accept',\n inputSchema: {\n tests: z.array(z.string()).describe('One or more tests (.ql, .qlref files, or test directories)'),\n verbose: createCodeQLSchemas.verbose(),\n additionalArgs: createCodeQLSchemas.additionalArgs()\n },\n examples: [\n 'codeql test accept -- languages/java/test/MyQuery/MyQuery.qlref',\n 'codeql test accept -- languages/java/test/MyQuery/',\n 'codeql test accept -- languages/java/src/MyQuery/MyQuery.ql'\n ],\n resultProcessor: defaultCLIResultProcessor\n};", "/**\n * CodeQL test extract tool\n */\n\nimport { z } from 'zod';\nimport { CLIToolDefinition, createCodeQLSchemas, defaultCLIResultProcessor } from '../../lib/cli-tool-registry';\n\nexport const codeqlTestExtractTool: CLIToolDefinition = {\n name: 'codeql_test_extract',\n description: 'Extract test databases for CodeQL query tests',\n command: 'codeql',\n subcommand: 'test extract',\n inputSchema: {\n tests: z.array(z.string()).describe('One or more test directories or files'),\n language: z.string().optional().describe('Programming language for extraction'),\n threads: createCodeQLSchemas.threads(),\n ram: createCodeQLSchemas.ram(),\n verbose: createCodeQLSchemas.verbose(),\n additionalArgs: createCodeQLSchemas.additionalArgs()\n },\n examples: [\n 'codeql test extract -- languages/java/test/MyQuery/',\n 'codeql test extract --language=java --threads=4 -- test-directory',\n 'codeql test extract --threads=2 --ram=2048 -- multiple/test/directories'\n ],\n resultProcessor: defaultCLIResultProcessor\n};", "/**\n * CodeQL test run tool\n */\n\nimport { CLIToolDefinition, createCodeQLSchemas } from '../../lib/cli-tool-registry';\nimport { z } from 'zod';\n\nexport const codeqlTestRunTool: CLIToolDefinition = {\n name: 'codeql_test_run',\n description: 'Run CodeQL query tests',\n command: 'codeql',\n subcommand: 'test run',\n inputSchema: {\n tests: z.array(z.string()).describe('One or more tests (.ql, .qlref files, or test directories)'),\n 'show-extractor-output': z.boolean().optional()\n .describe('Show output from extractors during test execution'),\n 'keep-databases': z.boolean().optional()\n .describe('Keep test databases after running tests'),\n 'learn': z.boolean().optional()\n .describe('Accept current output as expected for failing tests'),\n logDir: z.string().optional()\n .describe('Custom directory for test execution logs (overrides CODEQL_QUERY_LOG_DIR environment variable). If not provided, uses CODEQL_QUERY_LOG_DIR or defaults to .tmp/query-logs/'),\n threads: createCodeQLSchemas.threads(),\n ram: createCodeQLSchemas.ram(),\n verbose: createCodeQLSchemas.verbose(),\n additionalArgs: createCodeQLSchemas.additionalArgs()\n },\n examples: [\n 'codeql test run /path/to/tests',\n 'codeql test run --learn /path/to/failing/tests',\n 'codeql test run --threads=4 --keep-databases /path/to/tests',\n 'codeql test run --log-dir=/custom/log/path /path/to/tests'\n ]\n};", "/**\n * CodeQL tools registration for MCP server\n * Includes both high-level helpers and CLI command wrappers\n */\n\nimport { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport { z } from 'zod';\nimport { validateCodeQLSyntax } from '../lib/validation';\nimport { createCodeQLQuery } from '../lib/query-scaffolding';\nimport { registerCLITool } from '../lib/cli-tool-registry';\nimport {\n codeqlBqrsDecodeTool,\n codeqlBqrsInfoTool,\n codeqlBqrsInterpretTool,\n codeqlDatabaseAnalyzeTool,\n codeqlDatabaseCreateTool,\n codeqlGenerateLogSummaryTool,\n codeqlGenerateQueryHelpTool,\n codeqlPackInstallTool,\n codeqlPackLsTool,\n codeqlQueryCompileTool,\n codeqlQueryFormatTool,\n codeqlQueryRunTool,\n codeqlResolveDatabaseTool,\n codeqlResolveLanguagesTool,\n codeqlResolveLibraryPathTool,\n codeqlResolveMetadataTool,\n codeqlResolveQlrefTool,\n codeqlResolveQueriesTool,\n codeqlResolveTestsTool,\n codeqlTestAcceptTool,\n codeqlTestExtractTool,\n codeqlTestRunTool,\n registerFindClassPositionTool,\n registerFindCodeQLQueryFilesTool,\n registerFindPredicatePositionTool,\n registerListDatabasesTool,\n registerListMrvaRunResultsTool,\n registerListQueryRunResultsTool,\n registerProfileCodeQLQueryFromLogsTool,\n registerProfileCodeQLQueryTool,\n registerQuickEvaluateTool,\n registerRegisterDatabaseTool\n} from './codeql';\nimport { logger } from '../utils/logger';\n\n/**\n * Register all CodeQL tools with the MCP server\n */\nexport function registerCodeQLTools(server: McpServer): void {\n // Register high-level helper tools\n \n // Tool: Validate CodeQL Query (heuristic-based)\n server.tool(\n 'validate_codeql_query',\n 'Quick heuristic validation for CodeQL query structure - checks for common patterns like from/where/select clauses and metadata presence. Does NOT compile the query. For authoritative validation with actual compilation, use codeql_lsp_diagnostics instead.',\n {\n query: z.string().describe('The CodeQL query to validate'),\n language: z.string().optional().describe('Target programming language'),\n },\n async ({ query, language }) => {\n try {\n const validation = validateCodeQLSyntax(query, language);\n return {\n content: [{ type: 'text', text: JSON.stringify(validation, null, 2) }],\n };\n } catch (error) {\n logger.error('Error validating CodeQL query:', error);\n return {\n content: [\n {\n type: 'text',\n text: `Error: ${error instanceof Error ? error.message : 'Unknown error'}`,\n },\n ],\n isError: true,\n };\n }\n }\n );\n\n // Tool: Create CodeQL Query\n server.tool(\n 'create_codeql_query',\n 'Create directory structure and files for a new CodeQL query with tests',\n {\n basePath: z.string().describe('Base path where src/ and test/ directories will be created'),\n queryName: z.string().describe('Name of the query (e.g., MySecurityQuery)'),\n language: z.string().describe('Target programming language (e.g., javascript, python, java)'),\n description: z.string().optional().describe('Description of what the query does'),\n queryId: z.string().optional().describe('Custom query ID (defaults to language/example/queryname)'),\n },\n async ({ basePath, queryName, language, description, queryId }) => {\n try {\n const result = createCodeQLQuery({\n basePath,\n queryName,\n language,\n description,\n queryId\n });\n \n const summary = {\n success: true,\n queryPath: result.queryPath,\n testPath: result.testPath,\n qlrefPath: result.qlrefPath,\n testCodePath: result.testCodePath,\n filesCreated: result.filesCreated,\n nextSteps: [\n 'Review and customize the generated query in: ' + result.queryPath,\n 'Add test cases to: ' + result.testCodePath,\n 'Run codeql_pack_install to install dependencies',\n 'Run codeql_test_extract to create test database',\n 'Run codeql_test_run to execute tests'\n ]\n };\n \n return {\n content: [{ type: 'text', text: JSON.stringify(summary, null, 2) }],\n };\n } catch (error) {\n logger.error('Error creating CodeQL query:', error);\n return {\n content: [\n {\n type: 'text',\n text: `Error: ${error instanceof Error ? error.message : 'Unknown error'}`,\n },\n ],\n isError: true,\n };\n }\n }\n );\n\n // Register CLI tools (alphabetically by tool name)\n registerCLITool(server, codeqlBqrsDecodeTool);\n registerCLITool(server, codeqlBqrsInfoTool);\n registerCLITool(server, codeqlBqrsInterpretTool);\n registerCLITool(server, codeqlDatabaseAnalyzeTool);\n registerCLITool(server, codeqlDatabaseCreateTool);\n registerCLITool(server, codeqlGenerateLogSummaryTool);\n registerCLITool(server, codeqlGenerateQueryHelpTool);\n registerCLITool(server, codeqlPackInstallTool);\n registerCLITool(server, codeqlPackLsTool);\n registerCLITool(server, codeqlQueryCompileTool);\n registerCLITool(server, codeqlQueryFormatTool);\n registerCLITool(server, codeqlQueryRunTool);\n registerCLITool(server, codeqlResolveDatabaseTool);\n registerCLITool(server, codeqlResolveLanguagesTool);\n registerCLITool(server, codeqlResolveLibraryPathTool);\n registerCLITool(server, codeqlResolveMetadataTool);\n registerCLITool(server, codeqlResolveQlrefTool);\n registerCLITool(server, codeqlResolveQueriesTool);\n registerCLITool(server, codeqlResolveTestsTool);\n registerCLITool(server, codeqlTestAcceptTool);\n registerCLITool(server, codeqlTestExtractTool);\n registerCLITool(server, codeqlTestRunTool);\n\n // Register new MCP tools (inspired by JordyZomer/codeql-mcp repository)\n registerFindClassPositionTool(server);\n registerFindCodeQLQueryFilesTool(server);\n registerFindPredicatePositionTool(server);\n registerListDatabasesTool(server);\n registerListMrvaRunResultsTool(server);\n registerListQueryRunResultsTool(server);\n registerProfileCodeQLQueryFromLogsTool(server);\n registerProfileCodeQLQueryTool(server);\n registerQuickEvaluateTool(server);\n registerRegisterDatabaseTool(server);\n}\n", "/**\n * CodeQL query validation utilities\n */\n\nimport { resolve, normalize, isAbsolute, relative } from 'path';\n\nexport interface CodeQLValidationResult {\n isValid: boolean;\n errors: string[];\n warnings: string[];\n suggestions: string[];\n}\n\n/**\n * Validates CodeQL query syntax and structure\n */\nexport function validateCodeQLSyntax(query: string, _language?: string): CodeQLValidationResult {\n const validation: CodeQLValidationResult = {\n isValid: true,\n errors: [],\n warnings: [],\n suggestions: [],\n };\n\n if (!query.trim()) {\n validation.isValid = false;\n validation.errors.push('Query cannot be empty');\n return validation;\n }\n\n if (!query.includes('from') && !query.includes('select')) {\n validation.warnings.push('Query should typically include \"from\" and \"select\" clauses');\n }\n\n if (!query.includes('@name') && !query.includes('@description')) {\n validation.suggestions.push('Consider adding @name and @description metadata');\n }\n\n return validation;\n}\n\n/**\n * Validates a file path to prevent path traversal attacks\n * @param filePath - The file path to validate\n * @param workspaceRoot - Optional workspace root directory. If not provided, allows any absolute path but still blocks traversal attempts\n * @returns The validated absolute path\n * @throws Error if the path contains path traversal sequences\n */\nexport function validateFilePath(filePath: string, workspaceRoot?: string): string {\n // Normalize the path to resolve any . or .. segments\n const normalizedPath = normalize(filePath);\n \n // Check for path traversal attempts in the normalized path\n // This blocks paths like \"../../../etc/passwd\" even after normalization\n if (normalizedPath.includes('..')) {\n throw new Error(`Invalid file path: path traversal detected in \"${filePath}\"`);\n }\n \n // Resolve to absolute path\n const absolutePath = isAbsolute(normalizedPath) \n ? normalizedPath \n : resolve(workspaceRoot || process.cwd(), normalizedPath);\n \n // If workspace root is specified, ensure the resolved path is within it\n if (workspaceRoot) {\n const relativePath = relative(workspaceRoot, absolutePath);\n \n // If relative path starts with .. or is absolute, it's outside workspace\n if (relativePath.startsWith('..') || isAbsolute(relativePath)) {\n throw new Error(`Invalid file path: \"${filePath}\" is outside the workspace root`);\n }\n }\n \n return absolutePath;\n}", "/**\n * CodeQL query scaffolding utilities\n * Handles creation of query directory structure and files\n */\n\nimport * as fs from 'fs';\nimport * as path from 'path';\n\nexport interface QueryScaffoldingOptions {\n basePath: string;\n queryName: string;\n language: string;\n description?: string;\n queryId?: string;\n}\n\nexport interface QueryScaffoldingResult {\n queryPath: string;\n testPath: string;\n qlrefPath: string;\n testCodePath: string;\n filesCreated: string[];\n}\n\n/**\n * Get the file extension for test code based on language\n */\nfunction getLanguageExtension(language: string): string {\n const extensions: Record = {\n javascript: 'js',\n typescript: 'ts',\n python: 'py',\n java: 'java',\n csharp: 'cs',\n cpp: 'cpp',\n go: 'go',\n ruby: 'rb',\n actions: 'yml'\n };\n return extensions[language.toLowerCase()] || 'txt';\n}\n\n/**\n * Generate query template content\n */\nfunction generateQueryTemplate(\n queryName: string,\n language: string,\n description?: string,\n queryId?: string\n): string {\n const desc = description || `${queryName} query`;\n const id = queryId || `${language}/example/${queryName.toLowerCase()}`;\n \n return `/**\n * @id ${id}\n * @name ${queryName}\n * @description ${desc}\n * @kind problem\n * @precision medium\n * @problem.severity warning\n */\n\nimport ${language}\n\n// TODO: Implement query logic\nfrom File f\nwhere f.getBaseName() = \"${queryName}.${getLanguageExtension(language)}\"\nselect f, \"TODO: Add query logic\"\n`;\n}\n\n/**\n * Create the directory structure and files for a new CodeQL query\n */\nexport function createCodeQLQuery(options: QueryScaffoldingOptions): QueryScaffoldingResult {\n const { basePath, queryName, language, description, queryId } = options;\n \n // Resolve absolute paths\n const absoluteBasePath = path.resolve(basePath);\n \n // Define paths with intermediate directory\n const srcDir = path.join(absoluteBasePath, 'src', queryName);\n const testDir = path.join(absoluteBasePath, 'test', queryName);\n \n const queryPath = path.join(srcDir, `${queryName}.ql`);\n const qlrefPath = path.join(testDir, `${queryName}.qlref`);\n const testCodePath = path.join(testDir, `${queryName}.${getLanguageExtension(language)}`);\n \n const filesCreated: string[] = [];\n \n try {\n // Create directories (recursive: true is a no-op if they already exist)\n fs.mkdirSync(srcDir, { recursive: true });\n fs.mkdirSync(testDir, { recursive: true });\n \n // Create files atomically using 'wx' flag (exclusive create) to avoid\n // TOCTOU race between existsSync check and writeFileSync (CWE-367).\n // The 'wx' flag fails with EEXIST if the file already exists.\n try {\n const queryContent = generateQueryTemplate(queryName, language, description, queryId);\n fs.writeFileSync(queryPath, queryContent, { encoding: 'utf8', flag: 'wx' });\n filesCreated.push(queryPath);\n } catch (e: unknown) {\n const err = e as { code?: string };\n if (err.code !== 'EEXIST') throw e;\n }\n \n try {\n const qlrefContent = `${queryName}/${queryName}.ql\\n`;\n fs.writeFileSync(qlrefPath, qlrefContent, { encoding: 'utf8', flag: 'wx' });\n filesCreated.push(qlrefPath);\n } catch (e: unknown) {\n const err = e as { code?: string };\n if (err.code !== 'EEXIST') throw e;\n }\n \n try {\n const testCodeContent = `// Test code for ${queryName}\\n// TODO: Add test cases\\n`;\n fs.writeFileSync(testCodePath, testCodeContent, { encoding: 'utf8', flag: 'wx' });\n filesCreated.push(testCodePath);\n } catch (e: unknown) {\n const err = e as { code?: string };\n if (err.code !== 'EEXIST') throw e;\n }\n \n return {\n queryPath,\n testPath: testDir,\n qlrefPath,\n testCodePath,\n filesCreated\n };\n } catch (error) {\n throw new Error(`Failed to create query scaffolding: ${error instanceof Error ? error.message : 'Unknown error'}`);\n }\n}\n", "/**\n * CodeQL learning resources utilities\n */\n\nimport { readFileSync } from 'fs';\nimport { join, dirname } from 'path';\nimport { fileURLToPath } from 'url';\n\nconst __filename = fileURLToPath(import.meta.url);\nconst __dirname = dirname(__filename);\n\n/**\n * Get the getting started guide content\n */\nexport function getGettingStartedGuide(): string {\n try {\n return readFileSync(join(__dirname, '../resources/getting-started.md'), 'utf-8');\n } catch {\n return 'Getting started guide not available';\n }\n}\n\n/**\n * Get the query basics guide content\n */\nexport function getQueryBasicsGuide(): string {\n try {\n return readFileSync(join(__dirname, '../resources/query-basics.md'), 'utf-8');\n } catch {\n return 'Query basics guide not available';\n }\n}\n\n/**\n * Get the security templates content\n */\nexport function getSecurityTemplates(): string {\n try {\n return readFileSync(join(__dirname, '../resources/security-templates.md'), 'utf-8');\n } catch {\n return 'Security templates not available';\n }\n}\n\n/**\n * Get the performance patterns content\n */\nexport function getPerformancePatterns(): string {\n try {\n return readFileSync(join(__dirname, '../resources/performance-patterns.md'), 'utf-8');\n } catch {\n return 'Performance patterns not available';\n }\n}", "/**\n * CodeQL resources registration for MCP server\n */\n\nimport { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport {\n getGettingStartedGuide,\n getQueryBasicsGuide,\n getSecurityTemplates,\n getPerformancePatterns,\n} from '../lib/resources';\n\n/**\n * Register all CodeQL resources with the MCP server\n */\nexport function registerCodeQLResources(server: McpServer): void {\n // Getting Started Guide\n server.resource(\n 'CodeQL Getting Started',\n 'codeql://learning/getting-started',\n {\n description: 'Comprehensive introduction to CodeQL for beginners',\n mimeType: 'text/markdown',\n },\n async () => {\n return {\n contents: [\n {\n uri: 'codeql://learning/getting-started',\n mimeType: 'text/markdown',\n text: getGettingStartedGuide(),\n },\n ],\n };\n }\n );\n\n // Query Basics Guide\n server.resource(\n 'CodeQL Query Basics',\n 'codeql://learning/query-basics',\n {\n description: 'Learn the fundamentals of writing CodeQL queries',\n mimeType: 'text/markdown',\n },\n async () => {\n return {\n contents: [\n {\n uri: 'codeql://learning/query-basics',\n mimeType: 'text/markdown',\n text: getQueryBasicsGuide(),\n },\n ],\n };\n }\n );\n\n // Security Templates\n server.resource(\n 'CodeQL Security Templates',\n 'codeql://templates/security',\n {\n description: 'Ready-to-use security query templates',\n mimeType: 'text/markdown',\n },\n async () => {\n return {\n contents: [\n {\n uri: 'codeql://templates/security',\n mimeType: 'text/markdown',\n text: getSecurityTemplates(),\n },\n ],\n };\n }\n );\n\n // Performance Patterns\n server.resource(\n 'CodeQL Performance Patterns',\n 'codeql://patterns/performance',\n {\n description: 'Best practices for writing efficient CodeQL queries',\n mimeType: 'text/markdown',\n },\n async () => {\n return {\n contents: [\n {\n uri: 'codeql://patterns/performance',\n mimeType: 'text/markdown',\n text: getPerformancePatterns(),\n },\n ],\n };\n }\n );\n}\n", "/**\n * CodeQL LSP Diagnostics tool for MCP server.\n *\n * Provides real-time QL code validation through LSP communication.\n * Renamed from `codeql_language_server_eval` to `codeql_lsp_diagnostics`\n * for consistency with the `codeql_lsp_*` tool naming convention.\n */\n\nimport { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport { z } from 'zod';\nimport { Diagnostic, LanguageServerOptions } from '../../lib/language-server';\nimport { logger } from '../../utils/logger';\nimport { getProjectTmpDir } from '../../utils/temp-dir';\nimport { join } from 'path';\nimport { pathToFileURL } from 'url';\nimport { getInitializedLanguageServer } from './lsp-server-helper';\n\nexport interface LspDiagnosticsParams {\n qlCode: string;\n serverOptions?: LanguageServerOptions;\n workspaceUri?: string;\n}\n\nexport interface LspDiagnosticsResult {\n diagnostics: Diagnostic[];\n formattedOutput: string;\n isValid: boolean;\n summary: {\n errorCount: number;\n hintCount: number;\n infoCount: number;\n warningCount: number;\n };\n}\n\n/**\n * Format diagnostics for human-readable output.\n */\nfunction formatDiagnostics(diagnostics: Diagnostic[]): string {\n if (diagnostics.length === 0) {\n return '\u2705 No issues found in QL code';\n }\n\n const lines: string[] = [];\n lines.push(`Found ${diagnostics.length} issue(s):\\n`);\n\n diagnostics.forEach((diagnostic, index) => {\n const severityIcon = getSeverityIcon(diagnostic.severity);\n const severityName = getSeverityName(diagnostic.severity);\n const location = `Line ${diagnostic.range.start.line + 1}, Column ${diagnostic.range.start.character + 1}`;\n\n lines.push(`${index + 1}. ${severityIcon} ${severityName} at ${location}`);\n lines.push(` ${diagnostic.message}`);\n if (diagnostic.source) {\n lines.push(` Source: ${diagnostic.source}`);\n }\n if (diagnostic.code) {\n lines.push(` Code: ${diagnostic.code}`);\n }\n lines.push('');\n });\n\n return lines.join('\\n');\n}\n\nfunction getSeverityIcon(severity: number): string {\n switch (severity) {\n case 1: return '\u274C'; // Error\n case 2: return '\u26A0\uFE0F'; // Warning\n case 3: return '\u2139\uFE0F'; // Information\n case 4: return '\uD83D\uDCA1'; // Hint\n default: return '\u2753';\n }\n}\n\nfunction getSeverityName(severity: number): string {\n switch (severity) {\n case 1: return 'Error';\n case 2: return 'Warning';\n case 3: return 'Information';\n case 4: return 'Hint';\n default: return 'Unknown';\n }\n}\n\n/**\n * Evaluate QL code using the CodeQL Language Server and return diagnostics.\n */\nexport async function lspDiagnostics({\n qlCode,\n workspaceUri,\n serverOptions = {}\n}: LspDiagnosticsParams): Promise {\n try {\n logger.info('Evaluating QL code via Language Server...');\n\n const languageServer = await getInitializedLanguageServer({\n serverOptions,\n workspaceUri,\n });\n\n // Generate unique URI for this evaluation\n const evalUri = pathToFileURL(join(getProjectTmpDir('lsp-eval'), `eval_${Date.now()}.ql`)).href;\n\n const diagnostics = await languageServer.evaluateQL(qlCode, evalUri);\n\n // Count diagnostics by severity\n const summary = {\n errorCount: diagnostics.filter(d => d.severity === 1).length,\n hintCount: diagnostics.filter(d => d.severity === 4).length,\n infoCount: diagnostics.filter(d => d.severity === 3).length,\n warningCount: diagnostics.filter(d => d.severity === 2).length,\n };\n\n const isValid = summary.errorCount === 0;\n const formattedOutput = formatDiagnostics(diagnostics);\n\n logger.info(`QL evaluation complete. Valid: ${isValid}, Issues: ${diagnostics.length}`);\n\n return {\n diagnostics,\n formattedOutput,\n isValid,\n summary,\n };\n\n } catch (error) {\n logger.error('Error evaluating QL code:', error);\n throw new Error(`QL evaluation failed: ${error instanceof Error ? error.message : 'Unknown error'}`);\n }\n}\n\n/**\n * Shutdown the language server via the server manager.\n */\nexport async function shutdownDiagnosticsServer(): Promise {\n const { getServerManager } = await import('../../lib/server-manager');\n const manager = getServerManager();\n await manager.shutdownServer('language');\n}\n\n/**\n * Register the codeql_lsp_diagnostics tool with the MCP server.\n */\nexport function registerLspDiagnosticsTool(server: McpServer): void {\n server.tool(\n 'codeql_lsp_diagnostics',\n 'Authoritative syntax and semantic validation of CodeQL (QL) code via the CodeQL Language Server. Compiles the query and provides real-time diagnostics with precise error locations. Use this for accurate validation; for quick heuristic checks without compilation, use validate_codeql_query instead. Note: inline ql_code is evaluated as a virtual document and cannot resolve pack imports (e.g. `import javascript`). For validating queries with imports, use codeql_query_compile on the actual file instead.',\n {\n log_level: z.enum(['OFF', 'ERROR', 'WARN', 'INFO', 'DEBUG', 'TRACE', 'ALL']).optional().describe('Language server log level'),\n ql_code: z.string().describe('The CodeQL (QL) code to evaluate for syntax and semantic errors'),\n search_path: z.string().optional().describe('Optional search path for CodeQL libraries'),\n workspace_uri: z.string().optional().describe('Optional workspace URI for context (defaults to ./ql directory)'),\n },\n async ({ ql_code, workspace_uri, search_path, log_level }) => {\n try {\n const serverOptions: LanguageServerOptions = {};\n\n if (search_path) {\n serverOptions.searchPath = search_path;\n }\n if (log_level) {\n serverOptions.loglevel = log_level;\n }\n\n const result = await lspDiagnostics({\n qlCode: ql_code,\n serverOptions,\n workspaceUri: workspace_uri,\n });\n\n // Return structured result\n const responseContent = {\n diagnostics: result.diagnostics.map(d => ({\n code: d.code,\n column: d.range.start.character + 1, // Convert to 1-based column numbers\n line: d.range.start.line + 1, // Convert to 1-based line numbers\n message: d.message,\n severity: getSeverityName(d.severity),\n source: d.source,\n })),\n formattedOutput: result.formattedOutput,\n isValid: result.isValid,\n summary: result.summary,\n };\n\n return {\n content: [\n {\n text: JSON.stringify(responseContent, null, 2),\n type: 'text',\n }\n ],\n };\n\n } catch (error) {\n logger.error('Error in codeql_lsp_diagnostics tool:', error);\n return {\n content: [\n {\n text: `Error: ${error instanceof Error ? error.message : 'Unknown error'}`,\n type: 'text',\n },\n ],\n isError: true,\n };\n }\n }\n );\n\n // NOTE: Cleanup is handled centrally by shutdownServerManager() in\n // codeql-development-mcp-server.ts (setupGracefulShutdown). Registering\n // additional process.on('SIGINT'/'SIGTERM') handlers here would\n // accumulate on repeated calls and is unnecessary.\n}\n", "/**\n * Shared helper for obtaining a running, initialized CodeQL Language Server.\n *\n * Both `lsp-diagnostics.ts` and `lsp-handlers.ts` need to:\n * 1. Build a `LanguageServerConfig` with sensible defaults\n * 2. Obtain a server instance from the `CodeQLServerManager`\n * 3. Resolve a workspace URI (relative \u2192 absolute \u2192 `file://`)\n * 4. Initialize the server with the resolved workspace\n *\n * Centralizing this logic avoids duplication and ensures consistent\n * default behaviour across all LSP tools.\n */\n\nimport { isAbsolute, resolve } from 'path';\nimport { pathToFileURL } from 'url';\n\nimport { CodeQLLanguageServer, LanguageServerOptions } from '../../lib/language-server';\nimport { LanguageServerConfig } from '../../lib/server-config';\nimport { getServerManager } from '../../lib/server-manager';\nimport { logger } from '../../utils/logger';\n\n/**\n * Options accepted by {@link getInitializedLanguageServer}.\n */\nexport interface InitializedServerOptions {\n /** Language-server-level options (loglevel, searchPath, etc.). */\n serverOptions?: LanguageServerOptions;\n /** Workspace URI \u2014 may be a `file://` URI, absolute path, or relative path. */\n workspaceUri?: string;\n}\n\n/**\n * Return a running, initialized `CodeQLLanguageServer`.\n *\n * - Resolves `searchPath` to the bundled `ql` directory when not provided.\n * - Converts relative / bare-directory `workspaceUri` paths to `file://` URIs\n * resolved against `getUserWorkspaceDir()` (respects `CODEQL_MCP_WORKSPACE`).\n * - Falls back to the bundled `ql` directory when no workspace is given.\n * - Delegates lifecycle management to the global `CodeQLServerManager`.\n */\nexport async function getInitializedLanguageServer(\n opts: InitializedServerOptions = {},\n): Promise {\n const { packageRootDir: pkgRoot, getUserWorkspaceDir } = await import('../../utils/package-paths');\n const options = opts.serverOptions ?? {};\n\n const config: LanguageServerConfig = {\n checkErrors: 'ON_CHANGE',\n loglevel: options.loglevel ?? 'WARN',\n searchPath: options.searchPath ?? resolve(pkgRoot, 'ql'),\n synchronous: options.synchronous,\n verbosity: options.verbosity,\n };\n\n const manager = getServerManager();\n const server = await manager.getLanguageServer(config);\n\n // Normalize workspace URI: convert relative / bare directory paths to\n // file:// URIs against getUserWorkspaceDir() (respects CODEQL_MCP_WORKSPACE).\n let effectiveUri = opts.workspaceUri;\n if (effectiveUri && !effectiveUri.startsWith('file://')) {\n const absWorkspace = isAbsolute(effectiveUri)\n ? effectiveUri\n : resolve(getUserWorkspaceDir(), effectiveUri);\n effectiveUri = pathToFileURL(absWorkspace).href;\n }\n effectiveUri = effectiveUri ?? pathToFileURL(resolve(pkgRoot, 'ql')).href;\n\n await server.initialize(effectiveUri);\n logger.debug(`Language server initialized with workspace: ${effectiveUri}`);\n\n return server;\n}\n", "/**\n * CodeQL LSP tool handlers.\n *\n * Bridges MCP tool invocations to LSP requests on the CodeQL Language Server.\n * Each handler acquires a language server via the CodeQLServerManager,\n * opens the requested document, sends the LSP request, and returns the result.\n */\n\nimport { readFile } from 'fs/promises';\nimport { isAbsolute, resolve } from 'path';\nimport { pathToFileURL } from 'url';\n\nimport {\n CompletionItem,\n LSPLocation,\n TextDocumentPositionParams,\n} from '../../lib/language-server';\nimport { logger } from '../../utils/logger';\nimport { getUserWorkspaceDir } from '../../utils/package-paths';\nimport { getInitializedLanguageServer } from './lsp-server-helper';\n\n/**\n * Common parameters for LSP tool invocations.\n */\nexport interface LSPToolParams {\n /** 0-based character offset within the line. */\n character: number;\n /** Optional override for the file content (if not reading from disk). */\n fileContent?: string;\n /**\n * Path to the QL file. May be absolute or relative.\n * Relative paths are resolved against `getUserWorkspaceDir()`\n * (respects the `CODEQL_MCP_WORKSPACE` environment variable).\n */\n filePath: string;\n /** 0-based line number in the document. */\n line: number;\n /** Optional search path for CodeQL libraries. */\n searchPath?: string;\n /** Optional workspace URI for context. */\n workspaceUri?: string;\n}\n\n/**\n * Get a running, initialized language server for the given parameters.\n */\nasync function getInitializedServer(params: LSPToolParams) {\n return getInitializedLanguageServer({\n serverOptions: { searchPath: params.searchPath },\n workspaceUri: params.workspaceUri,\n });\n}\n\n/**\n * Resolve the file path to an absolute path and file:// URI.\n */\nfunction prepareDocumentPosition(\n params: LSPToolParams,\n): { absPath: string; docUri: string } {\n // Resolve relative paths against getUserWorkspaceDir() so that\n // CODEQL_MCP_WORKSPACE is respected and behaviour is consistent across tools.\n const absPath = isAbsolute(params.filePath)\n ? params.filePath\n : resolve(getUserWorkspaceDir(), params.filePath);\n const docUri = pathToFileURL(absPath).href;\n\n return { absPath, docUri };\n}\n\n/**\n * Read file content and open the document in the language server.\n */\nasync function openDocumentForPosition(\n server: Awaited>,\n params: LSPToolParams,\n absPath: string,\n docUri: string,\n): Promise {\n // Read file content from disk or use provided content\n let text: string;\n if (params.fileContent) {\n text = params.fileContent;\n } else {\n try {\n text = await readFile(absPath, 'utf-8');\n } catch (error) {\n throw new Error(`Cannot read file: ${absPath}: ${error instanceof Error ? error.message : error}`);\n }\n }\n\n // Open the document so the language server knows about it\n server.openDocument(docUri, text);\n\n return {\n position: { character: params.character, line: params.line },\n textDocument: { uri: docUri },\n };\n}\n\n/**\n * Get code completions at a position.\n */\nexport async function lspCompletion(params: LSPToolParams): Promise {\n logger.info(`LSP completion at ${params.filePath}:${params.line}:${params.character}`);\n const server = await getInitializedServer(params);\n const { absPath, docUri } = prepareDocumentPosition(params);\n const positionParams = await openDocumentForPosition(server, params, absPath, docUri);\n\n try {\n return await server.getCompletions(positionParams);\n } finally {\n server.closeDocument(docUri);\n }\n}\n\n/**\n * Go to definition of a symbol at a position.\n */\nexport async function lspDefinition(params: LSPToolParams): Promise {\n logger.info(`LSP definition at ${params.filePath}:${params.line}:${params.character}`);\n const server = await getInitializedServer(params);\n const { absPath, docUri } = prepareDocumentPosition(params);\n const positionParams = await openDocumentForPosition(server, params, absPath, docUri);\n\n try {\n return await server.getDefinition(positionParams);\n } finally {\n server.closeDocument(docUri);\n }\n}\n\n/**\n * Find all references to a symbol at a position.\n */\nexport async function lspReferences(params: LSPToolParams): Promise {\n logger.info(`LSP references at ${params.filePath}:${params.line}:${params.character}`);\n const server = await getInitializedServer(params);\n const { absPath, docUri } = prepareDocumentPosition(params);\n const positionParams = await openDocumentForPosition(server, params, absPath, docUri);\n\n try {\n return await server.getReferences({\n ...positionParams,\n context: { includeDeclaration: true },\n });\n } finally {\n server.closeDocument(docUri);\n }\n}\n", "/**\n * CodeQL LSP MCP tool definitions.\n *\n * Registers four LSP-based tools:\n * - codeql_lsp_completion \u2013 code completions at cursor position\n * - codeql_lsp_definition \u2013 go to definition\n * - codeql_lsp_diagnostics \u2013 QL code validation via LSP diagnostics\n * - codeql_lsp_references \u2013 find all references\n */\n\nimport { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport { z } from 'zod';\nimport { registerLspDiagnosticsTool } from './lsp-diagnostics';\nimport {\n lspCompletion,\n lspDefinition,\n lspReferences,\n} from './lsp-handlers';\nimport { logger } from '../../utils/logger';\n\n/**\n * Shared Zod schema for the common LSP tool parameters.\n */\nconst lspParamsSchema = {\n character: z.number().int().min(0).describe('0-based character offset within the line'),\n file_content: z.string().optional().describe('Optional file content override (reads from disk if omitted)'),\n file_path: z.string().describe('Path to the CodeQL (.ql/.qll) file. Relative paths are resolved against the user workspace directory (see CODEQL_MCP_WORKSPACE).'),\n line: z.number().int().min(0).describe('0-based line number in the document'),\n search_path: z.string().optional().describe('Optional search path for CodeQL libraries'),\n workspace_uri: z.string().optional().describe('Optional workspace URI for context (defaults to ./ql directory)'),\n};\n\n/**\n * Helper to build the handler params from the raw MCP tool input.\n */\nfunction toHandlerParams(input: {\n character: number;\n file_content?: string;\n file_path: string;\n line: number;\n search_path?: string;\n workspace_uri?: string;\n}) {\n return {\n character: input.character,\n fileContent: input.file_content,\n filePath: input.file_path,\n line: input.line,\n searchPath: input.search_path,\n workspaceUri: input.workspace_uri,\n };\n}\n\n/**\n * Register all LSP-based tools with the MCP server.\n */\nexport function registerLSPTools(server: McpServer): void {\n // --- codeql_lsp_diagnostics (relocated from codeql_language_server_eval) ---\n registerLspDiagnosticsTool(server);\n\n // --- codeql_lsp_completion ---\n server.tool(\n 'codeql_lsp_completion',\n 'Get code completions at a cursor position in a CodeQL file. Returns completion items with labels, documentation, and insert text. The file must be a .ql or .qll file. IMPORTANT: Set workspace_uri to the pack or workspace root directory for dependency resolution; without it, completions for imported libraries will be empty.',\n lspParamsSchema,\n async (input) => {\n try {\n const items = await lspCompletion(toHandlerParams(input));\n return {\n content: [{\n text: JSON.stringify({\n completionCount: items.length,\n items: items.map((item) => ({\n detail: item.detail,\n documentation: item.documentation,\n insertText: item.insertText,\n kind: item.kind,\n label: item.label,\n })),\n }, null, 2),\n type: 'text' as const,\n }],\n };\n } catch (error) {\n logger.error('codeql_lsp_completion error:', error);\n return {\n content: [{ text: `Error: ${error instanceof Error ? error.message : 'Unknown error'}`, type: 'text' as const }],\n isError: true,\n };\n }\n },\n );\n\n // --- codeql_lsp_definition ---\n server.tool(\n 'codeql_lsp_definition',\n 'Go to the definition of a CodeQL symbol at a given position. Returns one or more file locations where the symbol is defined. Set workspace_uri to the pack root for dependency resolution.',\n lspParamsSchema,\n async (input) => {\n try {\n const locations = await lspDefinition(toHandlerParams(input));\n return {\n content: [{\n text: JSON.stringify({\n definitionCount: locations.length,\n locations: locations.map((loc) => ({\n endCharacter: loc.range.end.character,\n endLine: loc.range.end.line + 1,\n startCharacter: loc.range.start.character,\n startLine: loc.range.start.line + 1,\n uri: loc.uri,\n })),\n }, null, 2),\n type: 'text' as const,\n }],\n };\n } catch (error) {\n logger.error('codeql_lsp_definition error:', error);\n return {\n content: [{ text: `Error: ${error instanceof Error ? error.message : 'Unknown error'}`, type: 'text' as const }],\n isError: true,\n };\n }\n },\n );\n\n // --- codeql_lsp_references ---\n server.tool(\n 'codeql_lsp_references',\n 'Find all references to a CodeQL symbol at a given position. Returns file locations of all usages, including the declaration. Set workspace_uri to the pack root for dependency resolution.',\n lspParamsSchema,\n async (input) => {\n try {\n const locations = await lspReferences(toHandlerParams(input));\n return {\n content: [{\n text: JSON.stringify({\n locations: locations.map((loc) => ({\n endCharacter: loc.range.end.character,\n endLine: loc.range.end.line + 1,\n startCharacter: loc.range.start.character,\n startLine: loc.range.start.line + 1,\n uri: loc.uri,\n })),\n referenceCount: locations.length,\n }, null, 2),\n type: 'text' as const,\n }],\n };\n } catch (error) {\n logger.error('codeql_lsp_references error:', error);\n return {\n content: [{ text: `Error: ${error instanceof Error ? error.message : 'Unknown error'}`, type: 'text' as const }],\n isError: true,\n };\n }\n },\n );\n}\n", "/**\n * Language-specific resources implementation\n * Dynamically loads and serves language-specific AST references and security patterns\n */\n\nimport { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport { readFileSync, existsSync } from 'fs';\nimport { join } from 'path';\nimport { LANGUAGE_RESOURCES } from '../types/language-types';\nimport { workspaceRootDir } from '../utils/package-paths';\nimport { logger } from '../utils/logger';\n\n/**\n * Get the base path for ql resources.\n * Uses the workspace root (monorepo root or package root) so that\n * resource files are found regardless of the server's process.cwd().\n */\nfunction getQLBasePath(): string {\n return workspaceRootDir;\n}\n\n/**\n * Load content from a resource file\n */\nfunction loadResourceContent(relativePath: string): string | null {\n try {\n const fullPath = join(getQLBasePath(), relativePath);\n \n if (!existsSync(fullPath)) {\n logger.warn(`Resource file not found: ${fullPath}`);\n return null;\n }\n \n return readFileSync(fullPath, 'utf-8');\n } catch (error) {\n logger.error(`Error loading resource file ${relativePath}:`, error);\n return null;\n }\n}\n\n/**\n * Register language-specific AST resources\n */\nexport function registerLanguageASTResources(server: McpServer): void {\n for (const langResource of LANGUAGE_RESOURCES) {\n if (!langResource.astFile) continue;\n \n const resourceUri = `codeql://languages/${langResource.language}/ast`;\n \n server.resource(\n `${langResource.language.toUpperCase()} AST Reference`,\n resourceUri,\n {\n description: `CodeQL AST class reference for ${langResource.language} programs`,\n mimeType: 'text/markdown'\n },\n async () => {\n const content = loadResourceContent(langResource.astFile!);\n \n if (!content) {\n return {\n contents: [{\n uri: resourceUri,\n mimeType: 'text/markdown',\n text: `# ${langResource.language.toUpperCase()} AST Reference\\n\\nResource file not found or could not be loaded.`\n }]\n };\n }\n \n return {\n contents: [{\n uri: resourceUri,\n mimeType: 'text/markdown',\n text: content\n }]\n };\n }\n );\n }\n}\n\n/**\n * Register language-specific security pattern resources\n */\nexport function registerLanguageSecurityResources(server: McpServer): void {\n for (const langResource of LANGUAGE_RESOURCES) {\n if (!langResource.securityFile) continue;\n \n const resourceUri = `codeql://languages/${langResource.language}/security`;\n \n server.resource(\n `${langResource.language.toUpperCase()} Security Patterns`,\n resourceUri,\n {\n description: `CodeQL security query patterns and framework modeling for ${langResource.language}`,\n mimeType: 'text/markdown'\n },\n async () => {\n const content = loadResourceContent(langResource.securityFile!);\n \n if (!content) {\n return {\n contents: [{\n uri: resourceUri,\n mimeType: 'text/markdown',\n text: `# ${langResource.language.toUpperCase()} Security Patterns\\n\\nResource file not found or could not be loaded.`\n }]\n };\n }\n \n return {\n contents: [{\n uri: resourceUri,\n mimeType: 'text/markdown',\n text: content\n }]\n };\n }\n );\n }\n}\n\n/**\n * Register additional language-specific resources (like Go's dataflow patterns)\n */\nexport function registerLanguageAdditionalResources(server: McpServer): void {\n for (const langResource of LANGUAGE_RESOURCES) {\n if (!langResource.additionalFiles) continue;\n \n for (const [resourceType, filePath] of Object.entries(langResource.additionalFiles)) {\n const resourceUri = `codeql://languages/${langResource.language}/${resourceType}`;\n \n server.resource(\n `${langResource.language.toUpperCase()} ${resourceType.replace('-', ' ').replace(/\\b\\w/g, l => l.toUpperCase())}`,\n resourceUri,\n {\n description: `CodeQL ${resourceType.replace('-', ' ')} guide for ${langResource.language}`,\n mimeType: 'text/markdown'\n },\n async () => {\n const content = loadResourceContent(filePath);\n \n if (!content) {\n return {\n contents: [{\n uri: resourceUri,\n mimeType: 'text/markdown',\n text: `# ${langResource.language.toUpperCase()} ${resourceType.replace('-', ' ').replace(/\\b\\w/g, l => l.toUpperCase())}\\n\\nResource file not found or could not be loaded.`\n }]\n };\n }\n \n return {\n contents: [{\n uri: resourceUri,\n mimeType: 'text/markdown',\n text: content\n }]\n };\n }\n );\n }\n }\n}\n\n/**\n * Register all language-specific resources\n */\nexport function registerLanguageResources(server: McpServer): void {\n logger.info('Registering language-specific resources...');\n \n // Register AST references for all languages\n registerLanguageASTResources(server);\n \n // Register security patterns for languages that have them\n registerLanguageSecurityResources(server);\n \n // Register additional resources (like Go's dataflow patterns)\n registerLanguageAdditionalResources(server);\n \n logger.info(`Registered resources for ${LANGUAGE_RESOURCES.length} languages`);\n}", "/**\n * Type definitions and constants for language-specific resources\n */\n\n// Language mappings to resource files\nexport interface LanguageResource {\n language: string;\n astFile?: string;\n securityFile?: string;\n additionalFiles?: Record;\n}\n\nexport const LANGUAGE_RESOURCES: LanguageResource[] = [\n {\n language: 'actions',\n astFile: 'ql/languages/actions/tools/dev/actions_ast.prompt.md'\n },\n {\n language: 'cpp',\n astFile: 'ql/languages/cpp/tools/dev/cpp_ast.prompt.md',\n securityFile: 'ql/languages/cpp/tools/dev/cpp_security_query_guide.prompt.md'\n },\n {\n language: 'csharp',\n astFile: 'ql/languages/csharp/tools/dev/csharp_ast.prompt.md',\n securityFile: 'ql/languages/csharp/tools/dev/csharp_security_query_guide.prompt.md'\n },\n {\n language: 'go',\n astFile: 'ql/languages/go/tools/dev/go_ast.prompt.md',\n securityFile: 'ql/languages/go/tools/dev/go_security_query_guide.prompt.md',\n additionalFiles: {\n 'dataflow': 'ql/languages/go/tools/dev/go_dataflow.prompt.md',\n 'library-modeling': 'ql/languages/go/tools/dev/go_library_modeling.prompt.md',\n 'basic-queries': 'ql/languages/go/tools/dev/go_basic_queries.prompt.md'\n }\n },\n {\n language: 'java',\n astFile: 'ql/languages/java/tools/dev/java_ast.prompt.md'\n },\n {\n language: 'javascript',\n astFile: 'ql/languages/javascript/tools/dev/javascript_ast.prompt.md',\n securityFile: 'ql/languages/javascript/tools/dev/javascript_security_query_guide.prompt.md'\n },\n {\n language: 'python',\n astFile: 'ql/languages/python/tools/dev/python_ast.prompt.md',\n securityFile: 'ql/languages/python/tools/dev/python_security_query_guide.prompt.md'\n },\n {\n language: 'ql',\n astFile: 'ql/languages/ql/tools/dev/ql_ast.prompt.md'\n },\n {\n language: 'ruby',\n astFile: 'ql/languages/ruby/tools/dev/ruby_ast.prompt.md'\n }\n];", "/**\n * MCP Server workflow prompts for CodeQL development\n *\n * All prompt content is loaded from .prompt.md files in this directory.\n * This file only handles prompt registration and parameter processing.\n */\n\nimport { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport { z } from 'zod';\nimport { basename } from 'path';\nimport { loadPromptTemplate, processPromptTemplate } from './prompt-loader';\nimport { logger } from '../utils/logger';\n\n/** Supported CodeQL languages for tools queries */\nexport const SUPPORTED_LANGUAGES = [\n 'actions',\n 'cpp',\n 'csharp',\n 'go',\n 'java',\n 'javascript',\n 'python',\n 'ruby',\n 'swift'\n] as const;\n\n// \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n// Exported parameter schemas for each workflow prompt.\n//\n// Extracting the schemas makes it easy to unit-test required vs optional\n// validation independently of the MCP server registration.\n//\n// **Convention for VS Code UX consistency**:\n// Every prompt MUST expose at least one parameter \u2013 even if all parameters\n// are optional \u2013 so that VS Code always displays the parameter input dialog\n// and allows the user to customize the prompt before Copilot Chat processes\n// it. The `description` field on each Zod schema member doubles as the\n// placeholder text shown in the VS Code input box.\n// \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n/**\n * Schema for test_driven_development prompt parameters.\n *\n * - `language` is **required** \u2013 the TDD workflow is language-specific.\n * - `queryName` is optional \u2013 defaults to '[QueryName]' if omitted.\n */\nexport const testDrivenDevelopmentSchema = z.object({\n language: z\n .enum(SUPPORTED_LANGUAGES)\n .describe('Programming language for the query'),\n queryName: z\n .string()\n .optional()\n .describe('Name of the query to develop'),\n});\n\n/**\n * Schema for tools_query_workflow prompt parameters.\n *\n * - `language` and `database` are **required**.\n * - `sourceFiles`, `sourceFunction`, `targetFunction` are optional context.\n */\nexport const toolsQueryWorkflowSchema = z.object({\n database: z\n .string()\n .describe('Path to the CodeQL database'),\n language: z\n .enum(SUPPORTED_LANGUAGES)\n .describe('Programming language for the tools queries'),\n sourceFiles: z\n .string()\n .optional()\n .describe('Comma-separated source file names for PrintAST (e.g., \"main.js,utils.js\")'),\n sourceFunction: z\n .string()\n .optional()\n .describe('Function name for PrintCFG or CallGraphFrom (e.g., \"processData\")'),\n targetFunction: z\n .string()\n .optional()\n .describe('Function name for CallGraphTo (e.g., \"validate\")'),\n});\n\n/**\n * Schema for workshop_creation_workflow prompt parameters.\n * Uses z.coerce.number() for numStages to handle string inputs from VSCode slash commands.\n *\n * - `queryPath` and `language` are **required**.\n * - `workshopName` and `numStages` are optional.\n */\nexport const workshopCreationWorkflowSchema = z.object({\n queryPath: z\n .string()\n .describe('Path to the production-grade CodeQL query (.ql or .qlref)'),\n language: z\n .enum(SUPPORTED_LANGUAGES)\n .describe('Programming language of the query'),\n workshopName: z\n .string()\n .optional()\n .describe('Name for the workshop directory'),\n numStages: z\n .coerce.number()\n .optional()\n .describe('Number of incremental stages (default: 4-8)'),\n});\n\n/**\n * Schema for ql_tdd_basic prompt parameters.\n *\n * All parameters are optional \u2013 but at least one should be present so the\n * VS Code quick-pick dialog appears.\n */\nexport const qlTddBasicSchema = z.object({\n language: z\n .enum(SUPPORTED_LANGUAGES)\n .optional()\n .describe('Programming language for the query (optional)'),\n queryName: z\n .string()\n .optional()\n .describe('Name of the query to develop'),\n});\n\n/**\n * Schema for ql_tdd_advanced prompt parameters.\n *\n * All parameters are optional.\n */\nexport const qlTddAdvancedSchema = z.object({\n database: z\n .string()\n .optional()\n .describe('Path to the CodeQL database for analysis'),\n language: z\n .enum(SUPPORTED_LANGUAGES)\n .optional()\n .describe('Programming language for the query (optional)'),\n queryName: z\n .string()\n .optional()\n .describe('Name of the query to develop'),\n});\n\n/**\n * Schema for sarif_rank_false_positives / sarif_rank_true_positives.\n *\n * Both parameters are optional.\n */\nexport const sarifRankSchema = z.object({\n queryId: z\n .string()\n .optional()\n .describe('CodeQL query/rule identifier'),\n sarifPath: z\n .string()\n .optional()\n .describe('Path to the SARIF file to analyze'),\n});\n\n/**\n * Schema for explain_codeql_query prompt parameters.\n *\n * - `queryPath` and `language` are **required**.\n * - `databasePath` is optional.\n */\nexport const explainCodeqlQuerySchema = z.object({\n databasePath: z\n .string()\n .optional()\n .describe('Optional path to a real CodeQL database for profiling'),\n language: z\n .enum(SUPPORTED_LANGUAGES)\n .describe('Programming language of the query'),\n queryPath: z\n .string()\n .describe('Path to the CodeQL query file (.ql or .qlref)'),\n});\n\n/**\n * Schema for document_codeql_query prompt parameters.\n *\n * - `queryPath` and `language` are **required**.\n */\nexport const documentCodeqlQuerySchema = z.object({\n language: z\n .enum(SUPPORTED_LANGUAGES)\n .describe('Programming language of the query'),\n queryPath: z\n .string()\n .describe('Path to the CodeQL query file (.ql or .qlref)'),\n});\n\n/**\n * Schema for ql_lsp_iterative_development prompt parameters.\n *\n * All parameters are optional.\n */\nexport const qlLspIterativeDevelopmentSchema = z.object({\n language: z\n .enum(SUPPORTED_LANGUAGES)\n .optional()\n .describe('Programming language for the query'),\n queryPath: z\n .string()\n .optional()\n .describe('Path to the query file being developed'),\n workspaceUri: z\n .string()\n .optional()\n .describe('Workspace URI for LSP dependency resolution'),\n});\n\n// \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n// Prompt names (exported for testing)\n// \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n/** Names of every workflow prompt registered with the MCP server. */\nexport const WORKFLOW_PROMPT_NAMES = [\n 'document_codeql_query',\n 'explain_codeql_query',\n 'ql_lsp_iterative_development',\n 'ql_tdd_advanced',\n 'ql_tdd_basic',\n 'sarif_rank_false_positives',\n 'sarif_rank_true_positives',\n 'test_driven_development',\n 'tools_query_workflow',\n 'workshop_creation_workflow',\n] as const;\n\n/**\n * Register MCP workflow prompts\n *\n * Each prompt loads its content from a corresponding .prompt.md file\n * and processes any parameter substitutions.\n *\n * **UX note**: Every prompt schema is passed to `server.prompt()` so that\n * VS Code always displays the parameter-input quick-pick before the prompt\n * is sent to Copilot Chat. This lets users review and customise the values.\n */\nexport function registerWorkflowPrompts(server: McpServer): void {\n // Test-Driven Development Prompt\n server.prompt(\n 'test_driven_development',\n 'Test-driven development workflow for CodeQL queries using MCP tools',\n testDrivenDevelopmentSchema.shape,\n async ({ language, queryName }) => {\n const template = loadPromptTemplate('ql-tdd-basic.prompt.md');\n const content = processPromptTemplate(template, {\n language,\n queryName: queryName || '[QueryName]'\n });\n\n return {\n messages: [\n {\n role: 'user',\n content: {\n type: 'text',\n text: `## Context\\n\\n- **Language**: ${language}\\n${queryName ? `- **Query Name**: ${queryName}\\n` : ''}\\n${content}`\n }\n }\n ]\n };\n }\n );\n\n // Tools Query Workflow Prompt\n server.prompt(\n 'tools_query_workflow',\n 'Guide for using built-in tools queries (PrintAST, PrintCFG, CallGraphFrom, CallGraphTo) to understand code structure',\n toolsQueryWorkflowSchema.shape,\n async ({\n language,\n database,\n sourceFiles,\n sourceFunction,\n targetFunction\n }) => {\n const template = loadPromptTemplate('tools-query-workflow.prompt.md');\n const content = processPromptTemplate(template, {\n language,\n database\n });\n\n const contextSection = buildToolsQueryContext(\n language,\n database,\n sourceFiles,\n sourceFunction,\n targetFunction\n );\n\n return {\n messages: [\n {\n role: 'user',\n content: {\n type: 'text',\n text: contextSection + content\n }\n }\n ]\n };\n }\n );\n\n // Workshop Creation Workflow Prompt\n server.prompt(\n 'workshop_creation_workflow',\n 'Guide for creating CodeQL query development workshops from production-grade queries',\n workshopCreationWorkflowSchema.shape,\n async ({ queryPath, language, workshopName, numStages }) => {\n const template = loadPromptTemplate('workshop-creation-workflow.prompt.md');\n\n // Derive workshop name from query path if not provided\n const derivedName =\n workshopName ||\n basename(queryPath)\n .replace(/\\.(ql|qlref)$/, '')\n .toLowerCase()\n .replace(/[^a-z0-9]+/g, '-') ||\n 'codeql-workshop';\n\n const contextSection = buildWorkshopContext(\n queryPath,\n language,\n derivedName,\n numStages\n );\n\n return {\n messages: [\n {\n role: 'user',\n content: {\n type: 'text',\n text: contextSection + template\n }\n }\n ]\n };\n }\n );\n\n // TDD Basic Prompt - Test-Driven Development Checklist\n server.prompt(\n 'ql_tdd_basic',\n 'Test-driven CodeQL query development checklist - write tests first, implement query, iterate until tests pass',\n qlTddBasicSchema.shape,\n async ({ language, queryName }) => {\n const template = loadPromptTemplate('ql-tdd-basic.prompt.md');\n\n let contextSection = '## Your Development Context\\n\\n';\n if (language) {\n contextSection += `- **Language**: ${language}\\n`;\n }\n if (queryName) {\n contextSection += `- **Query Name**: ${queryName}\\n`;\n }\n if (language || queryName) {\n contextSection += '\\n';\n }\n\n return {\n messages: [\n {\n role: 'user',\n content: {\n type: 'text',\n text: contextSection + template\n }\n }\n ]\n };\n }\n );\n\n // TDD Advanced Prompt - Advanced Techniques with AST/CFG/CallGraph\n server.prompt(\n 'ql_tdd_advanced',\n 'Advanced test-driven CodeQL development with AST visualization, control flow, and call graph analysis',\n qlTddAdvancedSchema.shape,\n async ({ language, queryName, database }) => {\n const template = loadPromptTemplate('ql-tdd-advanced.prompt.md');\n\n let contextSection = '## Your Development Context\\n\\n';\n if (language) {\n contextSection += `- **Language**: ${language}\\n`;\n }\n if (queryName) {\n contextSection += `- **Query Name**: ${queryName}\\n`;\n }\n if (database) {\n contextSection += `- **Database**: ${database}\\n`;\n }\n if (language || queryName || database) {\n contextSection += '\\n';\n }\n\n return {\n messages: [\n {\n role: 'user',\n content: {\n type: 'text',\n text: contextSection + template\n }\n }\n ]\n };\n }\n );\n\n // SARIF Rank False Positives Prompt\n server.prompt(\n 'sarif_rank_false_positives',\n 'Analyze SARIF results to identify likely false positives in CodeQL query results',\n sarifRankSchema.shape,\n async ({ queryId, sarifPath }) => {\n const template = loadPromptTemplate('sarif-rank-false-positives.prompt.md');\n\n let contextSection = '## Analysis Context\\n\\n';\n if (queryId) {\n contextSection += `- **Query ID**: ${queryId}\\n`;\n }\n if (sarifPath) {\n contextSection += `- **SARIF File**: ${sarifPath}\\n`;\n }\n if (queryId || sarifPath) {\n contextSection += '\\n';\n }\n\n return {\n messages: [\n {\n role: 'user',\n content: {\n type: 'text',\n text: contextSection + template\n }\n }\n ]\n };\n }\n );\n\n // SARIF Rank True Positives Prompt\n server.prompt(\n 'sarif_rank_true_positives',\n 'Analyze SARIF results to identify likely true positives in CodeQL query results',\n sarifRankSchema.shape,\n async ({ queryId, sarifPath }) => {\n const template = loadPromptTemplate('sarif-rank-true-positives.prompt.md');\n\n let contextSection = '## Analysis Context\\n\\n';\n if (queryId) {\n contextSection += `- **Query ID**: ${queryId}\\n`;\n }\n if (sarifPath) {\n contextSection += `- **SARIF File**: ${sarifPath}\\n`;\n }\n if (queryId || sarifPath) {\n contextSection += '\\n';\n }\n\n return {\n messages: [\n {\n role: 'user',\n content: {\n type: 'text',\n text: contextSection + template\n }\n }\n ]\n };\n }\n );\n\n // Explain CodeQL Query Prompt (for workshop learning content)\n server.prompt(\n 'explain_codeql_query',\n 'Generate detailed explanation of a CodeQL query for workshop learning content - uses MCP tools to gather context and produces both verbal explanations and mermaid evaluation diagrams',\n explainCodeqlQuerySchema.shape,\n async ({ queryPath, language, databasePath }) => {\n const template = loadPromptTemplate('explain-codeql-query.prompt.md');\n\n let contextSection = '## Query to Explain\\n\\n';\n contextSection += `- **Query Path**: ${queryPath}\\n`;\n contextSection += `- **Language**: ${language}\\n`;\n if (databasePath) {\n contextSection += `- **Database Path**: ${databasePath}\\n`;\n }\n contextSection += '\\n';\n\n return {\n messages: [\n {\n role: 'user',\n content: {\n type: 'text',\n text: contextSection + template\n }\n }\n ]\n };\n }\n );\n\n // Document CodeQL Query Prompt\n server.prompt(\n 'document_codeql_query',\n 'Create or update documentation for a CodeQL query - generates standardized markdown documentation as a sibling file to the query',\n documentCodeqlQuerySchema.shape,\n async ({ queryPath, language }) => {\n const template = loadPromptTemplate('document-codeql-query.prompt.md');\n\n const contextSection = `## Query to Document\n\n- **Query Path**: ${queryPath}\n- **Language**: ${language}\n\n`;\n\n return {\n messages: [\n {\n role: 'user',\n content: {\n type: 'text',\n text: contextSection + template\n }\n }\n ]\n };\n }\n );\n\n // LSP-powered Iterative Development Prompt\n server.prompt(\n 'ql_lsp_iterative_development',\n 'Iterative CodeQL query development using LSP tools for completion, navigation, and validation',\n qlLspIterativeDevelopmentSchema.shape,\n async ({ language, queryPath, workspaceUri }) => {\n const template = loadPromptTemplate('ql-lsp-iterative-development.prompt.md');\n\n let contextSection = '## Your Development Context\\n\\n';\n if (language) {\n contextSection += `- **Language**: ${language}\\n`;\n }\n if (queryPath) {\n contextSection += `- **Query Path**: ${queryPath}\\n`;\n }\n if (workspaceUri) {\n contextSection += `- **Workspace URI**: ${workspaceUri}\\n`;\n }\n if (language || queryPath || workspaceUri) {\n contextSection += '\\n';\n }\n\n return {\n messages: [\n {\n role: 'user',\n content: {\n type: 'text',\n text: contextSection + template,\n },\n },\n ],\n };\n }\n );\n\n logger.info(`Registered ${WORKFLOW_PROMPT_NAMES.length} workflow prompts`);\n}\n\n/**\n * Build context section for tools query workflow\n */\nexport function buildToolsQueryContext(\n language: string,\n database: string,\n sourceFiles?: string,\n sourceFunction?: string,\n targetFunction?: string\n): string {\n const lines = [\n '## Your Context',\n '',\n `- **Language**: ${language}`,\n `- **Database**: ${database}`\n ];\n\n if (sourceFiles) {\n lines.push(`- **Source Files**: ${sourceFiles}`);\n }\n if (sourceFunction) {\n lines.push(`- **Source Function**: ${sourceFunction}`);\n }\n if (targetFunction) {\n lines.push(`- **Target Function**: ${targetFunction}`);\n }\n\n lines.push('', '## Recommended Next Steps', '');\n\n if (sourceFiles) {\n lines.push(\n `1. Run \\`codeql_query_run\\` with queryName=\"PrintAST\", sourceFiles=\"${sourceFiles}\"`\n );\n } else {\n lines.push('1. Identify source files to analyze with PrintAST');\n }\n\n if (sourceFunction) {\n lines.push(\n `2. Run \\`codeql_query_run\\` with queryName=\"PrintCFG\" or \"CallGraphFrom\", sourceFunction=\"${sourceFunction}\"`\n );\n } else {\n lines.push(\n '2. Identify key functions for CFG or call graph analysis'\n );\n }\n\n if (targetFunction) {\n lines.push(\n `3. Run \\`codeql_query_run\\` with queryName=\"CallGraphTo\", targetFunction=\"${targetFunction}\"`\n );\n } else {\n lines.push('3. Identify target functions to find callers');\n }\n\n lines.push('', '');\n return lines.join('\\n');\n}\n\n/**\n * Build context section for workshop creation workflow\n */\nexport function buildWorkshopContext(\n queryPath: string,\n language: string,\n workshopName: string,\n numStages?: number\n): string {\n return `## Your Workshop Context\n\n- **Target Query**: ${queryPath}\n- **Language**: ${language}\n- **Workshop Name**: ${workshopName}\n- **Suggested Stages**: ${numStages || '4-8 (auto-detect based on query complexity)'}\n\n## Immediate Actions\n\n1. **Locate query files**: Use \\`find_codeql_query_files\\` with queryPath=\"${queryPath}\"\n2. **Understand query for learning content**: Use the \\`explain_codeql_query\\` prompt with queryPath=\"${queryPath}\" and language=\"${language}\"\n3. **Document each workshop stage**: Use the \\`document_codeql_query\\` prompt to create/update documentation for each solution query\n4. **Verify tests pass**: Use \\`codeql_test_run\\` on existing tests\n5. **Run tools queries**: Generate AST/CFG understanding for workshop materials\n\n`;\n}\n", "/**\n * Utility functions for loading prompt template files\n */\n\nimport { readFileSync } from 'fs';\nimport { join, dirname } from 'path';\nimport { fileURLToPath } from 'url';\n\nconst __filename = fileURLToPath(import.meta.url);\nconst __dirname = dirname(__filename);\n\n/**\n * Load a prompt template from a .prompt.md file\n */\nexport function loadPromptTemplate(promptFileName: string): string {\n try {\n const promptPath = join(__dirname, promptFileName);\n return readFileSync(promptPath, 'utf-8');\n } catch (error) {\n return `Prompt template '${promptFileName}' not available: ${error instanceof Error ? error.message : 'Unknown error'}`;\n }\n}\n\n/**\n * Process prompt template by replacing placeholders with actual values\n */\nexport function processPromptTemplate(template: string, variables: Record): string {\n let processed = template;\n \n // Replace variables in the format {{variable}} or {variable}\n for (const [key, value] of Object.entries(variables)) {\n const patterns = [\n new RegExp(`\\\\{\\\\{${key}\\\\}\\\\}`, 'g'),\n new RegExp(`\\\\{${key}\\\\}`, 'g')\n ];\n \n for (const pattern of patterns) {\n processed = processed.replace(pattern, value);\n }\n }\n \n return processed;\n}", "/**\n * Monitoring Tools - MCP tool implementations for session management and reporting\n * Provides the MCP Tool APIs specified in the monitoring specification\n */\n\nimport { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport { z } from 'zod';\nimport { randomUUID } from 'crypto';\nimport { sessionDataManager } from '../lib/session-data-manager';\nimport {\n QueryDevelopmentSession,\n SessionFilter,\n QualityScoreRecord,\n ComparisonReport,\n AggregateReport,\n ExportResult,\n FunctionalTestResult,\n} from '../types/monitoring';\nimport { logger } from '../utils/logger';\n\n/**\n * Register all monitoring and reporting tools with the MCP server\n * Note: These tools are opt-in and disabled by default for end-users.\n * Set enableMonitoringTools: true in monitoring config to enable them.\n */\nexport function registerMonitoringTools(server: McpServer): void {\n const config = sessionDataManager.getConfig();\n \n // Check if monitoring tools are enabled (opt-in, disabled by default)\n if (!config.enableMonitoringTools) {\n logger.info('Monitoring tools are disabled (opt-in). Set enableMonitoringTools: true to enable session_* tools.');\n return;\n }\n\n // Session Management Tools - session_start removed per feedback (auto-creation instead)\n registerSessionEndTool(server);\n registerSessionGetTool(server);\n registerSessionListTool(server);\n registerSessionUpdateStateTool(server);\n\n // Session Analytics Tools\n registerSessionGetCallHistoryTool(server);\n registerSessionGetTestHistoryTool(server);\n registerSessionGetScoreHistoryTool(server);\n registerSessionCalculateCurrentScoreTool(server);\n\n // Batch Operations Tools\n registerSessionsCompareTool(server);\n registerSessionsAggregateTool(server);\n registerSessionsExportTool(server);\n\n // Note: Functional Testing Support Tools are internal only, not exposed as MCP tools\n\n logger.info('Registered monitoring and reporting tools');\n}\n\n/**\n * Session Management Tools\n */\n\n// session_start tool removed - sessions are now auto-created when needed\n// Sessions are automatically created when MCP tools are called with queryPath\n// If explicit session creation is needed, provide sessionId=null and it will auto-create\n\nfunction registerSessionEndTool(server: McpServer): void {\n server.tool(\n 'session_end',\n 'End a query development session with final status',\n {\n sessionId: z.string().describe('ID of the session to end'),\n status: z.enum(['completed', 'failed', 'abandoned']).describe('Final status of the session'),\n },\n async ({ sessionId, status }) => {\n try {\n const session = await sessionDataManager.endSession(sessionId, status);\n \n if (!session) {\n return {\n content: [\n {\n type: 'text',\n text: `Session not found: ${sessionId}`,\n },\n ],\n isError: true,\n };\n }\n\n return {\n content: [\n {\n type: 'text',\n text: JSON.stringify(session, null, 2),\n },\n ],\n };\n } catch (error) {\n logger.error('Error ending session:', error);\n return {\n content: [\n {\n type: 'text',\n text: `Error ending session: ${error instanceof Error ? error.message : 'Unknown error'}`,\n },\n ],\n isError: true,\n };\n }\n }\n );\n}\n\nfunction registerSessionGetTool(server: McpServer): void {\n server.tool(\n 'session_get',\n 'Get complete details of a specific query development session',\n {\n sessionId: z.string().describe('ID of the session to retrieve'),\n },\n async ({ sessionId }) => {\n try {\n const session = await sessionDataManager.getSession(sessionId);\n \n if (!session) {\n return {\n content: [\n {\n type: 'text',\n text: `Session not found: ${sessionId}`,\n },\n ],\n isError: true,\n };\n }\n\n return {\n content: [\n {\n type: 'text',\n text: JSON.stringify(session, null, 2),\n },\n ],\n };\n } catch (error) {\n logger.error('Error getting session:', error);\n return {\n content: [\n {\n type: 'text',\n text: `Error getting session: ${error instanceof Error ? error.message : 'Unknown error'}`,\n },\n ],\n isError: true,\n };\n }\n }\n );\n}\n\nfunction registerSessionListTool(server: McpServer): void {\n server.tool(\n 'session_list',\n 'List query development sessions with optional filtering',\n {\n queryPath: z.string().optional().describe('Filter by query path (partial match)'),\n status: z.string().optional().describe('Filter by session status'),\n dateRange: z.array(z.string()).length(2).optional().describe('Filter by date range [start, end] (ISO timestamps)'),\n language: z.string().optional().describe('Filter by programming language'),\n queryType: z.string().optional().describe('Filter by query type'),\n },\n async ({ queryPath, status, dateRange, language, queryType }) => {\n try {\n const filters: SessionFilter = {};\n if (queryPath) filters.queryPath = queryPath;\n if (status) filters.status = status;\n if (dateRange) filters.dateRange = [dateRange[0], dateRange[1]];\n if (language) filters.language = language;\n if (queryType) filters.queryType = queryType;\n\n const sessions = await sessionDataManager.listSessions(\n Object.keys(filters).length > 0 ? filters : undefined\n );\n\n const sessionList = {\n totalSessions: sessions.length,\n sessions: sessions.map(s => ({\n sessionId: s.sessionId,\n queryPath: s.queryPath,\n language: s.language,\n status: s.status,\n startTime: s.startTime,\n endTime: s.endTime,\n mcpCallsCount: s.mcpCalls.length,\n testExecutionsCount: s.testExecutions.length,\n currentScore: s.qualityScores.length > 0 \n ? s.qualityScores[s.qualityScores.length - 1].overallScore \n : null,\n })),\n };\n\n return {\n content: [\n {\n type: 'text',\n text: JSON.stringify(sessionList, null, 2),\n },\n ],\n recommendations: generateListRecommendations(sessions),\n };\n } catch (error) {\n logger.error('Error listing sessions:', error);\n return {\n content: [\n {\n type: 'text',\n text: `Error listing sessions: ${error instanceof Error ? error.message : 'Unknown error'}`,\n },\n ],\n isError: true,\n };\n }\n }\n );\n}\n\nfunction registerSessionUpdateStateTool(server: McpServer): void {\n server.tool(\n 'session_update_state',\n 'Update the current state of a query development session',\n {\n sessionId: z.string().describe('ID of the session to update'),\n filesPresent: z.array(z.string()).optional().describe('List of files present in the query development'),\n compilationStatus: z.enum(['unknown', 'success', 'failed']).optional().describe('Current compilation status'),\n testStatus: z.enum(['unknown', 'passing', 'failing', 'no_tests']).optional().describe('Current test status'),\n documentationStatus: z.enum(['unknown', 'present', 'missing', 'incomplete']).optional().describe('Documentation status'),\n },\n async ({ sessionId, filesPresent, compilationStatus, testStatus, documentationStatus }) => {\n try {\n const stateUpdate: Record = {};\n if (filesPresent !== undefined) stateUpdate.filesPresent = filesPresent;\n if (compilationStatus !== undefined) stateUpdate.compilationStatus = compilationStatus;\n if (testStatus !== undefined) stateUpdate.testStatus = testStatus;\n if (documentationStatus !== undefined) stateUpdate.documentationStatus = documentationStatus;\n\n const session = await sessionDataManager.updateSessionState(sessionId, stateUpdate);\n \n if (!session) {\n return {\n content: [\n {\n type: 'text',\n text: `Session not found: ${sessionId}`,\n },\n ],\n isError: true,\n };\n }\n\n return {\n content: [\n {\n type: 'text',\n text: JSON.stringify(session, null, 2),\n },\n ],\n recommendations: generateRecommendations(session, 'session_update_state'),\n };\n } catch (error) {\n logger.error('Error updating session state:', error);\n return {\n content: [\n {\n type: 'text',\n text: `Error updating session state: ${error instanceof Error ? error.message : 'Unknown error'}`,\n },\n ],\n isError: true,\n };\n }\n }\n );\n}\n\n/**\n * Session Analytics Tools\n */\n\nfunction registerSessionGetCallHistoryTool(server: McpServer): void {\n server.tool(\n 'session_get_call_history',\n 'Get MCP call history for a specific session',\n {\n sessionId: z.string().describe('ID of the session'),\n limit: z.number().optional().describe('Maximum number of calls to return (most recent first)'),\n },\n async ({ sessionId, limit }) => {\n try {\n const session = await sessionDataManager.getSession(sessionId);\n \n if (!session) {\n return {\n content: [\n {\n type: 'text',\n text: `Session not found: ${sessionId}`,\n },\n ],\n isError: true,\n };\n }\n\n let calls = [...session.mcpCalls].reverse(); // Most recent first\n if (limit && limit > 0) {\n calls = calls.slice(0, limit);\n }\n\n return {\n content: [\n {\n type: 'text',\n text: JSON.stringify({\n sessionId,\n totalCalls: session.mcpCalls.length,\n callHistory: calls,\n }, null, 2),\n },\n ],\n };\n } catch (error) {\n logger.error('Error getting call history:', error);\n return {\n content: [\n {\n type: 'text',\n text: `Error getting call history: ${error instanceof Error ? error.message : 'Unknown error'}`,\n },\n ],\n isError: true,\n };\n }\n }\n );\n}\n\nfunction registerSessionGetTestHistoryTool(server: McpServer): void {\n server.tool(\n 'session_get_test_history',\n 'Get test execution history for a specific session',\n {\n sessionId: z.string().describe('ID of the session'),\n limit: z.number().optional().describe('Maximum number of test executions to return (most recent first)'),\n },\n async ({ sessionId, limit }) => {\n try {\n const session = await sessionDataManager.getSession(sessionId);\n \n if (!session) {\n return {\n content: [\n {\n type: 'text',\n text: `Session not found: ${sessionId}`,\n },\n ],\n isError: true,\n };\n }\n\n let tests = [...session.testExecutions].reverse(); // Most recent first\n if (limit && limit > 0) {\n tests = tests.slice(0, limit);\n }\n\n return {\n content: [\n {\n type: 'text',\n text: JSON.stringify({\n sessionId,\n totalTests: session.testExecutions.length,\n testHistory: tests,\n }, null, 2),\n },\n ],\n };\n } catch (error) {\n logger.error('Error getting test history:', error);\n return {\n content: [\n {\n type: 'text',\n text: `Error getting test history: ${error instanceof Error ? error.message : 'Unknown error'}`,\n },\n ],\n isError: true,\n };\n }\n }\n );\n}\n\nfunction registerSessionGetScoreHistoryTool(server: McpServer): void {\n server.tool(\n 'session_get_score_history',\n 'Get quality score history for a specific session',\n {\n sessionId: z.string().describe('ID of the session'),\n limit: z.number().optional().describe('Maximum number of scores to return (most recent first)'),\n },\n async ({ sessionId, limit }) => {\n try {\n const session = await sessionDataManager.getSession(sessionId);\n \n if (!session) {\n return {\n content: [\n {\n type: 'text',\n text: `Session not found: ${sessionId}`,\n },\n ],\n isError: true,\n };\n }\n\n let scores = [...session.qualityScores].reverse(); // Most recent first\n if (limit && limit > 0) {\n scores = scores.slice(0, limit);\n }\n\n return {\n content: [\n {\n type: 'text',\n text: JSON.stringify({\n sessionId,\n totalScores: session.qualityScores.length,\n scoreHistory: scores,\n }, null, 2),\n },\n ],\n };\n } catch (error) {\n logger.error('Error getting score history:', error);\n return {\n content: [\n {\n type: 'text',\n text: `Error getting score history: ${error instanceof Error ? error.message : 'Unknown error'}`,\n },\n ],\n isError: true,\n };\n }\n }\n );\n}\n\nfunction registerSessionCalculateCurrentScoreTool(server: McpServer): void {\n server.tool(\n 'session_calculate_current_score',\n 'Calculate current quality score for a session based on its state',\n {\n sessionId: z.string().describe('ID of the session'),\n },\n async ({ sessionId }) => {\n try {\n const session = await sessionDataManager.getSession(sessionId);\n \n if (!session) {\n return {\n content: [\n {\n type: 'text',\n text: `Session not found: ${sessionId}`,\n },\n ],\n isError: true,\n };\n }\n\n // Calculate quality score based on current state\n const scoreRecord = calculateQualityScore(session);\n \n // Add the score to the session\n await sessionDataManager.addQualityScore(sessionId, scoreRecord);\n \n // Get updated session with new score\n const updatedSession = await sessionDataManager.getSession(sessionId);\n\n return {\n content: [\n {\n type: 'text',\n text: JSON.stringify(scoreRecord, null, 2),\n },\n ],\n recommendations: generateRecommendations(updatedSession, 'session_calculate_current_score'),\n };\n } catch (error) {\n logger.error('Error calculating current score:', error);\n return {\n content: [\n {\n type: 'text',\n text: `Error calculating current score: ${error instanceof Error ? error.message : 'Unknown error'}`,\n },\n ],\n isError: true,\n };\n }\n }\n );\n}\n\n/**\n * Batch Operations Tools\n */\n\nfunction registerSessionsCompareTool(server: McpServer): void {\n server.tool(\n 'sessions_compare',\n 'Compare multiple query development sessions across specified dimensions',\n {\n sessionIds: z.array(z.string()).describe('Array of session IDs to compare'),\n dimensions: z.array(z.string()).optional().describe('Specific dimensions to compare (default: all)'),\n },\n async ({ sessionIds, dimensions }) => {\n try {\n const sessions = await Promise.all(\n sessionIds.map(id => sessionDataManager.getSession(id))\n );\n\n const validSessions = sessions.filter(s => s !== null) as QueryDevelopmentSession[];\n \n if (validSessions.length === 0) {\n return {\n content: [\n {\n type: 'text',\n text: 'No valid sessions found for comparison',\n },\n ],\n isError: true,\n };\n }\n\n const comparison = await compareSessions(validSessions, dimensions);\n\n return {\n content: [\n {\n type: 'text',\n text: JSON.stringify(comparison, null, 2),\n },\n ],\n };\n } catch (error) {\n logger.error('Error comparing sessions:', error);\n return {\n content: [\n {\n type: 'text',\n text: `Error comparing sessions: ${error instanceof Error ? error.message : 'Unknown error'}`,\n },\n ],\n isError: true,\n };\n }\n }\n );\n}\n\nfunction registerSessionsAggregateTool(server: McpServer): void {\n server.tool(\n 'sessions_aggregate',\n 'Generate aggregate insights from multiple sessions based on filters',\n {\n queryPath: z.string().optional().describe('Filter by query path (partial match)'),\n status: z.string().optional().describe('Filter by session status'),\n dateRange: z.array(z.string()).length(2).optional().describe('Filter by date range [start, end] (ISO timestamps)'),\n language: z.string().optional().describe('Filter by programming language'),\n queryType: z.string().optional().describe('Filter by query type'),\n },\n async ({ queryPath, status, dateRange, language, queryType }) => {\n try {\n const filters: SessionFilter = {};\n if (queryPath) filters.queryPath = queryPath;\n if (status) filters.status = status;\n if (dateRange) filters.dateRange = [dateRange[0], dateRange[1]];\n if (language) filters.language = language;\n if (queryType) filters.queryType = queryType;\n\n const sessions = await sessionDataManager.listSessions(\n Object.keys(filters).length > 0 ? filters : undefined\n );\n\n const aggregate = await aggregateSessions(sessions, filters);\n\n return {\n content: [\n {\n type: 'text',\n text: JSON.stringify(aggregate, null, 2),\n },\n ],\n };\n } catch (error) {\n logger.error('Error aggregating sessions:', error);\n return {\n content: [\n {\n type: 'text',\n text: `Error aggregating sessions: ${error instanceof Error ? error.message : 'Unknown error'}`,\n },\n ],\n isError: true,\n };\n }\n }\n );\n}\n\nfunction registerSessionsExportTool(server: McpServer): void {\n server.tool(\n 'sessions_export',\n 'Export session data in specified format for external analysis',\n {\n sessionIds: z.array(z.string()).describe('Array of session IDs to export'),\n format: z.enum(['json', 'html', 'markdown']).optional().default('json').describe('Export format'),\n },\n async ({ sessionIds, format = 'json' }) => {\n try {\n const sessions = await Promise.all(\n sessionIds.map(id => sessionDataManager.getSession(id))\n );\n\n const validSessions = sessions.filter(s => s !== null) as QueryDevelopmentSession[];\n \n if (validSessions.length === 0) {\n return {\n content: [\n {\n type: 'text',\n text: 'No valid sessions found for export',\n },\n ],\n isError: true,\n };\n }\n\n const exportResult = await exportSessions(validSessions, format);\n\n return {\n content: [\n {\n type: 'text',\n text: JSON.stringify(exportResult, null, 2),\n },\n ],\n };\n } catch (error) {\n logger.error('Error exporting sessions:', error);\n return {\n content: [\n {\n type: 'text',\n text: `Error exporting sessions: ${error instanceof Error ? error.message : 'Unknown error'}`,\n },\n ],\n isError: true,\n };\n }\n }\n );\n}\n\n/**\n * Helper Functions\n */\n\n/**\n * Calculate quality score for a session based on current state and history\n */\nfunction calculateQualityScore(session: QueryDevelopmentSession): QualityScoreRecord {\n const timestamp = new Date().toISOString();\n \n // Calculate syntactic correctness (25%)\n const syntacticCorrectness = session.currentState.compilationStatus === 'success' ? 100 :\n session.currentState.compilationStatus === 'failed' ? 0 : 50;\n\n // Calculate test coverage and results (30%)\n const testCoverageResults = session.currentState.testStatus === 'passing' ? 100 :\n session.currentState.testStatus === 'failing' ? 25 :\n session.currentState.testStatus === 'no_tests' ? 0 : 50;\n\n // Calculate documentation quality (20%)\n const documentationQuality = session.currentState.documentationStatus === 'present' ? 100 :\n session.currentState.documentationStatus === 'incomplete' ? 60 :\n session.currentState.documentationStatus === 'missing' ? 0 : 50;\n\n // Calculate functional correctness (25%) - based on successful test runs\n const successfulTests = session.testExecutions.filter(t => t.success && t.type === 'test_run').length;\n const totalTests = session.testExecutions.filter(t => t.type === 'test_run').length;\n const functionalCorrectness = totalTests > 0 ? (successfulTests / totalTests) * 100 : 50;\n\n // Calculate overall score\n const overallScore = Math.round(\n (syntacticCorrectness * 0.25) +\n (testCoverageResults * 0.30) +\n (documentationQuality * 0.20) +\n (functionalCorrectness * 0.25)\n );\n\n // Determine grade\n const grade = overallScore >= 90 ? 'A' :\n overallScore >= 80 ? 'B' :\n overallScore >= 70 ? 'C' :\n overallScore >= 60 ? 'D' : 'F';\n\n // Generate recommendations\n const recommendations: string[] = [];\n if (syntacticCorrectness < 100) {\n recommendations.push('Fix compilation errors to improve syntactic correctness');\n }\n if (testCoverageResults < 70) {\n recommendations.push('Add comprehensive tests and ensure they pass');\n }\n if (documentationQuality < 80) {\n recommendations.push('Add or improve query documentation with examples');\n }\n if (functionalCorrectness < 80) {\n recommendations.push('Improve test pass rate and verify query logic');\n }\n\n return {\n scoreId: randomUUID(),\n timestamp,\n overallScore,\n dimensions: {\n syntacticCorrectness,\n testCoverageResults,\n documentationQuality,\n functionalCorrectness,\n },\n grade,\n recommendations,\n };\n}\n\n/**\n * Compare multiple sessions\n */\nasync function compareSessions(\n sessions: QueryDevelopmentSession[],\n dimensions?: string[]\n): Promise {\n const timestamp = new Date().toISOString();\n const sessionIds = sessions.map(s => s.sessionId);\n \n const results: Record = {\n sessionCount: sessions.length,\n sessionOverview: sessions.map(s => ({\n sessionId: s.sessionId,\n queryPath: s.queryPath,\n status: s.status,\n mcpCallsCount: s.mcpCalls.length,\n duration: s.endTime ? \n new Date(s.endTime).getTime() - new Date(s.startTime).getTime() : \n new Date().getTime() - new Date(s.startTime).getTime(),\n currentScore: s.qualityScores.length > 0 ? \n s.qualityScores[s.qualityScores.length - 1].overallScore : null,\n })),\n };\n\n if (!dimensions || dimensions.includes('quality')) {\n const qualityScores = sessions.map(s => \n s.qualityScores.length > 0 ? s.qualityScores[s.qualityScores.length - 1] : null\n );\n results.qualityComparison = {\n averageScore: qualityScores\n .filter(q => q !== null)\n .reduce((sum, q) => sum + q!.overallScore, 0) / qualityScores.filter(q => q !== null).length,\n scoreRange: {\n min: Math.min(...qualityScores.filter(q => q !== null).map(q => q!.overallScore)),\n max: Math.max(...qualityScores.filter(q => q !== null).map(q => q!.overallScore)),\n },\n };\n }\n\n if (!dimensions || dimensions.includes('activity')) {\n results.activityComparison = {\n totalMCPCalls: sessions.reduce((sum, s) => sum + s.mcpCalls.length, 0),\n averageCallsPerSession: sessions.reduce((sum, s) => sum + s.mcpCalls.length, 0) / sessions.length,\n mostActiveTool: getMostUsedTool(sessions),\n };\n }\n\n return {\n sessionIds,\n dimensions: dimensions || ['all'],\n timestamp,\n results,\n };\n}\n\n/**\n * Aggregate insights from multiple sessions\n */\nasync function aggregateSessions(\n sessions: QueryDevelopmentSession[],\n filters: SessionFilter\n): Promise {\n const timestamp = new Date().toISOString();\n \n const completedSessions = sessions.filter(s => s.status === 'completed');\n const successRate = sessions.length > 0 ? completedSessions.length / sessions.length : 0;\n \n const qualityScores = sessions\n .map(s => s.qualityScores.length > 0 ? s.qualityScores[s.qualityScores.length - 1].overallScore : null)\n .filter(score => score !== null) as number[];\n \n const averageQualityScore = qualityScores.length > 0 ? \n qualityScores.reduce((sum, score) => sum + score, 0) / qualityScores.length : 0;\n\n const commonPatterns = identifyCommonPatterns(sessions);\n const recommendations = generateAggregateRecommendations(sessions);\n\n return {\n filters,\n timestamp,\n totalSessions: sessions.length,\n successRate,\n averageQualityScore,\n commonPatterns,\n recommendations,\n };\n}\n\n/**\n * Export sessions in specified format\n */\nasync function exportSessions(\n sessions: QueryDevelopmentSession[],\n format: 'json' | 'html' | 'markdown'\n): Promise {\n const timestamp = new Date().toISOString();\n const filename = `session-export-${timestamp.replace(/[:.]/g, '-')}.${format}`;\n \n let content: string;\n \n switch (format) {\n case 'json':\n content = JSON.stringify(sessions, null, 2);\n break;\n case 'html':\n content = generateHTMLReport(sessions);\n break;\n case 'markdown':\n content = generateMarkdownReport(sessions);\n break;\n }\n\n return {\n format,\n filename,\n content,\n timestamp,\n };\n}\n\n/**\n * Utility functions\n */\n\nfunction getMostUsedTool(sessions: QueryDevelopmentSession[]): string {\n const toolCounts: Record = {};\n \n sessions.forEach(session => {\n session.mcpCalls.forEach(call => {\n toolCounts[call.toolName] = (toolCounts[call.toolName] || 0) + 1;\n });\n });\n\n return Object.entries(toolCounts)\n .sort(([, a], [, b]) => b - a)[0]?.[0] || 'none';\n}\n\nfunction identifyCommonPatterns(sessions: QueryDevelopmentSession[]): string[] {\n const patterns: string[] = [];\n \n const commonTools = getMostUsedTool(sessions);\n if (commonTools && commonTools !== 'none') {\n patterns.push(`Most commonly used tool: ${commonTools}`);\n }\n\n const completionRate = sessions.filter(s => s.status === 'completed').length / sessions.length;\n if (completionRate > 0.8) {\n patterns.push('High completion rate indicates effective workflow');\n } else if (completionRate < 0.5) {\n patterns.push('Low completion rate suggests workflow issues');\n }\n\n return patterns;\n}\n\nfunction generateAggregateRecommendations(sessions: QueryDevelopmentSession[]): string[] {\n const recommendations: string[] = [];\n \n const failedSessions = sessions.filter(s => s.status === 'failed');\n if (failedSessions.length > sessions.length * 0.3) {\n recommendations.push('High failure rate - consider improving error handling and guidance');\n }\n\n const averageCallsPerSession = sessions.reduce((sum, s) => sum + s.mcpCalls.length, 0) / sessions.length;\n if (averageCallsPerSession > 20) {\n recommendations.push('High number of MCP calls per session - consider workflow optimization');\n }\n\n return recommendations;\n}\n\nfunction generateHTMLReport(sessions: QueryDevelopmentSession[]): string {\n const html = `\n\n\n\n Session Export Report\n \n\n\n

Query Development Sessions Report

\n

Generated: ${new Date().toISOString()}

\n

Total Sessions: ${sessions.length}

\n \n ${sessions.map(session => `\n
\n

Session: ${session.sessionId}

\n

Query Path: ${session.queryPath}

\n

Status: ${session.status}

\n

Language: ${session.language}

\n

Start Time: ${session.startTime}

\n

MCP Calls: ${session.mcpCalls.length}

\n

Test Executions: ${session.testExecutions.length}

\n

Quality Scores: ${session.qualityScores.length}

\n
\n `).join('')}\n\n`;\n \n return html;\n}\n\nfunction generateMarkdownReport(sessions: QueryDevelopmentSession[]): string {\n const md = `# Query Development Sessions Report\n\nGenerated: ${new Date().toISOString()}\nTotal Sessions: ${sessions.length}\n\n## Session Summary\n\n| Session ID | Query Path | Status | Language | MCP Calls | Test Executions |\n|------------|-----------|--------|----------|-----------|-----------------|\n${sessions.map(session => \n `| ${session.sessionId} | ${session.queryPath} | ${session.status} | ${session.language} | ${session.mcpCalls.length} | ${session.testExecutions.length} |`\n).join('\\n')}\n\n## Detailed Sessions\n\n${sessions.map(session => `\n### Session: ${session.sessionId}\n\n- **Query Path:** ${session.queryPath}\n- **Status:** ${session.status}\n- **Language:** ${session.language}\n- **Start Time:** ${session.startTime}\n- **End Time:** ${session.endTime || 'N/A'}\n- **MCP Calls:** ${session.mcpCalls.length}\n- **Test Executions:** ${session.testExecutions.length}\n- **Quality Scores:** ${session.qualityScores.length}\n\n${session.recommendations.length > 0 ? `\n**Current Recommendations:**\n${session.recommendations.map(rec => `- ${rec}`).join('\\n')}\n` : ''}\n`).join('\\n')}`;\n\n return md;\n}\n\nfunction _calculateAverageDuration(sessions: QueryDevelopmentSession[]): number {\n const completedSessions = sessions.filter(s => s.endTime);\n if (completedSessions.length === 0) return 0;\n\n const totalDuration = completedSessions.reduce((sum, session) => {\n return sum + (new Date(session.endTime!).getTime() - new Date(session.startTime).getTime());\n }, 0);\n\n return totalDuration / completedSessions.length;\n}\n\nfunction _identifyFailureReasons(results: FunctionalTestResult[]): string[] {\n const failedResults = results.filter(r => !r.passed);\n const reasons: Record = {};\n\n failedResults.forEach(result => {\n Object.entries(result.criteria).forEach(([criterion, passed]) => {\n if (!passed) {\n reasons[criterion] = (reasons[criterion] || 0) + 1;\n }\n });\n });\n\n return Object.entries(reasons)\n .sort(([, a], [, b]) => b - a)\n .map(([reason, count]) => `${reason}: ${count} sessions`);\n}\n\n/**\n * Generate recommendations for MCP tool responses\n * Returns a map of MCP primitive paths to recommendation reasons\n */\nfunction generateRecommendations(\n session: QueryDevelopmentSession | null,\n currentTool: string\n): Record {\n if (!session) {\n return {};\n }\n\n const recommendations: Record = {};\n\n // Session state-based recommendations\n if (session.currentState.compilationStatus === 'failed') {\n recommendations['codeql_query_format'] = 'Format query to fix potential syntax issues';\n recommendations['codeql_query_compile'] = 'Recompile after fixing syntax errors';\n } else if (session.currentState.compilationStatus === 'success') {\n if (session.currentState.testStatus === 'unknown' || session.currentState.testStatus === 'no_tests') {\n recommendations['codeql_test_run'] = 'Run tests to validate query functionality';\n } else if (session.currentState.testStatus === 'failing') {\n recommendations['session_get_test_history'] = 'Review test failures to identify issues';\n recommendations['codeql_query_compile'] = 'Verify query logic matches test expectations';\n } else if (session.currentState.testStatus === 'passing') {\n recommendations['session_calculate_current_score'] = 'Calculate quality score for completed query';\n }\n }\n\n // Tool-specific follow-up recommendations\n switch (currentTool) {\n case 'session_get':\n if (session.mcpCalls.length === 0) {\n recommendations['codeql_query_compile'] = 'Start development by compiling the query';\n }\n break;\n case 'session_end':\n if (session.status === 'completed') {\n recommendations['sessions_export'] = 'Export session data for analysis';\n }\n break;\n case 'session_calculate_current_score': {\n const latestScore = session.qualityScores[session.qualityScores.length - 1];\n if (latestScore && latestScore.overallScore < 80) {\n if (latestScore.dimensions.syntacticCorrectness < 100) {\n recommendations['codeql_query_format'] = 'Improve syntax and formatting';\n }\n if (latestScore.dimensions.testCoverageResults < 70) {\n recommendations['codeql_test_run'] = 'Improve test coverage and results';\n }\n }\n break;\n }\n case 'session_update_state':\n // Recommend next logical step based on updated state\n if (session.currentState.compilationStatus === 'success' && session.currentState.testStatus === 'unknown') {\n recommendations['codeql_test_run'] = 'Run tests now that compilation is successful';\n }\n break;\n }\n\n return recommendations;\n}\n\n/**\n * Generate recommendations for session list results\n */\nfunction generateListRecommendations(sessions: QueryDevelopmentSession[]): Record {\n const recommendations: Record = {};\n\n const activeSessions = sessions.filter(s => s.status === 'active');\n const completedSessions = sessions.filter(s => s.status === 'completed');\n\n if (activeSessions.length > 0) {\n recommendations['session_get'] = `Review details of ${activeSessions.length} active session(s)`;\n }\n\n if (completedSessions.length > 1) {\n recommendations['sessions_compare'] = 'Compare completed sessions to identify patterns';\n recommendations['sessions_aggregate'] = 'Generate aggregate insights from multiple sessions';\n }\n\n if (sessions.length > 5) {\n recommendations['sessions_export'] = 'Export session data for comprehensive analysis';\n }\n\n return recommendations;\n}", "function checkArgs(adapter, defaultData) {\n if (adapter === undefined)\n throw new Error('lowdb: missing adapter');\n if (defaultData === undefined)\n throw new Error('lowdb: missing default data');\n}\nexport class Low {\n adapter;\n data;\n constructor(adapter, defaultData) {\n checkArgs(adapter, defaultData);\n this.adapter = adapter;\n this.data = defaultData;\n }\n async read() {\n const data = await this.adapter.read();\n if (data)\n this.data = data;\n }\n async write() {\n if (this.data)\n await this.adapter.write(this.data);\n }\n async update(fn) {\n fn(this.data);\n await this.write();\n }\n}\nexport class LowSync {\n adapter;\n data;\n constructor(adapter, defaultData) {\n checkArgs(adapter, defaultData);\n this.adapter = adapter;\n this.data = defaultData;\n }\n read() {\n const data = this.adapter.read();\n if (data)\n this.data = data;\n }\n write() {\n if (this.data)\n this.adapter.write(this.data);\n }\n update(fn) {\n fn(this.data);\n this.write();\n }\n}\n", "import { readFileSync, renameSync, writeFileSync } from 'node:fs';\nimport { readFile } from 'node:fs/promises';\nimport path from 'node:path';\nimport { Writer } from 'steno';\nexport class TextFile {\n #filename;\n #writer;\n constructor(filename) {\n this.#filename = filename;\n this.#writer = new Writer(filename);\n }\n async read() {\n let data;\n try {\n data = await readFile(this.#filename, 'utf-8');\n }\n catch (e) {\n if (e.code === 'ENOENT') {\n return null;\n }\n throw e;\n }\n return data;\n }\n write(str) {\n return this.#writer.write(str);\n }\n}\nexport class TextFileSync {\n #tempFilename;\n #filename;\n constructor(filename) {\n this.#filename = filename;\n const f = filename.toString();\n this.#tempFilename = path.join(path.dirname(f), `.${path.basename(f)}.tmp`);\n }\n read() {\n let data;\n try {\n data = readFileSync(this.#filename, 'utf-8');\n }\n catch (e) {\n if (e.code === 'ENOENT') {\n return null;\n }\n throw e;\n }\n return data;\n }\n write(str) {\n writeFileSync(this.#tempFilename, str);\n renameSync(this.#tempFilename, this.#filename);\n }\n}\n", "import { TextFile, TextFileSync } from './TextFile.js';\nexport class DataFile {\n #adapter;\n #parse;\n #stringify;\n constructor(filename, { parse, stringify, }) {\n this.#adapter = new TextFile(filename);\n this.#parse = parse;\n this.#stringify = stringify;\n }\n async read() {\n const data = await this.#adapter.read();\n if (data === null) {\n return null;\n }\n else {\n return this.#parse(data);\n }\n }\n write(obj) {\n return this.#adapter.write(this.#stringify(obj));\n }\n}\nexport class DataFileSync {\n #adapter;\n #parse;\n #stringify;\n constructor(filename, { parse, stringify, }) {\n this.#adapter = new TextFileSync(filename);\n this.#parse = parse;\n this.#stringify = stringify;\n }\n read() {\n const data = this.#adapter.read();\n if (data === null) {\n return null;\n }\n else {\n return this.#parse(data);\n }\n }\n write(obj) {\n this.#adapter.write(this.#stringify(obj));\n }\n}\n", "import { DataFile, DataFileSync } from './DataFile.js';\nexport class JSONFile extends DataFile {\n constructor(filename) {\n super(filename, {\n parse: JSON.parse,\n stringify: (data) => JSON.stringify(data, null, 2),\n });\n }\n}\nexport class JSONFileSync extends DataFileSync {\n constructor(filename) {\n super(filename, {\n parse: JSON.parse,\n stringify: (data) => JSON.stringify(data, null, 2),\n });\n }\n}\n", "/**\n * Session Data Management\n * Provides unified JSON storage and session lifecycle management using lowdb\n */\n\nimport { Low } from 'lowdb';\nimport { JSONFileSync } from 'lowdb/node';\nimport { mkdirSync, writeFileSync } from 'fs';\nimport { join } from 'path';\nimport { randomUUID } from 'crypto';\nimport { getProjectTmpBase } from '../utils/temp-dir';\nimport {\n QueryDevelopmentSession,\n QueryState,\n MCPCallRecord,\n TestExecutionRecord,\n QualityScoreRecord,\n SessionFilter,\n MonitoringConfig,\n MonitoringConfigSchema,\n} from '../types/monitoring';\nimport { logger } from '../utils/logger';\n\n/**\n * Database schema for lowdb - sessions only\n */\ninterface SessionDatabase {\n sessions: QueryDevelopmentSession[];\n}\n\n/**\n * Session Data Manager - handles all session persistence and lifecycle\n */\nexport class SessionDataManager {\n private db: Low;\n private config: MonitoringConfig;\n private storageDir: string;\n\n constructor(configOverrides: Partial = {}) {\n this.config = MonitoringConfigSchema.parse({\n ...MonitoringConfigSchema.parse({}),\n ...configOverrides,\n });\n\n this.storageDir = this.config.storageLocation;\n this.ensureStorageDirectory();\n\n const adapter = new JSONFileSync(join(this.storageDir, 'sessions.json'));\n this.db = new Low(adapter, {\n sessions: [],\n });\n\n this.initializeDatabase();\n }\n\n /**\n * Initialize the database and ensure it's properly set up\n */\n async initialize(): Promise {\n await this.initializeDatabase();\n }\n\n /**\n * Initialize the database and ensure it's properly set up\n */\n private async initializeDatabase(): Promise {\n try {\n await this.db.read();\n \n logger.info(`Session data manager initialized with ${this.db.data.sessions.length} sessions`);\n } catch (error) {\n logger.error('Failed to initialize session database:', error);\n throw error;\n }\n }\n\n /**\n * Ensure storage directory structure exists\n */\n private ensureStorageDirectory(): void {\n try {\n // mkdirSync with recursive: true is a no-op if directories already exist\n mkdirSync(this.storageDir, { recursive: true });\n\n // Create subdirectories\n const subdirs = ['sessions-archive', 'exports'];\n for (const subdir of subdirs) {\n mkdirSync(join(this.storageDir, subdir), { recursive: true });\n }\n\n // Use 'wx' flag (exclusive create) to atomically create config only\n // if it doesn't exist, avoiding TOCTOU race (CWE-367).\n const configPath = join(this.storageDir, 'config.json');\n try {\n writeFileSync(configPath, JSON.stringify(this.config, null, 2), { flag: 'wx' });\n } catch (e: unknown) {\n const err = e as { code?: string };\n if (err.code !== 'EEXIST') throw e;\n }\n\n logger.debug(`Storage directory initialized: ${this.storageDir}`);\n } catch (error) {\n logger.error('Failed to create storage directory:', error);\n throw error;\n }\n }\n\n /**\n * Start a new query development session\n */\n async startSession(\n queryPath: string,\n language?: string,\n queryType?: string,\n description?: string\n ): Promise {\n const sessionId = randomUUID();\n const startTime = new Date().toISOString();\n\n const session: QueryDevelopmentSession = {\n sessionId,\n queryPath,\n language: language || 'unknown',\n queryType,\n description,\n startTime,\n status: 'active',\n mcpCalls: [],\n testExecutions: [],\n qualityScores: [],\n currentState: {\n filesPresent: [],\n compilationStatus: 'unknown',\n testStatus: 'unknown',\n documentationStatus: 'unknown',\n lastActivity: startTime,\n },\n recommendations: [],\n };\n\n await this.db.read();\n this.db.data.sessions.push(session);\n await this.db.write();\n\n logger.info(`Started new session: ${sessionId} for query: ${queryPath}`);\n return sessionId;\n }\n\n /**\n * End a session with final status\n */\n async endSession(\n sessionId: string,\n status: 'completed' | 'failed' | 'abandoned'\n ): Promise {\n await this.db.read();\n \n const session = this.db.data.sessions.find(s => s.sessionId === sessionId);\n if (!session) {\n logger.warn(`Session not found: ${sessionId}`);\n return null;\n }\n\n session.status = status;\n session.endTime = new Date().toISOString();\n session.currentState.lastActivity = session.endTime;\n\n await this.db.write();\n\n // Archive completed session if enabled\n if (this.config.archiveCompletedSessions && status === 'completed') {\n await this.archiveSession(sessionId);\n }\n\n logger.info(`Ended session: ${sessionId} with status: ${status}`);\n return session;\n }\n\n /**\n * Get a specific session by ID\n */\n async getSession(sessionId: string): Promise {\n await this.db.read();\n const session = this.db.data.sessions.find(s => s.sessionId === sessionId);\n return session || null;\n }\n\n /**\n * List sessions with optional filtering\n */\n async listSessions(filters?: SessionFilter): Promise {\n await this.db.read();\n let sessions = [...this.db.data.sessions];\n\n if (filters) {\n if (filters.queryPath) {\n sessions = sessions.filter(s => s.queryPath.includes(filters.queryPath!));\n }\n if (filters.status) {\n sessions = sessions.filter(s => s.status === filters.status);\n }\n if (filters.language) {\n sessions = sessions.filter(s => s.language === filters.language);\n }\n if (filters.queryType) {\n sessions = sessions.filter(s => s.queryType === filters.queryType);\n }\n if (filters.dateRange) {\n const [start, end] = filters.dateRange;\n sessions = sessions.filter(s => \n s.startTime >= start && s.startTime <= end\n );\n }\n }\n\n return sessions;\n }\n\n /**\n * Update session state\n */\n async updateSessionState(\n sessionId: string,\n stateUpdate: Partial\n ): Promise {\n await this.db.read();\n \n const session = this.db.data.sessions.find(s => s.sessionId === sessionId);\n if (!session) {\n logger.warn(`Session not found: ${sessionId}`);\n return null;\n }\n\n session.currentState = {\n ...session.currentState,\n ...stateUpdate,\n lastActivity: new Date().toISOString(),\n };\n\n await this.db.write();\n return session;\n }\n\n /**\n * Add MCP call record to session\n */\n async addMCPCall(sessionId: string, callRecord: MCPCallRecord): Promise {\n await this.db.read();\n \n const session = this.db.data.sessions.find(s => s.sessionId === sessionId);\n if (!session) {\n logger.warn(`Session not found for MCP call: ${sessionId}`);\n return;\n }\n\n session.mcpCalls.push(callRecord);\n session.currentState.lastActivity = callRecord.timestamp;\n\n // Update next suggested tool if provided\n if (callRecord.nextSuggestedTool) {\n session.nextSuggestedTool = callRecord.nextSuggestedTool;\n }\n\n await this.db.write();\n }\n\n /**\n * Add test execution record to session\n */\n async addTestExecution(sessionId: string, testRecord: TestExecutionRecord): Promise {\n await this.db.read();\n \n const session = this.db.data.sessions.find(s => s.sessionId === sessionId);\n if (!session) {\n logger.warn(`Session not found for test execution: ${sessionId}`);\n return;\n }\n\n session.testExecutions.push(testRecord);\n session.currentState.lastActivity = testRecord.timestamp;\n\n // Update compilation/test status based on execution\n if (testRecord.type === 'compilation') {\n session.currentState.compilationStatus = testRecord.success ? 'success' : 'failed';\n } else if (testRecord.type === 'test_run') {\n session.currentState.testStatus = testRecord.success ? 'passing' : 'failing';\n }\n\n await this.db.write();\n }\n\n /**\n * Add quality score record to session\n */\n async addQualityScore(sessionId: string, scoreRecord: QualityScoreRecord): Promise {\n await this.db.read();\n \n const session = this.db.data.sessions.find(s => s.sessionId === sessionId);\n if (!session) {\n logger.warn(`Session not found for quality score: ${sessionId}`);\n return;\n }\n\n session.qualityScores.push(scoreRecord);\n session.currentState.lastActivity = scoreRecord.timestamp;\n session.recommendations = scoreRecord.recommendations;\n\n await this.db.write();\n }\n\n /**\n * Archive a completed session to monthly file\n */\n private async archiveSession(sessionId: string): Promise {\n try {\n const session = await this.getSession(sessionId);\n if (!session) return;\n\n const date = new Date(session.endTime || session.startTime);\n const monthDir = `${date.getFullYear()}-${String(date.getMonth() + 1).padStart(2, '0')}`;\n const archiveDir = join(this.storageDir, 'sessions-archive', monthDir);\n\n mkdirSync(archiveDir, { recursive: true });\n\n const archiveFile = join(archiveDir, `${sessionId}.json`);\n writeFileSync(archiveFile, JSON.stringify(session, null, 2));\n\n // Remove from active sessions\n await this.db.read();\n this.db.data.sessions = this.db.data.sessions.filter(s => s.sessionId !== sessionId);\n await this.db.write();\n\n logger.info(`Archived session: ${sessionId} to ${archiveFile}`);\n } catch (error) {\n logger.error(`Failed to archive session ${sessionId}:`, error);\n }\n }\n\n /**\n * Get active sessions for a specific query path\n */\n async getActiveSessionsForQuery(queryPath: string): Promise {\n await this.db.read();\n return this.db.data.sessions.filter(s => \n s.queryPath === queryPath && s.status === 'active'\n );\n }\n\n /**\n * Clean up old sessions based on retention policy\n */\n async cleanupOldSessions(): Promise {\n const cutoffDate = new Date();\n cutoffDate.setDate(cutoffDate.getDate() - this.config.retentionDays);\n const cutoffTimestamp = cutoffDate.toISOString();\n\n await this.db.read();\n const sessionsToRemove = this.db.data.sessions.filter(s => \n s.endTime && s.endTime < cutoffTimestamp\n );\n\n if (sessionsToRemove.length > 0) {\n this.db.data.sessions = this.db.data.sessions.filter(s => \n !s.endTime || s.endTime >= cutoffTimestamp\n );\n await this.db.write();\n\n logger.info(`Cleaned up ${sessionsToRemove.length} old sessions`);\n }\n }\n\n /**\n * Get configuration\n */\n getConfig(): MonitoringConfig {\n return this.config;\n }\n\n /**\n * Update configuration\n */\n async updateConfig(configUpdate: Partial): Promise {\n this.config = MonitoringConfigSchema.parse({\n ...this.config,\n ...configUpdate,\n });\n\n // Update config.json file only\n const configPath = join(this.storageDir, 'config.json');\n writeFileSync(configPath, JSON.stringify(this.config, null, 2));\n\n logger.info('Updated monitoring configuration');\n }\n}\n\n/**\n * Parse boolean environment variable\n */\nfunction parseBoolEnv(envVar: string | undefined, defaultValue: boolean): boolean {\n if (envVar === undefined) return defaultValue;\n return envVar.toLowerCase() === 'true' || envVar === '1';\n}\n\n// Export singleton instance with environment variable support\nexport const sessionDataManager = new SessionDataManager({\n storageLocation: process.env.MONITORING_STORAGE_LOCATION || join(getProjectTmpBase(), '.ql-mcp-tracking'),\n enableMonitoringTools: parseBoolEnv(process.env.ENABLE_MONITORING_TOOLS, false),\n});", "import { z } from 'zod';\n\n/**\n * Monitoring and Reporting types for CodeQL Development MCP Server\n * Based on the specification in docs/mcp-server-monitoring-and-reporting.md\n */\n\n/**\n * MCP Call Record - captures individual MCP tool calls\n */\nexport const MCPCallRecordSchema = z.object({\n callId: z.string(),\n timestamp: z.string(), // ISO timestamp\n toolName: z.string(),\n parameters: z.record(z.any()),\n result: z.any(),\n success: z.boolean(),\n duration: z.number(), // milliseconds\n nextSuggestedTool: z.string().optional(),\n});\n\nexport type MCPCallRecord = z.infer;\n\n/**\n * Test Execution Record - captures query compilation and test runs\n */\nexport const TestExecutionRecordSchema = z.object({\n executionId: z.string(),\n timestamp: z.string(),\n type: z.enum(['compilation', 'test_run', 'database_build']),\n success: z.boolean(),\n details: z.record(z.any()),\n metrics: z.object({\n passRate: z.number().optional(),\n coverage: z.number().optional(),\n performance: z.number().optional(),\n }).optional(),\n});\n\nexport type TestExecutionRecord = z.infer;\n\n/**\n * Quality Score Record - multi-dimensional quality assessment\n */\nexport const QualityScoreRecordSchema = z.object({\n scoreId: z.string(),\n timestamp: z.string(),\n overallScore: z.number().min(0).max(100), // 0-100\n dimensions: z.object({\n syntacticCorrectness: z.number().min(0).max(100),\n testCoverageResults: z.number().min(0).max(100),\n documentationQuality: z.number().min(0).max(100),\n functionalCorrectness: z.number().min(0).max(100),\n }),\n grade: z.enum(['A', 'B', 'C', 'D', 'F']),\n recommendations: z.array(z.string()),\n});\n\nexport type QualityScoreRecord = z.infer;\n\n/**\n * Query State - current state of the query development\n */\nexport const QueryStateSchema = z.object({\n filesPresent: z.array(z.string()),\n compilationStatus: z.enum(['unknown', 'success', 'failed']),\n testStatus: z.enum(['unknown', 'passing', 'failing', 'no_tests']),\n documentationStatus: z.enum(['unknown', 'present', 'missing', 'incomplete']),\n lastActivity: z.string(), // ISO timestamp\n});\n\nexport type QueryState = z.infer;\n\n/**\n * Query Development Session - main data structure for tracking\n */\nexport const QueryDevelopmentSessionSchema = z.object({\n // Session Metadata\n sessionId: z.string(),\n queryPath: z.string(),\n language: z.string(),\n queryType: z.string().optional(),\n description: z.string().optional(),\n startTime: z.string(), // ISO timestamp\n endTime: z.string().optional(), // ISO timestamp\n status: z.enum(['active', 'completed', 'failed', 'abandoned']),\n\n // MCP Call History\n mcpCalls: z.array(MCPCallRecordSchema),\n\n // Test Execution Records\n testExecutions: z.array(TestExecutionRecordSchema),\n\n // Quality Metrics\n qualityScores: z.array(QualityScoreRecordSchema),\n\n // Development State\n currentState: QueryStateSchema,\n recommendations: z.array(z.string()),\n nextSuggestedTool: z.string().optional(),\n});\n\nexport type QueryDevelopmentSession = z.infer;\n\n/**\n * Session Filter for listing and searching\n */\nexport const SessionFilterSchema = z.object({\n queryPath: z.string().optional(),\n status: z.string().optional(),\n dateRange: z.tuple([z.string(), z.string()]).optional(),\n language: z.string().optional(),\n queryType: z.string().optional(),\n});\n\nexport type SessionFilter = z.infer;\n\n/**\n * Comparison Report for analyzing multiple sessions\n */\nexport const ComparisonReportSchema = z.object({\n sessionIds: z.array(z.string()),\n dimensions: z.array(z.string()),\n timestamp: z.string(),\n results: z.record(z.any()),\n});\n\nexport type ComparisonReport = z.infer;\n\n/**\n * Aggregate Report for batch analysis\n */\nexport const AggregateReportSchema = z.object({\n filters: SessionFilterSchema,\n timestamp: z.string(),\n totalSessions: z.number(),\n successRate: z.number(),\n averageQualityScore: z.number(),\n commonPatterns: z.array(z.string()),\n recommendations: z.array(z.string()),\n});\n\nexport type AggregateReport = z.infer;\n\n/**\n * Export Result for data export operations\n */\nexport const ExportResultSchema = z.object({\n format: z.enum(['json', 'html', 'markdown']),\n filename: z.string(),\n content: z.string(),\n timestamp: z.string(),\n});\n\nexport type ExportResult = z.infer;\n\n/**\n * Functional Test Result for automated testing\n */\nexport const FunctionalTestResultSchema = z.object({\n sessionId: z.string(),\n queryPath: z.string(),\n passed: z.boolean(),\n criteria: z.record(z.any()),\n details: z.record(z.any()),\n timestamp: z.string(),\n});\n\nexport type FunctionalTestResult = z.infer;\n\n/**\n * Test Report for comprehensive test analysis\n */\nexport const TestReportSchema = z.object({\n sessionIds: z.array(z.string()),\n criteria: z.record(z.any()),\n timestamp: z.string(),\n overallPassRate: z.number(),\n results: z.array(FunctionalTestResultSchema),\n summary: z.record(z.any()),\n});\n\nexport type TestReport = z.infer;\n\n/**\n * Monitoring Configuration\n */\nexport const MonitoringConfigSchema = z.object({\n storageLocation: z.string().default('.ql-mcp-tracking/'),\n autoTrackSessions: z.boolean().default(true),\n retentionDays: z.number().default(90),\n includeCallParameters: z.boolean().default(true),\n includeCallResults: z.boolean().default(true),\n maxActiveSessionsPerQuery: z.number().default(3),\n scoringFrequency: z.enum(['per_call', 'periodic', 'manual']).default('per_call'),\n archiveCompletedSessions: z.boolean().default(true),\n enableRecommendations: z.boolean().default(true),\n enableMonitoringTools: z.boolean().default(false), // Opt-in: session_* tools disabled by default for end-users\n});\n\nexport type MonitoringConfig = z.infer;"], - "mappings": "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", + "sourcesContent": ["/**\n * Simple logger utility.\n *\n * All log output is written to stderr. In stdio transport mode, stdout is\n * reserved exclusively for the MCP JSON-RPC protocol \u2014 any non-protocol\n * bytes on stdout would corrupt the message stream.\n */\nexport const logger = {\n info: (message: string, ...args: unknown[]) => {\n console.error(`[INFO] ${new Date().toISOString()} ${message}`, ...args);\n },\n error: (message: string, ...args: unknown[]) => {\n console.error(`[ERROR] ${new Date().toISOString()} ${message}`, ...args);\n },\n warn: (message: string, ...args: unknown[]) => {\n console.error(`[WARN] ${new Date().toISOString()} ${message}`, ...args);\n },\n debug: (message: string, ...args: unknown[]) => {\n if (process.env.DEBUG) {\n console.error(`[DEBUG] ${new Date().toISOString()} ${message}`, ...args);\n }\n },\n};\n", "/**\n * Configuration types for CodeQL background server processes.\n *\n * CodeQL provides three background server types:\n * 1. language-server \u2013 LSP-based QL validation (JSON-RPC over stdio)\n * 2. query-server2 \u2013 Query evaluation (custom protocol over stdio)\n * 3. cli-server \u2013 JVM reuse for CLI commands (custom protocol over stdio)\n *\n * Each server type has its own configuration options, but they share common\n * settings like searchPath and commonCaches.\n */\n\nimport { createHash } from 'crypto';\n\n/**\n * Server types supported by CodeQL.\n */\nexport type CodeQLServerType = 'cli' | 'language' | 'query';\n\n/**\n * Common configuration shared across all server types.\n */\nexport interface BaseServerConfig {\n /** Path to QL packs (like `codeql query compile --search-path`). */\n searchPath?: string;\n /** Location for cached data (compilation plans, downloaded packs). */\n commonCaches?: string;\n /** Directory for detailed logs. */\n logdir?: string;\n}\n\n/**\n * Configuration for the CodeQL Language Server.\n */\nexport interface LanguageServerConfig extends BaseServerConfig {\n /** Error checking mode. Default: ON_CHANGE */\n checkErrors?: 'EXPLICIT' | 'ON_CHANGE';\n /** Log level for the language server. */\n loglevel?: 'ALL' | 'DEBUG' | 'ERROR' | 'INFO' | 'OFF' | 'TRACE' | 'WARN';\n /** Single-threaded execution. */\n synchronous?: boolean;\n /** Verbosity level for progress. */\n verbosity?: 'errors' | 'progress' | 'progress+' | 'progress++' | 'progress+++' | 'warnings';\n}\n\n/**\n * Configuration for the CodeQL Query Server (query-server2).\n */\nexport interface QueryServerConfig extends BaseServerConfig {\n /** Thread count. 0 = one per core, -N = leave N cores free. */\n threads?: number;\n /** Query evaluation timeout in seconds. */\n timeout?: number;\n /** Maximum disk cache size in MB for intermediate results. */\n maxDiskCache?: number;\n /** Path for structured evaluator performance logs. */\n evaluatorLog?: string;\n /** Include tuple counts in evaluation logs. */\n tupleCounting?: boolean;\n /** Enable debug mode. */\n debug?: boolean;\n}\n\n/**\n * Configuration for the CodeQL CLI Server.\n */\nexport interface CLIServerConfig extends BaseServerConfig {\n // cli-server has fewer options \u2014 just commonCaches and logdir.\n}\n\n/**\n * Union of all server configurations (discriminated by usage context).\n */\nexport type ServerConfig = CLIServerConfig | LanguageServerConfig | QueryServerConfig;\n\n/**\n * Compute a deterministic hash for a server configuration.\n * Used to detect configuration changes that require a server restart.\n *\n * @param type - The server type.\n * @param config - The server configuration.\n * @returns A hex-encoded SHA-256 hash of the canonical JSON representation.\n */\nexport function computeConfigHash(type: CodeQLServerType, config: ServerConfig): string {\n // Deep-sort all keys to ensure deterministic serialization regardless of\n // property insertion order.\n const sortKeys = (_key: string, value: unknown): unknown => {\n if (value && typeof value === 'object' && !Array.isArray(value)) {\n const sorted: Record = {};\n for (const k of Object.keys(value as Record).sort()) {\n sorted[k] = (value as Record)[k];\n }\n return sorted;\n }\n return value;\n };\n const canonical = JSON.stringify({ config, type }, sortKeys);\n return createHash('sha256').update(canonical).digest('hex');\n}\n\n/**\n * Build command-line arguments for a language server from its configuration.\n */\nexport function buildLanguageServerArgs(config: LanguageServerConfig): string[] {\n const args: string[] = [\n 'execute', 'language-server',\n `--check-errors=${config.checkErrors ?? 'ON_CHANGE'}`,\n ];\n\n if (config.searchPath) {\n args.push(`--search-path=${config.searchPath}`);\n }\n if (config.commonCaches) {\n args.push(`--common-caches=${config.commonCaches}`);\n }\n if (config.logdir) {\n args.push(`--logdir=${config.logdir}`);\n }\n if (config.loglevel) {\n args.push(`--loglevel=${config.loglevel}`);\n }\n if (config.synchronous) {\n args.push('--synchronous');\n }\n if (config.verbosity) {\n args.push(`--verbosity=${config.verbosity}`);\n }\n\n return args;\n}\n\n/**\n * Build command-line arguments for a query server from its configuration.\n */\nexport function buildQueryServerArgs(config: QueryServerConfig): string[] {\n const args: string[] = [\n 'execute', 'query-server2',\n ];\n\n if (config.searchPath) {\n args.push(`--search-path=${config.searchPath}`);\n }\n if (config.commonCaches) {\n args.push(`--common-caches=${config.commonCaches}`);\n }\n if (config.logdir) {\n args.push(`--logdir=${config.logdir}`);\n }\n if (config.threads !== undefined) {\n args.push(`--threads=${config.threads}`);\n }\n if (config.timeout !== undefined) {\n args.push(`--timeout=${config.timeout}`);\n }\n if (config.maxDiskCache !== undefined) {\n args.push(`--max-disk-cache=${config.maxDiskCache}`);\n }\n if (config.evaluatorLog) {\n args.push(`--evaluator-log=${config.evaluatorLog}`);\n }\n if (config.debug) {\n args.push('--debug');\n args.push('--tuple-counting');\n } else if (config.tupleCounting) {\n args.push('--tuple-counting');\n }\n\n return args;\n}\n\n/**\n * Build command-line arguments for a CLI server from its configuration.\n */\nexport function buildCLIServerArgs(config: CLIServerConfig): string[] {\n const args: string[] = [\n 'execute', 'cli-server',\n ];\n\n if (config.commonCaches) {\n args.push(`--common-caches=${config.commonCaches}`);\n }\n if (config.logdir) {\n args.push(`--logdir=${config.logdir}`);\n }\n\n return args;\n}\n", "/**\n * Utilities for resolving filesystem paths relative to the server package root.\n *\n * The server can run from three different directory layouts:\n *\n * 1. **Source** (dev): `server/src/lib/` \u2192 packageRoot = `server/`\n * 2. **Bundle in monorepo** (dev/CI): `server/dist/` \u2192 packageRoot = `server/`\n * 3. **Bundle via npm** (production): `/dist/` \u2192 packageRoot = `/`\n *\n * In all three cases, the bundled QL tool query packs live at\n * `/ql//tools/src/`.\n *\n * The \"workspace root\" (monorepo root) is one level above packageRoot when\n * running from the monorepo checkout, and the packageRoot itself when running\n * from an npm install (no parent monorepo).\n */\n\nimport { dirname, resolve } from 'path';\nimport { existsSync, readFileSync } from 'fs';\nimport { fileURLToPath } from 'url';\n\nconst __filename = fileURLToPath(import.meta.url);\nconst __dirname = dirname(__filename);\n\n/**\n * Detect whether the current __dirname looks like source code (`src/lib` or\n * `src/utils`) vs a bundled flat output directory (`dist/`).\n *\n * Uses a tail-of-path check so that unrelated `/src/` segments earlier in the\n * install path (e.g. `~/src/project/node_modules/.../dist`) don't cause a\n * false positive.\n */\nfunction isRunningFromSource(dir: string): boolean {\n const normalized = dir.replace(/\\\\/g, '/');\n return /\\/src(\\/[^/]+)?$/.test(normalized);\n}\n\n/**\n * Get the server package root directory.\n *\n * - From source (`server/src/utils/`): up 2 levels \u2192 `server/`\n * - From bundle (`server/dist/` or `/dist/`): up 1 level \u2192 package root\n */\nexport function getPackageRootDir(currentDir: string = __dirname): string {\n return isRunningFromSource(currentDir)\n ? resolve(currentDir, '..', '..') // src/utils \u2192 server/\n : resolve(currentDir, '..'); // dist/ \u2192 package root\n}\n\n/**\n * Get the workspace root directory (monorepo root when applicable).\n *\n * If a `package.json` with `workspaces` exists one level above the package\n * root, we're in a monorepo and that parent is the workspace root. Otherwise,\n * the packageRoot itself is the workspace root (npm install scenario).\n */\nexport function getWorkspaceRootDir(packageRoot?: string): string {\n const pkgRoot = packageRoot ?? getPackageRootDir();\n const parentDir = resolve(pkgRoot, '..');\n\n // In the monorepo, the parent directory contains a package.json with workspaces\n try {\n const parentPkgPath = resolve(parentDir, 'package.json');\n if (existsSync(parentPkgPath)) {\n const parentPkg = JSON.parse(readFileSync(parentPkgPath, 'utf8'));\n if (parentPkg.workspaces) {\n return parentDir;\n }\n }\n } catch {\n // Not in a monorepo \u2014 fall through\n }\n\n return pkgRoot;\n}\n\n/**\n * Resolve the path to a tool query pack's source directory.\n *\n * @param language - CodeQL language identifier (e.g., \"javascript\", \"cpp\")\n * @param packageRoot - Override the package root (for testing)\n * @returns Absolute path to `ql//tools/src/`\n */\nexport function resolveToolQueryPackPath(language: string, packageRoot?: string): string {\n const pkgRoot = packageRoot ?? getPackageRootDir();\n return resolve(pkgRoot, 'ql', language, 'tools', 'src');\n}\n\n/**\n * Read the package version from the nearest package.json.\n *\n * Cached at first call so the file is read at most once per process.\n */\nlet _cachedVersion: string | undefined;\nexport function getPackageVersion(): string {\n if (_cachedVersion !== undefined) return _cachedVersion;\n try {\n const pkgPath = resolve(getPackageRootDir(), 'package.json');\n const pkg = JSON.parse(readFileSync(pkgPath, 'utf8'));\n _cachedVersion = pkg.version ?? '0.0.0';\n } catch {\n _cachedVersion = '0.0.0';\n }\n return _cachedVersion as string;\n}\n\n/**\n * Get the effective workspace directory for resolving user-supplied relative\n * paths (test directories, database paths, pack dirs, etc.).\n *\n * In a monorepo checkout the workspace root is the monorepo parent. In an\n * npm-installed layout, `workspaceRootDir` falls back to `packageRootDir`\n * which may be read-only and is not the user's project. In that case we\n * fall back to `process.cwd()` so that relative paths resolve against the\n * directory the user actually invoked the server from.\n *\n * Override with `CODEQL_MCP_WORKSPACE` for deterministic behavior.\n */\nexport function getUserWorkspaceDir(): string {\n if (process.env.CODEQL_MCP_WORKSPACE) {\n return process.env.CODEQL_MCP_WORKSPACE;\n }\n // When workspaceRootDir === packageRootDir we are NOT in a monorepo\n // (npm-installed), so fall back to process.cwd().\n if (workspaceRootDir === packageRootDir) {\n return process.cwd();\n }\n return workspaceRootDir;\n}\n\n// Pre-computed values for use throughout the server\nexport const packageRootDir = getPackageRootDir();\nexport const workspaceRootDir = getWorkspaceRootDir(packageRootDir);\n", "/**\n * Secure project-local temporary directory utilities.\n *\n * All temporary files are created under `/.tmp/` which is\n * `.gitignore`d. This avoids writing to the OS temp directory\n * (`os.tmpdir()` / `/tmp`), which is world-readable and triggers\n * CWE-377 / CWE-378 (js/insecure-temporary-file).\n */\n\nimport { mkdirSync, mkdtempSync } from 'fs';\nimport { isAbsolute, join, resolve } from 'path';\nimport { getPackageRootDir } from './package-paths';\n\n/**\n * Base directory for all project-local temporary data.\n *\n * Resolution order:\n * 1. `CODEQL_MCP_TMP_DIR` environment variable \u2014 for read-only package root\n * scenarios (e.g., npm global installs where the package directory is not\n * writable). Relative paths are resolved against process.cwd().\n * 2. `/.tmp` \u2014 default; excluded from version control.\n */\nconst PROJECT_TMP_BASE = process.env.CODEQL_MCP_TMP_DIR\n ? (isAbsolute(process.env.CODEQL_MCP_TMP_DIR) \n ? process.env.CODEQL_MCP_TMP_DIR \n : resolve(process.cwd(), process.env.CODEQL_MCP_TMP_DIR))\n : join(getPackageRootDir(), '.tmp');\n\n/**\n * Return the project-local `.tmp` base directory, creating it if needed.\n */\nexport function getProjectTmpBase(): string {\n mkdirSync(PROJECT_TMP_BASE, { recursive: true });\n return PROJECT_TMP_BASE;\n}\n\n/**\n * Create a unique temporary directory under the project `.tmp` root.\n *\n * Works identically to `fs.mkdtempSync(os.tmpdir(), prefix)` but is\n * scoped to the repository.\n *\n * @param prefix - Directory name prefix (e.g. `'codeql-external-'`).\n * @returns Absolute path to the newly created directory.\n */\nexport function createProjectTempDir(prefix: string): string {\n const base = getProjectTmpBase();\n return mkdtempSync(join(base, prefix));\n}\n\n/**\n * Return a deterministic subdirectory under `.tmp/`, creating it\n * if it does not already exist.\n *\n * Useful for well-known scratch areas such as `query-logs` or `quickeval`.\n *\n * @param name - Subdirectory name (e.g. `'query-logs'`).\n * @returns Absolute path to the subdirectory.\n */\nexport function getProjectTmpDir(name: string): string {\n const dir = join(getProjectTmpBase(), name);\n mkdirSync(dir, { recursive: true });\n return dir;\n}\n", "/**\n * Utility for waiting until a spawned child process is ready.\n *\n * CodeQL background servers (cli-server, query-server2, language-server) run\n * on the JVM and emit stderr log output once the JVM has initialised. Rather\n * than sleeping for a hard-coded duration \u2014 which is fragile on both fast and\n * slow machines \u2014 this helper resolves as soon as the first stderr output\n * arrives (indicating the JVM is alive), or when the maximum timeout expires.\n * It also rejects immediately if the process exits or errors before becoming\n * ready, giving callers a clear error instead of a silent hang.\n */\n\nimport { ChildProcess } from 'child_process';\nimport { clearTimeout, setTimeout } from 'timers';\nimport { logger } from './logger';\n\n/** Default maximum wait for a CodeQL server to become ready (30 s). */\nconst DEFAULT_READY_TIMEOUT_MS = 30_000;\n\n/**\n * Options for {@link waitForProcessReady}.\n */\nexport interface ProcessReadyOptions {\n /**\n * Maximum time in milliseconds to wait for the process to emit its first\n * stderr output. If the timeout is reached without a signal the promise\n * still resolves (best-effort) so the caller can attempt communication.\n *\n * Default: 30 000 ms.\n */\n timeoutMs?: number;\n}\n\n/**\n * Wait until a child process signals readiness.\n *\n * \"Ready\" is defined as any of:\n * 1. The process emits data on **stderr** (JVM startup log line).\n * 2. The process emits data on **stdout** (initial protocol message).\n * 3. The maximum timeout elapses (best-effort resolve).\n *\n * The promise **rejects** if the process emits an `error` event or exits\n * before any of the above conditions are met.\n *\n * @param child - The spawned child process.\n * @param name - A human-readable label for log messages.\n * @param opts - Optional configuration.\n */\nexport function waitForProcessReady(\n child: ChildProcess,\n name: string,\n opts?: ProcessReadyOptions,\n): Promise {\n const timeoutMs = opts?.timeoutMs ?? DEFAULT_READY_TIMEOUT_MS;\n\n return new Promise((resolve, reject) => {\n let settled = false;\n\n const cleanup = () => {\n settled = true;\n child.stderr?.removeListener('data', onStderr);\n child.stdout?.removeListener('data', onStdout);\n child.removeListener('error', onError);\n child.removeListener('exit', onExit);\n clearTimeout(timer);\n };\n\n const onStderr = () => {\n if (settled) return;\n logger.debug(`${name}: ready (stderr output detected)`);\n cleanup();\n resolve();\n };\n\n const onStdout = () => {\n if (settled) return;\n logger.debug(`${name}: ready (stdout output detected)`);\n cleanup();\n resolve();\n };\n\n const onError = (error: Error) => {\n if (settled) return;\n cleanup();\n reject(new Error(`${name} failed to start: ${error.message}`));\n };\n\n const onExit = (code: number | null) => {\n if (settled) return;\n cleanup();\n reject(new Error(`${name} exited before becoming ready (code: ${code})`));\n };\n\n const timer = setTimeout(() => {\n if (settled) return;\n logger.warn(`${name}: readiness timeout (${timeoutMs} ms) \u2014 proceeding anyway`);\n cleanup();\n resolve(); // best-effort: let the caller attempt communication\n }, timeoutMs);\n\n child.stderr?.on('data', onStderr);\n child.stdout?.on('data', onStdout);\n child.on('error', onError);\n child.on('exit', onExit);\n\n // If the process was dead before we even attached listeners, reject now\n if (child.killed || child.exitCode !== null) {\n cleanup();\n reject(new Error(`${name} is not running (exitCode: ${child.exitCode})`));\n }\n });\n}\n", "/**\n * CodeQL Language Server manager for LSP communication\n * Manages the lifecycle and communication with the CodeQL language server process\n */\n\nimport { spawn, ChildProcess } from 'child_process';\nimport { EventEmitter } from 'events';\nimport { setTimeout, clearTimeout } from 'timers';\nimport { pathToFileURL } from 'url';\nimport { delimiter, join } from 'path';\nimport { logger } from '../utils/logger';\nimport { getPackageVersion } from '../utils/package-paths';\nimport { getProjectTmpDir } from '../utils/temp-dir';\nimport { getResolvedCodeQLDir } from './cli-executor';\nimport { waitForProcessReady } from '../utils/process-ready';\n\nexport interface LSPMessage {\n jsonrpc: '2.0';\n id?: number | string;\n method: string;\n params?: unknown;\n result?: unknown;\n error?: {\n code: number;\n message: string;\n data?: unknown;\n };\n}\n\nexport interface Diagnostic {\n range: {\n start: { line: number; character: number };\n end: { line: number; character: number };\n };\n severity: number; // 1=Error, 2=Warning, 3=Information, 4=Hint\n source?: string;\n message: string;\n code?: string | number;\n}\n\nexport interface PublishDiagnosticsParams {\n uri: string;\n diagnostics: Diagnostic[];\n}\n\nexport interface LanguageServerOptions {\n searchPath?: string;\n logdir?: string;\n loglevel?: 'ALL' | 'DEBUG' | 'ERROR' | 'INFO' | 'OFF' | 'TRACE' | 'WARN';\n synchronous?: boolean;\n verbosity?: 'errors' | 'progress' | 'progress+' | 'progress++' | 'progress+++' | 'warnings';\n}\n\n/**\n * Position in a text document (0-based line and character).\n */\nexport interface LSPPosition {\n character: number;\n line: number;\n}\n\n/**\n * A range in a text document.\n */\nexport interface LSPRange {\n end: LSPPosition;\n start: LSPPosition;\n}\n\n/**\n * A location in a resource (file URI + range).\n */\nexport interface LSPLocation {\n range: LSPRange;\n uri: string;\n}\n\n/**\n * Identifies a text document by its URI.\n */\nexport interface TextDocumentIdentifier {\n uri: string;\n}\n\n/**\n * A text document position (document + position within it).\n */\nexport interface TextDocumentPositionParams {\n position: LSPPosition;\n textDocument: TextDocumentIdentifier;\n}\n\n/**\n * A completion item returned by the language server.\n */\nexport interface CompletionItem {\n detail?: string;\n documentation?: string | { kind: string; value: string };\n insertText?: string;\n kind?: number;\n label: string;\n sortText?: string;\n}\n\nexport class CodeQLLanguageServer extends EventEmitter {\n private server: ChildProcess | null = null;\n private messageId = 1;\n private pendingResponses = new Map void; reject: (_error: Error) => void }>();\n private isInitialized = false;\n private currentWorkspaceUri: string | undefined;\n private messageBuffer = '';\n\n constructor(private _options: LanguageServerOptions = {}) {\n super();\n }\n\n async start(): Promise {\n if (this.server) {\n throw new Error('Language server is already running');\n }\n\n logger.info('Starting CodeQL Language Server...');\n\n const args = [\n 'execute', 'language-server',\n '--check-errors=ON_CHANGE'\n ];\n\n // Add optional arguments\n if (this._options.searchPath) {\n args.push(`--search-path=${this._options.searchPath}`);\n }\n if (this._options.logdir) {\n args.push(`--logdir=${this._options.logdir}`);\n }\n if (this._options.loglevel) {\n args.push(`--loglevel=${this._options.loglevel}`);\n }\n if (this._options.synchronous) {\n args.push('--synchronous');\n }\n if (this._options.verbosity) {\n args.push(`--verbosity=${this._options.verbosity}`);\n }\n\n // Build environment with CODEQL_PATH directory prepended to PATH\n // (mirrors the approach in cli-executor.ts getSafeEnvironment).\n const spawnEnv = { ...process.env };\n const codeqlDir = getResolvedCodeQLDir();\n if (codeqlDir && spawnEnv.PATH) {\n spawnEnv.PATH = `${codeqlDir}${delimiter}${spawnEnv.PATH}`;\n } else if (codeqlDir) {\n spawnEnv.PATH = codeqlDir;\n }\n\n this.server = spawn('codeql', args, {\n stdio: ['pipe', 'pipe', 'pipe'],\n env: spawnEnv\n });\n\n this.server.stderr?.on('data', (data) => {\n logger.debug('CodeQL LS stderr:', data.toString());\n });\n\n this.server.stdout?.on('data', (data) => {\n this.handleStdout(data);\n });\n\n this.server.on('error', (error) => {\n logger.error('CodeQL Language Server error:', error);\n this.emit('error', error);\n });\n\n this.server.on('exit', (code) => {\n logger.info('CodeQL Language Server exited with code:', code);\n this.server = null;\n this.isInitialized = false;\n this.emit('exit', code);\n });\n\n // Wait for the JVM to initialise (resolves on first stderr/stdout output)\n await waitForProcessReady(this.server, 'CodeQL Language Server');\n }\n\n private handleStdout(data: Buffer): void {\n this.messageBuffer += data.toString();\n \n let headerEnd = this.messageBuffer.indexOf('\\r\\n\\r\\n');\n while (headerEnd !== -1) {\n const header = this.messageBuffer.substring(0, headerEnd);\n const contentLengthMatch = header.match(/Content-Length: (\\d+)/);\n \n if (contentLengthMatch) {\n const contentLength = parseInt(contentLengthMatch[1]);\n const messageStart = headerEnd + 4;\n const messageEnd = messageStart + contentLength;\n \n if (this.messageBuffer.length >= messageEnd) {\n const messageContent = this.messageBuffer.substring(messageStart, messageEnd);\n this.messageBuffer = this.messageBuffer.substring(messageEnd);\n \n try {\n const message: LSPMessage = JSON.parse(messageContent);\n this.handleMessage(message);\n } catch (error) {\n logger.error('Failed to parse LSP message:', error, messageContent);\n }\n \n headerEnd = this.messageBuffer.indexOf('\\r\\n\\r\\n');\n } else {\n break;\n }\n } else {\n logger.error('Invalid LSP header:', header);\n this.messageBuffer = '';\n break;\n }\n }\n }\n\n private handleMessage(message: LSPMessage): void {\n logger.debug('Received LSP message:', message);\n\n // Handle responses to our requests\n if (message.id !== undefined && this.pendingResponses.has(Number(message.id))) {\n const pending = this.pendingResponses.get(Number(message.id))!;\n this.pendingResponses.delete(Number(message.id));\n \n if (message.error) {\n pending.reject(new Error(`LSP Error: ${message.error.message}`));\n } else {\n pending.resolve(message.result);\n }\n return;\n }\n\n // Handle notifications from server\n if (message.method === 'textDocument/publishDiagnostics') {\n this.emit('diagnostics', message.params as PublishDiagnosticsParams);\n }\n }\n\n private sendMessage(message: LSPMessage): void {\n if (!this.server?.stdin) {\n throw new Error('Language server is not running');\n }\n\n const messageStr = JSON.stringify(message);\n const contentLength = Buffer.byteLength(messageStr, 'utf8');\n const header = `Content-Length: ${contentLength}\\r\\n\\r\\n`;\n const fullMessage = header + messageStr;\n\n logger.debug('Sending LSP message:', fullMessage);\n this.server.stdin.write(fullMessage);\n }\n\n private sendRequest(method: string, params?: unknown): Promise {\n const id = this.messageId++;\n const message: LSPMessage = {\n jsonrpc: '2.0',\n id,\n method,\n params\n };\n\n return new Promise((resolve, reject) => {\n // Wrap resolve/reject to clear the timer when the promise settles.\n const timer = setTimeout(() => {\n if (this.pendingResponses.has(id)) {\n this.pendingResponses.delete(id);\n reject(new Error(`LSP request timeout for method: ${method}`));\n }\n }, 60_000); // 60 second timeout (Windows CI cold JVM can exceed 30s)\n\n this.pendingResponses.set(id, {\n reject: (err: Error) => { clearTimeout(timer); reject(err); },\n resolve: (val: unknown) => { clearTimeout(timer); resolve(val); },\n });\n this.sendMessage(message);\n });\n }\n\n private sendNotification(method: string, params?: unknown): void {\n const message: LSPMessage = {\n jsonrpc: '2.0',\n method,\n params\n };\n this.sendMessage(message);\n }\n\n /**\n * Initialize the language server with an optional workspace URI.\n *\n * If the server is already initialized with a different workspace, a\n * `workspace/didChangeWorkspaceFolders` notification is sent to update\n * the workspace context instead of requiring a full restart.\n */\n async initialize(workspaceUri?: string): Promise {\n if (this.isInitialized) {\n // If workspace changed, notify the server\n if (workspaceUri && workspaceUri !== this.currentWorkspaceUri) {\n await this.updateWorkspace(workspaceUri);\n }\n return;\n }\n\n logger.info('Initializing CodeQL Language Server...');\n\n const initParams = {\n processId: process.pid,\n clientInfo: {\n name: 'codeql-development-mcp-server',\n version: getPackageVersion()\n },\n capabilities: {\n textDocument: {\n completion: { completionItem: { snippetSupport: false } },\n definition: {},\n publishDiagnostics: {},\n references: {},\n synchronization: {\n didClose: true,\n didChange: true,\n didOpen: true,\n },\n },\n workspace: {\n workspaceFolders: true,\n },\n }\n };\n\n if (workspaceUri) {\n (initParams as unknown as { workspaceFolders: unknown[] }).workspaceFolders = [{\n uri: workspaceUri,\n name: 'codeql-workspace'\n }];\n }\n\n await this.sendRequest('initialize', initParams);\n this.sendNotification('initialized', {});\n\n this.currentWorkspaceUri = workspaceUri;\n this.isInitialized = true;\n logger.info('CodeQL Language Server initialized successfully');\n }\n\n /**\n * Update the workspace folders on a running, initialized server.\n */\n private async updateWorkspace(newUri: string): Promise {\n logger.info(`Updating workspace from ${this.currentWorkspaceUri} to ${newUri}`);\n\n const removed = this.currentWorkspaceUri\n ? [{ uri: this.currentWorkspaceUri, name: 'codeql-workspace' }]\n : [];\n\n this.sendNotification('workspace/didChangeWorkspaceFolders', {\n event: {\n added: [{ uri: newUri, name: 'codeql-workspace' }],\n removed,\n },\n });\n\n this.currentWorkspaceUri = newUri;\n }\n\n /**\n * Get the current workspace URI.\n */\n getWorkspaceUri(): string | undefined {\n return this.currentWorkspaceUri;\n }\n\n async evaluateQL(qlCode: string, uri?: string): Promise {\n if (!this.isInitialized) {\n throw new Error('Language server is not initialized');\n }\n\n // Default to a project-local virtual URI rather than /tmp\n const documentUri = uri || pathToFileURL(join(getProjectTmpDir('lsp-eval'), 'eval.ql')).href;\n\n return new Promise((resolve, reject) => {\n let diagnosticsReceived = false;\n const timeout = setTimeout(() => {\n if (!diagnosticsReceived) {\n this.removeListener('diagnostics', diagnosticsHandler);\n reject(new Error('Timeout waiting for diagnostics'));\n }\n }, 90_000); // 90s \u2014 first call triggers JVM start + compilation; Windows CI is slow\n\n // Listen for diagnostics\n const diagnosticsHandler = (params: PublishDiagnosticsParams) => {\n if (params.uri === documentUri) {\n diagnosticsReceived = true;\n clearTimeout(timeout);\n this.removeListener('diagnostics', diagnosticsHandler);\n\n // Close the document\n this.sendNotification('textDocument/didClose', {\n textDocument: { uri: documentUri }\n });\n\n resolve(params.diagnostics);\n }\n };\n\n this.on('diagnostics', diagnosticsHandler);\n\n // Open the document with the QL code\n this.sendNotification('textDocument/didOpen', {\n textDocument: {\n uri: documentUri,\n languageId: 'ql',\n version: 1,\n text: qlCode\n }\n });\n });\n }\n\n // ---- LSP feature methods (issue #1) ----\n\n /**\n * Get code completions at a position in a document.\n */\n async getCompletions(params: TextDocumentPositionParams): Promise {\n if (!this.isInitialized) {\n throw new Error('Language server is not initialized');\n }\n if (!this.isRunning()) {\n throw new Error('Language server process is not running');\n }\n const result = await this.sendRequest('textDocument/completion', params);\n // The result may be a CompletionList or CompletionItem[]\n if (result && typeof result === 'object' && 'items' in (result as object)) {\n return (result as { items: CompletionItem[] }).items;\n }\n return (result as CompletionItem[]) || [];\n }\n\n /**\n * Find the definition(s) of a symbol at a position.\n */\n async getDefinition(params: TextDocumentPositionParams): Promise {\n if (!this.isInitialized) {\n throw new Error('Language server is not initialized');\n }\n if (!this.isRunning()) {\n throw new Error('Language server process is not running');\n }\n const result = await this.sendRequest('textDocument/definition', params);\n return this.normalizeLocations(result);\n }\n\n /**\n * Find all references to a symbol at a position.\n */\n async getReferences(params: TextDocumentPositionParams & { context?: { includeDeclaration: boolean } }): Promise {\n if (!this.isInitialized) {\n throw new Error('Language server is not initialized');\n }\n if (!this.isRunning()) {\n throw new Error('Language server process is not running');\n }\n const result = await this.sendRequest('textDocument/references', {\n ...params,\n context: params.context ?? { includeDeclaration: true },\n });\n return this.normalizeLocations(result);\n }\n\n /**\n * Open a text document in the language server.\n * The document must be opened before requesting completions, definitions, etc.\n */\n openDocument(uri: string, text: string, languageId = 'ql', version = 1): void {\n if (!this.isInitialized) {\n throw new Error('Language server is not initialized');\n }\n this.sendNotification('textDocument/didOpen', {\n textDocument: { uri, languageId, version, text },\n });\n }\n\n /**\n * Close a text document in the language server.\n */\n closeDocument(uri: string): void {\n if (!this.isInitialized) {\n throw new Error('Language server is not initialized');\n }\n this.sendNotification('textDocument/didClose', {\n textDocument: { uri },\n });\n }\n\n /**\n * Normalize a definition/references/implementation result to Location[].\n * The LSP spec allows Location | Location[] | LocationLink[].\n */\n private normalizeLocations(result: unknown): LSPLocation[] {\n if (!result) return [];\n if (Array.isArray(result)) {\n return result.map((item) => {\n // LocationLink has targetUri/targetRange\n if ('targetUri' in item) {\n return { uri: item.targetUri, range: item.targetRange } as LSPLocation;\n }\n return item as LSPLocation;\n });\n }\n // Single Location\n if (typeof result === 'object' && 'uri' in (result as object)) {\n return [result as LSPLocation];\n }\n return [];\n }\n\n async shutdown(): Promise {\n if (!this.server) {\n return;\n }\n\n logger.info('Shutting down CodeQL Language Server...');\n\n try {\n await this.sendRequest('shutdown', {});\n if (this.server) {\n this.sendNotification('exit', {});\n }\n } catch (error) {\n logger.warn('Error during graceful shutdown:', error);\n }\n\n // Force kill if needed\n await new Promise((resolve) => {\n const timer = setTimeout(() => {\n if (this.server) {\n this.server.kill('SIGTERM');\n }\n resolve();\n }, 1000);\n\n if (this.server) {\n this.server.once('exit', () => {\n clearTimeout(timer);\n this.server = null;\n resolve();\n });\n } else {\n clearTimeout(timer);\n resolve();\n }\n });\n\n this.isInitialized = false;\n }\n\n isRunning(): boolean {\n return this.server !== null && !this.server.killed;\n }\n}", "/**\n * CodeQL Query Server (query-server2) client.\n *\n * Manages a long-lived `codeql execute query-server2` process that evaluates\n * queries using a custom JSON-RPC protocol over stdio. Reusing the server\n * avoids repeated JVM startup for each query evaluation.\n *\n * Protocol: The query-server2 uses JSON-RPC with Content-Length headers\n * (same framing as LSP) over stdin/stdout.\n */\n\nimport { ChildProcess, spawn } from 'child_process';\nimport { delimiter } from 'path';\nimport { EventEmitter } from 'events';\nimport { clearTimeout, setTimeout } from 'timers';\nimport { buildQueryServerArgs, QueryServerConfig } from './server-config';\nimport { getResolvedCodeQLDir } from './cli-executor';\nimport { logger } from '../utils/logger';\nimport { waitForProcessReady } from '../utils/process-ready';\n\n/**\n * A pending request awaiting a response from the query server.\n */\ninterface PendingRequest {\n reject: (_error: Error) => void;\n resolve: (_value: unknown) => void;\n}\n\n/**\n * Client for the CodeQL query-server2 process.\n *\n * Spawns `codeql execute query-server2` and communicates over stdin/stdout\n * using JSON-RPC with Content-Length framing.\n */\nexport class CodeQLQueryServer extends EventEmitter {\n private messageBuffer = '';\n private messageId = 1;\n private pendingRequests = new Map();\n private process: ChildProcess | null = null;\n private readonly config: QueryServerConfig;\n\n constructor(config: QueryServerConfig) {\n super();\n this.config = config;\n }\n\n /**\n * Start the query-server2 process.\n */\n async start(): Promise {\n if (this.process) {\n throw new Error('Query server is already running');\n }\n\n logger.info('Starting CodeQL Query Server (query-server2)...');\n\n const args = buildQueryServerArgs(this.config);\n\n // Build environment with CODEQL_PATH directory prepended to PATH\n const spawnEnv = { ...process.env };\n const codeqlDir = getResolvedCodeQLDir();\n if (codeqlDir && spawnEnv.PATH) {\n spawnEnv.PATH = `${codeqlDir}${delimiter}${spawnEnv.PATH}`;\n } else if (codeqlDir) {\n spawnEnv.PATH = codeqlDir;\n }\n\n this.process = spawn('codeql', args, {\n stdio: ['pipe', 'pipe', 'pipe'],\n env: spawnEnv,\n });\n\n this.process.stderr?.on('data', (data: Buffer) => {\n logger.debug('QueryServer2 stderr:', data.toString());\n });\n\n this.process.stdout?.on('data', (data: Buffer) => {\n this.handleStdout(data);\n });\n\n this.process.on('error', (error: Error) => {\n logger.error('Query server process error:', error);\n this.emit('error', error);\n });\n\n this.process.on('exit', (code: number | null) => {\n logger.info(`Query server exited with code: ${code}`);\n this.rejectAllPending(new Error(`Query server exited with code: ${code}`));\n this.process = null;\n this.emit('exit', code);\n });\n\n // Wait for the JVM to initialise (resolves on first stderr/stdout output)\n await waitForProcessReady(this.process, 'CodeQL Query Server');\n logger.info('CodeQL Query Server started');\n }\n\n /**\n * Send a request to the query server and await the response.\n *\n * @param method - The JSON-RPC method name.\n * @param params - The method parameters.\n * @param timeoutMs - Request timeout in milliseconds (default: 300000 = 5 min).\n * @returns The result from the server.\n */\n sendRequest(method: string, params?: unknown, timeoutMs = 300_000): Promise {\n const id = this.messageId++;\n const message = {\n id,\n jsonrpc: '2.0' as const,\n method,\n params,\n };\n\n return new Promise((resolve, reject) => {\n this.pendingRequests.set(id, { reject, resolve });\n\n try {\n this.sendRaw(message);\n } catch (error) {\n // Clean up immediately \u2014 sendRaw() failed so no response will arrive.\n this.pendingRequests.delete(id);\n reject(error instanceof Error ? error : new Error(String(error)));\n return;\n }\n\n const timer = setTimeout(() => {\n if (this.pendingRequests.has(id)) {\n this.pendingRequests.delete(id);\n reject(new Error(`Query server request timeout for method: ${method}`));\n }\n }, timeoutMs);\n\n // Clear the timeout when the promise settles\n const originalResolve = resolve;\n const originalReject = reject;\n const wrapped = {\n reject: (err: Error) => { clearTimeout(timer); originalReject(err); },\n resolve: (val: unknown) => { clearTimeout(timer); originalResolve(val); },\n };\n this.pendingRequests.set(id, wrapped);\n });\n }\n\n /**\n * Gracefully shut down the query server.\n */\n async shutdown(): Promise {\n if (!this.process) {\n return;\n }\n\n logger.info('Shutting down CodeQL Query Server...');\n\n try {\n await this.sendRequest('shutdown', {}, 5000);\n } catch (error) {\n logger.warn('Error during query server graceful shutdown:', error);\n }\n\n // Force kill if process lingers\n await new Promise((resolve) => {\n const timer = setTimeout(() => {\n if (this.process) {\n this.process.kill('SIGTERM');\n this.process = null;\n }\n resolve();\n }, 2000);\n\n if (this.process) {\n this.process.once('exit', () => {\n clearTimeout(timer);\n this.process = null;\n resolve();\n });\n } else {\n clearTimeout(timer);\n resolve();\n }\n });\n }\n\n /**\n * Whether the query server process is running.\n */\n isRunning(): boolean {\n return this.process !== null && !this.process.killed;\n }\n\n // ---- private helpers ----\n\n private handleStdout(data: Buffer): void {\n this.messageBuffer += data.toString();\n\n let headerEnd = this.messageBuffer.indexOf('\\r\\n\\r\\n');\n while (headerEnd !== -1) {\n const header = this.messageBuffer.substring(0, headerEnd);\n const contentLengthMatch = header.match(/Content-Length: (\\d+)/);\n\n if (contentLengthMatch) {\n const contentLength = parseInt(contentLengthMatch[1]);\n const messageStart = headerEnd + 4;\n const messageEnd = messageStart + contentLength;\n\n if (this.messageBuffer.length >= messageEnd) {\n const messageContent = this.messageBuffer.substring(messageStart, messageEnd);\n this.messageBuffer = this.messageBuffer.substring(messageEnd);\n\n try {\n const message = JSON.parse(messageContent);\n this.handleMessage(message);\n } catch (error) {\n logger.error('Failed to parse query server message:', error);\n }\n\n headerEnd = this.messageBuffer.indexOf('\\r\\n\\r\\n');\n } else {\n break;\n }\n } else {\n logger.error('Invalid query server header:', header);\n this.messageBuffer = '';\n break;\n }\n }\n }\n\n private handleMessage(message: { error?: { message: string }; id?: number; method?: string; params?: unknown; result?: unknown }): void {\n logger.debug('QueryServer2 message:', message);\n\n // Handle responses\n if (message.id !== undefined && this.pendingRequests.has(Number(message.id))) {\n const pending = this.pendingRequests.get(Number(message.id))!;\n this.pendingRequests.delete(Number(message.id));\n\n if (message.error) {\n pending.reject(new Error(`Query server error: ${message.error.message}`));\n } else {\n pending.resolve(message.result);\n }\n return;\n }\n\n // Handle notifications (progress, etc.)\n if (message.method) {\n this.emit('notification', { method: message.method, params: message.params });\n }\n }\n\n private rejectAllPending(error: Error): void {\n for (const [id, pending] of this.pendingRequests) {\n pending.reject(error);\n this.pendingRequests.delete(id);\n }\n }\n\n private sendRaw(message: object): void {\n if (!this.process?.stdin) {\n throw new Error('Query server is not running');\n }\n\n const body = JSON.stringify(message);\n const contentLength = Buffer.byteLength(body, 'utf8');\n const frame = `Content-Length: ${contentLength}\\r\\n\\r\\n${body}`;\n this.process.stdin.write(frame);\n }\n}\n", "/**\n * CodeQL CLI Server client.\n *\n * Manages a long-lived `codeql execute cli-server` process that executes CLI\n * commands without repeated JVM startup overhead. Commands are serialized as\n * JSON arrays followed by a NUL byte, and responses are NUL-terminated JSON.\n *\n * Inspired by the `CodeQLCliServer` class in github/vscode-codeql.\n */\n\nimport { ChildProcess, spawn } from 'child_process';\nimport { delimiter } from 'path';\nimport { EventEmitter } from 'events';\nimport { clearTimeout, setTimeout } from 'timers';\nimport { buildCLIServerArgs, CLIServerConfig } from './server-config';\nimport { getResolvedCodeQLDir } from './cli-executor';\nimport { logger } from '../utils/logger';\nimport { waitForProcessReady } from '../utils/process-ready';\n\n/**\n * A queued command waiting to be sent to the CLI server.\n */\ninterface QueuedCommand {\n args: string[];\n reject: (_error: Error) => void;\n resolve: (_value: string) => void;\n}\n\n/**\n * Client for the CodeQL CLI Server process.\n *\n * The cli-server uses a simple NUL-delimited protocol:\n * - **Request**: JSON array of command arguments, followed by a NUL byte.\n * - **Response**: command stdout, terminated by a NUL byte on stdout.\n * stderr is forwarded as-is.\n */\nexport class CodeQLCLIServer extends EventEmitter {\n private commandInProgress = false;\n private commandQueue: Array<() => void> = [];\n private readonly config: CLIServerConfig;\n private currentReject: ((_error: Error) => void) | null = null;\n private currentResolve: ((_value: string) => void) | null = null;\n private nullBuffer = Buffer.alloc(1);\n private process: ChildProcess | null = null;\n private stdoutBuffer = '';\n\n constructor(config: CLIServerConfig) {\n super();\n this.config = config;\n }\n\n /**\n * Start the cli-server process.\n */\n async start(): Promise {\n if (this.process) {\n throw new Error('CLI server is already running');\n }\n\n logger.info('Starting CodeQL CLI Server...');\n\n const args = buildCLIServerArgs(this.config);\n\n const spawnEnv = { ...process.env };\n const codeqlDir = getResolvedCodeQLDir();\n if (codeqlDir && spawnEnv.PATH) {\n spawnEnv.PATH = `${codeqlDir}${delimiter}${spawnEnv.PATH}`;\n } else if (codeqlDir) {\n spawnEnv.PATH = codeqlDir;\n }\n\n this.process = spawn('codeql', args, {\n stdio: ['pipe', 'pipe', 'pipe'],\n env: spawnEnv,\n });\n\n this.process.stdout?.on('data', (data: Buffer) => {\n this.handleStdout(data);\n });\n\n this.process.stderr?.on('data', (data: Buffer) => {\n logger.debug('CLIServer stderr:', data.toString());\n });\n\n this.process.on('error', (error: Error) => {\n logger.error('CLI server process error:', error);\n if (this.currentReject) {\n this.currentReject(error);\n this.currentReject = null;\n this.currentResolve = null;\n }\n this.emit('error', error);\n });\n\n this.process.on('exit', (code: number | null) => {\n logger.info(`CLI server exited with code: ${code}`);\n if (this.currentReject) {\n this.currentReject(new Error(`CLI server exited unexpectedly with code: ${code}`));\n this.currentReject = null;\n this.currentResolve = null;\n }\n this.process = null;\n this.emit('exit', code);\n });\n\n // Wait for the JVM to initialise (resolves on first stderr/stdout output)\n await waitForProcessReady(this.process, 'CodeQL CLI Server');\n logger.info('CodeQL CLI Server started');\n }\n\n /**\n * Run a CodeQL CLI command through the persistent server.\n *\n * Commands are serialized and queued; only one command runs at a time.\n *\n * @param args - The full command arguments (e.g. `['resolve', 'qlpacks']`).\n * @returns The stdout output from the command.\n */\n runCommand(args: string[]): Promise {\n return new Promise((resolve, reject) => {\n const execute = () => {\n this.executeCommand({ args, reject, resolve });\n };\n\n if (this.commandInProgress) {\n this.commandQueue.push(execute);\n } else {\n execute();\n }\n });\n }\n\n /**\n * Gracefully shut down the CLI server.\n */\n async shutdown(): Promise {\n if (!this.process) {\n return;\n }\n\n logger.info('Shutting down CodeQL CLI Server...');\n\n try {\n // Send shutdown command\n this.process.stdin?.write(JSON.stringify(['shutdown']), 'utf8');\n this.process.stdin?.write(this.nullBuffer);\n } catch (error) {\n logger.warn('Error during CLI server shutdown request:', error);\n }\n\n // Give it a moment, then force kill\n await new Promise((resolve) => {\n const timer = setTimeout(() => {\n if (this.process) {\n this.process.kill('SIGTERM');\n this.process = null;\n }\n resolve();\n }, 2000);\n\n if (this.process) {\n this.process.once('exit', () => {\n clearTimeout(timer);\n this.process = null;\n resolve();\n });\n } else {\n clearTimeout(timer);\n resolve();\n }\n });\n\n this.commandInProgress = false;\n this.commandQueue = [];\n logger.info('CodeQL CLI Server stopped');\n }\n\n /**\n * Whether the CLI server process is running.\n */\n isRunning(): boolean {\n return this.process !== null && !this.process.killed;\n }\n\n // ---- private helpers ----\n\n private executeCommand(cmd: QueuedCommand): void {\n if (!this.process?.stdin) {\n cmd.reject(new Error('CLI server is not running'));\n return;\n }\n\n this.commandInProgress = true;\n this.currentResolve = cmd.resolve;\n this.currentReject = cmd.reject;\n\n try {\n this.process.stdin.write(JSON.stringify(cmd.args), 'utf8');\n this.process.stdin.write(this.nullBuffer);\n } catch (error) {\n this.commandInProgress = false;\n this.currentResolve = null;\n this.currentReject = null;\n cmd.reject(error instanceof Error ? error : new Error(String(error)));\n this.runNext();\n }\n }\n\n private handleStdout(data: Buffer): void {\n this.stdoutBuffer += data.toString();\n\n // Process all NUL-delimited responses in the buffer\n let nulIndex = this.stdoutBuffer.indexOf('\\0');\n while (nulIndex !== -1) {\n const result = this.stdoutBuffer.substring(0, nulIndex);\n this.stdoutBuffer = this.stdoutBuffer.substring(nulIndex + 1);\n\n if (this.currentResolve) {\n this.currentResolve(result);\n this.currentResolve = null;\n this.currentReject = null;\n }\n\n this.commandInProgress = false;\n this.runNext();\n\n nulIndex = this.stdoutBuffer.indexOf('\\0');\n }\n }\n\n private runNext(): void {\n const next = this.commandQueue.shift();\n if (next) {\n next();\n }\n }\n}\n", "/**\n * CodeQL Server Manager\n *\n * Manages the lifecycle of CodeQL background server processes:\n * - language-server (LSP-based QL validation)\n * - query-server2 (query evaluation)\n * - cli-server (JVM reuse for CLI commands)\n *\n * Servers are keyed by a hash of their configuration. When a caller requests\n * a server with a different configuration, the old server is shut down and a\n * new one is started. Session-specific cache directories provide isolation.\n */\n\nimport { mkdirSync } from 'fs';\nimport { join } from 'path';\nimport { randomUUID } from 'crypto';\nimport {\n CLIServerConfig,\n CodeQLServerType,\n computeConfigHash,\n LanguageServerConfig,\n QueryServerConfig,\n ServerConfig,\n} from './server-config';\nimport { CodeQLLanguageServer } from './language-server';\nimport { CodeQLQueryServer } from './query-server';\nimport { CodeQLCLIServer } from './cli-server';\nimport { getProjectTmpDir } from '../utils/temp-dir';\nimport { logger } from '../utils/logger';\n\n/**\n * Entry in the managed servers map.\n */\ninterface ManagedServer {\n configHash: string;\n server: CodeQLCLIServer | CodeQLLanguageServer | CodeQLQueryServer;\n sessionId: string;\n type: CodeQLServerType;\n}\n\n/**\n * Options for creating a session-specific cache layout.\n */\nexport interface SessionCacheOptions {\n /** Override the session ID (defaults to a random UUID). */\n sessionId?: string;\n}\n\n/**\n * Manages CodeQL background server processes with config-aware caching.\n *\n * Callers should use `getLanguageServer()`, `getQueryServer()`, or\n * `getCLIServer()` to obtain a running server. If the requested\n * configuration differs from the currently running server of that type, the\n * old server is stopped and replaced.\n */\nexport class CodeQLServerManager {\n /** Keyed by `CodeQLServerType` \u2014 at most one per type at a time. */\n private servers = new Map();\n\n /** In-flight `getOrRestart` promises, keyed by server type, to serialize concurrent calls. */\n private pendingStarts = new Map>();\n\n /** The session ID used for cache isolation. */\n private sessionId: string;\n\n /** Root directory for session-specific caches. */\n private sessionCacheDir: string;\n\n constructor(options?: SessionCacheOptions) {\n this.sessionId = options?.sessionId ?? randomUUID();\n this.sessionCacheDir = join(\n getProjectTmpDir('codeql-cache'),\n this.sessionId,\n );\n // Pre-create the cache directory tree\n for (const subdir of ['compilation-cache', 'logs', 'query-cache']) {\n mkdirSync(join(this.sessionCacheDir, subdir), { recursive: true });\n }\n logger.info(`CodeQLServerManager initialized (session: ${this.sessionId})`);\n }\n\n // ---- Public API ----\n\n /**\n * Get the current session ID.\n */\n getSessionId(): string {\n return this.sessionId;\n }\n\n /**\n * Get the session-specific cache directory.\n */\n getCacheDir(): string {\n return this.sessionCacheDir;\n }\n\n /**\n * Return the session-specific log directory.\n */\n getLogDir(): string {\n return join(this.sessionCacheDir, 'logs');\n }\n\n /**\n * Get or create a Language Server with the given configuration.\n *\n * If a language server is already running with the same config it is reused.\n * If the config has changed the old server is shut down first.\n */\n async getLanguageServer(config: LanguageServerConfig): Promise {\n const enriched = this.enrichConfig(config) as LanguageServerConfig;\n return this.getOrRestart('language', enriched, () => {\n // Convert LanguageServerConfig to the LanguageServerOptions the existing class expects\n return new CodeQLLanguageServer({\n loglevel: enriched.loglevel,\n logdir: enriched.logdir,\n searchPath: enriched.searchPath,\n synchronous: enriched.synchronous,\n verbosity: enriched.verbosity,\n });\n }) as Promise;\n }\n\n /**\n * Get or create a Query Server with the given configuration.\n */\n async getQueryServer(config: QueryServerConfig): Promise {\n const enriched = this.enrichConfig(config) as QueryServerConfig;\n return this.getOrRestart('query', enriched, () => {\n return new CodeQLQueryServer(enriched);\n }) as Promise;\n }\n\n /**\n * Get or create a CLI Server with the given configuration.\n */\n async getCLIServer(config: CLIServerConfig): Promise {\n const enriched = this.enrichConfig(config) as CLIServerConfig;\n return this.getOrRestart('cli', enriched, () => {\n return new CodeQLCLIServer(enriched);\n }) as Promise;\n }\n\n /**\n * Shut down a specific server type.\n */\n async shutdownServer(type: CodeQLServerType): Promise {\n const managed = this.servers.get(type);\n if (!managed) return;\n\n logger.info(`Shutting down ${type} server (session: ${managed.sessionId})`);\n await this.stopServer(managed);\n this.servers.delete(type);\n }\n\n /**\n * Shut down all managed servers.\n */\n async shutdownAll(): Promise {\n logger.info(`Shutting down all servers for session: ${this.sessionId}`);\n const shutdownPromises = Array.from(this.servers.entries()).map(\n async ([type, managed]) => {\n try {\n await this.stopServer(managed);\n } catch (error) {\n logger.error(`Error shutting down ${type} server:`, error);\n }\n },\n );\n await Promise.all(shutdownPromises);\n this.servers.clear();\n logger.info('All servers shut down');\n }\n\n /**\n * Check whether a server of the given type is currently running.\n */\n isRunning(type: CodeQLServerType): boolean {\n const managed = this.servers.get(type);\n if (!managed) return false;\n return managed.server.isRunning();\n }\n\n /**\n * Get status information for all managed servers.\n */\n getStatus(): Record {\n const status: Record = {\n cli: null,\n language: null,\n query: null,\n };\n for (const [type, managed] of this.servers) {\n status[type] = {\n configHash: managed.configHash,\n running: managed.server.isRunning(),\n sessionId: managed.sessionId,\n };\n }\n return status as Record;\n }\n\n // ---- Private helpers ----\n\n /**\n * Eagerly start the language server so the JVM is warm when the first\n * LSP tool call arrives. Uses the default configuration that\n * `lsp-handlers.ts` / `lsp-diagnostics.ts` would create on the first\n * `getLanguageServer()` call. The server is stored in the managed-servers\n * map and reused by subsequent tool invocations.\n *\n * This is fire-and-forget: errors are logged but do not prevent the MCP\n * server from starting.\n */\n async warmUpLanguageServer(): Promise {\n try {\n // Lazy-import to avoid circular dependency at module level\n const { packageRootDir } = await import('../utils/package-paths');\n const { resolve } = await import('path');\n\n const config: LanguageServerConfig = {\n checkErrors: 'ON_CHANGE',\n loglevel: 'WARN',\n searchPath: resolve(packageRootDir, 'ql'),\n };\n logger.info('Warming up language server (background JVM start)...');\n await this.getLanguageServer(config);\n logger.info('Language server warm-up complete');\n } catch (error) {\n logger.warn('Language server warm-up failed (will retry on first tool call):', error);\n }\n }\n\n /**\n * Eagerly start the CLI server so the JVM is warm when the first\n * `executeCodeQLCommand()` call routes through it.\n *\n * The CLI server uses only session-scoped `commonCaches` and `logdir`,\n * both injected by `enrichConfig()`. Passing an empty config is\n * intentional \u2014 it matches what `executeCodeQLCommand()` will request.\n *\n * Fire-and-forget: errors are logged but do not block startup.\n */\n async warmUpCLIServer(): Promise {\n try {\n logger.info('Warming up CLI server (background JVM start)...');\n await this.getCLIServer({});\n logger.info('CLI server warm-up complete');\n } catch (error) {\n logger.warn('CLI server warm-up failed (will retry on first tool call):', error);\n }\n }\n\n /**\n * Enrich a config with session-specific defaults for commonCaches and logdir.\n */\n private enrichConfig(config: T): T {\n return {\n ...config,\n commonCaches: config.commonCaches ?? this.sessionCacheDir,\n logdir: config.logdir ?? this.getLogDir(),\n };\n }\n\n /**\n * Get an existing server if its config matches, otherwise stop the old\n * one and start a new server.\n *\n * Concurrent calls for the same server type are serialized via\n * `pendingStarts` to avoid spawning duplicate server processes.\n */\n private async getOrRestart(\n type: CodeQLServerType,\n config: ServerConfig,\n factory: () => CodeQLCLIServer | CodeQLLanguageServer | CodeQLQueryServer,\n ): Promise {\n // If another call is already starting a server of this type, wait for it\n // to settle (success or failure) and then re-check whether the result is\n // still usable.\n const inflight = this.pendingStarts.get(type);\n if (inflight) {\n try { await inflight; } catch { /* swallow \u2014 original caller handles the rejection */ }\n }\n\n const work = this.doGetOrRestart(type, config, factory);\n this.pendingStarts.set(type, work);\n try {\n return await work;\n } finally {\n // Ensure `work` has settled before removing the pendingStarts entry so\n // that concurrent callers waiting on the same promise see a consistent\n // map state. The try/catch avoids re-throwing a rejection that the\n // outer `try` block already handles.\n try { await work; } catch { /* already handled */ }\n if (this.pendingStarts.get(type) === work) {\n this.pendingStarts.delete(type);\n }\n }\n }\n\n /**\n * Core logic for getOrRestart, separated to allow serialization.\n */\n private async doGetOrRestart(\n type: CodeQLServerType,\n config: ServerConfig,\n factory: () => CodeQLCLIServer | CodeQLLanguageServer | CodeQLQueryServer,\n ): Promise {\n const hash = computeConfigHash(type, config);\n const existing = this.servers.get(type);\n\n // Reuse if config matches and server is still running\n if (existing && existing.configHash === hash && existing.server.isRunning()) {\n logger.debug(`Reusing existing ${type} server (hash: ${hash.substring(0, 8)})`);\n return existing.server;\n }\n\n // Config changed or server died \u2014 stop the old one\n if (existing) {\n logger.info(`${type} server config changed or dead, restarting...`);\n await this.stopServer(existing);\n this.servers.delete(type);\n }\n\n // Start a new server\n const server = factory();\n await server.start();\n\n this.servers.set(type, {\n configHash: hash,\n server,\n sessionId: this.sessionId,\n type,\n });\n\n logger.info(`${type} server started (hash: ${hash.substring(0, 8)})`);\n return server;\n }\n\n /**\n * Stop a managed server, ignoring errors.\n */\n private async stopServer(managed: ManagedServer): Promise {\n try {\n await managed.server.shutdown();\n } catch (error) {\n logger.warn(`Error stopping ${managed.type} server:`, error);\n // Best-effort \u2014 don't propagate\n }\n }\n}\n\n/**\n * Global server manager singleton.\n *\n * Initialized lazily by `getServerManager()`. The MCP server entry point\n * should call `initServerManager()` at startup and `shutdownServerManager()`\n * at graceful shutdown.\n */\nlet globalServerManager: CodeQLServerManager | null = null;\n\n/**\n * Initialize the global server manager (idempotent).\n */\nexport function initServerManager(options?: SessionCacheOptions): CodeQLServerManager {\n if (!globalServerManager) {\n globalServerManager = new CodeQLServerManager(options);\n }\n return globalServerManager;\n}\n\n/**\n * Get the global server manager, creating it if needed.\n */\nexport function getServerManager(): CodeQLServerManager {\n if (!globalServerManager) {\n globalServerManager = new CodeQLServerManager();\n }\n return globalServerManager;\n}\n\n/**\n * Shut down the global server manager and all its servers.\n */\nexport async function shutdownServerManager(): Promise {\n if (globalServerManager) {\n await globalServerManager.shutdownAll();\n globalServerManager = null;\n }\n}\n\n/**\n * Reset the global server manager (for testing only).\n */\nexport function resetServerManager(): void {\n globalServerManager = null;\n}\n", "/**\n * Generic CLI command execution utilities for CodeQL and QLT commands\n */\n\nimport { execFile } from 'child_process';\nimport { existsSync } from 'fs';\nimport { basename, delimiter, dirname, isAbsolute } from 'path';\nimport { promisify } from 'util';\nimport { logger } from '../utils/logger';\n\nconst execFileAsync = promisify(execFile);\n\nexport interface CLIExecutionResult {\n stdout: string;\n stderr: string;\n success: boolean;\n error?: string;\n exitCode?: number;\n}\n\nexport interface CLIExecutionOptions {\n command: string;\n args: string[];\n cwd?: string;\n timeout?: number;\n env?: Record;\n}\n\n// Whitelist of allowed commands to prevent arbitrary command execution\nconst ALLOWED_COMMANDS = new Set([\n 'codeql',\n 'git',\n 'node',\n 'npm',\n 'qlt',\n 'which'\n]);\n\n// Additional commands allowed in test environments\nlet testCommands: Set | null = null;\n\n// Whitelist of safe environment variables to pass to child processes\n// This prevents potentially malicious environment variables from being passed through\nconst SAFE_ENV_VARS = [\n 'HOME', // User home directory\n 'LANG', // Locale setting\n 'LC_ALL', // Locale setting\n 'LC_CTYPE', // Locale setting\n 'PATH', // Required to find executables\n 'SHELL', // User's shell (Unix)\n 'TEMP', // Temporary directory (Windows)\n 'TERM', // Terminal type (Unix)\n 'TMP', // Temporary directory (Windows)\n 'TMPDIR', // Temporary directory (Unix)\n 'USER', // Current user (Unix)\n 'USERNAME', // Current user (Windows)\n] as const;\n\n// Whitelist of safe environment variable prefixes\n// These are needed for CodeQL and Node.js functionality\nconst SAFE_ENV_PREFIXES = [\n 'CODEQL_', // CodeQL-specific variables\n 'NODE_', // Node.js-specific variables (for npm, etc.)\n] as const;\n\n// Pattern for dangerous control characters in CLI arguments\n// Rejected characters:\n// \\x01-\\x08: SOH through BS (start of heading, text, null control chars, backspace)\n// \\x0B: Vertical tab - rarely used legitimately, can cause display issues\n// \\x0C: Form feed - can cause unexpected page breaks in output\n// \\x0E-\\x1F: SO through US (shift out/in, device controls, separators)\n// Allowed characters:\n// \\x00: Null byte - handled separately for clearer error messaging\n// \\x09: Horizontal tab - commonly used in file paths and arguments\n// \\x0A: Newline (LF) - may appear in multi-line arguments\n// \\x0D: Carriage return (CR) - may appear with newlines on Windows\n// eslint-disable-next-line no-control-regex\nconst DANGEROUS_CONTROL_CHARS = /[\\x01-\\x08\\x0B\\x0C\\x0E-\\x1F]/;\n\n/**\n * Enable test-specific commands for testing purposes\n * This should only be called in test environments\n */\nexport function enableTestCommands(): void {\n testCommands = new Set([\n 'cat',\n 'echo',\n 'ls',\n 'sh',\n 'sleep'\n ]);\n}\n\n/**\n * Disable test-specific commands\n */\nexport function disableTestCommands(): void {\n testCommands = null;\n}\n\n/**\n * Check if a command is allowed\n */\nfunction isCommandAllowed(command: string): boolean {\n return ALLOWED_COMMANDS.has(command) || (testCommands !== null && testCommands.has(command));\n}\n\n// Resolved CodeQL binary directory from CODEQL_PATH.\n// When set, this directory is prepended to PATH for all child processes\n// so that `execFile('codeql', ...)` finds the correct binary via execvp().\n// Using PATH lookup (rather than an absolute path) is essential because\n// execvp() handles shell-script shebangs correctly, whereas passing an\n// absolute path to execFile() can fail with ENOENT for shell scripts.\nlet resolvedCodeQLDir: string | null = null;\n\n// Cached result from resolveCodeQLBinary(). `undefined` means not yet resolved.\nlet resolvedBinaryResult: string | undefined;\n\n/**\n * Resolve the CodeQL CLI binary path.\n *\n * Resolution order:\n * 1. `CODEQL_PATH` environment variable \u2014 must point to an existing file whose\n * basename is `codeql` (or `codeql.exe` / `codeql.cmd` on Windows).\n * The parent directory is prepended to PATH for child processes.\n * 2. Falls back to the bare `codeql` command (resolved via PATH at exec time).\n *\n * The resolved value is cached for the lifetime of the process. Call this once\n * at startup; subsequent calls are a no-op and return the cached value.\n */\nexport function resolveCodeQLBinary(): string {\n // Short-circuit if already resolved\n if (resolvedBinaryResult !== undefined) {\n return resolvedBinaryResult;\n }\n\n const envPath = process.env.CODEQL_PATH;\n\n if (!envPath) {\n resolvedCodeQLDir = null;\n resolvedBinaryResult = 'codeql';\n return resolvedBinaryResult;\n }\n\n // Validate the path points to a plausible CodeQL binary\n const base = basename(envPath).toLowerCase();\n const validBaseNames = ['codeql', 'codeql.exe', 'codeql.cmd'];\n if (!validBaseNames.includes(base)) {\n throw new Error(\n `CODEQL_PATH must point to a CodeQL CLI binary (expected basename: codeql), got: ${base}`\n );\n }\n\n // Require an absolute path to avoid ambiguity\n if (!isAbsolute(envPath)) {\n throw new Error(\n `CODEQL_PATH must be an absolute path, got: ${envPath}`\n );\n }\n\n // Verify the file exists\n if (!existsSync(envPath)) {\n throw new Error(\n `CODEQL_PATH points to a file that does not exist: ${envPath}`\n );\n }\n\n resolvedCodeQLDir = dirname(envPath);\n resolvedBinaryResult = 'codeql';\n logger.info(`CodeQL CLI resolved via CODEQL_PATH: ${envPath} (dir: ${resolvedCodeQLDir})`);\n return resolvedBinaryResult;\n}\n\n/**\n * Get the currently resolved CodeQL binary directory, or null if using PATH.\n */\nexport function getResolvedCodeQLDir(): string | null {\n return resolvedCodeQLDir;\n}\n\n/**\n * Reset the resolved CodeQL binary to the default (for testing only).\n */\nexport function resetResolvedCodeQLBinary(): void {\n resolvedCodeQLDir = null;\n resolvedBinaryResult = undefined;\n}\n\n/**\n * Validate that the resolved CodeQL binary is actually callable.\n *\n * Runs `codeql version --format=terse` and verifies the process exits\n * successfully. This catches the case where `CODEQL_PATH` is unset and\n * `codeql` is not on PATH \u2014 the server would otherwise start normally\n * but every tool invocation would fail.\n *\n * @returns The version string reported by the CodeQL CLI.\n * @throws Error if the binary is not reachable or returns a non-zero exit code.\n */\nexport async function validateCodeQLBinaryReachable(): Promise {\n const binary = resolvedBinaryResult ?? 'codeql';\n const env = { ...process.env };\n if (resolvedCodeQLDir) {\n env.PATH = resolvedCodeQLDir + delimiter + (env.PATH || '');\n }\n\n try {\n const { stdout } = await execFileAsync(binary, ['version', '--format=terse'], {\n env,\n timeout: 15_000,\n });\n return stdout.trim();\n } catch (err: unknown) {\n const message = err instanceof Error ? err.message : String(err);\n throw new Error(\n `CodeQL CLI is not reachable (binary: ${binary}). ` +\n `Ensure codeql is on PATH or set the CODEQL_PATH environment variable ` +\n `to the absolute path of the CodeQL CLI binary. Details: ${message}`,\n { cause: err }\n );\n }\n}\n\n/**\n * Sanitize a CLI argument to prevent potential issues with special characters.\n * \n * While execFile() does not spawn a shell (preventing shell injection), we still\n * validate arguments to:\n * 1. Reject null bytes that could truncate strings in C-based commands\n * 2. Reject control characters that could cause unexpected behavior\n * 3. Provide defense-in-depth against potential issues\n * \n * @param arg - The argument to sanitize\n * @returns The sanitized argument\n * @throws Error if the argument contains dangerous characters\n */\nexport function sanitizeCLIArgument(arg: string): string {\n // Reject null bytes - these can truncate strings in C-based commands\n // Error message intentionally excludes argument content to avoid logging potentially sensitive data\n if (arg.includes('\\0')) {\n throw new Error(`CLI argument contains null byte: argument rejected for security`);\n }\n \n // Reject control characters using the module-level constant pattern\n if (DANGEROUS_CONTROL_CHARS.test(arg)) {\n // Error message intentionally excludes argument content to avoid logging potentially sensitive data\n throw new Error(`CLI argument contains control characters: argument rejected for security`);\n }\n \n return arg;\n}\n\n/**\n * Sanitize an array of CLI arguments\n * @param args - The arguments to sanitize\n * @returns The sanitized arguments\n * @throws Error if any argument contains dangerous characters\n */\nexport function sanitizeCLIArguments(args: string[]): string[] {\n return args.map(sanitizeCLIArgument);\n}\n\n/**\n * Filter environment variables to only include safe ones\n * This prevents potentially malicious environment variables from being passed to child processes\n */\nfunction getSafeEnvironment(additionalEnv?: Record): Record {\n const safeEnv: Record = {};\n \n // Copy whitelisted environment variables from process.env\n for (const key of SAFE_ENV_VARS) {\n if (process.env[key] !== undefined) {\n safeEnv[key] = process.env[key]!;\n }\n }\n \n // Copy environment variables with whitelisted prefixes\n for (const [key, value] of Object.entries(process.env)) {\n if (value !== undefined && SAFE_ENV_PREFIXES.some(prefix => key.startsWith(prefix))) {\n safeEnv[key] = value;\n }\n }\n \n // When CODEQL_PATH was set, prepend the resolved directory to PATH so that\n // `execFile('codeql', ...)` finds the user-specified binary via execvp().\n // This approach (PATH manipulation + bare command name) is essential because\n // execvp() handles shell-script shebangs correctly, whereas passing an\n // absolute path to execFile() fails with ENOENT for shell-script launchers.\n if (resolvedCodeQLDir && safeEnv.PATH) {\n safeEnv.PATH = `${resolvedCodeQLDir}${delimiter}${safeEnv.PATH}`;\n } else if (resolvedCodeQLDir) {\n safeEnv.PATH = resolvedCodeQLDir;\n }\n \n // Merge with explicitly provided environment variables\n // These are trusted as they come from the application code, not external sources\n if (additionalEnv) {\n Object.assign(safeEnv, additionalEnv);\n }\n \n return safeEnv;\n}\n\n/**\n * Execute a CLI command and return the result.\n * \n * Security: This function uses execFile() instead of exec() to avoid shell interpretation.\n * Arguments are passed directly to the executable as an array, preventing shell injection.\n * Additional security measures include:\n * - Command whitelist validation\n * - Shell metacharacter detection in command names\n * - CLI argument sanitization (null bytes, control characters)\n * - Environment variable filtering\n */\nexport async function executeCLICommand(options: CLIExecutionOptions): Promise {\n try {\n const { command, args, cwd, timeout = 300000, env } = options; // 5 minute default timeout\n \n // Validate command is in the whitelist to prevent arbitrary command execution\n if (!isCommandAllowed(command)) {\n throw new Error(`Command not allowed: ${command}. Only whitelisted commands can be executed.`);\n }\n \n // Validate command to ensure it doesn't contain shell metacharacters\n if (command.includes(';') || command.includes('|') || command.includes('&') || \n command.includes('$') || command.includes('`') || command.includes('\\n') ||\n command.includes('\\r')) {\n throw new Error(`Invalid command: contains shell metacharacters: ${command}`);\n }\n \n // Sanitize CLI arguments to prevent issues with special characters\n // This provides defense-in-depth even though execFile() doesn't use a shell\n const sanitizedArgs = sanitizeCLIArguments(args);\n \n logger.info(`Executing CLI command: ${command}`, { args: sanitizedArgs, cwd, timeout });\n \n const execOptions = {\n cwd,\n timeout,\n env: getSafeEnvironment(env),\n };\n \n // execFile() is used instead of exec() to avoid shell interpretation\n // Arguments are passed as an array, not interpolated into a command string\n const { stdout, stderr } = await execFileAsync(command, sanitizedArgs, execOptions);\n\n return {\n stdout,\n stderr,\n success: true,\n exitCode: 0\n };\n\n } catch (error: unknown) {\n logger.error('CLI command execution failed:', error);\n \n const err = error as Error & { code?: number; stdout?: string; stderr?: string };\n const errorMessage = err instanceof Error ? err.message : String(error);\n const exitCode = err.code || 1;\n \n return {\n stdout: err.stdout || '',\n stderr: err.stderr || errorMessage,\n success: false,\n error: errorMessage,\n exitCode\n };\n }\n}\n\n/**\n * Build CodeQL command arguments with proper escaping\n */\nexport function buildCodeQLArgs(subcommand: string, options: Record): string[] {\n const args = [subcommand];\n \n // Single-letter parameters that should use -key=value format (with equals sign)\n // Note: CodeQL CLI uses -t=key=value format for metadata, not -t key=value\n const singleLetterParams = new Set(['t', 'o', 'v', 'q', 'h', 'J']);\n \n for (const [key, value] of Object.entries(options)) {\n if (value === undefined || value === null) {\n continue;\n }\n \n const isSingleLetter = key.length === 1 && singleLetterParams.has(key);\n \n if (typeof value === 'boolean') {\n if (value) {\n args.push(isSingleLetter ? `-${key}` : `--${key}`);\n }\n } else if (Array.isArray(value)) {\n // Handle array values (e.g., multiple -t flags for metadata)\n for (const item of value) {\n if (isSingleLetter) {\n // For single-letter params like -t, use -key=value format\n args.push(`-${key}=${String(item)}`);\n } else {\n // For long params, use --key=value format\n args.push(`--${key}=${String(item)}`);\n }\n }\n } else {\n // Handle string, number, and other values\n if (isSingleLetter) {\n // For single-letter params, use -key=value format\n args.push(`-${key}=${String(value)}`);\n } else {\n args.push(`--${key}=${String(value)}`);\n }\n }\n }\n \n return args;\n}\n\n/**\n * Build QLT command arguments with proper escaping\n */\nexport function buildQLTArgs(subcommand: string, options: Record): string[] {\n const args = [subcommand];\n \n for (const [key, value] of Object.entries(options)) {\n if (value === undefined || value === null) {\n continue;\n }\n \n if (typeof value === 'boolean') {\n if (value) {\n args.push(`--${key}`);\n }\n } else if (Array.isArray(value)) {\n // Handle array values\n for (const item of value) {\n args.push(`--${key}`, String(item));\n }\n } else {\n // Handle string, number, and other values\n args.push(`--${key}`, String(value));\n }\n }\n \n return args;\n}\n\n/**\n * CodeQL subcommands that MUST run as fresh processes.\n *\n * These cannot use the cli-server because they:\n * - Spawn extractors or other long-running child processes (database create, test extract)\n * - Produce multi-event NUL-delimited streams (test run)\n * - Are compound orchestration commands (database analyze)\n *\n * Everything else is routed through the persistent cli-server JVM for\n * sub-second execution instead of 2-5 s JVM cold-start per invocation.\n */\nconst FRESH_PROCESS_SUBCOMMANDS = new Set([\n 'database analyze',\n 'database create',\n 'test extract',\n 'test run',\n]);\n\n/**\n * Execute a CodeQL command.\n *\n * By default, commands are routed through the persistent `codeql execute\n * cli-server` process managed by {@link CodeQLServerManager}, eliminating\n * repeated JVM startup overhead (~2-5 s savings per call).\n *\n * Commands listed in {@link FRESH_PROCESS_SUBCOMMANDS} (e.g. `database create`,\n * `test run`) are always executed as fresh processes because they either spawn\n * child extractors, produce streaming output, or require a dedicated working\n * directory.\n *\n * If the cli-server is not available (e.g. during early startup before\n * `initServerManager()` is called), the function falls back transparently to\n * a fresh process.\n */\nexport async function executeCodeQLCommand(\n subcommand: string,\n options: Record,\n additionalArgs: string[] = [],\n cwd?: string\n): Promise {\n const args = buildCodeQLArgs(subcommand, options);\n args.push(...additionalArgs);\n\n // Determine whether this subcommand can use the persistent cli-server.\n // Commands that need a specific CWD also must use a fresh process because\n // the cli-server's CWD is fixed at startup.\n const canUseCLIServer = !FRESH_PROCESS_SUBCOMMANDS.has(subcommand) && !cwd;\n\n if (canUseCLIServer) {\n try {\n // Lazy-import to avoid circular dependency at module level.\n // Use getServerManager() (not initServerManager()) \u2014 if the manager\n // hasn't been initialized yet (e.g. during tests or early startup),\n // this creates one, but we only attempt to *use* the cli-server if\n // it is already running (warmed up at MCP server startup). We never\n // block on starting a new cli-server here \u2014 that would add JVM\n // startup latency to the first fresh-process-fallback call.\n const { getServerManager } = await import('./server-manager');\n const manager = getServerManager();\n\n if (manager.isRunning('cli')) {\n const cliServer = await manager.getCLIServer({});\n const sanitizedArgs = sanitizeCLIArguments(args);\n\n logger.info(`Executing CodeQL command via cli-server: ${subcommand}`, { args: sanitizedArgs });\n\n const stdout = await cliServer.runCommand(sanitizedArgs);\n\n return {\n stdout,\n stderr: '',\n success: true,\n exitCode: 0,\n };\n } else {\n logger.debug(`cli-server not yet running for \"${subcommand}\", using fresh process`);\n }\n } catch (error) {\n // If the cli-server call fails, check whether it's a command-level\n // error (the CLI returned non-zero) or a transport/startup error.\n // For transport errors we fall back to a fresh process; for command\n // errors we return the failure directly.\n const message = error instanceof Error ? error.message : String(error);\n\n // Transport-level errors that warrant a fallback:\n if (message.includes('CLI server is not running') ||\n message.includes('CLI server exited') ||\n message.includes('failed to start')) {\n logger.warn(`cli-server unavailable for \"${subcommand}\", falling back to fresh process: ${message}`);\n // Fall through to fresh-process execution below\n } else {\n // Command-level error \u2014 return it as a failed result\n logger.error(`cli-server command failed for \"${subcommand}\": ${message}`);\n return {\n stdout: '',\n stderr: message,\n success: false,\n error: message,\n exitCode: 1,\n };\n }\n }\n }\n\n // Fresh-process execution (for FRESH_PROCESS_SUBCOMMANDS, CWD-specific\n // calls, or as a fallback when the cli-server is unavailable).\n // Use 0 (no timeout) because CodeQL operations such as query evaluation,\n // database analysis, profiling, and test runs are inherently long-running\n // and should not be killed by a process timeout.\n return executeCLICommand({\n command: 'codeql',\n args,\n cwd,\n timeout: 0\n });\n}\n\n/**\n * Execute a QLT command\n */\nexport async function executeQLTCommand(\n subcommand: string, \n options: Record, \n additionalArgs: string[] = []\n): Promise {\n const args = buildQLTArgs(subcommand, options);\n args.push(...additionalArgs);\n \n return executeCLICommand({\n command: 'qlt',\n args\n });\n}\n\n/**\n * Get help text for a CLI command\n */\nexport async function getCommandHelp(command: string, subcommand?: string): Promise {\n const args = subcommand ? [subcommand, '--help'] : ['--help'];\n \n const result = await executeCLICommand({\n command,\n args\n });\n \n return result.stdout || result.stderr || 'No help available';\n}\n\n/**\n * Validate that a command exists on the system.\n */\nexport async function validateCommandExists(command: string): Promise {\n try {\n const result = await executeCLICommand({\n command: 'which',\n args: [command]\n });\n return result.success;\n } catch {\n return false;\n }\n}", "/**\n * CodeQL Development MCP McpServer\n * Main entry point for the server\n */\n\nimport { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';\nimport { StreamableHTTPServerTransport } from '@modelcontextprotocol/sdk/server/streamableHttp.js';\nimport express from 'express';\nimport cors from 'cors';\nimport dotenv from 'dotenv';\nimport { realpathSync } from 'fs';\nimport { resolve } from 'path';\nimport { pathToFileURL } from 'url';\nimport { registerCodeQLTools, registerCodeQLResources } from './tools';\nimport { registerLSPTools } from './tools/lsp';\nimport { registerLanguageResources } from './resources/language-resources';\nimport { registerWorkflowPrompts } from './prompts/workflow-prompts';\nimport { registerMonitoringTools } from './tools/monitoring-tools';\nimport { sessionDataManager } from './lib/session-data-manager';\nimport { resolveCodeQLBinary, validateCodeQLBinaryReachable } from './lib/cli-executor';\nimport { initServerManager, shutdownServerManager } from './lib/server-manager';\nimport { packageRootDir } from './utils/package-paths';\nimport { logger } from './utils/logger';\n\n// Load environment variables from a .env file co-located with the package root.\n// Uses the package directory (not CWD) so that npm-installed users don't\n// accidentally inherit a .env from their project.\n// Set DOTENV_CONFIG_QUIET to suppress the dotenv banner that would otherwise\n// leak to stdout and corrupt the MCP stdio JSON-RPC channel.\ndotenv.config({ path: resolve(packageRootDir, '.env'), quiet: true });\n\nconst PACKAGE_NAME = 'codeql-development-mcp-server';\nconst VERSION = '2.24.1';\n\n/**\n * Start the MCP server\n */\nexport async function startServer(mode: 'stdio' | 'http' = 'stdio'): Promise {\n logger.info(`Starting CodeQL Development MCP McpServer v${VERSION} in ${mode} mode`);\n\n // Resolve the CodeQL CLI binary path (honors CODEQL_PATH env var).\n // This must happen before any tool registration so that all CodeQL commands\n // use the user-specified binary.\n const codeqlBinary = resolveCodeQLBinary();\n logger.info(`CodeQL CLI binary: ${codeqlBinary}`);\n\n // Validate that the resolved binary is actually callable. This catches\n // misconfigurations early (e.g. codeql not on PATH and CODEQL_PATH unset)\n // instead of failing silently and producing confusing tool-level errors.\n const codeqlVersion = await validateCodeQLBinaryReachable();\n logger.info(`CodeQL CLI version: ${codeqlVersion}`);\n\n const server = new McpServer({\n name: PACKAGE_NAME,\n version: VERSION,\n });\n\n // Register CodeQL tools (legacy high-level helpers)\n registerCodeQLTools(server);\n\n // Register LSP-based tools (diagnostics, completion, definition, references)\n registerLSPTools(server);\n\n // Register CodeQL resources (static guides)\n registerCodeQLResources(server);\n\n // Register language-specific resources (AST references, security patterns)\n registerLanguageResources(server);\n\n // Register high-level workflow prompts (complete development workflows)\n registerWorkflowPrompts(server);\n\n // Register monitoring and reporting tools\n registerMonitoringTools(server);\n\n // Initialize session data manager\n await sessionDataManager.initialize();\n\n // Initialize the CodeQL background server manager and eagerly start the\n // language server and CLI server JVMs so they are warm when the first tool\n // calls arrive. This avoids 2-60 s cold-start penalties per JVM.\n const manager = initServerManager();\n Promise.all([\n manager.warmUpLanguageServer(),\n manager.warmUpCLIServer(),\n ]).catch(() => { /* individual errors logged inside each warm-up method */ });\n\n if (mode === 'stdio') {\n const transport = new StdioServerTransport();\n await server.connect(transport);\n logger.info('McpServer started successfully on STDIO transport');\n } else {\n // HTTP mode\n const app = express();\n app.use(cors());\n app.use(express.json());\n\n const transport = new StreamableHTTPServerTransport({\n sessionIdGenerator: () => Math.random().toString(36).substring(7),\n });\n await server.connect(transport);\n\n app.all('/mcp', (req, res) => {\n transport.handleRequest(req, res, req.body).catch((err) => {\n logger.error('Error handling MCP request:', err);\n if (!res.headersSent) {\n res.status(500).json({ error: 'Internal McpServer Error' });\n }\n });\n });\n\n app.get('/', (_req, res) => {\n res.json({\n name: PACKAGE_NAME,\n version: VERSION,\n description: 'CodeQL Development MCP McpServer',\n status: 'running',\n });\n });\n\n const host = process.env.HTTP_HOST || 'localhost';\n const port = Number(process.env.HTTP_PORT || process.env.PORT) || 3000;\n \n // Return a promise that keeps the process alive\n return new Promise((resolve, reject) => {\n const httpServer = app.listen(port, host, () => {\n logger.info(`HTTP server listening on http://${host}:${port}/mcp`);\n resolve();\n });\n \n httpServer.on('error', (error) => {\n logger.error('HTTP server error:', error);\n reject(error);\n });\n });\n }\n\n setupGracefulShutdown(server);\n return server;\n}\n\n/**\n * Set up graceful shutdown handling\n */\nfunction setupGracefulShutdown(server: McpServer): void {\n const shutdown = async () => {\n logger.info('Shutting down server...');\n try {\n // Shut down all CodeQL background servers first\n await shutdownServerManager();\n await server.close();\n logger.info('McpServer closed gracefully');\n process.exit(0);\n } catch (error) {\n logger.error('Error during shutdown:', error);\n process.exit(1);\n }\n };\n\n process.on('SIGINT', shutdown);\n process.on('SIGTERM', shutdown);\n}\n\n/**\n * Main function to start the server\n */\nasync function main(): Promise {\n try {\n const transportMode = (process.env.TRANSPORT_MODE || 'stdio').toLowerCase();\n const mode: 'stdio' | 'http' = transportMode === 'http' ? 'http' : 'stdio';\n await startServer(mode);\n } catch (error) {\n logger.error('Failed to start server:', error);\n process.exit(1);\n }\n}\n\n// Start the server if this file is run directly.\n// Use realpathSync to resolve npm/npx symlinks so the guard works for both\n// direct invocation and globally-installed npm bin entries.\nconst scriptPath = process.argv[1] ? realpathSync(resolve(process.argv[1])) : undefined;\nif (scriptPath && import.meta.url === pathToFileURL(scriptPath).href) {\n main();\n}\n", "/**\n * CodeQL BQRS decode tool\n *\n * Decodes BQRS (Binary Query Result Set) files to human-readable formats.\n * Use `list_query_run_results` to discover BQRS files from previous query runs,\n * then decode them with this tool. For long-running queries (codeql_query_run)\n * or suites (codeql_database_analyze), the BQRS file is located at\n * `/results.bqrs`. Use `codeql_bqrs_info` first to discover available\n * result sets and column schemas.\n */\n\nimport { z } from 'zod';\nimport { CLIToolDefinition, createCodeQLSchemas, createBQRSResultProcessor } from '../../lib/cli-tool-registry';\n\nexport const codeqlBqrsDecodeTool: CLIToolDefinition = {\n name: 'codeql_bqrs_decode',\n description:\n 'Decode BQRS result files to human-readable formats (text, csv, json). ' +\n 'Typical workflow: (1) use list_query_run_results to find BQRS paths from previous codeql_query_run or codeql_database_analyze runs, ' +\n '(2) use codeql_bqrs_info to discover result sets and column schemas, ' +\n '(3) decode specific result sets with this tool. ' +\n 'For large result sets, use --rows to paginate.',\n command: 'codeql',\n subcommand: 'bqrs decode',\n inputSchema: {\n files: z.array(z.string()).describe('BQRS file(s) to decode'),\n output: createCodeQLSchemas.output(),\n format: z.enum(['csv', 'json', 'text', 'bqrs']).optional()\n .describe('Output format: text (human-readable table, default), csv, json (streaming JSON), or bqrs (binary, requires --output)'),\n 'result-set': z.string().optional()\n .describe('Decode a specific result set by name (use codeql_bqrs_info to list available sets). If omitted, all result sets are decoded.'),\n 'sort-key': z.string().optional()\n .describe('Sort by column(s): comma-separated column indices (0-based)'),\n 'sort-direction': z.string().optional()\n .describe('Sort direction(s): comma-separated \"asc\" or \"desc\" per column'),\n 'no-titles': z.boolean().optional()\n .describe('Omit column titles for text and csv formats'),\n entities: z.string().optional()\n .describe('Control entity column display: comma-separated list of url, string, id, all'),\n rows: z.number().optional()\n .describe('Maximum number of rows to output (for pagination). Use with --start-at for paging.'),\n 'start-at': z.number().optional()\n .describe('Byte offset to start decoding from (get from codeql_bqrs_info or previous JSON output \"next\" pointer). Must be used with --rows.'),\n verbose: createCodeQLSchemas.verbose(),\n additionalArgs: createCodeQLSchemas.additionalArgs()\n },\n examples: [\n 'codeql bqrs decode --format=csv --output=results.csv results.bqrs',\n 'codeql bqrs decode --format=json --rows=100 results.bqrs',\n 'codeql bqrs decode --result-set=#select --format=csv results.bqrs',\n 'codeql bqrs decode --format=json --entities=url,string results.bqrs'\n ],\n resultProcessor: createBQRSResultProcessor()\n};", "/**\n * Generic tool registry for creating MCP tools from CLI command definitions\n */\n\nimport { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport { z } from 'zod';\nimport { executeCodeQLCommand, executeQLTCommand, CLIExecutionResult } from './cli-executor';\nimport { logger } from '../utils/logger';\nimport { evaluateQueryResults, QueryEvaluationResult, extractQueryMetadata } from './query-results-evaluator';\nimport { getOrCreateLogDirectory } from './log-directory-manager';\nimport { getUserWorkspaceDir, packageRootDir, resolveToolQueryPackPath } from '../utils/package-paths';\nimport { writeFileSync, rmSync, existsSync, mkdirSync } from 'fs';\nimport { basename, dirname, isAbsolute, join, resolve } from 'path';\nimport { createProjectTempDir } from '../utils/temp-dir';\n\nexport type { CLIExecutionResult } from './cli-executor';\n\nexport interface CLIToolDefinition {\n name: string;\n description: string;\n command: 'codeql' | 'qlt';\n subcommand: string;\n inputSchema: Record;\n examples?: string[];\n resultProcessor?: (_result: CLIExecutionResult, _params: Record) => string;\n}\n\n/**\n * Default result processor that formats CLI output appropriately\n */\nexport const defaultCLIResultProcessor = (\n result: CLIExecutionResult, \n _params: Record\n): string => {\n if (!result.success) {\n return `Command failed (exit code ${result.exitCode || 'unknown'}):\\n${result.error || result.stderr}`;\n }\n \n let output = '';\n \n if (result.stdout) {\n output += result.stdout;\n }\n \n if (result.stderr) {\n if (output) {\n output += '\\n\\nWarnings/Info:\\n';\n }\n output += result.stderr;\n }\n \n if (!output) {\n output = 'Command executed successfully (no output)';\n }\n \n return output;\n};\n\n/**\n * Register a CLI tool with the MCP server\n */\nexport function registerCLITool(server: McpServer, definition: CLIToolDefinition): void {\n const {\n name,\n description,\n command,\n subcommand,\n inputSchema,\n resultProcessor = defaultCLIResultProcessor\n } = definition;\n\n server.tool(\n name,\n description,\n inputSchema,\n async (params: Record) => {\n // Track temporary directories for cleanup\n const tempDirsToCleanup: string[] = [];\n \n try {\n logger.info(`Executing CLI tool: ${name}`, { command, subcommand, params });\n\n // Separate positional arguments from named options\n // Extract tool-specific parameters that should not be passed to CLI\n // Note: format is extracted for tools that use it internally but not on CLI\n // For codeql_bqrs_interpret, codeql_bqrs_decode, codeql_bqrs_info, codeql_generate_query-help, and codeql_database_analyze, format should be passed to CLI\n const formatShouldBePassedToCLI = name === 'codeql_bqrs_interpret' || name === 'codeql_bqrs_decode' || name === 'codeql_bqrs_info' || name === 'codeql_generate_query-help' || name === 'codeql_database_analyze';\n \n const extractedParams = formatShouldBePassedToCLI\n ? {\n _positional: params._positional || [],\n files: params.files,\n file: params.file,\n dir: params.dir,\n packDir: params.packDir,\n tests: params.tests,\n query: params.query,\n queryName: params.queryName,\n queryLanguage: params.queryLanguage,\n queryPack: params.queryPack,\n sourceFiles: params.sourceFiles,\n sourceFunction: params.sourceFunction,\n targetFunction: params.targetFunction,\n interpretedOutput: params.interpretedOutput,\n evaluationFunction: params.evaluationFunction,\n evaluationOutput: params.evaluationOutput,\n directory: params.directory,\n logDir: params.logDir,\n qlref: params.qlref\n }\n : {\n _positional: params._positional || [],\n files: params.files,\n file: params.file,\n dir: params.dir,\n packDir: params.packDir,\n tests: params.tests,\n query: params.query,\n queryName: params.queryName,\n queryLanguage: params.queryLanguage,\n queryPack: params.queryPack, \n sourceFiles: params.sourceFiles,\n sourceFunction: params.sourceFunction,\n targetFunction: params.targetFunction,\n format: params.format,\n interpretedOutput: params.interpretedOutput,\n evaluationFunction: params.evaluationFunction,\n evaluationOutput: params.evaluationOutput,\n directory: params.directory,\n logDir: params.logDir,\n qlref: params.qlref\n };\n\n const {\n _positional = [],\n files,\n file,\n dir,\n packDir,\n tests,\n query,\n queryName,\n queryLanguage: _queryLanguage,\n queryPack: _queryPack,\n sourceFiles,\n sourceFunction,\n targetFunction,\n format: _format,\n interpretedOutput: _interpretedOutput,\n evaluationFunction: _evaluationFunction,\n evaluationOutput: _evaluationOutput,\n directory,\n logDir: customLogDir,\n qlref,\n } = extractedParams;\n\n // Get remaining options (everything not extracted above)\n const options = {...params};\n Object.keys(extractedParams).forEach(key => delete options[key]);\n let positionalArgs = Array.isArray(_positional) ? _positional as string[] : [_positional as string];\n\n // Handle files parameter as positional arguments for certain tools\n if (files && Array.isArray(files)) {\n positionalArgs = [...positionalArgs, ...files as string[]];\n }\n\n // Handle file parameter as positional argument for BQRS tools\n if (file && name.startsWith('codeql_bqrs_')) {\n positionalArgs = [...positionalArgs, file as string];\n }\n\n // Handle qlref parameter as positional argument for resolve qlref tool\n if (qlref && name === 'codeql_resolve_qlref') {\n positionalArgs = [...positionalArgs, qlref as string];\n }\n\n // Handle database parameter as positional argument for resolve database tool\n if (options.database && name === 'codeql_resolve_database') {\n positionalArgs = [...positionalArgs, options.database as string];\n delete options.database;\n }\n\n // Handle database parameter as positional argument for database create tool\n if (options.database && name === 'codeql_database_create') {\n positionalArgs = [...positionalArgs, options.database as string];\n delete options.database;\n }\n\n // Handle database and queries parameters as positional arguments for database analyze tool\n if (name === 'codeql_database_analyze') {\n if (options.database) {\n positionalArgs = [...positionalArgs, options.database as string];\n delete options.database;\n }\n if (options.queries) {\n positionalArgs = [...positionalArgs, options.queries as string];\n delete options.queries;\n }\n }\n\n // Handle query parameter as positional argument for generate query-help tool\n if (query && name === 'codeql_generate_query-help') {\n positionalArgs = [...positionalArgs, query as string];\n }\n\n // Handle dir parameter as positional argument for pack tools\n if (dir && (name === 'codeql_pack_ls')) {\n positionalArgs = [...positionalArgs, dir as string];\n }\n \n // Handle tool-specific parameters using switch pattern for better maintainability\n switch (name) {\n case 'codeql_test_accept':\n case 'codeql_test_extract':\n case 'codeql_test_run':\n case 'codeql_resolve_tests':\n // Handle tests parameter as positional arguments for test tools.\n // Resolve relative paths against the user's effective workspace\n // directory. In monorepo layouts this is the repo root; in npm-\n // installed layouts it falls back to process.cwd().\n if (tests && Array.isArray(tests)) {\n const userDir = getUserWorkspaceDir();\n positionalArgs = [...positionalArgs, ...(tests as string[]).map(\n t => isAbsolute(t) ? t : resolve(userDir, t)\n )];\n }\n break;\n \n case 'codeql_query_run': {\n // Resolve database path to absolute path if it's relative\n if (options.database && typeof options.database === 'string' && !isAbsolute(options.database)) {\n options.database = resolve(getUserWorkspaceDir(), options.database);\n logger.info(`Resolved database path to: ${options.database}`);\n }\n \n // Implement query resolution logic with enhanced results processing\n const resolvedQuery = await resolveQueryPath(params, logger);\n if (resolvedQuery) {\n positionalArgs = [...positionalArgs, resolvedQuery];\n } else if (query) {\n positionalArgs = [...positionalArgs, query as string];\n }\n \n // Handle external predicates for tool queries\n if (queryName === 'PrintAST' && sourceFiles) {\n // Create a CSV file with the source file paths for the external predicate\n // The external predicate expects a CSV file with one column containing file paths\n const filePaths = (sourceFiles as string).split(',').map((f: string) => f.trim());\n let tempDir: string;\n let csvPath: string;\n try {\n tempDir = createProjectTempDir('codeql-external-');\n tempDirsToCleanup.push(tempDir); // Track for cleanup\n csvPath = join(tempDir, 'selectedSourceFiles.csv');\n\n // Create CSV content\n const csvContent = filePaths.join('\\n') + '\\n';\n\n writeFileSync(csvPath, csvContent, 'utf8');\n } catch (err) {\n logger.error(`Failed to create external predicate CSV for PrintAST query at path ${csvPath || '[unknown]'}: ${err instanceof Error ? err.message : String(err)}`);\n throw err;\n }\n \n // Add the external predicate with the CSV file path\n const currentExternal = options.external || [];\n const externalArray = Array.isArray(currentExternal) ? currentExternal : [currentExternal];\n externalArray.push(`selectedSourceFiles=${csvPath}`);\n options.external = externalArray;\n \n logger.info(`Created external predicate CSV at ${csvPath} for files: ${filePaths.join(', ')}`);\n }\n \n // Handle external predicates for CallGraphFrom queries\n if (queryName === 'CallGraphFrom' && sourceFunction) {\n const functionNames = (sourceFunction as string).split(',').map((f: string) => f.trim());\n let tempDir: string;\n let csvPath: string;\n try {\n tempDir = createProjectTempDir('codeql-external-');\n tempDirsToCleanup.push(tempDir);\n csvPath = join(tempDir, 'sourceFunction.csv');\n\n // Create CSV content\n const csvContent = functionNames.join('\\n') + '\\n';\n\n writeFileSync(csvPath, csvContent, 'utf8');\n } catch (err) {\n logger.error(`Failed to create external predicate CSV for CallGraphFrom query at path ${csvPath || '[unknown]'}: ${err instanceof Error ? err.message : String(err)}`);\n throw err;\n }\n \n // Add the external predicate with the CSV file path\n const currentExternal = options.external || [];\n const externalArray = Array.isArray(currentExternal) ? currentExternal : [currentExternal];\n externalArray.push(`sourceFunction=${csvPath}`);\n options.external = externalArray;\n \n logger.info(`Created external predicate CSV at ${csvPath} for functions: ${functionNames.join(', ')}`);\n }\n \n // Handle external predicates for CallGraphTo queries\n if (queryName === 'CallGraphTo' && targetFunction) {\n const functionNames = (targetFunction as string).split(',').map((f: string) => f.trim());\n let tempDir: string;\n let csvPath: string;\n try {\n tempDir = createProjectTempDir('codeql-external-');\n tempDirsToCleanup.push(tempDir);\n csvPath = join(tempDir, 'targetFunction.csv');\n\n // Create CSV content\n const csvContent = functionNames.join('\\n') + '\\n';\n\n writeFileSync(csvPath, csvContent, 'utf8');\n } catch (err) {\n logger.error(`Failed to create external predicate CSV for CallGraphTo query at path ${csvPath || '[unknown]'}: ${err instanceof Error ? err.message : String(err)}`);\n throw err;\n }\n \n // Add the external predicate with the CSV file path\n const currentExternal = options.external || [];\n const externalArray = Array.isArray(currentExternal) ? currentExternal : [currentExternal];\n externalArray.push(`targetFunction=${csvPath}`);\n options.external = externalArray;\n \n logger.info(`Created external predicate CSV at ${csvPath} for functions: ${functionNames.join(', ')}`);\n }\n break;\n }\n \n case 'codeql_query_compile':\n case 'codeql_resolve_metadata':\n // Handle query parameter as positional argument for query compilation and metadata tools\n if (query) {\n positionalArgs = [...positionalArgs, query as string];\n }\n break;\n \n case 'codeql_resolve_queries':\n // Handle directory parameter as positional argument\n if (directory) {\n positionalArgs = [...positionalArgs, directory as string];\n }\n break;\n \n default:\n // No special parameter handling needed for other tools\n break;\n }\n\n // Set up logging directory for query/test/analyze runs\n let queryLogDir: string | undefined;\n if (name === 'codeql_query_run' || name === 'codeql_test_run' || name === 'codeql_database_analyze') {\n queryLogDir = getOrCreateLogDirectory(customLogDir as string | undefined);\n logger.info(`Using log directory for ${name}: ${queryLogDir}`);\n\n // Create timestamp file to track when query/test run started\n const timestampPath = join(queryLogDir, 'timestamp');\n writeFileSync(timestampPath, Date.now().toString(), 'utf8');\n\n // Set the --logdir option for CodeQL CLI\n options.logdir = queryLogDir;\n\n // Set verbosity to progress+ to generate detailed query.log/test.log\n if (!options.verbosity) {\n options.verbosity = 'progress+';\n }\n\n // Set evaluator-log if not explicitly provided\n if (!options['evaluator-log']) {\n options['evaluator-log'] = join(queryLogDir, 'evaluator-log.jsonl');\n }\n\n // Enable --tuple-counting by default for evaluator logging\n if (options['tuple-counting'] === undefined) {\n options['tuple-counting'] = true;\n }\n\n // For query run, also handle default output\n if (name === 'codeql_query_run') {\n // If output was not explicitly provided, set it to the log directory\n if (!options.output) {\n options.output = join(queryLogDir, 'results.bqrs');\n }\n }\n\n // Ensure the parent directory of --output exists (the CLI will not create it)\n if (options.output && typeof options.output === 'string') {\n const outputDir = dirname(options.output);\n mkdirSync(outputDir, { recursive: true });\n }\n }\n\n let result: CLIExecutionResult;\n \n if (command === 'codeql') {\n // For pack commands, set the working directory to where qlpack.yml is located.\n // Resolve to absolute path since the MCP server's cwd may differ from\n // the workspace root (especially when launched by VS Code).\n let cwd: string | undefined;\n if ((name === 'codeql_pack_install' || name === 'codeql_pack_ls') && (dir || packDir)) {\n const rawCwd = (dir || packDir) as string;\n // Resolve relative paths against the user's effective workspace\n // directory rather than a potentially read-only package root.\n cwd = isAbsolute(rawCwd) ? rawCwd : resolve(getUserWorkspaceDir(), rawCwd);\n }\n \n // Add --additional-packs for commands that need to access local test packs.\n // Only set the default examples path when it actually exists on disk\n // (it may be absent in npm-installed layouts where ql/javascript/examples/\n // is not included in the published package).\n const defaultExamplesPath = resolve(packageRootDir, 'ql', 'javascript', 'examples');\n const additionalPacksPath = process.env.CODEQL_ADDITIONAL_PACKS\n || (existsSync(defaultExamplesPath) ? defaultExamplesPath : undefined);\n if (additionalPacksPath && (name === 'codeql_test_run' || name === 'codeql_query_run' || name === 'codeql_query_compile' || name === 'codeql_database_analyze')) {\n options['additional-packs'] = additionalPacksPath;\n }\n \n // Keep test databases for codeql_test_run to allow subsequent query runs\n if (name === 'codeql_test_run') {\n options['keep-databases'] = true;\n }\n \n result = await executeCodeQLCommand(subcommand, options, positionalArgs, cwd);\n } else if (command === 'qlt') {\n result = await executeQLTCommand(subcommand, options, positionalArgs);\n } else {\n throw new Error(`Unsupported command: ${command}`);\n }\n\n // Post-execution processing for codeql_query_run\n if (name === 'codeql_query_run' && result.success && queryLogDir) {\n // Generate SARIF interpretation if results.bqrs exists and query path is known\n const bqrsPath = options.output as string;\n const sarifPath = join(queryLogDir, 'results-interpreted.sarif');\n\n // The query file path is the last positional argument (set during query resolution)\n const queryFilePath = positionalArgs.length > 0 ? positionalArgs[positionalArgs.length - 1] : undefined;\n\n if (existsSync(bqrsPath) && queryFilePath) {\n try {\n const sarifResult = await interpretBQRSFile(\n bqrsPath,\n queryFilePath,\n 'sarif-latest',\n sarifPath,\n logger\n );\n\n if (sarifResult.success) {\n logger.info(`Generated SARIF interpretation at ${sarifPath}`);\n } else {\n logger.warn(`SARIF interpretation returned error: ${sarifResult.error || sarifResult.stderr}`);\n }\n } catch (error) {\n logger.warn(`Failed to generate SARIF interpretation: ${error}`);\n }\n } else if (existsSync(bqrsPath) && !queryFilePath) {\n logger.warn('Skipping SARIF interpretation: query file path not available');\n }\n\n // Process evaluation results\n result = await processQueryRunResults(result, params, logger);\n }\n\n // Post-execution: generate evaluator log summary for query run / database analyze\n if ((name === 'codeql_query_run' || name === 'codeql_database_analyze') && result.success && queryLogDir) {\n const evalLogPath = options['evaluator-log'] as string | undefined;\n if (evalLogPath && existsSync(evalLogPath)) {\n try {\n const summaryPath = evalLogPath.replace(/\\.jsonl$/, '.summary.jsonl');\n // codeql generate log-summary takes positional args: []\n const summaryResult = await executeCodeQLCommand(\n 'generate log-summary',\n { format: 'predicates' },\n [evalLogPath, summaryPath]\n );\n\n if (summaryResult.success) {\n logger.info(`Generated evaluator log summary at ${summaryPath}`);\n }\n } catch (error) {\n logger.warn(`Failed to generate evaluator log summary: ${error}`);\n }\n }\n }\n\n // Process the result\n const processedResult = resultProcessor(result, params);\n\n return {\n content: [{\n type: 'text' as const,\n text: processedResult\n }],\n isError: !result.success\n };\n\n } catch (error) {\n logger.error(`Error in CLI tool ${name}:`, error);\n \n return {\n content: [{\n type: 'text' as const,\n text: `Failed to execute CLI tool: ${error instanceof Error ? error.message : String(error)}`\n }],\n isError: true\n };\n } finally {\n // Clean up temporary directories\n for (const tempDir of tempDirsToCleanup) {\n try {\n rmSync(tempDir, { recursive: true, force: true });\n logger.info(`Cleaned up temporary directory: ${tempDir}`);\n } catch (cleanupError) {\n logger.error(`Failed to clean up temporary directory ${tempDir}:`, cleanupError);\n }\n }\n }\n }\n );\n}\n\n/**\n * Helper function to create common CodeQL input schemas\n */\nexport const createCodeQLSchemas = {\n database: () => z.string().describe('Path to the CodeQL database'),\n \n query: () => z.string().describe('Path to the CodeQL query file (.ql)'),\n \n output: () => z.string().optional().describe('Output file path'),\n \n outputFormat: () => z.enum(['csv', 'json', 'bqrs', 'sarif-latest', 'sarifv2.1.0']).optional()\n .describe('Output format for results'),\n \n language: () => z.string().optional().describe('Programming language'),\n \n threads: () => z.number().optional().describe('Number of threads to use'),\n \n ram: () => z.number().optional().describe('Amount of RAM to use (MB)'),\n \n timeout: () => z.number().optional().describe('Timeout in seconds'),\n \n verbose: () => z.boolean().optional().describe('Enable verbose output'),\n \n additionalArgs: () => z.array(z.string()).optional().describe('Additional command-line arguments'),\n \n positionalArgs: () => z.array(z.string()).optional().describe('Positional arguments')\n .transform((val) => ({ _positional: val }))\n};\n\n/**\n * Helper function to create common QLT input schemas\n */\nexport const createQLTSchemas = {\n language: () => z.string().describe('Programming language'),\n \n output: () => z.string().optional().describe('Output directory or file path'),\n \n template: () => z.string().optional().describe('Template to use'),\n \n name: () => z.string().optional().describe('Name for generated query'),\n \n description: () => z.string().optional().describe('Description for generated query'),\n \n verbose: () => z.boolean().optional().describe('Enable verbose output'),\n \n force: () => z.boolean().optional().describe('Force overwrite existing files'),\n \n additionalArgs: () => z.array(z.string()).optional().describe('Additional command-line arguments')\n};\n\n/**\n * Create a result processor that formats BQRS output specially\n */\nexport const createBQRSResultProcessor = () => (\n result: CLIExecutionResult, \n params: Record\n): string => {\n if (!result.success) {\n return defaultCLIResultProcessor(result, params);\n }\n \n // For BQRS commands, provide more context about the output\n let output = result.stdout;\n \n if (params.output) {\n output += `\\n\\nResults saved to: ${params.output}`;\n }\n \n if (result.stderr) {\n output += `\\n\\nAdditional information:\\n${result.stderr}`;\n }\n \n return output;\n};\n\n/**\n * Create a result processor that formats database creation output\n */\nexport const createDatabaseResultProcessor = () => (\n result: CLIExecutionResult, \n params: Record\n): string => {\n if (!result.success) {\n return defaultCLIResultProcessor(result, params);\n }\n \n let output = 'Database creation completed successfully';\n \n if (params.database || params._positional) {\n const dbPath = params.database || (Array.isArray(params._positional) ? params._positional[0] : params._positional);\n output += `\\n\\nDatabase location: ${dbPath}`;\n }\n \n if (result.stdout) {\n output += `\\n\\nOutput:\\n${result.stdout}`;\n }\n \n if (result.stderr) {\n output += `\\n\\nAdditional information:\\n${result.stderr}`;\n }\n \n return output;\n};\n\n/**\n * Resolve query path for codeql_query_run tool\n * If queryName and queryLanguage are provided, resolve using codeql resolve queries\n */\nasync function resolveQueryPath(\n params: Record, \n logger: { info: (_message: string, ..._args: unknown[]) => void; error: (_message: string, ..._args: unknown[]) => void }\n): Promise {\n const { queryName, queryLanguage, queryPack, query } = params;\n \n // Validate parameter usage - queryName and query are mutually exclusive\n if (queryName && query) {\n logger.error('Cannot use both \"query\" and \"queryName\" parameters simultaneously. Use either \"query\" for direct file path OR \"queryName\" + \"queryLanguage\" for tool queries.');\n throw new Error('Cannot use both \"query\" and \"queryName\" parameters simultaneously. Use either \"query\" for direct file path OR \"queryName\" + \"queryLanguage\" for tool queries.');\n }\n \n // If no queryName provided, fall back to direct query parameter\n if (!queryName) {\n return query as string || null;\n }\n \n // If queryName provided but no language, we can't resolve\n if (!queryLanguage) {\n logger.error('queryLanguage is required when using queryName parameter. Supported languages: actions, cpp, csharp, go, java, javascript, python, ruby, swift');\n throw new Error('queryLanguage is required when using queryName parameter. Supported languages: actions, cpp, csharp, go, java, javascript, python, ruby, swift');\n }\n \n try {\n // Determine the query pack path - use absolute path to ensure it works regardless of cwd\n const defaultPackPath = resolveToolQueryPackPath(queryLanguage as string);\n const packPath = queryPack as string || defaultPackPath;\n \n logger.info(`Resolving query: ${queryName} for language: ${queryLanguage} in pack: ${packPath}`);\n \n // Execute codeql resolve queries to get available queries\n const { executeCodeQLCommand } = await import('./cli-executor');\n const resolveResult = await executeCodeQLCommand(\n 'resolve queries',\n { format: 'json' },\n [packPath]\n );\n \n if (!resolveResult.success) {\n logger.error('Failed to resolve queries:', resolveResult.stderr || resolveResult.error);\n throw new Error(`Failed to resolve queries: ${resolveResult.stderr || resolveResult.error}`);\n }\n \n // Parse the JSON output to find matching queries\n let resolvedQueries: string[];\n try {\n resolvedQueries = JSON.parse(resolveResult.stdout);\n } catch (parseError) {\n logger.error('Failed to parse resolve queries output:', parseError);\n throw new Error('Failed to parse resolve queries output', { cause: parseError });\n }\n \n // Find the query that matches the requested name exactly\n const matchingQuery = resolvedQueries.find(queryPath => {\n const fileName = basename(queryPath);\n // Match exact query name: \"PrintAST\" should match \"PrintAST.ql\" only\n return fileName === `${queryName}.ql`;\n });\n\n if (!matchingQuery) {\n logger.error(`Query \"${queryName}.ql\" not found in pack \"${packPath}\". Available queries:`, resolvedQueries.map(q => basename(q)));\n throw new Error(`Query \"${queryName}.ql\" not found in pack \"${packPath}\"`);\n }\n \n logger.info(`Resolved query \"${queryName}\" to: ${matchingQuery}`);\n return matchingQuery;\n \n } catch (error) {\n logger.error('Error resolving query path:', error);\n throw error;\n }\n}\n\n/**\n * Interpret BQRS file using codeql bqrs interpret\n */\nasync function interpretBQRSFile(\n bqrsPath: string,\n queryPath: string,\n format: string,\n outputPath: string,\n logger: { info: (_message: string, ..._args: unknown[]) => void; error: (_message: string, ..._args: unknown[]) => void }\n): Promise {\n try {\n // Extract query metadata to get id and kind\n const metadata = await extractQueryMetadata(queryPath);\n \n // Validate required metadata fields\n const missingFields = [];\n if (!metadata.id) missingFields.push('id');\n if (!metadata.kind) missingFields.push('kind');\n \n if (missingFields.length > 0) {\n return {\n success: false,\n exitCode: 1,\n stdout: '',\n stderr: '',\n error: `Query metadata is incomplete. Missing required field(s): ${missingFields.join(', ')}. Ensure the query file contains @id and @kind metadata.`\n };\n }\n \n // Sanitize metadata values to prevent command injection\n const sanitizedKind = (metadata.kind || '').replace(/[^a-zA-Z0-9_-]/g, '');\n const sanitizedId = (metadata.id || '').replace(/[^a-zA-Z0-9_/:-]/g, '');\n \n // Validate format for query kind\n const graphFormats = ['graphtext', 'dgml', 'dot'];\n if (graphFormats.includes(format) && metadata.kind !== 'graph') {\n return {\n success: false,\n exitCode: 1,\n stdout: '',\n stderr: '',\n error: `Format '${format}' is only compatible with @kind graph queries, but this query has @kind ${metadata.kind}`\n };\n }\n \n // Ensure output directory exists\n mkdirSync(dirname(outputPath), { recursive: true });\n \n // Build the codeql bqrs interpret command\n const params: Record = {\n format: format,\n output: outputPath,\n t: [`kind=${sanitizedKind}`, `id=${sanitizedId}`]\n };\n \n logger.info(`Interpreting BQRS file ${bqrsPath} with format ${format} to ${outputPath}`);\n \n // Execute codeql bqrs interpret\n const result = await executeCodeQLCommand(\n 'bqrs interpret',\n params,\n [bqrsPath]\n );\n \n return result;\n } catch (error) {\n return {\n success: false,\n exitCode: 1,\n stdout: '',\n stderr: '',\n error: `Failed to interpret BQRS file: ${error}`\n };\n }\n}\n\n/**\n * Get default output extension based on format\n */\nfunction getDefaultExtension(format: string): string {\n switch (format) {\n case 'sarif-latest':\n case 'sarifv2.1.0':\n return '.sarif';\n case 'csv':\n return '.csv';\n case 'graphtext':\n return '.txt';\n case 'dgml':\n return '.dgml';\n case 'dot':\n return '.dot';\n default:\n return '.txt';\n }\n}\n\n/**\n * Process query run results with optional interpretation or evaluation\n */\nasync function processQueryRunResults(\n result: CLIExecutionResult,\n params: Record,\n logger: { info: (_message: string, ..._args: unknown[]) => void; error: (_message: string, ..._args: unknown[]) => void }\n): Promise {\n try {\n const { format, interpretedOutput, evaluationFunction, evaluationOutput, output, query, queryName, queryLanguage } = params;\n \n // If no format or evaluationFunction specified, return as-is\n if (!format && !evaluationFunction) {\n return result;\n }\n \n // Ensure output (bqrs file) was generated\n if (!output) {\n return result;\n }\n \n const bqrsPath = output as string;\n \n // Determine the query path for metadata extraction\n let queryPath: string | null = null;\n \n if (query) {\n queryPath = query as string;\n } else if (queryName && queryLanguage) {\n // Try to resolve the query path again for evaluation\n queryPath = await resolveQueryPath(params, logger);\n }\n \n if (!queryPath) {\n logger.error('Cannot determine query path for interpretation/evaluation');\n return {\n ...result,\n stdout: result.stdout + '\\n\\nWarning: Query interpretation skipped - could not determine query path'\n };\n }\n \n // Handle new format parameter (preferred approach)\n if (format) {\n const outputFormat = format as string;\n \n // Determine output path\n let outputFilePath = interpretedOutput as string | undefined;\n if (!outputFilePath) {\n const ext = getDefaultExtension(outputFormat);\n outputFilePath = bqrsPath.replace('.bqrs', ext);\n }\n \n logger.info(`Interpreting query results from ${bqrsPath} with format: ${outputFormat}`);\n \n // Interpret the BQRS file\n const interpretResult = await interpretBQRSFile(\n bqrsPath,\n queryPath,\n outputFormat,\n outputFilePath,\n logger\n );\n \n if (interpretResult.success) {\n let enhancedOutput = result.stdout;\n enhancedOutput += `\\n\\nQuery results interpreted successfully with format: ${outputFormat}`;\n enhancedOutput += `\\nInterpreted output saved to: ${outputFilePath}`;\n \n return {\n ...result,\n stdout: enhancedOutput\n };\n } else {\n logger.error('Query interpretation failed:', interpretResult.error);\n return {\n ...result,\n stdout: result.stdout + `\\n\\nWarning: Query interpretation failed - ${interpretResult.error || interpretResult.stderr}`\n };\n }\n }\n \n // Handle legacy evaluationFunction parameter (deprecated)\n if (evaluationFunction) {\n logger.info(`Using deprecated evaluationFunction parameter. Consider using format parameter instead.`);\n logger.info(`Evaluating query results from ${bqrsPath} using function: ${evaluationFunction}`);\n \n // Perform the evaluation\n const evaluationResult: QueryEvaluationResult = await evaluateQueryResults(\n bqrsPath,\n queryPath,\n evaluationFunction as string,\n evaluationOutput as string | undefined\n );\n \n if (evaluationResult.success) {\n // Append evaluation results to the command output\n let enhancedOutput = result.stdout;\n \n if (evaluationResult.outputPath) {\n enhancedOutput += `\\n\\nQuery evaluation completed successfully.`;\n enhancedOutput += `\\nEvaluation output saved to: ${evaluationResult.outputPath}`;\n }\n \n if (evaluationResult.content) {\n enhancedOutput += `\\n\\n=== Query Results Evaluation ===\\n`;\n enhancedOutput += evaluationResult.content;\n }\n \n return {\n ...result,\n stdout: enhancedOutput\n };\n } else {\n // Evaluation failed, but don't fail the whole operation\n logger.error('Query evaluation failed:', evaluationResult.error);\n return {\n ...result,\n stdout: result.stdout + `\\n\\nWarning: Query evaluation failed - ${evaluationResult.error}`\n };\n }\n }\n \n return result;\n } catch (error) {\n logger.error('Error in query results processing:', error);\n return {\n ...result,\n stdout: result.stdout + `\\n\\nWarning: Query processing error - ${error}`\n };\n }\n}", "/**\n * Query results evaluation functions for processing .bqrs files\n */\n\nimport { executeCodeQLCommand } from './cli-executor';\nimport { logger } from '../utils/logger';\nimport { writeFileSync, readFileSync } from 'fs';\nimport { dirname, isAbsolute } from 'path';\nimport { mkdirSync } from 'fs';\n\nexport interface QueryEvaluationResult {\n success: boolean;\n outputPath?: string;\n content?: string;\n error?: string;\n}\n\nexport interface QueryMetadata {\n kind?: string;\n name?: string;\n description?: string;\n id?: string;\n tags?: string[];\n}\n\n/**\n * Built-in evaluation functions\n */\nexport const BUILT_IN_EVALUATORS = {\n 'json-decode': 'JSON format decoder for query results',\n 'csv-decode': 'CSV format decoder for query results', \n 'mermaid-graph': 'Mermaid diagram generator for @kind graph queries (like PrintAST)',\n} as const;\n\nexport type BuiltInEvaluator = keyof typeof BUILT_IN_EVALUATORS;\n\n/**\n * Extract metadata from a CodeQL query file\n */\nexport async function extractQueryMetadata(queryPath: string): Promise {\n try {\n const queryContent = readFileSync(queryPath, 'utf-8');\n const metadata: QueryMetadata = {};\n \n // Extract metadata from comments using regex patterns\n const kindMatch = queryContent.match(/@kind\\s+([^\\s]+)/);\n if (kindMatch) metadata.kind = kindMatch[1];\n \n const nameMatch = queryContent.match(/@name\\s+(.+)/);\n if (nameMatch) metadata.name = nameMatch[1].trim();\n \n const descMatch = queryContent.match(/@description\\s+(.+)/);\n if (descMatch) metadata.description = descMatch[1].trim();\n \n const idMatch = queryContent.match(/@id\\s+(.+)/);\n if (idMatch) metadata.id = idMatch[1].trim();\n \n const tagsMatch = queryContent.match(/@tags\\s+(.+)/);\n if (tagsMatch) {\n metadata.tags = tagsMatch[1].split(/\\s+/).filter(t => t.length > 0);\n }\n \n return metadata;\n } catch (error) {\n logger.error('Failed to extract query metadata:', error);\n return {};\n }\n}\n\n/**\n * JSON decoder - converts .bqrs to JSON format\n */\nexport async function evaluateWithJsonDecoder(\n bqrsPath: string, \n outputPath?: string\n): Promise {\n try {\n const result = await executeCodeQLCommand(\n 'bqrs decode',\n { format: 'json' },\n [bqrsPath]\n );\n \n if (!result.success) {\n return {\n success: false,\n error: `Failed to decode BQRS file: ${result.stderr || result.error}`\n };\n }\n \n const defaultOutputPath = outputPath || bqrsPath.replace('.bqrs', '.json');\n \n // Ensure output directory exists\n mkdirSync(dirname(defaultOutputPath), { recursive: true });\n \n // Write JSON results\n writeFileSync(defaultOutputPath, result.stdout);\n \n return {\n success: true,\n outputPath: defaultOutputPath,\n content: result.stdout\n };\n } catch (error) {\n return {\n success: false,\n error: `JSON evaluation failed: ${error}`\n };\n }\n}\n\n/**\n * CSV decoder - converts .bqrs to CSV format\n */\nexport async function evaluateWithCsvDecoder(\n bqrsPath: string,\n outputPath?: string\n): Promise {\n try {\n const result = await executeCodeQLCommand(\n 'bqrs decode',\n { format: 'csv' },\n [bqrsPath]\n );\n \n if (!result.success) {\n return {\n success: false,\n error: `Failed to decode BQRS file: ${result.stderr || result.error}`\n };\n }\n \n const defaultOutputPath = outputPath || bqrsPath.replace('.bqrs', '.csv');\n \n // Ensure output directory exists\n mkdirSync(dirname(defaultOutputPath), { recursive: true });\n \n // Write CSV results\n writeFileSync(defaultOutputPath, result.stdout);\n \n return {\n success: true,\n outputPath: defaultOutputPath,\n content: result.stdout\n };\n } catch (error) {\n return {\n success: false,\n error: `CSV evaluation failed: ${error}`\n };\n }\n}\n\n/**\n * Mermaid graph generator - converts @kind graph query results to mermaid diagrams\n */\nexport async function evaluateWithMermaidGraph(\n bqrsPath: string,\n queryPath: string,\n outputPath?: string\n): Promise {\n try {\n // First extract query metadata to confirm this is a graph query\n const metadata = await extractQueryMetadata(queryPath);\n \n if (metadata.kind !== 'graph') {\n logger.error(`Query is not a graph query (kind: ${metadata.kind}), mermaid-graph evaluation is only for @kind graph queries`);\n return {\n success: false,\n error: `Query is not a graph query (kind: ${metadata.kind}), mermaid-graph evaluation is only for @kind graph queries`\n };\n }\n \n // Decode the BQRS file to JSON first\n const jsonResult = await executeCodeQLCommand(\n 'bqrs decode',\n { format: 'json' },\n [bqrsPath]\n );\n \n if (!jsonResult.success) {\n return {\n success: false,\n error: `Failed to decode BQRS file: ${jsonResult.stderr || jsonResult.error}`\n };\n }\n \n // Parse the JSON results\n let queryResults;\n try {\n queryResults = JSON.parse(jsonResult.stdout);\n } catch (parseError) {\n return {\n success: false,\n error: `Failed to parse query results JSON: ${parseError}`\n };\n }\n \n // Generate mermaid diagram from graph results\n const mermaidContent = generateMermaidFromGraphResults(queryResults, metadata);\n \n const defaultOutputPath = outputPath || bqrsPath.replace('.bqrs', '.md');\n \n // Ensure output directory exists\n mkdirSync(dirname(defaultOutputPath), { recursive: true });\n \n // Write markdown file with mermaid diagram\n writeFileSync(defaultOutputPath, mermaidContent);\n \n return {\n success: true,\n outputPath: defaultOutputPath,\n content: mermaidContent\n };\n } catch (error) {\n return {\n success: false,\n error: `Mermaid graph evaluation failed: ${error}`\n };\n }\n}\n\n/**\n * Generate mermaid diagram from CodeQL graph query results\n */\nfunction generateMermaidFromGraphResults(queryResults: unknown, metadata: QueryMetadata): string {\n const queryName = sanitizeMarkdown(metadata.name || 'CodeQL Query Results');\n const queryDesc = sanitizeMarkdown(metadata.description || 'Graph visualization of CodeQL query results');\n \n let mermaidContent = `# ${queryName}\\n\\n${queryDesc}\\n\\n`;\n \n // Handle different result structures that CodeQL graph queries can produce\n if (!queryResults || typeof queryResults !== 'object') {\n mermaidContent += '```mermaid\\ngraph TD\\n A[No Results]\\n```\\n';\n return mermaidContent;\n }\n \n // Check if results have the expected structure for graph queries\n const tuples = queryResults.tuples || queryResults;\n \n if (!Array.isArray(tuples) || tuples.length === 0) {\n mermaidContent += '```mermaid\\ngraph TD\\n A[No Graph Data]\\n```\\n';\n return mermaidContent;\n }\n \n mermaidContent += '```mermaid\\ngraph TD\\n';\n \n // Track nodes and edges to avoid duplicates\n const nodes = new Set();\n const edges = new Set();\n \n // Process each tuple in the results\n tuples.forEach((tuple: unknown, index: number) => {\n if (Array.isArray(tuple) && tuple.length >= 2) {\n // Extract source and target from tuple\n const source = sanitizeNodeId(tuple[0]?.toString() || `node_${index}_0`);\n const target = sanitizeNodeId(tuple[1]?.toString() || `node_${index}_1`);\n const label = tuple[2]?.toString() || '';\n \n // Add nodes\n nodes.add(source);\n nodes.add(target);\n \n // Add edge\n const edgeId = `${source}_${target}`;\n if (!edges.has(edgeId)) {\n if (label) {\n mermaidContent += ` ${source} -->|${sanitizeLabel(label)}| ${target}\\n`;\n } else {\n mermaidContent += ` ${source} --> ${target}\\n`;\n }\n edges.add(edgeId);\n }\n } else if (typeof tuple === 'object' && tuple !== null) {\n // Handle object-based results\n const source = sanitizeNodeId(tuple.source?.toString() || tuple.from?.toString() || `node_${index}_src`);\n const target = sanitizeNodeId(tuple.target?.toString() || tuple.to?.toString() || `node_${index}_tgt`);\n const label = tuple.label?.toString() || tuple.relation?.toString() || '';\n \n nodes.add(source);\n nodes.add(target);\n \n const edgeId = `${source}_${target}`;\n if (!edges.has(edgeId)) {\n if (label) {\n mermaidContent += ` ${source} -->|${sanitizeLabel(label)}| ${target}\\n`;\n } else {\n mermaidContent += ` ${source} --> ${target}\\n`;\n }\n edges.add(edgeId);\n }\n }\n });\n \n // If no edges were created, create a simple diagram showing the first few nodes\n if (edges.size === 0 && nodes.size > 0) {\n const nodeArray = Array.from(nodes).slice(0, 10); // Limit to avoid clutter\n nodeArray.forEach((node, index) => {\n if (index === 0) {\n mermaidContent += ` ${node}[${sanitizeLabel(node)}]\\n`;\n } else {\n mermaidContent += ` ${nodeArray[0]} --> ${node}\\n`;\n }\n });\n }\n \n mermaidContent += '```\\n\\n';\n \n // Add statistics\n mermaidContent += `## Query Statistics\\n\\n`;\n mermaidContent += `- Total nodes: ${nodes.size}\\n`;\n mermaidContent += `- Total edges: ${edges.size}\\n`;\n mermaidContent += `- Total tuples processed: ${tuples.length}\\n`;\n \n return mermaidContent;\n}\n\n/**\n * Sanitize node IDs for mermaid compatibility\n */\nfunction sanitizeNodeId(id: string): string {\n return id\n .replace(/[^a-zA-Z0-9_]/g, '_')\n .replace(/^(\\d)/, 'n$1') // Prefix with 'n' if starts with number\n .substring(0, 50); // Limit length\n}\n\n/**\n * Sanitize labels for mermaid compatibility\n */\nfunction sanitizeLabel(label: string): string {\n return label\n .replace(/[|\"`<>\\n\\r\\t]/g, '') // Remove problematic characters including backticks, newlines, angle brackets\n .replace(/\\s+/g, ' ') // Normalize whitespace\n .trim()\n .substring(0, 30); // Limit length for readability\n}\n\n/**\n * Sanitize markdown content to prevent injection\n */\nfunction sanitizeMarkdown(content: string): string {\n return content\n .replace(/[<>\"`]/g, '') // Remove potentially dangerous characters\n .replace(/\\n/g, ' ') // Convert newlines to spaces\n .replace(/\\s+/g, ' ') // Normalize whitespace\n .trim()\n .substring(0, 100); // Limit length\n}\n\n/**\n * Main evaluation function that determines which evaluator to use\n */\nexport async function evaluateQueryResults(\n bqrsPath: string,\n queryPath: string,\n evaluationFunction?: string,\n outputPath?: string\n): Promise {\n try {\n // If no evaluation function specified, default to json-decode\n const evalFunc = evaluationFunction || 'json-decode';\n \n logger.info(`Evaluating query results with function: ${evalFunc}`);\n \n // Handle built-in evaluation functions\n switch (evalFunc) {\n case 'json-decode':\n return await evaluateWithJsonDecoder(bqrsPath, outputPath);\n \n case 'csv-decode':\n return await evaluateWithCsvDecoder(bqrsPath, outputPath);\n \n case 'mermaid-graph':\n return await evaluateWithMermaidGraph(bqrsPath, queryPath, outputPath);\n \n default:\n // Check if it's a path to a custom evaluation script\n if (isAbsolute(evalFunc)) {\n return await evaluateWithCustomScript(bqrsPath, queryPath, evalFunc, outputPath);\n } else {\n return {\n success: false,\n error: `Unknown evaluation function: ${evalFunc}. Available built-in functions: ${Object.keys(BUILT_IN_EVALUATORS).join(', ')}`\n };\n }\n }\n } catch (error) {\n return {\n success: false,\n error: `Query evaluation failed: ${error}`\n };\n }\n}\n\n/**\n * Execute custom evaluation script\n */\nasync function evaluateWithCustomScript(\n _bqrsPath: string,\n _queryPath: string,\n _scriptPath: string,\n _outputPath?: string\n): Promise {\n // TODO: Implement custom script execution\n // This would need to execute the script with bqrsPath and queryPath as arguments\n // and capture the output\n return {\n success: false,\n error: 'Custom evaluation scripts are not yet implemented'\n };\n}", "/**\n * Log directory management utilities for CodeQL query and test runs\n */\n\nimport { mkdirSync, existsSync } from 'fs';\nimport { join, resolve } from 'path';\nimport { randomBytes } from 'crypto';\nimport { getProjectTmpDir } from '../utils/temp-dir';\n\n/**\n * Ensure that a given path is within a base directory.\n * Throws an error if the path is outside the base directory.\n */\nfunction ensurePathWithinBase(baseDir: string, targetPath: string): string {\n const absBase = resolve(baseDir);\n const absTarget = resolve(targetPath);\n if (!absTarget.startsWith(absBase + '/') && absTarget !== absBase) {\n throw new Error(`Provided log directory is outside the allowed base directory: ${absBase}`);\n }\n return absTarget;\n}\n\n/**\n * Get or create a unique log directory for query/test runs\n * \n * @param logDir - Optional custom log directory from parameters\n * @returns Absolute path to the log directory\n */\nexport function getOrCreateLogDirectory(logDir?: string): string {\n // Use CODEQL_QUERY_LOG_DIR env var or default base\n const baseLogDir = process.env.CODEQL_QUERY_LOG_DIR || getProjectTmpDir('query-logs');\n\n // If logDir is explicitly provided, validate it is within baseLogDir\n if (logDir) {\n const absLogDir = ensurePathWithinBase(baseLogDir, logDir);\n if (!existsSync(absLogDir)) {\n mkdirSync(absLogDir, { recursive: true });\n }\n return absLogDir;\n }\n \n // Otherwise, use baseLogDir and create a unique subdirectory\n \n // Create base directory if it doesn't exist\n if (!existsSync(baseLogDir)) {\n mkdirSync(baseLogDir, { recursive: true });\n }\n \n // Generate unique subdirectory with timestamp and random ID\n const timestamp = new Date().toISOString().replace(/[:.]/g, '-');\n const uniqueId = randomBytes(4).toString('hex');\n const uniqueLogDir = join(baseLogDir, `query-run-${timestamp}-${uniqueId}`);\n \n mkdirSync(uniqueLogDir, { recursive: true });\n \n return uniqueLogDir;\n}\n", "/**\n * CodeQL BQRS info tool\n *\n * Lists result sets, column schemas, and row counts in a BQRS file.\n * Use this tool before codeql_bqrs_decode to discover available result\n * sets and their column types. BQRS files are produced by codeql_query_run\n * and codeql_database_analyze \u2014 use list_query_run_results to find them.\n */\n\nimport { z } from 'zod';\nimport { CLIToolDefinition, createCodeQLSchemas, createBQRSResultProcessor } from '../../lib/cli-tool-registry';\n\nexport const codeqlBqrsInfoTool: CLIToolDefinition = {\n name: 'codeql_bqrs_info',\n description:\n 'Get metadata about BQRS result files: lists result sets, column names/types, and row counts. ' +\n 'Use before codeql_bqrs_decode to discover available result sets (e.g., \"#select\", \"edges\", \"nodes\"). ' +\n 'BQRS files are found at /results.bqrs \u2014 use list_query_run_results to discover them. ' +\n 'Use --format=json with --paginate-rows to get byte offsets for paginated decoding with codeql_bqrs_decode --start-at.',\n command: 'codeql',\n subcommand: 'bqrs info',\n inputSchema: {\n files: z.array(z.string()).describe('BQRS file(s) to examine'),\n format: z.enum(['text', 'json']).optional()\n .describe('Output format: text (default) or json. Use json for machine-readable output and pagination offset computation.'),\n 'paginate-rows': z.number().optional()\n .describe('Compute byte offsets for pagination at intervals of this many rows. Use with --format=json. Offsets can be passed to codeql_bqrs_decode --start-at.'),\n 'paginate-result-set': z.string().optional()\n .describe('Compute pagination offsets only for this result set name'),\n verbose: createCodeQLSchemas.verbose(),\n additionalArgs: createCodeQLSchemas.additionalArgs()\n },\n examples: [\n 'codeql bqrs info results.bqrs',\n 'codeql bqrs info --format=json results.bqrs',\n 'codeql bqrs info --format=json --paginate-rows=100 --paginate-result-set=#select results.bqrs'\n ],\n resultProcessor: createBQRSResultProcessor()\n};", "/**\n * CodeQL BQRS interpret tool\n */\n\nimport { z } from 'zod';\nimport { CLIToolDefinition, createCodeQLSchemas, createBQRSResultProcessor } from '../../lib/cli-tool-registry';\n\nexport const codeqlBqrsInterpretTool: CLIToolDefinition = {\n name: 'codeql_bqrs_interpret',\n description: 'Interpret BQRS result files according to query metadata and generate output in specified formats (CSV, SARIF, graph formats)',\n command: 'codeql',\n subcommand: 'bqrs interpret',\n inputSchema: {\n file: z.string().describe('The BQRS file to interpret'),\n format: z.enum(['csv', 'sarif-latest', 'sarifv2.1.0', 'graphtext', 'dgml', 'dot'])\n .describe('Output format: csv (comma-separated), sarif-latest/sarifv2.1.0 (SARIF), graphtext/dgml/dot (graph formats, only for @kind graph queries)'),\n output: createCodeQLSchemas.output(),\n t: z.array(z.string())\n .describe('Query metadata key=value pairs. At least \"kind\" and \"id\" must be specified (e.g., [\"kind=graph\", \"id=js/print-ast\"])'),\n 'max-paths': z.number().optional()\n .describe('Maximum number of paths to produce for each alert with paths (default: 4)'),\n 'sarif-add-file-contents': z.boolean().optional()\n .describe('[SARIF only] Include full file contents for all files referenced in results'),\n 'sarif-add-snippets': z.boolean().optional()\n .describe('[SARIF only] Include code snippets for each location with context'),\n 'sarif-group-rules-by-pack': z.boolean().optional()\n .describe('[SARIF only] Place rule objects under their QL pack in tool.extensions property'),\n 'sarif-multicause-markdown': z.boolean().optional()\n .describe('[SARIF only] Include multi-cause alerts as Markdown-formatted lists'),\n 'sarif-category': z.string().optional()\n .describe('[SARIF only] Category for this analysis (distinguishes multiple analyses on same code)'),\n 'csv-location-format': z.enum(['uri', 'line-column', 'offset-length']).optional()\n .describe('[CSV only] Format for locations in CSV output (default: line-column)'),\n 'dot-location-url-format': z.string().optional()\n .describe('[DOT only] Format string for file location URLs (placeholders: {path}, {start:line}, {start:column}, {end:line}, {end:column}, {offset}, {length})'),\n threads: z.number().optional()\n .describe('Number of threads for computing paths (0 = one per core, -N = leave N cores unused)'),\n 'column-kind': z.enum(['utf8', 'utf16', 'utf32', 'bytes']).optional()\n .describe('[SARIF only] Column kind for interpreting location columns'),\n 'unicode-new-lines': z.boolean().optional()\n .describe('[SARIF only] Whether unicode newlines (U+2028, U+2029) are considered as newlines'),\n verbose: createCodeQLSchemas.verbose(),\n additionalArgs: createCodeQLSchemas.additionalArgs()\n },\n examples: [\n 'codeql bqrs interpret --format=sarif-latest --output=results.sarif -t kind=problem -t id=js/sql-injection results.bqrs',\n 'codeql bqrs interpret --format=graphtext --output=ast.txt -t kind=graph -t id=js/print-ast results.bqrs',\n 'codeql bqrs interpret --format=csv --csv-location-format=line-column --output=results.csv -t kind=problem -t id=js/xss results.bqrs',\n 'codeql bqrs interpret --format=dot --output=graph.dot -t kind=graph -t id=java/call-graph results.bqrs',\n 'codeql bqrs interpret --format=sarif-latest --sarif-add-snippets --sarif-category=security --output=results.sarif -t kind=path-problem -t id=go/path-injection results.bqrs'\n ],\n resultProcessor: createBQRSResultProcessor()\n};\n", "/**\n * CodeQL database analyze tool\n */\n\nimport { z } from 'zod';\nimport { CLIToolDefinition } from '../../lib/cli-tool-registry';\n\nexport const codeqlDatabaseAnalyzeTool: CLIToolDefinition = {\n name: 'codeql_database_analyze',\n description:\n 'Run queries or query suites against CodeQL databases. ' +\n 'Produces evaluator logs, BQRS results, and optionally SARIF output. ' +\n 'Use list_codeql_databases to discover available databases, and register_database to register new ones. ' +\n 'After analysis completes, use list_query_run_results to find result artifacts, then codeql_bqrs_info and codeql_bqrs_decode to inspect results.',\n command: 'codeql',\n subcommand: 'database analyze',\n inputSchema: {\n database: z.string().describe('Path to the CodeQL database'),\n queries: z.string().describe('Queries or query suite to run'),\n output: z.string().optional().describe('Output file path'),\n format: z.enum(['csv', 'json', 'sarif-latest', 'sarifv2.1.0']).optional()\n .describe('Output format for results'),\n 'download-location': z.string().optional()\n .describe('Location to download missing dependencies'),\n threads: z.number().optional().describe('Number of threads to use'),\n ram: z.number().optional().describe('Amount of RAM to use (MB)'),\n timeout: z.number().optional().describe('Timeout in seconds'),\n logDir: z.string().optional()\n .describe('Custom directory for analysis execution logs (overrides CODEQL_QUERY_LOG_DIR environment variable). If not provided, uses CODEQL_QUERY_LOG_DIR or defaults to .tmp/query-logs/'),\n 'evaluator-log': z.string().optional()\n .describe('Path to save evaluator log. If not provided and logDir is set, defaults to /evaluator-log.jsonl'),\n 'tuple-counting': z.boolean().optional()\n .describe('Display tuple counts for each evaluation step in evaluator logs'),\n 'evaluator-log-level': z.number().min(1).max(5).optional()\n .describe('Evaluator log verbosity level (1-5, default 5)'),\n rerun: z.boolean().optional()\n .describe('Force re-evaluation of queries even if BQRS results already exist in the database. Without this, cached results are reused.'),\n verbose: z.boolean().optional().describe('Enable verbose output'),\n additionalArgs: z.array(z.string()).optional().describe('Additional command-line arguments')\n },\n examples: [\n 'codeql database analyze mydb queries.qls --format=sarif-latest --output=results.sarif',\n 'codeql database analyze mydb codeql/java-queries --format=csv',\n 'codeql database analyze mydb queries.qls --format=sarif-latest --output=results.sarif --rerun --tuple-counting'\n ]\n};", "/**\n * CodeQL database create tool\n */\n\nimport { z } from 'zod';\nimport { CLIToolDefinition, createDatabaseResultProcessor } from '../../lib/cli-tool-registry';\n\nexport const codeqlDatabaseCreateTool: CLIToolDefinition = {\n name: 'codeql_database_create',\n description: 'Create a CodeQL database from source code',\n command: 'codeql',\n subcommand: 'database create',\n inputSchema: {\n database: z.string().describe('Database path/name to create'),\n language: z.string().optional().describe('Programming language(s) to extract'),\n 'source-root': z.string().optional().describe('Root directory of source code'),\n command: z.string().optional().describe('Build command for compiled languages'),\n 'build-mode': z.enum(['none', 'autobuild', 'manual']).optional()\n .describe('Build mode: none (interpreted langs), autobuild, or manual'),\n threads: z.number().optional().describe('Number of threads to use'),\n ram: z.number().optional().describe('Amount of RAM to use (MB)'),\n verbose: z.boolean().optional().describe('Enable verbose output'),\n overwrite: z.boolean().optional().describe('Overwrite existing database if it exists'),\n 'no-cleanup': z.boolean().optional().describe('Skip database cleanup after finalization'),\n additionalArgs: z.array(z.string()).optional().describe('Additional command-line arguments')\n },\n examples: [\n 'codeql database create --language=java --source-root=/path/to/project mydb',\n 'codeql database create --language=cpp --command=\"make all\" mydb',\n 'codeql database create --language=python,javascript mydb'\n ],\n resultProcessor: createDatabaseResultProcessor()\n};", "/**\n * CodeQL find class position tool\n * \n * Inspired by JordyZomer/codeql-mcp repository:\n * - https://github.com/JordyZomer/codeql-mcp/blob/main/server.py\n * - https://github.com/JordyZomer/codeql-mcp/blob/main/codeqlclient.py\n */\n\nimport { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport { z } from 'zod';\nimport { readFile } from 'fs/promises';\nimport { logger } from '../../utils/logger';\n\nexport interface ClassPosition {\n start_line: number;\n start_col: number;\n end_line: number;\n end_col: number;\n}\n\n/**\n * Find the 1-based position of a class name identifier in a QL file.\n * Returns: { start_line, start_col, end_line, end_col }\n */\nexport async function findClassPosition(filepath: string, className: string): Promise {\n try {\n const content = await readFile(filepath, 'utf-8');\n const lines = content.split('\\n');\n\n for (let i = 0; i < lines.length; i++) {\n const line = lines[i];\n // Match class definition with the specific class name\n const classNameRegex = new RegExp(`\\\\bclass\\\\s+(${className.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&')})\\\\b`);\n const match = classNameRegex.exec(line);\n \n if (match) {\n const start_line = i + 1; // 1-based line numbering\n // The class name is in capture group 1\n const classNameStart = match.index + match[0].indexOf(match[1]);\n const start_col = classNameStart + 1; // 1-based column numbering\n const end_col = start_col + className.length - 1; // end_col is inclusive\n \n return {\n start_line,\n start_col,\n end_line: start_line,\n end_col\n };\n }\n }\n\n throw new Error(`Class name '${className}' not found in file: ${filepath}`);\n } catch (error) {\n if (error instanceof Error && error.message.includes('not found in file')) {\n throw error;\n }\n throw new Error(`Failed to read or parse file ${filepath}: ${error instanceof Error ? error.message : 'Unknown error'}`, { cause: error });\n }\n}\n\n/**\n * Register the find class position tool with the MCP server\n */\nexport function registerFindClassPositionTool(server: McpServer): void {\n server.tool(\n 'find_class_position',\n 'Finds startline, startcol, endline endcol of a class for quickeval',\n {\n file: z.string().describe('Path to the .ql file to search'),\n name: z.string().describe('Name of the class to find'),\n },\n async ({ file, name }) => {\n try {\n const position = await findClassPosition(file, name);\n return {\n content: [{ type: 'text', text: JSON.stringify(position, null, 2) }],\n };\n } catch (error) {\n logger.error('Error finding class position:', error);\n return {\n content: [\n {\n type: 'text',\n text: `Error: ${error instanceof Error ? error.message : 'Unknown error'}`,\n },\n ],\n isError: true,\n };\n }\n }\n );\n}", "/**\n * CodeQL find predicate position tool\n * \n * Inspired by JordyZomer/codeql-mcp repository:\n * - https://github.com/JordyZomer/codeql-mcp/blob/main/server.py\n * - https://github.com/JordyZomer/codeql-mcp/blob/main/codeqlclient.py\n */\n\nimport { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport { z } from 'zod';\nimport { readFile } from 'fs/promises';\nimport { logger } from '../../utils/logger';\n\nexport interface PredicatePosition {\n start_line: number;\n start_col: number;\n end_line: number;\n end_col: number;\n}\n\n/**\n * Find the 1-based position of a predicate name in a QL file.\n * Supports: \n * - predicate name(...) - predicates with no return type\n * - Type name(...) - predicates with return type (e.g., string foo())\n * - name(...) (inside class) - member predicates\n * Returns: { start_line, start_col, end_line, end_col }\n */\nexport async function findPredicatePosition(filepath: string, predicateName: string): Promise {\n try {\n const content = await readFile(filepath, 'utf-8');\n const lines = content.split('\\n');\n const escapedName = predicateName.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&');\n\n for (let i = 0; i < lines.length; i++) {\n const line = lines[i];\n \n // Match predicate definition with the specific predicate name\n // Pattern 1: predicate name(...)\n const predicateKeywordRegex = new RegExp(`\\\\bpredicate\\\\s+(${escapedName})\\\\s*\\\\(`);\n let match = predicateKeywordRegex.exec(line);\n \n // Pattern 2: Type name(...) - predicates with return type\n // Matches: string foo(), int bar(), MyClass baz(), etc.\n // Must start at beginning of line (with optional whitespace) or after certain keywords\n if (!match) {\n const returnTypeRegex = new RegExp(`(?:^|\\\\s)(?:abstract\\\\s+)?(?:cached\\\\s+)?(?:private\\\\s+)?(?:deprecated\\\\s+)?(?:\\\\w+)\\\\s+(${escapedName})\\\\s*\\\\(`);\n match = returnTypeRegex.exec(line);\n }\n \n if (match) {\n const start_line = i + 1; // 1-based line numbering\n // The predicate name is in capture group 1\n const predicateNameStart = match.index + match[0].indexOf(match[1]);\n const start_col = predicateNameStart + 1; // 1-based column numbering\n const end_col = start_col + predicateName.length - 1; // end_col is inclusive\n \n return {\n start_line,\n start_col,\n end_line: start_line,\n end_col\n };\n }\n }\n\n throw new Error(`Predicate name '${predicateName}' not found in file: ${filepath}`);\n } catch (error) {\n if (error instanceof Error && error.message.includes('not found in file')) {\n throw error;\n }\n throw new Error(`Failed to read or parse file ${filepath}: ${error instanceof Error ? error.message : 'Unknown error'}`, { cause: error });\n }\n}\n\n/**\n * Register the find predicate position tool with the MCP server\n */\nexport function registerFindPredicatePositionTool(server: McpServer): void {\n server.tool(\n 'find_predicate_position',\n 'Finds startline, startcol, endline endcol of a predicate for quickeval',\n {\n file: z.string().describe('Path to the .ql file to search'),\n name: z.string().describe('Name of the predicate to find'),\n },\n async ({ file, name }) => {\n try {\n const position = await findPredicatePosition(file, name);\n return {\n content: [{ type: 'text', text: JSON.stringify(position, null, 2) }],\n };\n } catch (error) {\n logger.error('Error finding predicate position:', error);\n return {\n content: [\n {\n type: 'text',\n text: `Error: ${error instanceof Error ? error.message : 'Unknown error'}`,\n },\n ],\n isError: true,\n };\n }\n }\n );\n}", "/**\n * CodeQL find query files tool\n * Discovers and tracks all files related to a CodeQL query\n */\n\nimport { z } from 'zod';\nimport { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport { findCodeQLQueryFiles } from '../../lib/query-file-finder';\nimport { logger } from '../../utils/logger';\n\n/**\n * Register the find_codeql_query_files tool\n */\nexport function registerFindCodeQLQueryFilesTool(server: McpServer): void {\n server.tool(\n 'find_codeql_query_files',\n 'Find and track all files and directories related to a CodeQL query, including resolved metadata',\n {\n queryPath: z.string().describe('Path to the CodeQL query file (.ql)'),\n language: z.string().optional().describe('Programming language (optional, will be inferred if not provided)'),\n resolveMetadata: z.boolean().optional().describe('Whether to resolve query metadata (default: true)')\n },\n async ({ queryPath, language, resolveMetadata }) => {\n try {\n const result = await findCodeQLQueryFiles(\n queryPath,\n language,\n resolveMetadata !== false // Default to true if not specified\n );\n\n return {\n content: [{ type: 'text', text: JSON.stringify(result, null, 2) }]\n };\n } catch (error) {\n logger.error('Error finding CodeQL query files:', error);\n return {\n content: [\n {\n type: 'text',\n text: `Error: ${error instanceof Error ? error.message : 'Unknown error'}`\n }\n ],\n isError: true\n };\n }\n }\n );\n}\n", "/**\n * CodeQL query file finder utilities\n * Handles discovery and tracking of query-related files and directories\n */\n\nimport * as fs from 'fs';\nimport * as path from 'path';\nimport * as yaml from 'js-yaml';\nimport { QueryFileInfo, QueryFilesResult } from '../types/codeql';\nimport { resolveQueryMetadata } from './metadata-resolver';\n\n// Supported CodeQL languages and their file extensions (alphabetically ordered)\nconst LANGUAGE_EXTENSIONS: Record = {\n actions: 'yml',\n cpp: 'cpp',\n csharp: 'cs',\n go: 'go',\n java: 'java',\n javascript: 'js',\n python: 'py',\n ruby: 'rb',\n swift: 'swift',\n typescript: 'ts'\n};\n\nconst KNOWN_LANGUAGES = Object.keys(LANGUAGE_EXTENSIONS);\n\n/**\n * Get the file extension for test code based on language\n */\nfunction getLanguageExtension(language: string): string {\n return LANGUAGE_EXTENSIONS[language.toLowerCase()] || 'txt';\n}\n\n/**\n * Infer the language from the query file's directory structure\n */\nfunction inferLanguageFromPath(queryPath: string): string {\n const parts = queryPath.split(path.sep);\n\n for (const part of parts) {\n if (KNOWN_LANGUAGES.includes(part.toLowerCase())) {\n return part.toLowerCase();\n }\n }\n\n // Default fallback\n return 'unknown';\n}\n\n/**\n * Find the nearest qlpack.yml or codeql-pack.yml file by walking up the directory tree\n */\nfunction findNearestQlpack(startPath: string): string | null {\n let currentPath = startPath;\n const root = path.parse(currentPath).root;\n\n while (currentPath !== root) {\n // Check for codeql-pack.yml first (newer format), then qlpack.yml\n for (const packFile of ['codeql-pack.yml', 'qlpack.yml']) {\n const packPath = path.join(currentPath, packFile);\n if (fs.existsSync(packPath) && fs.statSync(packPath).isFile()) {\n return packPath;\n }\n }\n currentPath = path.dirname(currentPath);\n }\n\n return null;\n}\n\n/**\n * Read and parse qlpack.yml file\n */\nfunction readQlpackMetadata(qlpackPath: string): Record | null {\n try {\n const content = fs.readFileSync(qlpackPath, 'utf-8');\n const parsed = yaml.load(content) as Record;\n return parsed;\n } catch (_error) {\n // If we can't parse it, return null rather than failing\n return null;\n }\n}\n\n/**\n * Check if a file exists and return QueryFileInfo\n */\nfunction checkFile(filePath: string): QueryFileInfo {\n try {\n const exists = fs.existsSync(filePath) && fs.statSync(filePath).isFile();\n return {\n exists,\n path: filePath // Always return path, whether it exists or not\n };\n } catch {\n return {\n exists: false,\n path: filePath // Return the path even on error\n };\n }\n}\n\n/**\n * Check if a directory exists and return QueryFileInfo\n */\nfunction checkDirectory(dirPath: string): QueryFileInfo {\n try {\n const exists = fs.existsSync(dirPath) && fs.statSync(dirPath).isDirectory();\n return {\n exists,\n path: dirPath // Always return path, whether it exists or not\n };\n } catch {\n return {\n exists: false,\n path: dirPath // Return the path even on error\n };\n }\n}\n\n/**\n * Find all test code files in the test directory\n */\nfunction findTestCodeFiles(testDir: string, queryName: string, language: string): string[] {\n if (!fs.existsSync(testDir)) {\n return [];\n }\n\n try {\n const files = fs.readdirSync(testDir);\n const languageExt = getLanguageExtension(language);\n const testFiles: string[] = [];\n\n // Look for files matching the query name or other test code files\n const allValidExtensions = [...new Set([...Object.values(LANGUAGE_EXTENSIONS), 'yaml'])]; // Include yaml as alias for yml\n\n for (const file of files) {\n const filePath = path.join(testDir, file);\n const stat = fs.statSync(filePath);\n\n if (stat.isFile()) {\n // Include the primary test file matching query name\n if (file === `${queryName}.${languageExt}`) {\n testFiles.push(filePath);\n }\n // Include other code files (but not .qlref, .expected, .actual files)\n else if (!file.endsWith('.qlref') && !file.endsWith('.expected') && !file.endsWith('.actual')) {\n const ext = path.extname(file).slice(1);\n if (ext === languageExt || allValidExtensions.includes(ext)) {\n testFiles.push(filePath);\n }\n }\n }\n }\n\n return testFiles;\n } catch {\n return [];\n }\n}\n\n/**\n * Find CodeQL query files and directories based on a query file path\n * Optionally resolves metadata if the query file exists\n */\nexport async function findCodeQLQueryFiles(\n queryFilePath: string,\n language?: string,\n resolveMetadata: boolean = true\n): Promise {\n // Resolve absolute path\n const absoluteQueryPath = path.resolve(queryFilePath);\n\n // Extract query name and directory\n const queryName = path.basename(absoluteQueryPath, '.ql');\n const queryDir = path.dirname(absoluteQueryPath);\n\n // Infer language if not provided\n const detectedLanguage = language || inferLanguageFromPath(absoluteQueryPath);\n\n // Check query file itself\n const queryPath = checkFile(absoluteQueryPath);\n const queryDirectory = checkDirectory(queryDir);\n\n // Check for documentation files\n const mdPath = path.join(queryDir, `${queryName}.md`);\n const qhelpPath = path.join(queryDir, `${queryName}.qhelp`);\n const mdInfo = checkFile(mdPath);\n const qhelpInfo = checkFile(qhelpPath);\n\n const documentationPath: QueryFileInfo = mdInfo.exists ? mdInfo : (qhelpInfo.exists ? qhelpInfo : {\n exists: false,\n path: mdPath // Suggest .md as the default\n });\n\n // Check for specification file\n const qspecPath = path.join(queryDir, `${queryName}.qspec`);\n const specificationPath = checkFile(qspecPath);\n\n // Determine test directory\n // Pattern: if query is in .../src/QueryName/, test should be in .../test/QueryName/\n let testDir: string;\n if (queryDir.includes(`${path.sep}src${path.sep}`)) {\n // Find the last occurrence of /src/ and replace it with /test/\n const parts = queryDir.split(path.sep);\n const srcIndex = parts.lastIndexOf('src');\n if (srcIndex !== -1) {\n parts[srcIndex] = 'test';\n testDir = parts.join(path.sep);\n } else {\n // Fallback in case split didn't find it\n testDir = path.join(path.dirname(queryDir), 'test', queryName);\n }\n } else {\n // Fallback: if not in src directory, construct test dir based on parent\n testDir = path.join(path.dirname(queryDir), 'test', queryName);\n }\n const testDirectory = checkDirectory(testDir);\n\n // Check for .qlref file\n const qlrefPath = path.join(testDir, `${queryName}.qlref`);\n const qlrefInfo = checkFile(qlrefPath);\n\n // Find test code files\n const testCodePaths = findTestCodeFiles(testDir, queryName, detectedLanguage);\n\n // Check for expected results\n const expectedPath = path.join(testDir, `${queryName}.expected`);\n const expectedResultsPath = checkFile(expectedPath);\n\n // Check for actual results\n const actualPath = path.join(testDir, `${queryName}.actual`);\n const actualResultsPath = checkFile(actualPath);\n\n // Check for test database\n const testprojPath = path.join(testDir, `${queryName}.testproj`);\n const testDatabasePath = checkDirectory(testprojPath);\n\n // Determine missing files\n const missingFiles: string[] = [];\n if (!queryPath.exists) missingFiles.push(queryPath.path);\n if (!documentationPath.exists) missingFiles.push(documentationPath.path);\n if (!specificationPath.exists) missingFiles.push(specificationPath.path);\n if (!testDirectory.exists) missingFiles.push(testDirectory.path);\n if (!qlrefInfo.exists) missingFiles.push(qlrefInfo.path);\n if (testCodePaths.length === 0) missingFiles.push(path.join(testDir, `${queryName}.${getLanguageExtension(detectedLanguage)}`));\n if (!expectedResultsPath.exists) missingFiles.push(expectedResultsPath.path);\n\n const allFilesExist = missingFiles.length === 0;\n\n // Resolve metadata if requested and query file exists\n let metadata: { [key: string]: string | string[] } | undefined;\n if (resolveMetadata && queryPath.exists) {\n const resolvedMetadata = await resolveQueryMetadata(absoluteQueryPath);\n if (resolvedMetadata) {\n metadata = resolvedMetadata;\n }\n }\n\n // Resolve pack metadata and directories by finding the nearest qlpack.yml files\n let packMetadata: Record | undefined;\n const queryPackPath = findNearestQlpack(queryDir);\n const queryPackDir = queryPackPath ? path.dirname(queryPackPath) : queryDir;\n if (queryPackPath) {\n const parsed = readQlpackMetadata(queryPackPath);\n if (parsed) {\n packMetadata = parsed;\n }\n }\n\n // Find pack directory for test files\n const testPackPath = findNearestQlpack(testDir);\n const testPackDir = testPackPath ? path.dirname(testPackPath) : testDir;\n\n return {\n queryName,\n language: detectedLanguage,\n\n allFilesExist,\n\n files: {\n query: {\n dir: queryDirectory.path,\n doc: path.basename(documentationPath.path),\n packDir: queryPackDir,\n query: path.basename(queryPath.path),\n spec: path.basename(specificationPath.path)\n },\n test: {\n actual: path.basename(actualResultsPath.path),\n dir: testDirectory.path,\n expected: path.basename(expectedResultsPath.path),\n packDir: testPackDir,\n qlref: path.basename(qlrefInfo.path),\n testCode: testCodePaths,\n testDatabaseDir: testDatabasePath.path\n }\n },\n\n metadata,\n\n missingFiles,\n\n packMetadata,\n\n status: {\n actualResultsExist: actualResultsPath.exists,\n documentationExists: documentationPath.exists,\n expectedResultsExist: expectedResultsPath.exists,\n hasTestCode: testCodePaths.length > 0,\n qlrefExists: qlrefInfo.exists,\n queryExists: queryPath.exists,\n specificationExists: specificationPath.exists,\n testDatabaseDirExists: testDatabasePath.exists,\n testDirectoryExists: testDirectory.exists\n }\n };\n}\n", "\n/*! js-yaml 4.1.1 https://github.com/nodeca/js-yaml @license MIT */\nfunction isNothing(subject) {\n return (typeof subject === 'undefined') || (subject === null);\n}\n\n\nfunction isObject(subject) {\n return (typeof subject === 'object') && (subject !== null);\n}\n\n\nfunction toArray(sequence) {\n if (Array.isArray(sequence)) return sequence;\n else if (isNothing(sequence)) return [];\n\n return [ sequence ];\n}\n\n\nfunction extend(target, source) {\n var index, length, key, sourceKeys;\n\n if (source) {\n sourceKeys = Object.keys(source);\n\n for (index = 0, length = sourceKeys.length; index < length; index += 1) {\n key = sourceKeys[index];\n target[key] = source[key];\n }\n }\n\n return target;\n}\n\n\nfunction repeat(string, count) {\n var result = '', cycle;\n\n for (cycle = 0; cycle < count; cycle += 1) {\n result += string;\n }\n\n return result;\n}\n\n\nfunction isNegativeZero(number) {\n return (number === 0) && (Number.NEGATIVE_INFINITY === 1 / number);\n}\n\n\nvar isNothing_1 = isNothing;\nvar isObject_1 = isObject;\nvar toArray_1 = toArray;\nvar repeat_1 = repeat;\nvar isNegativeZero_1 = isNegativeZero;\nvar extend_1 = extend;\n\nvar common = {\n\tisNothing: isNothing_1,\n\tisObject: isObject_1,\n\ttoArray: toArray_1,\n\trepeat: repeat_1,\n\tisNegativeZero: isNegativeZero_1,\n\textend: extend_1\n};\n\n// YAML error class. http://stackoverflow.com/questions/8458984\n\n\nfunction formatError(exception, compact) {\n var where = '', message = exception.reason || '(unknown reason)';\n\n if (!exception.mark) return message;\n\n if (exception.mark.name) {\n where += 'in \"' + exception.mark.name + '\" ';\n }\n\n where += '(' + (exception.mark.line + 1) + ':' + (exception.mark.column + 1) + ')';\n\n if (!compact && exception.mark.snippet) {\n where += '\\n\\n' + exception.mark.snippet;\n }\n\n return message + ' ' + where;\n}\n\n\nfunction YAMLException$1(reason, mark) {\n // Super constructor\n Error.call(this);\n\n this.name = 'YAMLException';\n this.reason = reason;\n this.mark = mark;\n this.message = formatError(this, false);\n\n // Include stack trace in error object\n if (Error.captureStackTrace) {\n // Chrome and NodeJS\n Error.captureStackTrace(this, this.constructor);\n } else {\n // FF, IE 10+ and Safari 6+. Fallback for others\n this.stack = (new Error()).stack || '';\n }\n}\n\n\n// Inherit from Error\nYAMLException$1.prototype = Object.create(Error.prototype);\nYAMLException$1.prototype.constructor = YAMLException$1;\n\n\nYAMLException$1.prototype.toString = function toString(compact) {\n return this.name + ': ' + formatError(this, compact);\n};\n\n\nvar exception = YAMLException$1;\n\n// get snippet for a single line, respecting maxLength\nfunction getLine(buffer, lineStart, lineEnd, position, maxLineLength) {\n var head = '';\n var tail = '';\n var maxHalfLength = Math.floor(maxLineLength / 2) - 1;\n\n if (position - lineStart > maxHalfLength) {\n head = ' ... ';\n lineStart = position - maxHalfLength + head.length;\n }\n\n if (lineEnd - position > maxHalfLength) {\n tail = ' ...';\n lineEnd = position + maxHalfLength - tail.length;\n }\n\n return {\n str: head + buffer.slice(lineStart, lineEnd).replace(/\\t/g, '\u2192') + tail,\n pos: position - lineStart + head.length // relative position\n };\n}\n\n\nfunction padStart(string, max) {\n return common.repeat(' ', max - string.length) + string;\n}\n\n\nfunction makeSnippet(mark, options) {\n options = Object.create(options || null);\n\n if (!mark.buffer) return null;\n\n if (!options.maxLength) options.maxLength = 79;\n if (typeof options.indent !== 'number') options.indent = 1;\n if (typeof options.linesBefore !== 'number') options.linesBefore = 3;\n if (typeof options.linesAfter !== 'number') options.linesAfter = 2;\n\n var re = /\\r?\\n|\\r|\\0/g;\n var lineStarts = [ 0 ];\n var lineEnds = [];\n var match;\n var foundLineNo = -1;\n\n while ((match = re.exec(mark.buffer))) {\n lineEnds.push(match.index);\n lineStarts.push(match.index + match[0].length);\n\n if (mark.position <= match.index && foundLineNo < 0) {\n foundLineNo = lineStarts.length - 2;\n }\n }\n\n if (foundLineNo < 0) foundLineNo = lineStarts.length - 1;\n\n var result = '', i, line;\n var lineNoLength = Math.min(mark.line + options.linesAfter, lineEnds.length).toString().length;\n var maxLineLength = options.maxLength - (options.indent + lineNoLength + 3);\n\n for (i = 1; i <= options.linesBefore; i++) {\n if (foundLineNo - i < 0) break;\n line = getLine(\n mark.buffer,\n lineStarts[foundLineNo - i],\n lineEnds[foundLineNo - i],\n mark.position - (lineStarts[foundLineNo] - lineStarts[foundLineNo - i]),\n maxLineLength\n );\n result = common.repeat(' ', options.indent) + padStart((mark.line - i + 1).toString(), lineNoLength) +\n ' | ' + line.str + '\\n' + result;\n }\n\n line = getLine(mark.buffer, lineStarts[foundLineNo], lineEnds[foundLineNo], mark.position, maxLineLength);\n result += common.repeat(' ', options.indent) + padStart((mark.line + 1).toString(), lineNoLength) +\n ' | ' + line.str + '\\n';\n result += common.repeat('-', options.indent + lineNoLength + 3 + line.pos) + '^' + '\\n';\n\n for (i = 1; i <= options.linesAfter; i++) {\n if (foundLineNo + i >= lineEnds.length) break;\n line = getLine(\n mark.buffer,\n lineStarts[foundLineNo + i],\n lineEnds[foundLineNo + i],\n mark.position - (lineStarts[foundLineNo] - lineStarts[foundLineNo + i]),\n maxLineLength\n );\n result += common.repeat(' ', options.indent) + padStart((mark.line + i + 1).toString(), lineNoLength) +\n ' | ' + line.str + '\\n';\n }\n\n return result.replace(/\\n$/, '');\n}\n\n\nvar snippet = makeSnippet;\n\nvar TYPE_CONSTRUCTOR_OPTIONS = [\n 'kind',\n 'multi',\n 'resolve',\n 'construct',\n 'instanceOf',\n 'predicate',\n 'represent',\n 'representName',\n 'defaultStyle',\n 'styleAliases'\n];\n\nvar YAML_NODE_KINDS = [\n 'scalar',\n 'sequence',\n 'mapping'\n];\n\nfunction compileStyleAliases(map) {\n var result = {};\n\n if (map !== null) {\n Object.keys(map).forEach(function (style) {\n map[style].forEach(function (alias) {\n result[String(alias)] = style;\n });\n });\n }\n\n return result;\n}\n\nfunction Type$1(tag, options) {\n options = options || {};\n\n Object.keys(options).forEach(function (name) {\n if (TYPE_CONSTRUCTOR_OPTIONS.indexOf(name) === -1) {\n throw new exception('Unknown option \"' + name + '\" is met in definition of \"' + tag + '\" YAML type.');\n }\n });\n\n // TODO: Add tag format check.\n this.options = options; // keep original options in case user wants to extend this type later\n this.tag = tag;\n this.kind = options['kind'] || null;\n this.resolve = options['resolve'] || function () { return true; };\n this.construct = options['construct'] || function (data) { return data; };\n this.instanceOf = options['instanceOf'] || null;\n this.predicate = options['predicate'] || null;\n this.represent = options['represent'] || null;\n this.representName = options['representName'] || null;\n this.defaultStyle = options['defaultStyle'] || null;\n this.multi = options['multi'] || false;\n this.styleAliases = compileStyleAliases(options['styleAliases'] || null);\n\n if (YAML_NODE_KINDS.indexOf(this.kind) === -1) {\n throw new exception('Unknown kind \"' + this.kind + '\" is specified for \"' + tag + '\" YAML type.');\n }\n}\n\nvar type = Type$1;\n\n/*eslint-disable max-len*/\n\n\n\n\n\nfunction compileList(schema, name) {\n var result = [];\n\n schema[name].forEach(function (currentType) {\n var newIndex = result.length;\n\n result.forEach(function (previousType, previousIndex) {\n if (previousType.tag === currentType.tag &&\n previousType.kind === currentType.kind &&\n previousType.multi === currentType.multi) {\n\n newIndex = previousIndex;\n }\n });\n\n result[newIndex] = currentType;\n });\n\n return result;\n}\n\n\nfunction compileMap(/* lists... */) {\n var result = {\n scalar: {},\n sequence: {},\n mapping: {},\n fallback: {},\n multi: {\n scalar: [],\n sequence: [],\n mapping: [],\n fallback: []\n }\n }, index, length;\n\n function collectType(type) {\n if (type.multi) {\n result.multi[type.kind].push(type);\n result.multi['fallback'].push(type);\n } else {\n result[type.kind][type.tag] = result['fallback'][type.tag] = type;\n }\n }\n\n for (index = 0, length = arguments.length; index < length; index += 1) {\n arguments[index].forEach(collectType);\n }\n return result;\n}\n\n\nfunction Schema$1(definition) {\n return this.extend(definition);\n}\n\n\nSchema$1.prototype.extend = function extend(definition) {\n var implicit = [];\n var explicit = [];\n\n if (definition instanceof type) {\n // Schema.extend(type)\n explicit.push(definition);\n\n } else if (Array.isArray(definition)) {\n // Schema.extend([ type1, type2, ... ])\n explicit = explicit.concat(definition);\n\n } else if (definition && (Array.isArray(definition.implicit) || Array.isArray(definition.explicit))) {\n // Schema.extend({ explicit: [ type1, type2, ... ], implicit: [ type1, type2, ... ] })\n if (definition.implicit) implicit = implicit.concat(definition.implicit);\n if (definition.explicit) explicit = explicit.concat(definition.explicit);\n\n } else {\n throw new exception('Schema.extend argument should be a Type, [ Type ], ' +\n 'or a schema definition ({ implicit: [...], explicit: [...] })');\n }\n\n implicit.forEach(function (type$1) {\n if (!(type$1 instanceof type)) {\n throw new exception('Specified list of YAML types (or a single Type object) contains a non-Type object.');\n }\n\n if (type$1.loadKind && type$1.loadKind !== 'scalar') {\n throw new exception('There is a non-scalar type in the implicit list of a schema. Implicit resolving of such types is not supported.');\n }\n\n if (type$1.multi) {\n throw new exception('There is a multi type in the implicit list of a schema. Multi tags can only be listed as explicit.');\n }\n });\n\n explicit.forEach(function (type$1) {\n if (!(type$1 instanceof type)) {\n throw new exception('Specified list of YAML types (or a single Type object) contains a non-Type object.');\n }\n });\n\n var result = Object.create(Schema$1.prototype);\n\n result.implicit = (this.implicit || []).concat(implicit);\n result.explicit = (this.explicit || []).concat(explicit);\n\n result.compiledImplicit = compileList(result, 'implicit');\n result.compiledExplicit = compileList(result, 'explicit');\n result.compiledTypeMap = compileMap(result.compiledImplicit, result.compiledExplicit);\n\n return result;\n};\n\n\nvar schema = Schema$1;\n\nvar str = new type('tag:yaml.org,2002:str', {\n kind: 'scalar',\n construct: function (data) { return data !== null ? data : ''; }\n});\n\nvar seq = new type('tag:yaml.org,2002:seq', {\n kind: 'sequence',\n construct: function (data) { return data !== null ? data : []; }\n});\n\nvar map = new type('tag:yaml.org,2002:map', {\n kind: 'mapping',\n construct: function (data) { return data !== null ? data : {}; }\n});\n\nvar failsafe = new schema({\n explicit: [\n str,\n seq,\n map\n ]\n});\n\nfunction resolveYamlNull(data) {\n if (data === null) return true;\n\n var max = data.length;\n\n return (max === 1 && data === '~') ||\n (max === 4 && (data === 'null' || data === 'Null' || data === 'NULL'));\n}\n\nfunction constructYamlNull() {\n return null;\n}\n\nfunction isNull(object) {\n return object === null;\n}\n\nvar _null = new type('tag:yaml.org,2002:null', {\n kind: 'scalar',\n resolve: resolveYamlNull,\n construct: constructYamlNull,\n predicate: isNull,\n represent: {\n canonical: function () { return '~'; },\n lowercase: function () { return 'null'; },\n uppercase: function () { return 'NULL'; },\n camelcase: function () { return 'Null'; },\n empty: function () { return ''; }\n },\n defaultStyle: 'lowercase'\n});\n\nfunction resolveYamlBoolean(data) {\n if (data === null) return false;\n\n var max = data.length;\n\n return (max === 4 && (data === 'true' || data === 'True' || data === 'TRUE')) ||\n (max === 5 && (data === 'false' || data === 'False' || data === 'FALSE'));\n}\n\nfunction constructYamlBoolean(data) {\n return data === 'true' ||\n data === 'True' ||\n data === 'TRUE';\n}\n\nfunction isBoolean(object) {\n return Object.prototype.toString.call(object) === '[object Boolean]';\n}\n\nvar bool = new type('tag:yaml.org,2002:bool', {\n kind: 'scalar',\n resolve: resolveYamlBoolean,\n construct: constructYamlBoolean,\n predicate: isBoolean,\n represent: {\n lowercase: function (object) { return object ? 'true' : 'false'; },\n uppercase: function (object) { return object ? 'TRUE' : 'FALSE'; },\n camelcase: function (object) { return object ? 'True' : 'False'; }\n },\n defaultStyle: 'lowercase'\n});\n\nfunction isHexCode(c) {\n return ((0x30/* 0 */ <= c) && (c <= 0x39/* 9 */)) ||\n ((0x41/* A */ <= c) && (c <= 0x46/* F */)) ||\n ((0x61/* a */ <= c) && (c <= 0x66/* f */));\n}\n\nfunction isOctCode(c) {\n return ((0x30/* 0 */ <= c) && (c <= 0x37/* 7 */));\n}\n\nfunction isDecCode(c) {\n return ((0x30/* 0 */ <= c) && (c <= 0x39/* 9 */));\n}\n\nfunction resolveYamlInteger(data) {\n if (data === null) return false;\n\n var max = data.length,\n index = 0,\n hasDigits = false,\n ch;\n\n if (!max) return false;\n\n ch = data[index];\n\n // sign\n if (ch === '-' || ch === '+') {\n ch = data[++index];\n }\n\n if (ch === '0') {\n // 0\n if (index + 1 === max) return true;\n ch = data[++index];\n\n // base 2, base 8, base 16\n\n if (ch === 'b') {\n // base 2\n index++;\n\n for (; index < max; index++) {\n ch = data[index];\n if (ch === '_') continue;\n if (ch !== '0' && ch !== '1') return false;\n hasDigits = true;\n }\n return hasDigits && ch !== '_';\n }\n\n\n if (ch === 'x') {\n // base 16\n index++;\n\n for (; index < max; index++) {\n ch = data[index];\n if (ch === '_') continue;\n if (!isHexCode(data.charCodeAt(index))) return false;\n hasDigits = true;\n }\n return hasDigits && ch !== '_';\n }\n\n\n if (ch === 'o') {\n // base 8\n index++;\n\n for (; index < max; index++) {\n ch = data[index];\n if (ch === '_') continue;\n if (!isOctCode(data.charCodeAt(index))) return false;\n hasDigits = true;\n }\n return hasDigits && ch !== '_';\n }\n }\n\n // base 10 (except 0)\n\n // value should not start with `_`;\n if (ch === '_') return false;\n\n for (; index < max; index++) {\n ch = data[index];\n if (ch === '_') continue;\n if (!isDecCode(data.charCodeAt(index))) {\n return false;\n }\n hasDigits = true;\n }\n\n // Should have digits and should not end with `_`\n if (!hasDigits || ch === '_') return false;\n\n return true;\n}\n\nfunction constructYamlInteger(data) {\n var value = data, sign = 1, ch;\n\n if (value.indexOf('_') !== -1) {\n value = value.replace(/_/g, '');\n }\n\n ch = value[0];\n\n if (ch === '-' || ch === '+') {\n if (ch === '-') sign = -1;\n value = value.slice(1);\n ch = value[0];\n }\n\n if (value === '0') return 0;\n\n if (ch === '0') {\n if (value[1] === 'b') return sign * parseInt(value.slice(2), 2);\n if (value[1] === 'x') return sign * parseInt(value.slice(2), 16);\n if (value[1] === 'o') return sign * parseInt(value.slice(2), 8);\n }\n\n return sign * parseInt(value, 10);\n}\n\nfunction isInteger(object) {\n return (Object.prototype.toString.call(object)) === '[object Number]' &&\n (object % 1 === 0 && !common.isNegativeZero(object));\n}\n\nvar int = new type('tag:yaml.org,2002:int', {\n kind: 'scalar',\n resolve: resolveYamlInteger,\n construct: constructYamlInteger,\n predicate: isInteger,\n represent: {\n binary: function (obj) { return obj >= 0 ? '0b' + obj.toString(2) : '-0b' + obj.toString(2).slice(1); },\n octal: function (obj) { return obj >= 0 ? '0o' + obj.toString(8) : '-0o' + obj.toString(8).slice(1); },\n decimal: function (obj) { return obj.toString(10); },\n /* eslint-disable max-len */\n hexadecimal: function (obj) { return obj >= 0 ? '0x' + obj.toString(16).toUpperCase() : '-0x' + obj.toString(16).toUpperCase().slice(1); }\n },\n defaultStyle: 'decimal',\n styleAliases: {\n binary: [ 2, 'bin' ],\n octal: [ 8, 'oct' ],\n decimal: [ 10, 'dec' ],\n hexadecimal: [ 16, 'hex' ]\n }\n});\n\nvar YAML_FLOAT_PATTERN = new RegExp(\n // 2.5e4, 2.5 and integers\n '^(?:[-+]?(?:[0-9][0-9_]*)(?:\\\\.[0-9_]*)?(?:[eE][-+]?[0-9]+)?' +\n // .2e4, .2\n // special case, seems not from spec\n '|\\\\.[0-9_]+(?:[eE][-+]?[0-9]+)?' +\n // .inf\n '|[-+]?\\\\.(?:inf|Inf|INF)' +\n // .nan\n '|\\\\.(?:nan|NaN|NAN))$');\n\nfunction resolveYamlFloat(data) {\n if (data === null) return false;\n\n if (!YAML_FLOAT_PATTERN.test(data) ||\n // Quick hack to not allow integers end with `_`\n // Probably should update regexp & check speed\n data[data.length - 1] === '_') {\n return false;\n }\n\n return true;\n}\n\nfunction constructYamlFloat(data) {\n var value, sign;\n\n value = data.replace(/_/g, '').toLowerCase();\n sign = value[0] === '-' ? -1 : 1;\n\n if ('+-'.indexOf(value[0]) >= 0) {\n value = value.slice(1);\n }\n\n if (value === '.inf') {\n return (sign === 1) ? Number.POSITIVE_INFINITY : Number.NEGATIVE_INFINITY;\n\n } else if (value === '.nan') {\n return NaN;\n }\n return sign * parseFloat(value, 10);\n}\n\n\nvar SCIENTIFIC_WITHOUT_DOT = /^[-+]?[0-9]+e/;\n\nfunction representYamlFloat(object, style) {\n var res;\n\n if (isNaN(object)) {\n switch (style) {\n case 'lowercase': return '.nan';\n case 'uppercase': return '.NAN';\n case 'camelcase': return '.NaN';\n }\n } else if (Number.POSITIVE_INFINITY === object) {\n switch (style) {\n case 'lowercase': return '.inf';\n case 'uppercase': return '.INF';\n case 'camelcase': return '.Inf';\n }\n } else if (Number.NEGATIVE_INFINITY === object) {\n switch (style) {\n case 'lowercase': return '-.inf';\n case 'uppercase': return '-.INF';\n case 'camelcase': return '-.Inf';\n }\n } else if (common.isNegativeZero(object)) {\n return '-0.0';\n }\n\n res = object.toString(10);\n\n // JS stringifier can build scientific format without dots: 5e-100,\n // while YAML requres dot: 5.e-100. Fix it with simple hack\n\n return SCIENTIFIC_WITHOUT_DOT.test(res) ? res.replace('e', '.e') : res;\n}\n\nfunction isFloat(object) {\n return (Object.prototype.toString.call(object) === '[object Number]') &&\n (object % 1 !== 0 || common.isNegativeZero(object));\n}\n\nvar float = new type('tag:yaml.org,2002:float', {\n kind: 'scalar',\n resolve: resolveYamlFloat,\n construct: constructYamlFloat,\n predicate: isFloat,\n represent: representYamlFloat,\n defaultStyle: 'lowercase'\n});\n\nvar json = failsafe.extend({\n implicit: [\n _null,\n bool,\n int,\n float\n ]\n});\n\nvar core = json;\n\nvar YAML_DATE_REGEXP = new RegExp(\n '^([0-9][0-9][0-9][0-9])' + // [1] year\n '-([0-9][0-9])' + // [2] month\n '-([0-9][0-9])$'); // [3] day\n\nvar YAML_TIMESTAMP_REGEXP = new RegExp(\n '^([0-9][0-9][0-9][0-9])' + // [1] year\n '-([0-9][0-9]?)' + // [2] month\n '-([0-9][0-9]?)' + // [3] day\n '(?:[Tt]|[ \\\\t]+)' + // ...\n '([0-9][0-9]?)' + // [4] hour\n ':([0-9][0-9])' + // [5] minute\n ':([0-9][0-9])' + // [6] second\n '(?:\\\\.([0-9]*))?' + // [7] fraction\n '(?:[ \\\\t]*(Z|([-+])([0-9][0-9]?)' + // [8] tz [9] tz_sign [10] tz_hour\n '(?::([0-9][0-9]))?))?$'); // [11] tz_minute\n\nfunction resolveYamlTimestamp(data) {\n if (data === null) return false;\n if (YAML_DATE_REGEXP.exec(data) !== null) return true;\n if (YAML_TIMESTAMP_REGEXP.exec(data) !== null) return true;\n return false;\n}\n\nfunction constructYamlTimestamp(data) {\n var match, year, month, day, hour, minute, second, fraction = 0,\n delta = null, tz_hour, tz_minute, date;\n\n match = YAML_DATE_REGEXP.exec(data);\n if (match === null) match = YAML_TIMESTAMP_REGEXP.exec(data);\n\n if (match === null) throw new Error('Date resolve error');\n\n // match: [1] year [2] month [3] day\n\n year = +(match[1]);\n month = +(match[2]) - 1; // JS month starts with 0\n day = +(match[3]);\n\n if (!match[4]) { // no hour\n return new Date(Date.UTC(year, month, day));\n }\n\n // match: [4] hour [5] minute [6] second [7] fraction\n\n hour = +(match[4]);\n minute = +(match[5]);\n second = +(match[6]);\n\n if (match[7]) {\n fraction = match[7].slice(0, 3);\n while (fraction.length < 3) { // milli-seconds\n fraction += '0';\n }\n fraction = +fraction;\n }\n\n // match: [8] tz [9] tz_sign [10] tz_hour [11] tz_minute\n\n if (match[9]) {\n tz_hour = +(match[10]);\n tz_minute = +(match[11] || 0);\n delta = (tz_hour * 60 + tz_minute) * 60000; // delta in mili-seconds\n if (match[9] === '-') delta = -delta;\n }\n\n date = new Date(Date.UTC(year, month, day, hour, minute, second, fraction));\n\n if (delta) date.setTime(date.getTime() - delta);\n\n return date;\n}\n\nfunction representYamlTimestamp(object /*, style*/) {\n return object.toISOString();\n}\n\nvar timestamp = new type('tag:yaml.org,2002:timestamp', {\n kind: 'scalar',\n resolve: resolveYamlTimestamp,\n construct: constructYamlTimestamp,\n instanceOf: Date,\n represent: representYamlTimestamp\n});\n\nfunction resolveYamlMerge(data) {\n return data === '<<' || data === null;\n}\n\nvar merge = new type('tag:yaml.org,2002:merge', {\n kind: 'scalar',\n resolve: resolveYamlMerge\n});\n\n/*eslint-disable no-bitwise*/\n\n\n\n\n\n// [ 64, 65, 66 ] -> [ padding, CR, LF ]\nvar BASE64_MAP = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=\\n\\r';\n\n\nfunction resolveYamlBinary(data) {\n if (data === null) return false;\n\n var code, idx, bitlen = 0, max = data.length, map = BASE64_MAP;\n\n // Convert one by one.\n for (idx = 0; idx < max; idx++) {\n code = map.indexOf(data.charAt(idx));\n\n // Skip CR/LF\n if (code > 64) continue;\n\n // Fail on illegal characters\n if (code < 0) return false;\n\n bitlen += 6;\n }\n\n // If there are any bits left, source was corrupted\n return (bitlen % 8) === 0;\n}\n\nfunction constructYamlBinary(data) {\n var idx, tailbits,\n input = data.replace(/[\\r\\n=]/g, ''), // remove CR/LF & padding to simplify scan\n max = input.length,\n map = BASE64_MAP,\n bits = 0,\n result = [];\n\n // Collect by 6*4 bits (3 bytes)\n\n for (idx = 0; idx < max; idx++) {\n if ((idx % 4 === 0) && idx) {\n result.push((bits >> 16) & 0xFF);\n result.push((bits >> 8) & 0xFF);\n result.push(bits & 0xFF);\n }\n\n bits = (bits << 6) | map.indexOf(input.charAt(idx));\n }\n\n // Dump tail\n\n tailbits = (max % 4) * 6;\n\n if (tailbits === 0) {\n result.push((bits >> 16) & 0xFF);\n result.push((bits >> 8) & 0xFF);\n result.push(bits & 0xFF);\n } else if (tailbits === 18) {\n result.push((bits >> 10) & 0xFF);\n result.push((bits >> 2) & 0xFF);\n } else if (tailbits === 12) {\n result.push((bits >> 4) & 0xFF);\n }\n\n return new Uint8Array(result);\n}\n\nfunction representYamlBinary(object /*, style*/) {\n var result = '', bits = 0, idx, tail,\n max = object.length,\n map = BASE64_MAP;\n\n // Convert every three bytes to 4 ASCII characters.\n\n for (idx = 0; idx < max; idx++) {\n if ((idx % 3 === 0) && idx) {\n result += map[(bits >> 18) & 0x3F];\n result += map[(bits >> 12) & 0x3F];\n result += map[(bits >> 6) & 0x3F];\n result += map[bits & 0x3F];\n }\n\n bits = (bits << 8) + object[idx];\n }\n\n // Dump tail\n\n tail = max % 3;\n\n if (tail === 0) {\n result += map[(bits >> 18) & 0x3F];\n result += map[(bits >> 12) & 0x3F];\n result += map[(bits >> 6) & 0x3F];\n result += map[bits & 0x3F];\n } else if (tail === 2) {\n result += map[(bits >> 10) & 0x3F];\n result += map[(bits >> 4) & 0x3F];\n result += map[(bits << 2) & 0x3F];\n result += map[64];\n } else if (tail === 1) {\n result += map[(bits >> 2) & 0x3F];\n result += map[(bits << 4) & 0x3F];\n result += map[64];\n result += map[64];\n }\n\n return result;\n}\n\nfunction isBinary(obj) {\n return Object.prototype.toString.call(obj) === '[object Uint8Array]';\n}\n\nvar binary = new type('tag:yaml.org,2002:binary', {\n kind: 'scalar',\n resolve: resolveYamlBinary,\n construct: constructYamlBinary,\n predicate: isBinary,\n represent: representYamlBinary\n});\n\nvar _hasOwnProperty$3 = Object.prototype.hasOwnProperty;\nvar _toString$2 = Object.prototype.toString;\n\nfunction resolveYamlOmap(data) {\n if (data === null) return true;\n\n var objectKeys = [], index, length, pair, pairKey, pairHasKey,\n object = data;\n\n for (index = 0, length = object.length; index < length; index += 1) {\n pair = object[index];\n pairHasKey = false;\n\n if (_toString$2.call(pair) !== '[object Object]') return false;\n\n for (pairKey in pair) {\n if (_hasOwnProperty$3.call(pair, pairKey)) {\n if (!pairHasKey) pairHasKey = true;\n else return false;\n }\n }\n\n if (!pairHasKey) return false;\n\n if (objectKeys.indexOf(pairKey) === -1) objectKeys.push(pairKey);\n else return false;\n }\n\n return true;\n}\n\nfunction constructYamlOmap(data) {\n return data !== null ? data : [];\n}\n\nvar omap = new type('tag:yaml.org,2002:omap', {\n kind: 'sequence',\n resolve: resolveYamlOmap,\n construct: constructYamlOmap\n});\n\nvar _toString$1 = Object.prototype.toString;\n\nfunction resolveYamlPairs(data) {\n if (data === null) return true;\n\n var index, length, pair, keys, result,\n object = data;\n\n result = new Array(object.length);\n\n for (index = 0, length = object.length; index < length; index += 1) {\n pair = object[index];\n\n if (_toString$1.call(pair) !== '[object Object]') return false;\n\n keys = Object.keys(pair);\n\n if (keys.length !== 1) return false;\n\n result[index] = [ keys[0], pair[keys[0]] ];\n }\n\n return true;\n}\n\nfunction constructYamlPairs(data) {\n if (data === null) return [];\n\n var index, length, pair, keys, result,\n object = data;\n\n result = new Array(object.length);\n\n for (index = 0, length = object.length; index < length; index += 1) {\n pair = object[index];\n\n keys = Object.keys(pair);\n\n result[index] = [ keys[0], pair[keys[0]] ];\n }\n\n return result;\n}\n\nvar pairs = new type('tag:yaml.org,2002:pairs', {\n kind: 'sequence',\n resolve: resolveYamlPairs,\n construct: constructYamlPairs\n});\n\nvar _hasOwnProperty$2 = Object.prototype.hasOwnProperty;\n\nfunction resolveYamlSet(data) {\n if (data === null) return true;\n\n var key, object = data;\n\n for (key in object) {\n if (_hasOwnProperty$2.call(object, key)) {\n if (object[key] !== null) return false;\n }\n }\n\n return true;\n}\n\nfunction constructYamlSet(data) {\n return data !== null ? data : {};\n}\n\nvar set = new type('tag:yaml.org,2002:set', {\n kind: 'mapping',\n resolve: resolveYamlSet,\n construct: constructYamlSet\n});\n\nvar _default = core.extend({\n implicit: [\n timestamp,\n merge\n ],\n explicit: [\n binary,\n omap,\n pairs,\n set\n ]\n});\n\n/*eslint-disable max-len,no-use-before-define*/\n\n\n\n\n\n\n\nvar _hasOwnProperty$1 = Object.prototype.hasOwnProperty;\n\n\nvar CONTEXT_FLOW_IN = 1;\nvar CONTEXT_FLOW_OUT = 2;\nvar CONTEXT_BLOCK_IN = 3;\nvar CONTEXT_BLOCK_OUT = 4;\n\n\nvar CHOMPING_CLIP = 1;\nvar CHOMPING_STRIP = 2;\nvar CHOMPING_KEEP = 3;\n\n\nvar PATTERN_NON_PRINTABLE = /[\\x00-\\x08\\x0B\\x0C\\x0E-\\x1F\\x7F-\\x84\\x86-\\x9F\\uFFFE\\uFFFF]|[\\uD800-\\uDBFF](?![\\uDC00-\\uDFFF])|(?:[^\\uD800-\\uDBFF]|^)[\\uDC00-\\uDFFF]/;\nvar PATTERN_NON_ASCII_LINE_BREAKS = /[\\x85\\u2028\\u2029]/;\nvar PATTERN_FLOW_INDICATORS = /[,\\[\\]\\{\\}]/;\nvar PATTERN_TAG_HANDLE = /^(?:!|!!|![a-z\\-]+!)$/i;\nvar PATTERN_TAG_URI = /^(?:!|[^,\\[\\]\\{\\}])(?:%[0-9a-f]{2}|[0-9a-z\\-#;\\/\\?:@&=\\+\\$,_\\.!~\\*'\\(\\)\\[\\]])*$/i;\n\n\nfunction _class(obj) { return Object.prototype.toString.call(obj); }\n\nfunction is_EOL(c) {\n return (c === 0x0A/* LF */) || (c === 0x0D/* CR */);\n}\n\nfunction is_WHITE_SPACE(c) {\n return (c === 0x09/* Tab */) || (c === 0x20/* Space */);\n}\n\nfunction is_WS_OR_EOL(c) {\n return (c === 0x09/* Tab */) ||\n (c === 0x20/* Space */) ||\n (c === 0x0A/* LF */) ||\n (c === 0x0D/* CR */);\n}\n\nfunction is_FLOW_INDICATOR(c) {\n return c === 0x2C/* , */ ||\n c === 0x5B/* [ */ ||\n c === 0x5D/* ] */ ||\n c === 0x7B/* { */ ||\n c === 0x7D/* } */;\n}\n\nfunction fromHexCode(c) {\n var lc;\n\n if ((0x30/* 0 */ <= c) && (c <= 0x39/* 9 */)) {\n return c - 0x30;\n }\n\n /*eslint-disable no-bitwise*/\n lc = c | 0x20;\n\n if ((0x61/* a */ <= lc) && (lc <= 0x66/* f */)) {\n return lc - 0x61 + 10;\n }\n\n return -1;\n}\n\nfunction escapedHexLen(c) {\n if (c === 0x78/* x */) { return 2; }\n if (c === 0x75/* u */) { return 4; }\n if (c === 0x55/* U */) { return 8; }\n return 0;\n}\n\nfunction fromDecimalCode(c) {\n if ((0x30/* 0 */ <= c) && (c <= 0x39/* 9 */)) {\n return c - 0x30;\n }\n\n return -1;\n}\n\nfunction simpleEscapeSequence(c) {\n /* eslint-disable indent */\n return (c === 0x30/* 0 */) ? '\\x00' :\n (c === 0x61/* a */) ? '\\x07' :\n (c === 0x62/* b */) ? '\\x08' :\n (c === 0x74/* t */) ? '\\x09' :\n (c === 0x09/* Tab */) ? '\\x09' :\n (c === 0x6E/* n */) ? '\\x0A' :\n (c === 0x76/* v */) ? '\\x0B' :\n (c === 0x66/* f */) ? '\\x0C' :\n (c === 0x72/* r */) ? '\\x0D' :\n (c === 0x65/* e */) ? '\\x1B' :\n (c === 0x20/* Space */) ? ' ' :\n (c === 0x22/* \" */) ? '\\x22' :\n (c === 0x2F/* / */) ? '/' :\n (c === 0x5C/* \\ */) ? '\\x5C' :\n (c === 0x4E/* N */) ? '\\x85' :\n (c === 0x5F/* _ */) ? '\\xA0' :\n (c === 0x4C/* L */) ? '\\u2028' :\n (c === 0x50/* P */) ? '\\u2029' : '';\n}\n\nfunction charFromCodepoint(c) {\n if (c <= 0xFFFF) {\n return String.fromCharCode(c);\n }\n // Encode UTF-16 surrogate pair\n // https://en.wikipedia.org/wiki/UTF-16#Code_points_U.2B010000_to_U.2B10FFFF\n return String.fromCharCode(\n ((c - 0x010000) >> 10) + 0xD800,\n ((c - 0x010000) & 0x03FF) + 0xDC00\n );\n}\n\n// set a property of a literal object, while protecting against prototype pollution,\n// see https://github.com/nodeca/js-yaml/issues/164 for more details\nfunction setProperty(object, key, value) {\n // used for this specific key only because Object.defineProperty is slow\n if (key === '__proto__') {\n Object.defineProperty(object, key, {\n configurable: true,\n enumerable: true,\n writable: true,\n value: value\n });\n } else {\n object[key] = value;\n }\n}\n\nvar simpleEscapeCheck = new Array(256); // integer, for fast access\nvar simpleEscapeMap = new Array(256);\nfor (var i = 0; i < 256; i++) {\n simpleEscapeCheck[i] = simpleEscapeSequence(i) ? 1 : 0;\n simpleEscapeMap[i] = simpleEscapeSequence(i);\n}\n\n\nfunction State$1(input, options) {\n this.input = input;\n\n this.filename = options['filename'] || null;\n this.schema = options['schema'] || _default;\n this.onWarning = options['onWarning'] || null;\n // (Hidden) Remove? makes the loader to expect YAML 1.1 documents\n // if such documents have no explicit %YAML directive\n this.legacy = options['legacy'] || false;\n\n this.json = options['json'] || false;\n this.listener = options['listener'] || null;\n\n this.implicitTypes = this.schema.compiledImplicit;\n this.typeMap = this.schema.compiledTypeMap;\n\n this.length = input.length;\n this.position = 0;\n this.line = 0;\n this.lineStart = 0;\n this.lineIndent = 0;\n\n // position of first leading tab in the current line,\n // used to make sure there are no tabs in the indentation\n this.firstTabInLine = -1;\n\n this.documents = [];\n\n /*\n this.version;\n this.checkLineBreaks;\n this.tagMap;\n this.anchorMap;\n this.tag;\n this.anchor;\n this.kind;\n this.result;*/\n\n}\n\n\nfunction generateError(state, message) {\n var mark = {\n name: state.filename,\n buffer: state.input.slice(0, -1), // omit trailing \\0\n position: state.position,\n line: state.line,\n column: state.position - state.lineStart\n };\n\n mark.snippet = snippet(mark);\n\n return new exception(message, mark);\n}\n\nfunction throwError(state, message) {\n throw generateError(state, message);\n}\n\nfunction throwWarning(state, message) {\n if (state.onWarning) {\n state.onWarning.call(null, generateError(state, message));\n }\n}\n\n\nvar directiveHandlers = {\n\n YAML: function handleYamlDirective(state, name, args) {\n\n var match, major, minor;\n\n if (state.version !== null) {\n throwError(state, 'duplication of %YAML directive');\n }\n\n if (args.length !== 1) {\n throwError(state, 'YAML directive accepts exactly one argument');\n }\n\n match = /^([0-9]+)\\.([0-9]+)$/.exec(args[0]);\n\n if (match === null) {\n throwError(state, 'ill-formed argument of the YAML directive');\n }\n\n major = parseInt(match[1], 10);\n minor = parseInt(match[2], 10);\n\n if (major !== 1) {\n throwError(state, 'unacceptable YAML version of the document');\n }\n\n state.version = args[0];\n state.checkLineBreaks = (minor < 2);\n\n if (minor !== 1 && minor !== 2) {\n throwWarning(state, 'unsupported YAML version of the document');\n }\n },\n\n TAG: function handleTagDirective(state, name, args) {\n\n var handle, prefix;\n\n if (args.length !== 2) {\n throwError(state, 'TAG directive accepts exactly two arguments');\n }\n\n handle = args[0];\n prefix = args[1];\n\n if (!PATTERN_TAG_HANDLE.test(handle)) {\n throwError(state, 'ill-formed tag handle (first argument) of the TAG directive');\n }\n\n if (_hasOwnProperty$1.call(state.tagMap, handle)) {\n throwError(state, 'there is a previously declared suffix for \"' + handle + '\" tag handle');\n }\n\n if (!PATTERN_TAG_URI.test(prefix)) {\n throwError(state, 'ill-formed tag prefix (second argument) of the TAG directive');\n }\n\n try {\n prefix = decodeURIComponent(prefix);\n } catch (err) {\n throwError(state, 'tag prefix is malformed: ' + prefix);\n }\n\n state.tagMap[handle] = prefix;\n }\n};\n\n\nfunction captureSegment(state, start, end, checkJson) {\n var _position, _length, _character, _result;\n\n if (start < end) {\n _result = state.input.slice(start, end);\n\n if (checkJson) {\n for (_position = 0, _length = _result.length; _position < _length; _position += 1) {\n _character = _result.charCodeAt(_position);\n if (!(_character === 0x09 ||\n (0x20 <= _character && _character <= 0x10FFFF))) {\n throwError(state, 'expected valid JSON character');\n }\n }\n } else if (PATTERN_NON_PRINTABLE.test(_result)) {\n throwError(state, 'the stream contains non-printable characters');\n }\n\n state.result += _result;\n }\n}\n\nfunction mergeMappings(state, destination, source, overridableKeys) {\n var sourceKeys, key, index, quantity;\n\n if (!common.isObject(source)) {\n throwError(state, 'cannot merge mappings; the provided source object is unacceptable');\n }\n\n sourceKeys = Object.keys(source);\n\n for (index = 0, quantity = sourceKeys.length; index < quantity; index += 1) {\n key = sourceKeys[index];\n\n if (!_hasOwnProperty$1.call(destination, key)) {\n setProperty(destination, key, source[key]);\n overridableKeys[key] = true;\n }\n }\n}\n\nfunction storeMappingPair(state, _result, overridableKeys, keyTag, keyNode, valueNode,\n startLine, startLineStart, startPos) {\n\n var index, quantity;\n\n // The output is a plain object here, so keys can only be strings.\n // We need to convert keyNode to a string, but doing so can hang the process\n // (deeply nested arrays that explode exponentially using aliases).\n if (Array.isArray(keyNode)) {\n keyNode = Array.prototype.slice.call(keyNode);\n\n for (index = 0, quantity = keyNode.length; index < quantity; index += 1) {\n if (Array.isArray(keyNode[index])) {\n throwError(state, 'nested arrays are not supported inside keys');\n }\n\n if (typeof keyNode === 'object' && _class(keyNode[index]) === '[object Object]') {\n keyNode[index] = '[object Object]';\n }\n }\n }\n\n // Avoid code execution in load() via toString property\n // (still use its own toString for arrays, timestamps,\n // and whatever user schema extensions happen to have @@toStringTag)\n if (typeof keyNode === 'object' && _class(keyNode) === '[object Object]') {\n keyNode = '[object Object]';\n }\n\n\n keyNode = String(keyNode);\n\n if (_result === null) {\n _result = {};\n }\n\n if (keyTag === 'tag:yaml.org,2002:merge') {\n if (Array.isArray(valueNode)) {\n for (index = 0, quantity = valueNode.length; index < quantity; index += 1) {\n mergeMappings(state, _result, valueNode[index], overridableKeys);\n }\n } else {\n mergeMappings(state, _result, valueNode, overridableKeys);\n }\n } else {\n if (!state.json &&\n !_hasOwnProperty$1.call(overridableKeys, keyNode) &&\n _hasOwnProperty$1.call(_result, keyNode)) {\n state.line = startLine || state.line;\n state.lineStart = startLineStart || state.lineStart;\n state.position = startPos || state.position;\n throwError(state, 'duplicated mapping key');\n }\n\n setProperty(_result, keyNode, valueNode);\n delete overridableKeys[keyNode];\n }\n\n return _result;\n}\n\nfunction readLineBreak(state) {\n var ch;\n\n ch = state.input.charCodeAt(state.position);\n\n if (ch === 0x0A/* LF */) {\n state.position++;\n } else if (ch === 0x0D/* CR */) {\n state.position++;\n if (state.input.charCodeAt(state.position) === 0x0A/* LF */) {\n state.position++;\n }\n } else {\n throwError(state, 'a line break is expected');\n }\n\n state.line += 1;\n state.lineStart = state.position;\n state.firstTabInLine = -1;\n}\n\nfunction skipSeparationSpace(state, allowComments, checkIndent) {\n var lineBreaks = 0,\n ch = state.input.charCodeAt(state.position);\n\n while (ch !== 0) {\n while (is_WHITE_SPACE(ch)) {\n if (ch === 0x09/* Tab */ && state.firstTabInLine === -1) {\n state.firstTabInLine = state.position;\n }\n ch = state.input.charCodeAt(++state.position);\n }\n\n if (allowComments && ch === 0x23/* # */) {\n do {\n ch = state.input.charCodeAt(++state.position);\n } while (ch !== 0x0A/* LF */ && ch !== 0x0D/* CR */ && ch !== 0);\n }\n\n if (is_EOL(ch)) {\n readLineBreak(state);\n\n ch = state.input.charCodeAt(state.position);\n lineBreaks++;\n state.lineIndent = 0;\n\n while (ch === 0x20/* Space */) {\n state.lineIndent++;\n ch = state.input.charCodeAt(++state.position);\n }\n } else {\n break;\n }\n }\n\n if (checkIndent !== -1 && lineBreaks !== 0 && state.lineIndent < checkIndent) {\n throwWarning(state, 'deficient indentation');\n }\n\n return lineBreaks;\n}\n\nfunction testDocumentSeparator(state) {\n var _position = state.position,\n ch;\n\n ch = state.input.charCodeAt(_position);\n\n // Condition state.position === state.lineStart is tested\n // in parent on each call, for efficiency. No needs to test here again.\n if ((ch === 0x2D/* - */ || ch === 0x2E/* . */) &&\n ch === state.input.charCodeAt(_position + 1) &&\n ch === state.input.charCodeAt(_position + 2)) {\n\n _position += 3;\n\n ch = state.input.charCodeAt(_position);\n\n if (ch === 0 || is_WS_OR_EOL(ch)) {\n return true;\n }\n }\n\n return false;\n}\n\nfunction writeFoldedLines(state, count) {\n if (count === 1) {\n state.result += ' ';\n } else if (count > 1) {\n state.result += common.repeat('\\n', count - 1);\n }\n}\n\n\nfunction readPlainScalar(state, nodeIndent, withinFlowCollection) {\n var preceding,\n following,\n captureStart,\n captureEnd,\n hasPendingContent,\n _line,\n _lineStart,\n _lineIndent,\n _kind = state.kind,\n _result = state.result,\n ch;\n\n ch = state.input.charCodeAt(state.position);\n\n if (is_WS_OR_EOL(ch) ||\n is_FLOW_INDICATOR(ch) ||\n ch === 0x23/* # */ ||\n ch === 0x26/* & */ ||\n ch === 0x2A/* * */ ||\n ch === 0x21/* ! */ ||\n ch === 0x7C/* | */ ||\n ch === 0x3E/* > */ ||\n ch === 0x27/* ' */ ||\n ch === 0x22/* \" */ ||\n ch === 0x25/* % */ ||\n ch === 0x40/* @ */ ||\n ch === 0x60/* ` */) {\n return false;\n }\n\n if (ch === 0x3F/* ? */ || ch === 0x2D/* - */) {\n following = state.input.charCodeAt(state.position + 1);\n\n if (is_WS_OR_EOL(following) ||\n withinFlowCollection && is_FLOW_INDICATOR(following)) {\n return false;\n }\n }\n\n state.kind = 'scalar';\n state.result = '';\n captureStart = captureEnd = state.position;\n hasPendingContent = false;\n\n while (ch !== 0) {\n if (ch === 0x3A/* : */) {\n following = state.input.charCodeAt(state.position + 1);\n\n if (is_WS_OR_EOL(following) ||\n withinFlowCollection && is_FLOW_INDICATOR(following)) {\n break;\n }\n\n } else if (ch === 0x23/* # */) {\n preceding = state.input.charCodeAt(state.position - 1);\n\n if (is_WS_OR_EOL(preceding)) {\n break;\n }\n\n } else if ((state.position === state.lineStart && testDocumentSeparator(state)) ||\n withinFlowCollection && is_FLOW_INDICATOR(ch)) {\n break;\n\n } else if (is_EOL(ch)) {\n _line = state.line;\n _lineStart = state.lineStart;\n _lineIndent = state.lineIndent;\n skipSeparationSpace(state, false, -1);\n\n if (state.lineIndent >= nodeIndent) {\n hasPendingContent = true;\n ch = state.input.charCodeAt(state.position);\n continue;\n } else {\n state.position = captureEnd;\n state.line = _line;\n state.lineStart = _lineStart;\n state.lineIndent = _lineIndent;\n break;\n }\n }\n\n if (hasPendingContent) {\n captureSegment(state, captureStart, captureEnd, false);\n writeFoldedLines(state, state.line - _line);\n captureStart = captureEnd = state.position;\n hasPendingContent = false;\n }\n\n if (!is_WHITE_SPACE(ch)) {\n captureEnd = state.position + 1;\n }\n\n ch = state.input.charCodeAt(++state.position);\n }\n\n captureSegment(state, captureStart, captureEnd, false);\n\n if (state.result) {\n return true;\n }\n\n state.kind = _kind;\n state.result = _result;\n return false;\n}\n\nfunction readSingleQuotedScalar(state, nodeIndent) {\n var ch,\n captureStart, captureEnd;\n\n ch = state.input.charCodeAt(state.position);\n\n if (ch !== 0x27/* ' */) {\n return false;\n }\n\n state.kind = 'scalar';\n state.result = '';\n state.position++;\n captureStart = captureEnd = state.position;\n\n while ((ch = state.input.charCodeAt(state.position)) !== 0) {\n if (ch === 0x27/* ' */) {\n captureSegment(state, captureStart, state.position, true);\n ch = state.input.charCodeAt(++state.position);\n\n if (ch === 0x27/* ' */) {\n captureStart = state.position;\n state.position++;\n captureEnd = state.position;\n } else {\n return true;\n }\n\n } else if (is_EOL(ch)) {\n captureSegment(state, captureStart, captureEnd, true);\n writeFoldedLines(state, skipSeparationSpace(state, false, nodeIndent));\n captureStart = captureEnd = state.position;\n\n } else if (state.position === state.lineStart && testDocumentSeparator(state)) {\n throwError(state, 'unexpected end of the document within a single quoted scalar');\n\n } else {\n state.position++;\n captureEnd = state.position;\n }\n }\n\n throwError(state, 'unexpected end of the stream within a single quoted scalar');\n}\n\nfunction readDoubleQuotedScalar(state, nodeIndent) {\n var captureStart,\n captureEnd,\n hexLength,\n hexResult,\n tmp,\n ch;\n\n ch = state.input.charCodeAt(state.position);\n\n if (ch !== 0x22/* \" */) {\n return false;\n }\n\n state.kind = 'scalar';\n state.result = '';\n state.position++;\n captureStart = captureEnd = state.position;\n\n while ((ch = state.input.charCodeAt(state.position)) !== 0) {\n if (ch === 0x22/* \" */) {\n captureSegment(state, captureStart, state.position, true);\n state.position++;\n return true;\n\n } else if (ch === 0x5C/* \\ */) {\n captureSegment(state, captureStart, state.position, true);\n ch = state.input.charCodeAt(++state.position);\n\n if (is_EOL(ch)) {\n skipSeparationSpace(state, false, nodeIndent);\n\n // TODO: rework to inline fn with no type cast?\n } else if (ch < 256 && simpleEscapeCheck[ch]) {\n state.result += simpleEscapeMap[ch];\n state.position++;\n\n } else if ((tmp = escapedHexLen(ch)) > 0) {\n hexLength = tmp;\n hexResult = 0;\n\n for (; hexLength > 0; hexLength--) {\n ch = state.input.charCodeAt(++state.position);\n\n if ((tmp = fromHexCode(ch)) >= 0) {\n hexResult = (hexResult << 4) + tmp;\n\n } else {\n throwError(state, 'expected hexadecimal character');\n }\n }\n\n state.result += charFromCodepoint(hexResult);\n\n state.position++;\n\n } else {\n throwError(state, 'unknown escape sequence');\n }\n\n captureStart = captureEnd = state.position;\n\n } else if (is_EOL(ch)) {\n captureSegment(state, captureStart, captureEnd, true);\n writeFoldedLines(state, skipSeparationSpace(state, false, nodeIndent));\n captureStart = captureEnd = state.position;\n\n } else if (state.position === state.lineStart && testDocumentSeparator(state)) {\n throwError(state, 'unexpected end of the document within a double quoted scalar');\n\n } else {\n state.position++;\n captureEnd = state.position;\n }\n }\n\n throwError(state, 'unexpected end of the stream within a double quoted scalar');\n}\n\nfunction readFlowCollection(state, nodeIndent) {\n var readNext = true,\n _line,\n _lineStart,\n _pos,\n _tag = state.tag,\n _result,\n _anchor = state.anchor,\n following,\n terminator,\n isPair,\n isExplicitPair,\n isMapping,\n overridableKeys = Object.create(null),\n keyNode,\n keyTag,\n valueNode,\n ch;\n\n ch = state.input.charCodeAt(state.position);\n\n if (ch === 0x5B/* [ */) {\n terminator = 0x5D;/* ] */\n isMapping = false;\n _result = [];\n } else if (ch === 0x7B/* { */) {\n terminator = 0x7D;/* } */\n isMapping = true;\n _result = {};\n } else {\n return false;\n }\n\n if (state.anchor !== null) {\n state.anchorMap[state.anchor] = _result;\n }\n\n ch = state.input.charCodeAt(++state.position);\n\n while (ch !== 0) {\n skipSeparationSpace(state, true, nodeIndent);\n\n ch = state.input.charCodeAt(state.position);\n\n if (ch === terminator) {\n state.position++;\n state.tag = _tag;\n state.anchor = _anchor;\n state.kind = isMapping ? 'mapping' : 'sequence';\n state.result = _result;\n return true;\n } else if (!readNext) {\n throwError(state, 'missed comma between flow collection entries');\n } else if (ch === 0x2C/* , */) {\n // \"flow collection entries can never be completely empty\", as per YAML 1.2, section 7.4\n throwError(state, \"expected the node content, but found ','\");\n }\n\n keyTag = keyNode = valueNode = null;\n isPair = isExplicitPair = false;\n\n if (ch === 0x3F/* ? */) {\n following = state.input.charCodeAt(state.position + 1);\n\n if (is_WS_OR_EOL(following)) {\n isPair = isExplicitPair = true;\n state.position++;\n skipSeparationSpace(state, true, nodeIndent);\n }\n }\n\n _line = state.line; // Save the current line.\n _lineStart = state.lineStart;\n _pos = state.position;\n composeNode(state, nodeIndent, CONTEXT_FLOW_IN, false, true);\n keyTag = state.tag;\n keyNode = state.result;\n skipSeparationSpace(state, true, nodeIndent);\n\n ch = state.input.charCodeAt(state.position);\n\n if ((isExplicitPair || state.line === _line) && ch === 0x3A/* : */) {\n isPair = true;\n ch = state.input.charCodeAt(++state.position);\n skipSeparationSpace(state, true, nodeIndent);\n composeNode(state, nodeIndent, CONTEXT_FLOW_IN, false, true);\n valueNode = state.result;\n }\n\n if (isMapping) {\n storeMappingPair(state, _result, overridableKeys, keyTag, keyNode, valueNode, _line, _lineStart, _pos);\n } else if (isPair) {\n _result.push(storeMappingPair(state, null, overridableKeys, keyTag, keyNode, valueNode, _line, _lineStart, _pos));\n } else {\n _result.push(keyNode);\n }\n\n skipSeparationSpace(state, true, nodeIndent);\n\n ch = state.input.charCodeAt(state.position);\n\n if (ch === 0x2C/* , */) {\n readNext = true;\n ch = state.input.charCodeAt(++state.position);\n } else {\n readNext = false;\n }\n }\n\n throwError(state, 'unexpected end of the stream within a flow collection');\n}\n\nfunction readBlockScalar(state, nodeIndent) {\n var captureStart,\n folding,\n chomping = CHOMPING_CLIP,\n didReadContent = false,\n detectedIndent = false,\n textIndent = nodeIndent,\n emptyLines = 0,\n atMoreIndented = false,\n tmp,\n ch;\n\n ch = state.input.charCodeAt(state.position);\n\n if (ch === 0x7C/* | */) {\n folding = false;\n } else if (ch === 0x3E/* > */) {\n folding = true;\n } else {\n return false;\n }\n\n state.kind = 'scalar';\n state.result = '';\n\n while (ch !== 0) {\n ch = state.input.charCodeAt(++state.position);\n\n if (ch === 0x2B/* + */ || ch === 0x2D/* - */) {\n if (CHOMPING_CLIP === chomping) {\n chomping = (ch === 0x2B/* + */) ? CHOMPING_KEEP : CHOMPING_STRIP;\n } else {\n throwError(state, 'repeat of a chomping mode identifier');\n }\n\n } else if ((tmp = fromDecimalCode(ch)) >= 0) {\n if (tmp === 0) {\n throwError(state, 'bad explicit indentation width of a block scalar; it cannot be less than one');\n } else if (!detectedIndent) {\n textIndent = nodeIndent + tmp - 1;\n detectedIndent = true;\n } else {\n throwError(state, 'repeat of an indentation width identifier');\n }\n\n } else {\n break;\n }\n }\n\n if (is_WHITE_SPACE(ch)) {\n do { ch = state.input.charCodeAt(++state.position); }\n while (is_WHITE_SPACE(ch));\n\n if (ch === 0x23/* # */) {\n do { ch = state.input.charCodeAt(++state.position); }\n while (!is_EOL(ch) && (ch !== 0));\n }\n }\n\n while (ch !== 0) {\n readLineBreak(state);\n state.lineIndent = 0;\n\n ch = state.input.charCodeAt(state.position);\n\n while ((!detectedIndent || state.lineIndent < textIndent) &&\n (ch === 0x20/* Space */)) {\n state.lineIndent++;\n ch = state.input.charCodeAt(++state.position);\n }\n\n if (!detectedIndent && state.lineIndent > textIndent) {\n textIndent = state.lineIndent;\n }\n\n if (is_EOL(ch)) {\n emptyLines++;\n continue;\n }\n\n // End of the scalar.\n if (state.lineIndent < textIndent) {\n\n // Perform the chomping.\n if (chomping === CHOMPING_KEEP) {\n state.result += common.repeat('\\n', didReadContent ? 1 + emptyLines : emptyLines);\n } else if (chomping === CHOMPING_CLIP) {\n if (didReadContent) { // i.e. only if the scalar is not empty.\n state.result += '\\n';\n }\n }\n\n // Break this `while` cycle and go to the funciton's epilogue.\n break;\n }\n\n // Folded style: use fancy rules to handle line breaks.\n if (folding) {\n\n // Lines starting with white space characters (more-indented lines) are not folded.\n if (is_WHITE_SPACE(ch)) {\n atMoreIndented = true;\n // except for the first content line (cf. Example 8.1)\n state.result += common.repeat('\\n', didReadContent ? 1 + emptyLines : emptyLines);\n\n // End of more-indented block.\n } else if (atMoreIndented) {\n atMoreIndented = false;\n state.result += common.repeat('\\n', emptyLines + 1);\n\n // Just one line break - perceive as the same line.\n } else if (emptyLines === 0) {\n if (didReadContent) { // i.e. only if we have already read some scalar content.\n state.result += ' ';\n }\n\n // Several line breaks - perceive as different lines.\n } else {\n state.result += common.repeat('\\n', emptyLines);\n }\n\n // Literal style: just add exact number of line breaks between content lines.\n } else {\n // Keep all line breaks except the header line break.\n state.result += common.repeat('\\n', didReadContent ? 1 + emptyLines : emptyLines);\n }\n\n didReadContent = true;\n detectedIndent = true;\n emptyLines = 0;\n captureStart = state.position;\n\n while (!is_EOL(ch) && (ch !== 0)) {\n ch = state.input.charCodeAt(++state.position);\n }\n\n captureSegment(state, captureStart, state.position, false);\n }\n\n return true;\n}\n\nfunction readBlockSequence(state, nodeIndent) {\n var _line,\n _tag = state.tag,\n _anchor = state.anchor,\n _result = [],\n following,\n detected = false,\n ch;\n\n // there is a leading tab before this token, so it can't be a block sequence/mapping;\n // it can still be flow sequence/mapping or a scalar\n if (state.firstTabInLine !== -1) return false;\n\n if (state.anchor !== null) {\n state.anchorMap[state.anchor] = _result;\n }\n\n ch = state.input.charCodeAt(state.position);\n\n while (ch !== 0) {\n if (state.firstTabInLine !== -1) {\n state.position = state.firstTabInLine;\n throwError(state, 'tab characters must not be used in indentation');\n }\n\n if (ch !== 0x2D/* - */) {\n break;\n }\n\n following = state.input.charCodeAt(state.position + 1);\n\n if (!is_WS_OR_EOL(following)) {\n break;\n }\n\n detected = true;\n state.position++;\n\n if (skipSeparationSpace(state, true, -1)) {\n if (state.lineIndent <= nodeIndent) {\n _result.push(null);\n ch = state.input.charCodeAt(state.position);\n continue;\n }\n }\n\n _line = state.line;\n composeNode(state, nodeIndent, CONTEXT_BLOCK_IN, false, true);\n _result.push(state.result);\n skipSeparationSpace(state, true, -1);\n\n ch = state.input.charCodeAt(state.position);\n\n if ((state.line === _line || state.lineIndent > nodeIndent) && (ch !== 0)) {\n throwError(state, 'bad indentation of a sequence entry');\n } else if (state.lineIndent < nodeIndent) {\n break;\n }\n }\n\n if (detected) {\n state.tag = _tag;\n state.anchor = _anchor;\n state.kind = 'sequence';\n state.result = _result;\n return true;\n }\n return false;\n}\n\nfunction readBlockMapping(state, nodeIndent, flowIndent) {\n var following,\n allowCompact,\n _line,\n _keyLine,\n _keyLineStart,\n _keyPos,\n _tag = state.tag,\n _anchor = state.anchor,\n _result = {},\n overridableKeys = Object.create(null),\n keyTag = null,\n keyNode = null,\n valueNode = null,\n atExplicitKey = false,\n detected = false,\n ch;\n\n // there is a leading tab before this token, so it can't be a block sequence/mapping;\n // it can still be flow sequence/mapping or a scalar\n if (state.firstTabInLine !== -1) return false;\n\n if (state.anchor !== null) {\n state.anchorMap[state.anchor] = _result;\n }\n\n ch = state.input.charCodeAt(state.position);\n\n while (ch !== 0) {\n if (!atExplicitKey && state.firstTabInLine !== -1) {\n state.position = state.firstTabInLine;\n throwError(state, 'tab characters must not be used in indentation');\n }\n\n following = state.input.charCodeAt(state.position + 1);\n _line = state.line; // Save the current line.\n\n //\n // Explicit notation case. There are two separate blocks:\n // first for the key (denoted by \"?\") and second for the value (denoted by \":\")\n //\n if ((ch === 0x3F/* ? */ || ch === 0x3A/* : */) && is_WS_OR_EOL(following)) {\n\n if (ch === 0x3F/* ? */) {\n if (atExplicitKey) {\n storeMappingPair(state, _result, overridableKeys, keyTag, keyNode, null, _keyLine, _keyLineStart, _keyPos);\n keyTag = keyNode = valueNode = null;\n }\n\n detected = true;\n atExplicitKey = true;\n allowCompact = true;\n\n } else if (atExplicitKey) {\n // i.e. 0x3A/* : */ === character after the explicit key.\n atExplicitKey = false;\n allowCompact = true;\n\n } else {\n throwError(state, 'incomplete explicit mapping pair; a key node is missed; or followed by a non-tabulated empty line');\n }\n\n state.position += 1;\n ch = following;\n\n //\n // Implicit notation case. Flow-style node as the key first, then \":\", and the value.\n //\n } else {\n _keyLine = state.line;\n _keyLineStart = state.lineStart;\n _keyPos = state.position;\n\n if (!composeNode(state, flowIndent, CONTEXT_FLOW_OUT, false, true)) {\n // Neither implicit nor explicit notation.\n // Reading is done. Go to the epilogue.\n break;\n }\n\n if (state.line === _line) {\n ch = state.input.charCodeAt(state.position);\n\n while (is_WHITE_SPACE(ch)) {\n ch = state.input.charCodeAt(++state.position);\n }\n\n if (ch === 0x3A/* : */) {\n ch = state.input.charCodeAt(++state.position);\n\n if (!is_WS_OR_EOL(ch)) {\n throwError(state, 'a whitespace character is expected after the key-value separator within a block mapping');\n }\n\n if (atExplicitKey) {\n storeMappingPair(state, _result, overridableKeys, keyTag, keyNode, null, _keyLine, _keyLineStart, _keyPos);\n keyTag = keyNode = valueNode = null;\n }\n\n detected = true;\n atExplicitKey = false;\n allowCompact = false;\n keyTag = state.tag;\n keyNode = state.result;\n\n } else if (detected) {\n throwError(state, 'can not read an implicit mapping pair; a colon is missed');\n\n } else {\n state.tag = _tag;\n state.anchor = _anchor;\n return true; // Keep the result of `composeNode`.\n }\n\n } else if (detected) {\n throwError(state, 'can not read a block mapping entry; a multiline key may not be an implicit key');\n\n } else {\n state.tag = _tag;\n state.anchor = _anchor;\n return true; // Keep the result of `composeNode`.\n }\n }\n\n //\n // Common reading code for both explicit and implicit notations.\n //\n if (state.line === _line || state.lineIndent > nodeIndent) {\n if (atExplicitKey) {\n _keyLine = state.line;\n _keyLineStart = state.lineStart;\n _keyPos = state.position;\n }\n\n if (composeNode(state, nodeIndent, CONTEXT_BLOCK_OUT, true, allowCompact)) {\n if (atExplicitKey) {\n keyNode = state.result;\n } else {\n valueNode = state.result;\n }\n }\n\n if (!atExplicitKey) {\n storeMappingPair(state, _result, overridableKeys, keyTag, keyNode, valueNode, _keyLine, _keyLineStart, _keyPos);\n keyTag = keyNode = valueNode = null;\n }\n\n skipSeparationSpace(state, true, -1);\n ch = state.input.charCodeAt(state.position);\n }\n\n if ((state.line === _line || state.lineIndent > nodeIndent) && (ch !== 0)) {\n throwError(state, 'bad indentation of a mapping entry');\n } else if (state.lineIndent < nodeIndent) {\n break;\n }\n }\n\n //\n // Epilogue.\n //\n\n // Special case: last mapping's node contains only the key in explicit notation.\n if (atExplicitKey) {\n storeMappingPair(state, _result, overridableKeys, keyTag, keyNode, null, _keyLine, _keyLineStart, _keyPos);\n }\n\n // Expose the resulting mapping.\n if (detected) {\n state.tag = _tag;\n state.anchor = _anchor;\n state.kind = 'mapping';\n state.result = _result;\n }\n\n return detected;\n}\n\nfunction readTagProperty(state) {\n var _position,\n isVerbatim = false,\n isNamed = false,\n tagHandle,\n tagName,\n ch;\n\n ch = state.input.charCodeAt(state.position);\n\n if (ch !== 0x21/* ! */) return false;\n\n if (state.tag !== null) {\n throwError(state, 'duplication of a tag property');\n }\n\n ch = state.input.charCodeAt(++state.position);\n\n if (ch === 0x3C/* < */) {\n isVerbatim = true;\n ch = state.input.charCodeAt(++state.position);\n\n } else if (ch === 0x21/* ! */) {\n isNamed = true;\n tagHandle = '!!';\n ch = state.input.charCodeAt(++state.position);\n\n } else {\n tagHandle = '!';\n }\n\n _position = state.position;\n\n if (isVerbatim) {\n do { ch = state.input.charCodeAt(++state.position); }\n while (ch !== 0 && ch !== 0x3E/* > */);\n\n if (state.position < state.length) {\n tagName = state.input.slice(_position, state.position);\n ch = state.input.charCodeAt(++state.position);\n } else {\n throwError(state, 'unexpected end of the stream within a verbatim tag');\n }\n } else {\n while (ch !== 0 && !is_WS_OR_EOL(ch)) {\n\n if (ch === 0x21/* ! */) {\n if (!isNamed) {\n tagHandle = state.input.slice(_position - 1, state.position + 1);\n\n if (!PATTERN_TAG_HANDLE.test(tagHandle)) {\n throwError(state, 'named tag handle cannot contain such characters');\n }\n\n isNamed = true;\n _position = state.position + 1;\n } else {\n throwError(state, 'tag suffix cannot contain exclamation marks');\n }\n }\n\n ch = state.input.charCodeAt(++state.position);\n }\n\n tagName = state.input.slice(_position, state.position);\n\n if (PATTERN_FLOW_INDICATORS.test(tagName)) {\n throwError(state, 'tag suffix cannot contain flow indicator characters');\n }\n }\n\n if (tagName && !PATTERN_TAG_URI.test(tagName)) {\n throwError(state, 'tag name cannot contain such characters: ' + tagName);\n }\n\n try {\n tagName = decodeURIComponent(tagName);\n } catch (err) {\n throwError(state, 'tag name is malformed: ' + tagName);\n }\n\n if (isVerbatim) {\n state.tag = tagName;\n\n } else if (_hasOwnProperty$1.call(state.tagMap, tagHandle)) {\n state.tag = state.tagMap[tagHandle] + tagName;\n\n } else if (tagHandle === '!') {\n state.tag = '!' + tagName;\n\n } else if (tagHandle === '!!') {\n state.tag = 'tag:yaml.org,2002:' + tagName;\n\n } else {\n throwError(state, 'undeclared tag handle \"' + tagHandle + '\"');\n }\n\n return true;\n}\n\nfunction readAnchorProperty(state) {\n var _position,\n ch;\n\n ch = state.input.charCodeAt(state.position);\n\n if (ch !== 0x26/* & */) return false;\n\n if (state.anchor !== null) {\n throwError(state, 'duplication of an anchor property');\n }\n\n ch = state.input.charCodeAt(++state.position);\n _position = state.position;\n\n while (ch !== 0 && !is_WS_OR_EOL(ch) && !is_FLOW_INDICATOR(ch)) {\n ch = state.input.charCodeAt(++state.position);\n }\n\n if (state.position === _position) {\n throwError(state, 'name of an anchor node must contain at least one character');\n }\n\n state.anchor = state.input.slice(_position, state.position);\n return true;\n}\n\nfunction readAlias(state) {\n var _position, alias,\n ch;\n\n ch = state.input.charCodeAt(state.position);\n\n if (ch !== 0x2A/* * */) return false;\n\n ch = state.input.charCodeAt(++state.position);\n _position = state.position;\n\n while (ch !== 0 && !is_WS_OR_EOL(ch) && !is_FLOW_INDICATOR(ch)) {\n ch = state.input.charCodeAt(++state.position);\n }\n\n if (state.position === _position) {\n throwError(state, 'name of an alias node must contain at least one character');\n }\n\n alias = state.input.slice(_position, state.position);\n\n if (!_hasOwnProperty$1.call(state.anchorMap, alias)) {\n throwError(state, 'unidentified alias \"' + alias + '\"');\n }\n\n state.result = state.anchorMap[alias];\n skipSeparationSpace(state, true, -1);\n return true;\n}\n\nfunction composeNode(state, parentIndent, nodeContext, allowToSeek, allowCompact) {\n var allowBlockStyles,\n allowBlockScalars,\n allowBlockCollections,\n indentStatus = 1, // 1: this>parent, 0: this=parent, -1: this parentIndent) {\n indentStatus = 1;\n } else if (state.lineIndent === parentIndent) {\n indentStatus = 0;\n } else if (state.lineIndent < parentIndent) {\n indentStatus = -1;\n }\n }\n }\n\n if (indentStatus === 1) {\n while (readTagProperty(state) || readAnchorProperty(state)) {\n if (skipSeparationSpace(state, true, -1)) {\n atNewLine = true;\n allowBlockCollections = allowBlockStyles;\n\n if (state.lineIndent > parentIndent) {\n indentStatus = 1;\n } else if (state.lineIndent === parentIndent) {\n indentStatus = 0;\n } else if (state.lineIndent < parentIndent) {\n indentStatus = -1;\n }\n } else {\n allowBlockCollections = false;\n }\n }\n }\n\n if (allowBlockCollections) {\n allowBlockCollections = atNewLine || allowCompact;\n }\n\n if (indentStatus === 1 || CONTEXT_BLOCK_OUT === nodeContext) {\n if (CONTEXT_FLOW_IN === nodeContext || CONTEXT_FLOW_OUT === nodeContext) {\n flowIndent = parentIndent;\n } else {\n flowIndent = parentIndent + 1;\n }\n\n blockIndent = state.position - state.lineStart;\n\n if (indentStatus === 1) {\n if (allowBlockCollections &&\n (readBlockSequence(state, blockIndent) ||\n readBlockMapping(state, blockIndent, flowIndent)) ||\n readFlowCollection(state, flowIndent)) {\n hasContent = true;\n } else {\n if ((allowBlockScalars && readBlockScalar(state, flowIndent)) ||\n readSingleQuotedScalar(state, flowIndent) ||\n readDoubleQuotedScalar(state, flowIndent)) {\n hasContent = true;\n\n } else if (readAlias(state)) {\n hasContent = true;\n\n if (state.tag !== null || state.anchor !== null) {\n throwError(state, 'alias node should not have any properties');\n }\n\n } else if (readPlainScalar(state, flowIndent, CONTEXT_FLOW_IN === nodeContext)) {\n hasContent = true;\n\n if (state.tag === null) {\n state.tag = '?';\n }\n }\n\n if (state.anchor !== null) {\n state.anchorMap[state.anchor] = state.result;\n }\n }\n } else if (indentStatus === 0) {\n // Special case: block sequences are allowed to have same indentation level as the parent.\n // http://www.yaml.org/spec/1.2/spec.html#id2799784\n hasContent = allowBlockCollections && readBlockSequence(state, blockIndent);\n }\n }\n\n if (state.tag === null) {\n if (state.anchor !== null) {\n state.anchorMap[state.anchor] = state.result;\n }\n\n } else if (state.tag === '?') {\n // Implicit resolving is not allowed for non-scalar types, and '?'\n // non-specific tag is only automatically assigned to plain scalars.\n //\n // We only need to check kind conformity in case user explicitly assigns '?'\n // tag, for example like this: \"! [0]\"\n //\n if (state.result !== null && state.kind !== 'scalar') {\n throwError(state, 'unacceptable node kind for ! tag; it should be \"scalar\", not \"' + state.kind + '\"');\n }\n\n for (typeIndex = 0, typeQuantity = state.implicitTypes.length; typeIndex < typeQuantity; typeIndex += 1) {\n type = state.implicitTypes[typeIndex];\n\n if (type.resolve(state.result)) { // `state.result` updated in resolver if matched\n state.result = type.construct(state.result);\n state.tag = type.tag;\n if (state.anchor !== null) {\n state.anchorMap[state.anchor] = state.result;\n }\n break;\n }\n }\n } else if (state.tag !== '!') {\n if (_hasOwnProperty$1.call(state.typeMap[state.kind || 'fallback'], state.tag)) {\n type = state.typeMap[state.kind || 'fallback'][state.tag];\n } else {\n // looking for multi type\n type = null;\n typeList = state.typeMap.multi[state.kind || 'fallback'];\n\n for (typeIndex = 0, typeQuantity = typeList.length; typeIndex < typeQuantity; typeIndex += 1) {\n if (state.tag.slice(0, typeList[typeIndex].tag.length) === typeList[typeIndex].tag) {\n type = typeList[typeIndex];\n break;\n }\n }\n }\n\n if (!type) {\n throwError(state, 'unknown tag !<' + state.tag + '>');\n }\n\n if (state.result !== null && type.kind !== state.kind) {\n throwError(state, 'unacceptable node kind for !<' + state.tag + '> tag; it should be \"' + type.kind + '\", not \"' + state.kind + '\"');\n }\n\n if (!type.resolve(state.result, state.tag)) { // `state.result` updated in resolver if matched\n throwError(state, 'cannot resolve a node with !<' + state.tag + '> explicit tag');\n } else {\n state.result = type.construct(state.result, state.tag);\n if (state.anchor !== null) {\n state.anchorMap[state.anchor] = state.result;\n }\n }\n }\n\n if (state.listener !== null) {\n state.listener('close', state);\n }\n return state.tag !== null || state.anchor !== null || hasContent;\n}\n\nfunction readDocument(state) {\n var documentStart = state.position,\n _position,\n directiveName,\n directiveArgs,\n hasDirectives = false,\n ch;\n\n state.version = null;\n state.checkLineBreaks = state.legacy;\n state.tagMap = Object.create(null);\n state.anchorMap = Object.create(null);\n\n while ((ch = state.input.charCodeAt(state.position)) !== 0) {\n skipSeparationSpace(state, true, -1);\n\n ch = state.input.charCodeAt(state.position);\n\n if (state.lineIndent > 0 || ch !== 0x25/* % */) {\n break;\n }\n\n hasDirectives = true;\n ch = state.input.charCodeAt(++state.position);\n _position = state.position;\n\n while (ch !== 0 && !is_WS_OR_EOL(ch)) {\n ch = state.input.charCodeAt(++state.position);\n }\n\n directiveName = state.input.slice(_position, state.position);\n directiveArgs = [];\n\n if (directiveName.length < 1) {\n throwError(state, 'directive name must not be less than one character in length');\n }\n\n while (ch !== 0) {\n while (is_WHITE_SPACE(ch)) {\n ch = state.input.charCodeAt(++state.position);\n }\n\n if (ch === 0x23/* # */) {\n do { ch = state.input.charCodeAt(++state.position); }\n while (ch !== 0 && !is_EOL(ch));\n break;\n }\n\n if (is_EOL(ch)) break;\n\n _position = state.position;\n\n while (ch !== 0 && !is_WS_OR_EOL(ch)) {\n ch = state.input.charCodeAt(++state.position);\n }\n\n directiveArgs.push(state.input.slice(_position, state.position));\n }\n\n if (ch !== 0) readLineBreak(state);\n\n if (_hasOwnProperty$1.call(directiveHandlers, directiveName)) {\n directiveHandlers[directiveName](state, directiveName, directiveArgs);\n } else {\n throwWarning(state, 'unknown document directive \"' + directiveName + '\"');\n }\n }\n\n skipSeparationSpace(state, true, -1);\n\n if (state.lineIndent === 0 &&\n state.input.charCodeAt(state.position) === 0x2D/* - */ &&\n state.input.charCodeAt(state.position + 1) === 0x2D/* - */ &&\n state.input.charCodeAt(state.position + 2) === 0x2D/* - */) {\n state.position += 3;\n skipSeparationSpace(state, true, -1);\n\n } else if (hasDirectives) {\n throwError(state, 'directives end mark is expected');\n }\n\n composeNode(state, state.lineIndent - 1, CONTEXT_BLOCK_OUT, false, true);\n skipSeparationSpace(state, true, -1);\n\n if (state.checkLineBreaks &&\n PATTERN_NON_ASCII_LINE_BREAKS.test(state.input.slice(documentStart, state.position))) {\n throwWarning(state, 'non-ASCII line breaks are interpreted as content');\n }\n\n state.documents.push(state.result);\n\n if (state.position === state.lineStart && testDocumentSeparator(state)) {\n\n if (state.input.charCodeAt(state.position) === 0x2E/* . */) {\n state.position += 3;\n skipSeparationSpace(state, true, -1);\n }\n return;\n }\n\n if (state.position < (state.length - 1)) {\n throwError(state, 'end of the stream or a document separator is expected');\n } else {\n return;\n }\n}\n\n\nfunction loadDocuments(input, options) {\n input = String(input);\n options = options || {};\n\n if (input.length !== 0) {\n\n // Add tailing `\\n` if not exists\n if (input.charCodeAt(input.length - 1) !== 0x0A/* LF */ &&\n input.charCodeAt(input.length - 1) !== 0x0D/* CR */) {\n input += '\\n';\n }\n\n // Strip BOM\n if (input.charCodeAt(0) === 0xFEFF) {\n input = input.slice(1);\n }\n }\n\n var state = new State$1(input, options);\n\n var nullpos = input.indexOf('\\0');\n\n if (nullpos !== -1) {\n state.position = nullpos;\n throwError(state, 'null byte is not allowed in input');\n }\n\n // Use 0 as string terminator. That significantly simplifies bounds check.\n state.input += '\\0';\n\n while (state.input.charCodeAt(state.position) === 0x20/* Space */) {\n state.lineIndent += 1;\n state.position += 1;\n }\n\n while (state.position < (state.length - 1)) {\n readDocument(state);\n }\n\n return state.documents;\n}\n\n\nfunction loadAll$1(input, iterator, options) {\n if (iterator !== null && typeof iterator === 'object' && typeof options === 'undefined') {\n options = iterator;\n iterator = null;\n }\n\n var documents = loadDocuments(input, options);\n\n if (typeof iterator !== 'function') {\n return documents;\n }\n\n for (var index = 0, length = documents.length; index < length; index += 1) {\n iterator(documents[index]);\n }\n}\n\n\nfunction load$1(input, options) {\n var documents = loadDocuments(input, options);\n\n if (documents.length === 0) {\n /*eslint-disable no-undefined*/\n return undefined;\n } else if (documents.length === 1) {\n return documents[0];\n }\n throw new exception('expected a single document in the stream, but found more');\n}\n\n\nvar loadAll_1 = loadAll$1;\nvar load_1 = load$1;\n\nvar loader = {\n\tloadAll: loadAll_1,\n\tload: load_1\n};\n\n/*eslint-disable no-use-before-define*/\n\n\n\n\n\nvar _toString = Object.prototype.toString;\nvar _hasOwnProperty = Object.prototype.hasOwnProperty;\n\nvar CHAR_BOM = 0xFEFF;\nvar CHAR_TAB = 0x09; /* Tab */\nvar CHAR_LINE_FEED = 0x0A; /* LF */\nvar CHAR_CARRIAGE_RETURN = 0x0D; /* CR */\nvar CHAR_SPACE = 0x20; /* Space */\nvar CHAR_EXCLAMATION = 0x21; /* ! */\nvar CHAR_DOUBLE_QUOTE = 0x22; /* \" */\nvar CHAR_SHARP = 0x23; /* # */\nvar CHAR_PERCENT = 0x25; /* % */\nvar CHAR_AMPERSAND = 0x26; /* & */\nvar CHAR_SINGLE_QUOTE = 0x27; /* ' */\nvar CHAR_ASTERISK = 0x2A; /* * */\nvar CHAR_COMMA = 0x2C; /* , */\nvar CHAR_MINUS = 0x2D; /* - */\nvar CHAR_COLON = 0x3A; /* : */\nvar CHAR_EQUALS = 0x3D; /* = */\nvar CHAR_GREATER_THAN = 0x3E; /* > */\nvar CHAR_QUESTION = 0x3F; /* ? */\nvar CHAR_COMMERCIAL_AT = 0x40; /* @ */\nvar CHAR_LEFT_SQUARE_BRACKET = 0x5B; /* [ */\nvar CHAR_RIGHT_SQUARE_BRACKET = 0x5D; /* ] */\nvar CHAR_GRAVE_ACCENT = 0x60; /* ` */\nvar CHAR_LEFT_CURLY_BRACKET = 0x7B; /* { */\nvar CHAR_VERTICAL_LINE = 0x7C; /* | */\nvar CHAR_RIGHT_CURLY_BRACKET = 0x7D; /* } */\n\nvar ESCAPE_SEQUENCES = {};\n\nESCAPE_SEQUENCES[0x00] = '\\\\0';\nESCAPE_SEQUENCES[0x07] = '\\\\a';\nESCAPE_SEQUENCES[0x08] = '\\\\b';\nESCAPE_SEQUENCES[0x09] = '\\\\t';\nESCAPE_SEQUENCES[0x0A] = '\\\\n';\nESCAPE_SEQUENCES[0x0B] = '\\\\v';\nESCAPE_SEQUENCES[0x0C] = '\\\\f';\nESCAPE_SEQUENCES[0x0D] = '\\\\r';\nESCAPE_SEQUENCES[0x1B] = '\\\\e';\nESCAPE_SEQUENCES[0x22] = '\\\\\"';\nESCAPE_SEQUENCES[0x5C] = '\\\\\\\\';\nESCAPE_SEQUENCES[0x85] = '\\\\N';\nESCAPE_SEQUENCES[0xA0] = '\\\\_';\nESCAPE_SEQUENCES[0x2028] = '\\\\L';\nESCAPE_SEQUENCES[0x2029] = '\\\\P';\n\nvar DEPRECATED_BOOLEANS_SYNTAX = [\n 'y', 'Y', 'yes', 'Yes', 'YES', 'on', 'On', 'ON',\n 'n', 'N', 'no', 'No', 'NO', 'off', 'Off', 'OFF'\n];\n\nvar DEPRECATED_BASE60_SYNTAX = /^[-+]?[0-9_]+(?::[0-9_]+)+(?:\\.[0-9_]*)?$/;\n\nfunction compileStyleMap(schema, map) {\n var result, keys, index, length, tag, style, type;\n\n if (map === null) return {};\n\n result = {};\n keys = Object.keys(map);\n\n for (index = 0, length = keys.length; index < length; index += 1) {\n tag = keys[index];\n style = String(map[tag]);\n\n if (tag.slice(0, 2) === '!!') {\n tag = 'tag:yaml.org,2002:' + tag.slice(2);\n }\n type = schema.compiledTypeMap['fallback'][tag];\n\n if (type && _hasOwnProperty.call(type.styleAliases, style)) {\n style = type.styleAliases[style];\n }\n\n result[tag] = style;\n }\n\n return result;\n}\n\nfunction encodeHex(character) {\n var string, handle, length;\n\n string = character.toString(16).toUpperCase();\n\n if (character <= 0xFF) {\n handle = 'x';\n length = 2;\n } else if (character <= 0xFFFF) {\n handle = 'u';\n length = 4;\n } else if (character <= 0xFFFFFFFF) {\n handle = 'U';\n length = 8;\n } else {\n throw new exception('code point within a string may not be greater than 0xFFFFFFFF');\n }\n\n return '\\\\' + handle + common.repeat('0', length - string.length) + string;\n}\n\n\nvar QUOTING_TYPE_SINGLE = 1,\n QUOTING_TYPE_DOUBLE = 2;\n\nfunction State(options) {\n this.schema = options['schema'] || _default;\n this.indent = Math.max(1, (options['indent'] || 2));\n this.noArrayIndent = options['noArrayIndent'] || false;\n this.skipInvalid = options['skipInvalid'] || false;\n this.flowLevel = (common.isNothing(options['flowLevel']) ? -1 : options['flowLevel']);\n this.styleMap = compileStyleMap(this.schema, options['styles'] || null);\n this.sortKeys = options['sortKeys'] || false;\n this.lineWidth = options['lineWidth'] || 80;\n this.noRefs = options['noRefs'] || false;\n this.noCompatMode = options['noCompatMode'] || false;\n this.condenseFlow = options['condenseFlow'] || false;\n this.quotingType = options['quotingType'] === '\"' ? QUOTING_TYPE_DOUBLE : QUOTING_TYPE_SINGLE;\n this.forceQuotes = options['forceQuotes'] || false;\n this.replacer = typeof options['replacer'] === 'function' ? options['replacer'] : null;\n\n this.implicitTypes = this.schema.compiledImplicit;\n this.explicitTypes = this.schema.compiledExplicit;\n\n this.tag = null;\n this.result = '';\n\n this.duplicates = [];\n this.usedDuplicates = null;\n}\n\n// Indents every line in a string. Empty lines (\\n only) are not indented.\nfunction indentString(string, spaces) {\n var ind = common.repeat(' ', spaces),\n position = 0,\n next = -1,\n result = '',\n line,\n length = string.length;\n\n while (position < length) {\n next = string.indexOf('\\n', position);\n if (next === -1) {\n line = string.slice(position);\n position = length;\n } else {\n line = string.slice(position, next + 1);\n position = next + 1;\n }\n\n if (line.length && line !== '\\n') result += ind;\n\n result += line;\n }\n\n return result;\n}\n\nfunction generateNextLine(state, level) {\n return '\\n' + common.repeat(' ', state.indent * level);\n}\n\nfunction testImplicitResolving(state, str) {\n var index, length, type;\n\n for (index = 0, length = state.implicitTypes.length; index < length; index += 1) {\n type = state.implicitTypes[index];\n\n if (type.resolve(str)) {\n return true;\n }\n }\n\n return false;\n}\n\n// [33] s-white ::= s-space | s-tab\nfunction isWhitespace(c) {\n return c === CHAR_SPACE || c === CHAR_TAB;\n}\n\n// Returns true if the character can be printed without escaping.\n// From YAML 1.2: \"any allowed characters known to be non-printable\n// should also be escaped. [However,] This isn\u2019t mandatory\"\n// Derived from nb-char - \\t - #x85 - #xA0 - #x2028 - #x2029.\nfunction isPrintable(c) {\n return (0x00020 <= c && c <= 0x00007E)\n || ((0x000A1 <= c && c <= 0x00D7FF) && c !== 0x2028 && c !== 0x2029)\n || ((0x0E000 <= c && c <= 0x00FFFD) && c !== CHAR_BOM)\n || (0x10000 <= c && c <= 0x10FFFF);\n}\n\n// [34] ns-char ::= nb-char - s-white\n// [27] nb-char ::= c-printable - b-char - c-byte-order-mark\n// [26] b-char ::= b-line-feed | b-carriage-return\n// Including s-white (for some reason, examples doesn't match specs in this aspect)\n// ns-char ::= c-printable - b-line-feed - b-carriage-return - c-byte-order-mark\nfunction isNsCharOrWhitespace(c) {\n return isPrintable(c)\n && c !== CHAR_BOM\n // - b-char\n && c !== CHAR_CARRIAGE_RETURN\n && c !== CHAR_LINE_FEED;\n}\n\n// [127] ns-plain-safe(c) ::= c = flow-out \u21D2 ns-plain-safe-out\n// c = flow-in \u21D2 ns-plain-safe-in\n// c = block-key \u21D2 ns-plain-safe-out\n// c = flow-key \u21D2 ns-plain-safe-in\n// [128] ns-plain-safe-out ::= ns-char\n// [129] ns-plain-safe-in ::= ns-char - c-flow-indicator\n// [130] ns-plain-char(c) ::= ( ns-plain-safe(c) - \u201C:\u201D - \u201C#\u201D )\n// | ( /* An ns-char preceding */ \u201C#\u201D )\n// | ( \u201C:\u201D /* Followed by an ns-plain-safe(c) */ )\nfunction isPlainSafe(c, prev, inblock) {\n var cIsNsCharOrWhitespace = isNsCharOrWhitespace(c);\n var cIsNsChar = cIsNsCharOrWhitespace && !isWhitespace(c);\n return (\n // ns-plain-safe\n inblock ? // c = flow-in\n cIsNsCharOrWhitespace\n : cIsNsCharOrWhitespace\n // - c-flow-indicator\n && c !== CHAR_COMMA\n && c !== CHAR_LEFT_SQUARE_BRACKET\n && c !== CHAR_RIGHT_SQUARE_BRACKET\n && c !== CHAR_LEFT_CURLY_BRACKET\n && c !== CHAR_RIGHT_CURLY_BRACKET\n )\n // ns-plain-char\n && c !== CHAR_SHARP // false on '#'\n && !(prev === CHAR_COLON && !cIsNsChar) // false on ': '\n || (isNsCharOrWhitespace(prev) && !isWhitespace(prev) && c === CHAR_SHARP) // change to true on '[^ ]#'\n || (prev === CHAR_COLON && cIsNsChar); // change to true on ':[^ ]'\n}\n\n// Simplified test for values allowed as the first character in plain style.\nfunction isPlainSafeFirst(c) {\n // Uses a subset of ns-char - c-indicator\n // where ns-char = nb-char - s-white.\n // No support of ( ( \u201C?\u201D | \u201C:\u201D | \u201C-\u201D ) /* Followed by an ns-plain-safe(c)) */ ) part\n return isPrintable(c) && c !== CHAR_BOM\n && !isWhitespace(c) // - s-white\n // - (c-indicator ::=\n // \u201C-\u201D | \u201C?\u201D | \u201C:\u201D | \u201C,\u201D | \u201C[\u201D | \u201C]\u201D | \u201C{\u201D | \u201C}\u201D\n && c !== CHAR_MINUS\n && c !== CHAR_QUESTION\n && c !== CHAR_COLON\n && c !== CHAR_COMMA\n && c !== CHAR_LEFT_SQUARE_BRACKET\n && c !== CHAR_RIGHT_SQUARE_BRACKET\n && c !== CHAR_LEFT_CURLY_BRACKET\n && c !== CHAR_RIGHT_CURLY_BRACKET\n // | \u201C#\u201D | \u201C&\u201D | \u201C*\u201D | \u201C!\u201D | \u201C|\u201D | \u201C=\u201D | \u201C>\u201D | \u201C'\u201D | \u201C\"\u201D\n && c !== CHAR_SHARP\n && c !== CHAR_AMPERSAND\n && c !== CHAR_ASTERISK\n && c !== CHAR_EXCLAMATION\n && c !== CHAR_VERTICAL_LINE\n && c !== CHAR_EQUALS\n && c !== CHAR_GREATER_THAN\n && c !== CHAR_SINGLE_QUOTE\n && c !== CHAR_DOUBLE_QUOTE\n // | \u201C%\u201D | \u201C@\u201D | \u201C`\u201D)\n && c !== CHAR_PERCENT\n && c !== CHAR_COMMERCIAL_AT\n && c !== CHAR_GRAVE_ACCENT;\n}\n\n// Simplified test for values allowed as the last character in plain style.\nfunction isPlainSafeLast(c) {\n // just not whitespace or colon, it will be checked to be plain character later\n return !isWhitespace(c) && c !== CHAR_COLON;\n}\n\n// Same as 'string'.codePointAt(pos), but works in older browsers.\nfunction codePointAt(string, pos) {\n var first = string.charCodeAt(pos), second;\n if (first >= 0xD800 && first <= 0xDBFF && pos + 1 < string.length) {\n second = string.charCodeAt(pos + 1);\n if (second >= 0xDC00 && second <= 0xDFFF) {\n // https://mathiasbynens.be/notes/javascript-encoding#surrogate-formulae\n return (first - 0xD800) * 0x400 + second - 0xDC00 + 0x10000;\n }\n }\n return first;\n}\n\n// Determines whether block indentation indicator is required.\nfunction needIndentIndicator(string) {\n var leadingSpaceRe = /^\\n* /;\n return leadingSpaceRe.test(string);\n}\n\nvar STYLE_PLAIN = 1,\n STYLE_SINGLE = 2,\n STYLE_LITERAL = 3,\n STYLE_FOLDED = 4,\n STYLE_DOUBLE = 5;\n\n// Determines which scalar styles are possible and returns the preferred style.\n// lineWidth = -1 => no limit.\n// Pre-conditions: str.length > 0.\n// Post-conditions:\n// STYLE_PLAIN or STYLE_SINGLE => no \\n are in the string.\n// STYLE_LITERAL => no lines are suitable for folding (or lineWidth is -1).\n// STYLE_FOLDED => a line > lineWidth and can be folded (and lineWidth != -1).\nfunction chooseScalarStyle(string, singleLineOnly, indentPerLevel, lineWidth,\n testAmbiguousType, quotingType, forceQuotes, inblock) {\n\n var i;\n var char = 0;\n var prevChar = null;\n var hasLineBreak = false;\n var hasFoldableLine = false; // only checked if shouldTrackWidth\n var shouldTrackWidth = lineWidth !== -1;\n var previousLineBreak = -1; // count the first line correctly\n var plain = isPlainSafeFirst(codePointAt(string, 0))\n && isPlainSafeLast(codePointAt(string, string.length - 1));\n\n if (singleLineOnly || forceQuotes) {\n // Case: no block styles.\n // Check for disallowed characters to rule out plain and single.\n for (i = 0; i < string.length; char >= 0x10000 ? i += 2 : i++) {\n char = codePointAt(string, i);\n if (!isPrintable(char)) {\n return STYLE_DOUBLE;\n }\n plain = plain && isPlainSafe(char, prevChar, inblock);\n prevChar = char;\n }\n } else {\n // Case: block styles permitted.\n for (i = 0; i < string.length; char >= 0x10000 ? i += 2 : i++) {\n char = codePointAt(string, i);\n if (char === CHAR_LINE_FEED) {\n hasLineBreak = true;\n // Check if any line can be folded.\n if (shouldTrackWidth) {\n hasFoldableLine = hasFoldableLine ||\n // Foldable line = too long, and not more-indented.\n (i - previousLineBreak - 1 > lineWidth &&\n string[previousLineBreak + 1] !== ' ');\n previousLineBreak = i;\n }\n } else if (!isPrintable(char)) {\n return STYLE_DOUBLE;\n }\n plain = plain && isPlainSafe(char, prevChar, inblock);\n prevChar = char;\n }\n // in case the end is missing a \\n\n hasFoldableLine = hasFoldableLine || (shouldTrackWidth &&\n (i - previousLineBreak - 1 > lineWidth &&\n string[previousLineBreak + 1] !== ' '));\n }\n // Although every style can represent \\n without escaping, prefer block styles\n // for multiline, since they're more readable and they don't add empty lines.\n // Also prefer folding a super-long line.\n if (!hasLineBreak && !hasFoldableLine) {\n // Strings interpretable as another type have to be quoted;\n // e.g. the string 'true' vs. the boolean true.\n if (plain && !forceQuotes && !testAmbiguousType(string)) {\n return STYLE_PLAIN;\n }\n return quotingType === QUOTING_TYPE_DOUBLE ? STYLE_DOUBLE : STYLE_SINGLE;\n }\n // Edge case: block indentation indicator can only have one digit.\n if (indentPerLevel > 9 && needIndentIndicator(string)) {\n return STYLE_DOUBLE;\n }\n // At this point we know block styles are valid.\n // Prefer literal style unless we want to fold.\n if (!forceQuotes) {\n return hasFoldableLine ? STYLE_FOLDED : STYLE_LITERAL;\n }\n return quotingType === QUOTING_TYPE_DOUBLE ? STYLE_DOUBLE : STYLE_SINGLE;\n}\n\n// Note: line breaking/folding is implemented for only the folded style.\n// NB. We drop the last trailing newline (if any) of a returned block scalar\n// since the dumper adds its own newline. This always works:\n// \u2022 No ending newline => unaffected; already using strip \"-\" chomping.\n// \u2022 Ending newline => removed then restored.\n// Importantly, this keeps the \"+\" chomp indicator from gaining an extra line.\nfunction writeScalar(state, string, level, iskey, inblock) {\n state.dump = (function () {\n if (string.length === 0) {\n return state.quotingType === QUOTING_TYPE_DOUBLE ? '\"\"' : \"''\";\n }\n if (!state.noCompatMode) {\n if (DEPRECATED_BOOLEANS_SYNTAX.indexOf(string) !== -1 || DEPRECATED_BASE60_SYNTAX.test(string)) {\n return state.quotingType === QUOTING_TYPE_DOUBLE ? ('\"' + string + '\"') : (\"'\" + string + \"'\");\n }\n }\n\n var indent = state.indent * Math.max(1, level); // no 0-indent scalars\n // As indentation gets deeper, let the width decrease monotonically\n // to the lower bound min(state.lineWidth, 40).\n // Note that this implies\n // state.lineWidth \u2264 40 + state.indent: width is fixed at the lower bound.\n // state.lineWidth > 40 + state.indent: width decreases until the lower bound.\n // This behaves better than a constant minimum width which disallows narrower options,\n // or an indent threshold which causes the width to suddenly increase.\n var lineWidth = state.lineWidth === -1\n ? -1 : Math.max(Math.min(state.lineWidth, 40), state.lineWidth - indent);\n\n // Without knowing if keys are implicit/explicit, assume implicit for safety.\n var singleLineOnly = iskey\n // No block styles in flow mode.\n || (state.flowLevel > -1 && level >= state.flowLevel);\n function testAmbiguity(string) {\n return testImplicitResolving(state, string);\n }\n\n switch (chooseScalarStyle(string, singleLineOnly, state.indent, lineWidth,\n testAmbiguity, state.quotingType, state.forceQuotes && !iskey, inblock)) {\n\n case STYLE_PLAIN:\n return string;\n case STYLE_SINGLE:\n return \"'\" + string.replace(/'/g, \"''\") + \"'\";\n case STYLE_LITERAL:\n return '|' + blockHeader(string, state.indent)\n + dropEndingNewline(indentString(string, indent));\n case STYLE_FOLDED:\n return '>' + blockHeader(string, state.indent)\n + dropEndingNewline(indentString(foldString(string, lineWidth), indent));\n case STYLE_DOUBLE:\n return '\"' + escapeString(string) + '\"';\n default:\n throw new exception('impossible error: invalid scalar style');\n }\n }());\n}\n\n// Pre-conditions: string is valid for a block scalar, 1 <= indentPerLevel <= 9.\nfunction blockHeader(string, indentPerLevel) {\n var indentIndicator = needIndentIndicator(string) ? String(indentPerLevel) : '';\n\n // note the special case: the string '\\n' counts as a \"trailing\" empty line.\n var clip = string[string.length - 1] === '\\n';\n var keep = clip && (string[string.length - 2] === '\\n' || string === '\\n');\n var chomp = keep ? '+' : (clip ? '' : '-');\n\n return indentIndicator + chomp + '\\n';\n}\n\n// (See the note for writeScalar.)\nfunction dropEndingNewline(string) {\n return string[string.length - 1] === '\\n' ? string.slice(0, -1) : string;\n}\n\n// Note: a long line without a suitable break point will exceed the width limit.\n// Pre-conditions: every char in str isPrintable, str.length > 0, width > 0.\nfunction foldString(string, width) {\n // In folded style, $k$ consecutive newlines output as $k+1$ newlines\u2014\n // unless they're before or after a more-indented line, or at the very\n // beginning or end, in which case $k$ maps to $k$.\n // Therefore, parse each chunk as newline(s) followed by a content line.\n var lineRe = /(\\n+)([^\\n]*)/g;\n\n // first line (possibly an empty line)\n var result = (function () {\n var nextLF = string.indexOf('\\n');\n nextLF = nextLF !== -1 ? nextLF : string.length;\n lineRe.lastIndex = nextLF;\n return foldLine(string.slice(0, nextLF), width);\n }());\n // If we haven't reached the first content line yet, don't add an extra \\n.\n var prevMoreIndented = string[0] === '\\n' || string[0] === ' ';\n var moreIndented;\n\n // rest of the lines\n var match;\n while ((match = lineRe.exec(string))) {\n var prefix = match[1], line = match[2];\n moreIndented = (line[0] === ' ');\n result += prefix\n + (!prevMoreIndented && !moreIndented && line !== ''\n ? '\\n' : '')\n + foldLine(line, width);\n prevMoreIndented = moreIndented;\n }\n\n return result;\n}\n\n// Greedy line breaking.\n// Picks the longest line under the limit each time,\n// otherwise settles for the shortest line over the limit.\n// NB. More-indented lines *cannot* be folded, as that would add an extra \\n.\nfunction foldLine(line, width) {\n if (line === '' || line[0] === ' ') return line;\n\n // Since a more-indented line adds a \\n, breaks can't be followed by a space.\n var breakRe = / [^ ]/g; // note: the match index will always be <= length-2.\n var match;\n // start is an inclusive index. end, curr, and next are exclusive.\n var start = 0, end, curr = 0, next = 0;\n var result = '';\n\n // Invariants: 0 <= start <= length-1.\n // 0 <= curr <= next <= max(0, length-2). curr - start <= width.\n // Inside the loop:\n // A match implies length >= 2, so curr and next are <= length-2.\n while ((match = breakRe.exec(line))) {\n next = match.index;\n // maintain invariant: curr - start <= width\n if (next - start > width) {\n end = (curr > start) ? curr : next; // derive end <= length-2\n result += '\\n' + line.slice(start, end);\n // skip the space that was output as \\n\n start = end + 1; // derive start <= length-1\n }\n curr = next;\n }\n\n // By the invariants, start <= length-1, so there is something left over.\n // It is either the whole string or a part starting from non-whitespace.\n result += '\\n';\n // Insert a break if the remainder is too long and there is a break available.\n if (line.length - start > width && curr > start) {\n result += line.slice(start, curr) + '\\n' + line.slice(curr + 1);\n } else {\n result += line.slice(start);\n }\n\n return result.slice(1); // drop extra \\n joiner\n}\n\n// Escapes a double-quoted string.\nfunction escapeString(string) {\n var result = '';\n var char = 0;\n var escapeSeq;\n\n for (var i = 0; i < string.length; char >= 0x10000 ? i += 2 : i++) {\n char = codePointAt(string, i);\n escapeSeq = ESCAPE_SEQUENCES[char];\n\n if (!escapeSeq && isPrintable(char)) {\n result += string[i];\n if (char >= 0x10000) result += string[i + 1];\n } else {\n result += escapeSeq || encodeHex(char);\n }\n }\n\n return result;\n}\n\nfunction writeFlowSequence(state, level, object) {\n var _result = '',\n _tag = state.tag,\n index,\n length,\n value;\n\n for (index = 0, length = object.length; index < length; index += 1) {\n value = object[index];\n\n if (state.replacer) {\n value = state.replacer.call(object, String(index), value);\n }\n\n // Write only valid elements, put null instead of invalid elements.\n if (writeNode(state, level, value, false, false) ||\n (typeof value === 'undefined' &&\n writeNode(state, level, null, false, false))) {\n\n if (_result !== '') _result += ',' + (!state.condenseFlow ? ' ' : '');\n _result += state.dump;\n }\n }\n\n state.tag = _tag;\n state.dump = '[' + _result + ']';\n}\n\nfunction writeBlockSequence(state, level, object, compact) {\n var _result = '',\n _tag = state.tag,\n index,\n length,\n value;\n\n for (index = 0, length = object.length; index < length; index += 1) {\n value = object[index];\n\n if (state.replacer) {\n value = state.replacer.call(object, String(index), value);\n }\n\n // Write only valid elements, put null instead of invalid elements.\n if (writeNode(state, level + 1, value, true, true, false, true) ||\n (typeof value === 'undefined' &&\n writeNode(state, level + 1, null, true, true, false, true))) {\n\n if (!compact || _result !== '') {\n _result += generateNextLine(state, level);\n }\n\n if (state.dump && CHAR_LINE_FEED === state.dump.charCodeAt(0)) {\n _result += '-';\n } else {\n _result += '- ';\n }\n\n _result += state.dump;\n }\n }\n\n state.tag = _tag;\n state.dump = _result || '[]'; // Empty sequence if no valid values.\n}\n\nfunction writeFlowMapping(state, level, object) {\n var _result = '',\n _tag = state.tag,\n objectKeyList = Object.keys(object),\n index,\n length,\n objectKey,\n objectValue,\n pairBuffer;\n\n for (index = 0, length = objectKeyList.length; index < length; index += 1) {\n\n pairBuffer = '';\n if (_result !== '') pairBuffer += ', ';\n\n if (state.condenseFlow) pairBuffer += '\"';\n\n objectKey = objectKeyList[index];\n objectValue = object[objectKey];\n\n if (state.replacer) {\n objectValue = state.replacer.call(object, objectKey, objectValue);\n }\n\n if (!writeNode(state, level, objectKey, false, false)) {\n continue; // Skip this pair because of invalid key;\n }\n\n if (state.dump.length > 1024) pairBuffer += '? ';\n\n pairBuffer += state.dump + (state.condenseFlow ? '\"' : '') + ':' + (state.condenseFlow ? '' : ' ');\n\n if (!writeNode(state, level, objectValue, false, false)) {\n continue; // Skip this pair because of invalid value.\n }\n\n pairBuffer += state.dump;\n\n // Both key and value are valid.\n _result += pairBuffer;\n }\n\n state.tag = _tag;\n state.dump = '{' + _result + '}';\n}\n\nfunction writeBlockMapping(state, level, object, compact) {\n var _result = '',\n _tag = state.tag,\n objectKeyList = Object.keys(object),\n index,\n length,\n objectKey,\n objectValue,\n explicitPair,\n pairBuffer;\n\n // Allow sorting keys so that the output file is deterministic\n if (state.sortKeys === true) {\n // Default sorting\n objectKeyList.sort();\n } else if (typeof state.sortKeys === 'function') {\n // Custom sort function\n objectKeyList.sort(state.sortKeys);\n } else if (state.sortKeys) {\n // Something is wrong\n throw new exception('sortKeys must be a boolean or a function');\n }\n\n for (index = 0, length = objectKeyList.length; index < length; index += 1) {\n pairBuffer = '';\n\n if (!compact || _result !== '') {\n pairBuffer += generateNextLine(state, level);\n }\n\n objectKey = objectKeyList[index];\n objectValue = object[objectKey];\n\n if (state.replacer) {\n objectValue = state.replacer.call(object, objectKey, objectValue);\n }\n\n if (!writeNode(state, level + 1, objectKey, true, true, true)) {\n continue; // Skip this pair because of invalid key.\n }\n\n explicitPair = (state.tag !== null && state.tag !== '?') ||\n (state.dump && state.dump.length > 1024);\n\n if (explicitPair) {\n if (state.dump && CHAR_LINE_FEED === state.dump.charCodeAt(0)) {\n pairBuffer += '?';\n } else {\n pairBuffer += '? ';\n }\n }\n\n pairBuffer += state.dump;\n\n if (explicitPair) {\n pairBuffer += generateNextLine(state, level);\n }\n\n if (!writeNode(state, level + 1, objectValue, true, explicitPair)) {\n continue; // Skip this pair because of invalid value.\n }\n\n if (state.dump && CHAR_LINE_FEED === state.dump.charCodeAt(0)) {\n pairBuffer += ':';\n } else {\n pairBuffer += ': ';\n }\n\n pairBuffer += state.dump;\n\n // Both key and value are valid.\n _result += pairBuffer;\n }\n\n state.tag = _tag;\n state.dump = _result || '{}'; // Empty mapping if no valid pairs.\n}\n\nfunction detectType(state, object, explicit) {\n var _result, typeList, index, length, type, style;\n\n typeList = explicit ? state.explicitTypes : state.implicitTypes;\n\n for (index = 0, length = typeList.length; index < length; index += 1) {\n type = typeList[index];\n\n if ((type.instanceOf || type.predicate) &&\n (!type.instanceOf || ((typeof object === 'object') && (object instanceof type.instanceOf))) &&\n (!type.predicate || type.predicate(object))) {\n\n if (explicit) {\n if (type.multi && type.representName) {\n state.tag = type.representName(object);\n } else {\n state.tag = type.tag;\n }\n } else {\n state.tag = '?';\n }\n\n if (type.represent) {\n style = state.styleMap[type.tag] || type.defaultStyle;\n\n if (_toString.call(type.represent) === '[object Function]') {\n _result = type.represent(object, style);\n } else if (_hasOwnProperty.call(type.represent, style)) {\n _result = type.represent[style](object, style);\n } else {\n throw new exception('!<' + type.tag + '> tag resolver accepts not \"' + style + '\" style');\n }\n\n state.dump = _result;\n }\n\n return true;\n }\n }\n\n return false;\n}\n\n// Serializes `object` and writes it to global `result`.\n// Returns true on success, or false on invalid object.\n//\nfunction writeNode(state, level, object, block, compact, iskey, isblockseq) {\n state.tag = null;\n state.dump = object;\n\n if (!detectType(state, object, false)) {\n detectType(state, object, true);\n }\n\n var type = _toString.call(state.dump);\n var inblock = block;\n var tagStr;\n\n if (block) {\n block = (state.flowLevel < 0 || state.flowLevel > level);\n }\n\n var objectOrArray = type === '[object Object]' || type === '[object Array]',\n duplicateIndex,\n duplicate;\n\n if (objectOrArray) {\n duplicateIndex = state.duplicates.indexOf(object);\n duplicate = duplicateIndex !== -1;\n }\n\n if ((state.tag !== null && state.tag !== '?') || duplicate || (state.indent !== 2 && level > 0)) {\n compact = false;\n }\n\n if (duplicate && state.usedDuplicates[duplicateIndex]) {\n state.dump = '*ref_' + duplicateIndex;\n } else {\n if (objectOrArray && duplicate && !state.usedDuplicates[duplicateIndex]) {\n state.usedDuplicates[duplicateIndex] = true;\n }\n if (type === '[object Object]') {\n if (block && (Object.keys(state.dump).length !== 0)) {\n writeBlockMapping(state, level, state.dump, compact);\n if (duplicate) {\n state.dump = '&ref_' + duplicateIndex + state.dump;\n }\n } else {\n writeFlowMapping(state, level, state.dump);\n if (duplicate) {\n state.dump = '&ref_' + duplicateIndex + ' ' + state.dump;\n }\n }\n } else if (type === '[object Array]') {\n if (block && (state.dump.length !== 0)) {\n if (state.noArrayIndent && !isblockseq && level > 0) {\n writeBlockSequence(state, level - 1, state.dump, compact);\n } else {\n writeBlockSequence(state, level, state.dump, compact);\n }\n if (duplicate) {\n state.dump = '&ref_' + duplicateIndex + state.dump;\n }\n } else {\n writeFlowSequence(state, level, state.dump);\n if (duplicate) {\n state.dump = '&ref_' + duplicateIndex + ' ' + state.dump;\n }\n }\n } else if (type === '[object String]') {\n if (state.tag !== '?') {\n writeScalar(state, state.dump, level, iskey, inblock);\n }\n } else if (type === '[object Undefined]') {\n return false;\n } else {\n if (state.skipInvalid) return false;\n throw new exception('unacceptable kind of an object to dump ' + type);\n }\n\n if (state.tag !== null && state.tag !== '?') {\n // Need to encode all characters except those allowed by the spec:\n //\n // [35] ns-dec-digit ::= [#x30-#x39] /* 0-9 */\n // [36] ns-hex-digit ::= ns-dec-digit\n // | [#x41-#x46] /* A-F */ | [#x61-#x66] /* a-f */\n // [37] ns-ascii-letter ::= [#x41-#x5A] /* A-Z */ | [#x61-#x7A] /* a-z */\n // [38] ns-word-char ::= ns-dec-digit | ns-ascii-letter | \u201C-\u201D\n // [39] ns-uri-char ::= \u201C%\u201D ns-hex-digit ns-hex-digit | ns-word-char | \u201C#\u201D\n // | \u201C;\u201D | \u201C/\u201D | \u201C?\u201D | \u201C:\u201D | \u201C@\u201D | \u201C&\u201D | \u201C=\u201D | \u201C+\u201D | \u201C$\u201D | \u201C,\u201D\n // | \u201C_\u201D | \u201C.\u201D | \u201C!\u201D | \u201C~\u201D | \u201C*\u201D | \u201C'\u201D | \u201C(\u201D | \u201C)\u201D | \u201C[\u201D | \u201C]\u201D\n //\n // Also need to encode '!' because it has special meaning (end of tag prefix).\n //\n tagStr = encodeURI(\n state.tag[0] === '!' ? state.tag.slice(1) : state.tag\n ).replace(/!/g, '%21');\n\n if (state.tag[0] === '!') {\n tagStr = '!' + tagStr;\n } else if (tagStr.slice(0, 18) === 'tag:yaml.org,2002:') {\n tagStr = '!!' + tagStr.slice(18);\n } else {\n tagStr = '!<' + tagStr + '>';\n }\n\n state.dump = tagStr + ' ' + state.dump;\n }\n }\n\n return true;\n}\n\nfunction getDuplicateReferences(object, state) {\n var objects = [],\n duplicatesIndexes = [],\n index,\n length;\n\n inspectNode(object, objects, duplicatesIndexes);\n\n for (index = 0, length = duplicatesIndexes.length; index < length; index += 1) {\n state.duplicates.push(objects[duplicatesIndexes[index]]);\n }\n state.usedDuplicates = new Array(length);\n}\n\nfunction inspectNode(object, objects, duplicatesIndexes) {\n var objectKeyList,\n index,\n length;\n\n if (object !== null && typeof object === 'object') {\n index = objects.indexOf(object);\n if (index !== -1) {\n if (duplicatesIndexes.indexOf(index) === -1) {\n duplicatesIndexes.push(index);\n }\n } else {\n objects.push(object);\n\n if (Array.isArray(object)) {\n for (index = 0, length = object.length; index < length; index += 1) {\n inspectNode(object[index], objects, duplicatesIndexes);\n }\n } else {\n objectKeyList = Object.keys(object);\n\n for (index = 0, length = objectKeyList.length; index < length; index += 1) {\n inspectNode(object[objectKeyList[index]], objects, duplicatesIndexes);\n }\n }\n }\n }\n}\n\nfunction dump$1(input, options) {\n options = options || {};\n\n var state = new State(options);\n\n if (!state.noRefs) getDuplicateReferences(input, state);\n\n var value = input;\n\n if (state.replacer) {\n value = state.replacer.call({ '': value }, '', value);\n }\n\n if (writeNode(state, 0, value, true, true)) return state.dump + '\\n';\n\n return '';\n}\n\nvar dump_1 = dump$1;\n\nvar dumper = {\n\tdump: dump_1\n};\n\nfunction renamed(from, to) {\n return function () {\n throw new Error('Function yaml.' + from + ' is removed in js-yaml 4. ' +\n 'Use yaml.' + to + ' instead, which is now safe by default.');\n };\n}\n\n\nvar Type = type;\nvar Schema = schema;\nvar FAILSAFE_SCHEMA = failsafe;\nvar JSON_SCHEMA = json;\nvar CORE_SCHEMA = core;\nvar DEFAULT_SCHEMA = _default;\nvar load = loader.load;\nvar loadAll = loader.loadAll;\nvar dump = dumper.dump;\nvar YAMLException = exception;\n\n// Re-export all types in case user wants to create custom schema\nvar types = {\n binary: binary,\n float: float,\n map: map,\n null: _null,\n pairs: pairs,\n set: set,\n timestamp: timestamp,\n bool: bool,\n int: int,\n merge: merge,\n omap: omap,\n seq: seq,\n str: str\n};\n\n// Removed functions from JS-YAML 3.0.x\nvar safeLoad = renamed('safeLoad', 'load');\nvar safeLoadAll = renamed('safeLoadAll', 'loadAll');\nvar safeDump = renamed('safeDump', 'dump');\n\nvar jsYaml = {\n\tType: Type,\n\tSchema: Schema,\n\tFAILSAFE_SCHEMA: FAILSAFE_SCHEMA,\n\tJSON_SCHEMA: JSON_SCHEMA,\n\tCORE_SCHEMA: CORE_SCHEMA,\n\tDEFAULT_SCHEMA: DEFAULT_SCHEMA,\n\tload: load,\n\tloadAll: loadAll,\n\tdump: dump,\n\tYAMLException: YAMLException,\n\ttypes: types,\n\tsafeLoad: safeLoad,\n\tsafeLoadAll: safeLoadAll,\n\tsafeDump: safeDump\n};\n\nexport { CORE_SCHEMA, DEFAULT_SCHEMA, FAILSAFE_SCHEMA, JSON_SCHEMA, Schema, Type, YAMLException, jsYaml as default, dump, load, loadAll, safeDump, safeLoad, safeLoadAll, types };\n", "/**\n * CodeQL metadata resolver utilities\n * Handles resolution of query metadata using the CodeQL CLI\n */\n\nimport { executeCodeQLCommand } from './cli-executor';\nimport { logger } from '../utils/logger';\n\n/**\n * Query metadata structure returned by codeql resolve metadata\n */\nexport interface QueryMetadata {\n [key: string]: string | string[];\n}\n\n/**\n * Resolve metadata for a CodeQL query file\n * @param queryPath - Absolute or relative path to the .ql query file\n * @returns Parsed metadata object or null if resolution fails\n */\nexport async function resolveQueryMetadata(queryPath: string): Promise {\n try {\n logger.info(`Resolving metadata for query: ${queryPath}`);\n\n const result = await executeCodeQLCommand(\n 'resolve metadata',\n { format: 'json' },\n [queryPath]\n );\n\n if (!result.success) {\n logger.error(`Failed to resolve metadata for ${queryPath}:`, result.stderr || result.error);\n return null;\n }\n\n // Parse the JSON output\n try {\n const metadata = JSON.parse(result.stdout);\n return metadata;\n } catch (parseError) {\n logger.error(`Failed to parse metadata JSON for ${queryPath}:`, parseError);\n return null;\n }\n } catch (error) {\n logger.error(`Error resolving metadata for ${queryPath}:`, error);\n return null;\n }\n}\n", "/**\n * CodeQL generate log-summary tool\n */\n\nimport { z } from 'zod';\nimport { CLIToolDefinition, createCodeQLSchemas, defaultCLIResultProcessor } from '../../lib/cli-tool-registry';\n\nexport const codeqlGenerateLogSummaryTool: CLIToolDefinition = {\n name: 'codeql_generate_log-summary',\n description: 'Create a summary of a structured JSON evaluator event log file',\n command: 'codeql',\n subcommand: 'generate log-summary',\n inputSchema: {\n inputLog: z.string().describe('Path to the evaluator log file to summarize'),\n outputFile: z.string().optional().describe('Path to write the summary (optional, defaults to stdout)'),\n format: z.enum(['text', 'predicates', 'overall']).optional()\n .describe('Output format: text (human-readable), predicates (JSON), or overall (stats)'),\n 'minify-output': z.boolean().optional().describe('Minify JSON output'),\n utc: z.boolean().optional().describe('Force UTC timestamps'),\n 'deduplicate-stage-summaries': z.boolean().optional().describe('Deduplicate stage summaries'),\n verbose: createCodeQLSchemas.verbose(),\n additionalArgs: createCodeQLSchemas.additionalArgs()\n },\n examples: [\n 'codeql generate log-summary --format=text -- evaluator-log.json.txt summary.txt',\n 'codeql generate log-summary --format=predicates --minify-output -- evaluator-log.json.txt',\n 'codeql generate log-summary --format=overall -- evaluator-log.json.txt overall-stats.json'\n ],\n resultProcessor: defaultCLIResultProcessor\n};", "/**\n * CodeQL generate query-help tool\n */\n\nimport { z } from 'zod';\nimport { CLIToolDefinition, createCodeQLSchemas, defaultCLIResultProcessor } from '../../lib/cli-tool-registry';\n\nexport const codeqlGenerateQueryHelpTool: CLIToolDefinition = {\n name: 'codeql_generate_query-help',\n description: 'Generate query help documentation from QLDoc comments',\n command: 'codeql',\n subcommand: 'generate query-help',\n inputSchema: {\n query: z.string().describe('Path to the query file to generate help for'),\n outputFile: z.string().optional().describe('Path to write the help documentation'),\n format: z.enum(['markdown', 'text', 'html']).optional()\n .describe('Output format for the help documentation'),\n verbose: createCodeQLSchemas.verbose(),\n additionalArgs: createCodeQLSchemas.additionalArgs()\n },\n examples: [\n 'codeql generate query-help -- MyQuery.ql',\n 'codeql generate query-help --format=markdown -- MyQuery.ql help.md',\n 'codeql generate query-help --format=html -- MyQuery.ql help.html'\n ],\n resultProcessor: defaultCLIResultProcessor\n};", "/**\n * list_codeql_databases tool\n *\n * Discovers CodeQL databases in configured base directories.\n * Scans each directory in `CODEQL_DATABASES_BASE_DIRS` for subdirectories\n * containing `codeql-database.yml`, extracts metadata (language, CLI version,\n * creation time), and returns the list.\n */\n\nimport { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport { existsSync, readdirSync, readFileSync, statSync } from 'fs';\nimport { join } from 'path';\nimport { z } from 'zod';\nimport { getDatabaseBaseDirs } from '../../lib/discovery-config';\nimport { logger } from '../../utils/logger';\n\nexport interface DatabaseInfo {\n cliVersion?: string;\n creationTime?: string;\n language?: string;\n name: string;\n path: string;\n}\n\n/**\n * Parse `codeql-database.yml` to extract metadata.\n * Uses simple line-based parsing to avoid a YAML dependency.\n */\nfunction parseDatabaseYml(ymlPath: string): Partial {\n try {\n const content = readFileSync(ymlPath, 'utf-8');\n const info: Partial = {};\n\n for (const line of content.split('\\n')) {\n const trimmed = line.trim();\n const colonIdx = trimmed.indexOf(':');\n if (colonIdx === -1) continue;\n\n const key = trimmed.substring(0, colonIdx).trim();\n const value = trimmed.substring(colonIdx + 1).trim().replace(/^[\"']|[\"']$/g, '');\n\n switch (key) {\n case 'primaryLanguage':\n info.language = value;\n break;\n case 'cliVersion':\n info.cliVersion = value;\n break;\n case 'creationTime':\n info.creationTime = value;\n break;\n }\n }\n\n return info;\n } catch {\n return {};\n }\n}\n\n/**\n * Discover CodeQL databases in the given base directories.\n *\n * @param baseDirs - Directories to scan for database subdirectories\n * @param language - Optional language filter\n * @returns List of discovered databases with metadata\n */\nexport async function discoverDatabases(\n baseDirs: string[],\n language?: string,\n): Promise {\n const databases: DatabaseInfo[] = [];\n\n for (const baseDir of baseDirs) {\n if (!existsSync(baseDir)) {\n continue;\n }\n\n let entries: string[];\n try {\n entries = readdirSync(baseDir);\n } catch {\n continue;\n }\n\n for (const entry of entries) {\n const entryPath = join(baseDir, entry);\n\n // Skip non-directories\n try {\n if (!statSync(entryPath).isDirectory()) {\n continue;\n }\n } catch {\n continue;\n }\n\n // Check for codeql-database.yml\n const ymlPath = join(entryPath, 'codeql-database.yml');\n if (!existsSync(ymlPath)) {\n continue;\n }\n\n const metadata = parseDatabaseYml(ymlPath);\n\n // Apply language filter\n if (language && metadata.language !== language) {\n continue;\n }\n\n databases.push({\n cliVersion: metadata.cliVersion,\n creationTime: metadata.creationTime,\n language: metadata.language,\n name: entry,\n path: entryPath,\n });\n }\n }\n\n return databases;\n}\n\n/**\n * Register the list_codeql_databases tool with the MCP server.\n */\nexport function registerListDatabasesTool(server: McpServer): void {\n server.tool(\n 'list_codeql_databases',\n 'List CodeQL databases discovered in configured base directories (set via CODEQL_DATABASES_BASE_DIRS env var). Returns path, language, CLI version, and creation time for each database. Use the returned database paths with codeql_query_run or codeql_database_analyze to run queries against them.',\n {\n language: z\n .string()\n .optional()\n .describe('Filter databases by language (e.g., \"javascript\", \"python\")'),\n },\n async ({ language }) => {\n try {\n const baseDirs = getDatabaseBaseDirs();\n\n if (baseDirs.length === 0) {\n return {\n content: [\n {\n type: 'text' as const,\n text: 'No database base directories configured. Set the CODEQL_DATABASES_BASE_DIRS environment variable to a colon-separated list of directories to search.',\n },\n ],\n };\n }\n\n const databases = await discoverDatabases(baseDirs, language);\n\n if (databases.length === 0) {\n const filterMsg = language ? ` for language \"${language}\"` : '';\n return {\n content: [\n {\n type: 'text' as const,\n text: `No CodeQL databases found${filterMsg} in: ${baseDirs.join(', ')}`,\n },\n ],\n };\n }\n\n const lines = [\n `Found ${databases.length} CodeQL database(s):`,\n '',\n ...databases.map((db) => {\n const parts = [` ${db.name}`];\n parts.push(` Path: ${db.path}`);\n if (db.language) parts.push(` Language: ${db.language}`);\n if (db.cliVersion) parts.push(` CLI Version: ${db.cliVersion}`);\n if (db.creationTime) parts.push(` Created: ${db.creationTime}`);\n return parts.join('\\n');\n }),\n ];\n\n return {\n content: [{ type: 'text' as const, text: lines.join('\\n') }],\n };\n } catch (error) {\n logger.error('Error listing databases:', error);\n return {\n content: [\n {\n type: 'text' as const,\n text: `Error: ${error instanceof Error ? error.message : 'Unknown error'}`,\n },\n ],\n isError: true,\n };\n }\n },\n );\n}\n", "/**\n * Discovery configuration for locating CodeQL databases, query run results,\n * and MRVA (Multi-Repository Variant Analysis) run results.\n *\n * Reads colon-separated directory lists from environment variables:\n * - `CODEQL_DATABASES_BASE_DIRS` \u2014 directories to search for CodeQL databases\n * - `CODEQL_MRVA_RUN_RESULTS_DIRS` \u2014 directories containing MRVA run result subdirectories\n * - `CODEQL_QUERY_RUN_RESULTS_DIRS` \u2014 directories containing per-run query result subdirectories\n *\n * The VS Code extension sets these automatically from vscode-codeql storage paths.\n * CLI users can set them manually.\n */\n\n/**\n * Parse a colon-separated list of directories from an environment variable.\n */\nfunction parsePathList(envValue: string | undefined): string[] {\n if (!envValue) {\n return [];\n }\n return envValue\n .split(':')\n .map((p) => p.trim())\n .filter((p) => p.length > 0);\n}\n\n/**\n * Get the list of base directories to search for CodeQL databases.\n *\n * Each directory is expected to contain one or more CodeQL database directories\n * (each with a `codeql-database.yml` file).\n *\n * Set via `CODEQL_DATABASES_BASE_DIRS` (colon-separated).\n */\nexport function getDatabaseBaseDirs(): string[] {\n return parsePathList(process.env.CODEQL_DATABASES_BASE_DIRS);\n}\n\n/**\n * Get the list of directories containing MRVA run result subdirectories.\n *\n * Each directory is expected to contain numeric subdirectories (run IDs),\n * each holding `timestamp`, `repo_states.json`, and per-repository\n * subdirectories with `repo_task.json`, `results/results.sarif`, and\n * `results/results.bqrs`.\n *\n * Set via `CODEQL_MRVA_RUN_RESULTS_DIRS` (colon-separated).\n */\nexport function getMrvaRunResultsDirs(): string[] {\n return parsePathList(process.env.CODEQL_MRVA_RUN_RESULTS_DIRS);\n}\n\n/**\n * Get the list of directories containing per-run query result subdirectories.\n *\n * Each directory is expected to contain subdirectories named like\n * `.ql-/`, each holding artifacts such as\n * `evaluator-log.jsonl`, `results.bqrs`, and `results-interpreted.sarif`.\n *\n * Set via `CODEQL_QUERY_RUN_RESULTS_DIRS` (colon-separated).\n */\nexport function getQueryRunResultsDirs(): string[] {\n return parsePathList(process.env.CODEQL_QUERY_RUN_RESULTS_DIRS);\n}\n", "/**\n * list_mrva_run_results tool\n *\n * Discovers MRVA (Multi-Repository Variant Analysis) run result directories\n * in configured search paths.\n * Scans each directory in `CODEQL_MRVA_RUN_RESULTS_DIRS` for numeric\n * subdirectories representing variant analysis runs created by vscode-codeql.\n * Reports run ID, timestamp, repositories scanned, analysis status, and\n * available artifacts for each run.\n */\n\nimport { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport { existsSync, readdirSync, readFileSync, statSync } from 'fs';\nimport { join } from 'path';\nimport { z } from 'zod';\nimport { getMrvaRunResultsDirs } from '../../lib/discovery-config';\nimport { logger } from '../../utils/logger';\n\nexport interface MrvaRepoResult {\n analysisStatus?: string;\n fullName: string;\n hasBqrs: boolean;\n hasSarif: boolean;\n resultCount?: number;\n}\n\nexport interface MrvaRunResult {\n path: string;\n repositories: MrvaRepoResult[];\n runId: string;\n timestamp?: string;\n}\n\n/**\n * Pattern matching numeric MRVA run directory names.\n */\nconst NUMERIC_DIR_PATTERN = /^\\d+$/;\n\n/**\n * Directory names to skip when walking repository subdirectories.\n */\nconst SKIP_DIRS = new Set(['.DS_Store', 'exported-results']);\n\n/**\n * Discover MRVA run result directories in the given search paths.\n *\n * @param resultsDirs - Directories to scan for MRVA run subdirectories\n * @param runId - Optional run ID filter (e.g., \"20442\")\n * @returns List of discovered MRVA run results with repository inventory\n */\nexport async function discoverMrvaRunResults(\n resultsDirs: string[],\n runId?: string,\n): Promise {\n const results: MrvaRunResult[] = [];\n\n for (const dir of resultsDirs) {\n if (!existsSync(dir)) {\n continue;\n }\n\n let entries: string[];\n try {\n entries = readdirSync(dir);\n } catch {\n continue;\n }\n\n for (const entry of entries) {\n const entryPath = join(dir, entry);\n\n // Skip non-directories\n try {\n if (!statSync(entryPath).isDirectory()) {\n continue;\n }\n } catch {\n continue;\n }\n\n // Match numeric directory names\n if (!NUMERIC_DIR_PATTERN.test(entry)) {\n continue;\n }\n\n // Apply run ID filter\n if (runId && entry !== runId) {\n continue;\n }\n\n // Read timestamp if available\n let timestamp: string | undefined;\n const timestampPath = join(entryPath, 'timestamp');\n if (existsSync(timestampPath)) {\n try {\n timestamp = readFileSync(timestampPath, 'utf-8').trim();\n } catch {\n // Ignore read errors\n }\n }\n\n // Discover repository subdirectories\n const repositories = discoverRepoResults(entryPath);\n\n results.push({\n path: entryPath,\n repositories,\n runId: entry,\n timestamp,\n });\n }\n }\n\n return results;\n}\n\n/**\n * Walk a single MRVA run directory to discover per-repository results.\n *\n * The directory structure is `//` containing `repo_task.json`\n * and optionally `results/results.sarif` and `results/results.bqrs`.\n */\nfunction discoverRepoResults(runPath: string): MrvaRepoResult[] {\n const repos: MrvaRepoResult[] = [];\n\n let ownerEntries: string[];\n try {\n ownerEntries = readdirSync(runPath);\n } catch {\n return repos;\n }\n\n for (const ownerEntry of ownerEntries) {\n if (SKIP_DIRS.has(ownerEntry)) {\n continue;\n }\n\n // Skip non-directory entries (timestamp, repo_states.json, etc.)\n const ownerPath = join(runPath, ownerEntry);\n try {\n if (!statSync(ownerPath).isDirectory()) {\n continue;\n }\n } catch {\n continue;\n }\n\n let repoEntries: string[];\n try {\n repoEntries = readdirSync(ownerPath);\n } catch {\n continue;\n }\n\n for (const repoEntry of repoEntries) {\n const repoPath = join(ownerPath, repoEntry);\n try {\n if (!statSync(repoPath).isDirectory()) {\n continue;\n }\n } catch {\n continue;\n }\n\n const fullName = `${ownerEntry}/${repoEntry}`;\n\n // Parse repo_task.json if present\n let analysisStatus: string | undefined;\n let resultCount: number | undefined;\n const repoTaskPath = join(repoPath, 'repo_task.json');\n if (existsSync(repoTaskPath)) {\n try {\n const raw = readFileSync(repoTaskPath, 'utf-8');\n const task = JSON.parse(raw);\n if (typeof task.analysisStatus === 'string') {\n analysisStatus = task.analysisStatus;\n }\n if (typeof task.resultCount === 'number') {\n resultCount = task.resultCount;\n }\n } catch {\n // Ignore parse errors\n }\n }\n\n // Check for SARIF and BQRS artifacts\n const hasSarif = existsSync(join(repoPath, 'results', 'results.sarif'));\n const hasBqrs = existsSync(join(repoPath, 'results', 'results.bqrs'));\n\n repos.push({\n analysisStatus,\n fullName,\n hasBqrs,\n hasSarif,\n resultCount,\n });\n }\n }\n\n return repos;\n}\n\n/**\n * Register the list_mrva_run_results tool with the MCP server.\n */\nexport function registerListMrvaRunResultsTool(server: McpServer): void {\n server.tool(\n 'list_mrva_run_results',\n 'List discovered MRVA (Multi-Repository Variant Analysis) run results (set via CODEQL_MRVA_RUN_RESULTS_DIRS env var). Returns run ID, timestamp, repositories scanned, analysis status, and available artifacts for each run.',\n {\n runId: z\n .string()\n .optional()\n .describe('Filter results by run ID (e.g., \"20442\")'),\n },\n async ({ runId }) => {\n try {\n const resultsDirs = getMrvaRunResultsDirs();\n\n if (resultsDirs.length === 0) {\n return {\n content: [\n {\n type: 'text' as const,\n text: 'No MRVA run results directories configured. Set the CODEQL_MRVA_RUN_RESULTS_DIRS environment variable to a colon-separated list of directories to search.',\n },\n ],\n };\n }\n\n const runs = await discoverMrvaRunResults(resultsDirs, runId);\n\n if (runs.length === 0) {\n const filterMsg = runId ? ` for run ID \"${runId}\"` : '';\n return {\n content: [\n {\n type: 'text' as const,\n text: `No MRVA run results found${filterMsg} in: ${resultsDirs.join(', ')}`,\n },\n ],\n };\n }\n\n const lines = [\n `Found ${runs.length} MRVA run result(s):`,\n '',\n ...runs.map((run) => {\n const parts = [` Run ${run.runId}`];\n parts.push(` Path: ${run.path}`);\n if (run.timestamp) parts.push(` Timestamp: ${run.timestamp}`);\n parts.push(` Repositories: ${run.repositories.length}`);\n for (const repo of run.repositories) {\n const artifacts: string[] = [];\n if (repo.hasSarif) artifacts.push('sarif');\n if (repo.hasBqrs) artifacts.push('bqrs');\n const status = repo.analysisStatus ?? 'unknown';\n const count = repo.resultCount !== undefined ? `, ${repo.resultCount} result(s)` : '';\n parts.push(` ${repo.fullName} [${status}${count}] artifacts: ${artifacts.length > 0 ? artifacts.join(', ') : 'none'}`);\n }\n return parts.join('\\n');\n }),\n ];\n\n return {\n content: [{ type: 'text' as const, text: lines.join('\\n') }],\n };\n } catch (error) {\n logger.error('Error listing MRVA run results:', error);\n return {\n content: [\n {\n type: 'text' as const,\n text: `Error: ${error instanceof Error ? error.message : 'Unknown error'}`,\n },\n ],\n isError: true,\n };\n }\n },\n );\n}\n", "/**\n * list_query_run_results tool\n *\n * Discovers per-query-run result directories in configured search paths.\n * Scans each directory in `CODEQL_QUERY_RUN_RESULTS_DIRS` for subdirectories\n * matching the `.ql-` naming convention used by vscode-codeql.\n * Reports which artifacts (evaluator logs, BQRS, SARIF) are present in each run.\n *\n * Supports filtering by:\n * - `queryName` \u2014 exact match on the query file name (e.g., \"UI5Xss.ql\")\n * - `language` \u2014 filter by CodeQL language extracted from query.log db-scheme path\n * - `queryPath` \u2014 substring or exact match against the full query file path\n */\n\nimport { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport { existsSync, readdirSync, readFileSync, statSync } from 'fs';\nimport { join } from 'path';\nimport { z } from 'zod';\nimport { getQueryRunResultsDirs } from '../../lib/discovery-config';\nimport { logger } from '../../utils/logger';\n\nexport interface QueryRunResult {\n databasePath?: string;\n hasBqrs: boolean;\n hasEvaluatorLog: boolean;\n hasQueryLog: boolean;\n hasSarif: boolean;\n hasSummaryLog: boolean;\n language?: string;\n path: string;\n queryName: string;\n queryPath?: string;\n runId: string;\n timestamp?: string;\n}\n\n/**\n * Metadata extracted from a vscode-codeql query.log file.\n */\nexport interface QueryLogMetadata {\n databasePath?: string;\n language?: string;\n queryPath?: string;\n}\n\n/**\n * Filters for narrowing query run results.\n */\nexport interface QueryRunResultsFilter {\n language?: string;\n queryName?: string;\n queryPath?: string;\n}\n\n/**\n * Pattern matching vscode-codeql query run directory names: `.ql-`\n */\nconst QUERY_RUN_DIR_PATTERN = /^(.+\\.ql)-(.+)$/;\n\n/**\n * Pattern matching the `runQuery called with ` line in query.log.\n * Example: `[2026-02-15 12:52:37] [SPAMMY] execute query-server2> runQuery called with /path/to/Query.ql`\n */\nconst RUN_QUERY_PATTERN = /runQuery called with\\s+(\\S+)/;\n\n/**\n * Pattern matching the `--dbscheme=` argument in query.log when it\n * includes the database root directory with the `db-/` segment.\n * Example: `--dbscheme=/databases/my-db/db-javascript/semmlecode.javascript.dbscheme`\n */\nconst DBSCHEME_DB_PATH_PATTERN = /--dbscheme=(.+?)\\/db-(\\w+)\\//;\n\n/**\n * Fallback pattern matching language from the semmlecode dbscheme filename.\n * Matches both `semmlecode..dbscheme` and `semmlecode.dbscheme`\n * (the latter is used by Java). Also matches dbscheme paths from QL packs\n * like `codeql/-all/`.\n *\n * Examples:\n * - `semmlecode.javascript.dbscheme` \u2192 javascript\n * - `semmlecode.python.dbscheme` \u2192 python\n * - `codeql/javascript-all/2.6.20/semmlecode.javascript.dbscheme` \u2192 javascript\n * - `semmlecode.dbscheme` (Java) \u2192 java (from `db-java/` or `codeql/java-all/`)\n */\nconst DBSCHEME_LANGUAGE_PATTERN = /semmlecode\\.(\\w+)\\.dbscheme/;\n\n/**\n * Fallback pattern to extract language from QL pack path in dbscheme references.\n * Example: `codeql/javascript-all/2.6.20/` \u2192 javascript\n */\nconst QLPACK_LANGUAGE_PATTERN = /codeql\\/(\\w+)-all\\//;\n\n/**\n * Parse a vscode-codeql query.log file to extract metadata about the query run.\n *\n * Extracts:\n * - `queryPath` \u2014 from the `runQuery called with ` line\n * - `databasePath` \u2014 the database root from the `--dbscheme=` argument (when available)\n * - `language` \u2014 from `db-/` segment, or `semmlecode..dbscheme`,\n * or `codeql/-all/` QL pack path\n *\n * @param logContent - Raw content of the query.log file\n * @returns Extracted metadata (fields are undefined if not found)\n */\nexport function parseQueryLogMetadata(logContent: string): QueryLogMetadata {\n const metadata: QueryLogMetadata = {};\n\n // Extract query path from runQuery line\n const runQueryMatch = RUN_QUERY_PATTERN.exec(logContent);\n if (runQueryMatch) {\n metadata.queryPath = runQueryMatch[1];\n }\n\n // Try to extract database path and language from --dbscheme=/db-/\n const dbPathMatch = DBSCHEME_DB_PATH_PATTERN.exec(logContent);\n if (dbPathMatch) {\n metadata.databasePath = dbPathMatch[1];\n metadata.language = dbPathMatch[2];\n }\n\n // If language wasn't found from db path, try semmlecode..dbscheme\n if (!metadata.language) {\n const langMatch = DBSCHEME_LANGUAGE_PATTERN.exec(logContent);\n if (langMatch) {\n metadata.language = langMatch[1];\n }\n }\n\n // Last resort: extract from codeql/-all/ QL pack path\n if (!metadata.language) {\n const packMatch = QLPACK_LANGUAGE_PATTERN.exec(logContent);\n if (packMatch) {\n metadata.language = packMatch[1];\n }\n }\n\n return metadata;\n}\n\n/**\n * Discover query run result directories in the given search paths.\n *\n * @param resultsDirs - Directories to scan for per-run subdirectories\n * @param filter - Optional filters: queryName, language, queryPath\n * @returns List of discovered query run results with artifact inventory\n */\nexport async function discoverQueryRunResults(\n resultsDirs: string[],\n filter?: QueryRunResultsFilter | string,\n): Promise {\n // Backward-compatible: if filter is a string, treat as queryName\n const normalizedFilter: QueryRunResultsFilter | undefined =\n typeof filter === 'string' ? { queryName: filter } : filter;\n\n const results: QueryRunResult[] = [];\n\n for (const dir of resultsDirs) {\n if (!existsSync(dir)) {\n continue;\n }\n\n let entries: string[];\n try {\n entries = readdirSync(dir);\n } catch {\n continue;\n }\n\n for (const entry of entries) {\n const entryPath = join(dir, entry);\n\n // Skip non-directories\n try {\n if (!statSync(entryPath).isDirectory()) {\n continue;\n }\n } catch {\n continue;\n }\n\n // Match the naming pattern\n const match = QUERY_RUN_DIR_PATTERN.exec(entry);\n if (!match) {\n continue;\n }\n\n const [, name, runId] = match;\n\n // Apply query name filter (cheap, no I/O needed)\n if (normalizedFilter?.queryName && name !== normalizedFilter.queryName) {\n continue;\n }\n\n // Check which artifacts are present\n const hasEvaluatorLog = existsSync(join(entryPath, 'evaluator-log.jsonl'));\n const hasBqrs = existsSync(join(entryPath, 'results.bqrs'));\n const hasSarif = existsSync(join(entryPath, 'results-interpreted.sarif'));\n const hasQueryLog = existsSync(join(entryPath, 'query.log'));\n const hasSummaryLog = existsSync(join(entryPath, 'evaluator-log.summary.jsonl'));\n\n // Read timestamp if available\n let timestamp: string | undefined;\n const timestampPath = join(entryPath, 'timestamp');\n if (existsSync(timestampPath)) {\n try {\n timestamp = readFileSync(timestampPath, 'utf-8').trim();\n } catch {\n // Ignore read errors\n }\n }\n\n // Parse query.log for metadata (queryPath, language, databasePath)\n let metadata: QueryLogMetadata = {};\n if (hasQueryLog) {\n try {\n const logContent = readFileSync(join(entryPath, 'query.log'), 'utf-8');\n metadata = parseQueryLogMetadata(logContent);\n } catch {\n // Ignore read errors\n }\n }\n\n // Apply language filter (requires metadata from query.log)\n if (normalizedFilter?.language && metadata.language !== normalizedFilter.language) {\n continue;\n }\n\n // Apply queryPath filter (substring or exact match)\n if (normalizedFilter?.queryPath) {\n if (!metadata.queryPath) {\n continue;\n }\n const filterPath = normalizedFilter.queryPath;\n const isExact = filterPath.startsWith('/');\n if (isExact) {\n if (metadata.queryPath !== filterPath) {\n continue;\n }\n } else {\n if (!metadata.queryPath.toLowerCase().includes(filterPath.toLowerCase())) {\n continue;\n }\n }\n }\n\n results.push({\n databasePath: metadata.databasePath,\n hasBqrs,\n hasEvaluatorLog,\n hasQueryLog,\n hasSarif,\n hasSummaryLog,\n language: metadata.language,\n path: entryPath,\n queryName: name,\n queryPath: metadata.queryPath,\n runId,\n timestamp,\n });\n }\n }\n\n return results;\n}\n\n/**\n * Register the list_query_run_results tool with the MCP server.\n */\nexport function registerListQueryRunResultsTool(server: McpServer): void {\n server.tool(\n 'list_query_run_results',\n 'List discovered query run result directories (set via CODEQL_QUERY_RUN_RESULTS_DIRS env var). Returns path, query name, timestamp, language, query file path, and available artifacts (evaluator-log, bqrs, sarif, query.log, summary) for each run. Filter by queryName, language, or queryPath to narrow results. Use the returned BQRS paths with codeql_bqrs_decode or codeql_bqrs_info to inspect query results.',\n {\n language: z\n .string()\n .optional()\n .describe(\n 'Filter by CodeQL language (e.g., \"javascript\", \"python\", \"java\"). Extracted from the database path in query.log. Runs without a query.log are excluded when this filter is set.',\n ),\n queryName: z\n .string()\n .optional()\n .describe('Filter results by query name (e.g., \"UI5Xss.ql\")'),\n queryPath: z\n .string()\n .optional()\n .describe(\n 'Filter by query file path. Absolute paths match exactly; relative paths/substrings match case-insensitively. Requires query.log to be present.',\n ),\n },\n async ({ language, queryName, queryPath }) => {\n try {\n const resultsDirs = getQueryRunResultsDirs();\n\n if (resultsDirs.length === 0) {\n return {\n content: [\n {\n type: 'text' as const,\n text: 'No query run results directories configured. Set the CODEQL_QUERY_RUN_RESULTS_DIRS environment variable to a colon-separated list of directories to search.',\n },\n ],\n };\n }\n\n const filter: QueryRunResultsFilter = {};\n if (queryName) filter.queryName = queryName;\n if (language) filter.language = language;\n if (queryPath) filter.queryPath = queryPath;\n\n const runs = await discoverQueryRunResults(\n resultsDirs,\n Object.keys(filter).length > 0 ? filter : undefined,\n );\n\n if (runs.length === 0) {\n const filterParts: string[] = [];\n if (queryName) filterParts.push(`query \"${queryName}\"`);\n if (language) filterParts.push(`language \"${language}\"`);\n if (queryPath) filterParts.push(`path \"${queryPath}\"`);\n const filterMsg = filterParts.length > 0 ? ` for ${filterParts.join(', ')}` : '';\n return {\n content: [\n {\n type: 'text' as const,\n text: `No query run results found${filterMsg} in: ${resultsDirs.join(', ')}`,\n },\n ],\n };\n }\n\n const lines = [\n `Found ${runs.length} query run result(s):`,\n '',\n ...runs.map((run) => {\n const artifacts: string[] = [];\n if (run.hasEvaluatorLog) artifacts.push('evaluator-log');\n if (run.hasSummaryLog) artifacts.push('summary-log');\n if (run.hasBqrs) artifacts.push('bqrs');\n if (run.hasSarif) artifacts.push('sarif');\n if (run.hasQueryLog) artifacts.push('query-log');\n const parts = [` ${run.queryName} (${run.runId})`];\n parts.push(` Path: ${run.path}`);\n if (run.timestamp) parts.push(` Timestamp: ${run.timestamp}`);\n if (run.language) parts.push(` Language: ${run.language}`);\n if (run.queryPath) parts.push(` Query: ${run.queryPath}`);\n if (run.databasePath) parts.push(` Database: ${run.databasePath}`);\n parts.push(` Artifacts: ${artifacts.length > 0 ? artifacts.join(', ') : 'none'}`);\n if (run.hasBqrs) parts.push(` BQRS: ${join(run.path, 'results.bqrs')}`);\n return parts.join('\\n');\n }),\n ];\n\n return {\n content: [{ type: 'text' as const, text: lines.join('\\n') }],\n };\n } catch (error) {\n logger.error('Error listing query run results:', error);\n return {\n content: [\n {\n type: 'text' as const,\n text: `Error: ${error instanceof Error ? error.message : 'Unknown error'}`,\n },\n ],\n isError: true,\n };\n }\n },\n );\n}\n", "/**\n * CodeQL pack install tool\n */\n\nimport { z } from 'zod';\nimport { CLIToolDefinition, createCodeQLSchemas } from '../../lib/cli-tool-registry';\n\nexport const codeqlPackInstallTool: CLIToolDefinition = {\n name: 'codeql_pack_install',\n description: 'Install CodeQL pack dependencies',\n command: 'codeql',\n subcommand: 'pack install',\n inputSchema: {\n packDir: z.string().optional().describe('Directory containing qlpack.yml (default: current)'),\n force: z.boolean().optional().describe('Force reinstall of dependencies'),\n 'no-strict-mode': z.boolean().optional()\n .describe('Allow non-strict dependency resolution'),\n verbose: createCodeQLSchemas.verbose(),\n additionalArgs: createCodeQLSchemas.additionalArgs()\n },\n examples: [\n 'codeql pack install',\n 'codeql pack install --force /path/to/pack',\n 'codeql pack install --no-strict-mode'\n ]\n};", "/**\n * CodeQL pack ls tool\n */\n\nimport { z } from 'zod';\nimport { CLIToolDefinition, createCodeQLSchemas, defaultCLIResultProcessor } from '../../lib/cli-tool-registry';\n\nexport const codeqlPackLsTool: CLIToolDefinition = {\n name: 'codeql_pack_ls',\n description: 'List CodeQL packs under some local directory path',\n command: 'codeql',\n subcommand: 'pack ls',\n inputSchema: {\n dir: z.string().optional().describe('The root directory of the package or workspace, defaults to the current working directory'),\n format: z.enum(['text', 'json']).optional()\n .describe('Output format: text (default) or json'),\n groups: z.string().optional()\n .describe('List of CodeQL pack groups to include or exclude'),\n verbose: createCodeQLSchemas.verbose(),\n additionalArgs: createCodeQLSchemas.additionalArgs()\n },\n examples: [\n 'codeql pack ls -- .',\n 'codeql pack ls --format=json -- /path/to/pack-directory',\n 'codeql pack ls --format=json --groups=queries,tests -- .'\n ],\n resultProcessor: defaultCLIResultProcessor\n};", "/**\n * MCP tool: profile_codeql_query_from_logs\n *\n * Parses CodeQL query evaluation logs into a performance profile WITHOUT\n * running the query. Works with logs from `codeql query run`,\n * `codeql database analyze`, or vscode-codeql query history.\n */\n\nimport { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport { existsSync, mkdirSync, writeFileSync } from 'fs';\nimport { basename, dirname, join } from 'path';\nimport { z } from 'zod';\nimport {\n parseEvaluatorLog,\n type PredicateProfile,\n type ProfileData,\n} from '../../lib/evaluator-log-parser';\nimport { logger } from '../../utils/logger';\n\n// ---------------------------------------------------------------------------\n// Formatting helpers\n// ---------------------------------------------------------------------------\n\n/**\n * Format the full profile data as pretty-printed JSON.\n */\nfunction formatAsJson(profile: ProfileData): string {\n return JSON.stringify(profile, null, 2);\n}\n\n/**\n * Format profile data as a Mermaid diagram.\n *\n * For single-query logs the diagram has one query root node with sub-nodes\n * for the top-N most expensive predicates. For multi-query logs each query\n * gets its own sub-graph.\n */\nfunction formatAsMermaid(profile: ProfileData, topN: number): string {\n const lines: string[] = [];\n\n lines.push('```mermaid');\n lines.push('graph TD');\n lines.push('');\n\n if (profile.queries.length <= 1) {\n // Single query layout\n const query = profile.queries[0] ?? {\n queryName: 'unknown',\n totalDurationMs: 0,\n predicates: [],\n predicateCount: 0,\n cacheHits: 0,\n };\n const qLabel = sanitizeMermaid(basename(query.queryName));\n lines.push(\n ` QUERY[\"${qLabel}
Total: ${query.totalDurationMs.toFixed(2)}ms
Predicates: ${query.predicateCount}\"]`\n );\n lines.push('');\n\n const topPredicates = getTopPredicates(query.predicates, topN);\n topPredicates.forEach((pred, idx) => {\n const nodeId = `P${idx}`;\n const name = sanitizeMermaid(pred.predicateName).substring(0, 50);\n const dur = pred.durationMs.toFixed(2);\n const size =\n pred.resultSize !== undefined ? String(pred.resultSize) : '?';\n lines.push(\n ` ${nodeId}[\"${name}
${dur}ms | ${size} results\"]`\n );\n });\n\n lines.push('');\n\n topPredicates.forEach((_pred, idx) => {\n lines.push(` QUERY --> P${idx}`);\n });\n } else {\n // Multi-query layout\n lines.push(\n ` ROOT[\"Evaluation Log
${profile.queries.length} queries\"]`\n );\n lines.push('');\n\n profile.queries.forEach((query, qIdx) => {\n const qNodeId = `Q${qIdx}`;\n const qLabel = sanitizeMermaid(basename(query.queryName));\n lines.push(\n ` ${qNodeId}[\"${qLabel}
${query.totalDurationMs.toFixed(2)}ms
Predicates: ${query.predicateCount}\"]`\n );\n lines.push(` ROOT --> ${qNodeId}`);\n\n const topPredicates = getTopPredicates(query.predicates, topN);\n topPredicates.forEach((pred, pIdx) => {\n const nodeId = `Q${qIdx}P${pIdx}`;\n const name = sanitizeMermaid(pred.predicateName).substring(0, 50);\n const dur = pred.durationMs.toFixed(2);\n const size =\n pred.resultSize !== undefined ? String(pred.resultSize) : '?';\n lines.push(\n ` ${nodeId}[\"${name}
${dur}ms | ${size} results\"]`\n );\n lines.push(` ${qNodeId} --> ${nodeId}`);\n });\n lines.push('');\n });\n }\n\n lines.push('');\n lines.push(\n ' classDef default fill:#e1f5ff,stroke:#333,stroke-width:2px'\n );\n lines.push(\n ' classDef query fill:#ffe1e1,stroke:#333,stroke-width:3px'\n );\n lines.push(' class QUERY query');\n lines.push('```');\n\n return lines.join('\\n');\n}\n\n/**\n * Sanitize a string for safe inclusion in a Mermaid node label.\n */\nfunction sanitizeMermaid(text: string): string {\n return text.replace(/[<>\"]/g, '');\n}\n\n/**\n * Return the top-N most expensive predicates sorted by descending duration.\n */\nfunction getTopPredicates(\n predicates: PredicateProfile[],\n topN: number\n): PredicateProfile[] {\n return [...predicates]\n .sort((a, b) => b.durationMs - a.durationMs)\n .slice(0, topN);\n}\n\n// ---------------------------------------------------------------------------\n// Text summary\n// ---------------------------------------------------------------------------\n\nfunction buildTextSummary(\n profile: ProfileData,\n topN: number,\n outputFiles: string[]\n): string {\n const sections: string[] = [];\n\n sections.push('Query log profiling completed successfully!');\n sections.push('');\n sections.push('Output Files:');\n for (const f of outputFiles) {\n sections.push(` - ${f}`);\n }\n\n sections.push('');\n sections.push(`Log Format: ${profile.logFormat}`);\n if (profile.codeqlVersion) {\n sections.push(`CodeQL Version: ${profile.codeqlVersion}`);\n }\n sections.push(`Total Events: ${profile.totalEvents}`);\n sections.push(`Queries: ${profile.queries.length}`);\n\n for (const query of profile.queries) {\n sections.push('');\n sections.push(`--- ${basename(query.queryName)} ---`);\n sections.push(` Total Duration: ${query.totalDurationMs.toFixed(2)} ms`);\n sections.push(` Predicates Evaluated: ${query.predicateCount}`);\n sections.push(` Cache Hits: ${query.cacheHits}`);\n\n const top = getTopPredicates(query.predicates, topN);\n if (top.length > 0) {\n sections.push(` Top ${top.length} Most Expensive Predicates:`);\n top.forEach((pred, idx) => {\n const sizeStr =\n pred.resultSize !== undefined ? `, ${pred.resultSize} results` : '';\n sections.push(\n ` ${idx + 1}. ${pred.predicateName} (${pred.durationMs.toFixed(2)} ms${sizeStr})`\n );\n });\n }\n }\n\n return sections.join('\\n');\n}\n\n// ---------------------------------------------------------------------------\n// Tool registration\n// ---------------------------------------------------------------------------\n\n/**\n * Register the `profile_codeql_query_from_logs` tool with the MCP server.\n */\nexport function registerProfileCodeQLQueryFromLogsTool(\n server: McpServer\n): void {\n server.tool(\n 'profile_codeql_query_from_logs',\n 'Parse CodeQL query evaluation logs into a performance profile without re-running the query. Works with logs from codeql query run, codeql database analyze, or vscode-codeql query history.',\n {\n evaluatorLog: z\n .string()\n .describe(\n 'Path to evaluator-log.jsonl or evaluator-log.summary.jsonl'\n ),\n outputDir: z\n .string()\n .optional()\n .describe(\n 'Directory to write profile output files (defaults to same directory as log)'\n ),\n topN: z\n .number()\n .optional()\n .describe(\n 'Number of most expensive predicates to highlight (default: 20)'\n ),\n },\n async (params) => {\n try {\n const { evaluatorLog, outputDir, topN } = params;\n const effectiveTopN = topN ?? 20;\n\n // Validate input path\n if (!existsSync(evaluatorLog)) {\n return {\n content: [\n {\n type: 'text' as const,\n text: `Evaluator log not found at: ${evaluatorLog}`,\n },\n ],\n isError: true,\n };\n }\n\n // Parse log\n logger.info(`Parsing evaluator log from: ${evaluatorLog}`);\n const profile = parseEvaluatorLog(evaluatorLog);\n\n // Determine output directory\n const profileOutputDir = outputDir ?? dirname(evaluatorLog);\n mkdirSync(profileOutputDir, { recursive: true });\n\n // Write profile JSON\n const jsonPath = join(\n profileOutputDir,\n 'query-evaluation-profile.json'\n );\n writeFileSync(jsonPath, formatAsJson(profile));\n logger.info(`Profile JSON written to: ${jsonPath}`);\n\n // Write Mermaid diagram\n const mdPath = join(\n profileOutputDir,\n 'query-evaluation-profile.md'\n );\n writeFileSync(mdPath, formatAsMermaid(profile, effectiveTopN));\n logger.info(`Profile Mermaid diagram written to: ${mdPath}`);\n\n // Build response\n const outputFilesList = [\n `Profile JSON: ${jsonPath}`,\n `Profile Mermaid: ${mdPath}`,\n `Evaluator Log: ${evaluatorLog}`,\n ];\n\n const responseText = buildTextSummary(\n profile,\n effectiveTopN,\n outputFilesList\n );\n\n return {\n content: [{ type: 'text' as const, text: responseText }],\n };\n } catch (error) {\n logger.error(\n 'Error profiling CodeQL query from logs:',\n error\n );\n return {\n content: [\n {\n type: 'text' as const,\n text: `Failed to profile query from logs: ${error instanceof Error ? error.message : String(error)}`,\n },\n ],\n isError: true,\n };\n }\n }\n );\n}\n", "/**\n * Reusable parser for CodeQL evaluator log files.\n *\n * Supports two formats:\n * - **Raw** (`evaluator-log.jsonl`): Pretty-printed JSON objects with a `type`\n * field (`LOG_HEADER`, `QUERY_STARTED`, `PREDICATE_STARTED`, etc.)\n * - **Summary** (`evaluator-log.summary.jsonl`): Pretty-printed JSON objects\n * without a `type` field; identified by `summaryLogVersion` or\n * `evaluationStrategy`.\n *\n * Both formats use pretty-printed JSON separated by `}\\n{` boundaries.\n */\n\nimport { readFileSync } from 'fs';\nimport { logger } from '../utils/logger';\n\n// ---------------------------------------------------------------------------\n// Public interfaces\n// ---------------------------------------------------------------------------\n\n/** Performance profile for a single evaluated predicate. */\nexport interface PredicateProfile {\n predicateName: string;\n position?: string;\n durationMs: number;\n resultSize?: number;\n pipelineCount?: number;\n evaluationStrategy?: string;\n dependencies: string[];\n}\n\n/** Performance profile for a single query within a log. */\nexport interface QueryProfile {\n queryName: string;\n totalDurationMs: number;\n predicateCount: number;\n predicates: PredicateProfile[];\n cacheHits: number;\n}\n\n/** Top-level result returned by all parse functions. */\nexport interface ProfileData {\n codeqlVersion?: string;\n logFormat: 'raw' | 'summary';\n queries: QueryProfile[];\n totalEvents: number;\n}\n\n// ---------------------------------------------------------------------------\n// Format detection\n// ---------------------------------------------------------------------------\n\n/**\n * Auto-detect whether the first parsed JSON object comes from a raw\n * evaluator log or a summary log.\n *\n * Raw events always contain a `type` string field.\n * Summary events never have `type`; the header carries `summaryLogVersion`.\n */\nexport function detectLogFormat(firstEvent: Record): 'raw' | 'summary' {\n if (typeof firstEvent.type === 'string') {\n return 'raw';\n }\n return 'summary';\n}\n\n// ---------------------------------------------------------------------------\n// Helpers\n// ---------------------------------------------------------------------------\n\n/**\n * Split a pretty-printed multi-JSON file into individual JSON strings.\n *\n * The log file contains multiple JSON objects that are pretty-printed,\n * separated by the pattern `}\\n\\n{` (closing brace, blank line, opening\n * brace). We split on `\\n}\\n` boundaries and reconstruct valid objects.\n */\nfunction splitJsonObjects(content: string): string[] {\n // Trim leading/trailing whitespace\n const trimmed = content.trim();\n if (trimmed.length === 0) {\n return [];\n }\n\n // Split on closing-brace + newline(s) + opening-brace boundaries.\n // We use a regex that matches `}\\n` followed by optional blank lines\n // then `{` \u2013 capturing the boundary so we can reconstruct.\n const parts = trimmed.split(/\\n\\}\\s*\\n\\s*\\{/);\n\n if (parts.length === 1) {\n // Single object or single-line \u2013 return as-is\n return [trimmed];\n }\n\n // Reconstruct: first part needs closing `}`, middle parts need both,\n // last part needs opening `{`.\n return parts.map((part, idx) => {\n if (idx === 0) {\n return part + '\\n}';\n }\n if (idx === parts.length - 1) {\n return '{\\n' + part;\n }\n return '{\\n' + part + '\\n}';\n });\n}\n\n/**\n * Parse all JSON objects from an evaluator log file.\n */\nfunction parseJsonObjects(logPath: string): Record[] {\n const content = readFileSync(logPath, 'utf-8');\n const objectStrings = splitJsonObjects(content);\n\n const results: Record[] = [];\n for (const objStr of objectStrings) {\n try {\n results.push(JSON.parse(objStr) as Record);\n } catch {\n logger.warn(\n `Failed to parse evaluator log object: ${objStr.substring(0, 120)}...`\n );\n }\n }\n return results;\n}\n\n// ---------------------------------------------------------------------------\n// Raw evaluator log parsing\n// ---------------------------------------------------------------------------\n\n/**\n * Parse a raw `evaluator-log.jsonl` file into {@link ProfileData}.\n *\n * Tracks `QUERY_STARTED`/`QUERY_COMPLETED` pairs, computes predicate\n * durations from `PREDICATE_STARTED`/`PREDICATE_COMPLETED` nanoTime\n * differences, and groups predicates by `queryCausingWork`.\n */\nexport function parseRawEvaluatorLog(logPath: string): ProfileData {\n const events = parseJsonObjects(logPath);\n\n let codeqlVersion: string | undefined;\n\n // Maps: eventId \u2192 event data for lookups\n const queryStartEvents = new Map<\n number,\n { queryName: string; nanoTime: number }\n >();\n const predicateStartEvents = new Map<\n number,\n {\n predicateName: string;\n position?: string;\n predicateType?: string;\n dependencies: string[];\n queryCausingWork?: number;\n nanoTime: number;\n pipelineCount: number;\n }\n >();\n\n // Completed predicate profiles grouped by query eventId\n const queryPredicates = new Map();\n // Query end nanoTimes keyed by query start eventId\n const queryEndNanoTimes = new Map();\n // Track cache lookups per query\n const queryCacheHits = new Map();\n // Fallback query eventId for predicates without queryCausingWork\n let firstQueryEventId: number | undefined;\n\n for (const event of events) {\n const eventType = event.type as string | undefined;\n\n switch (eventType) {\n case 'LOG_HEADER': {\n codeqlVersion = event.codeqlVersion as string | undefined;\n break;\n }\n\n case 'QUERY_STARTED': {\n const eid = event.eventId as number;\n const qName = (event.queryName as string) || 'unknown';\n queryStartEvents.set(eid, {\n queryName: qName,\n nanoTime: event.nanoTime as number,\n });\n queryPredicates.set(eid, []);\n queryCacheHits.set(eid, 0);\n if (firstQueryEventId === undefined) {\n firstQueryEventId = eid;\n }\n break;\n }\n\n case 'QUERY_COMPLETED': {\n const startEid = event.startEvent as number;\n queryEndNanoTimes.set(startEid, event.nanoTime as number);\n break;\n }\n\n case 'PREDICATE_STARTED': {\n const eid = event.eventId as number;\n const deps = event.dependencies as Record | undefined;\n predicateStartEvents.set(eid, {\n predicateName: (event.predicateName as string) || 'unknown',\n position: event.position as string | undefined,\n predicateType: event.predicateType as string | undefined,\n dependencies: deps ? Object.keys(deps) : [],\n queryCausingWork: event.queryCausingWork as number | undefined,\n nanoTime: event.nanoTime as number,\n pipelineCount: 0,\n });\n break;\n }\n\n case 'PIPELINE_COMPLETED': {\n // Count pipelines for the parent predicate\n const pipelineStartEid = event.startEvent as number;\n // Find the pipeline_started event to get predicateStartEvent\n const pipelineStartEvt = events.find(\n (e) =>\n (e.type as string) === 'PIPELINE_STARTED' &&\n (e.eventId as number) === pipelineStartEid\n );\n if (pipelineStartEvt) {\n const predEid = pipelineStartEvt.predicateStartEvent as number;\n const predStart = predicateStartEvents.get(predEid);\n if (predStart) {\n predStart.pipelineCount += 1;\n }\n }\n break;\n }\n\n case 'PREDICATE_COMPLETED': {\n const startEid = event.startEvent as number;\n const predStart = predicateStartEvents.get(startEid);\n if (predStart) {\n const durationNs =\n (event.nanoTime as number) - predStart.nanoTime;\n const durationMs = durationNs / 1_000_000;\n\n const profile: PredicateProfile = {\n predicateName: predStart.predicateName,\n position: predStart.position,\n durationMs,\n resultSize: event.resultSize as number | undefined,\n pipelineCount:\n predStart.pipelineCount > 0\n ? predStart.pipelineCount\n : undefined,\n evaluationStrategy: predStart.predicateType,\n dependencies: predStart.dependencies,\n };\n\n const qEid =\n predStart.queryCausingWork ?? firstQueryEventId;\n if (qEid !== undefined) {\n let arr = queryPredicates.get(qEid);\n if (!arr) {\n arr = [];\n queryPredicates.set(qEid, arr);\n }\n arr.push(profile);\n }\n }\n break;\n }\n\n case 'CACHE_LOOKUP': {\n // Attribute to the most recent query\n const qEid =\n (event.queryCausingWork as number | undefined) ??\n firstQueryEventId;\n if (qEid !== undefined) {\n queryCacheHits.set(qEid, (queryCacheHits.get(qEid) ?? 0) + 1);\n }\n break;\n }\n }\n }\n\n // Build QueryProfile entries\n const queries: QueryProfile[] = [];\n for (const [qEid, startInfo] of queryStartEvents) {\n const predicates = queryPredicates.get(qEid) ?? [];\n const endNano = queryEndNanoTimes.get(qEid);\n const totalDurationMs =\n endNano !== undefined\n ? (endNano - startInfo.nanoTime) / 1_000_000\n : predicates.reduce((sum, p) => sum + p.durationMs, 0);\n\n queries.push({\n queryName: startInfo.queryName,\n totalDurationMs,\n predicateCount: predicates.length,\n predicates,\n cacheHits: queryCacheHits.get(qEid) ?? 0,\n });\n }\n\n return {\n codeqlVersion,\n logFormat: 'raw',\n queries,\n totalEvents: events.length,\n };\n}\n\n// ---------------------------------------------------------------------------\n// Summary log parsing\n// ---------------------------------------------------------------------------\n\n/**\n * Parse an `evaluator-log.summary.jsonl` file into {@link ProfileData}.\n *\n * Summary events carry `millis` directly (already in ms). Predicates are\n * grouped by `queryCausingWork` which is a **string** (query name) in the\n * summary format.\n */\nexport function parseSummaryLog(logPath: string): ProfileData {\n const events = parseJsonObjects(logPath);\n\n let codeqlVersion: string | undefined;\n\n // queryCausingWork (string) \u2192 collected predicates\n const queryPredicatesMap = new Map();\n // Track total millis per query\n const queryTotalMs = new Map();\n // Track cache hits per query\n const queryCacheHits = new Map();\n\n for (const event of events) {\n // Header detection\n if (event.summaryLogVersion !== undefined) {\n codeqlVersion = event.codeqlVersion as string | undefined;\n continue;\n }\n\n const strategy = event.evaluationStrategy as string | undefined;\n\n // Skip sentinel-empty entries (no useful timing data)\n if (strategy === 'SENTINEL_EMPTY') {\n continue;\n }\n\n // Skip events without millis (non-predicate summaries)\n if (event.millis === undefined) {\n continue;\n }\n\n const predicateName =\n (event.predicateName as string) || 'unknown';\n const millis = event.millis as number;\n const queryName =\n (event.queryCausingWork as string) || 'unknown';\n\n const deps = event.dependencies as Record | undefined;\n const pipelineRuns = event.pipelineRuns as number | undefined;\n\n const profile: PredicateProfile = {\n predicateName,\n position: event.position as string | undefined,\n durationMs: millis,\n resultSize: event.resultSize as number | undefined,\n pipelineCount: pipelineRuns,\n evaluationStrategy: strategy,\n dependencies: deps ? Object.keys(deps) : [],\n };\n\n // Check if this is a cached entry\n if (event.isCached === true || strategy === 'CACHEHIT') {\n queryCacheHits.set(\n queryName,\n (queryCacheHits.get(queryName) ?? 0) + 1\n );\n }\n\n let arr = queryPredicatesMap.get(queryName);\n if (!arr) {\n arr = [];\n queryPredicatesMap.set(queryName, arr);\n }\n arr.push(profile);\n\n queryTotalMs.set(\n queryName,\n (queryTotalMs.get(queryName) ?? 0) + millis\n );\n }\n\n // Build QueryProfile entries\n const queries: QueryProfile[] = [];\n for (const [queryName, predicates] of queryPredicatesMap) {\n queries.push({\n queryName,\n totalDurationMs: queryTotalMs.get(queryName) ?? 0,\n predicateCount: predicates.length,\n predicates,\n cacheHits: queryCacheHits.get(queryName) ?? 0,\n });\n }\n\n return {\n codeqlVersion,\n logFormat: 'summary',\n queries,\n totalEvents: events.length,\n };\n}\n\n// ---------------------------------------------------------------------------\n// Auto-detect entry point\n// ---------------------------------------------------------------------------\n\n/**\n * Auto-detect the log format and parse accordingly.\n *\n * @param logPath - Absolute path to `evaluator-log.jsonl` or\n * `evaluator-log.summary.jsonl`.\n * @returns Parsed profile data.\n */\nexport function parseEvaluatorLog(logPath: string): ProfileData {\n const events = parseJsonObjects(logPath);\n\n if (events.length === 0) {\n return {\n logFormat: 'raw',\n queries: [],\n totalEvents: 0,\n };\n }\n\n const format = detectLogFormat(events[0]);\n\n if (format === 'raw') {\n return parseRawEvaluatorLog(logPath);\n }\n return parseSummaryLog(logPath);\n}\n", "/**\n * CodeQL query profiling tool\n */\n\nimport { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport { z } from 'zod';\nimport { executeCodeQLCommand } from '../../lib/cli-executor';\nimport { logger } from '../../utils/logger';\nimport { writeFileSync, readFileSync, existsSync } from 'fs';\nimport { join, dirname, basename } from 'path';\nimport { mkdirSync } from 'fs';\n\ninterface EvaluatorLogEvent {\n time: string;\n type: string;\n eventId: number;\n nanoTime: number;\n [key: string]: unknown;\n}\n\ninterface PipelineNode {\n eventId: number;\n name: string;\n position?: string;\n type?: string;\n startTime: number;\n endTime: number;\n duration: number;\n resultSize?: number;\n tupleCount?: number;\n dependencies: string[];\n dependencyEventIds: number[];\n}\n\ninterface ProfileData {\n queryName: string;\n totalDuration: number;\n totalEvents: number;\n pipelines: PipelineNode[];\n}\n\n/**\n * Parse evaluator log and create profile data\n */\nfunction parseEvaluatorLog(logPath: string): ProfileData {\n const logContent = readFileSync(logPath, 'utf-8');\n \n // Split by empty lines to get each JSON object (handles both JSONL and pretty-printed JSON)\n const jsonObjects = logContent.split('\\n\\n').filter((s) => s.trim());\n const events: EvaluatorLogEvent[] = jsonObjects\n .map((obj) => {\n try {\n return JSON.parse(obj);\n } catch (_error) {\n logger.warn(`Failed to parse evaluator log object: ${obj.substring(0, 100)}...`);\n return null;\n }\n })\n .filter((event): event is EvaluatorLogEvent => event !== null);\n\n // Map to track pipeline nodes by their start event ID\n const pipelineMap = new Map>();\n // Map to track dependency event IDs by predicate name\n const predicateNameToEventId = new Map();\n \n let queryName = '';\n let queryStartTime = 0;\n let queryEndTime = 0;\n\n for (const event of events) {\n switch (event.type) {\n case 'QUERY_STARTED':\n queryName = (event.queryName as string) || '';\n queryStartTime = event.nanoTime;\n break;\n\n case 'QUERY_COMPLETED':\n queryEndTime = event.nanoTime;\n break;\n\n case 'PREDICATE_STARTED': {\n const predicateName = event.predicateName as string;\n const position = event.position as string | undefined;\n const predicateType = event.predicateType as string | undefined;\n const dependencies = event.dependencies as Record | undefined;\n \n // Track this predicate's event ID by name for dependency resolution\n predicateNameToEventId.set(predicateName, event.eventId);\n \n // Get dependency event IDs\n const dependencyEventIds: number[] = [];\n const dependencyNames: string[] = [];\n if (dependencies) {\n for (const depName of Object.keys(dependencies)) {\n dependencyNames.push(depName);\n const depEventId = predicateNameToEventId.get(depName);\n if (depEventId !== undefined) {\n dependencyEventIds.push(depEventId);\n }\n }\n }\n\n pipelineMap.set(event.eventId, {\n eventId: event.eventId,\n name: predicateName,\n position,\n type: predicateType,\n startTime: event.nanoTime,\n dependencies: dependencyNames,\n dependencyEventIds,\n });\n break;\n }\n\n case 'PREDICATE_COMPLETED': {\n const startEventId = event.startEvent as number;\n const pipelineInfo = pipelineMap.get(startEventId);\n if (pipelineInfo) {\n const startEvent = events.find((e) => e.eventId === startEventId);\n if (startEvent) {\n const duration = (event.nanoTime - startEvent.nanoTime) / 1_000_000; // Convert to ms\n pipelineInfo.endTime = event.nanoTime;\n pipelineInfo.duration = duration;\n pipelineInfo.resultSize = event.resultSize as number | undefined;\n pipelineInfo.tupleCount = event.tupleCount as number | undefined;\n }\n }\n break;\n }\n }\n }\n\n // Convert to array and maintain original evaluation order (by eventId)\n const pipelines: PipelineNode[] = Array.from(pipelineMap.values())\n .filter((p): p is PipelineNode => p.duration !== undefined)\n .sort((a, b) => a.eventId - b.eventId);\n\n const totalDuration = queryEndTime > 0 ? (queryEndTime - queryStartTime) / 1_000_000 : 0;\n\n return {\n queryName,\n totalDuration,\n totalEvents: events.length,\n pipelines,\n };\n}\n\n/**\n * Format profile data as JSON\n */\nfunction formatAsJson(profile: ProfileData): string {\n return JSON.stringify(profile, null, 2);\n}\n\n/**\n * Format profile data as Mermaid diagram\n * Creates a graph showing the query evaluation pipelines in order of execution\n * with dependencies as edges, annotated with duration and result sizes\n */\nfunction formatAsMermaid(profile: ProfileData): string {\n const lines: string[] = [];\n\n lines.push('```mermaid');\n lines.push('graph TD');\n lines.push('');\n \n // Add query root node\n lines.push(` QUERY[\"${basename(profile.queryName)}
Total: ${profile.totalDuration.toFixed(2)}ms\"]`);\n lines.push('');\n \n // Create nodes for each pipeline in evaluation order (already sorted by eventId)\n profile.pipelines.forEach((pipeline) => {\n const nodeId = `P${pipeline.eventId}`;\n const duration = pipeline.duration.toFixed(2);\n const resultSize = pipeline.resultSize !== undefined ? pipeline.resultSize : '?';\n // Sanitize predicate name for Mermaid\n const name = pipeline.name.replace(/[<>]/g, '').substring(0, 40);\n lines.push(` ${nodeId}[\"${name}
${duration}ms | ${resultSize} results\"]`);\n });\n \n lines.push('');\n \n // Add edges from QUERY to root pipelines (those with no dependencies)\n const rootPipelines = profile.pipelines.filter((p) => p.dependencies.length === 0);\n \n rootPipelines.forEach((pipeline) => {\n lines.push(` QUERY --> P${pipeline.eventId}`);\n });\n \n lines.push('');\n \n // Add edges between pipelines based on dependencies (using eventIds to preserve links)\n profile.pipelines.forEach((pipeline) => {\n pipeline.dependencyEventIds.forEach((depEventId) => {\n const duration = pipeline.duration.toFixed(2);\n lines.push(` P${depEventId} -->|\"${duration}ms\"| P${pipeline.eventId}`);\n });\n });\n \n lines.push('');\n lines.push(' classDef default fill:#e1f5ff,stroke:#333,stroke-width:2px');\n lines.push(' classDef query fill:#ffe1e1,stroke:#333,stroke-width:3px');\n lines.push(' class QUERY query');\n lines.push('```');\n\n return lines.join('\\n');\n}\n\n/**\n * Register the profile_codeql_query tool\n */\nexport function registerProfileCodeQLQueryTool(server: McpServer): void {\n server.tool(\n 'profile_codeql_query',\n 'Profile the performance of a CodeQL query run against a specific database by analyzing the evaluator log JSON file',\n {\n query: z.string().describe('Path to the .ql query file'),\n database: z.string().describe('Path to the CodeQL database directory'),\n evaluatorLog: z\n .string()\n .optional()\n .describe(\n 'Path to an existing structured JSON log (e.g., evaluator-log.jsonl) file. If not provided, the tool will run the query to generate one.'\n ),\n outputDir: z\n .string()\n .optional()\n .describe('Directory to write profiling data files (defaults to same directory as evaluator log)'),\n },\n async (params) => {\n try {\n const { query, database, evaluatorLog, outputDir } = params;\n let logPath = evaluatorLog;\n let bqrsPath: string | undefined;\n let sarifPath: string | undefined;\n\n // If evaluator log not provided, run the query to generate one\n if (!logPath) {\n logger.info('No evaluator log provided, running query to generate one');\n\n // Determine output directory\n const defaultOutputDir = outputDir || join(dirname(query as string), 'profile-output');\n mkdirSync(defaultOutputDir, { recursive: true });\n\n logPath = join(defaultOutputDir, 'evaluator-log.jsonl');\n bqrsPath = join(defaultOutputDir, 'query-results.bqrs');\n sarifPath = join(defaultOutputDir, 'query-results.sarif');\n\n // Run query with evaluator logging and tuple counting\n const queryResult = await executeCodeQLCommand(\n 'query run',\n {\n database: database as string,\n output: bqrsPath,\n 'evaluator-log': logPath,\n 'tuple-counting': true,\n 'evaluator-log-level': 5,\n },\n [query as string]\n );\n\n if (!queryResult.success) {\n return {\n content: [\n {\n type: 'text' as const,\n text: `Failed to run query: ${queryResult.stderr || queryResult.error}`,\n },\n ],\n isError: true,\n };\n }\n\n // Generate SARIF interpretation\n if (existsSync(bqrsPath)) {\n try {\n const sarifResult = await executeCodeQLCommand(\n 'bqrs interpret',\n { format: 'sarif-latest', output: sarifPath },\n [bqrsPath]\n );\n\n if (sarifResult.success) {\n logger.info(`Generated SARIF interpretation at ${sarifPath}`);\n }\n } catch (error) {\n logger.warn(`Failed to generate SARIF interpretation: ${error}`);\n }\n }\n }\n\n // Verify evaluator log exists\n if (!existsSync(logPath)) {\n return {\n content: [\n {\n type: 'text' as const,\n text: `Evaluator log not found at: ${logPath}`,\n },\n ],\n isError: true,\n };\n }\n\n // Parse the evaluator log\n logger.info(`Parsing evaluator log from: ${logPath}`);\n const profile = parseEvaluatorLog(logPath);\n\n // Determine output directory for profile\n const profileOutputDir = outputDir || dirname(logPath);\n mkdirSync(profileOutputDir, { recursive: true });\n\n // Write profile JSON file\n const jsonPath = join(profileOutputDir, 'query-evaluation-profile.json');\n const jsonContent = formatAsJson(profile);\n writeFileSync(jsonPath, jsonContent);\n logger.info(`Profile JSON written to: ${jsonPath}`);\n\n // Write profile Mermaid diagram file\n const mdPath = join(profileOutputDir, 'query-evaluation-profile.md');\n const mdContent = formatAsMermaid(profile);\n writeFileSync(mdPath, mdContent);\n logger.info(`Profile Mermaid diagram written to: ${mdPath}`);\n\n // Build response message\n const outputFiles: string[] = [\n `Profile JSON: ${jsonPath}`,\n `Profile Mermaid: ${mdPath}`,\n `Evaluator Log: ${logPath}`,\n ];\n\n if (bqrsPath) {\n outputFiles.push(`Query Results (BQRS): ${bqrsPath}`);\n }\n\n if (sarifPath && existsSync(sarifPath)) {\n outputFiles.push(`Query Results (SARIF): ${sarifPath}`);\n }\n\n const responseText = [\n 'Query profiling completed successfully!',\n '',\n 'Output Files:',\n ...outputFiles.map((f) => ` - ${f}`),\n '',\n 'Profile Summary:',\n ` - Query: ${basename(profile.queryName)}`,\n ` - Total Duration: ${profile.totalDuration.toFixed(2)} ms`,\n ` - Total Pipelines: ${profile.pipelines.length}`,\n ` - Total Events: ${profile.totalEvents}`,\n '',\n 'First 5 Pipeline Nodes (in evaluation order):',\n ...profile.pipelines.slice(0, 5).map((p, idx) => {\n return ` ${idx + 1}. ${p.name} (${p.duration.toFixed(2)} ms, ${p.resultSize || '?'} results)`;\n }),\n ].join('\\n');\n\n return {\n content: [\n {\n type: 'text' as const,\n text: responseText,\n },\n ],\n };\n } catch (error) {\n logger.error('Error profiling CodeQL query:', error);\n\n return {\n content: [\n {\n type: 'text' as const,\n text: `Failed to profile query: ${error instanceof Error ? error.message : String(error)}`,\n },\n ],\n isError: true,\n };\n }\n }\n );\n}\n", "/**\n * CodeQL query compile tool\n */\n\nimport { z } from 'zod';\nimport { CLIToolDefinition } from '../../lib/cli-tool-registry';\n\nexport const codeqlQueryCompileTool: CLIToolDefinition = {\n name: 'codeql_query_compile',\n description: 'Compile and validate CodeQL queries',\n command: 'codeql',\n subcommand: 'query compile',\n inputSchema: {\n query: z.string().describe('Path to the CodeQL query file (.ql)'),\n database: z.string().optional().describe('Path to the CodeQL database'),\n library: z.string().optional().describe('Path to query library'),\n output: z.string().optional().describe('Output file path'),\n warnings: z.enum(['hide', 'show', 'error']).optional()\n .describe('How to handle compilation warnings'),\n verbose: z.boolean().optional().describe('Enable verbose output'),\n additionalArgs: z.array(z.string()).optional().describe('Additional command-line arguments')\n },\n examples: [\n 'codeql query compile --database=/path/to/db MyQuery.ql',\n 'codeql query compile --library=/path/to/lib --output=compiled.qlo MyQuery.ql'\n ]\n};", "/**\n * CodeQL query format tool\n */\n\nimport { z } from 'zod';\nimport { CLIToolDefinition, createCodeQLSchemas, defaultCLIResultProcessor, CLIExecutionResult } from '../../lib/cli-tool-registry';\n\n/**\n * Custom result processor for codeql query format tool\n * Exit code 1 with --check-only means \"file would change\" - this is success for format checking\n */\nfunction formatResultProcessor(result: CLIExecutionResult, params: Record): string {\n const isCheckOnly = params['check-only'];\n const hasFormatChanges = result.exitCode === 1;\n \n if (isCheckOnly && hasFormatChanges) {\n // Mark as success for the CLI tool registry since detecting format changes is the intended behavior\n result.success = true;\n return result.stdout || result.stderr || 'File would change by autoformatting.';\n }\n \n return defaultCLIResultProcessor(result, params);\n}\n\nexport const codeqlQueryFormatTool: CLIToolDefinition = {\n name: 'codeql_query_format',\n description: 'Automatically format CodeQL source code files',\n command: 'codeql',\n subcommand: 'query format',\n inputSchema: {\n files: z.array(z.string()).describe('One or more .ql or .qll source files to format'),\n output: z.string().optional().describe('Write formatted code to this file instead of stdout'),\n 'in-place': z.boolean().optional().describe('Overwrite each input file with formatted version'),\n 'check-only': z.boolean().optional().describe('Check formatting without writing output'),\n backup: z.string().optional().describe('Backup extension when overwriting existing files'),\n 'no-syntax-errors': z.boolean().optional().describe('Ignore syntax errors and pretend file is formatted'),\n verbose: createCodeQLSchemas.verbose(),\n additionalArgs: createCodeQLSchemas.additionalArgs()\n },\n examples: [\n 'codeql query format -i -- ExampleQuery.ql',\n 'codeql query format --in-place -- queries/*.ql',\n 'codeql query format --check-only -- queries/*.ql'\n ],\n resultProcessor: formatResultProcessor\n};", "/**\n * CodeQL query run tool\n */\n\nimport { z } from 'zod';\nimport { CLIToolDefinition, createCodeQLSchemas } from '../../lib/cli-tool-registry';\n\nexport const codeqlQueryRunTool: CLIToolDefinition = {\n name: 'codeql_query_run',\n description:\n 'Execute a CodeQL query against a database. Use either \"query\" parameter for direct file path OR \"queryName\" + \"queryLanguage\" for pre-defined tool queries. ' +\n 'Produces evaluator logs and BQRS results in a log directory. ' +\n 'Use list_codeql_databases to discover databases, list_query_run_results to find previous results, and codeql_bqrs_decode to inspect BQRS output.',\n command: 'codeql',\n subcommand: 'query run',\n inputSchema: {\n query: z.string().optional().describe('Path to the CodeQL query file (.ql) - cannot be used with queryName'),\n queryName: z.string().optional().describe('Name of pre-defined query to run (e.g., \"PrintAST\", \"CallGraphFrom\", \"CallGraphTo\") - requires queryLanguage'),\n queryLanguage: z.string().optional().describe('Programming language for tools queries (e.g., \"javascript\", \"java\", \"python\") - required when using queryName'),\n queryPack: z.string().optional().describe('Query pack path (defaults to server/ql//tools/src/ for tool queries)'),\n sourceFiles: z.string().optional().describe('Comma-separated list of source file paths for PrintAST queries (e.g., \"src/main.js,src/utils.js\" or just \"main.js\")'),\n sourceFunction: z.string().optional().describe('Comma-separated list of source function names for CallGraphFrom queries (e.g., \"main,processData\")'),\n targetFunction: z.string().optional().describe('Comma-separated list of target function names for CallGraphTo queries (e.g., \"helper,validateInput\")'),\n database: createCodeQLSchemas.database(),\n output: createCodeQLSchemas.output(),\n external: z.array(z.string()).optional()\n .describe('External predicate data: predicate=file.csv'),\n timeout: createCodeQLSchemas.timeout(),\n logDir: z.string().optional()\n .describe('Custom directory for query execution logs (overrides CODEQL_QUERY_LOG_DIR environment variable). If not provided, uses CODEQL_QUERY_LOG_DIR or defaults to .tmp/query-logs/'),\n 'evaluator-log': z.string().optional().describe('Path to save evaluator log (deprecated: use logDir instead)'),\n 'evaluator-log-minify': z.boolean().optional()\n .describe('Minimize evaluator log for smaller size'),\n 'evaluator-log-level': z.number().min(1).max(5).optional()\n .describe('Evaluator log verbosity level (1-5, default 5)'),\n 'tuple-counting': z.boolean().optional()\n .describe('Display tuple counts for each evaluation step in evaluator logs'),\n format: z.enum(['sarif-latest', 'sarifv2.1.0', 'csv', 'graphtext', 'dgml', 'dot']).optional()\n .describe('Output format for query results via codeql bqrs interpret. Defaults to sarif-latest for @kind problem/path-problem queries, graphtext for @kind graph queries. Graph formats (graphtext, dgml, dot) only work with @kind graph queries.'),\n interpretedOutput: z.string().optional()\n .describe('Output file for interpreted results (e.g., results.sarif, results.txt). If not provided, defaults based on format: .sarif for SARIF, .txt for graphtext/csv, .dgml for dgml, .dot for dot'),\n evaluationFunction: z.string().optional()\n .describe('[DEPRECATED - use format parameter instead] Built-in function for query results evaluation (e.g., \"mermaid-graph\", \"json-decode\", \"csv-decode\") or path to custom evaluation script'),\n evaluationOutput: z.string().optional()\n .describe('[DEPRECATED - use interpretedOutput parameter instead] Output file for evaluation results'),\n verbose: createCodeQLSchemas.verbose(),\n additionalArgs: createCodeQLSchemas.additionalArgs()\n },\n examples: [\n 'codeql query run --database=mydb --output=results.bqrs MyQuery.ql',\n 'codeql query run --database=mydb --query-name=PrintAST --query-language=javascript --source-files=src/index.js --output=results.bqrs --format=graphtext --interpreted-output=results.txt',\n 'codeql query run --database=mydb --external=data=input.csv --output=results.bqrs MyQuery.ql --format=sarif-latest --interpreted-output=results.sarif',\n 'codeql query run --database=mydb --evaluator-log=eval.log --tuple-counting --evaluator-log-level=5 --output=results.bqrs MyQuery.ql',\n 'codeql query run --database=mydb --query-name=PrintAST --query-language=javascript --source-files=\"main.js,utils.js\" --format=graphtext',\n 'codeql query run --database=mydb --log-dir=/custom/log/path --tuple-counting --output=results.bqrs MyQuery.ql'\n ]\n};", "/**\n * CodeQL quick evaluate tool\n * \n * Inspired by JordyZomer/codeql-mcp repository:\n * - https://github.com/JordyZomer/codeql-mcp/blob/main/server.py\n * - https://github.com/JordyZomer/codeql-mcp/blob/main/codeqlclient.py\n */\n\nimport { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport { z } from 'zod';\nimport { join, resolve } from 'path';\nimport { findClassPosition } from './find-class-position';\nimport { findPredicatePosition } from './find-predicate-position';\nimport { logger } from '../../utils/logger';\nimport { getProjectTmpDir } from '../../utils/temp-dir';\n\nexport interface QuickEvaluateParams {\n file: string;\n db: string;\n symbol: string;\n output_path?: string;\n}\n\n/**\n * Quick evaluate either a class or a predicate in a CodeQL query.\n * This allows debugging a select portion of QL code without running the whole query.\n */\nexport async function quickEvaluate({\n file,\n db: _db,\n symbol,\n output_path\n}: QuickEvaluateParams): Promise {\n try {\n // Try to find as a class first, then as a predicate\n try {\n await findClassPosition(file, symbol);\n } catch {\n try {\n await findPredicatePosition(file, symbol);\n } catch {\n throw new Error(`Symbol '${symbol}' not found as class or predicate in file: ${file}`);\n }\n }\n \n const resolvedOutput = resolve(output_path || join(getProjectTmpDir('quickeval'), 'quickeval.bqrs'));\n \n // For now, return the resolved output path\n // In a full implementation, this would use the CodeQL CLI or query server\n // to perform the actual quick evaluation with the position parameters\n return resolvedOutput;\n } catch (error) {\n throw new Error(`CodeQL evaluation failed: ${error instanceof Error ? error.message : 'Unknown error'}`, { cause: error });\n }\n}\n\n/**\n * Register the quick evaluate tool with the MCP server\n */\nexport function registerQuickEvaluateTool(server: McpServer): void {\n server.tool(\n 'quick_evaluate',\n 'Quick evaluate either a class or a predicate in a CodeQL query for debugging',\n {\n file: z.string().describe('Path to the .ql file containing the symbol'),\n db: z.string().describe('Path to the CodeQL database'),\n symbol: z.string().describe('Name of the class or predicate to evaluate'),\n output_path: z.string().optional().describe('Output path for results (defaults to project-local .tmp/quickeval/)'),\n },\n async ({ file, db, symbol, output_path }) => {\n try {\n const result = await quickEvaluate({ file, db, symbol, output_path });\n return {\n content: [{ type: 'text', text: result }],\n };\n } catch (error) {\n logger.error('Error in quick evaluate:', error);\n return {\n content: [\n {\n type: 'text',\n text: `Error: ${error instanceof Error ? error.message : 'Unknown error'}`,\n },\n ],\n isError: true,\n };\n }\n }\n );\n}", "/**\n * CodeQL register database tool\n * \n * Inspired by JordyZomer/codeql-mcp repository:\n * - https://github.com/JordyZomer/codeql-mcp/blob/main/server.py\n * - https://github.com/JordyZomer/codeql-mcp/blob/main/codeqlclient.py\n */\n\nimport { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport { z } from 'zod';\nimport { access, constants } from 'fs/promises';\nimport { resolve } from 'path';\nimport { logger } from '../../utils/logger';\n\nexport interface DatabaseRegistration {\n uri: string;\n content: {\n sourceArchiveZip: string;\n dbDir: string;\n };\n}\n\n/**\n * Register a CodeQL database given a local path to the database directory.\n * Validates that the database exists and has required structure.\n * Supports both full databases (with src.zip) and test databases (with src/ folder).\n */\nexport async function registerDatabase(dbPath: string): Promise {\n try {\n const resolvedPath = resolve(dbPath);\n \n // Check if database directory exists\n await access(resolvedPath, constants.F_OK);\n \n // Check for codeql-database.yml (required for all CodeQL databases)\n const dbYmlPath = resolve(resolvedPath, 'codeql-database.yml');\n await access(dbYmlPath, constants.F_OK);\n \n // Check if src.zip exists (for full databases) OR src/ directory exists (for test databases)\n const srcZipPath = resolve(resolvedPath, 'src.zip');\n const srcDirPath = resolve(resolvedPath, 'src');\n \n let hasSrcZip = false;\n let hasSrcDir = false;\n \n try {\n await access(srcZipPath, constants.F_OK);\n hasSrcZip = true;\n } catch {\n // src.zip not found, check for src/ directory\n }\n \n if (!hasSrcZip) {\n try {\n await access(srcDirPath, constants.F_OK);\n hasSrcDir = true;\n } catch {\n // src directory not found either\n }\n }\n \n if (!hasSrcZip && !hasSrcDir) {\n throw new Error(`Missing required source archive (src.zip) or source directory (src/) in: ${dbPath}`);\n }\n \n // For now, we just validate and return success message\n // In a full implementation, this would register with a query server\n const sourceType = hasSrcZip ? 'src.zip' : 'src/';\n return `Database registered: ${dbPath} (source: ${sourceType})`;\n } catch (error) {\n if (error instanceof Error) {\n const errorCode = (error as { code?: string }).code;\n if (errorCode === 'ENOENT') {\n if (error.message.includes('codeql-database.yml')) {\n throw new Error(`Missing required codeql-database.yml in: ${dbPath}`, { cause: error });\n }\n throw new Error(`Database path does not exist: ${dbPath}`, { cause: error });\n }\n if (errorCode === 'EACCES') {\n throw new Error(`Database path does not exist: ${dbPath}`, { cause: error });\n }\n }\n throw new Error(`Failed to register database: ${error instanceof Error ? error.message : 'Unknown error'}`, { cause: error });\n }\n}\n\n/**\n * Register the register database tool with the MCP server\n */\nexport function registerRegisterDatabaseTool(server: McpServer): void {\n server.tool(\n 'register_database',\n 'Register a CodeQL database given a local path to the database directory',\n {\n db_path: z.string().describe('Path to the CodeQL database directory'),\n },\n async ({ db_path }) => {\n try {\n const result = await registerDatabase(db_path);\n return {\n content: [{ type: 'text', text: result }],\n };\n } catch (error) {\n logger.error('Error registering database:', error);\n return {\n content: [\n {\n type: 'text',\n text: `Error: ${error instanceof Error ? error.message : 'Unknown error'}`,\n },\n ],\n isError: true,\n };\n }\n }\n );\n}", "/**\n * CodeQL resolve database tool\n */\n\nimport { z } from 'zod';\nimport { CLIToolDefinition, createCodeQLSchemas, defaultCLIResultProcessor } from '../../lib/cli-tool-registry';\n\nexport const codeqlResolveDatabaseTool: CLIToolDefinition = {\n name: 'codeql_resolve_database',\n description: 'Resolve database path and validate database structure',\n command: 'codeql',\n subcommand: 'resolve database',\n inputSchema: {\n database: z.string().describe('Database path to resolve'),\n format: z.enum(['text', 'json', 'betterjson']).optional()\n .describe('Output format for database information'),\n verbose: createCodeQLSchemas.verbose(),\n additionalArgs: createCodeQLSchemas.additionalArgs()\n },\n examples: [\n 'codeql resolve database -- /path/to/database',\n 'codeql resolve database --format=json -- my-database',\n 'codeql resolve database --format=betterjson -- database-dir'\n ],\n resultProcessor: defaultCLIResultProcessor\n};", "/**\n * CodeQL resolve languages tool\n */\n\nimport { z } from 'zod';\nimport { CLIToolDefinition, defaultCLIResultProcessor } from '../../lib/cli-tool-registry';\n\nexport const codeqlResolveLanguagesTool: CLIToolDefinition = {\n name: 'codeql_resolve_languages',\n description: 'List installed CodeQL extractor packs',\n command: 'codeql',\n subcommand: 'resolve languages',\n inputSchema: {\n format: z.enum(['text', 'json', 'betterjson']).optional()\n .describe('Output format for language information'),\n verbose: z.boolean().optional().describe('Enable verbose output'),\n additionalArgs: z.array(z.string()).optional().describe('Additional command-line arguments')\n },\n examples: [\n 'codeql resolve languages --format=text',\n 'codeql resolve languages --format=json',\n 'codeql resolve languages --format=betterjson'\n ],\n resultProcessor: defaultCLIResultProcessor\n};", "/**\n * CodeQL resolve library-path tool\n */\n\nimport { z } from 'zod';\nimport { CLIToolDefinition, defaultCLIResultProcessor } from '../../lib/cli-tool-registry';\n\nexport const codeqlResolveLibraryPathTool: CLIToolDefinition = {\n name: 'codeql_resolve_library-path',\n description: 'Resolve library path for CodeQL queries and libraries',\n command: 'codeql',\n subcommand: 'resolve library-path',\n inputSchema: {\n language: z.string().optional().describe('Programming language to resolve library path for'),\n format: z.enum(['text', 'json', 'betterjson']).optional()\n .describe('Output format for library path information'),\n verbose: z.boolean().optional().describe('Enable verbose output'),\n additionalArgs: z.array(z.string()).optional().describe('Additional command-line arguments')\n },\n examples: [\n 'codeql resolve library-path --language=java',\n 'codeql resolve library-path --format=json --language=python',\n 'codeql resolve library-path --format=betterjson'\n ],\n resultProcessor: defaultCLIResultProcessor\n};", "/**\n * CodeQL resolve metadata tool\n */\n\nimport { z } from 'zod';\nimport { CLIToolDefinition, defaultCLIResultProcessor } from '../../lib/cli-tool-registry';\n\nexport const codeqlResolveMetadataTool: CLIToolDefinition = {\n name: 'codeql_resolve_metadata',\n description: 'Resolve and return the key-value metadata pairs from a CodeQL query source file.',\n command: 'codeql',\n subcommand: 'resolve metadata',\n inputSchema: {\n query: z.string().describe('Query file to resolve metadata for'),\n format: z.enum(['json']).optional()\n .describe('Output format for metadata information (always JSON, optional for future compatibility)'),\n verbose: z.boolean().optional().describe('Enable verbose output'),\n additionalArgs: z.array(z.string()).optional().describe('Additional command-line arguments')\n },\n examples: [\n 'codeql resolve metadata -- relative-path/2/MyQuery.ql',\n 'codeql resolve metadata --format=json -- /absolute-plus/relative-path/2/MyQuery.ql'\n ],\n resultProcessor: defaultCLIResultProcessor\n};", "/**\n * CodeQL resolve qlref tool\n */\n\nimport { z } from 'zod';\nimport { CLIToolDefinition, createCodeQLSchemas, defaultCLIResultProcessor } from '../../lib/cli-tool-registry';\n\nexport const codeqlResolveQlrefTool: CLIToolDefinition = {\n name: 'codeql_resolve_qlref',\n description: 'Resolve qlref files to their corresponding query files',\n command: 'codeql',\n subcommand: 'resolve qlref',\n inputSchema: {\n qlref: z.string().describe('Path to the .qlref file to resolve'),\n format: z.enum(['text', 'json', 'betterjson']).optional()\n .describe('Output format for qlref resolution'),\n verbose: createCodeQLSchemas.verbose(),\n additionalArgs: createCodeQLSchemas.additionalArgs()\n },\n examples: [\n 'codeql resolve qlref -- test/MyQuery.qlref',\n 'codeql resolve qlref --format=json -- test/MyQuery.qlref',\n 'codeql resolve qlref --format=betterjson -- test/MyQuery.qlref'\n ],\n resultProcessor: defaultCLIResultProcessor\n};", "/**\n * CodeQL resolve queries tool\n */\n\nimport { z } from 'zod';\nimport { CLIToolDefinition, createCodeQLSchemas, CLIExecutionResult } from '../../lib/cli-tool-registry';\n\n/**\n * Result processor that only returns stdout for JSON formats\n * This prevents warnings/info from stderr from corrupting JSON output\n */\nconst jsonOnlyResultProcessor = (\n result: CLIExecutionResult,\n params: Record\n): string => {\n if (!result.success) {\n return `Command failed (exit code ${result.exitCode || 'unknown'}):\\n${result.error || result.stderr}`;\n }\n\n // For JSON formats (including bylanguage), only return stdout to avoid mixing warnings with JSON\n if (params.format === 'json' || params.format === 'betterjson' || params.format === 'bylanguage') {\n return result.stdout || '[]';\n }\n\n // For text format, include warnings\n let output = '';\n\n if (result.stdout) {\n output += result.stdout;\n }\n\n if (result.stderr) {\n if (output) {\n output += '\\n\\nWarnings/Info:\\n';\n }\n output += result.stderr;\n }\n\n if (!output) {\n output = 'Command executed successfully (no output)';\n }\n\n return output;\n};\n\nexport const codeqlResolveQueriesTool: CLIToolDefinition = {\n name: 'codeql_resolve_queries',\n description: 'List available CodeQL queries found on the local filesystem',\n command: 'codeql',\n subcommand: 'resolve queries',\n inputSchema: {\n directory: z.string().optional().describe('Directory to search for queries'),\n language: z.string().optional().describe('Filter queries by programming language'),\n format: z.enum(['text', 'json', 'betterjson', 'bylanguage']).optional()\n .describe('Output format for query list'),\n 'additional-packs': z.union([z.string(), z.array(z.string())]).optional()\n .describe('Additional pack directories to search for CodeQL packs'),\n verbose: createCodeQLSchemas.verbose(),\n additionalArgs: createCodeQLSchemas.additionalArgs()\n },\n examples: [\n 'codeql resolve queries',\n 'codeql resolve queries --language=java --format=json',\n 'codeql resolve queries --format=betterjson -- /path/to/queries',\n 'codeql resolve queries --additional-packs=/path/to/packs codeql/java-queries'\n ],\n resultProcessor: jsonOnlyResultProcessor\n};", "/**\n * CodeQL resolve tests tool\n */\n\nimport { z } from 'zod';\nimport { CLIToolDefinition, createCodeQLSchemas, defaultCLIResultProcessor } from '../../lib/cli-tool-registry';\n\nexport const codeqlResolveTestsTool: CLIToolDefinition = {\n name: 'codeql_resolve_tests',\n description: 'Resolve the local filesystem paths of unit tests and/or queries under some base directory',\n command: 'codeql',\n subcommand: 'resolve tests',\n inputSchema: {\n tests: z.array(z.string()).optional().describe('One or more tests (.ql, .qlref files, or test directories)'),\n format: z.enum(['text', 'json']).optional()\n .describe('Output format for test list'),\n verbose: createCodeQLSchemas.verbose(),\n additionalArgs: createCodeQLSchemas.additionalArgs()\n },\n examples: [\n 'codeql resolve tests',\n 'codeql resolve tests --format=json -- test-directory',\n 'codeql resolve tests --format=json -- test1.ql test2.ql'\n ],\n resultProcessor: defaultCLIResultProcessor\n};", "/**\n * CodeQL test accept tool\n */\n\nimport { z } from 'zod';\nimport { CLIToolDefinition, createCodeQLSchemas, defaultCLIResultProcessor } from '../../lib/cli-tool-registry';\n\nexport const codeqlTestAcceptTool: CLIToolDefinition = {\n name: 'codeql_test_accept',\n description: 'Accept new test results as the expected baseline',\n command: 'codeql',\n subcommand: 'test accept',\n inputSchema: {\n tests: z.array(z.string()).describe('One or more tests (.ql, .qlref files, or test directories)'),\n verbose: createCodeQLSchemas.verbose(),\n additionalArgs: createCodeQLSchemas.additionalArgs()\n },\n examples: [\n 'codeql test accept -- languages/java/test/MyQuery/MyQuery.qlref',\n 'codeql test accept -- languages/java/test/MyQuery/',\n 'codeql test accept -- languages/java/src/MyQuery/MyQuery.ql'\n ],\n resultProcessor: defaultCLIResultProcessor\n};", "/**\n * CodeQL test extract tool\n */\n\nimport { z } from 'zod';\nimport { CLIToolDefinition, createCodeQLSchemas, defaultCLIResultProcessor } from '../../lib/cli-tool-registry';\n\nexport const codeqlTestExtractTool: CLIToolDefinition = {\n name: 'codeql_test_extract',\n description: 'Extract test databases for CodeQL query tests',\n command: 'codeql',\n subcommand: 'test extract',\n inputSchema: {\n tests: z.array(z.string()).describe('One or more test directories or files'),\n language: z.string().optional().describe('Programming language for extraction'),\n threads: createCodeQLSchemas.threads(),\n ram: createCodeQLSchemas.ram(),\n verbose: createCodeQLSchemas.verbose(),\n additionalArgs: createCodeQLSchemas.additionalArgs()\n },\n examples: [\n 'codeql test extract -- languages/java/test/MyQuery/',\n 'codeql test extract --language=java --threads=4 -- test-directory',\n 'codeql test extract --threads=2 --ram=2048 -- multiple/test/directories'\n ],\n resultProcessor: defaultCLIResultProcessor\n};", "/**\n * CodeQL test run tool\n */\n\nimport { CLIToolDefinition, createCodeQLSchemas } from '../../lib/cli-tool-registry';\nimport { z } from 'zod';\n\nexport const codeqlTestRunTool: CLIToolDefinition = {\n name: 'codeql_test_run',\n description: 'Run CodeQL query tests',\n command: 'codeql',\n subcommand: 'test run',\n inputSchema: {\n tests: z.array(z.string()).describe('One or more tests (.ql, .qlref files, or test directories)'),\n 'show-extractor-output': z.boolean().optional()\n .describe('Show output from extractors during test execution'),\n 'keep-databases': z.boolean().optional()\n .describe('Keep test databases after running tests'),\n 'learn': z.boolean().optional()\n .describe('Accept current output as expected for failing tests'),\n logDir: z.string().optional()\n .describe('Custom directory for test execution logs (overrides CODEQL_QUERY_LOG_DIR environment variable). If not provided, uses CODEQL_QUERY_LOG_DIR or defaults to .tmp/query-logs/'),\n threads: createCodeQLSchemas.threads(),\n ram: createCodeQLSchemas.ram(),\n verbose: createCodeQLSchemas.verbose(),\n additionalArgs: createCodeQLSchemas.additionalArgs()\n },\n examples: [\n 'codeql test run /path/to/tests',\n 'codeql test run --learn /path/to/failing/tests',\n 'codeql test run --threads=4 --keep-databases /path/to/tests',\n 'codeql test run --log-dir=/custom/log/path /path/to/tests'\n ]\n};", "/**\n * CodeQL tools registration for MCP server\n * Includes both high-level helpers and CLI command wrappers\n */\n\nimport { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport { z } from 'zod';\nimport { validateCodeQLSyntax } from '../lib/validation';\nimport { createCodeQLQuery } from '../lib/query-scaffolding';\nimport { registerCLITool } from '../lib/cli-tool-registry';\nimport {\n codeqlBqrsDecodeTool,\n codeqlBqrsInfoTool,\n codeqlBqrsInterpretTool,\n codeqlDatabaseAnalyzeTool,\n codeqlDatabaseCreateTool,\n codeqlGenerateLogSummaryTool,\n codeqlGenerateQueryHelpTool,\n codeqlPackInstallTool,\n codeqlPackLsTool,\n codeqlQueryCompileTool,\n codeqlQueryFormatTool,\n codeqlQueryRunTool,\n codeqlResolveDatabaseTool,\n codeqlResolveLanguagesTool,\n codeqlResolveLibraryPathTool,\n codeqlResolveMetadataTool,\n codeqlResolveQlrefTool,\n codeqlResolveQueriesTool,\n codeqlResolveTestsTool,\n codeqlTestAcceptTool,\n codeqlTestExtractTool,\n codeqlTestRunTool,\n registerFindClassPositionTool,\n registerFindCodeQLQueryFilesTool,\n registerFindPredicatePositionTool,\n registerListDatabasesTool,\n registerListMrvaRunResultsTool,\n registerListQueryRunResultsTool,\n registerProfileCodeQLQueryFromLogsTool,\n registerProfileCodeQLQueryTool,\n registerQuickEvaluateTool,\n registerRegisterDatabaseTool\n} from './codeql';\nimport { logger } from '../utils/logger';\n\n/**\n * Register all CodeQL tools with the MCP server\n */\nexport function registerCodeQLTools(server: McpServer): void {\n // Register high-level helper tools\n \n // Tool: Validate CodeQL Query (heuristic-based)\n server.tool(\n 'validate_codeql_query',\n 'Quick heuristic validation for CodeQL query structure - checks for common patterns like from/where/select clauses and metadata presence. Does NOT compile the query. For authoritative validation with actual compilation, use codeql_lsp_diagnostics instead.',\n {\n query: z.string().describe('The CodeQL query to validate'),\n language: z.string().optional().describe('Target programming language'),\n },\n async ({ query, language }) => {\n try {\n const validation = validateCodeQLSyntax(query, language);\n return {\n content: [{ type: 'text', text: JSON.stringify(validation, null, 2) }],\n };\n } catch (error) {\n logger.error('Error validating CodeQL query:', error);\n return {\n content: [\n {\n type: 'text',\n text: `Error: ${error instanceof Error ? error.message : 'Unknown error'}`,\n },\n ],\n isError: true,\n };\n }\n }\n );\n\n // Tool: Create CodeQL Query\n server.tool(\n 'create_codeql_query',\n 'Create directory structure and files for a new CodeQL query with tests',\n {\n basePath: z.string().describe('Base path where src/ and test/ directories will be created'),\n queryName: z.string().describe('Name of the query (e.g., MySecurityQuery)'),\n language: z.string().describe('Target programming language (e.g., javascript, python, java)'),\n description: z.string().optional().describe('Description of what the query does'),\n queryId: z.string().optional().describe('Custom query ID (defaults to language/example/queryname)'),\n },\n async ({ basePath, queryName, language, description, queryId }) => {\n try {\n const result = createCodeQLQuery({\n basePath,\n queryName,\n language,\n description,\n queryId\n });\n \n const summary = {\n success: true,\n queryPath: result.queryPath,\n testPath: result.testPath,\n qlrefPath: result.qlrefPath,\n testCodePath: result.testCodePath,\n filesCreated: result.filesCreated,\n nextSteps: [\n 'Review and customize the generated query in: ' + result.queryPath,\n 'Add test cases to: ' + result.testCodePath,\n 'Run codeql_pack_install to install dependencies',\n 'Run codeql_test_extract to create test database',\n 'Run codeql_test_run to execute tests'\n ]\n };\n \n return {\n content: [{ type: 'text', text: JSON.stringify(summary, null, 2) }],\n };\n } catch (error) {\n logger.error('Error creating CodeQL query:', error);\n return {\n content: [\n {\n type: 'text',\n text: `Error: ${error instanceof Error ? error.message : 'Unknown error'}`,\n },\n ],\n isError: true,\n };\n }\n }\n );\n\n // Register CLI tools (alphabetically by tool name)\n registerCLITool(server, codeqlBqrsDecodeTool);\n registerCLITool(server, codeqlBqrsInfoTool);\n registerCLITool(server, codeqlBqrsInterpretTool);\n registerCLITool(server, codeqlDatabaseAnalyzeTool);\n registerCLITool(server, codeqlDatabaseCreateTool);\n registerCLITool(server, codeqlGenerateLogSummaryTool);\n registerCLITool(server, codeqlGenerateQueryHelpTool);\n registerCLITool(server, codeqlPackInstallTool);\n registerCLITool(server, codeqlPackLsTool);\n registerCLITool(server, codeqlQueryCompileTool);\n registerCLITool(server, codeqlQueryFormatTool);\n registerCLITool(server, codeqlQueryRunTool);\n registerCLITool(server, codeqlResolveDatabaseTool);\n registerCLITool(server, codeqlResolveLanguagesTool);\n registerCLITool(server, codeqlResolveLibraryPathTool);\n registerCLITool(server, codeqlResolveMetadataTool);\n registerCLITool(server, codeqlResolveQlrefTool);\n registerCLITool(server, codeqlResolveQueriesTool);\n registerCLITool(server, codeqlResolveTestsTool);\n registerCLITool(server, codeqlTestAcceptTool);\n registerCLITool(server, codeqlTestExtractTool);\n registerCLITool(server, codeqlTestRunTool);\n\n // Register new MCP tools (inspired by JordyZomer/codeql-mcp repository)\n registerFindClassPositionTool(server);\n registerFindCodeQLQueryFilesTool(server);\n registerFindPredicatePositionTool(server);\n registerListDatabasesTool(server);\n registerListMrvaRunResultsTool(server);\n registerListQueryRunResultsTool(server);\n registerProfileCodeQLQueryFromLogsTool(server);\n registerProfileCodeQLQueryTool(server);\n registerQuickEvaluateTool(server);\n registerRegisterDatabaseTool(server);\n}\n", "/**\n * CodeQL query validation utilities\n */\n\nimport { resolve, normalize, isAbsolute, relative } from 'path';\n\nexport interface CodeQLValidationResult {\n isValid: boolean;\n errors: string[];\n warnings: string[];\n suggestions: string[];\n}\n\n/**\n * Validates CodeQL query syntax and structure\n */\nexport function validateCodeQLSyntax(query: string, _language?: string): CodeQLValidationResult {\n const validation: CodeQLValidationResult = {\n isValid: true,\n errors: [],\n warnings: [],\n suggestions: [],\n };\n\n if (!query.trim()) {\n validation.isValid = false;\n validation.errors.push('Query cannot be empty');\n return validation;\n }\n\n if (!query.includes('from') && !query.includes('select')) {\n validation.warnings.push('Query should typically include \"from\" and \"select\" clauses');\n }\n\n if (!query.includes('@name') && !query.includes('@description')) {\n validation.suggestions.push('Consider adding @name and @description metadata');\n }\n\n return validation;\n}\n\n/**\n * Validates a file path to prevent path traversal attacks\n * @param filePath - The file path to validate\n * @param workspaceRoot - Optional workspace root directory. If not provided, allows any absolute path but still blocks traversal attempts\n * @returns The validated absolute path\n * @throws Error if the path contains path traversal sequences\n */\nexport function validateFilePath(filePath: string, workspaceRoot?: string): string {\n // Normalize the path to resolve any . or .. segments\n const normalizedPath = normalize(filePath);\n \n // Check for path traversal attempts in the normalized path\n // This blocks paths like \"../../../etc/passwd\" even after normalization\n if (normalizedPath.includes('..')) {\n throw new Error(`Invalid file path: path traversal detected in \"${filePath}\"`);\n }\n \n // Resolve to absolute path\n const absolutePath = isAbsolute(normalizedPath) \n ? normalizedPath \n : resolve(workspaceRoot || process.cwd(), normalizedPath);\n \n // If workspace root is specified, ensure the resolved path is within it\n if (workspaceRoot) {\n const relativePath = relative(workspaceRoot, absolutePath);\n \n // If relative path starts with .. or is absolute, it's outside workspace\n if (relativePath.startsWith('..') || isAbsolute(relativePath)) {\n throw new Error(`Invalid file path: \"${filePath}\" is outside the workspace root`);\n }\n }\n \n return absolutePath;\n}", "/**\n * CodeQL query scaffolding utilities\n * Handles creation of query directory structure and files\n */\n\nimport * as fs from 'fs';\nimport * as path from 'path';\n\nexport interface QueryScaffoldingOptions {\n basePath: string;\n queryName: string;\n language: string;\n description?: string;\n queryId?: string;\n}\n\nexport interface QueryScaffoldingResult {\n queryPath: string;\n testPath: string;\n qlrefPath: string;\n testCodePath: string;\n filesCreated: string[];\n}\n\n/**\n * Get the file extension for test code based on language\n */\nfunction getLanguageExtension(language: string): string {\n const extensions: Record = {\n javascript: 'js',\n typescript: 'ts',\n python: 'py',\n java: 'java',\n csharp: 'cs',\n cpp: 'cpp',\n go: 'go',\n ruby: 'rb',\n actions: 'yml'\n };\n return extensions[language.toLowerCase()] || 'txt';\n}\n\n/**\n * Generate query template content\n */\nfunction generateQueryTemplate(\n queryName: string,\n language: string,\n description?: string,\n queryId?: string\n): string {\n const desc = description || `${queryName} query`;\n const id = queryId || `${language}/example/${queryName.toLowerCase()}`;\n \n return `/**\n * @id ${id}\n * @name ${queryName}\n * @description ${desc}\n * @kind problem\n * @precision medium\n * @problem.severity warning\n */\n\nimport ${language}\n\n// TODO: Implement query logic\nfrom File f\nwhere f.getBaseName() = \"${queryName}.${getLanguageExtension(language)}\"\nselect f, \"TODO: Add query logic\"\n`;\n}\n\n/**\n * Create the directory structure and files for a new CodeQL query\n */\nexport function createCodeQLQuery(options: QueryScaffoldingOptions): QueryScaffoldingResult {\n const { basePath, queryName, language, description, queryId } = options;\n \n // Resolve absolute paths\n const absoluteBasePath = path.resolve(basePath);\n \n // Define paths with intermediate directory\n const srcDir = path.join(absoluteBasePath, 'src', queryName);\n const testDir = path.join(absoluteBasePath, 'test', queryName);\n \n const queryPath = path.join(srcDir, `${queryName}.ql`);\n const qlrefPath = path.join(testDir, `${queryName}.qlref`);\n const testCodePath = path.join(testDir, `${queryName}.${getLanguageExtension(language)}`);\n \n const filesCreated: string[] = [];\n \n try {\n // Create directories (recursive: true is a no-op if they already exist)\n fs.mkdirSync(srcDir, { recursive: true });\n fs.mkdirSync(testDir, { recursive: true });\n \n // Create files atomically using 'wx' flag (exclusive create) to avoid\n // TOCTOU race between existsSync check and writeFileSync (CWE-367).\n // The 'wx' flag fails with EEXIST if the file already exists.\n try {\n const queryContent = generateQueryTemplate(queryName, language, description, queryId);\n fs.writeFileSync(queryPath, queryContent, { encoding: 'utf8', flag: 'wx' });\n filesCreated.push(queryPath);\n } catch (e: unknown) {\n const err = e as { code?: string };\n if (err.code !== 'EEXIST') throw e;\n }\n \n try {\n const qlrefContent = `${queryName}/${queryName}.ql\\n`;\n fs.writeFileSync(qlrefPath, qlrefContent, { encoding: 'utf8', flag: 'wx' });\n filesCreated.push(qlrefPath);\n } catch (e: unknown) {\n const err = e as { code?: string };\n if (err.code !== 'EEXIST') throw e;\n }\n \n try {\n const testCodeContent = `// Test code for ${queryName}\\n// TODO: Add test cases\\n`;\n fs.writeFileSync(testCodePath, testCodeContent, { encoding: 'utf8', flag: 'wx' });\n filesCreated.push(testCodePath);\n } catch (e: unknown) {\n const err = e as { code?: string };\n if (err.code !== 'EEXIST') throw e;\n }\n \n return {\n queryPath,\n testPath: testDir,\n qlrefPath,\n testCodePath,\n filesCreated\n };\n } catch (error) {\n throw new Error(`Failed to create query scaffolding: ${error instanceof Error ? error.message : 'Unknown error'}`, { cause: error });\n }\n}\n", "/**\n * CodeQL learning resources utilities\n */\n\nimport { readFileSync } from 'fs';\nimport { join, dirname } from 'path';\nimport { fileURLToPath } from 'url';\n\nconst __filename = fileURLToPath(import.meta.url);\nconst __dirname = dirname(__filename);\n\n/**\n * Get the getting started guide content\n */\nexport function getGettingStartedGuide(): string {\n try {\n return readFileSync(join(__dirname, '../resources/getting-started.md'), 'utf-8');\n } catch {\n return 'Getting started guide not available';\n }\n}\n\n/**\n * Get the query basics guide content\n */\nexport function getQueryBasicsGuide(): string {\n try {\n return readFileSync(join(__dirname, '../resources/query-basics.md'), 'utf-8');\n } catch {\n return 'Query basics guide not available';\n }\n}\n\n/**\n * Get the security templates content\n */\nexport function getSecurityTemplates(): string {\n try {\n return readFileSync(join(__dirname, '../resources/security-templates.md'), 'utf-8');\n } catch {\n return 'Security templates not available';\n }\n}\n\n/**\n * Get the performance patterns content\n */\nexport function getPerformancePatterns(): string {\n try {\n return readFileSync(join(__dirname, '../resources/performance-patterns.md'), 'utf-8');\n } catch {\n return 'Performance patterns not available';\n }\n}", "/**\n * CodeQL resources registration for MCP server\n */\n\nimport { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport {\n getGettingStartedGuide,\n getQueryBasicsGuide,\n getSecurityTemplates,\n getPerformancePatterns,\n} from '../lib/resources';\n\n/**\n * Register all CodeQL resources with the MCP server\n */\nexport function registerCodeQLResources(server: McpServer): void {\n // Getting Started Guide\n server.resource(\n 'CodeQL Getting Started',\n 'codeql://learning/getting-started',\n {\n description: 'Comprehensive introduction to CodeQL for beginners',\n mimeType: 'text/markdown',\n },\n async () => {\n return {\n contents: [\n {\n uri: 'codeql://learning/getting-started',\n mimeType: 'text/markdown',\n text: getGettingStartedGuide(),\n },\n ],\n };\n }\n );\n\n // Query Basics Guide\n server.resource(\n 'CodeQL Query Basics',\n 'codeql://learning/query-basics',\n {\n description: 'Learn the fundamentals of writing CodeQL queries',\n mimeType: 'text/markdown',\n },\n async () => {\n return {\n contents: [\n {\n uri: 'codeql://learning/query-basics',\n mimeType: 'text/markdown',\n text: getQueryBasicsGuide(),\n },\n ],\n };\n }\n );\n\n // Security Templates\n server.resource(\n 'CodeQL Security Templates',\n 'codeql://templates/security',\n {\n description: 'Ready-to-use security query templates',\n mimeType: 'text/markdown',\n },\n async () => {\n return {\n contents: [\n {\n uri: 'codeql://templates/security',\n mimeType: 'text/markdown',\n text: getSecurityTemplates(),\n },\n ],\n };\n }\n );\n\n // Performance Patterns\n server.resource(\n 'CodeQL Performance Patterns',\n 'codeql://patterns/performance',\n {\n description: 'Best practices for writing efficient CodeQL queries',\n mimeType: 'text/markdown',\n },\n async () => {\n return {\n contents: [\n {\n uri: 'codeql://patterns/performance',\n mimeType: 'text/markdown',\n text: getPerformancePatterns(),\n },\n ],\n };\n }\n );\n}\n", "/**\n * CodeQL LSP Diagnostics tool for MCP server.\n *\n * Provides real-time QL code validation through LSP communication.\n * Renamed from `codeql_language_server_eval` to `codeql_lsp_diagnostics`\n * for consistency with the `codeql_lsp_*` tool naming convention.\n */\n\nimport { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport { z } from 'zod';\nimport { Diagnostic, LanguageServerOptions } from '../../lib/language-server';\nimport { logger } from '../../utils/logger';\nimport { getProjectTmpDir } from '../../utils/temp-dir';\nimport { join } from 'path';\nimport { pathToFileURL } from 'url';\nimport { getInitializedLanguageServer } from './lsp-server-helper';\n\nexport interface LspDiagnosticsParams {\n qlCode: string;\n serverOptions?: LanguageServerOptions;\n workspaceUri?: string;\n}\n\nexport interface LspDiagnosticsResult {\n diagnostics: Diagnostic[];\n formattedOutput: string;\n isValid: boolean;\n summary: {\n errorCount: number;\n hintCount: number;\n infoCount: number;\n warningCount: number;\n };\n}\n\n/**\n * Format diagnostics for human-readable output.\n */\nfunction formatDiagnostics(diagnostics: Diagnostic[]): string {\n if (diagnostics.length === 0) {\n return '\u2705 No issues found in QL code';\n }\n\n const lines: string[] = [];\n lines.push(`Found ${diagnostics.length} issue(s):\\n`);\n\n diagnostics.forEach((diagnostic, index) => {\n const severityIcon = getSeverityIcon(diagnostic.severity);\n const severityName = getSeverityName(diagnostic.severity);\n const location = `Line ${diagnostic.range.start.line + 1}, Column ${diagnostic.range.start.character + 1}`;\n\n lines.push(`${index + 1}. ${severityIcon} ${severityName} at ${location}`);\n lines.push(` ${diagnostic.message}`);\n if (diagnostic.source) {\n lines.push(` Source: ${diagnostic.source}`);\n }\n if (diagnostic.code) {\n lines.push(` Code: ${diagnostic.code}`);\n }\n lines.push('');\n });\n\n return lines.join('\\n');\n}\n\nfunction getSeverityIcon(severity: number): string {\n switch (severity) {\n case 1: return '\u274C'; // Error\n case 2: return '\u26A0\uFE0F'; // Warning\n case 3: return '\u2139\uFE0F'; // Information\n case 4: return '\uD83D\uDCA1'; // Hint\n default: return '\u2753';\n }\n}\n\nfunction getSeverityName(severity: number): string {\n switch (severity) {\n case 1: return 'Error';\n case 2: return 'Warning';\n case 3: return 'Information';\n case 4: return 'Hint';\n default: return 'Unknown';\n }\n}\n\n/**\n * Evaluate QL code using the CodeQL Language Server and return diagnostics.\n */\nexport async function lspDiagnostics({\n qlCode,\n workspaceUri,\n serverOptions = {}\n}: LspDiagnosticsParams): Promise {\n try {\n logger.info('Evaluating QL code via Language Server...');\n\n const languageServer = await getInitializedLanguageServer({\n serverOptions,\n workspaceUri,\n });\n\n // Generate unique URI for this evaluation\n const evalUri = pathToFileURL(join(getProjectTmpDir('lsp-eval'), `eval_${Date.now()}.ql`)).href;\n\n const diagnostics = await languageServer.evaluateQL(qlCode, evalUri);\n\n // Count diagnostics by severity\n const summary = {\n errorCount: diagnostics.filter(d => d.severity === 1).length,\n hintCount: diagnostics.filter(d => d.severity === 4).length,\n infoCount: diagnostics.filter(d => d.severity === 3).length,\n warningCount: diagnostics.filter(d => d.severity === 2).length,\n };\n\n const isValid = summary.errorCount === 0;\n const formattedOutput = formatDiagnostics(diagnostics);\n\n logger.info(`QL evaluation complete. Valid: ${isValid}, Issues: ${diagnostics.length}`);\n\n return {\n diagnostics,\n formattedOutput,\n isValid,\n summary,\n };\n\n } catch (error) {\n logger.error('Error evaluating QL code:', error);\n throw new Error(`QL evaluation failed: ${error instanceof Error ? error.message : 'Unknown error'}`, { cause: error });\n }\n}\n\n/**\n * Shutdown the language server via the server manager.\n */\nexport async function shutdownDiagnosticsServer(): Promise {\n const { getServerManager } = await import('../../lib/server-manager');\n const manager = getServerManager();\n await manager.shutdownServer('language');\n}\n\n/**\n * Register the codeql_lsp_diagnostics tool with the MCP server.\n */\nexport function registerLspDiagnosticsTool(server: McpServer): void {\n server.tool(\n 'codeql_lsp_diagnostics',\n 'Authoritative syntax and semantic validation of CodeQL (QL) code via the CodeQL Language Server. Compiles the query and provides real-time diagnostics with precise error locations. Use this for accurate validation; for quick heuristic checks without compilation, use validate_codeql_query instead. Note: inline ql_code is evaluated as a virtual document and cannot resolve pack imports (e.g. `import javascript`). For validating queries with imports, use codeql_query_compile on the actual file instead.',\n {\n log_level: z.enum(['OFF', 'ERROR', 'WARN', 'INFO', 'DEBUG', 'TRACE', 'ALL']).optional().describe('Language server log level'),\n ql_code: z.string().describe('The CodeQL (QL) code to evaluate for syntax and semantic errors'),\n search_path: z.string().optional().describe('Optional search path for CodeQL libraries'),\n workspace_uri: z.string().optional().describe('Optional workspace URI for context (defaults to ./ql directory)'),\n },\n async ({ ql_code, workspace_uri, search_path, log_level }) => {\n try {\n const serverOptions: LanguageServerOptions = {};\n\n if (search_path) {\n serverOptions.searchPath = search_path;\n }\n if (log_level) {\n serverOptions.loglevel = log_level;\n }\n\n const result = await lspDiagnostics({\n qlCode: ql_code,\n serverOptions,\n workspaceUri: workspace_uri,\n });\n\n // Return structured result\n const responseContent = {\n diagnostics: result.diagnostics.map(d => ({\n code: d.code,\n column: d.range.start.character + 1, // Convert to 1-based column numbers\n line: d.range.start.line + 1, // Convert to 1-based line numbers\n message: d.message,\n severity: getSeverityName(d.severity),\n source: d.source,\n })),\n formattedOutput: result.formattedOutput,\n isValid: result.isValid,\n summary: result.summary,\n };\n\n return {\n content: [\n {\n text: JSON.stringify(responseContent, null, 2),\n type: 'text',\n }\n ],\n };\n\n } catch (error) {\n logger.error('Error in codeql_lsp_diagnostics tool:', error);\n return {\n content: [\n {\n text: `Error: ${error instanceof Error ? error.message : 'Unknown error'}`,\n type: 'text',\n },\n ],\n isError: true,\n };\n }\n }\n );\n\n // NOTE: Cleanup is handled centrally by shutdownServerManager() in\n // codeql-development-mcp-server.ts (setupGracefulShutdown). Registering\n // additional process.on('SIGINT'/'SIGTERM') handlers here would\n // accumulate on repeated calls and is unnecessary.\n}\n", "/**\n * Shared helper for obtaining a running, initialized CodeQL Language Server.\n *\n * Both `lsp-diagnostics.ts` and `lsp-handlers.ts` need to:\n * 1. Build a `LanguageServerConfig` with sensible defaults\n * 2. Obtain a server instance from the `CodeQLServerManager`\n * 3. Resolve a workspace URI (relative \u2192 absolute \u2192 `file://`)\n * 4. Initialize the server with the resolved workspace\n *\n * Centralizing this logic avoids duplication and ensures consistent\n * default behaviour across all LSP tools.\n */\n\nimport { isAbsolute, resolve } from 'path';\nimport { pathToFileURL } from 'url';\n\nimport { CodeQLLanguageServer, LanguageServerOptions } from '../../lib/language-server';\nimport { LanguageServerConfig } from '../../lib/server-config';\nimport { getServerManager } from '../../lib/server-manager';\nimport { logger } from '../../utils/logger';\n\n/**\n * Options accepted by {@link getInitializedLanguageServer}.\n */\nexport interface InitializedServerOptions {\n /** Language-server-level options (loglevel, searchPath, etc.). */\n serverOptions?: LanguageServerOptions;\n /** Workspace URI \u2014 may be a `file://` URI, absolute path, or relative path. */\n workspaceUri?: string;\n}\n\n/**\n * Return a running, initialized `CodeQLLanguageServer`.\n *\n * - Resolves `searchPath` to the bundled `ql` directory when not provided.\n * - Converts relative / bare-directory `workspaceUri` paths to `file://` URIs\n * resolved against `getUserWorkspaceDir()` (respects `CODEQL_MCP_WORKSPACE`).\n * - Falls back to the bundled `ql` directory when no workspace is given.\n * - Delegates lifecycle management to the global `CodeQLServerManager`.\n */\nexport async function getInitializedLanguageServer(\n opts: InitializedServerOptions = {},\n): Promise {\n const { packageRootDir: pkgRoot, getUserWorkspaceDir } = await import('../../utils/package-paths');\n const options = opts.serverOptions ?? {};\n\n const config: LanguageServerConfig = {\n checkErrors: 'ON_CHANGE',\n loglevel: options.loglevel ?? 'WARN',\n searchPath: options.searchPath ?? resolve(pkgRoot, 'ql'),\n synchronous: options.synchronous,\n verbosity: options.verbosity,\n };\n\n const manager = getServerManager();\n const server = await manager.getLanguageServer(config);\n\n // Normalize workspace URI: convert relative / bare directory paths to\n // file:// URIs against getUserWorkspaceDir() (respects CODEQL_MCP_WORKSPACE).\n let effectiveUri = opts.workspaceUri;\n if (effectiveUri && !effectiveUri.startsWith('file://')) {\n const absWorkspace = isAbsolute(effectiveUri)\n ? effectiveUri\n : resolve(getUserWorkspaceDir(), effectiveUri);\n effectiveUri = pathToFileURL(absWorkspace).href;\n }\n effectiveUri = effectiveUri ?? pathToFileURL(resolve(pkgRoot, 'ql')).href;\n\n await server.initialize(effectiveUri);\n logger.debug(`Language server initialized with workspace: ${effectiveUri}`);\n\n return server;\n}\n", "/**\n * CodeQL LSP tool handlers.\n *\n * Bridges MCP tool invocations to LSP requests on the CodeQL Language Server.\n * Each handler acquires a language server via the CodeQLServerManager,\n * opens the requested document, sends the LSP request, and returns the result.\n */\n\nimport { readFile } from 'fs/promises';\nimport { isAbsolute, resolve } from 'path';\nimport { pathToFileURL } from 'url';\n\nimport {\n CompletionItem,\n LSPLocation,\n TextDocumentPositionParams,\n} from '../../lib/language-server';\nimport { logger } from '../../utils/logger';\nimport { getUserWorkspaceDir } from '../../utils/package-paths';\nimport { getInitializedLanguageServer } from './lsp-server-helper';\n\n/**\n * Common parameters for LSP tool invocations.\n */\nexport interface LSPToolParams {\n /** 0-based character offset within the line. */\n character: number;\n /** Optional override for the file content (if not reading from disk). */\n fileContent?: string;\n /**\n * Path to the QL file. May be absolute or relative.\n * Relative paths are resolved against `getUserWorkspaceDir()`\n * (respects the `CODEQL_MCP_WORKSPACE` environment variable).\n */\n filePath: string;\n /** 0-based line number in the document. */\n line: number;\n /** Optional search path for CodeQL libraries. */\n searchPath?: string;\n /** Optional workspace URI for context. */\n workspaceUri?: string;\n}\n\n/**\n * Get a running, initialized language server for the given parameters.\n */\nasync function getInitializedServer(params: LSPToolParams) {\n return getInitializedLanguageServer({\n serverOptions: { searchPath: params.searchPath },\n workspaceUri: params.workspaceUri,\n });\n}\n\n/**\n * Resolve the file path to an absolute path and file:// URI.\n */\nfunction prepareDocumentPosition(\n params: LSPToolParams,\n): { absPath: string; docUri: string } {\n // Resolve relative paths against getUserWorkspaceDir() so that\n // CODEQL_MCP_WORKSPACE is respected and behaviour is consistent across tools.\n const absPath = isAbsolute(params.filePath)\n ? params.filePath\n : resolve(getUserWorkspaceDir(), params.filePath);\n const docUri = pathToFileURL(absPath).href;\n\n return { absPath, docUri };\n}\n\n/**\n * Read file content and open the document in the language server.\n */\nasync function openDocumentForPosition(\n server: Awaited>,\n params: LSPToolParams,\n absPath: string,\n docUri: string,\n): Promise {\n // Read file content from disk or use provided content\n let text: string;\n if (params.fileContent) {\n text = params.fileContent;\n } else {\n try {\n text = await readFile(absPath, 'utf-8');\n } catch (error) {\n throw new Error(`Cannot read file: ${absPath}: ${error instanceof Error ? error.message : error}`, { cause: error });\n }\n }\n\n // Open the document so the language server knows about it\n server.openDocument(docUri, text);\n\n return {\n position: { character: params.character, line: params.line },\n textDocument: { uri: docUri },\n };\n}\n\n/**\n * Get code completions at a position.\n */\nexport async function lspCompletion(params: LSPToolParams): Promise {\n logger.info(`LSP completion at ${params.filePath}:${params.line}:${params.character}`);\n const server = await getInitializedServer(params);\n const { absPath, docUri } = prepareDocumentPosition(params);\n const positionParams = await openDocumentForPosition(server, params, absPath, docUri);\n\n try {\n return await server.getCompletions(positionParams);\n } finally {\n server.closeDocument(docUri);\n }\n}\n\n/**\n * Go to definition of a symbol at a position.\n */\nexport async function lspDefinition(params: LSPToolParams): Promise {\n logger.info(`LSP definition at ${params.filePath}:${params.line}:${params.character}`);\n const server = await getInitializedServer(params);\n const { absPath, docUri } = prepareDocumentPosition(params);\n const positionParams = await openDocumentForPosition(server, params, absPath, docUri);\n\n try {\n return await server.getDefinition(positionParams);\n } finally {\n server.closeDocument(docUri);\n }\n}\n\n/**\n * Find all references to a symbol at a position.\n */\nexport async function lspReferences(params: LSPToolParams): Promise {\n logger.info(`LSP references at ${params.filePath}:${params.line}:${params.character}`);\n const server = await getInitializedServer(params);\n const { absPath, docUri } = prepareDocumentPosition(params);\n const positionParams = await openDocumentForPosition(server, params, absPath, docUri);\n\n try {\n return await server.getReferences({\n ...positionParams,\n context: { includeDeclaration: true },\n });\n } finally {\n server.closeDocument(docUri);\n }\n}\n", "/**\n * CodeQL LSP MCP tool definitions.\n *\n * Registers four LSP-based tools:\n * - codeql_lsp_completion \u2013 code completions at cursor position\n * - codeql_lsp_definition \u2013 go to definition\n * - codeql_lsp_diagnostics \u2013 QL code validation via LSP diagnostics\n * - codeql_lsp_references \u2013 find all references\n */\n\nimport { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport { z } from 'zod';\nimport { registerLspDiagnosticsTool } from './lsp-diagnostics';\nimport {\n lspCompletion,\n lspDefinition,\n lspReferences,\n} from './lsp-handlers';\nimport { logger } from '../../utils/logger';\n\n/**\n * Shared Zod schema for the common LSP tool parameters.\n */\nconst lspParamsSchema = {\n character: z.number().int().min(0).describe('0-based character offset within the line'),\n file_content: z.string().optional().describe('Optional file content override (reads from disk if omitted)'),\n file_path: z.string().describe('Path to the CodeQL (.ql/.qll) file. Relative paths are resolved against the user workspace directory (see CODEQL_MCP_WORKSPACE).'),\n line: z.number().int().min(0).describe('0-based line number in the document'),\n search_path: z.string().optional().describe('Optional search path for CodeQL libraries'),\n workspace_uri: z.string().optional().describe('Optional workspace URI for context (defaults to ./ql directory)'),\n};\n\n/**\n * Helper to build the handler params from the raw MCP tool input.\n */\nfunction toHandlerParams(input: {\n character: number;\n file_content?: string;\n file_path: string;\n line: number;\n search_path?: string;\n workspace_uri?: string;\n}) {\n return {\n character: input.character,\n fileContent: input.file_content,\n filePath: input.file_path,\n line: input.line,\n searchPath: input.search_path,\n workspaceUri: input.workspace_uri,\n };\n}\n\n/**\n * Register all LSP-based tools with the MCP server.\n */\nexport function registerLSPTools(server: McpServer): void {\n // --- codeql_lsp_diagnostics (relocated from codeql_language_server_eval) ---\n registerLspDiagnosticsTool(server);\n\n // --- codeql_lsp_completion ---\n server.tool(\n 'codeql_lsp_completion',\n 'Get code completions at a cursor position in a CodeQL file. Returns completion items with labels, documentation, and insert text. The file must be a .ql or .qll file. IMPORTANT: Set workspace_uri to the pack or workspace root directory for dependency resolution; without it, completions for imported libraries will be empty.',\n lspParamsSchema,\n async (input) => {\n try {\n const items = await lspCompletion(toHandlerParams(input));\n return {\n content: [{\n text: JSON.stringify({\n completionCount: items.length,\n items: items.map((item) => ({\n detail: item.detail,\n documentation: item.documentation,\n insertText: item.insertText,\n kind: item.kind,\n label: item.label,\n })),\n }, null, 2),\n type: 'text' as const,\n }],\n };\n } catch (error) {\n logger.error('codeql_lsp_completion error:', error);\n return {\n content: [{ text: `Error: ${error instanceof Error ? error.message : 'Unknown error'}`, type: 'text' as const }],\n isError: true,\n };\n }\n },\n );\n\n // --- codeql_lsp_definition ---\n server.tool(\n 'codeql_lsp_definition',\n 'Go to the definition of a CodeQL symbol at a given position. Returns one or more file locations where the symbol is defined. Set workspace_uri to the pack root for dependency resolution.',\n lspParamsSchema,\n async (input) => {\n try {\n const locations = await lspDefinition(toHandlerParams(input));\n return {\n content: [{\n text: JSON.stringify({\n definitionCount: locations.length,\n locations: locations.map((loc) => ({\n endCharacter: loc.range.end.character,\n endLine: loc.range.end.line + 1,\n startCharacter: loc.range.start.character,\n startLine: loc.range.start.line + 1,\n uri: loc.uri,\n })),\n }, null, 2),\n type: 'text' as const,\n }],\n };\n } catch (error) {\n logger.error('codeql_lsp_definition error:', error);\n return {\n content: [{ text: `Error: ${error instanceof Error ? error.message : 'Unknown error'}`, type: 'text' as const }],\n isError: true,\n };\n }\n },\n );\n\n // --- codeql_lsp_references ---\n server.tool(\n 'codeql_lsp_references',\n 'Find all references to a CodeQL symbol at a given position. Returns file locations of all usages, including the declaration. Set workspace_uri to the pack root for dependency resolution.',\n lspParamsSchema,\n async (input) => {\n try {\n const locations = await lspReferences(toHandlerParams(input));\n return {\n content: [{\n text: JSON.stringify({\n locations: locations.map((loc) => ({\n endCharacter: loc.range.end.character,\n endLine: loc.range.end.line + 1,\n startCharacter: loc.range.start.character,\n startLine: loc.range.start.line + 1,\n uri: loc.uri,\n })),\n referenceCount: locations.length,\n }, null, 2),\n type: 'text' as const,\n }],\n };\n } catch (error) {\n logger.error('codeql_lsp_references error:', error);\n return {\n content: [{ text: `Error: ${error instanceof Error ? error.message : 'Unknown error'}`, type: 'text' as const }],\n isError: true,\n };\n }\n },\n );\n}\n", "/**\n * Language-specific resources implementation\n * Dynamically loads and serves language-specific AST references and security patterns\n */\n\nimport { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport { readFileSync, existsSync } from 'fs';\nimport { join } from 'path';\nimport { LANGUAGE_RESOURCES } from '../types/language-types';\nimport { workspaceRootDir } from '../utils/package-paths';\nimport { logger } from '../utils/logger';\n\n/**\n * Get the base path for ql resources.\n * Uses the workspace root (monorepo root or package root) so that\n * resource files are found regardless of the server's process.cwd().\n */\nfunction getQLBasePath(): string {\n return workspaceRootDir;\n}\n\n/**\n * Load content from a resource file\n */\nfunction loadResourceContent(relativePath: string): string | null {\n try {\n const fullPath = join(getQLBasePath(), relativePath);\n \n if (!existsSync(fullPath)) {\n logger.warn(`Resource file not found: ${fullPath}`);\n return null;\n }\n \n return readFileSync(fullPath, 'utf-8');\n } catch (error) {\n logger.error(`Error loading resource file ${relativePath}:`, error);\n return null;\n }\n}\n\n/**\n * Register language-specific AST resources\n */\nexport function registerLanguageASTResources(server: McpServer): void {\n for (const langResource of LANGUAGE_RESOURCES) {\n if (!langResource.astFile) continue;\n \n const resourceUri = `codeql://languages/${langResource.language}/ast`;\n \n server.resource(\n `${langResource.language.toUpperCase()} AST Reference`,\n resourceUri,\n {\n description: `CodeQL AST class reference for ${langResource.language} programs`,\n mimeType: 'text/markdown'\n },\n async () => {\n const content = loadResourceContent(langResource.astFile!);\n \n if (!content) {\n return {\n contents: [{\n uri: resourceUri,\n mimeType: 'text/markdown',\n text: `# ${langResource.language.toUpperCase()} AST Reference\\n\\nResource file not found or could not be loaded.`\n }]\n };\n }\n \n return {\n contents: [{\n uri: resourceUri,\n mimeType: 'text/markdown',\n text: content\n }]\n };\n }\n );\n }\n}\n\n/**\n * Register language-specific security pattern resources\n */\nexport function registerLanguageSecurityResources(server: McpServer): void {\n for (const langResource of LANGUAGE_RESOURCES) {\n if (!langResource.securityFile) continue;\n \n const resourceUri = `codeql://languages/${langResource.language}/security`;\n \n server.resource(\n `${langResource.language.toUpperCase()} Security Patterns`,\n resourceUri,\n {\n description: `CodeQL security query patterns and framework modeling for ${langResource.language}`,\n mimeType: 'text/markdown'\n },\n async () => {\n const content = loadResourceContent(langResource.securityFile!);\n \n if (!content) {\n return {\n contents: [{\n uri: resourceUri,\n mimeType: 'text/markdown',\n text: `# ${langResource.language.toUpperCase()} Security Patterns\\n\\nResource file not found or could not be loaded.`\n }]\n };\n }\n \n return {\n contents: [{\n uri: resourceUri,\n mimeType: 'text/markdown',\n text: content\n }]\n };\n }\n );\n }\n}\n\n/**\n * Register additional language-specific resources (like Go's dataflow patterns)\n */\nexport function registerLanguageAdditionalResources(server: McpServer): void {\n for (const langResource of LANGUAGE_RESOURCES) {\n if (!langResource.additionalFiles) continue;\n \n for (const [resourceType, filePath] of Object.entries(langResource.additionalFiles)) {\n const resourceUri = `codeql://languages/${langResource.language}/${resourceType}`;\n \n server.resource(\n `${langResource.language.toUpperCase()} ${resourceType.replace('-', ' ').replace(/\\b\\w/g, l => l.toUpperCase())}`,\n resourceUri,\n {\n description: `CodeQL ${resourceType.replace('-', ' ')} guide for ${langResource.language}`,\n mimeType: 'text/markdown'\n },\n async () => {\n const content = loadResourceContent(filePath);\n \n if (!content) {\n return {\n contents: [{\n uri: resourceUri,\n mimeType: 'text/markdown',\n text: `# ${langResource.language.toUpperCase()} ${resourceType.replace('-', ' ').replace(/\\b\\w/g, l => l.toUpperCase())}\\n\\nResource file not found or could not be loaded.`\n }]\n };\n }\n \n return {\n contents: [{\n uri: resourceUri,\n mimeType: 'text/markdown',\n text: content\n }]\n };\n }\n );\n }\n }\n}\n\n/**\n * Register all language-specific resources\n */\nexport function registerLanguageResources(server: McpServer): void {\n logger.info('Registering language-specific resources...');\n \n // Register AST references for all languages\n registerLanguageASTResources(server);\n \n // Register security patterns for languages that have them\n registerLanguageSecurityResources(server);\n \n // Register additional resources (like Go's dataflow patterns)\n registerLanguageAdditionalResources(server);\n \n logger.info(`Registered resources for ${LANGUAGE_RESOURCES.length} languages`);\n}", "/**\n * Type definitions and constants for language-specific resources\n */\n\n// Language mappings to resource files\nexport interface LanguageResource {\n language: string;\n astFile?: string;\n securityFile?: string;\n additionalFiles?: Record;\n}\n\nexport const LANGUAGE_RESOURCES: LanguageResource[] = [\n {\n language: 'actions',\n astFile: 'ql/languages/actions/tools/dev/actions_ast.prompt.md'\n },\n {\n language: 'cpp',\n astFile: 'ql/languages/cpp/tools/dev/cpp_ast.prompt.md',\n securityFile: 'ql/languages/cpp/tools/dev/cpp_security_query_guide.prompt.md'\n },\n {\n language: 'csharp',\n astFile: 'ql/languages/csharp/tools/dev/csharp_ast.prompt.md',\n securityFile: 'ql/languages/csharp/tools/dev/csharp_security_query_guide.prompt.md'\n },\n {\n language: 'go',\n astFile: 'ql/languages/go/tools/dev/go_ast.prompt.md',\n securityFile: 'ql/languages/go/tools/dev/go_security_query_guide.prompt.md',\n additionalFiles: {\n 'dataflow': 'ql/languages/go/tools/dev/go_dataflow.prompt.md',\n 'library-modeling': 'ql/languages/go/tools/dev/go_library_modeling.prompt.md',\n 'basic-queries': 'ql/languages/go/tools/dev/go_basic_queries.prompt.md'\n }\n },\n {\n language: 'java',\n astFile: 'ql/languages/java/tools/dev/java_ast.prompt.md'\n },\n {\n language: 'javascript',\n astFile: 'ql/languages/javascript/tools/dev/javascript_ast.prompt.md',\n securityFile: 'ql/languages/javascript/tools/dev/javascript_security_query_guide.prompt.md'\n },\n {\n language: 'python',\n astFile: 'ql/languages/python/tools/dev/python_ast.prompt.md',\n securityFile: 'ql/languages/python/tools/dev/python_security_query_guide.prompt.md'\n },\n {\n language: 'ql',\n astFile: 'ql/languages/ql/tools/dev/ql_ast.prompt.md'\n },\n {\n language: 'ruby',\n astFile: 'ql/languages/ruby/tools/dev/ruby_ast.prompt.md'\n }\n];", "/**\n * MCP Server workflow prompts for CodeQL development\n *\n * All prompt content is loaded from .prompt.md files in this directory.\n * This file only handles prompt registration and parameter processing.\n */\n\nimport { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport { z } from 'zod';\nimport { basename } from 'path';\nimport { loadPromptTemplate, processPromptTemplate } from './prompt-loader';\nimport { logger } from '../utils/logger';\n\n/** Supported CodeQL languages for tools queries */\nexport const SUPPORTED_LANGUAGES = [\n 'actions',\n 'cpp',\n 'csharp',\n 'go',\n 'java',\n 'javascript',\n 'python',\n 'ruby',\n 'swift'\n] as const;\n\n// \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n// Exported parameter schemas for each workflow prompt.\n//\n// Extracting the schemas makes it easy to unit-test required vs optional\n// validation independently of the MCP server registration.\n//\n// **Convention for VS Code UX consistency**:\n// Every prompt MUST expose at least one parameter \u2013 even if all parameters\n// are optional \u2013 so that VS Code always displays the parameter input dialog\n// and allows the user to customize the prompt before Copilot Chat processes\n// it. The `description` field on each Zod schema member doubles as the\n// placeholder text shown in the VS Code input box.\n// \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n/**\n * Schema for test_driven_development prompt parameters.\n *\n * - `language` is **required** \u2013 the TDD workflow is language-specific.\n * - `queryName` is optional \u2013 defaults to '[QueryName]' if omitted.\n */\nexport const testDrivenDevelopmentSchema = z.object({\n language: z\n .enum(SUPPORTED_LANGUAGES)\n .describe('Programming language for the query'),\n queryName: z\n .string()\n .optional()\n .describe('Name of the query to develop'),\n});\n\n/**\n * Schema for tools_query_workflow prompt parameters.\n *\n * - `language` and `database` are **required**.\n * - `sourceFiles`, `sourceFunction`, `targetFunction` are optional context.\n */\nexport const toolsQueryWorkflowSchema = z.object({\n database: z\n .string()\n .describe('Path to the CodeQL database'),\n language: z\n .enum(SUPPORTED_LANGUAGES)\n .describe('Programming language for the tools queries'),\n sourceFiles: z\n .string()\n .optional()\n .describe('Comma-separated source file names for PrintAST (e.g., \"main.js,utils.js\")'),\n sourceFunction: z\n .string()\n .optional()\n .describe('Function name for PrintCFG or CallGraphFrom (e.g., \"processData\")'),\n targetFunction: z\n .string()\n .optional()\n .describe('Function name for CallGraphTo (e.g., \"validate\")'),\n});\n\n/**\n * Schema for workshop_creation_workflow prompt parameters.\n * Uses z.coerce.number() for numStages to handle string inputs from VSCode slash commands.\n *\n * - `queryPath` and `language` are **required**.\n * - `workshopName` and `numStages` are optional.\n */\nexport const workshopCreationWorkflowSchema = z.object({\n queryPath: z\n .string()\n .describe('Path to the production-grade CodeQL query (.ql or .qlref)'),\n language: z\n .enum(SUPPORTED_LANGUAGES)\n .describe('Programming language of the query'),\n workshopName: z\n .string()\n .optional()\n .describe('Name for the workshop directory'),\n numStages: z\n .coerce.number()\n .optional()\n .describe('Number of incremental stages (default: 4-8)'),\n});\n\n/**\n * Schema for ql_tdd_basic prompt parameters.\n *\n * All parameters are optional \u2013 but at least one should be present so the\n * VS Code quick-pick dialog appears.\n */\nexport const qlTddBasicSchema = z.object({\n language: z\n .enum(SUPPORTED_LANGUAGES)\n .optional()\n .describe('Programming language for the query (optional)'),\n queryName: z\n .string()\n .optional()\n .describe('Name of the query to develop'),\n});\n\n/**\n * Schema for ql_tdd_advanced prompt parameters.\n *\n * All parameters are optional.\n */\nexport const qlTddAdvancedSchema = z.object({\n database: z\n .string()\n .optional()\n .describe('Path to the CodeQL database for analysis'),\n language: z\n .enum(SUPPORTED_LANGUAGES)\n .optional()\n .describe('Programming language for the query (optional)'),\n queryName: z\n .string()\n .optional()\n .describe('Name of the query to develop'),\n});\n\n/**\n * Schema for sarif_rank_false_positives / sarif_rank_true_positives.\n *\n * Both parameters are optional.\n */\nexport const sarifRankSchema = z.object({\n queryId: z\n .string()\n .optional()\n .describe('CodeQL query/rule identifier'),\n sarifPath: z\n .string()\n .optional()\n .describe('Path to the SARIF file to analyze'),\n});\n\n/**\n * Schema for explain_codeql_query prompt parameters.\n *\n * - `queryPath` and `language` are **required**.\n * - `databasePath` is optional.\n */\nexport const explainCodeqlQuerySchema = z.object({\n databasePath: z\n .string()\n .optional()\n .describe('Optional path to a real CodeQL database for profiling'),\n language: z\n .enum(SUPPORTED_LANGUAGES)\n .describe('Programming language of the query'),\n queryPath: z\n .string()\n .describe('Path to the CodeQL query file (.ql or .qlref)'),\n});\n\n/**\n * Schema for document_codeql_query prompt parameters.\n *\n * - `queryPath` and `language` are **required**.\n */\nexport const documentCodeqlQuerySchema = z.object({\n language: z\n .enum(SUPPORTED_LANGUAGES)\n .describe('Programming language of the query'),\n queryPath: z\n .string()\n .describe('Path to the CodeQL query file (.ql or .qlref)'),\n});\n\n/**\n * Schema for ql_lsp_iterative_development prompt parameters.\n *\n * All parameters are optional.\n */\nexport const qlLspIterativeDevelopmentSchema = z.object({\n language: z\n .enum(SUPPORTED_LANGUAGES)\n .optional()\n .describe('Programming language for the query'),\n queryPath: z\n .string()\n .optional()\n .describe('Path to the query file being developed'),\n workspaceUri: z\n .string()\n .optional()\n .describe('Workspace URI for LSP dependency resolution'),\n});\n\n// \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n// Prompt names (exported for testing)\n// \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n/** Names of every workflow prompt registered with the MCP server. */\nexport const WORKFLOW_PROMPT_NAMES = [\n 'document_codeql_query',\n 'explain_codeql_query',\n 'ql_lsp_iterative_development',\n 'ql_tdd_advanced',\n 'ql_tdd_basic',\n 'sarif_rank_false_positives',\n 'sarif_rank_true_positives',\n 'test_driven_development',\n 'tools_query_workflow',\n 'workshop_creation_workflow',\n] as const;\n\n/**\n * Register MCP workflow prompts\n *\n * Each prompt loads its content from a corresponding .prompt.md file\n * and processes any parameter substitutions.\n *\n * **UX note**: Every prompt schema is passed to `server.prompt()` so that\n * VS Code always displays the parameter-input quick-pick before the prompt\n * is sent to Copilot Chat. This lets users review and customise the values.\n */\nexport function registerWorkflowPrompts(server: McpServer): void {\n // Test-Driven Development Prompt\n server.prompt(\n 'test_driven_development',\n 'Test-driven development workflow for CodeQL queries using MCP tools',\n testDrivenDevelopmentSchema.shape,\n async ({ language, queryName }) => {\n const template = loadPromptTemplate('ql-tdd-basic.prompt.md');\n const content = processPromptTemplate(template, {\n language,\n queryName: queryName || '[QueryName]'\n });\n\n return {\n messages: [\n {\n role: 'user',\n content: {\n type: 'text',\n text: `## Context\\n\\n- **Language**: ${language}\\n${queryName ? `- **Query Name**: ${queryName}\\n` : ''}\\n${content}`\n }\n }\n ]\n };\n }\n );\n\n // Tools Query Workflow Prompt\n server.prompt(\n 'tools_query_workflow',\n 'Guide for using built-in tools queries (PrintAST, PrintCFG, CallGraphFrom, CallGraphTo) to understand code structure',\n toolsQueryWorkflowSchema.shape,\n async ({\n language,\n database,\n sourceFiles,\n sourceFunction,\n targetFunction\n }) => {\n const template = loadPromptTemplate('tools-query-workflow.prompt.md');\n const content = processPromptTemplate(template, {\n language,\n database\n });\n\n const contextSection = buildToolsQueryContext(\n language,\n database,\n sourceFiles,\n sourceFunction,\n targetFunction\n );\n\n return {\n messages: [\n {\n role: 'user',\n content: {\n type: 'text',\n text: contextSection + content\n }\n }\n ]\n };\n }\n );\n\n // Workshop Creation Workflow Prompt\n server.prompt(\n 'workshop_creation_workflow',\n 'Guide for creating CodeQL query development workshops from production-grade queries',\n workshopCreationWorkflowSchema.shape,\n async ({ queryPath, language, workshopName, numStages }) => {\n const template = loadPromptTemplate('workshop-creation-workflow.prompt.md');\n\n // Derive workshop name from query path if not provided\n const derivedName =\n workshopName ||\n basename(queryPath)\n .replace(/\\.(ql|qlref)$/, '')\n .toLowerCase()\n .replace(/[^a-z0-9]+/g, '-') ||\n 'codeql-workshop';\n\n const contextSection = buildWorkshopContext(\n queryPath,\n language,\n derivedName,\n numStages\n );\n\n return {\n messages: [\n {\n role: 'user',\n content: {\n type: 'text',\n text: contextSection + template\n }\n }\n ]\n };\n }\n );\n\n // TDD Basic Prompt - Test-Driven Development Checklist\n server.prompt(\n 'ql_tdd_basic',\n 'Test-driven CodeQL query development checklist - write tests first, implement query, iterate until tests pass',\n qlTddBasicSchema.shape,\n async ({ language, queryName }) => {\n const template = loadPromptTemplate('ql-tdd-basic.prompt.md');\n\n let contextSection = '## Your Development Context\\n\\n';\n if (language) {\n contextSection += `- **Language**: ${language}\\n`;\n }\n if (queryName) {\n contextSection += `- **Query Name**: ${queryName}\\n`;\n }\n if (language || queryName) {\n contextSection += '\\n';\n }\n\n return {\n messages: [\n {\n role: 'user',\n content: {\n type: 'text',\n text: contextSection + template\n }\n }\n ]\n };\n }\n );\n\n // TDD Advanced Prompt - Advanced Techniques with AST/CFG/CallGraph\n server.prompt(\n 'ql_tdd_advanced',\n 'Advanced test-driven CodeQL development with AST visualization, control flow, and call graph analysis',\n qlTddAdvancedSchema.shape,\n async ({ language, queryName, database }) => {\n const template = loadPromptTemplate('ql-tdd-advanced.prompt.md');\n\n let contextSection = '## Your Development Context\\n\\n';\n if (language) {\n contextSection += `- **Language**: ${language}\\n`;\n }\n if (queryName) {\n contextSection += `- **Query Name**: ${queryName}\\n`;\n }\n if (database) {\n contextSection += `- **Database**: ${database}\\n`;\n }\n if (language || queryName || database) {\n contextSection += '\\n';\n }\n\n return {\n messages: [\n {\n role: 'user',\n content: {\n type: 'text',\n text: contextSection + template\n }\n }\n ]\n };\n }\n );\n\n // SARIF Rank False Positives Prompt\n server.prompt(\n 'sarif_rank_false_positives',\n 'Analyze SARIF results to identify likely false positives in CodeQL query results',\n sarifRankSchema.shape,\n async ({ queryId, sarifPath }) => {\n const template = loadPromptTemplate('sarif-rank-false-positives.prompt.md');\n\n let contextSection = '## Analysis Context\\n\\n';\n if (queryId) {\n contextSection += `- **Query ID**: ${queryId}\\n`;\n }\n if (sarifPath) {\n contextSection += `- **SARIF File**: ${sarifPath}\\n`;\n }\n if (queryId || sarifPath) {\n contextSection += '\\n';\n }\n\n return {\n messages: [\n {\n role: 'user',\n content: {\n type: 'text',\n text: contextSection + template\n }\n }\n ]\n };\n }\n );\n\n // SARIF Rank True Positives Prompt\n server.prompt(\n 'sarif_rank_true_positives',\n 'Analyze SARIF results to identify likely true positives in CodeQL query results',\n sarifRankSchema.shape,\n async ({ queryId, sarifPath }) => {\n const template = loadPromptTemplate('sarif-rank-true-positives.prompt.md');\n\n let contextSection = '## Analysis Context\\n\\n';\n if (queryId) {\n contextSection += `- **Query ID**: ${queryId}\\n`;\n }\n if (sarifPath) {\n contextSection += `- **SARIF File**: ${sarifPath}\\n`;\n }\n if (queryId || sarifPath) {\n contextSection += '\\n';\n }\n\n return {\n messages: [\n {\n role: 'user',\n content: {\n type: 'text',\n text: contextSection + template\n }\n }\n ]\n };\n }\n );\n\n // Explain CodeQL Query Prompt (for workshop learning content)\n server.prompt(\n 'explain_codeql_query',\n 'Generate detailed explanation of a CodeQL query for workshop learning content - uses MCP tools to gather context and produces both verbal explanations and mermaid evaluation diagrams',\n explainCodeqlQuerySchema.shape,\n async ({ queryPath, language, databasePath }) => {\n const template = loadPromptTemplate('explain-codeql-query.prompt.md');\n\n let contextSection = '## Query to Explain\\n\\n';\n contextSection += `- **Query Path**: ${queryPath}\\n`;\n contextSection += `- **Language**: ${language}\\n`;\n if (databasePath) {\n contextSection += `- **Database Path**: ${databasePath}\\n`;\n }\n contextSection += '\\n';\n\n return {\n messages: [\n {\n role: 'user',\n content: {\n type: 'text',\n text: contextSection + template\n }\n }\n ]\n };\n }\n );\n\n // Document CodeQL Query Prompt\n server.prompt(\n 'document_codeql_query',\n 'Create or update documentation for a CodeQL query - generates standardized markdown documentation as a sibling file to the query',\n documentCodeqlQuerySchema.shape,\n async ({ queryPath, language }) => {\n const template = loadPromptTemplate('document-codeql-query.prompt.md');\n\n const contextSection = `## Query to Document\n\n- **Query Path**: ${queryPath}\n- **Language**: ${language}\n\n`;\n\n return {\n messages: [\n {\n role: 'user',\n content: {\n type: 'text',\n text: contextSection + template\n }\n }\n ]\n };\n }\n );\n\n // LSP-powered Iterative Development Prompt\n server.prompt(\n 'ql_lsp_iterative_development',\n 'Iterative CodeQL query development using LSP tools for completion, navigation, and validation',\n qlLspIterativeDevelopmentSchema.shape,\n async ({ language, queryPath, workspaceUri }) => {\n const template = loadPromptTemplate('ql-lsp-iterative-development.prompt.md');\n\n let contextSection = '## Your Development Context\\n\\n';\n if (language) {\n contextSection += `- **Language**: ${language}\\n`;\n }\n if (queryPath) {\n contextSection += `- **Query Path**: ${queryPath}\\n`;\n }\n if (workspaceUri) {\n contextSection += `- **Workspace URI**: ${workspaceUri}\\n`;\n }\n if (language || queryPath || workspaceUri) {\n contextSection += '\\n';\n }\n\n return {\n messages: [\n {\n role: 'user',\n content: {\n type: 'text',\n text: contextSection + template,\n },\n },\n ],\n };\n }\n );\n\n logger.info(`Registered ${WORKFLOW_PROMPT_NAMES.length} workflow prompts`);\n}\n\n/**\n * Build context section for tools query workflow\n */\nexport function buildToolsQueryContext(\n language: string,\n database: string,\n sourceFiles?: string,\n sourceFunction?: string,\n targetFunction?: string\n): string {\n const lines = [\n '## Your Context',\n '',\n `- **Language**: ${language}`,\n `- **Database**: ${database}`\n ];\n\n if (sourceFiles) {\n lines.push(`- **Source Files**: ${sourceFiles}`);\n }\n if (sourceFunction) {\n lines.push(`- **Source Function**: ${sourceFunction}`);\n }\n if (targetFunction) {\n lines.push(`- **Target Function**: ${targetFunction}`);\n }\n\n lines.push('', '## Recommended Next Steps', '');\n\n if (sourceFiles) {\n lines.push(\n `1. Run \\`codeql_query_run\\` with queryName=\"PrintAST\", sourceFiles=\"${sourceFiles}\"`\n );\n } else {\n lines.push('1. Identify source files to analyze with PrintAST');\n }\n\n if (sourceFunction) {\n lines.push(\n `2. Run \\`codeql_query_run\\` with queryName=\"PrintCFG\" or \"CallGraphFrom\", sourceFunction=\"${sourceFunction}\"`\n );\n } else {\n lines.push(\n '2. Identify key functions for CFG or call graph analysis'\n );\n }\n\n if (targetFunction) {\n lines.push(\n `3. Run \\`codeql_query_run\\` with queryName=\"CallGraphTo\", targetFunction=\"${targetFunction}\"`\n );\n } else {\n lines.push('3. Identify target functions to find callers');\n }\n\n lines.push('', '');\n return lines.join('\\n');\n}\n\n/**\n * Build context section for workshop creation workflow\n */\nexport function buildWorkshopContext(\n queryPath: string,\n language: string,\n workshopName: string,\n numStages?: number\n): string {\n return `## Your Workshop Context\n\n- **Target Query**: ${queryPath}\n- **Language**: ${language}\n- **Workshop Name**: ${workshopName}\n- **Suggested Stages**: ${numStages || '4-8 (auto-detect based on query complexity)'}\n\n## Immediate Actions\n\n1. **Locate query files**: Use \\`find_codeql_query_files\\` with queryPath=\"${queryPath}\"\n2. **Understand query for learning content**: Use the \\`explain_codeql_query\\` prompt with queryPath=\"${queryPath}\" and language=\"${language}\"\n3. **Document each workshop stage**: Use the \\`document_codeql_query\\` prompt to create/update documentation for each solution query\n4. **Verify tests pass**: Use \\`codeql_test_run\\` on existing tests\n5. **Run tools queries**: Generate AST/CFG understanding for workshop materials\n\n`;\n}\n", "/**\n * Utility functions for loading prompt template files\n */\n\nimport { readFileSync } from 'fs';\nimport { join, dirname } from 'path';\nimport { fileURLToPath } from 'url';\n\nconst __filename = fileURLToPath(import.meta.url);\nconst __dirname = dirname(__filename);\n\n/**\n * Load a prompt template from a .prompt.md file\n */\nexport function loadPromptTemplate(promptFileName: string): string {\n try {\n const promptPath = join(__dirname, promptFileName);\n return readFileSync(promptPath, 'utf-8');\n } catch (error) {\n return `Prompt template '${promptFileName}' not available: ${error instanceof Error ? error.message : 'Unknown error'}`;\n }\n}\n\n/**\n * Process prompt template by replacing placeholders with actual values\n */\nexport function processPromptTemplate(template: string, variables: Record): string {\n let processed = template;\n \n // Replace variables in the format {{variable}} or {variable}\n for (const [key, value] of Object.entries(variables)) {\n const patterns = [\n new RegExp(`\\\\{\\\\{${key}\\\\}\\\\}`, 'g'),\n new RegExp(`\\\\{${key}\\\\}`, 'g')\n ];\n \n for (const pattern of patterns) {\n processed = processed.replace(pattern, value);\n }\n }\n \n return processed;\n}", "/**\n * Monitoring Tools - MCP tool implementations for session management and reporting\n * Provides the MCP Tool APIs specified in the monitoring specification\n */\n\nimport { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport { z } from 'zod';\nimport { randomUUID } from 'crypto';\nimport { sessionDataManager } from '../lib/session-data-manager';\nimport {\n QueryDevelopmentSession,\n SessionFilter,\n QualityScoreRecord,\n ComparisonReport,\n AggregateReport,\n ExportResult,\n FunctionalTestResult,\n} from '../types/monitoring';\nimport { logger } from '../utils/logger';\n\n/**\n * Register all monitoring and reporting tools with the MCP server\n * Note: These tools are opt-in and disabled by default for end-users.\n * Set enableMonitoringTools: true in monitoring config to enable them.\n */\nexport function registerMonitoringTools(server: McpServer): void {\n const config = sessionDataManager.getConfig();\n \n // Check if monitoring tools are enabled (opt-in, disabled by default)\n if (!config.enableMonitoringTools) {\n logger.info('Monitoring tools are disabled (opt-in). Set enableMonitoringTools: true to enable session_* tools.');\n return;\n }\n\n // Session Management Tools - session_start removed per feedback (auto-creation instead)\n registerSessionEndTool(server);\n registerSessionGetTool(server);\n registerSessionListTool(server);\n registerSessionUpdateStateTool(server);\n\n // Session Analytics Tools\n registerSessionGetCallHistoryTool(server);\n registerSessionGetTestHistoryTool(server);\n registerSessionGetScoreHistoryTool(server);\n registerSessionCalculateCurrentScoreTool(server);\n\n // Batch Operations Tools\n registerSessionsCompareTool(server);\n registerSessionsAggregateTool(server);\n registerSessionsExportTool(server);\n\n // Note: Functional Testing Support Tools are internal only, not exposed as MCP tools\n\n logger.info('Registered monitoring and reporting tools');\n}\n\n/**\n * Session Management Tools\n */\n\n// session_start tool removed - sessions are now auto-created when needed\n// Sessions are automatically created when MCP tools are called with queryPath\n// If explicit session creation is needed, provide sessionId=null and it will auto-create\n\nfunction registerSessionEndTool(server: McpServer): void {\n server.tool(\n 'session_end',\n 'End a query development session with final status',\n {\n sessionId: z.string().describe('ID of the session to end'),\n status: z.enum(['completed', 'failed', 'abandoned']).describe('Final status of the session'),\n },\n async ({ sessionId, status }) => {\n try {\n const session = await sessionDataManager.endSession(sessionId, status);\n \n if (!session) {\n return {\n content: [\n {\n type: 'text',\n text: `Session not found: ${sessionId}`,\n },\n ],\n isError: true,\n };\n }\n\n return {\n content: [\n {\n type: 'text',\n text: JSON.stringify(session, null, 2),\n },\n ],\n };\n } catch (error) {\n logger.error('Error ending session:', error);\n return {\n content: [\n {\n type: 'text',\n text: `Error ending session: ${error instanceof Error ? error.message : 'Unknown error'}`,\n },\n ],\n isError: true,\n };\n }\n }\n );\n}\n\nfunction registerSessionGetTool(server: McpServer): void {\n server.tool(\n 'session_get',\n 'Get complete details of a specific query development session',\n {\n sessionId: z.string().describe('ID of the session to retrieve'),\n },\n async ({ sessionId }) => {\n try {\n const session = await sessionDataManager.getSession(sessionId);\n \n if (!session) {\n return {\n content: [\n {\n type: 'text',\n text: `Session not found: ${sessionId}`,\n },\n ],\n isError: true,\n };\n }\n\n return {\n content: [\n {\n type: 'text',\n text: JSON.stringify(session, null, 2),\n },\n ],\n };\n } catch (error) {\n logger.error('Error getting session:', error);\n return {\n content: [\n {\n type: 'text',\n text: `Error getting session: ${error instanceof Error ? error.message : 'Unknown error'}`,\n },\n ],\n isError: true,\n };\n }\n }\n );\n}\n\nfunction registerSessionListTool(server: McpServer): void {\n server.tool(\n 'session_list',\n 'List query development sessions with optional filtering',\n {\n queryPath: z.string().optional().describe('Filter by query path (partial match)'),\n status: z.string().optional().describe('Filter by session status'),\n dateRange: z.array(z.string()).length(2).optional().describe('Filter by date range [start, end] (ISO timestamps)'),\n language: z.string().optional().describe('Filter by programming language'),\n queryType: z.string().optional().describe('Filter by query type'),\n },\n async ({ queryPath, status, dateRange, language, queryType }) => {\n try {\n const filters: SessionFilter = {};\n if (queryPath) filters.queryPath = queryPath;\n if (status) filters.status = status;\n if (dateRange) filters.dateRange = [dateRange[0], dateRange[1]];\n if (language) filters.language = language;\n if (queryType) filters.queryType = queryType;\n\n const sessions = await sessionDataManager.listSessions(\n Object.keys(filters).length > 0 ? filters : undefined\n );\n\n const sessionList = {\n totalSessions: sessions.length,\n sessions: sessions.map(s => ({\n sessionId: s.sessionId,\n queryPath: s.queryPath,\n language: s.language,\n status: s.status,\n startTime: s.startTime,\n endTime: s.endTime,\n mcpCallsCount: s.mcpCalls.length,\n testExecutionsCount: s.testExecutions.length,\n currentScore: s.qualityScores.length > 0 \n ? s.qualityScores[s.qualityScores.length - 1].overallScore \n : null,\n })),\n };\n\n return {\n content: [\n {\n type: 'text',\n text: JSON.stringify(sessionList, null, 2),\n },\n ],\n recommendations: generateListRecommendations(sessions),\n };\n } catch (error) {\n logger.error('Error listing sessions:', error);\n return {\n content: [\n {\n type: 'text',\n text: `Error listing sessions: ${error instanceof Error ? error.message : 'Unknown error'}`,\n },\n ],\n isError: true,\n };\n }\n }\n );\n}\n\nfunction registerSessionUpdateStateTool(server: McpServer): void {\n server.tool(\n 'session_update_state',\n 'Update the current state of a query development session',\n {\n sessionId: z.string().describe('ID of the session to update'),\n filesPresent: z.array(z.string()).optional().describe('List of files present in the query development'),\n compilationStatus: z.enum(['unknown', 'success', 'failed']).optional().describe('Current compilation status'),\n testStatus: z.enum(['unknown', 'passing', 'failing', 'no_tests']).optional().describe('Current test status'),\n documentationStatus: z.enum(['unknown', 'present', 'missing', 'incomplete']).optional().describe('Documentation status'),\n },\n async ({ sessionId, filesPresent, compilationStatus, testStatus, documentationStatus }) => {\n try {\n const stateUpdate: Record = {};\n if (filesPresent !== undefined) stateUpdate.filesPresent = filesPresent;\n if (compilationStatus !== undefined) stateUpdate.compilationStatus = compilationStatus;\n if (testStatus !== undefined) stateUpdate.testStatus = testStatus;\n if (documentationStatus !== undefined) stateUpdate.documentationStatus = documentationStatus;\n\n const session = await sessionDataManager.updateSessionState(sessionId, stateUpdate);\n \n if (!session) {\n return {\n content: [\n {\n type: 'text',\n text: `Session not found: ${sessionId}`,\n },\n ],\n isError: true,\n };\n }\n\n return {\n content: [\n {\n type: 'text',\n text: JSON.stringify(session, null, 2),\n },\n ],\n recommendations: generateRecommendations(session, 'session_update_state'),\n };\n } catch (error) {\n logger.error('Error updating session state:', error);\n return {\n content: [\n {\n type: 'text',\n text: `Error updating session state: ${error instanceof Error ? error.message : 'Unknown error'}`,\n },\n ],\n isError: true,\n };\n }\n }\n );\n}\n\n/**\n * Session Analytics Tools\n */\n\nfunction registerSessionGetCallHistoryTool(server: McpServer): void {\n server.tool(\n 'session_get_call_history',\n 'Get MCP call history for a specific session',\n {\n sessionId: z.string().describe('ID of the session'),\n limit: z.number().optional().describe('Maximum number of calls to return (most recent first)'),\n },\n async ({ sessionId, limit }) => {\n try {\n const session = await sessionDataManager.getSession(sessionId);\n \n if (!session) {\n return {\n content: [\n {\n type: 'text',\n text: `Session not found: ${sessionId}`,\n },\n ],\n isError: true,\n };\n }\n\n let calls = [...session.mcpCalls].reverse(); // Most recent first\n if (limit && limit > 0) {\n calls = calls.slice(0, limit);\n }\n\n return {\n content: [\n {\n type: 'text',\n text: JSON.stringify({\n sessionId,\n totalCalls: session.mcpCalls.length,\n callHistory: calls,\n }, null, 2),\n },\n ],\n };\n } catch (error) {\n logger.error('Error getting call history:', error);\n return {\n content: [\n {\n type: 'text',\n text: `Error getting call history: ${error instanceof Error ? error.message : 'Unknown error'}`,\n },\n ],\n isError: true,\n };\n }\n }\n );\n}\n\nfunction registerSessionGetTestHistoryTool(server: McpServer): void {\n server.tool(\n 'session_get_test_history',\n 'Get test execution history for a specific session',\n {\n sessionId: z.string().describe('ID of the session'),\n limit: z.number().optional().describe('Maximum number of test executions to return (most recent first)'),\n },\n async ({ sessionId, limit }) => {\n try {\n const session = await sessionDataManager.getSession(sessionId);\n \n if (!session) {\n return {\n content: [\n {\n type: 'text',\n text: `Session not found: ${sessionId}`,\n },\n ],\n isError: true,\n };\n }\n\n let tests = [...session.testExecutions].reverse(); // Most recent first\n if (limit && limit > 0) {\n tests = tests.slice(0, limit);\n }\n\n return {\n content: [\n {\n type: 'text',\n text: JSON.stringify({\n sessionId,\n totalTests: session.testExecutions.length,\n testHistory: tests,\n }, null, 2),\n },\n ],\n };\n } catch (error) {\n logger.error('Error getting test history:', error);\n return {\n content: [\n {\n type: 'text',\n text: `Error getting test history: ${error instanceof Error ? error.message : 'Unknown error'}`,\n },\n ],\n isError: true,\n };\n }\n }\n );\n}\n\nfunction registerSessionGetScoreHistoryTool(server: McpServer): void {\n server.tool(\n 'session_get_score_history',\n 'Get quality score history for a specific session',\n {\n sessionId: z.string().describe('ID of the session'),\n limit: z.number().optional().describe('Maximum number of scores to return (most recent first)'),\n },\n async ({ sessionId, limit }) => {\n try {\n const session = await sessionDataManager.getSession(sessionId);\n \n if (!session) {\n return {\n content: [\n {\n type: 'text',\n text: `Session not found: ${sessionId}`,\n },\n ],\n isError: true,\n };\n }\n\n let scores = [...session.qualityScores].reverse(); // Most recent first\n if (limit && limit > 0) {\n scores = scores.slice(0, limit);\n }\n\n return {\n content: [\n {\n type: 'text',\n text: JSON.stringify({\n sessionId,\n totalScores: session.qualityScores.length,\n scoreHistory: scores,\n }, null, 2),\n },\n ],\n };\n } catch (error) {\n logger.error('Error getting score history:', error);\n return {\n content: [\n {\n type: 'text',\n text: `Error getting score history: ${error instanceof Error ? error.message : 'Unknown error'}`,\n },\n ],\n isError: true,\n };\n }\n }\n );\n}\n\nfunction registerSessionCalculateCurrentScoreTool(server: McpServer): void {\n server.tool(\n 'session_calculate_current_score',\n 'Calculate current quality score for a session based on its state',\n {\n sessionId: z.string().describe('ID of the session'),\n },\n async ({ sessionId }) => {\n try {\n const session = await sessionDataManager.getSession(sessionId);\n \n if (!session) {\n return {\n content: [\n {\n type: 'text',\n text: `Session not found: ${sessionId}`,\n },\n ],\n isError: true,\n };\n }\n\n // Calculate quality score based on current state\n const scoreRecord = calculateQualityScore(session);\n \n // Add the score to the session\n await sessionDataManager.addQualityScore(sessionId, scoreRecord);\n \n // Get updated session with new score\n const updatedSession = await sessionDataManager.getSession(sessionId);\n\n return {\n content: [\n {\n type: 'text',\n text: JSON.stringify(scoreRecord, null, 2),\n },\n ],\n recommendations: generateRecommendations(updatedSession, 'session_calculate_current_score'),\n };\n } catch (error) {\n logger.error('Error calculating current score:', error);\n return {\n content: [\n {\n type: 'text',\n text: `Error calculating current score: ${error instanceof Error ? error.message : 'Unknown error'}`,\n },\n ],\n isError: true,\n };\n }\n }\n );\n}\n\n/**\n * Batch Operations Tools\n */\n\nfunction registerSessionsCompareTool(server: McpServer): void {\n server.tool(\n 'sessions_compare',\n 'Compare multiple query development sessions across specified dimensions',\n {\n sessionIds: z.array(z.string()).describe('Array of session IDs to compare'),\n dimensions: z.array(z.string()).optional().describe('Specific dimensions to compare (default: all)'),\n },\n async ({ sessionIds, dimensions }) => {\n try {\n const sessions = await Promise.all(\n sessionIds.map(id => sessionDataManager.getSession(id))\n );\n\n const validSessions = sessions.filter(s => s !== null) as QueryDevelopmentSession[];\n \n if (validSessions.length === 0) {\n return {\n content: [\n {\n type: 'text',\n text: 'No valid sessions found for comparison',\n },\n ],\n isError: true,\n };\n }\n\n const comparison = await compareSessions(validSessions, dimensions);\n\n return {\n content: [\n {\n type: 'text',\n text: JSON.stringify(comparison, null, 2),\n },\n ],\n };\n } catch (error) {\n logger.error('Error comparing sessions:', error);\n return {\n content: [\n {\n type: 'text',\n text: `Error comparing sessions: ${error instanceof Error ? error.message : 'Unknown error'}`,\n },\n ],\n isError: true,\n };\n }\n }\n );\n}\n\nfunction registerSessionsAggregateTool(server: McpServer): void {\n server.tool(\n 'sessions_aggregate',\n 'Generate aggregate insights from multiple sessions based on filters',\n {\n queryPath: z.string().optional().describe('Filter by query path (partial match)'),\n status: z.string().optional().describe('Filter by session status'),\n dateRange: z.array(z.string()).length(2).optional().describe('Filter by date range [start, end] (ISO timestamps)'),\n language: z.string().optional().describe('Filter by programming language'),\n queryType: z.string().optional().describe('Filter by query type'),\n },\n async ({ queryPath, status, dateRange, language, queryType }) => {\n try {\n const filters: SessionFilter = {};\n if (queryPath) filters.queryPath = queryPath;\n if (status) filters.status = status;\n if (dateRange) filters.dateRange = [dateRange[0], dateRange[1]];\n if (language) filters.language = language;\n if (queryType) filters.queryType = queryType;\n\n const sessions = await sessionDataManager.listSessions(\n Object.keys(filters).length > 0 ? filters : undefined\n );\n\n const aggregate = await aggregateSessions(sessions, filters);\n\n return {\n content: [\n {\n type: 'text',\n text: JSON.stringify(aggregate, null, 2),\n },\n ],\n };\n } catch (error) {\n logger.error('Error aggregating sessions:', error);\n return {\n content: [\n {\n type: 'text',\n text: `Error aggregating sessions: ${error instanceof Error ? error.message : 'Unknown error'}`,\n },\n ],\n isError: true,\n };\n }\n }\n );\n}\n\nfunction registerSessionsExportTool(server: McpServer): void {\n server.tool(\n 'sessions_export',\n 'Export session data in specified format for external analysis',\n {\n sessionIds: z.array(z.string()).describe('Array of session IDs to export'),\n format: z.enum(['json', 'html', 'markdown']).optional().default('json').describe('Export format'),\n },\n async ({ sessionIds, format = 'json' }) => {\n try {\n const sessions = await Promise.all(\n sessionIds.map(id => sessionDataManager.getSession(id))\n );\n\n const validSessions = sessions.filter(s => s !== null) as QueryDevelopmentSession[];\n \n if (validSessions.length === 0) {\n return {\n content: [\n {\n type: 'text',\n text: 'No valid sessions found for export',\n },\n ],\n isError: true,\n };\n }\n\n const exportResult = await exportSessions(validSessions, format);\n\n return {\n content: [\n {\n type: 'text',\n text: JSON.stringify(exportResult, null, 2),\n },\n ],\n };\n } catch (error) {\n logger.error('Error exporting sessions:', error);\n return {\n content: [\n {\n type: 'text',\n text: `Error exporting sessions: ${error instanceof Error ? error.message : 'Unknown error'}`,\n },\n ],\n isError: true,\n };\n }\n }\n );\n}\n\n/**\n * Helper Functions\n */\n\n/**\n * Calculate quality score for a session based on current state and history\n */\nfunction calculateQualityScore(session: QueryDevelopmentSession): QualityScoreRecord {\n const timestamp = new Date().toISOString();\n \n // Calculate syntactic correctness (25%)\n const syntacticCorrectness = session.currentState.compilationStatus === 'success' ? 100 :\n session.currentState.compilationStatus === 'failed' ? 0 : 50;\n\n // Calculate test coverage and results (30%)\n const testCoverageResults = session.currentState.testStatus === 'passing' ? 100 :\n session.currentState.testStatus === 'failing' ? 25 :\n session.currentState.testStatus === 'no_tests' ? 0 : 50;\n\n // Calculate documentation quality (20%)\n const documentationQuality = session.currentState.documentationStatus === 'present' ? 100 :\n session.currentState.documentationStatus === 'incomplete' ? 60 :\n session.currentState.documentationStatus === 'missing' ? 0 : 50;\n\n // Calculate functional correctness (25%) - based on successful test runs\n const successfulTests = session.testExecutions.filter(t => t.success && t.type === 'test_run').length;\n const totalTests = session.testExecutions.filter(t => t.type === 'test_run').length;\n const functionalCorrectness = totalTests > 0 ? (successfulTests / totalTests) * 100 : 50;\n\n // Calculate overall score\n const overallScore = Math.round(\n (syntacticCorrectness * 0.25) +\n (testCoverageResults * 0.30) +\n (documentationQuality * 0.20) +\n (functionalCorrectness * 0.25)\n );\n\n // Determine grade\n const grade = overallScore >= 90 ? 'A' :\n overallScore >= 80 ? 'B' :\n overallScore >= 70 ? 'C' :\n overallScore >= 60 ? 'D' : 'F';\n\n // Generate recommendations\n const recommendations: string[] = [];\n if (syntacticCorrectness < 100) {\n recommendations.push('Fix compilation errors to improve syntactic correctness');\n }\n if (testCoverageResults < 70) {\n recommendations.push('Add comprehensive tests and ensure they pass');\n }\n if (documentationQuality < 80) {\n recommendations.push('Add or improve query documentation with examples');\n }\n if (functionalCorrectness < 80) {\n recommendations.push('Improve test pass rate and verify query logic');\n }\n\n return {\n scoreId: randomUUID(),\n timestamp,\n overallScore,\n dimensions: {\n syntacticCorrectness,\n testCoverageResults,\n documentationQuality,\n functionalCorrectness,\n },\n grade,\n recommendations,\n };\n}\n\n/**\n * Compare multiple sessions\n */\nasync function compareSessions(\n sessions: QueryDevelopmentSession[],\n dimensions?: string[]\n): Promise {\n const timestamp = new Date().toISOString();\n const sessionIds = sessions.map(s => s.sessionId);\n \n const results: Record = {\n sessionCount: sessions.length,\n sessionOverview: sessions.map(s => ({\n sessionId: s.sessionId,\n queryPath: s.queryPath,\n status: s.status,\n mcpCallsCount: s.mcpCalls.length,\n duration: s.endTime ? \n new Date(s.endTime).getTime() - new Date(s.startTime).getTime() : \n new Date().getTime() - new Date(s.startTime).getTime(),\n currentScore: s.qualityScores.length > 0 ? \n s.qualityScores[s.qualityScores.length - 1].overallScore : null,\n })),\n };\n\n if (!dimensions || dimensions.includes('quality')) {\n const qualityScores = sessions.map(s => \n s.qualityScores.length > 0 ? s.qualityScores[s.qualityScores.length - 1] : null\n );\n results.qualityComparison = {\n averageScore: qualityScores\n .filter(q => q !== null)\n .reduce((sum, q) => sum + q!.overallScore, 0) / qualityScores.filter(q => q !== null).length,\n scoreRange: {\n min: Math.min(...qualityScores.filter(q => q !== null).map(q => q!.overallScore)),\n max: Math.max(...qualityScores.filter(q => q !== null).map(q => q!.overallScore)),\n },\n };\n }\n\n if (!dimensions || dimensions.includes('activity')) {\n results.activityComparison = {\n totalMCPCalls: sessions.reduce((sum, s) => sum + s.mcpCalls.length, 0),\n averageCallsPerSession: sessions.reduce((sum, s) => sum + s.mcpCalls.length, 0) / sessions.length,\n mostActiveTool: getMostUsedTool(sessions),\n };\n }\n\n return {\n sessionIds,\n dimensions: dimensions || ['all'],\n timestamp,\n results,\n };\n}\n\n/**\n * Aggregate insights from multiple sessions\n */\nasync function aggregateSessions(\n sessions: QueryDevelopmentSession[],\n filters: SessionFilter\n): Promise {\n const timestamp = new Date().toISOString();\n \n const completedSessions = sessions.filter(s => s.status === 'completed');\n const successRate = sessions.length > 0 ? completedSessions.length / sessions.length : 0;\n \n const qualityScores = sessions\n .map(s => s.qualityScores.length > 0 ? s.qualityScores[s.qualityScores.length - 1].overallScore : null)\n .filter(score => score !== null) as number[];\n \n const averageQualityScore = qualityScores.length > 0 ? \n qualityScores.reduce((sum, score) => sum + score, 0) / qualityScores.length : 0;\n\n const commonPatterns = identifyCommonPatterns(sessions);\n const recommendations = generateAggregateRecommendations(sessions);\n\n return {\n filters,\n timestamp,\n totalSessions: sessions.length,\n successRate,\n averageQualityScore,\n commonPatterns,\n recommendations,\n };\n}\n\n/**\n * Export sessions in specified format\n */\nasync function exportSessions(\n sessions: QueryDevelopmentSession[],\n format: 'json' | 'html' | 'markdown'\n): Promise {\n const timestamp = new Date().toISOString();\n const filename = `session-export-${timestamp.replace(/[:.]/g, '-')}.${format}`;\n \n let content: string;\n \n switch (format) {\n case 'json':\n content = JSON.stringify(sessions, null, 2);\n break;\n case 'html':\n content = generateHTMLReport(sessions);\n break;\n case 'markdown':\n content = generateMarkdownReport(sessions);\n break;\n }\n\n return {\n format,\n filename,\n content,\n timestamp,\n };\n}\n\n/**\n * Utility functions\n */\n\nfunction getMostUsedTool(sessions: QueryDevelopmentSession[]): string {\n const toolCounts: Record = {};\n \n sessions.forEach(session => {\n session.mcpCalls.forEach(call => {\n toolCounts[call.toolName] = (toolCounts[call.toolName] || 0) + 1;\n });\n });\n\n return Object.entries(toolCounts)\n .sort(([, a], [, b]) => b - a)[0]?.[0] || 'none';\n}\n\nfunction identifyCommonPatterns(sessions: QueryDevelopmentSession[]): string[] {\n const patterns: string[] = [];\n \n const commonTools = getMostUsedTool(sessions);\n if (commonTools && commonTools !== 'none') {\n patterns.push(`Most commonly used tool: ${commonTools}`);\n }\n\n const completionRate = sessions.filter(s => s.status === 'completed').length / sessions.length;\n if (completionRate > 0.8) {\n patterns.push('High completion rate indicates effective workflow');\n } else if (completionRate < 0.5) {\n patterns.push('Low completion rate suggests workflow issues');\n }\n\n return patterns;\n}\n\nfunction generateAggregateRecommendations(sessions: QueryDevelopmentSession[]): string[] {\n const recommendations: string[] = [];\n \n const failedSessions = sessions.filter(s => s.status === 'failed');\n if (failedSessions.length > sessions.length * 0.3) {\n recommendations.push('High failure rate - consider improving error handling and guidance');\n }\n\n const averageCallsPerSession = sessions.reduce((sum, s) => sum + s.mcpCalls.length, 0) / sessions.length;\n if (averageCallsPerSession > 20) {\n recommendations.push('High number of MCP calls per session - consider workflow optimization');\n }\n\n return recommendations;\n}\n\nfunction generateHTMLReport(sessions: QueryDevelopmentSession[]): string {\n const html = `\n\n\n\n Session Export Report\n \n\n\n

Query Development Sessions Report

\n

Generated: ${new Date().toISOString()}

\n

Total Sessions: ${sessions.length}

\n \n ${sessions.map(session => `\n
\n

Session: ${session.sessionId}

\n

Query Path: ${session.queryPath}

\n

Status: ${session.status}

\n

Language: ${session.language}

\n

Start Time: ${session.startTime}

\n

MCP Calls: ${session.mcpCalls.length}

\n

Test Executions: ${session.testExecutions.length}

\n

Quality Scores: ${session.qualityScores.length}

\n
\n `).join('')}\n\n`;\n \n return html;\n}\n\nfunction generateMarkdownReport(sessions: QueryDevelopmentSession[]): string {\n const md = `# Query Development Sessions Report\n\nGenerated: ${new Date().toISOString()}\nTotal Sessions: ${sessions.length}\n\n## Session Summary\n\n| Session ID | Query Path | Status | Language | MCP Calls | Test Executions |\n|------------|-----------|--------|----------|-----------|-----------------|\n${sessions.map(session => \n `| ${session.sessionId} | ${session.queryPath} | ${session.status} | ${session.language} | ${session.mcpCalls.length} | ${session.testExecutions.length} |`\n).join('\\n')}\n\n## Detailed Sessions\n\n${sessions.map(session => `\n### Session: ${session.sessionId}\n\n- **Query Path:** ${session.queryPath}\n- **Status:** ${session.status}\n- **Language:** ${session.language}\n- **Start Time:** ${session.startTime}\n- **End Time:** ${session.endTime || 'N/A'}\n- **MCP Calls:** ${session.mcpCalls.length}\n- **Test Executions:** ${session.testExecutions.length}\n- **Quality Scores:** ${session.qualityScores.length}\n\n${session.recommendations.length > 0 ? `\n**Current Recommendations:**\n${session.recommendations.map(rec => `- ${rec}`).join('\\n')}\n` : ''}\n`).join('\\n')}`;\n\n return md;\n}\n\nfunction _calculateAverageDuration(sessions: QueryDevelopmentSession[]): number {\n const completedSessions = sessions.filter(s => s.endTime);\n if (completedSessions.length === 0) return 0;\n\n const totalDuration = completedSessions.reduce((sum, session) => {\n return sum + (new Date(session.endTime!).getTime() - new Date(session.startTime).getTime());\n }, 0);\n\n return totalDuration / completedSessions.length;\n}\n\nfunction _identifyFailureReasons(results: FunctionalTestResult[]): string[] {\n const failedResults = results.filter(r => !r.passed);\n const reasons: Record = {};\n\n failedResults.forEach(result => {\n Object.entries(result.criteria).forEach(([criterion, passed]) => {\n if (!passed) {\n reasons[criterion] = (reasons[criterion] || 0) + 1;\n }\n });\n });\n\n return Object.entries(reasons)\n .sort(([, a], [, b]) => b - a)\n .map(([reason, count]) => `${reason}: ${count} sessions`);\n}\n\n/**\n * Generate recommendations for MCP tool responses\n * Returns a map of MCP primitive paths to recommendation reasons\n */\nfunction generateRecommendations(\n session: QueryDevelopmentSession | null,\n currentTool: string\n): Record {\n if (!session) {\n return {};\n }\n\n const recommendations: Record = {};\n\n // Session state-based recommendations\n if (session.currentState.compilationStatus === 'failed') {\n recommendations['codeql_query_format'] = 'Format query to fix potential syntax issues';\n recommendations['codeql_query_compile'] = 'Recompile after fixing syntax errors';\n } else if (session.currentState.compilationStatus === 'success') {\n if (session.currentState.testStatus === 'unknown' || session.currentState.testStatus === 'no_tests') {\n recommendations['codeql_test_run'] = 'Run tests to validate query functionality';\n } else if (session.currentState.testStatus === 'failing') {\n recommendations['session_get_test_history'] = 'Review test failures to identify issues';\n recommendations['codeql_query_compile'] = 'Verify query logic matches test expectations';\n } else if (session.currentState.testStatus === 'passing') {\n recommendations['session_calculate_current_score'] = 'Calculate quality score for completed query';\n }\n }\n\n // Tool-specific follow-up recommendations\n switch (currentTool) {\n case 'session_get':\n if (session.mcpCalls.length === 0) {\n recommendations['codeql_query_compile'] = 'Start development by compiling the query';\n }\n break;\n case 'session_end':\n if (session.status === 'completed') {\n recommendations['sessions_export'] = 'Export session data for analysis';\n }\n break;\n case 'session_calculate_current_score': {\n const latestScore = session.qualityScores[session.qualityScores.length - 1];\n if (latestScore && latestScore.overallScore < 80) {\n if (latestScore.dimensions.syntacticCorrectness < 100) {\n recommendations['codeql_query_format'] = 'Improve syntax and formatting';\n }\n if (latestScore.dimensions.testCoverageResults < 70) {\n recommendations['codeql_test_run'] = 'Improve test coverage and results';\n }\n }\n break;\n }\n case 'session_update_state':\n // Recommend next logical step based on updated state\n if (session.currentState.compilationStatus === 'success' && session.currentState.testStatus === 'unknown') {\n recommendations['codeql_test_run'] = 'Run tests now that compilation is successful';\n }\n break;\n }\n\n return recommendations;\n}\n\n/**\n * Generate recommendations for session list results\n */\nfunction generateListRecommendations(sessions: QueryDevelopmentSession[]): Record {\n const recommendations: Record = {};\n\n const activeSessions = sessions.filter(s => s.status === 'active');\n const completedSessions = sessions.filter(s => s.status === 'completed');\n\n if (activeSessions.length > 0) {\n recommendations['session_get'] = `Review details of ${activeSessions.length} active session(s)`;\n }\n\n if (completedSessions.length > 1) {\n recommendations['sessions_compare'] = 'Compare completed sessions to identify patterns';\n recommendations['sessions_aggregate'] = 'Generate aggregate insights from multiple sessions';\n }\n\n if (sessions.length > 5) {\n recommendations['sessions_export'] = 'Export session data for comprehensive analysis';\n }\n\n return recommendations;\n}", "function checkArgs(adapter, defaultData) {\n if (adapter === undefined)\n throw new Error('lowdb: missing adapter');\n if (defaultData === undefined)\n throw new Error('lowdb: missing default data');\n}\nexport class Low {\n adapter;\n data;\n constructor(adapter, defaultData) {\n checkArgs(adapter, defaultData);\n this.adapter = adapter;\n this.data = defaultData;\n }\n async read() {\n const data = await this.adapter.read();\n if (data)\n this.data = data;\n }\n async write() {\n if (this.data)\n await this.adapter.write(this.data);\n }\n async update(fn) {\n fn(this.data);\n await this.write();\n }\n}\nexport class LowSync {\n adapter;\n data;\n constructor(adapter, defaultData) {\n checkArgs(adapter, defaultData);\n this.adapter = adapter;\n this.data = defaultData;\n }\n read() {\n const data = this.adapter.read();\n if (data)\n this.data = data;\n }\n write() {\n if (this.data)\n this.adapter.write(this.data);\n }\n update(fn) {\n fn(this.data);\n this.write();\n }\n}\n", "import { readFileSync, renameSync, writeFileSync } from 'node:fs';\nimport { readFile } from 'node:fs/promises';\nimport path from 'node:path';\nimport { Writer } from 'steno';\nexport class TextFile {\n #filename;\n #writer;\n constructor(filename) {\n this.#filename = filename;\n this.#writer = new Writer(filename);\n }\n async read() {\n let data;\n try {\n data = await readFile(this.#filename, 'utf-8');\n }\n catch (e) {\n if (e.code === 'ENOENT') {\n return null;\n }\n throw e;\n }\n return data;\n }\n write(str) {\n return this.#writer.write(str);\n }\n}\nexport class TextFileSync {\n #tempFilename;\n #filename;\n constructor(filename) {\n this.#filename = filename;\n const f = filename.toString();\n this.#tempFilename = path.join(path.dirname(f), `.${path.basename(f)}.tmp`);\n }\n read() {\n let data;\n try {\n data = readFileSync(this.#filename, 'utf-8');\n }\n catch (e) {\n if (e.code === 'ENOENT') {\n return null;\n }\n throw e;\n }\n return data;\n }\n write(str) {\n writeFileSync(this.#tempFilename, str);\n renameSync(this.#tempFilename, this.#filename);\n }\n}\n", "import { TextFile, TextFileSync } from './TextFile.js';\nexport class DataFile {\n #adapter;\n #parse;\n #stringify;\n constructor(filename, { parse, stringify, }) {\n this.#adapter = new TextFile(filename);\n this.#parse = parse;\n this.#stringify = stringify;\n }\n async read() {\n const data = await this.#adapter.read();\n if (data === null) {\n return null;\n }\n else {\n return this.#parse(data);\n }\n }\n write(obj) {\n return this.#adapter.write(this.#stringify(obj));\n }\n}\nexport class DataFileSync {\n #adapter;\n #parse;\n #stringify;\n constructor(filename, { parse, stringify, }) {\n this.#adapter = new TextFileSync(filename);\n this.#parse = parse;\n this.#stringify = stringify;\n }\n read() {\n const data = this.#adapter.read();\n if (data === null) {\n return null;\n }\n else {\n return this.#parse(data);\n }\n }\n write(obj) {\n this.#adapter.write(this.#stringify(obj));\n }\n}\n", "import { DataFile, DataFileSync } from './DataFile.js';\nexport class JSONFile extends DataFile {\n constructor(filename) {\n super(filename, {\n parse: JSON.parse,\n stringify: (data) => JSON.stringify(data, null, 2),\n });\n }\n}\nexport class JSONFileSync extends DataFileSync {\n constructor(filename) {\n super(filename, {\n parse: JSON.parse,\n stringify: (data) => JSON.stringify(data, null, 2),\n });\n }\n}\n", "/**\n * Session Data Management\n * Provides unified JSON storage and session lifecycle management using lowdb\n */\n\nimport { Low } from 'lowdb';\nimport { JSONFileSync } from 'lowdb/node';\nimport { mkdirSync, writeFileSync } from 'fs';\nimport { join } from 'path';\nimport { randomUUID } from 'crypto';\nimport { getProjectTmpBase } from '../utils/temp-dir';\nimport {\n QueryDevelopmentSession,\n QueryState,\n MCPCallRecord,\n TestExecutionRecord,\n QualityScoreRecord,\n SessionFilter,\n MonitoringConfig,\n MonitoringConfigSchema,\n} from '../types/monitoring';\nimport { logger } from '../utils/logger';\n\n/**\n * Database schema for lowdb - sessions only\n */\ninterface SessionDatabase {\n sessions: QueryDevelopmentSession[];\n}\n\n/**\n * Session Data Manager - handles all session persistence and lifecycle\n */\nexport class SessionDataManager {\n private db: Low;\n private config: MonitoringConfig;\n private storageDir: string;\n\n constructor(configOverrides: Partial = {}) {\n this.config = MonitoringConfigSchema.parse({\n ...MonitoringConfigSchema.parse({}),\n ...configOverrides,\n });\n\n this.storageDir = this.config.storageLocation;\n this.ensureStorageDirectory();\n\n const adapter = new JSONFileSync(join(this.storageDir, 'sessions.json'));\n this.db = new Low(adapter, {\n sessions: [],\n });\n\n this.initializeDatabase();\n }\n\n /**\n * Initialize the database and ensure it's properly set up\n */\n async initialize(): Promise {\n await this.initializeDatabase();\n }\n\n /**\n * Initialize the database and ensure it's properly set up\n */\n private async initializeDatabase(): Promise {\n try {\n await this.db.read();\n \n logger.info(`Session data manager initialized with ${this.db.data.sessions.length} sessions`);\n } catch (error) {\n logger.error('Failed to initialize session database:', error);\n throw error;\n }\n }\n\n /**\n * Ensure storage directory structure exists\n */\n private ensureStorageDirectory(): void {\n try {\n // mkdirSync with recursive: true is a no-op if directories already exist\n mkdirSync(this.storageDir, { recursive: true });\n\n // Create subdirectories\n const subdirs = ['sessions-archive', 'exports'];\n for (const subdir of subdirs) {\n mkdirSync(join(this.storageDir, subdir), { recursive: true });\n }\n\n // Use 'wx' flag (exclusive create) to atomically create config only\n // if it doesn't exist, avoiding TOCTOU race (CWE-367).\n const configPath = join(this.storageDir, 'config.json');\n try {\n writeFileSync(configPath, JSON.stringify(this.config, null, 2), { flag: 'wx' });\n } catch (e: unknown) {\n const err = e as { code?: string };\n if (err.code !== 'EEXIST') throw e;\n }\n\n logger.debug(`Storage directory initialized: ${this.storageDir}`);\n } catch (error) {\n logger.error('Failed to create storage directory:', error);\n throw error;\n }\n }\n\n /**\n * Start a new query development session\n */\n async startSession(\n queryPath: string,\n language?: string,\n queryType?: string,\n description?: string\n ): Promise {\n const sessionId = randomUUID();\n const startTime = new Date().toISOString();\n\n const session: QueryDevelopmentSession = {\n sessionId,\n queryPath,\n language: language || 'unknown',\n queryType,\n description,\n startTime,\n status: 'active',\n mcpCalls: [],\n testExecutions: [],\n qualityScores: [],\n currentState: {\n filesPresent: [],\n compilationStatus: 'unknown',\n testStatus: 'unknown',\n documentationStatus: 'unknown',\n lastActivity: startTime,\n },\n recommendations: [],\n };\n\n await this.db.read();\n this.db.data.sessions.push(session);\n await this.db.write();\n\n logger.info(`Started new session: ${sessionId} for query: ${queryPath}`);\n return sessionId;\n }\n\n /**\n * End a session with final status\n */\n async endSession(\n sessionId: string,\n status: 'completed' | 'failed' | 'abandoned'\n ): Promise {\n await this.db.read();\n \n const session = this.db.data.sessions.find(s => s.sessionId === sessionId);\n if (!session) {\n logger.warn(`Session not found: ${sessionId}`);\n return null;\n }\n\n session.status = status;\n session.endTime = new Date().toISOString();\n session.currentState.lastActivity = session.endTime;\n\n await this.db.write();\n\n // Archive completed session if enabled\n if (this.config.archiveCompletedSessions && status === 'completed') {\n await this.archiveSession(sessionId);\n }\n\n logger.info(`Ended session: ${sessionId} with status: ${status}`);\n return session;\n }\n\n /**\n * Get a specific session by ID\n */\n async getSession(sessionId: string): Promise {\n await this.db.read();\n const session = this.db.data.sessions.find(s => s.sessionId === sessionId);\n return session || null;\n }\n\n /**\n * List sessions with optional filtering\n */\n async listSessions(filters?: SessionFilter): Promise {\n await this.db.read();\n let sessions = [...this.db.data.sessions];\n\n if (filters) {\n if (filters.queryPath) {\n sessions = sessions.filter(s => s.queryPath.includes(filters.queryPath!));\n }\n if (filters.status) {\n sessions = sessions.filter(s => s.status === filters.status);\n }\n if (filters.language) {\n sessions = sessions.filter(s => s.language === filters.language);\n }\n if (filters.queryType) {\n sessions = sessions.filter(s => s.queryType === filters.queryType);\n }\n if (filters.dateRange) {\n const [start, end] = filters.dateRange;\n sessions = sessions.filter(s => \n s.startTime >= start && s.startTime <= end\n );\n }\n }\n\n return sessions;\n }\n\n /**\n * Update session state\n */\n async updateSessionState(\n sessionId: string,\n stateUpdate: Partial\n ): Promise {\n await this.db.read();\n \n const session = this.db.data.sessions.find(s => s.sessionId === sessionId);\n if (!session) {\n logger.warn(`Session not found: ${sessionId}`);\n return null;\n }\n\n session.currentState = {\n ...session.currentState,\n ...stateUpdate,\n lastActivity: new Date().toISOString(),\n };\n\n await this.db.write();\n return session;\n }\n\n /**\n * Add MCP call record to session\n */\n async addMCPCall(sessionId: string, callRecord: MCPCallRecord): Promise {\n await this.db.read();\n \n const session = this.db.data.sessions.find(s => s.sessionId === sessionId);\n if (!session) {\n logger.warn(`Session not found for MCP call: ${sessionId}`);\n return;\n }\n\n session.mcpCalls.push(callRecord);\n session.currentState.lastActivity = callRecord.timestamp;\n\n // Update next suggested tool if provided\n if (callRecord.nextSuggestedTool) {\n session.nextSuggestedTool = callRecord.nextSuggestedTool;\n }\n\n await this.db.write();\n }\n\n /**\n * Add test execution record to session\n */\n async addTestExecution(sessionId: string, testRecord: TestExecutionRecord): Promise {\n await this.db.read();\n \n const session = this.db.data.sessions.find(s => s.sessionId === sessionId);\n if (!session) {\n logger.warn(`Session not found for test execution: ${sessionId}`);\n return;\n }\n\n session.testExecutions.push(testRecord);\n session.currentState.lastActivity = testRecord.timestamp;\n\n // Update compilation/test status based on execution\n if (testRecord.type === 'compilation') {\n session.currentState.compilationStatus = testRecord.success ? 'success' : 'failed';\n } else if (testRecord.type === 'test_run') {\n session.currentState.testStatus = testRecord.success ? 'passing' : 'failing';\n }\n\n await this.db.write();\n }\n\n /**\n * Add quality score record to session\n */\n async addQualityScore(sessionId: string, scoreRecord: QualityScoreRecord): Promise {\n await this.db.read();\n \n const session = this.db.data.sessions.find(s => s.sessionId === sessionId);\n if (!session) {\n logger.warn(`Session not found for quality score: ${sessionId}`);\n return;\n }\n\n session.qualityScores.push(scoreRecord);\n session.currentState.lastActivity = scoreRecord.timestamp;\n session.recommendations = scoreRecord.recommendations;\n\n await this.db.write();\n }\n\n /**\n * Archive a completed session to monthly file\n */\n private async archiveSession(sessionId: string): Promise {\n try {\n const session = await this.getSession(sessionId);\n if (!session) return;\n\n const date = new Date(session.endTime || session.startTime);\n const monthDir = `${date.getFullYear()}-${String(date.getMonth() + 1).padStart(2, '0')}`;\n const archiveDir = join(this.storageDir, 'sessions-archive', monthDir);\n\n mkdirSync(archiveDir, { recursive: true });\n\n const archiveFile = join(archiveDir, `${sessionId}.json`);\n writeFileSync(archiveFile, JSON.stringify(session, null, 2));\n\n // Remove from active sessions\n await this.db.read();\n this.db.data.sessions = this.db.data.sessions.filter(s => s.sessionId !== sessionId);\n await this.db.write();\n\n logger.info(`Archived session: ${sessionId} to ${archiveFile}`);\n } catch (error) {\n logger.error(`Failed to archive session ${sessionId}:`, error);\n }\n }\n\n /**\n * Get active sessions for a specific query path\n */\n async getActiveSessionsForQuery(queryPath: string): Promise {\n await this.db.read();\n return this.db.data.sessions.filter(s => \n s.queryPath === queryPath && s.status === 'active'\n );\n }\n\n /**\n * Clean up old sessions based on retention policy\n */\n async cleanupOldSessions(): Promise {\n const cutoffDate = new Date();\n cutoffDate.setDate(cutoffDate.getDate() - this.config.retentionDays);\n const cutoffTimestamp = cutoffDate.toISOString();\n\n await this.db.read();\n const sessionsToRemove = this.db.data.sessions.filter(s => \n s.endTime && s.endTime < cutoffTimestamp\n );\n\n if (sessionsToRemove.length > 0) {\n this.db.data.sessions = this.db.data.sessions.filter(s => \n !s.endTime || s.endTime >= cutoffTimestamp\n );\n await this.db.write();\n\n logger.info(`Cleaned up ${sessionsToRemove.length} old sessions`);\n }\n }\n\n /**\n * Get configuration\n */\n getConfig(): MonitoringConfig {\n return this.config;\n }\n\n /**\n * Update configuration\n */\n async updateConfig(configUpdate: Partial): Promise {\n this.config = MonitoringConfigSchema.parse({\n ...this.config,\n ...configUpdate,\n });\n\n // Update config.json file only\n const configPath = join(this.storageDir, 'config.json');\n writeFileSync(configPath, JSON.stringify(this.config, null, 2));\n\n logger.info('Updated monitoring configuration');\n }\n}\n\n/**\n * Parse boolean environment variable\n */\nfunction parseBoolEnv(envVar: string | undefined, defaultValue: boolean): boolean {\n if (envVar === undefined) return defaultValue;\n return envVar.toLowerCase() === 'true' || envVar === '1';\n}\n\n// Export singleton instance with environment variable support\nexport const sessionDataManager = new SessionDataManager({\n storageLocation: process.env.MONITORING_STORAGE_LOCATION || join(getProjectTmpBase(), '.ql-mcp-tracking'),\n enableMonitoringTools: parseBoolEnv(process.env.ENABLE_MONITORING_TOOLS, false),\n});", "import { z } from 'zod';\n\n/**\n * Monitoring and Reporting types for CodeQL Development MCP Server\n * Based on the specification in docs/mcp-server-monitoring-and-reporting.md\n */\n\n/**\n * MCP Call Record - captures individual MCP tool calls\n */\nexport const MCPCallRecordSchema = z.object({\n callId: z.string(),\n timestamp: z.string(), // ISO timestamp\n toolName: z.string(),\n parameters: z.record(z.any()),\n result: z.any(),\n success: z.boolean(),\n duration: z.number(), // milliseconds\n nextSuggestedTool: z.string().optional(),\n});\n\nexport type MCPCallRecord = z.infer;\n\n/**\n * Test Execution Record - captures query compilation and test runs\n */\nexport const TestExecutionRecordSchema = z.object({\n executionId: z.string(),\n timestamp: z.string(),\n type: z.enum(['compilation', 'test_run', 'database_build']),\n success: z.boolean(),\n details: z.record(z.any()),\n metrics: z.object({\n passRate: z.number().optional(),\n coverage: z.number().optional(),\n performance: z.number().optional(),\n }).optional(),\n});\n\nexport type TestExecutionRecord = z.infer;\n\n/**\n * Quality Score Record - multi-dimensional quality assessment\n */\nexport const QualityScoreRecordSchema = z.object({\n scoreId: z.string(),\n timestamp: z.string(),\n overallScore: z.number().min(0).max(100), // 0-100\n dimensions: z.object({\n syntacticCorrectness: z.number().min(0).max(100),\n testCoverageResults: z.number().min(0).max(100),\n documentationQuality: z.number().min(0).max(100),\n functionalCorrectness: z.number().min(0).max(100),\n }),\n grade: z.enum(['A', 'B', 'C', 'D', 'F']),\n recommendations: z.array(z.string()),\n});\n\nexport type QualityScoreRecord = z.infer;\n\n/**\n * Query State - current state of the query development\n */\nexport const QueryStateSchema = z.object({\n filesPresent: z.array(z.string()),\n compilationStatus: z.enum(['unknown', 'success', 'failed']),\n testStatus: z.enum(['unknown', 'passing', 'failing', 'no_tests']),\n documentationStatus: z.enum(['unknown', 'present', 'missing', 'incomplete']),\n lastActivity: z.string(), // ISO timestamp\n});\n\nexport type QueryState = z.infer;\n\n/**\n * Query Development Session - main data structure for tracking\n */\nexport const QueryDevelopmentSessionSchema = z.object({\n // Session Metadata\n sessionId: z.string(),\n queryPath: z.string(),\n language: z.string(),\n queryType: z.string().optional(),\n description: z.string().optional(),\n startTime: z.string(), // ISO timestamp\n endTime: z.string().optional(), // ISO timestamp\n status: z.enum(['active', 'completed', 'failed', 'abandoned']),\n\n // MCP Call History\n mcpCalls: z.array(MCPCallRecordSchema),\n\n // Test Execution Records\n testExecutions: z.array(TestExecutionRecordSchema),\n\n // Quality Metrics\n qualityScores: z.array(QualityScoreRecordSchema),\n\n // Development State\n currentState: QueryStateSchema,\n recommendations: z.array(z.string()),\n nextSuggestedTool: z.string().optional(),\n});\n\nexport type QueryDevelopmentSession = z.infer;\n\n/**\n * Session Filter for listing and searching\n */\nexport const SessionFilterSchema = z.object({\n queryPath: z.string().optional(),\n status: z.string().optional(),\n dateRange: z.tuple([z.string(), z.string()]).optional(),\n language: z.string().optional(),\n queryType: z.string().optional(),\n});\n\nexport type SessionFilter = z.infer;\n\n/**\n * Comparison Report for analyzing multiple sessions\n */\nexport const ComparisonReportSchema = z.object({\n sessionIds: z.array(z.string()),\n dimensions: z.array(z.string()),\n timestamp: z.string(),\n results: z.record(z.any()),\n});\n\nexport type ComparisonReport = z.infer;\n\n/**\n * Aggregate Report for batch analysis\n */\nexport const AggregateReportSchema = z.object({\n filters: SessionFilterSchema,\n timestamp: z.string(),\n totalSessions: z.number(),\n successRate: z.number(),\n averageQualityScore: z.number(),\n commonPatterns: z.array(z.string()),\n recommendations: z.array(z.string()),\n});\n\nexport type AggregateReport = z.infer;\n\n/**\n * Export Result for data export operations\n */\nexport const ExportResultSchema = z.object({\n format: z.enum(['json', 'html', 'markdown']),\n filename: z.string(),\n content: z.string(),\n timestamp: z.string(),\n});\n\nexport type ExportResult = z.infer;\n\n/**\n * Functional Test Result for automated testing\n */\nexport const FunctionalTestResultSchema = z.object({\n sessionId: z.string(),\n queryPath: z.string(),\n passed: z.boolean(),\n criteria: z.record(z.any()),\n details: z.record(z.any()),\n timestamp: z.string(),\n});\n\nexport type FunctionalTestResult = z.infer;\n\n/**\n * Test Report for comprehensive test analysis\n */\nexport const TestReportSchema = z.object({\n sessionIds: z.array(z.string()),\n criteria: z.record(z.any()),\n timestamp: z.string(),\n overallPassRate: z.number(),\n results: z.array(FunctionalTestResultSchema),\n summary: z.record(z.any()),\n});\n\nexport type TestReport = z.infer;\n\n/**\n * Monitoring Configuration\n */\nexport const MonitoringConfigSchema = z.object({\n storageLocation: z.string().default('.ql-mcp-tracking/'),\n autoTrackSessions: z.boolean().default(true),\n retentionDays: z.number().default(90),\n includeCallParameters: z.boolean().default(true),\n includeCallResults: z.boolean().default(true),\n maxActiveSessionsPerQuery: z.number().default(3),\n scoringFrequency: z.enum(['per_call', 'periodic', 'manual']).default('per_call'),\n archiveCompletedSessions: z.boolean().default(true),\n enableRecommendations: z.boolean().default(true),\n enableMonitoringTools: z.boolean().default(false), // Opt-in: session_* tools disabled by default for end-users\n});\n\nexport type MonitoringConfig = z.infer;"], + "mappings": "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", "names": ["type", "resolve", "setTimeout", "resolve", "setTimeout", "clearTimeout", "join", "resolve", "spawn", "delimiter", "EventEmitter", "clearTimeout", "setTimeout", "resolve", "spawn", "delimiter", "EventEmitter", "clearTimeout", "setTimeout", "resolve", "mkdirSync", "join", "type", "packageRootDir", "resolve", "existsSync", "delimiter", "dirname", "isAbsolute", "binary", "getServerManager", "resolve", "pathToFileURL", "z", "readFileSync", "dirname", "isAbsolute", "mkdirSync", "mkdirSync", "existsSync", "join", "resolve", "timestamp", "writeFileSync", "existsSync", "mkdirSync", "basename", "dirname", "isAbsolute", "join", "resolve", "logger", "executeCodeQLCommand", "basename", "mkdirSync", "dirname", "z", "z", "z", "z", "z", "z", "z", "z", "z", "z", "readFile", "z", "exception", "map", "schema", "type", "extend", "str", "string", "z", "z", "z", "z", "z", "existsSync", "readdirSync", "readFileSync", "statSync", "join", "z", "readFileSync", "existsSync", "readdirSync", "join", "statSync", "z", "existsSync", "readdirSync", "readFileSync", "statSync", "join", "z", "existsSync", "readdirSync", "join", "statSync", "timestamp", "readFileSync", "z", "existsSync", "readdirSync", "readFileSync", "statSync", "join", "z", "existsSync", "readdirSync", "join", "statSync", "timestamp", "readFileSync", "z", "z", "z", "z", "z", "existsSync", "mkdirSync", "writeFileSync", "basename", "dirname", "join", "z", "readFileSync", "basename", "z", "existsSync", "dirname", "mkdirSync", "join", "writeFileSync", "z", "writeFileSync", "readFileSync", "existsSync", "join", "dirname", "basename", "mkdirSync", "parseEvaluatorLog", "formatAsJson", "formatAsMermaid", "z", "z", "z", "z", "z", "z", "join", "resolve", "resolve", "join", "z", "z", "resolve", "z", "z", "z", "z", "z", "z", "z", "z", "z", "z", "z", "z", "z", "z", "z", "z", "z", "z", "z", "z", "fs", "path", "getLanguageExtension", "z", "readFileSync", "join", "dirname", "fileURLToPath", "__filename", "__dirname", "z", "join", "pathToFileURL", "isAbsolute", "resolve", "pathToFileURL", "getUserWorkspaceDir", "pathToFileURL", "join", "z", "readFile", "isAbsolute", "resolve", "pathToFileURL", "isAbsolute", "resolve", "pathToFileURL", "readFile", "z", "z", "readFileSync", "existsSync", "join", "join", "existsSync", "readFileSync", "z", "basename", "readFileSync", "join", "dirname", "fileURLToPath", "__filename", "__dirname", "z", "basename", "z", "randomUUID", "readFileSync", "writeFileSync", "path", "path", "readFileSync", "str", "writeFileSync", "parse", "mkdirSync", "writeFileSync", "join", "randomUUID", "z", "join", "mkdirSync", "writeFileSync", "randomUUID", "z", "timestamp", "randomUUID", "resolve", "pathToFileURL"] } diff --git a/server/package.json b/server/package.json index 85a859cd..a1b09826 100644 --- a/server/package.json +++ b/server/package.json @@ -57,26 +57,26 @@ "dependencies": { "@modelcontextprotocol/sdk": "^1.26.0", "cors": "^2.8.6", - "dotenv": "^17.3.0", + "dotenv": "^17.3.1", "express": "^5.2.1", "js-yaml": "^4.1.1", "lowdb": "^7.0.1", "zod": "^3.25.76" }, "devDependencies": { - "@eslint/js": "^9.39.2", + "@eslint/js": "^10.0.1", "@types/cors": "^2.8.19", "@types/express": "^5.0.6", "@types/js-yaml": "^4.0.9", - "@types/node": "^25.2.1", + "@types/node": "^25.3.0", "@vitest/coverage-v8": "^4.0.18", "esbuild": "^0.27.3", - "eslint": "^9.39.2", + "eslint": "^10.0.0", "eslint-config-prettier": "^10.1.8", "eslint-plugin-prettier": "^5.5.5", "prettier": "^3.8.1", "typescript": "^5.9.3", - "typescript-eslint": "^8.54.0", + "typescript-eslint": "^8.56.0", "vitest": "^4.0.18" }, "scripts": { diff --git a/server/src/lib/cli-executor.ts b/server/src/lib/cli-executor.ts index 4a834c57..a1f9b19b 100644 --- a/server/src/lib/cli-executor.ts +++ b/server/src/lib/cli-executor.ts @@ -215,7 +215,8 @@ export async function validateCodeQLBinaryReachable(): Promise { throw new Error( `CodeQL CLI is not reachable (binary: ${binary}). ` + `Ensure codeql is on PATH or set the CODEQL_PATH environment variable ` + - `to the absolute path of the CodeQL CLI binary. Details: ${message}` + `to the absolute path of the CodeQL CLI binary. Details: ${message}`, + { cause: err } ); } } diff --git a/server/src/lib/cli-tool-registry.ts b/server/src/lib/cli-tool-registry.ts index 4b3a7599..49fa2bbc 100644 --- a/server/src/lib/cli-tool-registry.ts +++ b/server/src/lib/cli-tool-registry.ts @@ -679,7 +679,7 @@ async function resolveQueryPath( resolvedQueries = JSON.parse(resolveResult.stdout); } catch (parseError) { logger.error('Failed to parse resolve queries output:', parseError); - throw new Error('Failed to parse resolve queries output'); + throw new Error('Failed to parse resolve queries output', { cause: parseError }); } // Find the query that matches the requested name exactly diff --git a/server/src/lib/query-scaffolding.ts b/server/src/lib/query-scaffolding.ts index 23842e7c..24d7ac7b 100644 --- a/server/src/lib/query-scaffolding.ts +++ b/server/src/lib/query-scaffolding.ts @@ -132,6 +132,6 @@ export function createCodeQLQuery(options: QueryScaffoldingOptions): QueryScaffo filesCreated }; } catch (error) { - throw new Error(`Failed to create query scaffolding: ${error instanceof Error ? error.message : 'Unknown error'}`); + throw new Error(`Failed to create query scaffolding: ${error instanceof Error ? error.message : 'Unknown error'}`, { cause: error }); } } diff --git a/server/src/lib/session-tracking.ts b/server/src/lib/session-tracking.ts index f5f02d77..51181a68 100644 --- a/server/src/lib/session-tracking.ts +++ b/server/src/lib/session-tracking.ts @@ -269,7 +269,7 @@ export function withSessionTracking( return async (..._args: T): Promise => { const startTime = Date.now(); let success = false; - let result: R; + let result: R | undefined; let sessionId: string | null = null; try { @@ -287,9 +287,6 @@ export function withSessionTracking( success = true; return result; - } catch (error) { - success = false; - throw error; } finally { const duration = Date.now() - startTime; @@ -358,7 +355,7 @@ export function withAdvancedSessionTracking( return async (..._args: T): Promise => { const startTime = Date.now(); let success = false; - let result: R; + let result: R | undefined; let sessionId: string | null = null; try { @@ -394,9 +391,6 @@ export function withAdvancedSessionTracking( } return result; - } catch (error) { - success = false; - throw error; } finally { const duration = Date.now() - startTime; diff --git a/server/src/tools/codeql/find-class-position.ts b/server/src/tools/codeql/find-class-position.ts index 8ce45b0e..a4ed27ff 100644 --- a/server/src/tools/codeql/find-class-position.ts +++ b/server/src/tools/codeql/find-class-position.ts @@ -54,7 +54,7 @@ export async function findClassPosition(filepath: string, className: string): Pr if (error instanceof Error && error.message.includes('not found in file')) { throw error; } - throw new Error(`Failed to read or parse file ${filepath}: ${error instanceof Error ? error.message : 'Unknown error'}`); + throw new Error(`Failed to read or parse file ${filepath}: ${error instanceof Error ? error.message : 'Unknown error'}`, { cause: error }); } } diff --git a/server/src/tools/codeql/find-predicate-position.ts b/server/src/tools/codeql/find-predicate-position.ts index 3d3b8bbd..3a3c06bc 100644 --- a/server/src/tools/codeql/find-predicate-position.ts +++ b/server/src/tools/codeql/find-predicate-position.ts @@ -69,7 +69,7 @@ export async function findPredicatePosition(filepath: string, predicateName: str if (error instanceof Error && error.message.includes('not found in file')) { throw error; } - throw new Error(`Failed to read or parse file ${filepath}: ${error instanceof Error ? error.message : 'Unknown error'}`); + throw new Error(`Failed to read or parse file ${filepath}: ${error instanceof Error ? error.message : 'Unknown error'}`, { cause: error }); } } diff --git a/server/src/tools/codeql/quick-evaluate.ts b/server/src/tools/codeql/quick-evaluate.ts index bc5f027c..5d908b44 100644 --- a/server/src/tools/codeql/quick-evaluate.ts +++ b/server/src/tools/codeql/quick-evaluate.ts @@ -50,7 +50,7 @@ export async function quickEvaluate({ // to perform the actual quick evaluation with the position parameters return resolvedOutput; } catch (error) { - throw new Error(`CodeQL evaluation failed: ${error instanceof Error ? error.message : 'Unknown error'}`); + throw new Error(`CodeQL evaluation failed: ${error instanceof Error ? error.message : 'Unknown error'}`, { cause: error }); } } diff --git a/server/src/tools/codeql/register-database.ts b/server/src/tools/codeql/register-database.ts index 2cef0e31..018783f8 100644 --- a/server/src/tools/codeql/register-database.ts +++ b/server/src/tools/codeql/register-database.ts @@ -72,15 +72,15 @@ export async function registerDatabase(dbPath: string): Promise { const errorCode = (error as { code?: string }).code; if (errorCode === 'ENOENT') { if (error.message.includes('codeql-database.yml')) { - throw new Error(`Missing required codeql-database.yml in: ${dbPath}`); + throw new Error(`Missing required codeql-database.yml in: ${dbPath}`, { cause: error }); } - throw new Error(`Database path does not exist: ${dbPath}`); + throw new Error(`Database path does not exist: ${dbPath}`, { cause: error }); } if (errorCode === 'EACCES') { - throw new Error(`Database path does not exist: ${dbPath}`); + throw new Error(`Database path does not exist: ${dbPath}`, { cause: error }); } } - throw new Error(`Failed to register database: ${error instanceof Error ? error.message : 'Unknown error'}`); + throw new Error(`Failed to register database: ${error instanceof Error ? error.message : 'Unknown error'}`, { cause: error }); } } diff --git a/server/src/tools/lsp/lsp-diagnostics.ts b/server/src/tools/lsp/lsp-diagnostics.ts index a34a33ef..61cc3db6 100644 --- a/server/src/tools/lsp/lsp-diagnostics.ts +++ b/server/src/tools/lsp/lsp-diagnostics.ts @@ -126,7 +126,7 @@ export async function lspDiagnostics({ } catch (error) { logger.error('Error evaluating QL code:', error); - throw new Error(`QL evaluation failed: ${error instanceof Error ? error.message : 'Unknown error'}`); + throw new Error(`QL evaluation failed: ${error instanceof Error ? error.message : 'Unknown error'}`, { cause: error }); } } diff --git a/server/src/tools/lsp/lsp-handlers.ts b/server/src/tools/lsp/lsp-handlers.ts index ff5dc1f6..0920d347 100644 --- a/server/src/tools/lsp/lsp-handlers.ts +++ b/server/src/tools/lsp/lsp-handlers.ts @@ -84,7 +84,7 @@ async function openDocumentForPosition( try { text = await readFile(absPath, 'utf-8'); } catch (error) { - throw new Error(`Cannot read file: ${absPath}: ${error instanceof Error ? error.message : error}`); + throw new Error(`Cannot read file: ${absPath}: ${error instanceof Error ? error.message : error}`, { cause: error }); } } From 468b7caeb2cb3360277cf66ebfd479b6f3eab46b Mon Sep 17 00:00:00 2001 From: Nathan Randall Date: Thu, 19 Feb 2026 18:20:16 -0700 Subject: [PATCH 12/14] Update docs for vscode extension --- docs/getting-started.md | 12 ++++- docs/vscode/extension.md | 23 +++++++- extensions/vscode/README.md | 95 +++++++++++++++++++++++++++++++++- extensions/vscode/package.json | 2 +- package-lock.json | 2 +- package.json | 1 + 6 files changed, 129 insertions(+), 6 deletions(-) diff --git a/docs/getting-started.md b/docs/getting-started.md index 000a110e..86c04984 100644 --- a/docs/getting-started.md +++ b/docs/getting-started.md @@ -10,7 +10,17 @@ This guide covers installation, configuration, and usage of the CodeQL Developme ## Installation -### From npm (recommended) +### VS Code Extension (recommended) + +The easiest way to get started is the **VS Code extension**, which automates +installation, configuration, and CodeQL CLI discovery. +See the [VS Code Extension guide](./vscode/extension.md) for details. + +The `.vsix` can be downloaded from +[GitHub Releases](https://github.com/advanced-security/codeql-development-mcp-server/releases) +or built from source (`npm run package:vscode` at the repository root). + +### From npm The package is published to the [public npm registry](https://www.npmjs.com/package/codeql-development-mcp-server). No authentication or special configuration is needed: diff --git a/docs/vscode/extension.md b/docs/vscode/extension.md index 1bb583a6..4941dd7c 100644 --- a/docs/vscode/extension.md +++ b/docs/vscode/extension.md @@ -15,13 +15,34 @@ to do by hand. ## Installation -Install from the VS Code Marketplace: +### From `.vsix` (GitHub Releases) + +Download `codeql-development-mcp-server.vsix` from the latest +[GitHub Release](https://github.com/advanced-security/codeql-development-mcp-server/releases), +then install: + +```bash +code --install-extension codeql-development-mcp-server.vsix +``` + +Or in VS Code: **Extensions** sidebar → `⋯` menu → **Install from VSIX…** → select the file. + +### From VS Code Marketplace 1. Open VS Code 2. Go to Extensions (`Ctrl+Shift+X` / `Cmd+Shift+X`) 3. Search **"CodeQL Development MCP Server"** 4. Click **Install** +### From Source + +From the repository root: + +```bash +npm run package:vscode +code --install-extension extensions/vscode/codeql-development-mcp-server.vsix +``` + The extension requires the [CodeQL extension](https://marketplace.visualstudio.com/items?itemName=GitHub.vscode-codeql) (`GitHub.vscode-codeql`) and will prompt you to install it if missing. ## What it does diff --git a/extensions/vscode/README.md b/extensions/vscode/README.md index df736e34..bac14f8f 100644 --- a/extensions/vscode/README.md +++ b/extensions/vscode/README.md @@ -1,3 +1,94 @@ -# VS Code Extension for `codeql-development-mcp-server` +# CodeQL Development MCP Server — VS Code Extension -TODO +A VS Code extension that automatically installs, configures, and manages the [CodeQL Development MCP Server](https://github.com/advanced-security/codeql-development-mcp-server). It bridges the [`GitHub.vscode-codeql`](https://marketplace.visualstudio.com/items?itemName=GitHub.vscode-codeql) extension with AI assistants by exposing CodeQL databases, query results, and MRVA results to the MCP server. + +## Prerequisites + +- **VS Code** `^1.109.0` +- **Node.js** `>=24.13.0` +- **[CodeQL for VS Code](https://marketplace.visualstudio.com/items?itemName=GitHub.vscode-codeql)** — declared as an `extensionDependency` and must be installed first. + +## Installation + +### From `.vsix` + +```bash +code --install-extension codeql-development-mcp-server.vsix +``` + +Or in VS Code: **Extensions** sidebar → `⋯` menu → **Install from VSIX…** → select the file. + +### From Source + +```bash +cd extensions/vscode +npm run package +code --install-extension codeql-development-mcp-server.vsix +``` + +## What It Does + +On activation (`onStartupFinished`), the extension: + +1. **Auto-installs** the `codeql-development-mcp-server` npm package (unless `codeql-mcp.autoInstall` is `false`). +2. **Registers an MCP server definition** (`ql-mcp`) so VS Code's Copilot/MCP integration can discover and launch it. +3. **Watches** the CodeQL extension's storage paths for databases, query results, and MRVA results, passing them to the MCP server as environment variables. + +## Configuration + +All settings are under the `codeql-mcp` namespace in VS Code settings: + +| Setting | Default | Description | +| ------------------------------------------ | ---------- | ------------------------------------------------------------------- | +| `codeql-mcp.autoInstall` | `true` | Auto-install/update the MCP server on activation. | +| `codeql-mcp.serverVersion` | `"latest"` | npm version to install (`"latest"` for most recent). | +| `codeql-mcp.serverCommand` | `"node"` | Command to launch the server. Override to `"npx"` or a custom path. | +| `codeql-mcp.serverArgs` | `[]` | Custom args. When empty, the bundled entry point is used. | +| `codeql-mcp.watchCodeqlExtension` | `true` | Watch for databases and results from the CodeQL extension. | +| `codeql-mcp.additionalEnv` | `{}` | Extra environment variables passed to the server process. | +| `codeql-mcp.additionalDatabaseDirs` | `[]` | Additional directories to search for CodeQL databases. | +| `codeql-mcp.additionalMrvaRunResultsDirs` | `[]` | Additional directories containing MRVA run results. | +| `codeql-mcp.additionalQueryRunResultsDirs` | `[]` | Additional directories containing query run results. | + +## Commands + +Available from the Command Palette (`Cmd+Shift+P` / `Ctrl+Shift+P`): + +| Command | Description | +| ------------------------------------------------- | ----------------------------------------------- | +| **CodeQL MCP: Reinstall MCP Server** | Re-download and install the server package. | +| **CodeQL MCP: Reinstall CodeQL Tool Query Packs** | Re-install the bundled CodeQL tool query packs. | +| **CodeQL MCP: Show Status** | Display current server status. | +| **CodeQL MCP: Show Logs** | Open the server log output. | + +## Development + +### npm Scripts + +| Script | What it does | When to use | +| ----------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------- | +| `npm run package` | **Builds everything and produces the `.vsix`**. Internally runs `vscode:prepublish` (clean → lint → bundle → bundle:server) then `vsce package`. | **Building a distributable `.vsix`.** | +| `npm run build` | `clean` → `lint` → `bundle` (extension only, no server). | Development builds without packaging. | +| `npm run bundle` | esbuild the extension (no lint, no clean). | Fast iteration during development. | +| `npm run watch` | Rebuild the extension on file changes. | Active development. | +| `npm run test` | Run unit tests with Vitest. | Validating changes. | +| `npm run test:coverage` | Run unit tests with coverage. | CI / pre-merge validation. | +| `npm run lint` | Run ESLint on `src/` and `test/`. | Checking code style. | + +> **Note:** `vscode:prepublish` is a lifecycle hook invoked automatically by `vsce package` — you should not need to run it directly. + +### Project Structure + +```text +extensions/vscode/ +├── src/ +│ ├── extension.ts # Extension entry point (activate/deactivate) +│ ├── bridge/ # Watches CodeQL extension storage paths +│ ├── codeql/ # CodeQL CLI resolution +│ ├── common/ # Shared utilities +│ └── server/ # MCP server lifecycle management +├── test/ # Vitest unit tests +├── esbuild.config.js # Extension bundler config +├── scripts/bundle-server.js # Copies MCP server into the extension +└── package.json +``` diff --git a/extensions/vscode/package.json b/extensions/vscode/package.json index 504a2b08..897c3478 100644 --- a/extensions/vscode/package.json +++ b/extensions/vscode/package.json @@ -15,7 +15,7 @@ "url": "https://github.com/advanced-security/codeql-development-mcp-server/issues" }, "engines": { - "vscode": "^1.99.0", + "vscode": "^1.109.0", "node": ">=24.13.0" }, "categories": [ diff --git a/package-lock.json b/package-lock.json index 918d0446..10761b83 100644 --- a/package-lock.json +++ b/package-lock.json @@ -74,7 +74,7 @@ }, "engines": { "node": ">=24.13.0", - "vscode": "^1.99.0" + "vscode": "^1.109.0" } }, "extensions/vscode/node_modules/balanced-match": { diff --git a/package.json b/package.json index cc532b6e..3bfc7356 100644 --- a/package.json +++ b/package.json @@ -47,6 +47,7 @@ "test:client": "npm run test:integration:default -w client", "test:server": "npm run test -w server", "test:vscode": "npm run test -w extensions/vscode", + "package:vscode": "npm run package -w extensions/vscode", "tidy": "npm run lint:fix && npm run format", "tidy:check": "npm run lint && npm run format:check", "upgrade": "npm run upgrade:node", From a3a2029af41b010f52fc59ee3fdd0f2db4434dcd Mon Sep 17 00:00:00 2001 From: Nathan Randall Date: Thu, 19 Feb 2026 20:12:53 -0700 Subject: [PATCH 13/14] Add codeql-icon.png for vscode extension --- extensions/vscode/media/codeql-icon.png | Bin 0 -> 31407 bytes extensions/vscode/package.json | 1 + 2 files changed, 1 insertion(+) create mode 100644 extensions/vscode/media/codeql-icon.png diff --git a/extensions/vscode/media/codeql-icon.png b/extensions/vscode/media/codeql-icon.png new file mode 100644 index 0000000000000000000000000000000000000000..b457504f8698688b1beb3ce4b5814310cdcf99ca GIT binary patch literal 31407 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 literal 0 HcmV?d00001 diff --git a/extensions/vscode/package.json b/extensions/vscode/package.json index 897c3478..1f93e441 100644 --- a/extensions/vscode/package.json +++ b/extensions/vscode/package.json @@ -5,6 +5,7 @@ "version": "2.24.1", "publisher": "advanced-security", "license": "SEE LICENSE IN LICENSE", + "icon": "media/codeql-icon.png", "repository": { "type": "git", "url": "git+https://github.com/advanced-security/codeql-development-mcp-server.git" From 39b5f2a61ac0f78a203042ad71f1094c509610f5 Mon Sep 17 00:00:00 2001 From: Nathan Randall Date: Fri, 20 Feb 2026 06:49:00 -0700 Subject: [PATCH 14/14] Add dependency-review workflow & config This commit adds a dependency-review.yml actions workflow and its associated "config-file": - .github/dependency-review-config.yml - .github/workflows/dependency-review.yml --- .github/dependency-review-config.yml | 53 +++++++++++++++++++++++++ .github/workflows/dependency-review.yml | 21 ++++++++++ 2 files changed, 74 insertions(+) create mode 100644 .github/dependency-review-config.yml create mode 100644 .github/workflows/dependency-review.yml diff --git a/.github/dependency-review-config.yml b/.github/dependency-review-config.yml new file mode 100644 index 00000000..735efb65 --- /dev/null +++ b/.github/dependency-review-config.yml @@ -0,0 +1,53 @@ +# Dependency Review Configuration +# https://github.com/actions/dependency-review-action?tab=readme-ov-file#configuration-options +# +# All allowed packages are transitive devDependencies that cannot be directly +# controlled. They come from: +# - @vscode/vsce (VS Code extension packaging tool) — 16 packages +# - mocha (VS Code integration test runner) — 1 package +# +# None of these packages are bundled into the published extension (.vsix) or +# the published npm package (codeql-development-mcp-server). They are only +# present during development and CI builds. + +# Fail only on critical/high severity vulnerabilities in production dependencies. +fail-on-severity: 'high' + +# Allow specific transitive devDependencies with OpenSSF Scorecard below +# the repository threshold of 3. Each is a transitive dependency of either +# @vscode/vsce or mocha and cannot be removed or replaced. +allow-packages: + # @vscode/vsce → form-data → asynckit + - 'pkg:npm/asynckit' + # @vscode/vsce → keytar → prebuild-install → tar-fs → tar-stream → bl → buffer → base64-js + - 'pkg:npm/base64-js' + # @vscode/vsce → form-data → combined-stream + - 'pkg:npm/combined-stream' + # @vscode/vsce → form-data → combined-stream → delayed-stream + - 'pkg:npm/delayed-stream' + # @vscode/vsce → @azure/identity → @azure/msal-node → jsonwebtoken → jws → jwa → ecdsa-sig-formatter + - 'pkg:npm/ecdsa-sig-formatter' + # @vscode/vsce → yauzl → fd-slicer + - 'pkg:npm/fd-slicer' + # mocha → yargs → get-caller-file + - 'pkg:npm/get-caller-file' + # @vscode/vsce → keytar → prebuild-install → tar-fs → tar-stream → bl → buffer → ieee754 + - 'pkg:npm/ieee754' + # @vscode/vsce → secretlint → globby → fast-glob → merge2 + - 'pkg:npm/merge2' + # @vscode/vsce → yauzl → fd-slicer → pend + - 'pkg:npm/pend' + # @vscode/vsce → keytar → prebuild-install → rc + - 'pkg:npm/rc' + # @vscode/vsce → keytar/jsonwebtoken chains → safe-buffer + - 'pkg:npm/safe-buffer' + # @vscode/vsce → keytar → prebuild-install → simple-get → simple-concat + - 'pkg:npm/simple-concat' + # @vscode/vsce → azure-devops-node-api/typed-rest-client → tunnel + - 'pkg:npm/tunnel' + # @vscode/vsce → @secretlint/secretlint-formatter-sarif → node-sarif-builder → fs-extra → universalify + - 'pkg:npm/universalify' + # @vscode/vsce → keytar → prebuild-install → tar-fs → tar-stream → readable-stream → util-deprecate + - 'pkg:npm/util-deprecate' + # @vscode/vsce → xml2js → xmlbuilder + - 'pkg:npm/xmlbuilder' diff --git a/.github/workflows/dependency-review.yml b/.github/workflows/dependency-review.yml new file mode 100644 index 00000000..71e33d01 --- /dev/null +++ b/.github/workflows/dependency-review.yml @@ -0,0 +1,21 @@ +name: Dependency Review + +on: + pull_request: + branches: ['main'] + +permissions: + contents: read + +jobs: + dependency-review: + name: Dependency Review + runs-on: ubuntu-latest + steps: + - name: Checkout repository + uses: actions/checkout@v6 + + - name: Dependency Review + uses: actions/dependency-review-action@v4 + with: + config-file: '.github/dependency-review-config.yml'