diff --git a/projects/plugins/jetpack/_inc/client/ai/main.jsx b/projects/plugins/jetpack/_inc/client/ai/main.jsx index dd89e73fffbe..b74c0232d188 100644 --- a/projects/plugins/jetpack/_inc/client/ai/main.jsx +++ b/projects/plugins/jetpack/_inc/client/ai/main.jsx @@ -6,9 +6,10 @@ import { AdminPage, JetpackLogo } from '@automattic/jetpack-components'; import { Spinner } from '@wordpress/components'; -import { useCallback, useState } from '@wordpress/element'; +import { useCallback, useEffect, useState } from '@wordpress/element'; import { __ } from '@wordpress/i18n'; import { Notice, Stack } from '@wordpress/ui'; +import analytics from 'lib/analytics'; import McpHub from './mcp/index'; import McpRead from './mcp/read'; import McpSetup from './mcp/setup'; @@ -16,7 +17,7 @@ import McpUpsell from './mcp/upsell'; import { useMcpSettings } from './mcp/use-mcp-settings'; import McpWrite from './mcp/write'; -const { blogId, apiRoot, apiNonce } = window?.jetpackAiSettings ?? {}; +const { blogId, activityLogUrl, apiRoot, apiNonce } = window?.jetpackAiSettings ?? {}; const VIEW_TITLES = { hub: __( 'AI', 'jetpack' ), @@ -74,6 +75,12 @@ export default function App() { const { isLoading, savingToolIds, mcpAbilities, hasMcpAccess, error, updateMcpAbilities } = useMcpSettings(); + useEffect( () => { + if ( ! isLoading && hasMcpAccess ) { + analytics.tracks.recordEvent( 'jetpack_mcp_settings_viewed' ); + } + }, [ isLoading, hasMcpAccess ] ); + const handleUpdate = useCallback( update => { setSaveError( null ); @@ -138,6 +145,7 @@ export default function App() { { + analytics.tracks.recordEvent( 'jetpack_mcp_enabled_toggled', { enabled } ); const abilities = {}; if ( enabled ) { readTools.forEach( ( [ toolId ] ) => { @@ -258,7 +277,7 @@ export default function McpHub( { mcpAbilities, blogId, savingToolIds, onNavigat { isMcpEnabled && ( - + ) } + + { isMcpEnabled && activityLogUrl && ( + + + + + + + + { __( 'Activity log', 'jetpack' ) } + + + { __( 'Review recent actions taken by AI agents on your site.', 'jetpack' ) } + + + + + + + + ) } ); } diff --git a/projects/plugins/jetpack/_inc/client/ai/mcp/read.jsx b/projects/plugins/jetpack/_inc/client/ai/mcp/read.jsx index 225011068105..ead89711ef4c 100644 --- a/projects/plugins/jetpack/_inc/client/ai/mcp/read.jsx +++ b/projects/plugins/jetpack/_inc/client/ai/mcp/read.jsx @@ -15,6 +15,7 @@ import { import { Fragment, useCallback } from '@wordpress/element'; import { __ } from '@wordpress/i18n'; import { Stack } from '@wordpress/ui'; +import analytics from 'lib/analytics'; import { CATEGORY_ORDER, SUB_CATEGORY_ORDER, @@ -122,6 +123,11 @@ export default function McpRead( { mcpAbilities, blogId, savingToolIds, onUpdate const handleToolChange = useCallback( ( toolId, enabled ) => { + analytics.tracks.recordEvent( 'jetpack_mcp_allowlist_updated', { + tool_id: toolId, + enabled, + view: 'read', + } ); onUpdate( { sites: [ { @@ -136,6 +142,11 @@ export default function McpRead( { mcpAbilities, blogId, savingToolIds, onUpdate const handleEnableAll = useCallback( ( categoryTools, enabled ) => { + analytics.tracks.recordEvent( 'jetpack_mcp_allowlist_updated', { + enabled, + tool_count: categoryTools.length, + view: 'read', + } ); const overrides = {}; categoryTools.forEach( ( [ toolId ] ) => { overrides[ toolId ] = enabled; diff --git a/projects/plugins/jetpack/_inc/client/ai/mcp/style.scss b/projects/plugins/jetpack/_inc/client/ai/mcp/style.scss index c357c645a6fd..0a2fa21f645d 100644 --- a/projects/plugins/jetpack/_inc/client/ai/mcp/style.scss +++ b/projects/plugins/jetpack/_inc/client/ai/mcp/style.scss @@ -24,8 +24,13 @@ } } + &__action-card { + overflow: hidden; + } + &__connect-row { display: flex; + box-sizing: border-box; gap: 16px; align-items: flex-start; padding: 24px; @@ -36,6 +41,15 @@ text-align: left; border-radius: 0; + // Reset browser link styles when rendered as + &, + &:visited, + &:hover, + &:active { + color: inherit; + text-decoration: none; + } + &:hover { background: var(--color-surface-backdrop, #f0f0f1); } @@ -84,7 +98,7 @@ } &__access-card { - // Override default card margin if any + overflow: hidden; } } diff --git a/projects/plugins/jetpack/_inc/client/ai/mcp/write.jsx b/projects/plugins/jetpack/_inc/client/ai/mcp/write.jsx index 5e5f060be403..9f0986d2fb8d 100644 --- a/projects/plugins/jetpack/_inc/client/ai/mcp/write.jsx +++ b/projects/plugins/jetpack/_inc/client/ai/mcp/write.jsx @@ -16,6 +16,7 @@ import { import { Fragment, useCallback } from '@wordpress/element'; import { __ } from '@wordpress/i18n'; import { Stack } from '@wordpress/ui'; +import analytics from 'lib/analytics'; import { CATEGORY_ORDER, SUB_CATEGORY_ORDER, @@ -123,6 +124,11 @@ export default function McpWrite( { mcpAbilities, blogId, savingToolIds, onUpdat const handleToolChange = useCallback( ( toolId, enabled ) => { + analytics.tracks.recordEvent( 'jetpack_mcp_allowlist_updated', { + tool_id: toolId, + enabled, + view: 'write', + } ); onUpdate( { sites: [ { @@ -137,6 +143,11 @@ export default function McpWrite( { mcpAbilities, blogId, savingToolIds, onUpdat const handleEnableAll = useCallback( ( categoryTools, enabled ) => { + analytics.tracks.recordEvent( 'jetpack_mcp_allowlist_updated', { + enabled, + tool_count: categoryTools.length, + view: 'write', + } ); const overrides = {}; categoryTools.forEach( ( [ toolId ] ) => { overrides[ toolId ] = enabled; diff --git a/projects/plugins/jetpack/_inc/lib/admin-pages/class-jetpack-ai-page.php b/projects/plugins/jetpack/_inc/lib/admin-pages/class-jetpack-ai-page.php index 56aa70d4f69a..12b285dd680f 100644 --- a/projects/plugins/jetpack/_inc/lib/admin-pages/class-jetpack-ai-page.php +++ b/projects/plugins/jetpack/_inc/lib/admin-pages/class-jetpack-ai-page.php @@ -10,6 +10,9 @@ use Automattic\Jetpack\Admin_UI\Admin_Menu; use Automattic\Jetpack\Connection\Manager as Connection_Manager; +use Automattic\Jetpack\Redirect; +use Automattic\Jetpack\Status; +use Automattic\Jetpack\Status\Host; if ( ! defined( 'ABSPATH' ) ) { exit( 0 ); @@ -77,7 +80,18 @@ public function page_admin_scripts() { $script_version = $asset_manifest['version']; } - $blog_id = Connection_Manager::get_site_id( true ); + $blog_id = Connection_Manager::get_site_id( true ); + $site_suffix = ( new Status() )->get_site_suffix(); + // Use the plain hostname for the Atomic activity log URL — get_site_suffix() can + // include '::' for subdirectory installs, which would break the URL. This matches + // the approach used by jetpack-mu-wpcom for the sidebar Activity Log link. + $site_host = wp_parse_url( home_url(), PHP_URL_HOST ); + // On Atomic, jetpack-mu-wpcom replaces the cloud redirect with a direct WPCOM URL. + // Mirror that behaviour here so the activity log link resolves consistently. + $activity_log_site = ( is_string( $site_host ) && '' !== $site_host ) ? $site_host : $site_suffix; + $activity_log_url = ( new Host() )->is_woa_site() + ? 'https://wordpress.com/activity-log/' . $activity_log_site + : Redirect::get_url( 'cloud-activity-log-wp-menu', array( 'site' => $blog_id ? $blog_id : $site_suffix ) ); wp_enqueue_script( 'jetpack-ai-admin', @@ -93,12 +107,13 @@ public function page_admin_scripts() { 'jetpack-ai-admin', 'var jetpackAiSettings = ' . wp_json_encode( array( - 'blogId' => $blog_id ? (int) $blog_id : 0, - 'siteAdminUrl' => admin_url(), - 'apiRoot' => esc_url_raw( rest_url() ), - 'apiNonce' => wp_create_nonce( 'wp_rest' ), - 'pluginUrl' => plugins_url( '', JETPACK__PLUGIN_FILE ), - 'upgradeUrl' => 'https://wordpress.com/plans/' . rawurlencode( wp_parse_url( home_url(), PHP_URL_HOST ) ?? '' ), + 'blogId' => $blog_id ? (int) $blog_id : 0, + 'activityLogUrl' => $activity_log_url, + 'siteAdminUrl' => admin_url(), + 'apiRoot' => esc_url_raw( rest_url() ), + 'apiNonce' => wp_create_nonce( 'wp_rest' ), + 'pluginUrl' => plugins_url( '', JETPACK__PLUGIN_FILE ), + 'upgradeUrl' => 'https://wordpress.com/plans/' . rawurlencode( wp_parse_url( home_url(), PHP_URL_HOST ) ?? '' ), ), JSON_UNESCAPED_SLASHES | JSON_HEX_TAG | JSON_HEX_AMP ) . ';', diff --git a/projects/plugins/jetpack/changelog/aiint-357-jetpack-ai-mcp-activity-log-and-metrics b/projects/plugins/jetpack/changelog/aiint-357-jetpack-ai-mcp-activity-log-and-metrics new file mode 100644 index 000000000000..fc3956d90932 --- /dev/null +++ b/projects/plugins/jetpack/changelog/aiint-357-jetpack-ai-mcp-activity-log-and-metrics @@ -0,0 +1,4 @@ +Significance: minor +Type: enhancement + +AI MCP settings: add activity log link and Tracks analytics events (jp_mcp_settings_viewed, jp_mcp_enabled_toggled, jp_mcp_allowlist_updated)