# radar

Use radar for multi-framework smart contract AST generation and security analysis. Supports Rust (Anchor, native, Stylus) and Solidity (standard, Foundry). Triggers include generating AST, finding vulnerabilities, debugging via AST output, writing security templates, contributing detection rules, or working with radar's template DSL. Use when users mention radar, AST generation for Rust/Solidity/Anchor/Stylus/Foundry, smart contract parsing, vulnerability detection, template development, or security scanning.

- **Kind:** skill
- **Source:** https://github.com/Auditware/radar
- **Page:** https://forefy.com/skills/0441c01c-e428-4077-a7dd-08fe5d71990d
- **API (JSON + files):** https://forefy.com/api/skills/0441c01c-e428-4077-a7dd-08fe5d71990d

---

## SKILL.md

---
name: radar
description: Use radar for multi-framework smart contract AST generation and security analysis. Supports Rust (Anchor, native, Stylus) and Solidity (standard, Foundry). Triggers include generating AST, finding vulnerabilities, debugging via AST output, writing security templates, contributing detection rules, or working with radar's template DSL. Use when users mention radar, AST generation for Rust/Solidity/Anchor/Stylus/Foundry, smart contract parsing, vulnerability detection, template development, or security scanning.
---

# radar

Radar is a multi-framework AST generator and security analysis tool for smart contracts. Use this skill for AST generation across Rust and Solidity ecosystems, smart contract vulnerability scanning, and radar template development to repeat detection patterns to be reused against multiple contracts.

## Supported Frameworks

- **Anchor** (Solana framework)
- **Native Rust** (Solana programs)  
- **Stylus** (Arbitrum Rust)
- **Solidity** (standalone contracts)
- **Foundry** (Solidity projects)

All use Rust's `syn` parser for consistent, high-quality AST output.

## Generating AST

### AST for Any Framework
```bash
radar -p <contract-path> --ast -o output.json
```

Output includes both security findings and complete AST structure.

### AST-Only Mode
Generate AST without security scanning:
```bash
radar -p <contract-path> --ast --ignore low,medium,high,uncertain -o ast.json
```

### Framework Examples
```bash
# Anchor project
radar -p ./my-anchor-project --ast -o anchor_ast.json

# Native Rust (Solana)
radar -p ./native-solana --ast -o rust_ast.json

# Stylus (Arbitrum)
radar -p ./stylus-contract --ast -o stylus_ast.json

# Solidity
radar -p ./solidity-contract --ast -o solidity_ast.json

# Foundry project
radar -p ./foundry-project --ast -o foundry_ast.json
```

See [ast-generation.md](references/ast-generation.md) for complete AST guide including structure, node types, and integration patterns.

## Running Scans

### Basic Scan
```bash
radar -p <contract-path>
```

### With AST Output
Essential for template development and debugging:
```bash
radar --dev -p <contract-path> --ast -o output.json
```

### Custom Templates
```bash
radar -p <contract-path> -t <templates-directory>
```

See [usage.md](references/usage.md) for complete command reference and integration options.

## Developing Templates

Templates are YAML files that detect vulnerable patterns using a Python DSL.

### Quick Template Structure
```yaml
version: 0.1.0
author: your-name
accent: anchor
name: Template Name
description: Vulnerability description
severity: Low|Medium|High
certainty: Low|Medium|High
vulnerable_example: URL
rule: |
  for source, nodes in ast:
      try:
          pattern = nodes.find_by_names("VulnType").exit_on_none()
          nodes.find_by_names("Safeguard").exit_on_value()
          print(pattern.first().to_result())
      except:
          continue
```

### Development Workflow
1. Run radar with `--ast` to inspect contract structure
2. Write rule using DSL functions to detect vulnerable patterns
3. Test against bad example (must detect)
4. Test against good example (must not detect)
5. Add unit test to `api/tests/test_templates.py`
6. Run `make test`

### Key Rules
- Zero false positives (absolute requirement)
- Point to exact vulnerability line, not function/file
- Generalize patterns, don't hard-code values
- Use `exit_on_none()` when pattern must exist
- Use `exit_on_value()` to verify safeguard absence

See [template-writing.md](references/template-writing.md) for complete guide.

## DSL Functions

Template rules use methods from `RustASTNode`:

### Finding Patterns
- `find_by_names(*idents)` - Find by identifier
- `find_functions_by_names(*names)` - Find function declarations
- `find_method_calls(caller, method)` - Find method invocations
- `find_chained_calls(*idents)` - Find chained calls
- `find_comparison_involving(ident)` - Find comparisons
- `find_macro_attribute_by_names(*idents)` - Find macro attributes

### Control Flow
- `exit_on_none()` - Stop if not found (pattern required)
- `exit_on_value()` - Stop if found (safeguard exists)
- `first()` - Get first node
- `to_result()` - Convert to finding format

### Debugging
- `to_raw_ast_debug()` - Inspect AST structure (add to template, don't call print)

See [dsl-functions.md](references/dsl-functions.md) for complete API reference.

## Testing Templates

Every template requires:
- `api/tests/mocks/<template_name>/bad/src/lib.rs` - Vulnerable code
- `api/tests/mocks/<template_name>/good/src/lib.rs` - Safe code  
- Unit test in `api/tests/test_templates.py`

Test command:
```bash
radar --dev -p api/tests/mocks/<template_name>/bad --ast -o outputs/out.json
```

## Debugging

### Template Not Detecting
1. Run with `--dev` for detailed logs
2. Add `nodes.to_raw_ast_debug()` in template to inspect AST
3. Compare AST structure with template logic
4. Verify DSL methods exist on node type

### False Positives
Review template logic - templates must have 0% false positive rate.

### AST Inspection
Use `--ast` flag to understand contract structure:
```bash
radar --dev -p <contract> --ast -o debug.json
```

Examine the `ast` field in output to see node structure.

## Contributing

Templates are the primary contribution method. Each template must:
- Detect a real vulnerability pattern
- Have zero false positives
- Include bad/good test cases
- Pass unit tests

See [template-writing.md](references/template-writing.md) for complete contribution guide.

## references

```

```

## references/ast-generation.md

# AST Generation Guide

Radar generates Abstract Syntax Trees (ASTs) for multiple smart contract languages and frameworks. Many users leverage radar purely for its AST generation capabilities, independent of security scanning.

## Supported Languages & Frameworks

### Rust-Based
- **Anchor** (Solana framework)
- **Native Rust** (Solana programs)
- **Stylus** (Arbitrum Rust contracts)

### Solidity-Based
- **Solidity** (standalone contracts)
- **Foundry** (Solidity projects)

All frameworks use Rust's `syn` parser via `rust_syn_wrapper` for consistent, high-quality AST output.

## Generating AST Output

### Basic AST Generation
```bash
radar -p <contract-path> --ast -o output.json
```

This produces a JSON file with two main sections:
- `results`: Security findings (empty if no issues)
- `ast`: Complete AST structure of all scanned files

### AST-Only Mode
To generate AST without running security scans, use a minimal template directory or ignore all severities:

```bash
# Option 1: Ignore all severities
radar -p <contract-path> --ast --ignore low,medium,high,uncertain -o output.json

# Option 2: Empty template directory
mkdir empty_templates
radar -p <contract-path> --ast -t empty_templates -o output.json
```

## Framework-Specific Examples

### Anchor Projects
```bash
radar -p ./my-anchor-project --ast -o anchor_ast.json
```

Detects Anchor macros (`#[program]`, `#[account]`, etc.) and generates AST including:
- Account structures
- Program instructions
- Context definitions
- CPI calls

### Native Rust (Solana)
```bash
radar -p ./native-solana-program --ast -o rust_ast.json
```

Parses raw Solana programs without Anchor framework.

### Stylus Contracts
```bash
radar -p ./stylus-contract --ast -o stylus_ast.json
```

Generates AST for Arbitrum Stylus Rust contracts.

### Solidity Contracts
```bash
radar -p ./solidity-contract --ast -o solidity_ast.json
```

Parses standalone Solidity files.

### Foundry Projects
```bash
radar -p ./foundry-project --ast -o foundry_ast.json
```

Scans entire Foundry project structure including:
- Source contracts (`src/`)
- Test contracts (`test/`)
- Scripts (`script/`)
- Libraries (`lib/`)

## AST Structure

The output JSON has this structure:

```json
{
  "results": [...],
  "ast": {
    "file1.rs": {
      "nodes": [
        {
          "type": "ItemFn",
          "ident": "function_name",
          "access_path": "root.function_name",
          "children": [...],
          "metadata": {...}
        }
      ]
    },
    "file2.rs": {...}
  }
}
```

### Key AST Fields
- `type`: Node type (ItemFn, ItemStruct, Expr, etc.)
- `ident`: Identifier/name of the node
- `access_path`: Hierarchical path to the node
- `children`: Nested child nodes
- `metadata`: Additional context (line numbers, attributes, etc.)

## Using AST for Development

### Understanding Contract Structure
```bash
# Generate AST
radar --dev -p <contract-path> --ast -o debug.json

# Open debug.json and examine:
# - Function declarations (ItemFn)
# - Struct definitions (ItemStruct)
# - Macro attributes (Attribute)
# - Method calls (MethodCall)
# - Comparisons (ExprBinary)
```

### Template Development Workflow
1. **Generate AST of vulnerable contract**:
   ```bash
   radar --dev -p api/tests/mocks/my_vuln/bad --ast -o bad_ast.json
   ```

2. **Examine AST structure**: Find the nodes representing the vulnerability

3. **Generate AST of safe contract**:
   ```bash
   radar --dev -p api/tests/mocks/my_vuln/good --ast -o good_ast.json
   ```

4. **Compare**: Identify what differs between vulnerable and safe patterns

5. **Write template rule**: Use DSL to query the pattern identified in the AST

### Debugging Templates
When a template doesn't work:

1. **Add debug output in template**:
   ```python
   # In your template rule
   some_nodes.to_raw_ast_debug()  # Prints AST at this point
   ```

2. **Run with AST**:
   ```bash
   radar --dev -p <contract> --ast -o debug.json
   ```

3. **Compare**: Check what the template sees vs. what's actually in the AST

## AST Node Types

Common node types you'll encounter:

### Rust/Anchor
- `ItemFn`: Function declarations
- `ItemStruct`: Struct definitions
- `ItemImpl`: Implementation blocks
- `Expr`: Expressions
- `ExprBinary`: Binary operations (comparisons, arithmetic)
- `ExprMethodCall`: Method calls (e.g., `ctx.invoke()`)
- `ExprField`: Field access (e.g., `account.is_signer`)
- `Attribute`: Macro attributes (e.g., `#[program]`)
- `Pat`: Patterns (in match, let statements)
- `Stmt`: Statements

### Solidity
Solidity ASTs follow similar patterns with contract-specific nodes for:
- Contract declarations
- Function visibility
- State variables
- Events and modifiers

## Advanced AST Usage

### Filtering Specific Files
Use the `-s/--source` flag to scope AST generation:

```bash
# Only process src/ directory
radar -p ./project --source src --ast -o src_ast.json

# Specific file
radar -p ./project --source src/lib.rs --ast -o lib_ast.json
```

### Development Mode
Always use `--dev` when working with AST for detailed logging:

```bash
radar --dev -p <path> --ast -o output.json
```

This enables:
- Verbose DSL function logs
- Detailed parsing information
- Error traces

### Output Format
AST is always in JSON format. Use the `.json` extension:

```bash
radar -p <path> --ast -o analysis.json  # ✅ Correct
radar -p <path> --ast -o analysis.md    # ❌ AST still JSON, results in MD
```

## Integration with Other Tools

The AST output can be consumed by:
- Custom analysis scripts
- IDE integrations
- Documentation generators
- Code visualization tools
- AI/ML models for code understanding

Example Python script to parse radar AST:

```python
import json

with open('output.json', 'r') as f:
    data = json.load(f)
    
ast = data['ast']
for file_path, file_data in ast.items():
    print(f"\n=== {file_path} ===")
    for node in file_data.get('nodes', []):
        if node.get('type') == 'ItemFn':
            print(f"  Function: {node.get('ident')}")
```

## Performance Notes

AST generation is fast and scales well:
- Small contracts: <1 second
- Medium projects: 1-5 seconds
- Large projects (Foundry with deps): 5-30 seconds

The bottleneck is usually Docker container startup, not parsing.

## Common Use Cases

### 1. Code Analysis Tools
Use radar as an AST frontend for custom analysis:
```bash
radar -p ./contract --ast --ignore low,medium,high -o ast.json
# Process ast.json with your tools
```

### 2. Documentation Generation
Extract function signatures, structs, and comments from AST.

### 3. Refactoring Tools
Understand code structure before automated refactoring.

### 4. Educational Purposes
Visualize how Rust/Solidity code is parsed and structured.

### 5. Template Development
Essential for writing radar security templates.

## Troubleshooting

### Empty AST Output
- Ensure contract compiles (radar skips unparseable files)
- Check file extensions (.rs, .sol)
- Verify Docker is running

### Missing Nodes
- Some nodes may be filtered by radar's parser
- Check raw output in dev mode
- Verify the code pattern you're looking for exists

### Large AST Files
For huge projects, consider:
- Using `--source` to scope to specific directories
- Processing files incrementally
- Filtering AST in post-processing

## references/dsl-functions.md

# DSL Function Reference

Template rules inherit from `RustASTNode` in `api/utils/dsl/dsl_ast_iterator.py`. These methods enable querying and navigating the AST.

## Control Flow

### exit_on_none()
Stop execution if no nodes are found. Use when a pattern must exist.

```python
nodes.find_by_names("Signer").exit_on_none()  # Stop if no Signer found
```

### exit_on_value()
Stop execution if nodes are found. Use to verify absence of a safeguard.

```python
nodes.find_by_names("Signer").exit_on_value()  # Stop if Signer exists
```

## Finding Patterns

### find_by_names(*idents)
Find nodes by identifier name.

```python
nodes.find_by_names("Account", "Signer")  # Find Account or Signer
```

### find_functions_by_names(*function_names)
Find function declarations by name.

```python
nodes.find_functions_by_names("initialize", "update")
```

### find_all_functions()
Find all function declarations.

```python
all_funcs = nodes.find_all_functions()
```

### find_method_calls(caller, method)
Find method invocations on a specific caller.

```python
nodes.find_method_calls("ctx", "invoke")  # Find ctx.invoke() calls
```

### find_chained_calls(*idents)
Find chained method calls in sequence.

```python
nodes.find_chained_calls("derive", "Accounts")  # Find .derive().Accounts()
```

### find_macro_attribute_by_names(*idents)
Find macro attributes by name.

```python
nodes.find_macro_attribute_by_names("program", "account")
```

### find_comparison_involving(ident)
Find comparison operations involving an identifier.

```python
nodes.find_comparison_involving("is_signer")  # Find comparisons with is_signer
```

### find_comparisons_between(ident1, ident2)
Find comparisons between two identifiers.

```python
nodes.find_comparisons_between("balance", "amount")
```

### find_member_accesses(member)
Find member access operations.

```python
nodes.find_member_accesses("is_signer")  # Find .is_signer accesses
```

### find_by_access_path(access_path_part)
Find nodes by access path substring.

```python
nodes.find_by_access_path("accounts.user")
```

### find_by_similar_access_path(access_path_part)
Find nodes with similar access paths (fuzzy matching).

```python
nodes.find_by_similar_access_path("ctx.accounts")
```

### find_by_parent(parent_ident)
Find nodes with a specific parent identifier.

```python
nodes.find_by_parent("MyStruct")
```

### find_by_child(child_ident)
Find nodes containing a specific child identifier.

```python
nodes.find_by_child("inner_field")
```

### find_negative_of_operation(operation_type)
Find logical negations of specific operations.

```python
nodes.find_negative_of_operation("comparison")
```

## Result Manipulation

### first()
Get the first node from a list. Raises StopIteration if empty.

```python
vulnerable_node = nodes.find_by_names("RiskyType").first()
```

### to_result()
Convert node to structured finding format for radar output.

```python
print(vulnerable_node.to_result())  # Report the issue
```

### to_raw_ast_debug()
Print detailed AST structure for debugging. Don't call print(), just add to template code.

```python
some_nodes.to_raw_ast_debug()  # Debug helper
```

## Node Lists

Methods return `ASTNodeList` or `ASTNodeListGroup` which support:
- Iteration: `for node in node_list:`
- Indexing: `node_list[0]`
- Length: `len(node_list)`
- Chaining: All methods return lists for further querying

## Common Combinations

### Detect pattern without safeguard
```python
risky = nodes.find_by_names("UnsafeType").exit_on_none()
nodes.find_comparison_involving("is_safe").exit_on_value()
print(risky.first().to_result())
```

### Find function with missing check
```python
func = nodes.find_functions_by_names("transfer").exit_on_none()
func.find_by_names("Signer").exit_on_value()
print(func.first().to_result())
```

### Chain multiple queries
```python
accounts = nodes.find_macro_attribute_by_names("account").exit_on_none()
missing_check = accounts.find_by_names("Signer").exit_on_none()
print(missing_check.first().to_result())
```

## Error Handling

All template rules run in try/except blocks:
```python
for source, nodes in ast:
    try:
        # Rule logic
    except:
        continue  # Skip this file on any error
```

Use `exit_on_none()` and `exit_on_value()` to control flow instead of manual exception handling.

## references/template-writing.md

# Template Writing Guide

Templates are YAML files that define security checks for smart contracts. Each template operates on AST nodes and uses a DSL to query and identify vulnerable patterns.

## Template Structure

```yaml
version: 0.1.0
author: your-name
accent: anchor  # or stylus, solidity
name: Template Name
description: Brief description of the vulnerability
severity: Low|Medium|High
certainty: Low|Medium|High
vulnerable_example: URL to example vulnerable code
rule: |
  for source, nodes in ast:
      try:
          # Your detection logic here
      except:
          continue
```

## Core Principles

### Zero False Positives
Templates MUST NOT produce false positives. Every detection must be a real issue.

### Generalize Patterns
Write rules that generalize from specific examples to catch similar issues across contracts. Don't hard-code values or make rules contract-specific.

### Keep It Simple
Avoid complex logic that's hard to maintain. Prefer clear, readable code over clever tricks.

### Point to the Core Issue
Results must point to the exact line that represents the vulnerability, not just the function or file.

## Template Rule Flow

Rules operate on `(source, nodes)` pairs from the AST iterator:
- `source`: File path
- `nodes`: RustASTNode with DSL methods for querying

Common pattern:
```python
for source, nodes in ast:
    try:
        # Find patterns
        vulnerable_pattern = nodes.find_by_names("SomeType").exit_on_none()
        
        # Verify absence of mitigation
        nodes.find_by_names("SafeguardType").exit_on_value()
        
        # Report the issue
        print(vulnerable_pattern.first().to_result())
    except:
        continue
```

## Essential DSL Methods

### Exit Controls
- `exit_on_none()`: Stop if no matches (pattern not found)
- `exit_on_value()`: Stop if matches found (safeguard exists)

These prevent exceptions and control rule flow efficiently.

### Finding Patterns
- `find_by_names(*idents)`: Find nodes by identifier
- `find_functions_by_names(*names)`: Find function declarations
- `find_method_calls(caller, method)`: Find method invocations
- `find_chained_calls(*idents)`: Find chained method calls
- `find_comparison_involving(ident)`: Find comparisons with identifier
- `find_macro_attribute_by_names(*idents)`: Find macro attributes

### Accessing Results
- `first()`: Get first node from list
- `to_result()`: Convert to structured finding format
- `to_raw_ast_debug()`: Debug AST structure (don't call print, just add to code)

## Writing Workflow

1. **Understand the vulnerability**: Study real examples
2. **Identify the pattern**: What makes code vulnerable?
3. **Identify mitigations**: What makes code safe?
4. **Write the rule**: Detect pattern, verify no mitigation
5. **Test against bad example**: Must detect all issues
6. **Test against good example**: Must detect nothing
7. **Add unit test**: Add to `api/tests/test_templates.py`

## Testing

Every template requires:
- `api/tests/mocks/<template_name>/bad/src/lib.rs`: Vulnerable code
- `api/tests/mocks/<template_name>/good/src/lib.rs`: Safe code
- Unit test in `api/tests/test_templates.py`

Test with:
```bash
radar --dev --path api/tests/mocks/<template_name>/bad --ast --output outputs/out.json
```

Use `--ast` flag to inspect AST structure and verify your rule logic.

## Common Patterns

### Pattern: Missing check
```python
# Detect usage of risky pattern
risky = nodes.find_by_names("RiskyType").exit_on_none()

# Verify no safeguard
nodes.find_by_names("SafeguardType").exit_on_value()

# Report
print(risky.first().to_result())
```

### Pattern: Incorrect ordering
```python
# Find state changes
state_change = nodes.find_by_names("state_var").exit_on_none()

# Find external calls
external_call = nodes.find_method_calls("ctx", "invoke").exit_on_none()

# Report if state change happens after call (simplified)
print(state_change.first().to_result())
```

## Debugging

1. Use `--dev` mode for detailed logs
2. Add `node.to_raw_ast_debug()` in template to inspect AST
3. Check `dsl_log` decorator output for function call traces
4. Test one template at a time against one contract
5. Run `make test` before considering feature complete

## Avoid

- Comments unless absolutely necessary
- Hard-coded values or contract-specific logic
- Overly complex queries
- Generic detections (e.g., all imports)
- False positives (0% tolerance)

## references/usage.md

# Usage Guide

## Installation

Radar requires Docker to be installed and running.

### Quick Install
```bash
curl -L https://raw.githubusercontent.com/auditware/radar/main/install-radar.sh | bash
```

### From Source
```bash
git clone https://github.com/auditware/radar.git
cd radar
bash install-radar.sh
```

## Basic Usage

### Scan a Contract
```bash
radar -p <path-to-contract>
```

Example:
```bash
radar -p ./my-contract
```

### Development Mode
Run from local source with debug output:
```bash
radar --dev -p <path-to-contract>
```

### Output AST
Generate AST alongside vulnerability results:
```bash
radar -p <path> --ast --output results.json
```

The AST output is essential for:
- Understanding contract structure
- Debugging template rules
- Developing new templates

### Custom Templates
Run with custom template directory:
```bash
radar -p <path> -t <templates-directory>
```

### Filter Results
Ignore specific severity levels:
```bash
radar -p <path> --ignore low,medium
```

### Output Formats
Control output via file extension:
```bash
radar -p <path> -o results.json   # JSON format
radar -p <path> -o results.md     # Markdown format
radar -p <path> -o results.sarif  # SARIF format
```

## Common Workflows

### Finding Vulnerabilities
```bash
# Basic scan
radar -p ./contract

# Scan with custom templates
radar -p ./contract -t ./my-templates

# Scan and save results
radar -p ./contract -o findings.json
```

### Developing Templates

1. **Run with AST output**:
```bash
radar --dev -p api/tests/mocks/my_template/bad --ast -o output.json
```

2. **Inspect AST structure**: Open `output.json` and examine the `ast` field

3. **Write rule in template**: Use DSL functions to query the AST

4. **Test the template**:
```bash
# Test against vulnerable code (should detect)
radar --dev -p api/tests/mocks/my_template/bad

# Test against safe code (should not detect)
radar --dev -p api/tests/mocks/my_template/good
```

5. **Run unit tests**:
```bash
make test
```

### Debugging Templates

When a template doesn't work as expected:

1. **Enable dev mode for detailed logs**:
```bash
radar --dev -p <contract-path>
```

2. **Add debug output in template**:
```python
# In your template rule
some_nodes.to_raw_ast_debug()  # Inspect AST at this point
```

3. **Run single template**:
```bash
# Create temp directory with only your template
mkdir temp_templates
cp api/builtin_templates/my_template.yaml temp_templates/
radar --dev -p <contract> -t temp_templates
```

4. **Check AST output**: Compare template logic with actual AST structure

## Command Reference

### Scan Commands
- `radar scan` or `radar -p <path>`: Run vulnerability scan
- `radar list-templates`: List all available templates
- `radar info`: Display template information
- `radar update`: Update radar to latest version

### Scan Options
- `-p, --path`: Target contract path (required)
- `-s, --source`: Specific source/scope within contract
- `-t, --templates`: Custom templates directory
- `-i, --ignore`: Severities to ignore (low,medium,high,uncertain)
- `-o, --output`: Results output file path
- `-a, --ast`: Output parsed AST
- `-d, --dev`: Development mode with debug output
- `-u, --update`: Pull latest Docker images before running
- `-ss, --store-sarif`: Accumulate SARIF results from previous runs

## Integration

### GitHub Action
Add to `.github/workflows/radar.yml`:
```yaml
name: Radar Security Scan
on: [push, pull_request]
jobs:
  scan:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
      - uses: Auditware/radar-action@v1
```

### Pre-commit Hook
Add to `.git/hooks/pre-commit`:
```bash
#!/bin/sh
if ! command -v radar >/dev/null 2>&1; then
  curl -sL https://raw.githubusercontent.com/auditware/radar/main/install-radar.sh | bash
fi
radar -p . --ignore low
```

Or with pre-commit framework in `.pre-commit-config.yaml`:
```yaml
repos:
  - repo: local
    hooks:
      - id: run-radar
        name: Run radar Static Analysis
        entry: radar -p . --ignore low
        language: system
        stages: [commit]
        pass_filenames: false
        always_run: true
```

