# Zshrc Aliases Development Guide

This document provides comprehensive guidelines for creating and maintaining high-quality shell alias functions in this dotfiles repository.

## Overview

This guide is specifically designed for developers working with zshrc alias files in the `shells/oh-my-zsh/custom/aliases/` directory. It ensures consistency, quality, and best practices across all alias functions.

## Core Requirements

### Function Format
Expose commands with a normal alias that points to a wrapper function:
```bash
_category_aliases_command_name() {
  # command logic
}

alias command-name='_category_aliases_command_name'
```

Avoid `alias command-name='() { ... }'`. It works on macOS zsh, but can fail on Linux servers with older zsh versions or compatibility-mode startup.

### String Handling
- **No single quotes** in function body code
- Use double quotes `"` for all strings
- Escape double quotes with backslash: `\"`
- Escape single quotes in words: `couldn"t` instead of `couldn't`
- Example: `echo \"Hello, World!\"` instead of `echo 'Hello, World!'`

### Variable Usage
- **Local variables only** - no global variables
- Use `local` keyword for all variables
- Naming convention: `lowercase_with_underscores`
- Avoid reserved words: `path`, `file`, `dir`, `temp`, `status`, `result`
- Example: `local config_file="/path/to/config"`

### Temporary Files and Directories
- **Always use `mktemp`** for creating temporary files and directories
- Use `mktemp` for files: `local temp_file=$(mktemp)`
- Use `mktemp -d` for directories: `local temp_dir=$(mktemp -d)`
- Clean up temporary files in trap handlers: `trap 'rm -f "$temp_file"' EXIT`
- Example with proper cleanup:
```bash
local temp_file=$(mktemp)
trap 'rm -f "$temp_file"' EXIT

# Use temporary file
echo "data" > "$temp_file"
process_file "$temp_file"

# Cleanup happens automatically on exit
```

### Error Handling
- Check command exit status (`$?`) immediately after execution
- Provide clear, informative error messages
- Output errors to stderr (`>&2`)
- Include error type, location, and troubleshooting suggestions
- Validate all input parameters

### Parameter Design
- Use positional parameters (`$1`, `$2`, ...) as primary input
- Support optional flags with both short and long forms: `-f`, `--format`
- Always use named parameters for optional values: `--format jpg`, `-f jpg`
- Validate all parameters for type, format, and range
- Provide sensible defaults for optional parameters

## Code Structure

### Function Template
```bash
_category_aliases_function_name() {
    # Usage information
    echo -e "Function description.\nUsage:\n function_name <required_param> [--option value] [--flag]"

    # Parameter validation
    if [ $# -eq 0 ]; then
        echo "Error: Missing required parameter" >&2
        return 1
    fi

    local param="$1"
    local option_value=""
    local flag_enabled=false

    # Parse named parameters
    while [ $# -gt 0 ]; do
        case "$1" in
            --option)
                option_value="$2"
                shift 2
                ;;
            -o|--flag)
                flag_enabled=true
                shift
                ;;
            *)
                # Handle positional parameter or unknown option
                if [ -z "$param" ]; then
                    param="$1"
                else
                    echo "Error: Unknown parameter: $1" >&2
                    return 1
                fi
                shift
                ;;
        esac
    done

    # Main logic
    if ! some_command "$param"; then
        echo "Error: Command failed for parameter: $param" >&2
        return 1
    fi
}

alias function-name='_category_aliases_function_name'
```

### Usage Information Format
- Use `echo -e` for functions with parameters
- Use simple `echo` for basic functions
- Format: `<parameter_name:default_value>` for optional parameters
- Use `--option value` format for named parameters
- Include examples for complex functions

**Examples:**
```bash
# Simple function
echo "Show system information."

# Function with parameters
echo -e "Create a file with specified size.\nUsage:\n function_name <size_in_MB:100> [--directory path]"

# Complex function with examples
echo -e "Remove background from an image.\nUsage:\nbria-bg-remove <image_path_or_url> [--output path] [--format jpg|png]"
echo -e "Examples:\n bria-bg-remove photo.jpg\n -> Creates photo_background_remove.jpg"
echo -e " bria-bg-remove photo.png --format png --output output.png"
```

### Naming Conventions

#### Alias Names
- Use lowercase letters only
- Use hyphens to separate words: `get-user-info`, `process-data`
- No numbers unless meaningful: `get-1st-user`
- Avoid conflicts with system commands
- Use descriptive names: `mkd` instead of `md`
- Check for conflicts with `type alias_name` or `command -v alias_name`

#### Function Parameters
- Use lowercase letters only
- Avoid special characters
- Keep names concise but descriptive

#### Helper Functions
- Prefix with underscore: `_helper_function`
- Include filename suffix: `_filesystem_helper` for filesystem_aliases.zsh
- Extract common logic to improve maintainability

## Cross-Platform Compatibility

### Shell Compatibility
- Prioritize Bash compatibility
- Avoid Bashisms unless explicitly required
- Test on both Linux and macOS (Darwin)
- Use portable shell constructs

### Platform-Specific Considerations
- macOS uses BSD commands (different from GNU)
- Handle path differences appropriately
- Consider package manager differences (Homebrew vs apt)

## File Organization

### File Structure
```bash
# Description: Brief description of file purpose
# File: category_aliases.zsh

# Section 1: Basic Functions
# -------------------------

_category_aliases_basic_function() {
  # Basic function logic
}

alias basic-function='_category_aliases_basic_function' # Description

# Section 2: Advanced Functions
# -----------------------------

_category_aliases_advanced_function() {
  # Advanced function logic
}

alias advanced-function='_category_aliases_advanced_function' # Description

# Helper Functions
# ----------------

_helper_function() {
    # Helper logic
}
```

### Grouping Guidelines
- Group related functions together
- Use section headers with `#` symbols
- Add separators between sections
- Include comments explaining complex logic
- Add help functions for complex files

### Documentation Comments
- File description at top: `# Description: ...`
- Function descriptions on same line or next line
- Use English for all comments and documentation
- Include examples for complex functions

## Environment Variables and Configuration

### Environment Variables
- Use descriptive names: `BRIA_API_KEY`, `CONFIG_PATH`
- Provide default values when possible
- Document required variables in usage information
- Avoid conflicting with system variables

### Configuration Files
- Use standard paths: `~/.config/tool_name/config`
- Document configuration file format
- Provide fallback values for missing configurations
- Handle configuration file creation if needed

## Code Quality

### Error Handling Examples
```bash
# Good error handling
if [ ! -f "$file_path" ]; then
    echo "Error: File not found: $file_path" >&2
    echo "Please check the file path and try again." >&2
    return 1
fi

# Command execution with error checking
if ! some_command "$param"; then
    echo "Error: Failed to process $param" >&2
    echo "Check input and try again." >&2
    return 1
fi
```

### Code Style
- Use consistent indentation (2 spaces)
- Add comments for complex logic
- Keep functions focused on single responsibility
- Avoid deeply nested conditional logic
- Use early returns for error conditions

### Parameter Parsing Examples
```bash
# Good: Named parameters with short and long options
_image_aliases_convert_image() {
    echo -e "Convert image to different format.\nUsage:\n convert-image <input_file> [--format jpg|png|webp] [--quality 1-100] [--output path]"

    if [ $# -eq 0 ]; then
        echo "Error: Missing input file" >&2
        return 1
    fi

    local input_file="$1"
    local format="jpg"
    local quality="90"
    local output_file=""

    # Parse named parameters
    while [ $# -gt 1 ]; do
        case "$2" in
            --format|-f)
                format="$3"
                shift 2
                ;;
            --quality|-q)
                quality="$3"
                shift 2
                ;;
            --output|-o)
                output_file="$3"
                shift 2
                ;;
            *)
                echo "Error: Unknown option: $2" >&2
                return 1
                ;;
        esac
    done

    # Validate format
    case "$format" in
        jpg|png|webp) ;;
        *)
            echo "Error: Invalid format: $format. Use jpg, png, or webp" >&2
            return 1
            ;;
    esac
}

alias convert-image='_image_aliases_convert_image'
```

### Batch Image Processing Example
```bash
# Good: Single command supports file and directory workflows
_image_aliases_img_autocrop() {
    echo -e "Automatically trim white or transparent borders from a file or directory of images.\nUsage:\n img-autocrop <image_or_dir> [--mode auto|white|transparent] [--types jpg,png,webp] [--format png] [--output path] [--recursive]"

    if [ $# -eq 0 ]; then
        echo "Error: Image or directory path is required." >&2
        return 1
    fi

    local source_path="$1"
    local trim_mode="auto"
    local types_value="jpg,jpeg,png,gif,bmp,webp,heic,tif,tiff"
    local output_format=""
    local output_path=""
    local recursive=false

    while [ $# -gt 1 ]; do
        case "$2" in
            -m|--mode)
                trim_mode="$3"
                shift 2
                ;;
            -t|--types)
                types_value="$3"
                shift 2
                ;;
            -F|--format)
                output_format="$3"
                shift 2
                ;;
            -o|--output)
                output_path="$3"
                shift 2
                ;;
            -r|--recursive)
                recursive=true
                shift
                ;;
            *)
                echo "Error: Unknown option: $2" >&2
                return 1
                ;;
        esac
    done

    # Keep file and directory handling in one entrypoint, but validate each option clearly.
}

alias img-autocrop='_image_aliases_img_autocrop'
```

This pattern is recommended for image aliases that need to support both single-file execution and batch directory processing with filters such as `--types`, `--format`, and `--recursive`.

### Temporary File Management Examples
```bash
# Good: Temporary file with proper cleanup
_filesystem_aliases_process_large_file() {
    echo -e "Process large file safely with temporary storage.\nUsage:\n process-large-file <input_file> [--output path]"

    if [ $# -eq 0 ]; then
        echo "Error: Missing input file" >&2
        return 1
    fi

    local input_file="$1"
    local output_file="${2:-processed_output.txt}"
    local temp_file=$(mktemp)
    local temp_dir=$(mktemp -d)

    # Set up cleanup trap
    trap 'rm -f "$temp_file"; rm -rf "$temp_dir"' EXIT

    # Use temporary files for processing
    if ! process_data "$input_file" > "$temp_file"; then
        echo "Error: Failed to process input file" >&2
        return 1
    fi

    # Additional processing in temp directory
    if ! final_process "$temp_file" "$temp_dir/intermediate"; then
        echo "Error: Failed in final processing" >&2
        return 1
    fi

    # Move final result to output location
    mv "$temp_dir/intermediate" "$output_file"
}

alias process-large-file='_filesystem_aliases_process_large_file'
```

## Current Alias Files

The project contains the following alias files:

```
shells/oh-my-zsh/custom/aliases/
├── adb_aliases.zsh              # Android Debug Bridge aliases
├── archive_aliases.zsh          # File compression and extraction
├── audio_aliases.zsh            # Audio processing tools
├── base_aliases.zsh             # Basic shell aliases
├── brew_aliases.zsh             # Homebrew package manager
├── bria_aliases.zsh             # Bria API image processing
├── directory_aliases.zsh        # Directory navigation and management
├── docker_aliases.zsh           # Docker container management
├── docker_app_aliases.zsh       # Docker application aliases
├── filesystem_aliases.zsh       # File system operations
├── git_aliases.zsh              # Git version control
├── help_aliases.zsh             # Help and documentation
├── image_aliases.zsh            # Image processing tools
├── minio_aliases.zsh             # Minio object storage
├── network_aliases.zsh          # Network tools and utilities
├── notification_aliases.zsh     # System notifications
├── other_aliases.zsh            # Miscellaneous aliases
├── pdf_aliases.zsh              # PDF processing and watermarking tools
├── security_aliases.zsh         # Defensive external server security checks
├── srv_aliases.zsh              # Server management
├── ssh_aliases.zsh               # SSH connection management
├── ssh_server_aliases.zsh       # SSH server configuration
├── system_aliases.zsh           # System administration
├── tcpdump_aliases.zsh          # Network packet analysis
├── url_aliases.zsh              # URL handling and processing
├── video_aliases.zsh            # Video processing tools
├── vps_aliases.zsh              # Virtual Private Server management
├── web_aliases.zsh              # Web development tools
├── environment_aliases.zsh     # Environment variable management
└── zsh_config_aliases.zsh      # Zsh configuration management
```

### PDF aliases notes

`pdf_aliases.zsh` includes `pdf-wm` for text or image watermarks. It requires `python3` and the `PyMuPDF` Python package for real processing. Keep `--dry-run` side-effect free, preserve transparent image alpha channels, and guard overwrite flows against duplicate output targets in batch runs. Non-ASCII text should render with a CJK-capable font by default, while `--font` can override the font. Shell examples should use straight ASCII quotes because mixed smart and ASCII quotes can leave the shell waiting for a closing quote.

`pdf-from` converts Office and LibreOffice-compatible files to PDF through LibreOffice. `office-to-pdf` is an alias of `pdf-from`, and `pdf-from-batch` uses the same conversion behavior for batch workflows. It requires `soffice` or `libreoffice` in `PATH`.

Default `pdf-from` formats: `doc docx docm xls xlsx xlsm ppt pptx pptm odt ods odp rtf txt csv`.

Common `pdf-from` options: `--formats/-f`, `--output-dir/-o`, `--recursive/-r`, `--overwrite`, and `--dry-run`. Directory inputs are scanned non-recursively by default; use `--recursive` for nested files. Without `--output-dir`, PDFs are written next to each source file. Without `--overwrite`, duplicate or existing output paths are made unique.

`pdf-from-images` combines ordered image files into a single PDF for scan-like workflows. `pdf-scan` is an alias of `pdf-from-images`. It requires ImageMagick through `magick` or `convert` in `PATH`.

Common `pdf-from-images` options: `--output/-o`, `--page-size/-p`, `--page-mode`, `--pattern/-f`, `--recursive/-r`, and `--overwrite`. It accepts explicit image files, a directory of images, or a directory plus `--pattern` such as `合同_*.jpg`. Directory inputs are sorted before PDF generation so names like `合同_0001.jpg` through `合同_0007.jpg` stay in page order. Default `--page-mode` is `auto`, which keeps each image close to its original page size and reduces white margins. Use `--page-mode fit -p A4` only when you need a fixed paper size.

### Security aliases notes

`security_aliases.zsh` provides defensive external checks for systems the user owns or is authorized to test:

- `sec-reverse-ip <ipv4>` queries a passive reverse IP provider and verifies current A records. The default provider is HackerTarget; override it with an HTTPS `SECURITY_REVERSE_IP_URL`.
- `sec-port-scan <target> --authorized` runs a TCP connect scan with `T3`, open-port output, reasons, and a default five-minute host timeout. The default is the top 1000 TCP ports. Use `--ports`, `--top-ports`, `--full`, or explicit `--service` detection as needed.
- `sec-dns-check <target> --authorized` tests UDP/TCP DNS, a reserved `.invalid` name, Fake-IP ranges, and the CHAOS version response.
- `sec-tls-check <domain>` checks the certificate, OCSP stapling, TLS 1.2, and TLS 1.3. Use `--ip` to force a specific address while preserving SNI.
- `sec-http-check <domain>` checks the HTTP root response, HTTPS verification, and common security headers. Use `--ip` to test a specific virtual-host address.
- `sec-server-scan <target> --authorized` combines ownership, reverse IP, TCP, DNS, TLS, and HTTP checks. Add `--domain` when scanning an IP that hosts an SNI virtual host.
- `security-help` prints the complete command overview.

Required tools vary by command: `curl`, `dig`, `nmap`, and `openssl`; `whois` is optional in the combined scan. `DOTFILES_SECURITY_SCAN_ACK=1` can replace repeated `--authorized` flags for routine approved targets. The checks do not exploit vulnerabilities and do not inspect system patches, accounts, application code, cloud security groups, or authenticated routes.

## Testing and Validation

### Syntax Testing
```bash
# Test syntax
bash -n alias_file.zsh
zsh -n alias_file.zsh

# Test individual functions
source alias_file.zsh
function_name --help  # Should show usage
```

### Functionality Testing
- Test on both Linux and macOS
- Verify error handling works correctly
- Check parameter validation
- Test edge cases and boundary conditions
- Ensure no conflicts with existing commands

## Best Practices Summary

1. **Use wrapper functions**: `_category_aliases_command_name() { ... }` plus `alias command-name='_category_aliases_command_name'`
2. **No single quotes in function body**
3. **Use local variables exclusively**
4. **Always use `mktemp` for temporary files and directories**
5. **Include comprehensive error handling**
6. **Provide clear usage information**
7. **Use named parameters: `--format jpg`, `-f jpg`**
8. **Follow naming conventions consistently**
9. **Test cross-platform compatibility**
10. **Document thoroughly**
11. **Extract common logic to helper functions**
12. **Avoid conflicts with system commands**
13. **Clean up temporary resources with trap handlers**

## Integration with Development Workflow

This guide is automatically applied when working with files matching the pattern `shells/oh-my-zsh/custom/aliases/*.zsh`. The Cursor IDE integration ensures these standards are followed during development.

For additional information about the project structure and development workflow, refer to the main [CLAUDE.md](../CLAUDE.md) file.
