← Back to Home

CLI Reference

Complete command-line interface guide

Global Options

clay [options] [command]

Options:
  -V, --version     Output the version number
  -v, --verbose     Enable verbose output
  -h, --help        Display help information

Commands

init

Initialize a Clay project or generator

clay init [type] [name]

Initialize a project:

clay init

Creates a .clay file in the current directory.

Initialize a generator:

clay init generator my-generator

Creates a new generator in clay/generators/my-generator/

init-claude

Set up Claude Code hooks to prevent editing Clay-generated files

clay init-claude

Creates .claude/settings.json with a PreToolUse hook that calls clay check-generated before any Edit/Write operation. No scripts are generated — Clay handles the check entirely.

Safe to run multiple times — merges into existing settings without overwriting.

check-generated

Check if a file is Clay-generated (used internally by hooks)

echo '{"file_path": "/path/to/file.ts"}' | clay check-generated

Reads JSON from stdin, checks the .clay manifest, and exits with code 2 if the file is generated (blocking the edit). Exits 0 otherwise. This command is called automatically by the Claude Code hook — you don't need to run it manually.

init-mcp

Add the Clay MCP server to your AI platform's MCP configuration

clay init-mcp

Interactively asks which AI platforms you use, with auto-detection of platforms already present in your project (e.g. .vscode/, .claude/, .cursor/).

Supported platforms:

Merges into existing config files without overwriting other servers. Safe to run multiple times.

generate

Generate code from your model and reconcile the output tree

clay generate <model_path> <output_path>
clay generate  # Uses .clay file

Examples:

# Explicit paths
clay generate ./clay/model.json ./src

# Using .clay file (recommended)
clay generate

# Verbose output
clay generate -v

After a successful run, Clay mark-and-sweeps obsolete non-touch files for each model that actually generated: paths still listed in that model’s .clay generated_files but not produced again (including hash-skipped outputs) are dropped from the index and, when no other model entry claims them, deleted from disk.

clean

Full wipe of tracked generated files (not needed for ordinary model shrink)

clay clean <model_path> <output_path>
clay clean  # Uses .clay file

Examples:

# Explicit paths
clay clean ./clay/model.json ./src

# Using .clay file
clay clean

Use clean for full wipes, renaming/moving an output directory, or starting over. For removing entities or dropping obsolete outputs after a model change, prefer edit model → clay generate.

⚠️ Warning: The clean command permanently deletes all tracked generated files for the model(s). Make sure you've committed any manual changes to version control first!

watch

Watch for model changes and regenerate automatically

clay watch <model_path> <output_path>
clay watch  # Uses .clay file

Examples:

# Watch the clay directory
clay watch ./clay/model.json ./src

# Using .clay file
clay watch

Clay will monitor the model directory and regenerate when files change.

test-path

Test JSONPath expressions against your model

clay test-path <model_path> <json_path>

Examples:

# Get all types
clay test-path ./clay/model.json "$.model.types[*]"

# Get all fields
clay test-path ./clay/model.json "$.model.types[*].fields[*]"

# Filter by property
clay test-path ./clay/model.json "$.model.types[?(@.isActive)]"

# Get array-type fields
clay test-path ./clay/model.json "$.model.types[*].fields[?(@.type=='array')]"

The .clay File

The .clay file is the ownership ledger for generated (non-touch) files. It's created with clay init.

Structure (per model entry):

{
  "models": [
    {
      "path": "clay/model.json",
      "output": ".",
      "generated_files": {
        "src/models/user.model.js": { "md5": "...", "date": "..." },
        "src/models/order.model.js": { "md5": "...", "date": "..." }
      },
      "input_hash": "..."
    }
  ]
}

Benefits:

Workflow Examples

Starting a New Project

# 1. Create project directory
mkdir my-project && cd my-project

# 2. Initialize Clay
clay init

# 3. Create model directory
mkdir -p clay

# 4. Create your model
cat > clay/model.json << 'EOF'
{
  "name": "my-app",
  "generators": ["./generators/api"],
  "model": {...}
}
EOF

# 5. Generate code
clay generate

Development Workflow

# Terminal 1: Watch for changes
clay watch

# Terminal 2: Edit model and templates
vim clay/model.json
vim clay/generators/api/templates/model.js

# Files regenerate automatically!

Testing JSONPath

# Test a selector before using in generator
clay test-path ./clay/model.json "$.model.types[*]"

# Verify filtered results
clay test-path ./clay/model.json "$.model.types[?(@.isActive)]"

# Check nested paths
clay test-path ./clay/model.json "$.model.types[*].commands[*].parameters[*]"

Cleaning Up

# Remove all generated files
clay clean

# Regenerate from scratch
clay generate

Environment Variables

Clay respects these environment variables:

Exit Codes

Code Meaning
0 Success
1 General error (invalid args, file not found, etc.)
2 Template or generator error

Git Integration

Clay includes two git features that improve the experience of committing generated code. Both are configured during clay init.

Collapsed Diffs (gitattributes)

When enabled (clay config gitattributes true), Clay marks all generated files with linguist-generated=true in .gitattributes. This causes GitHub to collapse their diffs in pull requests, keeping PRs focused on the model and template changes rather than the generated output.

# Managed by Clay — do not edit between markers
# clay:generated:start
src/models/User.ts linguist-generated=true
src/models/Order.ts linguist-generated=true
src/controllers/UserController.ts linguist-generated=true
# clay:generated:end

The managed block is updated automatically on each clay generate run. Files outside the markers are left untouched.

Auto-Merge (.clay conflicts)

When enabled (clay config automerge true), Clay registers a custom git merge driver that automatically resolves .clay file conflicts. This prevents the most common merge conflict in Clay projects — two branches that generated different files.

The merge strategy:

# Enable both features
clay config gitattributes true
clay config automerge true

# Or during init (both enabled by default)
clay init --yes

Configuration

# Toggle features
clay config gitattributes true   # Enable collapsed diffs
clay config gitattributes false  # Disable collapsed diffs
clay config automerge true       # Enable auto-merge driver
clay config automerge false      # Disable auto-merge driver

Tips & Tricks

💡 Pro Tip: Create shell aliases for common commands:
alias cg="clay generate"
alias cw="clay watch"
alias cc="clay clean"