@@ -19,14 +19,57 @@ class Shell_Command extends WP_CLI_Command {
1919 * : Force the use of WP-CLI's built-in PHP REPL, even if the Boris or
2020 * PsySH PHP REPLs are available.
2121 *
22+ * [--hook=<hook>]
23+ * : Ensure that a specific WordPress action hook has fired before starting the shell.
24+ * This validates that the preconditions associated with that hook are met.
25+ * Only hooks that have already been triggered can be used (e.g., init, plugins_loaded, wp_loaded).
26+ * ---
27+ * default: ''
28+ * ---
29+ *
2230 * ## EXAMPLES
2331 *
2432 * # Call get_bloginfo() to get the name of the site.
2533 * $ wp shell
2634 * wp> get_bloginfo( 'name' );
2735 * => string(6) "WP-CLI"
36+ *
37+ * # Start a shell, ensuring the 'init' hook has already fired.
38+ * $ wp shell --hook=init
2839 */
2940 public function __invoke ( $ _ , $ assoc_args ) {
41+ $ hook = Utils \get_flag_value ( $ assoc_args , 'hook ' , '' );
42+
43+ // No hook specified, start immediately.
44+ if ( ! $ hook ) {
45+ $ this ->start_shell ( $ assoc_args );
46+ return ;
47+ }
48+
49+ // Check if the hook has already fired.
50+ if ( did_action ( $ hook ) ) {
51+ // Hook already fired, start the shell immediately.
52+ $ this ->start_shell ( $ assoc_args );
53+ return ;
54+ }
55+
56+ // Hook hasn't fired yet.
57+ WP_CLI ::error (
58+ sprintf (
59+ "The '%s' hook has not fired yet. " .
60+ 'The shell command runs after WordPress is loaded, so only hooks that have already been triggered can be used. ' .
61+ 'Common hooks that are available include: init, plugins_loaded, wp_loaded. ' ,
62+ $ hook
63+ )
64+ );
65+ }
66+
67+ /**
68+ * Start the shell REPL.
69+ *
70+ * @param array<string,bool|string> $assoc_args Associative arguments.
71+ */
72+ private function start_shell ( $ assoc_args ) {
3073 $ class = WP_CLI \Shell \REPL ::class;
3174
3275 $ implementations = array (
0 commit comments