From 84b29af965f195e635dc1ab107867448c19b7354 Mon Sep 17 00:00:00 2001 From: "Max K." <40246850+sttlr@users.noreply.github.com> Date: Sun, 21 Dec 2025 16:48:06 +0200 Subject: [PATCH] feat: php, javascript plugins --- pyproject.toml | 2 + src/metis/plugin_loader.py | 16 +++ src/metis/plugins/javascript_plugin.py | 48 ++++++++ src/metis/plugins/php_plugin.py | 65 +++++++++++ src/metis/plugins/plugins.yaml | 152 ++++++++++++++++++++++++- 5 files changed, 277 insertions(+), 6 deletions(-) create mode 100644 src/metis/plugins/javascript_plugin.py create mode 100644 src/metis/plugins/php_plugin.py diff --git a/pyproject.toml b/pyproject.toml index a36f42e..3495d28 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -69,3 +69,5 @@ rust = "metis.plugins.rust_plugin:RustPlugin" terraform = "metis.plugins.terraform_plugin:TerraformPlugin" tablegen = "metis.plugins.tb_plugin:TableGenPlugin" typescript = "metis.plugins.typescript_plugin:TypeScriptPlugin" +php = "metis.plugins.php_plugin:PHPPlugin" +javascript = "metis.plugins.javascript_plugin:JavaScriptPlugin" diff --git a/src/metis/plugin_loader.py b/src/metis/plugin_loader.py index 98e9f8d..0bb9a52 100644 --- a/src/metis/plugin_loader.py +++ b/src/metis/plugin_loader.py @@ -109,6 +109,22 @@ def _load_builtin_plugins(plugin_config): logger.error(f"Failed to load required TableGen plugin: {e}") raise + try: + from metis.plugins.php_plugin import PHPPlugin + + plugins.append(PHPPlugin(plugin_config)) + except Exception as e: + logger.error(f"Failed to load required PHPPlugin plugin: {e}") + raise + + try: + from metis.plugins.javascript_plugin import JavaScriptPlugin + + plugins.append(JavaScriptPlugin(plugin_config)) + except Exception as e: + logger.error(f"Failed to load required JavaScriptPlugin plugin: {e}") + raise + return plugins diff --git a/src/metis/plugins/javascript_plugin.py b/src/metis/plugins/javascript_plugin.py new file mode 100644 index 0000000..76d7c93 --- /dev/null +++ b/src/metis/plugins/javascript_plugin.py @@ -0,0 +1,48 @@ +# SPDX-FileCopyrightText: Copyright 2025 Arm Limited and/or its affiliates +# SPDX-License-Identifier: Apache-2.0 + +from llama_index.core.node_parser import CodeSplitter + +from metis.plugins.base import BaseLanguagePlugin + + +class JavaScriptPlugin(BaseLanguagePlugin): + """Language plugin providing JavaScript-specific splitter and prompts.""" + + def __init__(self, plugin_config): + self.plugin_config = plugin_config + + def get_name(self) -> str: + return "javascript" + + def can_handle(self, extension: str) -> bool: + supported = self.get_supported_extensions() + return extension.lower() in supported + + def get_supported_extensions(self) -> list[str]: + exts = ( + self.plugin_config.get("plugins", {}) + .get(self.get_name(), {}) + .get("supported_extensions", [".js", ".jsx"]) + ) + return [e.lower() for e in exts] + + def get_splitter(self): + splitting_cfg = ( + self.plugin_config.get("plugins", {}) + .get(self.get_name(), {}) + .get("splitting", {}) + ) + return CodeSplitter( + language=self.get_name(), + chunk_lines=splitting_cfg.get("chunk_lines"), + chunk_lines_overlap=splitting_cfg.get("chunk_lines_overlap"), + max_chars=splitting_cfg.get("max_chars"), + ) + + def get_prompts(self) -> dict: + return ( + self.plugin_config.get("plugins", {}) + .get(self.get_name(), {}) + .get("prompts", {}) + ) diff --git a/src/metis/plugins/php_plugin.py b/src/metis/plugins/php_plugin.py new file mode 100644 index 0000000..e930146 --- /dev/null +++ b/src/metis/plugins/php_plugin.py @@ -0,0 +1,65 @@ +# SPDX-FileCopyrightText: Copyright 2025 Arm Limited and/or its affiliates +# SPDX-License-Identifier: Apache-2.0 + +from llama_index.core.node_parser import CodeSplitter + +from metis.plugins.base import BaseLanguagePlugin + + +class PHPPlugin(BaseLanguagePlugin): + """Language plugin providing PHP-specific splitter and prompts.""" + + def __init__(self, plugin_config): + self.plugin_config = plugin_config + + def get_name(self) -> str: + return "php" + + def can_handle(self, extension: str) -> bool: + supported = self.get_supported_extensions() + return extension.lower() in supported + + def get_supported_extensions(self) -> list[str]: + exts = ( + self.plugin_config.get("plugins", {}) + .get(self.get_name(), {}) + .get( + "supported_extensions", + [ + ".php", + ".phps", + ".phtm", + ".phtml", + ".phpt", + ".pht", + ".php2", + ".php3", + ".php4", + ".php5", + ".php6", + ".php7", + ".php8", + ], + ) + ) + return [e.lower() for e in exts] + + def get_splitter(self): + splitting_cfg = ( + self.plugin_config.get("plugins", {}) + .get(self.get_name(), {}) + .get("splitting", {}) + ) + return CodeSplitter( + language=self.get_name(), + chunk_lines=splitting_cfg.get("chunk_lines"), + chunk_lines_overlap=splitting_cfg.get("chunk_lines_overlap"), + max_chars=splitting_cfg.get("max_chars"), + ) + + def get_prompts(self) -> dict: + return ( + self.plugin_config.get("plugins", {}) + .get(self.get_name(), {}) + .get("prompts", {}) + ) diff --git a/src/metis/plugins/plugins.yaml b/src/metis/plugins/plugins.yaml index dc2c99e..41cc56d 100644 --- a/src/metis/plugins/plugins.yaml +++ b/src/metis/plugins/plugins.yaml @@ -52,7 +52,7 @@ plugins: Your tasks are: 1. Security Review Scope - - Review the security implications of the FILE_CHANGES, focusing on lines marked with “+.” or “-” but take into account how they interact with the whole file. + - Review the security implications of the FILE_CHANGES, focusing on lines marked with “+” or “-” but take into account how they interact with the whole file. - Only produce findings that are fully justified by FILE_CHANGES, ORIGINAL_FILE, and RELEVANT_CONTEXT. If no real issues exist, return an empty reviews list. - If it is empty, ignore it. security_review_checks: |- @@ -194,7 +194,7 @@ plugins: Your tasks are: 1. Security Review Scope - - Review the security implications of the FILE_CHANGES, focusing on lines marked with “+.” or “-” but take into account how they interact with the whole file. + - Review the security implications of the FILE_CHANGES, focusing on lines marked with “+” or “-” but take into account how they interact with the whole file. If it is empty, ignore it. security_review_checks: |- 2. What to Check @@ -237,7 +237,7 @@ plugins: Your tasks are: 1. Security Review Scope - - Review the security implications of the FILE_CHANGES, focusing on lines marked with “+.” or “-” but take into account how they interact with the whole file. + - Review the security implications of the FILE_CHANGES, focusing on lines marked with “+” or “-” but take into account how they interact with the whole file. If it is empty, ignore it. security_review_checks: |- 2. What to Check @@ -329,7 +329,7 @@ plugins: Your tasks are: 1. Security Review Scope - - Review the security implications of the FILE_CHANGES, focusing on lines marked with “+.” or “-” but take into account how they interact with the whole file. + - Review the security implications of the FILE_CHANGES, focusing on lines marked with “+” or “-” but take into account how they interact with the whole file. If it is empty, ignore it. security_review_checks: |- 2. What to Check @@ -379,7 +379,7 @@ plugins: Your tasks are: 1. Security Review Scope - - Review the security implications of the FILE_CHANGES, focusing on lines marked with “+.” or “-” while considering interactions with the whole file. + - Review the security implications of the FILE_CHANGES, focusing on lines marked with “+” or “-” while considering interactions with the whole file. - Only produce findings that are fully justified by FILE_CHANGES, ORIGINAL_FILE, and RELEVANT_CONTEXT. If no real issues exist, return an empty reviews list. - If it is empty, ignore it. security_review_checks: |- @@ -437,7 +437,7 @@ plugins: Your tasks are: 1. Security Review Scope - - Review the security implications of the FILE_CHANGES, focusing on lines marked with “+.” or “-” but take into account how they interact with the whole file. + - Review the security implications of the FILE_CHANGES, focusing on lines marked with “+” or “-” but take into account how they interact with the whole file. If it is empty, ignore it. security_review_checks: |- 2. What to Check @@ -528,3 +528,143 @@ plugins: 1. Security Review Scope - Review the security implications of the FILE. If it is empty, ignore it. + php: + supported_extensions: [".php", ".phps", ".phtm", ".phtml", ".phpt", ".pht", ".php2", ".php3", ".php4", ".php5", ".php6", ".php7", ".php8"] + splitting: + chunk_lines: 40 + chunk_lines_overlap: 15 + max_chars: 1500 + prompts: + security_review: |- + You are a thorough security engineer specializing in PHP. + Always tie your identified issues directly to the evidence in FILE_CHANGES, RELEVANT_CONTEXT, + and ORIGINAL_FILE. Do not introduce new security conclusions that are not supported + by the specific changes or context provided. + You will be given: + 1. FILE_CHANGES - a set of code changes with lines marked by “+” indicating what has been added or “-” for removed. + 2. RELEVANT_CONTEXT - information about what these changes do. + 3. ORIGINAL_FILE - The original file before being modified. Use this to understand how changes affect the code. (this may be empty). + + Your tasks are: + 1. Security Review Scope + - Review the security implications of the FILE_CHANGES, focusing on lines marked with “+” or “-” but take into account how they interact with the whole file. + - Only produce findings that are fully justified by FILE_CHANGES, ORIGINAL_FILE, and RELEVANT_CONTEXT. If no real issues exist, return an empty reviews list. + - If it is empty, ignore it. + security_review_file: |- + You are a thorough security engineer specializing in PHP. + Always tie your identified issues directly to the evidence in FILE and RELEVANT_CONTEXT. + Do not introduce new security conclusions that are not supported by the specific changes or context provided. + You will be given: + 1. FILE - A source code file + 2. RELEVANT_CONTEXT - information about what these changes do. + + Your tasks are: + 1. Security Review Scope + - Review the security implications of the FILE. + - Only produce findings that are fully justified by FILE and RELEVANT_CONTEXT. If no real issues exist, return an empty reviews list. + - If it is empty, ignore it. + security_review_checks: |- + 2. What to Check + - Look for potential security issues such as: + - OWASP Top 10 vulnerabilities (e.g., SQL injection, XSS, CSRF) + - Hardcoded secrets or credentials + - Insecure file uploads or handling + - Unsafe use of eval(), exec(), or dynamic code execution + - Weak session management or cookie handling + - Insecure deserialization + - Improper input validation or sanitization + - Pay extra attention to variables that are externally controlled (e.g., $_GET, $_POST). + - Do not report on issues that do not affect security. + validation_review: |- + You will be given: + SNIPPET: The relevant PHP code snippet. + RELEVANT CONTEXT: Additional details or commentary on the snippet. + REVIEW: A list of potential security issues discovered in the code changes. + + Your task is to: + 1. Carefully examine each item in the REVIEW. Check if it's a genuine security concern by referencing the SNIPPET and RELEVANT CONTEXT. + 2. Remove any issues that are false positives or are already mitigated in the code (e.g., prepared statements for SQL, escaping for output). + 3. Keep only the issues that definitely represent real security risks. + 4. If an issue is missing details, add the necessary clarifications or background. + 5. If no real issues remain after validation, respond with an empty array: []. + snippet_security_summary: |- + You are a thorough security engineer specializing in PHP. + You will be given a concatenated list all identified security issues that have been identified in a code review. + Summarize all the issues in a single paragraph and explain what changed in the code patch and how it affects security. + attempt_fix: |- + You are an experienced software engineer specializing in secure coding. Based on the following identified security issues:\n + {issues}\n + and the patch file:\n + {patch}\n + Please update the patch file so that is fixes these vulnerabilities. + Do not include any commentary—only output the patch diff. + javascript: + supported_extensions: [".js", ".jsx"] + splitting: + chunk_lines: 40 + chunk_lines_overlap: 15 + max_chars: 1500 + prompts: + security_review: |- + You are a thorough security engineer specializing in JavaScript (including Node.js and browser contexts). + Always tie your identified issues directly to the evidence in FILE_CHANGES, RELEVANT_CONTEXT, + and ORIGINAL_FILE. Do not introduce new security conclusions that are not supported + by the specific changes or context provided. + You will be given: + 1. FILE_CHANGES - a set of code changes with lines marked by “+” indicating what has been added or “-” for removed. + 2. RELEVANT_CONTEXT - information about what these changes do. + 3. ORIGINAL_FILE - The original file before being modified. Use this to understand how changes affect the code. (this may be empty). + + Your tasks are: + 1. Security Review Scope + - Review the security implications of the FILE_CHANGES, focusing on lines marked with “+” or “-” but take into account how they interact with the whole file. + - Only produce findings that are fully justified by FILE_CHANGES, ORIGINAL_FILE, and RELEVANT_CONTEXT. If no real issues exist, return an empty reviews list. + - If it is empty, ignore it. + security_review_file: |- + You are a thorough security engineer specializing in JavaScript (including Node.js and browser contexts). + Always tie your identified issues directly to the evidence in FILE and RELEVANT_CONTEXT. + Do not introduce new security conclusions that are not supported by the specific changes or context provided. + You will be given: + 1. FILE - A source code file + 2. RELEVANT_CONTEXT - information about what these changes do. + + Your tasks are: + 1. Security Review Scope + - Review the security implications of the FILE. + - Only produce findings that are fully justified by FILE and RELEVANT_CONTEXT. If no real issues exist, return an empty reviews list. + - If it is empty, ignore it. + security_review_checks: |- + 2. What to Check + - Look for potential security issues such as: + - OWASP Top 10 vulnerabilities (e.g., XSS, injection in queries, CSRF) + - Hardcoded secrets or API keys + - Prototype pollution + - Insecure use of eval() or Function() constructors + - Weak dependency management or vulnerable libraries + - Improper handling of user input in DOM manipulations + - Race conditions in asynchronous code + - Pay extra attention to variables that are externally controlled (e.g., from req.body, URL params). + - Do not report on issues that do not affect security. + validation_review: |- + You will be given: + SNIPPET: The relevant JavaScript code snippet. + RELEVANT CONTEXT: Additional details or commentary on the snippet. + REVIEW: A list of potential security issues discovered in the code changes. + + Your task is to: + 1. Carefully examine each item in the REVIEW. Check if it's a genuine security concern by referencing the SNIPPET and RELEVANT CONTEXT. + 2. Remove any issues that are false positives or are already mitigated in the code (e.g., sanitization libraries like DOMPurify). + 3. Keep only the issues that definitely represent real security risks. + 4. If an issue is missing details, add the necessary clarifications or background. + 5. If no real issues remain after validation, respond with an empty array: []. + snippet_security_summary: |- + You are a thorough security engineer specializing in JavaScript. + You will be given a concatenated list all identified security issues that have been identified in a code review. + Summarize all the issues in a single paragraph and explain what changed in the code patch and how it affects security. + attempt_fix: |- + You are an experienced software engineer specializing in secure coding. Based on the following identified security issues:\n + {issues}\n + and the patch file:\n + {patch}\n + Please update the patch file so that is fixes these vulnerabilities. + Do not include any commentary—only output the patch diff.