CLI Reference

Ava CMS includes a command-line interface for managing your site. Run commands from your project root (the folder with ava in it):

./ava <command> [options]

The CLI has been thoughtfully designed for a simple and delightful experience. Most output includes helpful tips and next steps.

Beginner’s Guide to the Terminal

“CLI” just means typing commands instead of clicking buttons. It’s a superpower for servers and automation, but you only need a tiny slice of it to be productive with Ava CMS.

What is “the project root”?

It’s the folder that contains your Ava CMS project — where you can see composer.json, content/, app/, and the ava script.

Tip: If you type ./ava status and it works, you're in the right folder.

A tiny CLI cheat-sheet (you’ll use these a lot)

Command What it does
pwd Show your current folder (Linux/macOS). Short for "print working directory".
ls List files in the current folder (Linux/macOS). Short for "list".
cd folder-name Move into a folder. Short for "change directory".
cd .. Go up one folder.
php -v Show your PHP version.
Windows note: In PowerShell, the equivalents are Get-Location (like pwd) and dir (like ls). cd works everywhere.

Running Commands on a Server

To run Ava CMS commands on your live site, you'll need to connect via SSH. See the Hosting Guide for a complete walkthrough of SSH setup, clients, and connecting to your server.

Getting Help

Run ./ava or ./ava --help to see all available commands:

./ava --help

Shortcuts: Several commands have convenient aliases:

  • ./ava cachecache:stats
  • ./ava logslogs:stats
  • ./ava useruser:list
  • ./ava updateupdate:check
  • ./ava stress:benchmarkbenchmark
   ▄▄▄  ▄▄ ▄▄  ▄▄▄     ▄▄▄▄ ▄▄   ▄▄  ▄▄▄▄
  ██▀██ ██▄██ ██▀██   ██▀▀▀ ██▀▄▀██ ███▄▄
  ██▀██  ▀█▀  ██▀██   ▀████ ██   ██ ▄▄██▀   v1.1.0

  ─── Usage ─────────────────────────────────────────────

    ./ava <command> [options]

  ─── Site Management ───────────────────────────────────

    status                        Show site health and overview
    rebuild [--keep-webcache]     Rebuild the content index
    lint                          Validate all content files

  ─── Content ───────────────────────────────────────────

    make <type> "Title"           Create new content
    prefix <add|remove> [type]    Toggle date prefixes

  ─── Webpage Cache ─────────────────────────────────────

    cache:stats (or cache)        View cache statistics
    cache:clear [pattern]         Clear cached webpages

  ─── Logs ──────────────────────────────────────────────

    logs:stats (or logs)          View log file statistics
    logs:tail [name] [-n N]       Show last N lines of a log
    logs:clear [name]             Clear log files

  ─── Users ─────────────────────────────────────────────

    user:add <email> <pass>       Create admin user
    user:password <email> <pass>  Update password
    user:remove <email>           Remove user
    user:list (or user)           List all users

  ─── Updates ───────────────────────────────────────────

    update:check (or update)      Check for updates
    update:apply                  Apply available update
    update:stale                  Detect stale files from older releases

  ─── Testing ───────────────────────────────────────────

    test [filter]                 Run the test suite
    stress:generate <type> <n>    Generate test content
    stress:clean <type>           Remove test content
    stress:benchmark              Benchmark index backends

  ─── Plugins ───────────────────────────────────────────

    sitemap:stats                 Show sitemap statistics
    feed:stats                    Show RSS feed statistics
    redirects:list                List all redirects
    redirects:add                 Add a redirect
    redirects:remove              Remove a redirect

  ─── Examples ──────────────────────────────────────────

    ./ava status
    ./ava make post "Hello World"
    ./ava lint

version

Show the current Ava CMS version:

./ava --version
# or
./ava -v
# or
./ava version
   ▄▄▄  ▄▄ ▄▄  ▄▄▄     ▄▄▄▄ ▄▄   ▄▄  ▄▄▄▄
  ██▀██ ██▄██ ██▀██   ██▀▀▀ ██▀▄▀██ ███▄▄
  ██▀██  ▀█▀  ██▀██   ▀████ ██   ██ ▄▄██▀   v1.1.0
Why do commands start with ./?

Why do commands start with ./?

./ava means “run the ava script in this folder.” The ./ tells your computer to look for the command right here, not somewhere else on your system. This is common for project tools in PHP, Node, Python, and more. If you just type ava, it only works if you’ve installed it globally (which is not recommended for project scripts).

Site Management

status

Shows a quick overview of your site's health:

./ava status
   ▄▄▄  ▄▄ ▄▄  ▄▄▄     ▄▄▄▄ ▄▄   ▄▄  ▄▄▄▄
  ██▀██ ██▄██ ██▀██   ██▀▀▀ ██▀▄▀██ ███▄▄
  ██▀██  ▀█▀  ██▀██   ▀████ ██   ██ ▄▄██▀   v1.1.0

  ─── Site ──────────────────────────────────────────────

  Name:       My Site
  URL:        https://example.com

  ─── Environment ───────────────────────────────────────

  PHP:        8.3.29
  Extensions: igbinary, opcache

  ─── Content Index ─────────────────────────────────────

  Status:     ● Fresh
  Mode:       auto
  Backend:    Sqlite (auto-detected)
  Cache:      SQLite 892 KB
  Built:      2024-12-28 14:30:00

  ─── Content ───────────────────────────────────────────

  ◆ Page: 5 published
  ◆ Post: 38 published (4 drafts)

  ─── Taxonomies ────────────────────────────────────────

  ◆ Category: 8 terms
  ◆ Tag: 23 terms

  ─── Webpage Cache ────────────────────────────────────────

  Status:     ● Enabled
  TTL:        Forever (until cleared)
  Cached:     42 webpages
  Size:       1.2 MB

rebuild

Rebuild the content index:

./ava rebuild

# Preserve existing webpage cache while rebuilding the index
./ava rebuild --keep-webpage-cache   # alias: --keep-webcache
   Rebuilding content index (23ms)

  ✓ Content index rebuilt!

Use this after deploying new content in production, or if something looks stuck.

What it does:

  • Loads plugins first so rebuild hooks can run
  • Rebuilds the content index ($app->indexer()->rebuild())
  • If content_index.prerender_html is enabled: writes storage/cache/html_cache.bin (otherwise deletes it)
  • Clears the webpage cache at the end (so pages regenerate on the next request), unless the --keep-webpage-cache / --keep-webcache flag is supplied to preserve cached pages during the rebuild

Alternative invocation (if the ./ava script isn’t executable): php ava rebuild.

lint

Validate all content files for common problems:

./ava lint
  🔍 Validating content files...

  ╭────────────────────────────────╮
  │  All content files are valid!  │
  │  No issues found.              │
  ╰────────────────────────────────╯

If there are issues, you'll see them listed with links to documentation:

  🔍 Validating content files...

  ✗ Found 2 issue(s):

     posts/my-post.md: Invalid status "archived" — see https://ava.addy.zone/docs/content#status
     pages/about.md: Missing required field "slug" — see https://ava.addy.zone/docs/content#frontmatter

  💡 Tip: Fix the issues above and run lint again

Checks for:

Check What it means
YAML syntax Frontmatter must parse correctly
Required fields title, slug, status are present
Status values Must be draft, published, or unlisted
Slug format Lowercase, alphanumeric, hyphens only
Duplicate slugs Within the same content type
Duplicate IDs Across all content

Content Creation

make

Create new content with proper scaffolding:

./ava make <type> "Title"

Examples:

./ava make page "About Us"
./ava make post "Hello World"
  ╭───────────────────────────╮
  │  Created new post!        │
  ╰───────────────────────────╯

  File:       content/posts/hello-world.md
  ID:         01JGHK8M3Q4R5S6T7U8V9WXYZ
  Slug:       hello-world
  Status:     draft

  💡 Tip: Edit your content, then set status: published when ready

Run without arguments to see available types:

./ava make
   Usage: ./ava make <type> "Title"

  Available types:

    ▸ page — Pages
    ▸ post — Posts

  Example:
    ./ava make post "My New Post"

prefix

Toggle date prefixes on content filenames:

./ava prefix <add|remove> [type]

Examples:

./ava prefix add post
  Adding date prefixes...

     hello-world.md  2024-12-28-hello-world.md
     another-post.md  2024-11-15-another-post.md

   Renamed 2 file(s)

   ./ava rebuild — Update the content index

This reads the date field from frontmatter.

User Management

Manage admin dashboard users. Users are stored in app/config/users.php.

user:add

Create a new admin user:

./ava user:add [email protected] secretpass "Admin User"
  ╭─────────────────────────────────╮
  │  User created successfully!     │
  ╰─────────────────────────────────╯

  Email:      [email protected]
  Name:       Admin User

   /admin — Login at your admin dashboard

Password Security: Your password is hashed using bcrypt before being stored in app/config/users.php. This means:

  • Your actual password is never saved—only an irreversible hash
  • Even if someone accesses the users file, they can't recover your password
  • Each password has a unique salt, so identical passwords have different hashes

user:password

Update an existing user's password:

./ava user:password [email protected] newpassword
   Password updated for: [email protected]

user:remove

Remove a user:

./ava user:remove [email protected]
   User removed: [email protected]

user:list

List all configured users:

./ava user:list
  ─── Users ─────────────────────────────────────────────

    [email protected]
      Name: Admin User
      Created: 2024-12-28

    [email protected]
      Name: Editor
      Created: 2024-12-15

Updates

update

Check for available updates (alias for update:check):

./ava update

Results are cached for 1 hour. Force a fresh check:

./ava update --force
  🔍 Checking for updates...

  Current:    1.1.0
  Latest:     1.1.1

  ╭───────────────────────╮
  │  Update available!    │
  ╰───────────────────────╯

  Release:    v1.1.1
  Published:  2024-12-28

  ─── Changelog ──────────────────────────────────────────

  - Fixed page cache invalidation
  - Improved CLI output formatting
  - Added progress bars for bulk operations

   ./ava update:apply — Download and apply the update

update:apply

Download and apply the latest update:

./ava update:apply
  ─── Update Available ───────────────────────────────────

  From:       1.1.0
  To:         1.1.1

  Will be updated:
     Core files (core/, bin/, bootstrap.php)
     Default theme (app/themes/default/)
     Bundled plugins (sitemap, feed, redirects)
     Documentation (docs/)

  Will NOT be modified:
     Your content (content/)
     Your configuration (app/)
     Custom themes and plugins
     Storage and cache files

  ⚠️  Have you backed up your site and have a secure copy saved off-site?
  [y/N]: y

  Continue with update? [y/N]: y

   Downloading update (342ms)

  ✓ Update applied successfully!

   Rebuilding content index (18ms)
  ✓ Done!

Skip confirmation with -y or --yes:

./ava update:apply -y

Developer Mode: Update from the latest commit on the main branch instead of a release (for testing unreleased features):

./ava update --dev
# or
./ava update:apply --dev
  ─── Dev Update ──────────────────────────────────────────

  ⚠️  Forcing update from latest commit on main branch
      This may include unstable or untested changes.
      Version checks are bypassed in dev mode.

  From:       1.0.0
  To:         main (latest commit)
Caution: Dev mode updates may contain untested or breaking changes. Only use this for testing or if you need a specific fix before the next release.

See Updates for details on what gets updated and preserved.

update:stale

Detect leftover files from older Ava CMS releases that are no longer needed:

./ava update:stale
   Scanning for stale files (1.2s)

  Compared to: v1.1.0

  ╭──────────────────────────╮
  │  No stale files found    │
  ╰──────────────────────────╯

If stale files are detected:

   Scanning for stale files (1.2s)

  Compared to: v1.1.0

  ╭──────────────────────────────────╮
  │  Found 3 stale file(s)          │
  ╰──────────────────────────────────╯

   core/OldClass.php
   core/Deprecated/Helper.php
   app/plugins/feed/old-template.php

  💡 Tip: Review before deleting any files

This command compares your local files against the latest release to identify files that were removed in newer versions. Use --dev to compare against the latest main branch commit instead of a release.

Note: This command cannot run if you use custom paths (non-default app, content, or storage locations). Review stale files carefully before deleting—some may be intentional customizations.

Webpage Cache

Commands for managing the on-demand HTML webpage cache. This cache stores rendered webpages for all URLs on your site—not just the "Page" content type—including posts, archives, taxonomy pages, and custom content types.

cache:stats

View webpage cache statistics:

./ava cache:stats
  ─── Webpage Cache ─────────────────────────────────────

  Status:     ● Enabled
  TTL:        Forever (until cleared)

  Cached:     42 webpages
  Size:       1.2 MB
  Oldest:     2024-12-28 10:00:00
  Newest:     2024-12-28 14:30:00

cache:clear

Clear cached webpages:

# Clear all cached webpages (with confirmation)
./ava cache:clear
  Found 42 cached webpage(s).

  Clear all cached webpages? [y/N]: y

   Cleared 42 cached webpage(s)
# Clear webpages matching a URL pattern
./ava cache:clear /blog/*
   Cleared 15 webpage(s) matching: /blog/*

The webpage cache is also automatically cleared when:

  • You run ./ava rebuild
  • Content changes (in content_index.mode = 'auto')

See Performance for details.

Logs

Commands for managing log files in storage/logs/. Ava CMS automatically rotates log files when they exceed the configured size limit to prevent disk space issues.

logs:stats

View log file statistics:

./ava logs:stats
  ─── Logs ───────────────────────────────────────────────

  indexer.log:  245.3 KB (2 files) · 1,847 lines
  admin.log:    12.1 KB · 89 lines

  Total:        257.4 KB (3 files)

  Max Size:     10 MB per log
  Max Files:    3 rotated copies

logs:tail

Show the last lines of a log file:

# Show last 20 lines of indexer.log (default)
./ava logs:tail

# Show last 20 lines of a specific log
./ava logs:tail indexer.log

# Show last 50 lines
./ava logs:tail indexer -n 50

# Can also use -nN format
./ava logs:tail admin -n10
  ─── indexer.log (last 20 lines) ─────────────────────

  [2024-12-28T14:30:00+00:00] Indexer errors:
    - Missing required field "slug" in posts/draft-post.md
    - Invalid date format in posts/old-post.md

  [2024-12-28T15:45:00+00:00] Indexer errors:
    - Duplicate ID found: posts/copy-of-post.md

Available logs:

Log File Purpose
indexer.log Content indexer errors and warnings
admin.log Admin dashboard activity (logins, edits)
error.log PHP errors and exceptions

logs:clear

Clear log files:

# Clear all logs (with confirmation)
./ava logs:clear
  Found 3 log file(s) (257.4 KB).

  Clear all log files? [y/N]: y

   Cleared 3 log file(s) (257.4 KB)
# Clear a specific log (and its rotated copies)
./ava logs:clear indexer.log
   Cleared 2 log file(s) (245.3 KB)

Log Rotation

Ava CMS automatically rotates log files to prevent them from growing too large. Configure rotation in app/config/ava.php:

'logs' => [
    'max_size' => 10 * 1024 * 1024,  // 10 MB (default)
    'max_files' => 3,                 // Keep 3 rotated copies
],

When a log exceeds max_size, it's rotated:

  • indexer.logindexer.log.1
  • indexer.log.1indexer.log.2 (etc.)
  • Oldest files beyond max_files are deleted

See Configuration - Logs for details.

Testing

test

Run the automated test suite:

./ava test
  Ava CMS Test Suite
  ──────────────────────────────────────────────────

  StrTest

     slug converts to lowercase
     slug replaces spaces with separator
     starts with returns true for match
    ...

  ──────────────────────────────────────────────────
  Tests: 456 passed (95ms)

Options:

Option Description
[filter] Filter tests by class name (e.g., Str, Parser)
-q, --quiet Minimal output (useful for CI/CD)
-v, --verbose Verbose output with more details
--release Run release readiness checks

Examples:

# Run all tests
./ava test

# Filter tests by class name
./ava test Str           # Run StrTest only
./ava test Parser        # Run ParserTest only
./ava test Request       # Run RequestTest only

# Quiet mode (useful for CI/CD)
./ava test --quiet
./ava test -q

# Release checks
./ava test --release

Quiet mode output:

  Ava CMS Test Suite
  ──────────────────────────────────────────────────
  Tests: 456 passed (95ms)

Failed test output:

  Ava CMS Test Suite
  ──────────────────────────────────────────────────
  Tests: 455 passed, 1 failed (100ms)

  Failures:

  1) Ava\Tests\Core\ExampleTest::testSomething
     Expected true, got false
     at /path/to/core/Testing/TestCase.php:371

Release mode (--release) runs all standard tests plus additional checks that verify the project is ready for release — including configuration defaults, gitignore rules, version numbers, and documentation. See Releasing for details.

See Testing for details on writing tests and available assertions.

Benchmarking

benchmark

Test the performance of your content index:

./ava benchmark
# or
./ava stress:benchmark
   ▄▄▄  ▄▄ ▄▄  ▄▄▄     ▄▄▄▄ ▄▄   ▄▄  ▄▄▄▄
  ██▀██ ██▄██ ██▀██   ██▀▀▀ ██▀▄▀██ ███▄▄
  ██▀██  ▀█▀  ██▀██   ▀████ ██   ██ ▄▄██▀   v1.1.0

  ─── Performance Benchmark ───────────────────────────────

  Content:    1,003 items
              page: 2
              post: 1001

  Backend:    array + igbinary
  igbinary:   enabled
  Iterations: 5

  Testing array + igbinary...

  ─── Results ──────────────────────────────────────────────

  Test                array + igbinary
  ──────────────────────────────────────
  Count               2.2ms
  Get by slug         3.5ms
  Recent (page 1)     0.14ms
  Archive (page 50, beyond recent cache)   7.4ms
  Sort by date        9.7ms
  Sort by title       10.5ms
  Search              7.3ms
  ──────────────────────────────────────
  Build index         45ms
  Memory              124 KB
  Cache size          592.2 KB

  ─── Webpage Rendering ─────────────────────────────────

  Operation                     Time
  ─────────────────────────────────────────────
  Render post (uncached)        4.9ms
  Cache write                   0.12ms
  Cache read (HIT)              0.02ms

  💡 Tip: Run with --compare to test all backends.
  📚 Docs: https://ava.addy.zone/docs/performance

Options:

Option Description
--compare Compare all available backends side-by-side
--iterations=N Number of test iterations (default: 5)

What it tests:

Content Index:

  • Build index — Time to rebuild the content index
  • Count — Counting all posts
  • Get by slug — Fetching a single post by URL
  • Recent (page 1) — Homepage/recent posts (uses fast cache)
  • Archive (page 50, beyond recent cache) — Deep pagination (loads full index)
  • Sort by date — Sorting all posts by date
  • Sort by title — Sorting all posts by title
  • Search — Full-text search across content

Webpage Rendering:

  • Render post (uncached) — Full render pipeline (load item, markdown, template)
  • Cache write — Time to write rendered HTML to disk
  • Cache read (HIT) — Time to serve a cached page

Typical workflow:

# Generate test content at your target scale
./ava stress:generate post 10000

# Run benchmark on current backend
./ava benchmark

# Compare all backends (rebuilds for each)
./ava benchmark --compare

# Clean up when done
./ava stress:clean post

See Performance for detailed benchmark results and backend recommendations.

Stress Testing

Commands for testing performance with large amounts of content.

stress:generate

Generate dummy content for stress testing:

./ava stress:generate post 100
  🧪 Generating 100 dummy post(s)...

  [████████████████████████████████] 100% Creating posts...

   Generated 100 files in 245ms

   Rebuilding content index (89ms)

   ./ava stress:clean post — Remove generated content when done

Generated content includes:

  • Random lorem ipsum titles and content
  • Random dates (within last 2 years for dated types)
  • Random taxonomy terms from configured taxonomies
  • 80% published, 20% draft status
  • Files prefixed with _dummy- for easy identification

stress:clean

Remove all generated test content:

./ava stress:clean post
  Found 100 dummy content file(s).

  Delete all? [y/N]: y

  [████████████████████████████████] 100% Deleting files...

   Deleted 100 file(s)

   Rebuilding content index (12ms)
  ✓ Done!

Plugin Commands

Enabled plugins can register their own CLI commands. When you run ./ava --help, plugin commands appear in the Plugins section.

The bundled plugins provide these commands:

Command Plugin Description
sitemap:stats sitemap Show sitemap statistics
feed:stats feed Show RSS feed statistics
redirects:list redirects List all configured redirects
redirects:add <from> <to> [code] redirects Add a redirect
redirects:remove <from> redirects Remove a redirect

For detailed documentation and examples of each plugin command, see the Bundled Plugins reference.

Creating Plugin Commands

Plugins can register CLI commands by including a commands key in their plugin.php. See Creating Plugins for details.

return [
    'name' => 'My Plugin',
    'commands' => [
        [
            'name' => 'myplugin:status',
            'description' => 'Show plugin status',
            'handler' => function ($args, $cli, $app) {
                $cli->info("Plugin is running!");
                return 0; // Exit code
            },
        ],
    ],
];

Exit Codes

Code Meaning
0 Success
1 Error (invalid arguments, validation failures, etc.)

Quick Reference

Core Commands

Command Description
--help (or -h, help) Show all available commands
--version (or -v, version) Show Ava CMS version
status Show site overview and health
rebuild Rebuild the content index
lint Validate content files

Content Commands

Command Description
make <type> "Title" Create new content
prefix <add|remove> [type] Toggle date prefixes on filenames

User Management

Command Description
user:add <email> <pass> [name] Create admin user
user:password <email> <pass> Update user password
user:remove <email> Remove admin user
user:list (or user) List all users

Updates

Command Description
update:check [--force] (or update) Check for updates
update:apply [-y] [--dev] Apply available update
update:stale [--dev] Detect stale files from older releases

Webpage Cache

Command Description
cache:stats (or cache) Webpage cache statistics
cache:clear [pattern] Clear webpage cache

Logs

Command Description
logs:stats (or logs) Log file statistics
logs:tail [name] [-n N] Show last lines of a log
logs:clear [name] Clear log files

Testing & Benchmarking

Command Description
test [filter] [-q] [--release] Run the test suite
benchmark [--compare] [--iterations=N] Test content index performance
stress:generate <type> <count> Generate test content
stress:clean <type> Remove test content
stress:benchmark Alias for benchmark

Plugin Commands

Enabled plugins can add their own CLI commands. See Bundled Plugins for full documentation.

Command Plugin Description
sitemap:stats sitemap Show sitemap statistics
feed:stats feed Show RSS feed statistics
redirects:list redirects List all redirects
redirects:add <from> <to> [code] redirects Add a redirect
redirects:remove <from> redirects Remove a redirect

Colour Theme

The CLI uses a configurable colour theme for the banner, section headers, and highlights. Set your preferred theme in app/config/ava.php:

'cli' => [
    'theme' => 'cyan',  // cyan, pink, purple, green, blue, amber, disabled
],

Use disabled for CI/CD pipelines or terminals that don't support ANSI colours.

Common Workflows

Initial Setup

# Create your first admin user
./ava user:add [email protected] secretpassword "Admin"

# Check site status
./ava status

# Validate all content
./ava lint

Development

# Start dev server
php -S localhost:8000 -t public

# Content index rebuilds automatically when files change
# (when content_index.mode is 'auto')

# Create new content
./ava make page "About Us"
./ava make post "Hello World"

# Check for issues
./ava lint

Production Deploy

# In production, set content_index.mode to 'never' in config
# Then rebuild after deploying new content:
./ava rebuild

# Clear webpage cache if needed
./ava cache:clear

Content Validation

# Before committing content changes:
./ava lint

# Check site health
./ava status

# If errors found, fix and re-run

Performance Testing

# Generate test content at your target scale
./ava stress:generate post 1000

# Run benchmark
./ava benchmark

# Compare all backends
./ava benchmark --compare

# Clean up when done
./ava stress:clean post

User Management

# Add a new user
./ava user:add [email protected] password123 "Editor"

# Change a password
./ava user:password [email protected] newpassword

# List all users
./ava user

# Remove a user
./ava user:remove [email protected]

Updating Ava CMS

# Check for updates
./ava update

# Force a fresh check (bypass cache)
./ava update --force

# Apply update (with confirmation)
./ava update:apply

# Apply update without prompts (for scripts)
./ava update:apply -y

Troubleshooting

# Check site health
./ava status

# View recent errors
./ava logs:tail indexer -n 50

# View all log stats
./ava logs

# Clear caches and rebuild
./ava cache:clear
./ava rebuild

# After updating, check for stale files
./ava update:stale