# Smart Code AI Reviewer (by SF COE AI Labs)

[![License](https://img.shields.io/badge/License-BSD%203--Clause-blue.svg)](https://opensource.org/licenses/BSD-3-Clause)
[![Node.js](https://img.shields.io/badge/Node.js-18%2B-green.svg)](https://nodejs.org/)
[![TypeScript](https://img.shields.io/badge/TypeScript-5.8%2B-blue.svg)](https://www.typescriptlang.org/)

> **AI-assisted code review tool that combines static analysis with artificial intelligence to provide comprehensive code quality assessments for Salesforce and multi-language projects.**

---

## Table of Contents

- [Overview](#-overview)
- [Prerequisites](#-prerequisites)
- [Installation](#-installation)
- [Usage](#-usage)
- [Examples](#-examples)
- [Architectural Components](#️-architectural-components)
- [Tools & Technologies](#️-tools--technologies)
- [Workflow Integration](#-workflow-integration)
- [AI Analysis Output](#-ai-analysis-output)
- [License](#-license)
- [Support](#-support)
- [Roadmap](#-roadmap)

---

## 🚀 Overview

<b>Smart Code AI Reviewer</b> is a standalone CLI tool that revolutionizes code review workflows by integrating multiple static analysis tools with AI-powered insights. The tool performs hybrid analysis on code changes, combining <b>Salesforce Code Analyzer (SCA)</b> for Salesforce-specific files and <b>PMD</b> for general programming languages, then leverages <b>AI models</b> to provide intelligent, contextual code review comments.

---

## 📋 Prerequisites

- **Node.js** 20.0.0 or higher
- **Salesforce CLI** installed and configured
- **Git** repository with commit history
- **Java** (v11 or higher - required to run PMD commands)
- **Python** (v3.10 or higher - required for enabled FlowEngine check in SF Code Analyzer)
- **AI Provider API Key** (AzureOpenAI, OpenAI or Anthropic)
- **GitHub Token** (optional, for PR comments)
- **Datadog API Key** (optional, for observability features)

---

### Static Analysis Tools

- **Salesforce Code Analyzer**: Automatically managed by the tool
- **PMD**: Automatically invoked for non-Salesforce files

---

## 🚀 Installation

### As a Standalone CLI Tool

```bash
# Install globally from npm
npm install -g ds-sfcoe-ailabs
```

---

## 💻 Usage

### Basic Command Structure

```bash
ds-sfcoe-ailabs pr-review [OPTIONS]
```

### Required Flags

| Flag            | Short | Description                          | Example                                | Default               |
| --------------- | ----- | ------------------------------------ | -------------------------------------- | --------------------- |
| `--ai-provider` | `-a`  | AI service provider                  | `AzureOpenAI`, `OpenAI` or `Anthropic` | `AzureOpenAI`         |
| `--ai-token`    | `-n`  | Authentication token for AI provider | `$OPENAI_TOKEN`                        |                       |
| `--ai-model`    | `-m`  | AI model to use                      | `gpt-4o-mini`, `claude-3-sonnet`       | `gpt-4o-mini-eastus2` |

### Optional Flags

| Flag                | Short | Description                    | Default                                     |
| ------------------- | ----- | ------------------------------ | ------------------------------------------- |
| `--repo-dir`        | `-r`  | Path to Git repository         | Current directory                           |
| `--from`            | `-f`  | Base commit/branch             | `HEAD~1`                                    |
| `--to`              | `-t`  | Target commit/branch           | `HEAD`                                      |
| `--sf-config-file`  | `-s`  | SCA configuration file (YAML)  | Built-in ruleset                            |
| `--pmd-config-file` | `-x`  | PMD configuration file (XML)   | Built-in ruleset                            |
| `--pull-request-id` | `-p`  | PR ID for comment posting      | None                                        |
| `--git-provider`    | `-g`  | Git hosting service            | `GitHub`                                    |
| `--git-token`       | `-k`  | Git provider token             | None                                        |
| `--git-owner`       | `-w`  | Repository owner               | None                                        |
| `--git-repo`        | `-o`  | Repository name                | None                                        |
| `--ai-api-endpoint` | `-e`  | AzureOpenAI endpoint           | `https://dts-apigw-sandbox.docusignhq.com/` |
| `--ai-api-version`  | `-v`  | AzureOpenAI deployment version | `2024-08-01-preview`                        |

---

## 📚 Examples

### Basic Local Analysis

```bash
ds-sfcoe-ailabs pr-review \
  --repo-dir=./my-salesforce-project \
  --ai-provider=AzureOpenAI \
  --ai-token=$AZURE_OPENAI_TOKEN \
  --ai-model=gpt-4o-mini-eastus2 \
  --ai-api-endpoint=https://dts-apigw-sandbox.docusignhq.com/ \
  --ai-api-version=2024-08-01-preview \
  --from=main \
  --to=HEAD \
  --sf-config-file=code-analyzer/sf-code-analyzer-ruleset.yml \
  --pmd-config-file=code-analyzer/pmd-ruleset.yml
```

### Integration with GitHub Action

```bash
ds-sfcoe-ailabs pr-review \
  --repo-dir=./my-salesforce-project \
  --ai-provider=AzureOpenAI \
  --ai-token=$AZURE_OPENAI_TOKEN \
  --ai-model=gpt-4o-mini-eastus2 \
  --ai-api-endpoint=https://dts-apigw-sandbox.docusignhq.com/ \
  --ai-api-version=2024-08-01-preview \
  --git-provider=GitHub \
  --git-token=$GITHUB_TOKEN \
  --git-owner=myorg \
  --git-repo=my-repo \
  --pull-request-id=123 \
  --from=main \
  --to=HEAD \
  --sf-config-file=code-analyzer/sf-code-analyzer-ruleset.yml \
  --pmd-config-file=code-analyzer/pmd-ruleset.yml
```

---

## 🏗️ Architectural Components

### 1. **Core Command Layer**

- **Main Command**: `ds-sfcoe-ailabs pr-review` - Entry point for code review operations
- **CLI Interface**: Built on OCLIF framework as a standalone CLI tool

### 2. **Git Integration Layer**

- **Git Helper**: Manages repository operations and diff creation
- **Git Providers**: Support for GitHub (extensible for other providers)
- **Diff Management**: Creates temporary directories with code changes

### 3. **Static Analysis Layer**

- **Hybrid Analysis Engine**: Orchestrates different analysis tools
- **SCA Integration**: Salesforce Code Analyzer for Apex, LWC, Visualforce
- **PMD Integration**: PMD for JavaScript, TypeScript, HTML, PL/SQL
- **SARIF Processing**: Standardized Static Analysis Results Interchange Format

### 4. **AI Integration Layer**

- **AI Providers**: AzureOpenAI, OpenAI and Anthropic Claude integration
- **Context Processing**: Converts static analysis results to AI prompts
- **Response Handling**: Processes AI-generated review suggestions

### 5. **Configuration Layer**

- **Default Rulesets**: Built-in configuration files for both SCA and PMD
- **Custom Configuration**: Support for user-defined ruleset files
- **File-based Configuration**: YAML for SCA, XML for PMD

---

## 🛠️ Tools & Technologies

### **Core Technologies**

- **Language**: TypeScript 5.8+
- **Runtime**: Node.js 18+
- **CLI Framework**: OCLIF (Open CLI Framework)
- **Build System**: Wireit (Incremental build tool)

### **Static Analysis Tools**

- **Salesforce Code Analyzer (SCA)**: Official Salesforce static analysis tool
  - ESLint for JavaScript/TypeScript/LWC
  - PMD for Apex
  - Retire.js for security vulnerabilities
  - Custom regex rules
- **PMD**: Multi-language static analysis
  - JavaScript, TypeScript, HTML
  - PL/SQL and other database languages

### **AI Providers**

- **AzureOpenAI**: GPT-4, GPT-4o-mini models via Azure OpenAI endpoint
- **OpenAI**: GPT-4, GPT-4o-mini models via OpenAI model
- **Anthropic**: Claude models (claude-3-sonnet, claude-3-haiku)
- **Custom Prompts**: Specialized prompts for code review context with JSON schema validation

### **Git Integration**

- **SimpleGit**: Git operations and repository management
- **GitHub REST APIs**: Pull request comment integration with intelligent comment management for bot comments to avoid duplication
- **Bot Identification**: Multiple methods to identify and manage AI-generated comments

### **Development Tools**

- **Testing**: Jest, NYC (coverage), Mocha with comprehensive unit tests
- **Linting**: ESLint with TypeScript and code quality rules
- **Formatting**: Prettier
- **Type Checking**: TypeScript compiler
- **Observability**: Winston logging with Datadog integration, Datadog metrics
- **Git Hooks**: Husky for pre-commit validation
- **Build System**: Wireit for incremental compilation
- **Security**: Automated security scanning in pre-commit hooks
- **Commit Validation**: Commitlint for conventional commit messages

---

## 🔄 Workflow Integration

### CI/CD Pipeline Integration

```yaml
# .github/workflows/code-review.yml
name: Generate AI Code Suggestions

on:
  pull_request:
    types: [opened, synchronize, reopened]
  workflow_dispatch: # Can also be manually triggered, if needed.

permissions:
  contents: write # Required to commit changes from Salesforce and push them back to the remote.
  packages: read
  pull-requests: write
  id-token: write

jobs:
  generate-suggestions:
    runs-on: [self-hosted, linux]

    container:
      image: <docker_image_url>
      credentials:
        username: ${{ github.actor }}
        password: ${{ secrets.GITHUB_TOKEN }}

    env: # Set global environment variables for the job
      AI_PROVIDER: ${{ secrets.AI_PROVIDER }}
      AI_MODEL: ${{ secrets.AI_MODEL }}
      AI_API_ENDPOINT: ${{ secrets.AI_API_ENDPOINT }}
      AI_API_VERSION: ${{ secrets.AI_API_VERSION }}
      AI_TOKEN: ${{ secrets.AI_TOKEN }}
      GIT_TOKEN: ${{ secrets.GITHUB_TOKEN }}
      BASE_COMMIT: ${{ github.event.pull_request.base.sha }}
      HEAD_COMMIT: ${{ github.event.pull_request.head.sha }}
      DD_API_KEY: ${{ secrets.DD_API_KEY }}
      PMD_VERSION: ${{ secrets.PMD_VERSION || '7.15.0' }}
      MAX_TOKENS_PER_REQUEST: ${{ secrets.MAX_TOKENS_PER_REQUEST || '4096' }}
      DD_SOURCE: ${{ secrets.DD_SOURCE }}
      DD_HOSTNAME: ${{ secrets.DD_HOSTNAME }}
      DD_SERVICE: ${{ secrets.DD_SERVICE }}
      DD_METRIC_PREFIX: ${{ secrets.DD_METRIC_PREFIX' }}
      DD_ENV: ${{ secrets.DD_ENV }}
      LOG_LEVEL: ${{ secrets.LOG_LEVEL }}
      BOT_NAME: <bot_name>
      BOT_EMAIL: <bot_email>

    steps:
      - name: Checkout repository
        uses: actions/checkout@v4
        with:
          fetch-depth: 0 # Needed to fetch full history for git diffing later

      - name: Add safe directory for Git ownership
        run: |
          git config --global --add safe.directory "$(pwd)"
          echo "Git safe directory configured."

      - name: Configure Git Bot Identity
        run: |
          git config user.name "${{ env.BOT_NAME }}"
          git config user.email "${{ env.BOT_EMAIL }}"

      - name: Install Salesforce CLI
        run: |
          echo "Installing SF CLI package"
          npm install -g @salesforce/cli || { echo "Failed to install SF CLI" && exit 1; }
          echo "SF CLI installed successfully."

      - name: Ensure Java v11 or greater
        uses: actions/setup-java@v4
        with:
          java-version: '>=11'
          distribution: 'zulu'

      - name: Ensure Python v3.10 or greater
        uses: actions/setup-python@v5
        with:
          python-version: '>=3.10'

      - name: Install PMD CLI
        run: |
          echo "Installing PMD CLI"

          # Check Java version
          echo "Checking Java version..."
          if ! java -version 2>&1 | head -1; then
            echo "Java is not installed or not in PATH"
            exit 1
          fi

          # Check Python version
          echo "Checking Python version..."
          if ! python --version 2>/dev/null && ! python3 --version 2>/dev/null; then
            echo "Python is not installed or not in PATH"
            exit 1
          fi

          PMD_VERSION=${PMD_VERSION}
          PMD_URL="https://github.com/pmd/pmd/releases/download/pmd_releases%2F${PMD_VERSION}/pmd-dist-${PMD_VERSION}-bin.zip"

          echo "Downloading PMD from: $PMD_URL"
          # Download PMD with more verbose output for debugging
          if ! wget --progress=dot:giga "$PMD_URL" -O pmd.zip; then
            echo "Failed to download PMD from $PMD_URL"
            echo "Trying alternative download method..."
            # Try with curl as fallback
            if ! curl -L "$PMD_URL" -o pmd.zip; then
              echo "Failed to download PMD with both wget and curl"
              exit 1
            fi
          fi

          # Verify the zip file was downloaded
          if [ ! -f pmd.zip ] || [ ! -s pmd.zip ]; then
            echo "PMD zip file is missing or empty"
            exit 1
          fi

          # Extract PMD
          echo "Extracting PMD..."
          if ! unzip -q pmd.zip; then
            echo "Failed to extract PMD zip file"
            exit 1
          fi

          # Move PMD to relevant folder and add it to path
          echo "Setting up PMD..."
          if ! mv pmd-bin-${PMD_VERSION} pmd; then
            echo "Failed to move PMD directory"
            exit 1
          fi

          # Add PMD to PATH
          PMD_BIN_PATH="$(pwd)/pmd/bin"
          echo "$PMD_BIN_PATH" >> $GITHUB_PATH
          export PATH="$PMD_BIN_PATH:$PATH"

          # Verify PMD installation with explicit path
          echo "Verifying PMD installation..."
          if ! "$PMD_BIN_PATH/pmd" --version; then
            echo "PMD installation verification failed"
            echo "Checking if PMD binary exists..."
            ls -la "$PMD_BIN_PATH/" || echo "PMD bin directory not found"
            exit 1
          fi

          echo "PMD CLI installed successfully."

          # Clean up
          rm -f pmd.zip

      - name: Install ds-sfcoe-ailabs CLI tool
        run: |
          echo "Installing ds-sfcoe-ailabs CLI tool"
          npm install -g ds-sfcoe-ailabs

      - name: Verify CLI tool installation
        run: |
          echo "Verifying CLI tool installation"
          ds-sfcoe-ailabs --version
          if [ $? -ne 0 ]; then
            echo "Error: CLI tool 'ds-sfcoe-ailabs' not found after installation attempt."
            echo "Please ensure the package installation was successful."
            exit 1
          else
            echo "CLI tool 'ds-sfcoe-ailabs' is successfully installed."
          fi

      - name: Run the AI-assisted Pull Request Review app
        run: |
          # Ensure the tmp-diff and code-analyzer-logs directories exists
          mkdir -p tmp-diff
          mkdir -p code-analyzer/code-analyzer-logs

          # Construct the command with parameters
          REVIEW_COMMAND="ds-sfcoe-ailabs pr-review --repo-dir=. --ai-provider=${AI_PROVIDER} --ai-model=${AI_MODEL} --ai-token=${AI_TOKEN} --git-provider=GitHub --git-token=${GIT_TOKEN} --git-owner=${{ github.repository_owner }} --git-repo=${{ github.event.repository.name }} --pull-request-id=${{ github.event.pull_request.number }} --from=${BASE_COMMIT} --to=${HEAD_COMMIT} --ai-api-version=${AI_API_VERSION} --ai-api-endpoint=${AI_API_ENDPOINT}"

          # Print the command
          echo "Executing the command: $REVIEW_COMMAND"

          # Run the command
          $REVIEW_COMMAND
```

---

## 📊 AI Analysis Output

### Enhanced GitHub Integration

#### **Intelligent Comment Management**

- **Single Comment Per Analysis**: The tool maintains one AI-generated comment per pull request analysis
- **Update on Re-run**: Subsequent runs update the existing comment instead of creating new ones
- **Clear Bot Identification**: All bot comments are clearly marked with recognizable headers and signatures
- **Backward Compatibility**: Supports identifying and updating comments from previous versions

### Review Report Structure

The tool generates comprehensive review reports with:

#### **1. Code Quality Review**

- File-by-file issue breakdown
- Rule violations with line numbers
- Severity classification (Critical, High, Moderate, Low, Info)

#### **2. AI Suggestion Table**

- Intelligent issue prioritization
- Context-aware suggestions
- Code improvement recommendations
- Security and performance insights

#### **3. Docusign-Specific Checks**

- Test framework validation (SObjectMocker vs legacy patterns)
- Performance anti-patterns (Schema.getGlobalDescribe() usage)
- Security compliance checks
- Custom DocuSign development best practices

#### **4. Observability Features (on Datadog, if enabled)**

- Real-time logging with configurable levels
- Performance metrics and execution timing
- Error tracking with stack traces
- Custom metrics for analysis results

---

## 📄 License

This project is licensed under the BSD 3-Clause License - see the [LICENSE](LICENSE) file for details.

---

## 🆘 Support

### Common Issues

#### **1. Missing AI Token**

```bash
Error: Missing required flag: --ai-token
```

**Solution**: Set your AI provider token as an environment variable or pass it directly.

#### **2. Git Repository Not Found**

```bash
Error: Not a git repository
```

**Solution**: Ensure you're running the command in a Git repository or specify `--repo-dir`.

#### **3. No Changes Detected**

```bash
No issues found in analysis
```

**Solution**: Verify there are actual code changes between the specified commits/branches.

#### **4. GitHub API Issues**

**Comment Update vs Creation**: The tool now intelligently updates existing AI comments instead of creating duplicates. If you see multiple AI comments from older versions, they will be consolidated on the next run.

**Bot Comment Not Updating**: If the tool creates new comments instead of updating existing ones, ensure the previous comments contain the proper bot identification markers.

**GitHub API Rate Limits**: If you encounter rate limiting issues:

- Use a personal access token with appropriate permissions
- Ensure the token has `repo` and `pull_request` scopes
- Consider running analysis less frequently in CI/CD

### 🐛 **Additional Troubleshooting**

#### **5. File Analysis Issues**

```bash
No supported files found for analysis
```

**Solution**: The tool supports multiple file types including:

- **Salesforce**: `.cls`, `.trigger`, `.page`, `.component`, `.cmp`
- **JavaScript/TypeScript**: `.js`, `.ts`, `.mjs`, `.cjs`
- **Web**: `.html`, `.htm`, `.css`, `.xhtml`, `.xht`, `.shtml`
- **Database**: `.sql`, `.pks`, `.pkb`, `.prc`, `.fnc`, `.trg`, `.typ`, `.tps`, `.tpb`
- **Java**: `.java`
- **Aura Components**: `.cmp`
- **Visualforce**: `.page`, `.component`
- **Metadata**: `.xml`, `.json`, `.yaml`, `.yml`

Ensure your repository contains files with these extensions.

#### **6. Datadog Integration Issues**

```bash
Failed to initialize Datadog logger
```

**Solution**: Datadog integration is optional. If not using observability features, you can omit the `DD_API_KEY` environment variable.

---

## 🔮 Roadmap

- [ ] **Additional AI Providers**: Support for Google Gemini
- [ ] **More Git Providers**: BitBucket, GitLab integration
- [ ] **Enhanced Analysis**: Code complexity metrics, technical debt assessment
- [ ] **IDE Integration**: VS Code extension
- [ ] **Workflow Templates**: Pre-built CI/CD configurations
- [ ] **Custom Rule Development**: SDK for creating custom analysis rules
- [ ] **Comment Management**: Advanced comment threading and resolution tracking
- [ ] **Multi-language Support**: Expanded language coverage for static analysis
- [ ] **Performance Optimization**: Caching and incremental analysis
- [ ] **Security Enhancements**: Advanced secret detection and vulnerability scanning

---

**Made by SF COE Team, with ❤️ for our Salesforce Developer Community**
