summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'plugins/jetpack/class.jetpack-cli.php')
-rw-r--r--plugins/jetpack/class.jetpack-cli.php208
1 files changed, 118 insertions, 90 deletions
diff --git a/plugins/jetpack/class.jetpack-cli.php b/plugins/jetpack/class.jetpack-cli.php
index f1da8000..0d19310c 100644
--- a/plugins/jetpack/class.jetpack-cli.php
+++ b/plugins/jetpack/class.jetpack-cli.php
@@ -1,16 +1,18 @@
<?php
-WP_CLI::add_command( 'jetpack', 'Jetpack_CLI' );
-
use Automattic\Jetpack\Connection\Client;
use Automattic\Jetpack\Connection\Manager as Connection_Manager;
-use Automattic\Jetpack\Connection\Utils as Connection_Utils;
+use Automattic\Jetpack\Connection\Tokens;
+use Automattic\Jetpack\Identity_Crisis;
use Automattic\Jetpack\Status;
use Automattic\Jetpack\Sync\Actions;
use Automattic\Jetpack\Sync\Listener;
+use Automattic\Jetpack\Sync\Modules;
use Automattic\Jetpack\Sync\Queue;
use Automattic\Jetpack\Sync\Settings;
+WP_CLI::add_command( 'jetpack', 'Jetpack_CLI' );
+
/**
* Control your local Jetpack installation.
*/
@@ -63,7 +65,7 @@ class Jetpack_CLI extends WP_CLI_Command {
$cxntests->output_results_for_cli();
- WP_CLI::error( __( 'Jetpack connection is broken.', 'jetpack' ) ); // Exit CLI.
+ WP_CLI::error( __( 'One or more tests did not pass. Please investigate!', 'jetpack' ) ); // Exit CLI.
}
/* translators: %s is current version of Jetpack, for example 7.3 */
@@ -131,7 +133,7 @@ class Jetpack_CLI extends WP_CLI_Command {
/* translators: %s is the site URL */
WP_CLI::line( sprintf( __( 'Testing connection for %s', 'jetpack' ), esc_url( get_site_url() ) ) );
- if ( ! Jetpack::is_active() ) {
+ if ( ! Jetpack::is_connection_ready() ) {
WP_CLI::error( __( 'Jetpack is not currently connected to WordPress.com', 'jetpack' ) );
}
@@ -170,21 +172,21 @@ class Jetpack_CLI extends WP_CLI_Command {
*
* user <user_identifier>: Disconnect a specific user from WordPress.com.
*
- * Please note, the primary account that the blog is connected
- * to WordPress.com with cannot be disconnected without
- * disconnecting the entire blog.
+ * [--force]
+ * If the user ID provided is the connection owner, it will only be disconnected if --force is passed
*
* ## EXAMPLES
*
* wp jetpack disconnect blog
* wp jetpack disconnect user 13
+ * wp jetpack disconnect user 1 --force
* wp jetpack disconnect user username
* wp jetpack disconnect user email@domain.com
*
- * @synopsis <blog|user> [<user_identifier>]
+ * @synopsis <blog|user> [<user_identifier>] [--force]
*/
public function disconnect( $args, $assoc_args ) {
- if ( ! Jetpack::is_active() ) {
+ if ( ! Jetpack::is_connection_ready() ) {
WP_CLI::success( __( 'The site is not currently connected, so nothing to do!', 'jetpack' ) );
return;
}
@@ -216,6 +218,8 @@ class Jetpack_CLI extends WP_CLI_Command {
}
}
+ $force_user_disconnect = ! empty( $assoc_args['force'] );
+
switch ( $action ) {
case 'blog':
Jetpack::log( 'disconnect' );
@@ -229,12 +233,23 @@ class Jetpack_CLI extends WP_CLI_Command {
);
break;
case 'user':
- if ( Connection_Manager::disconnect_user( $user->ID ) ) {
+ $connection_manager = new Connection_Manager( 'jetpack' );
+ $disconnected = $connection_manager->disconnect_user( $user->ID, $force_user_disconnect );
+ if ( $disconnected ) {
Jetpack::log( 'unlink', $user->ID );
WP_CLI::success( __( 'User has been successfully disconnected.', 'jetpack' ) );
} else {
- /* translators: %s is a username */
- WP_CLI::error( sprintf( __( "User %s could not be disconnected. Are you sure they're connected currently?", 'jetpack' ), "{$user->login} <{$user->email}>" ) );
+ if ( ! $connection_manager->is_user_connected( $user->ID ) ) {
+ /* translators: %s is a username */
+ $error_message = sprintf( __( 'User %s could not be disconnected because it is not connected!', 'jetpack' ), "{$user->data->user_login} <{$user->data->user_email}>" );
+ } elseif ( ! $force_user_disconnect && $connection_manager->is_connection_owner( $user->ID ) ) {
+ /* translators: %s is a username */
+ $error_message = sprintf( __( 'User %s could not be disconnected because it is the connection owner! If you want to disconnect in anyway, use the --force parameter.', 'jetpack' ), "{$user->data->user_login} <{$user->data->user_email}>" );
+ } else {
+ /* translators: %s is a username */
+ $error_message = sprintf( __( 'User %s could not be disconnected.', 'jetpack' ), "{$user->data->user_login} <{$user->data->user_email}>" );
+ }
+ WP_CLI::error( $error_message );
}
break;
case 'prompt':
@@ -563,20 +578,20 @@ class Jetpack_CLI extends WP_CLI_Command {
*
* ## OPTIONS
*
- * whitelist: Whitelist an IP address. You can also read or clear the whitelist.
+ * allow: Add an IP address to an always allow list. You can also read or clear the allow list.
*
*
* ## EXAMPLES
*
- * wp jetpack protect whitelist <ip address>
- * wp jetpack protect whitelist list
- * wp jetpack protect whitelist clear
+ * wp jetpack protect allow <ip address>
+ * wp jetpack protect allow list
+ * wp jetpack protect allow clear
*
- * @synopsis <whitelist> [<ip|ip_low-ip_high|list|clear>]
+ * @synopsis <allow> [<ip|ip_low-ip_high|list|clear>]
*/
public function protect( $args, $assoc_args ) {
$action = isset( $args[0] ) ? $args[0] : 'prompt';
- if ( ! in_array( $action, array( 'whitelist' ) ) ) {
+ if ( ! in_array( $action, array( 'whitelist', 'allow' ), true ) ) { // Still allow "whitelist" for legacy support.
/* translators: %s is a command like "prompt" */
WP_CLI::error( sprintf( __( '%s is not a valid command.', 'jetpack' ), $action ) );
}
@@ -585,96 +600,96 @@ class Jetpack_CLI extends WP_CLI_Command {
/* translators: %s is a module name */
WP_CLI::error( sprintf( _x( '%1$s is not active. You can activate it with "wp jetpack module activate %2$s"', '"wp jetpack module activate" is a command - do not translate', 'jetpack' ), __FUNCTION__, __FUNCTION__ ) );
}
- if ( in_array( $action, array( 'whitelist' ) ) ) {
+ if ( in_array( $action, array( 'allow', 'whitelist' ), true ) ) {
if ( isset( $args[1] ) ) {
- $action = 'whitelist';
+ $action = 'allow';
} else {
$action = 'prompt';
}
}
switch ( $action ) {
- case 'whitelist':
- $whitelist = array();
- $new_ip = $args[1];
- $current_whitelist = get_site_option( 'jetpack_protect_whitelist', array() );
+ case 'allow':
+ $allow = array();
+ $new_ip = $args[1];
+ $current_allow = get_site_option( 'jetpack_protect_whitelist', array() ); // @todo Update the option name.
- // Build array of IPs that are already whitelisted.
+ // Build array of IPs that are already on the allowed list.
// Re-build manually instead of using jetpack_protect_format_whitelist() so we can easily get
// low & high range params for jetpack_protect_ip_address_is_in_range();
- foreach ( $current_whitelist as $whitelisted ) {
+ foreach ( $current_allow as $allowed ) {
// IP ranges
- if ( $whitelisted->range ) {
+ if ( $allowed->range ) {
- // Is it already whitelisted?
- if ( jetpack_protect_ip_address_is_in_range( $new_ip, $whitelisted->range_low, $whitelisted->range_high ) ) {
+ // Is it already on the allowed list?
+ if ( jetpack_protect_ip_address_is_in_range( $new_ip, $allowed->range_low, $allowed->range_high ) ) {
/* translators: %s is an IP address */
- WP_CLI::error( sprintf( __( '%s has already been whitelisted', 'jetpack' ), $new_ip ) );
+ WP_CLI::error( sprintf( __( '%s is already on the always allow list.', 'jetpack' ), $new_ip ) );
break;
}
- $whitelist[] = $whitelisted->range_low . ' - ' . $whitelisted->range_high;
+ $allow[] = $allowed->range_low . ' - ' . $allowed->range_high;
} else { // Individual IPs
- // Check if the IP is already whitelisted (single IP only)
- if ( $new_ip == $whitelisted->ip_address ) {
+ // Check if the IP is already on the allow list (single IP only).
+ if ( $new_ip === $allowed->ip_address ) {
/* translators: %s is an IP address */
- WP_CLI::error( sprintf( __( '%s has already been whitelisted', 'jetpack' ), $new_ip ) );
+ WP_CLI::error( sprintf( __( '%s is already on the always allow list.', 'jetpack' ), $new_ip ) );
break;
}
- $whitelist[] = $whitelisted->ip_address;
+ $allow[] = $allowed->ip_address;
}
}
/*
- * List the whitelist
- * Done here because it's easier to read the $whitelist array after it's been rebuilt
+ * List the allowed IPs.
+ * Done here because it's easier to read the $allow array after it's been rebuilt.
*/
if ( isset( $args[1] ) && 'list' == $args[1] ) {
- if ( ! empty( $whitelist ) ) {
- WP_CLI::success( __( 'Here are your whitelisted IPs:', 'jetpack' ) );
- foreach ( $whitelist as $ip ) {
+ if ( ! empty( $allow ) ) {
+ WP_CLI::success( __( 'Here are your always allowed IPs:', 'jetpack' ) );
+ foreach ( $allow as $ip ) {
WP_CLI::line( "\t" . str_pad( $ip, 24 ) );
}
} else {
- WP_CLI::line( __( 'Whitelist is empty.', 'jetpack' ) );
+ WP_CLI::line( __( 'Always allow list is empty.', 'jetpack' ) );
}
break;
}
/*
- * Clear the whitelist
+ * Clear the always allow list.
*/
if ( isset( $args[1] ) && 'clear' == $args[1] ) {
- if ( ! empty( $whitelist ) ) {
- $whitelist = array();
- jetpack_protect_save_whitelist( $whitelist );
- WP_CLI::success( __( 'Cleared all whitelisted IPs', 'jetpack' ) );
+ if ( ! empty( $allow ) ) {
+ $allow = array();
+ jetpack_protect_save_whitelist( $allow ); // @todo Need to update function name in the Protect module.
+ WP_CLI::success( __( 'Cleared all IPs from the always allow list.', 'jetpack' ) );
} else {
- WP_CLI::line( __( 'Whitelist is empty.', 'jetpack' ) );
+ WP_CLI::line( __( 'Always allow list is empty.', 'jetpack' ) );
}
break;
}
- // Append new IP to whitelist array
- array_push( $whitelist, $new_ip );
+ // Append new IP to allow array.
+ array_push( $allow, $new_ip );
- // Save whitelist if there are no errors
- $result = jetpack_protect_save_whitelist( $whitelist );
+ // Save allow list if there are no errors.
+ $result = jetpack_protect_save_whitelist( $allow ); // @todo Need to update function name in the Protect module.
if ( is_wp_error( $result ) ) {
WP_CLI::error( $result );
}
/* translators: %s is an IP address */
- WP_CLI::success( sprintf( __( '%s has been whitelisted.', 'jetpack' ), $new_ip ) );
+ WP_CLI::success( sprintf( __( '%s has been added to the always allowed list.', 'jetpack' ), $new_ip ) );
break;
case 'prompt':
WP_CLI::error(
__( 'No command found.', 'jetpack' ) . "\n" .
- __( 'Please enter the IP address you want to whitelist.', 'jetpack' ) . "\n" .
- _x( 'You can save a range of IPs {low_range}-{high_range}. No spaces allowed. (example: 1.1.1.1-2.2.2.2)', 'Instructions on how to whitelist IP ranges - low_range/high_range should be translated.', 'jetpack' ) . "\n" .
- _x( "You can also 'list' or 'clear' the whitelist.", "'list' and 'clear' are commands and should not be translated", 'jetpack' ) . "\n"
+ __( 'Please enter the IP address you want to always allow.', 'jetpack' ) . "\n" .
+ _x( 'You can save a range of IPs {low_range}-{high_range}. No spaces allowed. (example: 1.1.1.1-2.2.2.2)', 'Instructions on how to add IP ranges - low_range/high_range should be translated.', 'jetpack' ) . "\n" .
+ _x( "You can also 'list' or 'clear' the always allowed list.", "'list' and 'clear' are commands and should not be translated", 'jetpack' ) . "\n"
);
break;
}
@@ -728,7 +743,7 @@ class Jetpack_CLI extends WP_CLI_Command {
// Bail if the option isn't found
$option = isset( $args[1] ) ? Jetpack_Options::get_option( $args[1] ) : false;
if ( isset( $args[1] ) && ! $option && 'update' !== $args[0] ) {
- WP_CLI::error( __( 'Option not found or is empty. Use "list" to list option names', 'jetpack' ) );
+ WP_CLI::error( __( 'Option not found or is empty. Use "list" to list option names', 'jetpack' ) );
}
// Let's print_r the option if it's an array
@@ -896,19 +911,22 @@ class Jetpack_CLI extends WP_CLI_Command {
break;
case 'start':
if ( ! Actions::sync_allowed() ) {
- if ( ! Settings::get_setting( 'disable' ) ) {
+ if ( Settings::get_setting( 'disable' ) ) {
WP_CLI::error( __( 'Jetpack sync is not currently allowed for this site. It is currently disabled. Run `wp jetpack sync enable` to enable it.', 'jetpack' ) );
return;
}
- if ( doing_action( 'jetpack_user_authorized' ) || Jetpack::is_active() ) {
- WP_CLI::error( __( 'Jetpack sync is not currently allowed for this site. Jetpack is not connected.', 'jetpack' ) );
- return;
+ $connection = new Connection_Manager();
+ if ( ! $connection->is_connected() ) {
+ if ( ! doing_action( 'jetpack_site_registered' ) ) {
+ WP_CLI::error( __( 'Jetpack sync is not currently allowed for this site. Jetpack is not connected.', 'jetpack' ) );
+ return;
+ }
}
$status = new Status();
- if ( $status->is_development_mode() ) {
- WP_CLI::error( __( 'Jetpack sync is not currently allowed for this site. The site is in development mode.', 'jetpack' ) );
+ if ( $status->is_offline_mode() ) {
+ WP_CLI::error( __( 'Jetpack sync is not currently allowed for this site. The site is in offline mode.', 'jetpack' ) );
return;
}
if ( $status->is_staging_site() ) {
@@ -997,6 +1015,11 @@ class Jetpack_CLI extends WP_CLI_Command {
} else {
WP_CLI::log( __( 'Sent more data to WordPress.com', 'jetpack' ) );
}
+
+ // Immediate Full Sync does not wait for WP.com to process data so we need to enforce a wait.
+ if ( false !== strpos( get_class( Modules::get_module( 'full-sync' ) ), 'Full_Sync_Immediately' ) ) {
+ sleep( 15 );
+ }
}
$i++;
} while ( $result && ! is_wp_error( $result ) );
@@ -1101,7 +1124,7 @@ class Jetpack_CLI extends WP_CLI_Command {
$this->partner_provision_error( new WP_Error( 'missing_access_token', __( 'Missing or invalid access token', 'jetpack' ) ) );
}
- if ( Jetpack::validate_sync_error_idc_option() ) {
+ if ( Identity_Crisis::validate_sync_error_idc_option() ) {
$this->partner_provision_error(
new WP_Error(
'site_in_safe_mode',
@@ -1113,7 +1136,8 @@ class Jetpack_CLI extends WP_CLI_Command {
$site_identifier = Jetpack_Options::get_option( 'id' );
if ( ! $site_identifier ) {
- $site_identifier = Jetpack::build_raw_urls( get_home_url() );
+ $status = new Status();
+ $site_identifier = $status->get_site_suffix();
}
$request = array(
@@ -1125,7 +1149,7 @@ class Jetpack_CLI extends WP_CLI_Command {
'method' => 'POST',
);
- $url = sprintf( 'https://%s/rest/v1.3/jpphp/%s/partner-cancel', $this->get_api_host(), $site_identifier );
+ $url = sprintf( '%s/rest/v1.3/jpphp/%s/partner-cancel', $this->get_api_host(), $site_identifier );
if ( ! empty( $named_args ) && ! empty( $named_args['partner_tracking_id'] ) ) {
$url = esc_url_raw( add_query_arg( 'partner_tracking_id', $named_args['partner_tracking_id'], $url ) );
}
@@ -1231,7 +1255,7 @@ class Jetpack_CLI extends WP_CLI_Command {
* @synopsis <rebuild> [--purge]
*/
public function sitemap( $args, $assoc_args ) {
- if ( ! Jetpack::is_active() ) {
+ if ( ! Jetpack::is_connection_ready() ) {
WP_CLI::error( __( 'Jetpack is not currently connected to WordPress.com', 'jetpack' ) );
}
if ( ! Jetpack::is_module_active( 'sitemaps' ) ) {
@@ -1268,14 +1292,14 @@ class Jetpack_CLI extends WP_CLI_Command {
WP_CLI::error( __( 'A non-empty token argument must be passed.', 'jetpack' ) );
}
- $is_master_user = ! Jetpack::is_active();
- $current_user_id = get_current_user_id();
+ $is_connection_owner = ! Jetpack::connection()->has_connected_owner();
+ $current_user_id = get_current_user_id();
- Connection_Utils::update_user_token( $current_user_id, sprintf( '%s.%d', $named_args['token'], $current_user_id ), $is_master_user );
+ ( new Tokens() )->update_user_token( $current_user_id, sprintf( '%s.%d', $named_args['token'], $current_user_id ), $is_connection_owner );
WP_CLI::log( wp_json_encode( $named_args ) );
- if ( $is_master_user ) {
+ if ( $is_connection_owner ) {
/**
* Auto-enable SSO module for new Jetpack Start connections
*
@@ -1327,7 +1351,7 @@ class Jetpack_CLI extends WP_CLI_Command {
* wp jetpack call_api --resource='/sites/%d'
*/
public function call_api( $args, $named_args ) {
- if ( ! Jetpack::is_active() ) {
+ if ( ! Jetpack::is_connection_ready() ) {
WP_CLI::error( __( 'Jetpack is not currently connected to WordPress.com', 'jetpack' ) );
}
@@ -1426,7 +1450,7 @@ class Jetpack_CLI extends WP_CLI_Command {
* wp jetpack updload_ssh_creds --host=example.com --ssh-user=example --kpri=key
*/
public function upload_ssh_creds( $args, $named_args ) {
- if ( ! Jetpack::is_active() ) {
+ if ( ! Jetpack::is_connection_ready() ) {
WP_CLI::error( __( 'Jetpack is not currently connected to WordPress.com', 'jetpack' ) );
}
@@ -1606,24 +1630,25 @@ class Jetpack_CLI extends WP_CLI_Command {
* $ wp jetpack publicize disconnect twitter
*/
public function publicize( $args, $named_args ) {
- if ( ! Jetpack::is_active() ) {
- WP_CLI::error( __( 'Jetpack is not currently connected to WordPress.com', 'jetpack' ) );
+ if ( ! Jetpack::connection()->has_connected_owner() ) {
+ WP_CLI::error( __( 'Publicize requires a user-level connection to WordPress.com', 'jetpack' ) );
}
if ( ! Jetpack::is_module_active( 'publicize' ) ) {
WP_CLI::error( __( 'The publicize module is not active.', 'jetpack' ) );
}
- if ( ( new Status() )->is_development_mode() ) {
+ if ( ( new Status() )->is_offline_mode() ) {
if (
! defined( 'JETPACK_DEV_DEBUG' ) &&
! has_filter( 'jetpack_development_mode' ) &&
+ ! has_filter( 'jetpack_offline_mode' ) &&
false === strpos( site_url(), '.' )
) {
- WP_CLI::error( __( "Jetpack is current in development mode because the site url does not contain a '.', which often occurs when dynamically setting the WP_SITEURL constant. While in development mode, the publicize module will not load.", 'jetpack' ) );
+ WP_CLI::error( __( "Jetpack is current in offline mode because the site url does not contain a '.', which often occurs when dynamically setting the WP_SITEURL constant. While in offline mode, the publicize module will not load.", 'jetpack' ) );
}
- WP_CLI::error( __( 'Jetpack is currently in development mode, so the publicize module will not load.', 'jetpack' ) );
+ WP_CLI::error( __( 'Jetpack is currently in offline mode, so the publicize module will not load.', 'jetpack' ) );
}
if ( ! class_exists( 'Publicize' ) ) {
@@ -1783,7 +1808,7 @@ class Jetpack_CLI extends WP_CLI_Command {
private function get_api_host() {
$env_api_host = getenv( 'JETPACK_START_API_HOST', true );
- return $env_api_host ? $env_api_host : JETPACK__WPCOM_JSON_API_HOST;
+ return $env_api_host ? 'https://' . $env_api_host : JETPACK__WPCOM_JSON_API_BASE;
}
private function partner_provision_error( $error ) {
@@ -1890,16 +1915,17 @@ class Jetpack_CLI extends WP_CLI_Command {
$hasKeywords = isset( $assoc_args['keywords'] );
$files = array(
- "$path/$slug.php" => $this->render_block_file(
+ "$path/$slug.php" => $this->render_block_file(
'block-register-php',
array(
- 'slug' => $slug,
- 'title' => $title,
- 'underscoredSlug' => str_replace( '-', '_', $slug ),
- 'jetpackVersion' => substr( JETPACK__VERSION, 0, strpos( JETPACK__VERSION, '.' ) ) . '.x',
+ 'slug' => $slug,
+ 'title' => $title,
+ 'underscoredSlug' => str_replace( '-', '_', $slug ),
+ 'underscoredTitle' => str_replace( ' ', '_', $title ),
+ 'jetpackVersion' => substr( JETPACK__VERSION, 0, strpos( JETPACK__VERSION, '.' ) ) . '.x',
)
),
- "$path/index.js" => $this->render_block_file(
+ "$path/index.js" => $this->render_block_file(
'block-index-js',
array(
'slug' => $slug,
@@ -1919,21 +1945,23 @@ class Jetpack_CLI extends WP_CLI_Command {
'hasKeywords' => $hasKeywords,
)
),
- "$path/editor.js" => $this->render_block_file( 'block-editor-js' ),
- "$path/editor.scss" => $this->render_block_file(
+ "$path/editor.js" => $this->render_block_file( 'block-editor-js' ),
+ "$path/editor.scss" => $this->render_block_file(
'block-editor-scss',
array(
'slug' => $slug,
'title' => $title,
)
),
- "$path/edit.js" => $this->render_block_file(
+ "$path/edit.js" => $this->render_block_file(
'block-edit-js',
array(
'title' => $title,
'className' => str_replace( ' ', '', ucwords( str_replace( '-', ' ', $slug ) ) ),
)
),
+ "$path/icon.js" => $this->render_block_file( 'block-icon-js' ),
+ "$path/attributes.js" => $this->render_block_file( 'block-attributes-js' ),
);
$files_written = array();
@@ -1995,7 +2023,7 @@ class Jetpack_CLI extends WP_CLI_Command {
"--------------------------------------------------------------------------------------------------------------------\n" .
/* translators: the placeholder is a directory path */
esc_html__( 'The files were created at %3$s', 'jetpack' ) . "\n" .
- esc_html__( 'To start using the block, build the blocks with yarn run build-extensions', 'jetpack' ) . "\n" .
+ esc_html__( 'To start using the block, build the blocks with pnpm run build-extensions', 'jetpack' ) . "\n" .
/* translators: the placeholder is a file path */
esc_html__( 'The block slug has been added to the %4$s list at %5$s', 'jetpack' ) . "\n" .
'%6$s' . "\n" .
@@ -2051,7 +2079,7 @@ function jetpack_cli_are_you_sure( $flagged = false, $error_msg = false ) {
if ( ! $flagged ) {
$prompt_message = _x( 'Are you sure? This cannot be undone. Type "yes" to continue:', '"yes" is a command - do not translate.', 'jetpack' );
} else {
- $prompt_message = _x( 'Are you sure? Modifying this option may disrupt your Jetpack connection. Type "yes" to continue.', '"yes" is a command - do not translate.', 'jetpack' );
+ $prompt_message = _x( 'Are you sure? Modifying this option may disrupt your Jetpack connection. Type "yes" to continue.', '"yes" is a command - do not translate.', 'jetpack' );
}
WP_CLI::line( $prompt_message );