원클릭으로
add-cli-command
Register a WP-CLI command in a plugin using a command class, following Dekode conventions.
Codex 또는 Claude로 설치 이 Prompt를 복사해 Codex, Claude 또는 다른 어시스턴트에 붙여 넣으면 Skill 페이지를 검토하고 설치를 진행할 수 있습니다.
메뉴
Register a WP-CLI command in a plugin using a command class, following Dekode conventions.
Codex 또는 Claude로 설치 이 Prompt를 복사해 Codex, Claude 또는 다른 어시스턴트에 붙여 넣으면 Skill 페이지를 검토하고 설치를 진행할 수 있습니다.
SOC 직업 분류 기준
Add a WordPress AJAX handler to a plugin, with nonce verification, input sanitisation, and JSON response.
Register a block pattern in a theme or plugin, using the WordPress 6.0+ file-based pattern system.
Add a new Gutenberg block to an existing plugin or theme.
Add a WordPress action or filter hook to a plugin or theme.
Scaffold a new must-use plugin in packages/mu-plugins/ - either a simple utility or a service-class integration.
Register a custom post type (and optionally a taxonomy) in a theme or plugin, following Dekode conventions.
| name | add-cli-command |
| description | Register a WP-CLI command in a plugin using a command class, following Dekode conventions. |
Register a WP-CLI command in an existing plugin. Covers command class structure, subcommand pattern, argument handling, and gating so the class is never loaded on web requests.
| Input | Required | Notes |
|---|---|---|
| Plugin | Yes | Which plugin in packages/plugins/ |
| Command name | Yes | Top-level command, e.g. dekode-sync. Registered as wp {command-name} |
| Subcommands | Yes | List of subcommands and what each does, e.g. run, status, reset |
| Arguments / flags | No | Positional args or --flag options each subcommand accepts |
| Namespace | Yes | Check the target package — e.g. Dekodeinteraktiv\Plugin\<PascalSlug>\Cli |
If any required inputs are missing, ask for them before writing any code.
Create src/Cli/<CommandName>Command.php in the target plugin.
<?php
/**
* WP-CLI: {Command Name} commands.
*
* @package {PhpNamespace}
*/
declare( strict_types=1 );
namespace {PhpNamespace}\Cli;
/**
* Manages {description of what the command does}.
*
* ## EXAMPLES
*
* wp {command-name} run
* wp {command-name} status --format=json
*/
class <CommandName>Command {
/**
* Run the synchronisation.
*
* ## OPTIONS
*
* [--dry-run]
* : Preview changes without applying them.
*
* ## EXAMPLES
*
* wp {command-name} run
* wp {command-name} run --dry-run
*
* @param array<int, string> $args Positional arguments.
* @param array<string, string> $assoc_args Named arguments and flags.
*/
public function run( array $args, array $assoc_args ): void {
$dry_run = (bool) ( $assoc_args['dry-run'] ?? false );
\WP_CLI::log( 'Starting sync...' );
// ... perform work ...
if ( $dry_run ) {
\WP_CLI::success( 'Dry run complete — no changes applied.' );
return;
}
\WP_CLI::success( 'Sync complete.' );
}
/**
* Show the current sync status.
*
* ## OPTIONS
*
* [--format=<format>]
* : Output format. Options: table, json, csv. Default: table.
* ---
* default: table
* options:
* - table
* - json
* - csv
* ---
*
* ## EXAMPLES
*
* wp {command-name} status
* wp {command-name} status --format=json
*
* @param array<int, string> $args Positional arguments.
* @param array<string, string> $assoc_args Named arguments and flags.
*/
public function status( array $args, array $assoc_args ): void {
$format = $assoc_args['format'] ?? 'table';
$items = [
[ 'key' => 'last_run', 'value' => \get_option( '{plugin-slug}_last_run', 'never' ) ],
[ 'key' => 'status', 'value' => \get_option( '{plugin-slug}_status', 'idle' ) ],
];
\WP_CLI\Utils\format_items( $format, $items, [ 'key', 'value' ] );
}
}
hooks()Gate the registration so the command class is never loaded on web requests:
public function hooks(): void {
if ( defined( 'WP_CLI' ) && \WP_CLI ) {
add_action( 'after_setup_theme', [ $this, 'register_cli_commands' ] );
}
}
public function register_cli_commands(): void {
\WP_CLI::add_command( '{command-name}', new \{PhpNamespace}\Cli\<CommandName>Command() );
}
Use after_setup_theme rather than init — WP-CLI typically loads before init fires for some operations, and after_setup_theme ensures WordPress is sufficiently bootstrapped.
Use the appropriate WP_CLI method for each output type — never echo or var_dump:
| Method | When to use |
|---|---|
WP_CLI::log( $msg ) | Informational progress messages |
WP_CLI::success( $msg ) | Final success message (green) |
WP_CLI::warning( $msg ) | Non-fatal issue (yellow) |
WP_CLI::error( $msg ) | Fatal error — halts execution (red) |
WP_CLI::error( $msg, false ) | Non-fatal error — continues execution |
WP_CLI\Utils\format_items() | Tabular data with --format support |
WP_CLI\Utils\make_progress_bar() | Progress bar for long-running loops |
composer lint
composer lint-fix # if needed
composer lint # re-run to confirm clean
defined( 'WP_CLI' ) && WP_CLI: the command class and its dependencies must not be instantiated on web requestsdekode-sync, not just sync) to avoid conflicts with Core and other plugins## OPTIONS / ## EXAMPLES: WP-CLI parses these docblocks to generate wp help {command-name} {subcommand} output — always include them--format flag for data output: any command that outputs a list of items should support --format=table,json,csv via WP_CLI\Utils\format_items()--dry-run flag for destructive operations: any command that writes, deletes, or modifies data should support a --dry-run flagWP_CLI::error() exits with code 1; WP_CLI::success() exits with 0 — do not call exit() directlyA src/Cli/<CommandName>Command.php class with documented subcommands, registered via hooks() behind a WP_CLI gate. Each subcommand is callable as wp {command-name} {subcommand} and outputs correctly formatted results. Lint passes clean.