PHPackages                             trk/processwire-console - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [CLI &amp; Console](/categories/cli)
4. /
5. trk/processwire-console

ActiveLibrary[CLI &amp; Console](/categories/cli)

trk/processwire-console
=======================

A professional CLI tool for ProcessWire CMS.

0.1.0(1mo ago)2191MITPHPPHP &gt;=8.2CI passing

Since Apr 8Pushed 1mo agoCompare

[ Source](https://github.com/trk/processwire-console)[ Packagist](https://packagist.org/packages/trk/processwire-console)[ Patreon](https://www.patreon.com/ukyo)[ RSS](/packages/trk-processwire-console/feed)WikiDiscussions main Synced 2w ago

READMEChangelog (10)Dependencies (3)Versions (10)Used By (1)

 **ProcessWire Console**
 `vendor/bin/wire`

 A professional CLI for [ProcessWire CMS/CMF](https://processwire.com).
 57 production-ready commands · JSON output for AI agents · Composer-driven extensibility

 [![PHP 8.3+](https://camo.githubusercontent.com/38027453aeb7eb818641c9de8f82b7624c3558d92634f1946edc715c3ddf8956/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f5048502d382e332532422d3737374242343f6c6f676f3d706870266c6f676f436f6c6f723d7768697465)](https://camo.githubusercontent.com/38027453aeb7eb818641c9de8f82b7624c3558d92634f1946edc715c3ddf8956/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f5048502d382e332532422d3737374242343f6c6f676f3d706870266c6f676f436f6c6f723d7768697465) [![ProcessWire 3.x](https://camo.githubusercontent.com/36bd0e6eecb80b2d4b3222c60abeedca654fab8ab85974917bafe858d5ed0583/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f50726f63657373576972652d332e782d3231393646333f6c6f676f3d646174613a696d6167652f7376672b786d6c3b6261736536342c50484e325a79423462577875637a30696148523063446f764c336433647935334d793576636d63764d6a41774d43397a646d636949485a705a58644362336739496a41674d4341794e4341794e43492b5043397a646d632b)](https://camo.githubusercontent.com/36bd0e6eecb80b2d4b3222c60abeedca654fab8ab85974917bafe858d5ed0583/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f50726f63657373576972652d332e782d3231393646333f6c6f676f3d646174613a696d6167652f7376672b786d6c3b6261736536342c50484e325a79423462577875637a30696148523063446f764c336433647935334d793576636d63764d6a41774d43397a646d636949485a705a58644362336739496a41674d4341794e4341794e43492b5043397a646d632b) [![Symfony Console 7.x](https://camo.githubusercontent.com/f3a950d00c431b17981c7c3995e1ec0a2d99ac097b36176f25f634df08c667f4/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f53796d666f6e795f436f6e736f6c652d372e782d3030303030303f6c6f676f3d73796d666f6e79)](https://camo.githubusercontent.com/f3a950d00c431b17981c7c3995e1ec0a2d99ac097b36176f25f634df08c667f4/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f53796d666f6e795f436f6e736f6c652d372e782d3030303030303f6c6f676f3d73796d666f6e79) [![MIT License](https://camo.githubusercontent.com/5caa455d8debc46fb23abbadb45a733a937f3910a73fc875c2f7820468e1bb54/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f4c6963656e73652d4d49542d677265656e)](https://camo.githubusercontent.com/5caa455d8debc46fb23abbadb45a733a937f3910a73fc875c2f7820468e1bb54/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f4c6963656e73652d4d49542d677265656e)

---

Table of Contents
-----------------

[](#table-of-contents)

- [Why ProcessWire Console?](#why-processwire-console)
- [Installation](#installation)
- [Shell Alias (Recommended)](#shell-alias-recommended)
- [Quick Start](#quick-start)
- [Command Reference](#command-reference)
    - [Pages](#pages)
    - [Fields](#fields)
    - [Templates](#templates)
    - [Modules](#modules)
    - [Users &amp; RBAC](#users--rbac)
    - [Cache](#cache)
    - [Logs](#logs)
    - [Database &amp; Backup](#database--backup)
    - [Scaffolding](#scaffolding)
    - [Migrations](#migrations)
    - [Queues](#queues)
    - [Database Seeding](#database-seeding)
    - [Testing](#testing)
    - [Task Scheduling](#task-scheduling)
    - [Maintenance Mode](#maintenance-mode)
    - [Tinker (REPL)](#tinker-repl)
- [JSON Output (Machine-Readable)](#json-output-machine-readable)
- [Interactive Mode](#interactive-mode)
- [Extending the Console](#extending-the-console)
- [Security](#security)
- [Architecture](#architecture)
- [Requirements](#requirements)
- [License](#license)

---

Why ProcessWire Console?
------------------------

[](#why-processwire-console)

ProcessWire is a powerful CMF but lacks a first-party CLI. This package fills that gap with **57 production-ready commands** purpose-built for ProcessWire's architecture:

DomainCommandsDescriptionContent (Pages)8 commandsCreate, update, publish, move, trash, restoreSchema (Fields)7 commandsList, info, create, update, rename, attach, detachSchema (Templates)6 commandsList, info, create, update, rename, reorder fieldsModules5 commandsList, install, uninstall, refresh, upgradeUsers &amp; RBAC11 commandsUsers, roles, permissions managementCache &amp; Logs7 commandsClear caches, list/read/tail/clear log filesDatabase4 commandsBackup, restore, list backups, purge old backupsScaffolding5 commandsGenerate modules, migrations, queues, seeders, schedulesMigrations8 commandsRun, rollback, reset, refresh, fresh, statusQueues5 commandsWork, failed, retry, clear, initialize tablesSeeding1 commandPopulate the database with test dataScheduling1 commandRun due scheduled tasksMaintenance2 commandsPut the application up or downRuntime2 commandsInteractive REPL, command listingTesting2 commandsRun tests, scaffold test files**Total****73 commands**Every command supports `--json` for machine-readable output, `--dry-run` for safe previews, and `--force` for non-interactive scripting.

---

Installation
------------

[](#installation)

```
composer require trk/processwire-console
```

A `wire` symlink is created at your project root automatically. If it isn't, run:

```
php vendor/bin/wire list
```

### Verify Installation

[](#verify-installation)

```
php vendor/bin/wire list
```

If the database is not configured, the CLI will still start and display command help. Full functionality requires a working ProcessWire installation with database access.

---

Shell Alias (Recommended)
-------------------------

[](#shell-alias-recommended)

Typing `php vendor/bin/wire` every time is tedious. Set up a shell alias to use just `wire`:

### macOS / Linux (Bash/Zsh)

[](#macos--linux-bashzsh)

Add this line to your shell config file (`~/.zshrc`, `~/.bashrc`, or `~/.bash_profile`):

```
# Add ProcessWire Console alias
echo 'alias wire="php vendor/bin/wire"' >> ~/.zshrc && source ~/.zshrc
```

> For Bash users, replace `~/.zshrc` with `~/.bashrc`.

### Windows (PowerShell)

[](#windows-powershell)

Run in PowerShell to add a persistent alias:

```
# Create profile if it doesn't exist, then add alias
if (!(Test-Path $PROFILE)) { New-Item -Path $PROFILE -Force }
Add-Content $PROFILE 'function wire { php vendor/bin/wire @args }'
. $PROFILE
```

### Windows (CMD)

[](#windows-cmd)

Create a `wire.bat` file in a directory that's in your PATH:

```
@echo off
php vendor/bin/wire %*
```

### After Setup

[](#after-setup)

Now you can use `wire` directly:

```
# Before
php vendor/bin/wire page:list --template=basic-page

# After ✨
wire page:list --template=basic-page
wire user:create -i
wire migrate:status
```

---

Quick Start
-----------

[](#quick-start)

```
# List all available commands
php vendor/bin/wire list

# Get detailed help for any command
php vendor/bin/wire help page:create

# Create a page
php vendor/bin/wire page:create --parent=/ --template=basic-page --title="Hello World"

# List pages as JSON
php vendor/bin/wire page:list --template=basic-page --json

# Create a user with roles
php vendor/bin/wire user:create

# Backup the database
php vendor/bin/wire db:backup

# Interactive REPL
php vendor/bin/wire tinker

# Start Queue Worker
php vendor/bin/wire queue:work
```

---

Command Reference
-----------------

[](#command-reference)

### Pages

[](#pages)

Manage the ProcessWire page tree — create, update, publish, move, trash, and restore pages.

#### `page:list`

[](#pagelist)

List pages with filtering, sorting, and pagination.

```
# List the 20 most recent pages
php vendor/bin/wire page:list

# Filter by template and parent
php vendor/bin/wire page:list --template=blog-post --parent=/blog/ --limit=50

# Sort by title ascending
php vendor/bin/wire page:list --sort=title --limit=10

# Include hidden and unpublished pages
php vendor/bin/wire page:list --include=all

# JSON output for scripting
php vendor/bin/wire page:list --template=product --json
```

**Options:**

OptionShortDescription`--template``-t`Filter by template name`--parent``-p`Filter by parent path or ID`--sort``-s`Sort field (default: `-created`). Prefix with `-` for descending`--limit``-l`Number of results (default: `20`)`--include``-i`Include scope: `all`, `hidden`, `unpublished` (default: `all`)`--json`Output as JSON---

#### `page:find`

[](#pagefind)

Find pages using a raw ProcessWire selector string.

```
php vendor/bin/wire page:find "template=blog-post, title%=ProcessWire, limit=10"

# JSON output
php vendor/bin/wire page:find "parent=/products/, sort=-created, limit=5" --json
```

**Options:**

OptionDescription`selector`Argument: ProcessWire selector string (required)`--json`Output as JSON---

#### `page:create`

[](#pagecreate)

Create a new page under a parent with a specific template.

```
# Basic creation
php vendor/bin/wire page:create --parent=/ --template=basic-page --title="About Us"

# Create as unpublished
php vendor/bin/wire page:create --parent=/blog/ --template=blog-post --title="Draft Post" --unpublished

# Fully interactive mode — prompts for template, parent, title, and all fields
php vendor/bin/wire page:create -i

# Preview without saving
php vendor/bin/wire page:create --parent=/ --template=basic-page --title="Test" --dry-run
```

**Options:**

OptionShortDescription`--parent``-p`Parent page path or ID (required)`--template``-t`Template name (required)`--title`Page title`--name`URL-safe name (auto-generated from title if omitted)`--unpublished`Create as unpublished`--interactive``-i`Prompt for all values including template field filling`--dry-run`Preview changes without saving`--json`Output as JSON---

#### `page:update`

[](#pageupdate)

Update page properties and field values.

```
# Update title
php vendor/bin/wire page:update --id=1042 --title="New Title"

# Set arbitrary fields with --set
php vendor/bin/wire page:update --id=1042 --set="summary=Updated summary" --set="body=New body content"

# Change page status
php vendor/bin/wire page:update --id=1042 --status=hidden

# Move and rename
php vendor/bin/wire page:update --id=1042 --parent=/another-parent/ --name=new-url-name

# Preview changes
php vendor/bin/wire page:update --id=1042 --title="Preview" --dry-run
```

**Options:**

OptionDescription`--id`Page ID (required; or use `--path`)`--path`Page path (alternative to `--id`)`--title`New title`--name`New URL-safe name`--parent`New parent path or ID`--template`Change template`--status`Status: `published`, `unpublished`, `hidden`, `locked``--set`Set field value as `key=value` (repeatable)`--dry-run`Preview without saving`--json`Output as JSON---

#### `page:publish` / `page:unpublish`

[](#pagepublish--pageunpublish)

```
php vendor/bin/wire page:publish --id=1042
php vendor/bin/wire page:unpublish --id=1042

# Skip confirmation
php vendor/bin/wire page:publish --id=1042 --force
```

#### `page:trash` / `page:restore`

[](#pagetrash--pagerestore)

```
php vendor/bin/wire page:trash --id=1042
php vendor/bin/wire page:restore --id=1042

# Force without confirmation
php vendor/bin/wire page:trash --id=1042 --force
```

#### `page:move`

[](#pagemove)

```
php vendor/bin/wire page:move --id=1042 --parent=/new-section/
php vendor/bin/wire page:move --id=1042 --parent=1001 --dry-run
```

---

### Fields

[](#fields)

Full lifecycle management for ProcessWire fields.

#### `field:list`

[](#fieldlist)

```
# List all fields
php vendor/bin/wire field:list

# Filter by type
php vendor/bin/wire field:list --type=FieldtypeText

# Search by name or label
php vendor/bin/wire field:list --search=body

# JSON output
php vendor/bin/wire field:list --json
```

#### `field:info`

[](#fieldinfo)

```
php vendor/bin/wire field:info --name=body
php vendor/bin/wire field:info --name=body --json
```

#### `field:update`

[](#fieldupdate)

```
# Update label and description
php vendor/bin/wire field:update --name=body --set="label=Body Text" --set="description=Main content area"

# Change field settings
php vendor/bin/wire field:update --name=summary --set="maxlength=500" --set="required=1"
```

#### `field:rename`

[](#fieldrename)

```
php vendor/bin/wire field:rename --name=old_field_name --new-name=new_field_name
php vendor/bin/wire field:rename --name=body --new-name=content --dry-run
```

#### `field:attach` / `field:detach`

[](#fieldattach--fielddetach)

```
# Attach a field to a template
php vendor/bin/wire field:attach --template=blog-post --field=images

# Attach after a specific field
php vendor/bin/wire field:attach --template=blog-post --field=tags --after=body

# Detach a field from a template
php vendor/bin/wire field:detach --template=blog-post --field=sidebar
```

#### `field:delete`

[](#fielddelete)

```
php vendor/bin/wire field:delete --name=unused_field
php vendor/bin/wire field:delete --name=unused_field --force
```

---

### Templates

[](#templates)

#### `template:list`

[](#templatelist)

```
php vendor/bin/wire template:list
php vendor/bin/wire template:list --search=blog --json
```

#### `template:info`

[](#templateinfo)

```
php vendor/bin/wire template:info --name=basic-page
php vendor/bin/wire template:info --name=basic-page --json
```

#### `template:update`

[](#templateupdate)

```
php vendor/bin/wire template:update --name=blog-post --set="label=Blog Article"
php vendor/bin/wire template:update --name=blog-post --set="noChildren=1" --set="noParents=-1"
```

#### `template:rename`

[](#templaterename)

```
php vendor/bin/wire template:rename --name=old-template --new-name=new-template
```

#### `template:fields:reorder`

[](#templatefieldsreorder)

```
# Reorder fields within a template
php vendor/bin/wire template:fields:reorder --template=blog-post --fields="title,body,images,tags,summary"
```

#### `template:delete`

[](#templatedelete)

```
php vendor/bin/wire template:delete --name=unused-template
php vendor/bin/wire template:delete --name=unused-template --force
```

---

### Modules

[](#modules)

A complete module lifecycle manager — discover, install, enable, disable, upgrade.

#### `module:list`

[](#modulelist)

```
# List all installed modules
php vendor/bin/wire module:list

# Core modules only
php vendor/bin/wire module:list --core

# Site (third-party) modules only
php vendor/bin/wire module:list --site

# Search
php vendor/bin/wire module:list --search=Image

# JSON output
php vendor/bin/wire module:list --site --json
```

#### `module:install` / `module:uninstall`

[](#moduleinstall--moduleuninstall)

```
php vendor/bin/wire module:install --name=ModuleName
php vendor/bin/wire module:uninstall --name=ModuleName --force
```

#### `module:refresh`

[](#modulerefresh)

```
# Refresh all module caches
php vendor/bin/wire module:refresh

# Refresh a specific module
php vendor/bin/wire module:refresh --name=ModuleName
```

#### `module:upgrade`

[](#moduleupgrade)

```
php vendor/bin/wire module:upgrade --name=ModuleName
```

---

### Users &amp; RBAC

[](#users--rbac)

Complete role-based access control management from the command line.

#### Users

[](#users)

```
# List all users
php vendor/bin/wire user:list
php vendor/bin/wire user:list --role=editor --json

# Create a user (interactive prompts for password, email, roles)
php vendor/bin/wire user:create

# Create a user non-interactively
php vendor/bin/wire user:create --name=john --email=john@example.com --password=SecretPass --role=editor --force

# Update a user
php vendor/bin/wire user:update --name=john --email=new@example.com
php vendor/bin/wire user:update --name=john --add-role=admin --remove-role=guest

# Delete a user
php vendor/bin/wire user:delete --name=john
php vendor/bin/wire user:delete --id=1045 --force
```

#### Roles

[](#roles)

```
# List roles
php vendor/bin/wire role:list
php vendor/bin/wire role:list --json

# Create a role
php vendor/bin/wire role:create --name=editor --title="Content Editor"

# Grant a permission to a role
php vendor/bin/wire role:grant --role=editor --permission=page-edit

# Revoke a permission from a role
php vendor/bin/wire role:revoke --role=editor --permission=page-delete
```

#### Permissions

[](#permissions)

```
# List permissions
php vendor/bin/wire permission:list

# Create a custom permission
php vendor/bin/wire permission:create --name=my-custom-permission

# Delete a custom permission
php vendor/bin/wire permission:delete --name=my-custom-permission
```

---

### Cache

[](#cache)

#### `cache:clear`

[](#cacheclear)

Clears compiled files, session caches, and file caches.

```
php vendor/bin/wire cache:clear
php vendor/bin/wire cache:clear --json
```

#### `cache:wire:clear`

[](#cachewireclear)

Clear WireCache entries by exact key or SQL LIKE pattern.

```
# Clear a specific cache key
php vendor/bin/wire cache:wire:clear --key=MyModule.someData

# Clear all cache entries matching a pattern
php vendor/bin/wire cache:wire:clear --pattern="Template%"
php vendor/bin/wire cache:wire:clear --pattern="MyModule.%" --json
```

---

### Logs

[](#logs)

#### `log:list`

[](#loglist)

List all available log files.

```
php vendor/bin/wire log:list
php vendor/bin/wire log:list --json
```

#### `log:read`

[](#logread)

Retrieve and display ProcessWire logs as a formatted table.

```
# Read 'errors' log
php vendor/bin/wire log:read errors

# Read with a specific date range
php vendor/bin/wire log:read messages --from="2026-04-01" --to="today"

# Limit output and filter by string
php vendor/bin/wire log:read errors --limit=50 --find="Exception"

# JSON output
php vendor/bin/wire log:read errors --json
```

#### `log:tail`

[](#logtail)

Read the last N lines of a log file and follow output.

```
# Read errors.txt (last 200 lines by default)
php vendor/bin/wire log:tail errors

# Read fewer lines
php vendor/bin/wire log:tail exceptions --lines=20

# Follow output (like tail -f)
php vendor/bin/wire log:tail messages --follow

# JSON output
php vendor/bin/wire log:tail errors --json
```

#### `log:clear`

[](#logclear)

Clear a specific log file.

```
php vendor/bin/wire log:clear errors
php vendor/bin/wire log:clear exceptions --force
```

#### `log:clear-all`

[](#logclear-all)

Clear all ProcessWire log files.

```
php vendor/bin/wire log:clear-all
php vendor/bin/wire log:clear-all --force
```

---

### Database &amp; Backup

[](#database--backup)

#### `db:backup`

[](#dbbackup)

Create a database backup using ProcessWire's native `WireDatabaseBackup`.

```
php vendor/bin/wire db:backup
php vendor/bin/wire db:backup --json
```

#### `db:restore`

[](#dbrestore)

Restore the database from a backup file.

```
php vendor/bin/wire db:restore --file=backup-2026-04-08.sql
php vendor/bin/wire db:restore --file=backup-2026-04-08.sql --force
```

> **Warning:** This operation replaces your entire database. Always back up before restoring.

#### `backup:list`

[](#backuplist)

```
php vendor/bin/wire backup:list
php vendor/bin/wire backup:list --json
```

#### `backup:purge`

[](#backuppurge)

Remove old backup files, keeping only the most recent N backups.

```
# Keep the 5 most recent backups
php vendor/bin/wire backup:purge --keep=5
php vendor/bin/wire backup:purge --keep=3 --force
```

---

### Scaffolding

[](#scaffolding)

#### `make:module`

[](#makemodule)

Scaffold a new ProcessWire module from a professional stub.

```
# Standard module
php vendor/bin/wire make:module HelloWorld

# Fieldtype module
php vendor/bin/wire make:module FieldtypeColor --type=fieldtype

# Inputfield module
php vendor/bin/wire make:module InputfieldColor --type=inputfield

# Process (admin page) module
php vendor/bin/wire make:module ProcessDashboard --type=process

# With custom metadata
php vendor/bin/wire make:module MyModule \
  --type=module \
  --title="My Custom Module" \
  --summary="Does amazing things" \
  --author="Developer Name" \
  --mod-version=0.1.0 \
  --autoload
```

**Module types and stubs:**

TypeBase ClassUse Case`module``WireData`General-purpose module with init/ready hooks`fieldtype``Fieldtype`Custom database field storage`inputfield``Inputfield`Custom form input widget`process``Process`Admin page with URL routing#### `make:migration`

[](#makemigration)

Scaffold a new timestamped migration file. See [Migrations](#migrations) for full documentation.

```
php vendor/bin/wire make:migration create_blog_section
php vendor/bin/wire make:migration add_body_field --type=create-field --field=body
```

---

### Migrations

[](#migrations)

A complete migration system for ProcessWire — schema versioning with up/down methods, batch tracking, rollback support, and 7 typed stubs for common PW operations.

Migrations live in `site/migrations/` and are tracked in the `wire_migrations` database table (auto-created on first run).

#### `make:migration`

[](#makemigration-1)

Generate a new timestamped migration file from a stub.

```
# Blank migration
php vendor/bin/wire make:migration create_blog_section

# Create a field
php vendor/bin/wire make:migration add_subtitle_field --type=create-field --field=subtitle --fieldtype=FieldtypeText

# Create a template
php vendor/bin/wire make:migration create_blog_template --type=create-template --template=blog-post --label="Blog Post"

# Attach field to template
php vendor/bin/wire make:migration attach_images_to_blog --type=attach-field --template=blog-post --field=images

# Create a page
php vendor/bin/wire make:migration create_about_page --type=create-page --template=basic-page --parent=/ --label="About Us"

# Create a role with permissions
php vendor/bin/wire make:migration create_editor_role --type=create-role --label="Content Editor"

# Install a module
php vendor/bin/wire make:migration install_seo_module --type=install-module --module=SeoMaestro
```

**Stub types:**

`--type`Generatesup()down()`blank`Empty skeleton (default)——`create-field`Field creation`new Field()` + savedelete field`create-template`Template + fieldgroup + fileFull scaffolddelete template + file`attach-field`Field-to-template attachmentfieldgroup addfieldgroup remove`create-page`Page creation`new Page()` + savedelete page`create-role`Role + permission grantsroles add + grantdelete role`install-module`Module install`modules->install()`uninstall#### Dependency Order (Critical)

[](#dependency-order-critical)

ProcessWire objects have strict dependency chains. **Migrations must respect this order:**

```
CREATE order:  Field → Fieldgroup → Template → Page
DELETE order:  Page → Template → Fieldgroup → Field

```

For a typical blog setup, the **correct migration sequence** is:

```
# 1. Create fields first
php vendor/bin/wire make:migration create_body_field     --type=create-field --field=body
php vendor/bin/wire make:migration create_summary_field  --type=create-field --field=summary

# 2. Create template (depends on fields existing)
php vendor/bin/wire make:migration create_blog_template  --type=create-template --template=blog-post

# 3. Attach fields to template
php vendor/bin/wire make:migration attach_body_to_blog   --type=attach-field --template=blog-post --field=body
php vendor/bin/wire make:migration attach_summary_to_blog --type=attach-field --template=blog-post --field=summary

# 4. Create pages last (depends on template existing)
php vendor/bin/wire make:migration create_blog_page      --type=create-page --template=blog-post --parent=/
```

**On rollback**, these run in **reverse order** (last-in-first-out) — pages deleted before templates, fields detached before being deleted.

#### Safe-by-Default Guards

[](#safe-by-default-guards)

All stubs include **precondition guards** in `down()` that throw clear errors instead of cascading destructive operations:

StubGuardError`create-field`Field attached to template(s)?`"Cannot delete — detach first"``create-template`Pages using this template?`"Cannot delete — remove pages first"``attach-field`Pages have data in this field?`"Cannot detach — data would be lost"``create-page`Page has children?`"Cannot delete — remove children first"``create-role`Users assigned this role?`"Cannot delete — remove from users first"``install-module`Other modules depend on it?`"Cannot uninstall — dependencies exist"`### make:queue

[](#makequeue)

Generate a new file-based Queue class in ProcessWire Console.

```
php vendor/bin/wire make:queue SendEmailQueue

# Save directly to a specific module instead of the global site/queue directory
php vendor/bin/wire make:queue CompileImagesQueue --module=FieldtypeAiAssistant
```

**Options:**

OptionShortDescription`name`Class name ending with Queue (required)`--module``-m`Placed inside site/modules/YourModule/queue/> **Design philosophy:** Stubs never auto-delete user content or cascade-remove dependencies. They fail loudly so you can write the correct cleanup migration yourself.

Each migration file returns an anonymous class with `up()` and `down()` methods:

```
