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.
./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. |
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 cache→cache:stats./ava logs→logs:stats./ava user→user:list./ava update→update:check./ava stress:benchmark→benchmark
▄▄▄ ▄▄ ▄▄ ▄▄▄ ▄▄▄▄ ▄▄ ▄▄ ▄▄▄▄ ██▀██ ██▄██ ██▀██ ██▀▀▀ ██▀▄▀██ ███▄▄ ██▀██ ▀█▀ ██▀██ ▀████ ██ ██ ▄▄██▀ 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_htmlis enabled: writesstorage/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-webcacheflag 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)
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.
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.log→indexer.log.1indexer.log.1→indexer.log.2(etc.)- Oldest files beyond
max_filesare 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