diff --git a/.claude-plugin/marketplace.json b/.claude-plugin/marketplace.json index 843673a..dd607b6 100644 --- a/.claude-plugin/marketplace.json +++ b/.claude-plugin/marketplace.json @@ -6,16 +6,13 @@ "url": "https://project-codeguard.org", "email": "contact@project-codeguard.org" }, - "repository": { - "type": "git", - "url": "https://github.com/project-codeguard/rules.git" - }, "plugins": [ { "name": "codeguard-security", - "source": ".", + "source": "./", "description": "Comprehensive security rules for AI coding agents", "version": "1.0.0", + "repository": "https://github.com/project-codeguard/rules.git", "tags": ["security", "code-review", "vulnerability-prevention"] } ] diff --git a/.claude-plugin/plugin.json b/.claude-plugin/plugin.json index a9a0f9c..2e5756d 100644 --- a/.claude-plugin/plugin.json +++ b/.claude-plugin/plugin.json @@ -8,10 +8,7 @@ }, "license": "CC-BY-4.0 (rules), Apache-2.0 (tools)", "homepage": "https://github.com/project-codeguard/rules", - "repository": { - "type": "git", - "url": "https://github.com/project-codeguard/rules.git" - }, + "repository": "https://github.com/project-codeguard/rules.git", "keywords": ["security", "secure-coding", "vulnerability-prevention", "code-review", "appsec"] } diff --git a/skills/software-security/rules/codeguard-0-additional-cryptography.md b/skills/software-security/rules/codeguard-0-additional-cryptography.md index 6bcb4fd..1969747 100644 --- a/skills/software-security/rules/codeguard-0-additional-cryptography.md +++ b/skills/software-security/rules/codeguard-0-additional-cryptography.md @@ -17,6 +17,8 @@ languages: alwaysApply: false --- +rule_id: codeguard-0-additional-cryptography + ## Additional Cryptography & TLS Apply modern, vetted cryptography for data at rest and in transit. Manage keys safely, configure TLS correctly, deploy HSTS, and consider pinning only when appropriate. diff --git a/skills/software-security/rules/codeguard-0-api-web-services.md b/skills/software-security/rules/codeguard-0-api-web-services.md index 94a51fc..7e8a188 100644 --- a/skills/software-security/rules/codeguard-0-api-web-services.md +++ b/skills/software-security/rules/codeguard-0-api-web-services.md @@ -15,6 +15,8 @@ languages: alwaysApply: false --- +rule_id: codeguard-0-api-web-services + ## API & Web Services Security Secure REST, GraphQL, and SOAP/WS services end‑to‑end: transport, authn/z, schema validation, SSRF controls, DoS limits, and microservice‑safe patterns. diff --git a/skills/software-security/rules/codeguard-0-authentication-mfa.md b/skills/software-security/rules/codeguard-0-authentication-mfa.md index 2be26cc..53201bf 100644 --- a/skills/software-security/rules/codeguard-0-authentication-mfa.md +++ b/skills/software-security/rules/codeguard-0-authentication-mfa.md @@ -16,6 +16,8 @@ languages: alwaysApply: false --- +rule_id: codeguard-0-authentication-mfa + ## Authentication & MFA Build a resilient, user-friendly authentication system that resists credential attacks, protects secrets, and supports strong, phishing-resistant MFA and secure recovery. diff --git a/skills/software-security/rules/codeguard-0-authorization-access-control.md b/skills/software-security/rules/codeguard-0-authorization-access-control.md index 116ab2d..9fee91d 100644 --- a/skills/software-security/rules/codeguard-0-authorization-access-control.md +++ b/skills/software-security/rules/codeguard-0-authorization-access-control.md @@ -14,6 +14,8 @@ languages: alwaysApply: false --- +rule_id: codeguard-0-authorization-access-control + ## Authorization & Access Control Enforce least privilege and precise access decisions for every request and resource, prevent IDOR and mass assignment, and provide strong transaction authorization where necessary. diff --git a/skills/software-security/rules/codeguard-0-client-side-web-security.md b/skills/software-security/rules/codeguard-0-client-side-web-security.md index 17a4e89..b49a5bf 100644 --- a/skills/software-security/rules/codeguard-0-client-side-web-security.md +++ b/skills/software-security/rules/codeguard-0-client-side-web-security.md @@ -11,6 +11,8 @@ languages: alwaysApply: false --- +rule_id: codeguard-0-client-side-web-security + ## Client‑side Web Security Protect browser clients against code injection, request forgery, UI redress, cross‑site leaks, and unsafe third‑party scripts with layered, context‑aware controls. diff --git a/skills/software-security/rules/codeguard-0-cloud-orchestration-kubernetes.md b/skills/software-security/rules/codeguard-0-cloud-orchestration-kubernetes.md index ec2e982..4527de4 100644 --- a/skills/software-security/rules/codeguard-0-cloud-orchestration-kubernetes.md +++ b/skills/software-security/rules/codeguard-0-cloud-orchestration-kubernetes.md @@ -7,6 +7,8 @@ languages: alwaysApply: false --- +rule_id: codeguard-0-cloud-orchestration-kubernetes + ## Cloud & Orchestration (Kubernetes) Kubernetes cluster and workload hardening: identity, policy, networking, secrets, and supply chain controls. diff --git a/skills/software-security/rules/codeguard-0-data-storage.md b/skills/software-security/rules/codeguard-0-data-storage.md index 6bd68f5..4df19cc 100644 --- a/skills/software-security/rules/codeguard-0-data-storage.md +++ b/skills/software-security/rules/codeguard-0-data-storage.md @@ -9,6 +9,8 @@ languages: alwaysApply: false --- +rule_id: codeguard-0-data-storage + ## Database Security Guidelines This rule advises on securely configuring SQL and NoSQL databases to protect against data breaches and unauthorized access: diff --git a/skills/software-security/rules/codeguard-0-devops-ci-cd-containers.md b/skills/software-security/rules/codeguard-0-devops-ci-cd-containers.md index 1db3562..01cf39d 100644 --- a/skills/software-security/rules/codeguard-0-devops-ci-cd-containers.md +++ b/skills/software-security/rules/codeguard-0-devops-ci-cd-containers.md @@ -11,6 +11,8 @@ languages: alwaysApply: false --- +rule_id: codeguard-0-devops-ci-cd-containers + ## DevOps, CI/CD, and Containers Secure the build, packaging, and deployment supply chain: protect pipelines and artifacts, harden containers, and use virtual patching and toolchain flags when necessary. diff --git a/skills/software-security/rules/codeguard-0-file-handling-and-uploads.md b/skills/software-security/rules/codeguard-0-file-handling-and-uploads.md index e48ae95..3c6277c 100644 --- a/skills/software-security/rules/codeguard-0-file-handling-and-uploads.md +++ b/skills/software-security/rules/codeguard-0-file-handling-and-uploads.md @@ -13,6 +13,8 @@ languages: alwaysApply: false --- +rule_id: codeguard-0-file-handling-and-uploads + ## File Upload Security Guidelines This rule advises on secure file upload practices to prevent malicious file attacks and protect system integrity: diff --git a/skills/software-security/rules/codeguard-0-framework-and-languages.md b/skills/software-security/rules/codeguard-0-framework-and-languages.md index 8fb583d..f004909 100644 --- a/skills/software-security/rules/codeguard-0-framework-and-languages.md +++ b/skills/software-security/rules/codeguard-0-framework-and-languages.md @@ -15,6 +15,8 @@ languages: alwaysApply: false --- +rule_id: codeguard-0-framework-and-languages + ## Framework & Language Guides Apply secure‑by‑default patterns per platform. Harden configurations, use built‑in protections, and avoid common pitfalls. diff --git a/skills/software-security/rules/codeguard-0-iac-security.md b/skills/software-security/rules/codeguard-0-iac-security.md index 0785120..20e243c 100644 --- a/skills/software-security/rules/codeguard-0-iac-security.md +++ b/skills/software-security/rules/codeguard-0-iac-security.md @@ -11,6 +11,8 @@ languages: alwaysApply: false --- +rule_id: codeguard-0-iac-security + # Infrastructure as Code (IaC) Security When designing cloud infrastructure and writing Infrastructure as Code (IaC) in languages like Terraform and CloudFormation, always use secure practices and defaults such as preventing public exposure and follow the principle of least privilege. Actively identify security misconfigurations and provide secure alternatives. diff --git a/skills/software-security/rules/codeguard-0-input-validation-injection.md b/skills/software-security/rules/codeguard-0-input-validation-injection.md index 9ae2ab1..016badb 100644 --- a/skills/software-security/rules/codeguard-0-input-validation-injection.md +++ b/skills/software-security/rules/codeguard-0-input-validation-injection.md @@ -17,6 +17,8 @@ languages: alwaysApply: false --- +rule_id: codeguard-0-input-validation-injection + ## Input Validation & Injection Defense Ensure untrusted input is validated and never interpreted as code. Prevent injection across SQL, LDAP, OS commands, templating, and JavaScript runtime object graphs. diff --git a/skills/software-security/rules/codeguard-0-logging.md b/skills/software-security/rules/codeguard-0-logging.md index 659be01..48322e5 100644 --- a/skills/software-security/rules/codeguard-0-logging.md +++ b/skills/software-security/rules/codeguard-0-logging.md @@ -8,6 +8,8 @@ languages: alwaysApply: false --- +rule_id: codeguard-0-logging + ## Logging & Monitoring Produce structured, privacy‑aware telemetry that supports detection, response, and forensics without exposing secrets. diff --git a/skills/software-security/rules/codeguard-0-mobile-apps.md b/skills/software-security/rules/codeguard-0-mobile-apps.md index bc7d3c1..b100ca2 100644 --- a/skills/software-security/rules/codeguard-0-mobile-apps.md +++ b/skills/software-security/rules/codeguard-0-mobile-apps.md @@ -12,6 +12,8 @@ languages: alwaysApply: false --- +rule_id: codeguard-0-mobile-apps + ## Mobile Application Security Guidelines Essential security practices for developing secure mobile applications across iOS and Android platforms. diff --git a/skills/software-security/rules/codeguard-0-privacy-data-protection.md b/skills/software-security/rules/codeguard-0-privacy-data-protection.md index f28876d..dd2cf2e 100644 --- a/skills/software-security/rules/codeguard-0-privacy-data-protection.md +++ b/skills/software-security/rules/codeguard-0-privacy-data-protection.md @@ -8,6 +8,8 @@ languages: alwaysApply: false --- +rule_id: codeguard-0-privacy-data-protection + - Implement strong cryptography, enforce HTTPS with HSTS, enable certificate pinning, and provide user privacy features to protect data and anonymity. - Use strong, up-to-date cryptographic algorithms for data in transit and at rest; securely hash passwords with established libraries. diff --git a/skills/software-security/rules/codeguard-0-session-management-and-cookies.md b/skills/software-security/rules/codeguard-0-session-management-and-cookies.md index be73bf8..34f4905 100644 --- a/skills/software-security/rules/codeguard-0-session-management-and-cookies.md +++ b/skills/software-security/rules/codeguard-0-session-management-and-cookies.md @@ -14,6 +14,8 @@ languages: alwaysApply: false --- +rule_id: codeguard-0-session-management-and-cookies + ## Session Management & Cookies Implement robust, attack-resistant session handling that prevents fixation, hijacking, and theft while maintaining usability. diff --git a/skills/software-security/rules/codeguard-0-supply-chain-security.md b/skills/software-security/rules/codeguard-0-supply-chain-security.md index e5adc3b..cd87ea4 100644 --- a/skills/software-security/rules/codeguard-0-supply-chain-security.md +++ b/skills/software-security/rules/codeguard-0-supply-chain-security.md @@ -8,6 +8,8 @@ languages: alwaysApply: false --- +rule_id: codeguard-0-supply-chain-security + ## Dependency & Supply Chain Security Control third‑party risk across ecosystems, from selection and pinning to provenance, scanning, and rapid response. diff --git a/skills/software-security/rules/codeguard-0-xml-and-serialization.md b/skills/software-security/rules/codeguard-0-xml-and-serialization.md index 9a64d85..bb187ef 100644 --- a/skills/software-security/rules/codeguard-0-xml-and-serialization.md +++ b/skills/software-security/rules/codeguard-0-xml-and-serialization.md @@ -12,6 +12,8 @@ languages: alwaysApply: false --- +rule_id: codeguard-0-xml-and-serialization + ## XML & Serialization Hardening Secure parsing and processing of XML and serialized data; prevent XXE, entity expansion, SSRF, DoS, and unsafe deserialization across platforms. diff --git a/skills/software-security/rules/codeguard-1-crypto-algorithms.md b/skills/software-security/rules/codeguard-1-crypto-algorithms.md index e748452..7f0b820 100644 --- a/skills/software-security/rules/codeguard-1-crypto-algorithms.md +++ b/skills/software-security/rules/codeguard-1-crypto-algorithms.md @@ -1,9 +1,10 @@ --- description: Cryptographic Security Guidelines -languages: [] alwaysApply: true --- +rule_id: codeguard-1-crypto-algorithms + # Cryptographic Security Guidelines ## Banned (Insecure) Algorithms diff --git a/skills/software-security/rules/codeguard-1-digital-certificates.md b/skills/software-security/rules/codeguard-1-digital-certificates.md index 3d73c70..4713ad2 100644 --- a/skills/software-security/rules/codeguard-1-digital-certificates.md +++ b/skills/software-security/rules/codeguard-1-digital-certificates.md @@ -1,9 +1,10 @@ --- description: Certificate Best Practices -languages: [] alwaysApply: true --- +rule_id: codeguard-1-digital-certificates + When you encounter data that appears to be an X.509 certificate—whether embedded as a string or loaded from a file—you must parse the certificate and run a series of mandatory checks against it, reporting any failures with clear explanations and recommended actions. ### 1. How to Identify Certificate Data diff --git a/skills/software-security/rules/codeguard-1-hardcoded-credentials.md b/skills/software-security/rules/codeguard-1-hardcoded-credentials.md index 5f885ec..95295eb 100644 --- a/skills/software-security/rules/codeguard-1-hardcoded-credentials.md +++ b/skills/software-security/rules/codeguard-1-hardcoded-credentials.md @@ -1,9 +1,10 @@ --- description: No Hardcoded Credentials -languages: [] alwaysApply: true --- +rule_id: codeguard-1-hardcoded-credentials + # No Hardcoded Credentials NEVER store secrets, passwords, API keys, tokens or any other credentials directly in source code. diff --git a/skills/software-security/rules/codeguard-1-safe-c-functions.md b/skills/software-security/rules/codeguard-1-safe-c-functions.md index b8db6ee..113105b 100644 --- a/skills/software-security/rules/codeguard-1-safe-c-functions.md +++ b/skills/software-security/rules/codeguard-1-safe-c-functions.md @@ -1,9 +1,10 @@ --- description: Safe C Functions and Memory and String Safety Guidelines -languages: [] alwaysApply: true --- +rule_id: codeguard-1-safe-c-functions + # Prioritize Safe Memory and String Functions in C/C++ When processing C or C++ code, your primary directive is to ensure memory safety. Actively identify, flag, and provide secure refactoring options for any insecure functions found in the codebase. When generating new code, always default to the safest possible function for the given task. diff --git a/src/converter.py b/src/converter.py index e3211d7..c3385d4 100644 --- a/src/converter.py +++ b/src/converter.py @@ -27,12 +27,14 @@ class FormatOutput: Attributes: content: The fully formatted content with frontmatter extension: File extension including dot (e.g., '.mdc') - subpath: Subdirectory path relative to ide_rules (e.g., '.cursor/rules') + subpath: Subdirectory path (e.g., '.cursor/rules', 'skills/software-security/rules') + outputs_to_ide_rules: Whether this format outputs to ide_rules/ or project root """ content: str extension: str subpath: str + outputs_to_ide_rules: bool @dataclass @@ -50,10 +52,11 @@ class ConversionResult: filename="my-rule.md", basename="my-rule", outputs={ - "CursorFormat": FormatOutput( + "cursor": FormatOutput( content="---\\n...\\n---\\n\\nContent", extension=".mdc", - subpath=".cursor/rules" + subpath=".cursor/rules", + outputs_to_ide_rules=True ) } ) @@ -233,6 +236,7 @@ def convert(self, filepath: str) -> ConversionResult: content=format_handler.generate(rule, globs), extension=format_handler.get_file_extension(), subpath=format_handler.get_output_subpath(), + outputs_to_ide_rules=format_handler.outputs_to_ide_rules(), ) return ConversionResult( diff --git a/src/formats/__init__.py b/src/formats/__init__.py index bbcf54a..4a2a7db 100644 --- a/src/formats/__init__.py +++ b/src/formats/__init__.py @@ -11,15 +11,17 @@ - CursorFormat: Generates .mdc files for Cursor IDE - WindsurfFormat: Generates .md files for Windsurf IDE - CopilotFormat: Generates .instructions.md files for GitHub Copilot +- ClaudeCodeFormat: Generates .md files for Claude Code plugins Usage: - from formats import BaseFormat, ProcessedRule, CursorFormat, WindsurfFormat, CopilotFormat + from formats import BaseFormat, ProcessedRule, CursorFormat, WindsurfFormat, CopilotFormat, ClaudeCodeFormat version = "1.0.0" formats = [ CursorFormat(version), WindsurfFormat(version), CopilotFormat(version), + ClaudeCodeFormat(version), ] """ @@ -27,6 +29,7 @@ from formats.cursor import CursorFormat from formats.windsurf import WindsurfFormat from formats.copilot import CopilotFormat +from formats.claudecode import ClaudeCodeFormat __all__ = [ "BaseFormat", @@ -34,4 +37,5 @@ "CursorFormat", "WindsurfFormat", "CopilotFormat", + "ClaudeCodeFormat", ] diff --git a/src/formats/base.py b/src/formats/base.py index a6a01ca..1cc65f5 100644 --- a/src/formats/base.py +++ b/src/formats/base.py @@ -77,13 +77,25 @@ def get_file_extension(self) -> str: @abstractmethod def get_output_subpath(self) -> str: """ - Return the subdirectory path for this format relative to ide_rules. + Return the subdirectory path for this format. Returns: - Subdirectory path (e.g., '.cursor/rules', '.windsurf/rules') + Subdirectory path (e.g., '.cursor/rules', 'skills/software-security/rules') """ pass + def outputs_to_ide_rules(self) -> bool: + """ + Return whether this format outputs to the ide_rules directory. + + Returns: + True if output should go to ide_rules/, False for project root + + Override this method if your format outputs to project root instead + of ide_rules/ (e.g., Claude Code plugin outputs to skills/) + """ + return True + @abstractmethod def generate(self, rule: ProcessedRule, globs: str) -> str: """ diff --git a/src/formats/claudecode.py b/src/formats/claudecode.py new file mode 100644 index 0000000..f0cb2d6 --- /dev/null +++ b/src/formats/claudecode.py @@ -0,0 +1,78 @@ +# Copyright 2025 Cisco Systems, Inc. and its affiliates +# +# SPDX-License-Identifier: Apache-2.0 + +""" +Claude Code Format Implementation + +Generates .md files for Claude Code Skills/Plugins. +""" + +from formats.base import BaseFormat, ProcessedRule + + +class ClaudeCodeFormat(BaseFormat): + """ + Claude Code plugin format implementation (.md files). + + Claude Code Skills use standard markdown files without + special frontmatter. The original rule content is preserved + and placed in the skills/software-security/rules/ directory + for plugin distribution. + + Unlike other IDE formats, Claude Code doesn't require special + frontmatter transformations - it uses the rules as-is for + plugin-based Skills. + """ + + def get_format_name(self) -> str: + """Return Claude Code format identifier.""" + return "claudecode" + + def get_file_extension(self) -> str: + """Return Claude Code format file extension.""" + return ".md" + + def get_output_subpath(self) -> str: + """Return Claude Code output subdirectory.""" + return "skills/software-security/rules" + + def outputs_to_ide_rules(self) -> bool: + """Claude Code outputs to project root, not ide_rules/.""" + return False + + def generate(self, rule: ProcessedRule, globs: str) -> str: + """ + Generate Claude Code .md format. + + Claude Code Skills should preserve the original YAML frontmatter + (description, languages, alwaysApply) so the rules remain complete + and can be referenced properly. + + Args: + rule: The processed rule to format + globs: Glob patterns (not used for Claude Code format) + + Returns: + Complete markdown with original YAML frontmatter preserved + """ + # Build YAML frontmatter + yaml_lines = [] + + # Add description + desc = self._format_yaml_field("description", rule.description) + if desc: + yaml_lines.append(desc) + + # Add languages if present + if rule.languages: + # Format as YAML list + yaml_lines.append("languages:") + for lang in rule.languages: + yaml_lines.append(f"- {lang}") + + # Add alwaysApply + yaml_lines.append(f"alwaysApply: {str(rule.always_apply).lower()}") + + return self._build_yaml_frontmatter(yaml_lines, rule.content) + diff --git a/src/prepare-claude-code-plugin.sh b/src/prepare-claude-code-plugin.sh deleted file mode 100755 index 63b6970..0000000 --- a/src/prepare-claude-code-plugin.sh +++ /dev/null @@ -1,69 +0,0 @@ -#!/bin/bash -# Prepare CodeGuard plugin for distribution -# This script copies the rule files from the main rules directory -# to the skills directory for plugin packaging - -set -e # Exit on error - -SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" -PROJECT_ROOT="$(dirname "$SCRIPT_DIR")" - -echo "===================================" -echo "Preparing CodeGuard Plugin" -echo "===================================" -echo "" - -# Create skills directory structure if it doesn't exist -echo "1. Creating skills directory structure..." -mkdir -p "$PROJECT_ROOT/skills/software-security" - -# Remove old rules directory in skills if it exists -if [ -d "$PROJECT_ROOT/skills/software-security/rules" ]; then - echo "2. Removing old rules directory..." - rm -rf "$PROJECT_ROOT/skills/software-security/rules" -fi - -# Copy rules to skills directory -echo "3. Copying rules from rules/ to skills/software-security/rules/..." -cp -r "$PROJECT_ROOT/rules" "$PROJECT_ROOT/skills/software-security/rules" - -# Count the number of rules -RULE_COUNT=$(find "$PROJECT_ROOT/skills/software-security/rules" -name "*.md" | wc -l | tr -d ' ') - -echo "4. Verifying plugin structure..." -# Verify required files exist -if [ ! -f "$PROJECT_ROOT/.claude-plugin/plugin.json" ]; then - echo " ERROR: Missing .claude-plugin/plugin.json" - exit 1 -fi - -if [ ! -f "$PROJECT_ROOT/.claude-plugin/marketplace.json" ]; then - echo " ERROR: Missing .claude-plugin/marketplace.json" - exit 1 -fi - -if [ ! -f "$PROJECT_ROOT/skills/software-security/SKILL.md" ]; then - echo " ERROR: Missing skills/software-security/SKILL.md" - exit 1 -fi - -echo " ✓ All required plugin files present" -echo "" -echo "===================================" -echo "Plugin Preparation Complete!" -echo "===================================" -echo "" -echo "Summary:" -echo " - Rules copied: $RULE_COUNT files" -echo " - Plugin version: $(grep -o '"version": "[^"]*"' "$PROJECT_ROOT/.claude-plugin/plugin.json" | cut -d'"' -f4)" -echo " - Location: $PROJECT_ROOT" -echo "" -echo "The plugin is ready for distribution." -echo "" -echo "To test locally:" -echo " 1. cd /path/to/parent/directory" -echo " 2. claude" -echo " 3. /plugin marketplace add ./rules" -echo " 4. /plugin install codeguard-security@project-codeguard" -echo "" - diff --git a/src/unified_to_all.py b/src/unified_to_all.py index c1af61b..b0bc798 100644 --- a/src/unified_to_all.py +++ b/src/unified_to_all.py @@ -5,14 +5,14 @@ """ Unified to All Formats Converter -Converts unified markdown format to all IDE formats (Cursor, Windsurf, Copilot). +Converts unified markdown format to all IDE formats (Cursor, Windsurf, Copilot, Claude Code). Single source of truth for AI coding rules. """ from pathlib import Path from converter import RuleConverter -from formats import CursorFormat, WindsurfFormat, CopilotFormat +from formats import CursorFormat, WindsurfFormat, CopilotFormat, ClaudeCodeFormat from utils import get_version_from_pyproject @@ -42,6 +42,7 @@ def convert_rules(input_path: str, output_dir: str = ".") -> dict[str, list[str] CursorFormat(version), WindsurfFormat(version), CopilotFormat(version), + ClaudeCodeFormat(version), ] converter = RuleConverter(formats=all_formats) @@ -78,8 +79,11 @@ def convert_rules(input_path: str, output_dir: str = ".") -> dict[str, list[str] output_files = [] for format_name, output in result.outputs.items(): # Construct output path + # Use format's output preference (ide_rules/ or project root) + base_dir = ide_rules_dir if output.outputs_to_ide_rules else output_base + output_file = ( - ide_rules_dir + base_dir / output.subpath / f"{result.basename}{output.extension}" )