mcp-wordpress 1.1.7 → 1.2.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (255) hide show
  1. package/README.md +388 -66
  2. package/dist/cache/CacheInvalidation.d.ts +118 -0
  3. package/dist/cache/CacheInvalidation.d.ts.map +1 -0
  4. package/dist/cache/CacheInvalidation.js +349 -0
  5. package/dist/cache/CacheInvalidation.js.map +1 -0
  6. package/dist/cache/CacheManager.d.ts +143 -0
  7. package/dist/cache/CacheManager.d.ts.map +1 -0
  8. package/dist/cache/CacheManager.js +308 -0
  9. package/dist/cache/CacheManager.js.map +1 -0
  10. package/dist/cache/HttpCacheWrapper.d.ts +121 -0
  11. package/dist/cache/HttpCacheWrapper.d.ts.map +1 -0
  12. package/dist/cache/HttpCacheWrapper.js +280 -0
  13. package/dist/cache/HttpCacheWrapper.js.map +1 -0
  14. package/dist/cache/__tests__/CacheInvalidation.test.d.ts +5 -0
  15. package/dist/cache/__tests__/CacheInvalidation.test.d.ts.map +1 -0
  16. package/dist/cache/__tests__/CacheInvalidation.test.js +236 -0
  17. package/dist/cache/__tests__/CacheInvalidation.test.js.map +1 -0
  18. package/dist/cache/__tests__/CacheManager.test.d.ts +5 -0
  19. package/dist/cache/__tests__/CacheManager.test.d.ts.map +1 -0
  20. package/dist/cache/__tests__/CacheManager.test.js +233 -0
  21. package/dist/cache/__tests__/CacheManager.test.js.map +1 -0
  22. package/dist/cache/__tests__/CachedWordPressClient.test.d.ts +5 -0
  23. package/dist/cache/__tests__/CachedWordPressClient.test.d.ts.map +1 -0
  24. package/dist/cache/__tests__/CachedWordPressClient.test.js +228 -0
  25. package/dist/cache/__tests__/CachedWordPressClient.test.js.map +1 -0
  26. package/dist/cache/__tests__/HttpCacheWrapper.test.d.ts +5 -0
  27. package/dist/cache/__tests__/HttpCacheWrapper.test.d.ts.map +1 -0
  28. package/dist/cache/__tests__/HttpCacheWrapper.test.js +296 -0
  29. package/dist/cache/__tests__/HttpCacheWrapper.test.js.map +1 -0
  30. package/dist/cache/index.d.ts +12 -0
  31. package/dist/cache/index.d.ts.map +1 -0
  32. package/dist/cache/index.js +9 -0
  33. package/dist/cache/index.js.map +1 -0
  34. package/dist/client/CachedWordPressClient.d.ts +160 -0
  35. package/dist/client/CachedWordPressClient.d.ts.map +1 -0
  36. package/dist/client/CachedWordPressClient.js +338 -0
  37. package/dist/client/CachedWordPressClient.js.map +1 -0
  38. package/dist/client/WordPressClient.d.ts +81 -0
  39. package/dist/client/WordPressClient.d.ts.map +1 -0
  40. package/dist/client/WordPressClient.js +354 -0
  41. package/dist/client/WordPressClient.js.map +1 -0
  42. package/dist/config/ConfigurationSchema.d.ts +281 -0
  43. package/dist/config/ConfigurationSchema.d.ts.map +1 -0
  44. package/dist/config/ConfigurationSchema.js +205 -0
  45. package/dist/config/ConfigurationSchema.js.map +1 -0
  46. package/dist/config/ServerConfiguration.d.ts +38 -0
  47. package/dist/config/ServerConfiguration.d.ts.map +1 -0
  48. package/dist/config/ServerConfiguration.js +158 -0
  49. package/dist/config/ServerConfiguration.js.map +1 -0
  50. package/dist/docs/DocumentationGenerator.d.ts +184 -0
  51. package/dist/docs/DocumentationGenerator.d.ts.map +1 -0
  52. package/dist/docs/DocumentationGenerator.js +735 -0
  53. package/dist/docs/DocumentationGenerator.js.map +1 -0
  54. package/dist/docs/MarkdownFormatter.d.ts +84 -0
  55. package/dist/docs/MarkdownFormatter.d.ts.map +1 -0
  56. package/dist/docs/MarkdownFormatter.js +448 -0
  57. package/dist/docs/MarkdownFormatter.js.map +1 -0
  58. package/dist/docs/index.d.ts +8 -0
  59. package/dist/docs/index.d.ts.map +1 -0
  60. package/dist/docs/index.js +7 -0
  61. package/dist/docs/index.js.map +1 -0
  62. package/dist/index.d.ts +1 -4
  63. package/dist/index.d.ts.map +1 -1
  64. package/dist/index.js +12 -212
  65. package/dist/index.js.map +1 -1
  66. package/dist/performance/AnomalyDetector.d.ts +63 -0
  67. package/dist/performance/AnomalyDetector.d.ts.map +1 -0
  68. package/dist/performance/AnomalyDetector.js +222 -0
  69. package/dist/performance/AnomalyDetector.js.map +1 -0
  70. package/dist/performance/BenchmarkAnalyzer.d.ts +67 -0
  71. package/dist/performance/BenchmarkAnalyzer.d.ts.map +1 -0
  72. package/dist/performance/BenchmarkAnalyzer.js +301 -0
  73. package/dist/performance/BenchmarkAnalyzer.js.map +1 -0
  74. package/dist/performance/MetricsCollector.d.ts +139 -0
  75. package/dist/performance/MetricsCollector.d.ts.map +1 -0
  76. package/dist/performance/MetricsCollector.js +320 -0
  77. package/dist/performance/MetricsCollector.js.map +1 -0
  78. package/dist/performance/PerformanceAnalytics.d.ts +162 -0
  79. package/dist/performance/PerformanceAnalytics.d.ts.map +1 -0
  80. package/dist/performance/PerformanceAnalytics.js +554 -0
  81. package/dist/performance/PerformanceAnalytics.js.map +1 -0
  82. package/dist/performance/PerformanceMonitor.d.ts +202 -0
  83. package/dist/performance/PerformanceMonitor.d.ts.map +1 -0
  84. package/dist/performance/PerformanceMonitor.js +478 -0
  85. package/dist/performance/PerformanceMonitor.js.map +1 -0
  86. package/dist/performance/TrendAnalyzer.d.ts +69 -0
  87. package/dist/performance/TrendAnalyzer.d.ts.map +1 -0
  88. package/dist/performance/TrendAnalyzer.js +203 -0
  89. package/dist/performance/TrendAnalyzer.js.map +1 -0
  90. package/dist/performance/index.d.ts +11 -0
  91. package/dist/performance/index.d.ts.map +1 -0
  92. package/dist/performance/index.js +8 -0
  93. package/dist/performance/index.js.map +1 -0
  94. package/dist/security/InputValidator.d.ts +215 -0
  95. package/dist/security/InputValidator.d.ts.map +1 -0
  96. package/dist/security/InputValidator.js +278 -0
  97. package/dist/security/InputValidator.js.map +1 -0
  98. package/dist/security/SecurityConfig.d.ts +129 -0
  99. package/dist/security/SecurityConfig.d.ts.map +1 -0
  100. package/dist/security/SecurityConfig.js +262 -0
  101. package/dist/security/SecurityConfig.js.map +1 -0
  102. package/dist/server/ConnectionTester.d.ts +24 -0
  103. package/dist/server/ConnectionTester.d.ts.map +1 -0
  104. package/dist/server/ConnectionTester.js +61 -0
  105. package/dist/server/ConnectionTester.js.map +1 -0
  106. package/dist/server/ToolRegistry.d.ts +46 -0
  107. package/dist/server/ToolRegistry.d.ts.map +1 -0
  108. package/dist/server/ToolRegistry.js +148 -0
  109. package/dist/server/ToolRegistry.js.map +1 -0
  110. package/dist/tools/BaseToolClass.d.ts +76 -0
  111. package/dist/tools/BaseToolClass.d.ts.map +1 -0
  112. package/dist/tools/BaseToolClass.js +104 -0
  113. package/dist/tools/BaseToolClass.js.map +1 -0
  114. package/dist/tools/BaseToolManager.d.ts +26 -0
  115. package/dist/tools/BaseToolManager.d.ts.map +1 -0
  116. package/dist/tools/BaseToolManager.js +56 -0
  117. package/dist/tools/BaseToolManager.js.map +1 -0
  118. package/dist/tools/base.d.ts +37 -0
  119. package/dist/tools/base.d.ts.map +1 -0
  120. package/dist/tools/base.js +60 -0
  121. package/dist/tools/base.js.map +1 -0
  122. package/dist/tools/cache.d.ts +260 -0
  123. package/dist/tools/cache.d.ts.map +1 -0
  124. package/dist/tools/cache.js +237 -0
  125. package/dist/tools/cache.js.map +1 -0
  126. package/dist/tools/index.d.ts +2 -0
  127. package/dist/tools/index.d.ts.map +1 -1
  128. package/dist/tools/index.js +2 -0
  129. package/dist/tools/index.js.map +1 -1
  130. package/dist/tools/performance.d.ts +63 -0
  131. package/dist/tools/performance.d.ts.map +1 -0
  132. package/dist/tools/performance.js +865 -0
  133. package/dist/tools/performance.js.map +1 -0
  134. package/dist/types/client.d.ts +1 -0
  135. package/dist/types/client.d.ts.map +1 -1
  136. package/dist/types/client.js.map +1 -1
  137. package/dist/utils/toolWrapper.d.ts +4 -0
  138. package/dist/utils/toolWrapper.d.ts.map +1 -1
  139. package/dist/utils/toolWrapper.js +11 -0
  140. package/dist/utils/toolWrapper.js.map +1 -1
  141. package/dist/utils/validation.d.ts +68 -0
  142. package/dist/utils/validation.d.ts.map +1 -0
  143. package/dist/utils/validation.js +185 -0
  144. package/dist/utils/validation.js.map +1 -0
  145. package/docs/CACHING.md +340 -0
  146. package/docs/DOCKER.md +451 -0
  147. package/docs/PERFORMANCE_MONITORING.md +471 -0
  148. package/docs/SECURITY_TESTING.md +393 -0
  149. package/docs/api/README.md +200 -0
  150. package/docs/api/categories/auth.md +40 -0
  151. package/docs/api/categories/cache.md +41 -0
  152. package/docs/api/categories/comment.md +44 -0
  153. package/docs/api/categories/media.md +43 -0
  154. package/docs/api/categories/page.md +43 -0
  155. package/docs/api/categories/performance.md +44 -0
  156. package/docs/api/categories/post.md +43 -0
  157. package/docs/api/categories/site.md +43 -0
  158. package/docs/api/categories/taxonomy.md +47 -0
  159. package/docs/api/categories/user.md +43 -0
  160. package/docs/api/openapi.json +3305 -0
  161. package/docs/api/summary.json +12 -0
  162. package/docs/api/tools/wp_approve_comment.md +98 -0
  163. package/docs/api/tools/wp_cache_clear.md +120 -0
  164. package/docs/api/tools/wp_cache_info.md +119 -0
  165. package/docs/api/tools/wp_cache_stats.md +119 -0
  166. package/docs/api/tools/wp_cache_warm.md +119 -0
  167. package/docs/api/tools/wp_create_application_password.md +102 -0
  168. package/docs/api/tools/wp_create_category.md +102 -0
  169. package/docs/api/tools/wp_create_comment.md +128 -0
  170. package/docs/api/tools/wp_create_page.md +135 -0
  171. package/docs/api/tools/wp_create_post.md +147 -0
  172. package/docs/api/tools/wp_create_tag.md +101 -0
  173. package/docs/api/tools/wp_create_user.md +135 -0
  174. package/docs/api/tools/wp_delete_application_password.md +101 -0
  175. package/docs/api/tools/wp_delete_category.md +100 -0
  176. package/docs/api/tools/wp_delete_comment.md +101 -0
  177. package/docs/api/tools/wp_delete_media.md +108 -0
  178. package/docs/api/tools/wp_delete_page.md +108 -0
  179. package/docs/api/tools/wp_delete_post.md +117 -0
  180. package/docs/api/tools/wp_delete_tag.md +100 -0
  181. package/docs/api/tools/wp_delete_user.md +108 -0
  182. package/docs/api/tools/wp_get_application_passwords.md +103 -0
  183. package/docs/api/tools/wp_get_auth_status.md +101 -0
  184. package/docs/api/tools/wp_get_category.md +103 -0
  185. package/docs/api/tools/wp_get_comment.md +103 -0
  186. package/docs/api/tools/wp_get_current_user.md +101 -0
  187. package/docs/api/tools/wp_get_media.md +103 -0
  188. package/docs/api/tools/wp_get_page.md +103 -0
  189. package/docs/api/tools/wp_get_page_revisions.md +103 -0
  190. package/docs/api/tools/wp_get_post.md +112 -0
  191. package/docs/api/tools/wp_get_post_revisions.md +103 -0
  192. package/docs/api/tools/wp_get_site_settings.md +108 -0
  193. package/docs/api/tools/wp_get_tag.md +103 -0
  194. package/docs/api/tools/wp_get_user.md +103 -0
  195. package/docs/api/tools/wp_list_categories.md +111 -0
  196. package/docs/api/tools/wp_list_comments.md +111 -0
  197. package/docs/api/tools/wp_list_media.md +145 -0
  198. package/docs/api/tools/wp_list_pages.md +145 -0
  199. package/docs/api/tools/wp_list_posts.md +156 -0
  200. package/docs/api/tools/wp_list_tags.md +110 -0
  201. package/docs/api/tools/wp_list_users.md +111 -0
  202. package/docs/api/tools/wp_performance_alerts.md +162 -0
  203. package/docs/api/tools/wp_performance_benchmark.md +160 -0
  204. package/docs/api/tools/wp_performance_export.md +162 -0
  205. package/docs/api/tools/wp_performance_history.md +161 -0
  206. package/docs/api/tools/wp_performance_optimize.md +162 -0
  207. package/docs/api/tools/wp_performance_stats.md +160 -0
  208. package/docs/api/tools/wp_search_site.md +99 -0
  209. package/docs/api/tools/wp_spam_comment.md +98 -0
  210. package/docs/api/tools/wp_switch_auth_method.md +122 -0
  211. package/docs/api/tools/wp_test_auth.md +96 -0
  212. package/docs/api/tools/wp_update_category.md +102 -0
  213. package/docs/api/tools/wp_update_comment.md +127 -0
  214. package/docs/api/tools/wp_update_media.md +129 -0
  215. package/docs/api/tools/wp_update_page.md +135 -0
  216. package/docs/api/tools/wp_update_post.md +144 -0
  217. package/docs/api/tools/wp_update_site_settings.md +127 -0
  218. package/docs/api/tools/wp_update_tag.md +102 -0
  219. package/docs/api/tools/wp_update_user.md +134 -0
  220. package/docs/api/tools/wp_upload_media.md +131 -0
  221. package/docs/api/types/WordPressPost.md +39 -0
  222. package/docs/contract-testing.md +183 -0
  223. package/docs/developer/NPM_AUTH_SETUP.md +3 -3
  224. package/docs/wordpress-rest-api-authentication-troubleshooting.md +218 -0
  225. package/package.json +84 -64
  226. package/src/cache/CacheInvalidation.ts +421 -0
  227. package/src/cache/CacheManager.ts +391 -0
  228. package/src/cache/HttpCacheWrapper.ts +372 -0
  229. package/src/cache/__tests__/CacheInvalidation.test.ts +299 -0
  230. package/src/cache/__tests__/CacheManager.test.ts +300 -0
  231. package/src/cache/__tests__/CachedWordPressClient.test.ts +304 -0
  232. package/src/cache/__tests__/HttpCacheWrapper.test.ts +359 -0
  233. package/src/cache/index.ts +26 -0
  234. package/src/client/CachedWordPressClient.ts +442 -0
  235. package/src/config/ConfigurationSchema.ts +246 -0
  236. package/src/config/ServerConfiguration.ts +215 -0
  237. package/src/docs/DocumentationGenerator.ts +952 -0
  238. package/src/docs/MarkdownFormatter.ts +494 -0
  239. package/src/docs/index.ts +21 -0
  240. package/src/index.ts +14 -274
  241. package/src/performance/MetricsCollector.ts +447 -0
  242. package/src/performance/PerformanceAnalytics.ts +762 -0
  243. package/src/performance/PerformanceMonitor.ts +649 -0
  244. package/src/performance/index.ts +28 -0
  245. package/src/security/InputValidator.ts +319 -0
  246. package/src/security/SecurityConfig.ts +301 -0
  247. package/src/server/ConnectionTester.ts +74 -0
  248. package/src/server/ToolRegistry.ts +194 -0
  249. package/src/tools/BaseToolManager.ts +66 -0
  250. package/src/tools/cache.ts +259 -0
  251. package/src/tools/index.ts +2 -0
  252. package/src/tools/performance.ts +948 -0
  253. package/src/types/client.ts +1 -0
  254. package/src/utils/toolWrapper.ts +11 -0
  255. package/src/utils/validation.ts +259 -0
@@ -0,0 +1,447 @@
1
+ /**
2
+ * Real-time Metrics Collector for WordPress MCP Server
3
+ * Integrates with existing client and cache systems
4
+ */
5
+
6
+ import { PerformanceMonitor, PerformanceMetrics } from './PerformanceMonitor.js';
7
+ import type { CacheStats } from '../cache/CacheManager.js';
8
+ import type { ClientStats } from '../types/client.js';
9
+
10
+ export interface CollectorConfig {
11
+ enableRealTime: boolean;
12
+ collectInterval: number;
13
+ enableToolTracking: boolean;
14
+ enableRequestInterception: boolean;
15
+ enableCacheIntegration: boolean;
16
+ enableSystemMetrics: boolean;
17
+ }
18
+
19
+ export interface RequestMetadata {
20
+ toolName?: string;
21
+ siteId?: string;
22
+ endpoint: string;
23
+ method: string;
24
+ startTime: number;
25
+ fromCache: boolean;
26
+ }
27
+
28
+ export interface ToolExecutionContext {
29
+ toolName: string;
30
+ parameters: any;
31
+ startTime: number;
32
+ siteId: string | undefined;
33
+ }
34
+
35
+ /**
36
+ * Metrics Collector - Central hub for all performance data
37
+ */
38
+ export class MetricsCollector {
39
+ private monitor: PerformanceMonitor;
40
+ private config: CollectorConfig;
41
+ private activeRequests: Map<string, RequestMetadata> = new Map();
42
+ private activeTools: Map<string, ToolExecutionContext> = new Map();
43
+ private clientInstances: Map<string, any> = new Map();
44
+ private cacheManagers: Map<string, any> = new Map();
45
+
46
+ constructor(
47
+ monitor: PerformanceMonitor,
48
+ config: Partial<CollectorConfig> = {}
49
+ ) {
50
+ this.monitor = monitor;
51
+ this.config = {
52
+ enableRealTime: true,
53
+ collectInterval: 30000, // 30 seconds
54
+ enableToolTracking: true,
55
+ enableRequestInterception: true,
56
+ enableCacheIntegration: true,
57
+ enableSystemMetrics: true,
58
+ ...config
59
+ };
60
+
61
+ if (this.config.enableRealTime) {
62
+ this.startRealTimeCollection();
63
+ }
64
+ }
65
+
66
+ /**
67
+ * Register a WordPress client for monitoring
68
+ */
69
+ registerClient(siteId: string, client: any): void {
70
+ this.clientInstances.set(siteId, client);
71
+
72
+ if (this.config.enableRequestInterception) {
73
+ this.interceptClientRequests(siteId, client);
74
+ }
75
+ }
76
+
77
+ /**
78
+ * Register a cache manager for monitoring
79
+ */
80
+ registerCacheManager(siteId: string, cacheManager: any): void {
81
+ this.cacheManagers.set(siteId, cacheManager);
82
+ }
83
+
84
+ /**
85
+ * Start tracking a tool execution
86
+ */
87
+ startToolExecution(toolName: string, parameters: any, siteId?: string): string {
88
+ const executionId = `${toolName}-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;
89
+
90
+ this.activeTools.set(executionId, {
91
+ toolName,
92
+ parameters,
93
+ startTime: Date.now(),
94
+ siteId
95
+ });
96
+
97
+ return executionId;
98
+ }
99
+
100
+ /**
101
+ * End tool execution and record metrics
102
+ */
103
+ endToolExecution(executionId: string, success: boolean, error?: Error): void {
104
+ const context = this.activeTools.get(executionId);
105
+ if (!context) return;
106
+
107
+ const responseTime = Date.now() - context.startTime;
108
+
109
+ // Record in performance monitor
110
+ this.monitor.recordRequest(responseTime, success, context.toolName);
111
+
112
+ this.activeTools.delete(executionId);
113
+ }
114
+
115
+ /**
116
+ * Record a raw request (bypass tool tracking)
117
+ */
118
+ recordRawRequest(
119
+ responseTime: number,
120
+ success: boolean,
121
+ endpoint: string,
122
+ fromCache: boolean = false
123
+ ): void {
124
+ this.monitor.recordRequest(responseTime, success);
125
+ }
126
+
127
+ /**
128
+ * Collect current metrics from all sources
129
+ */
130
+ collectCurrentMetrics(): PerformanceMetrics {
131
+ // Update cache metrics from all registered cache managers
132
+ this.updateCacheMetrics();
133
+
134
+ // Update client metrics from all registered clients
135
+ this.updateClientMetrics();
136
+
137
+ // Get current metrics from monitor
138
+ return this.monitor.getMetrics();
139
+ }
140
+
141
+ /**
142
+ * Get aggregated cache statistics
143
+ */
144
+ getAggregatedCacheStats(): CacheStats {
145
+ const aggregated: CacheStats = {
146
+ hits: 0,
147
+ misses: 0,
148
+ evictions: 0,
149
+ totalSize: 0,
150
+ hitRate: 0
151
+ };
152
+
153
+ for (const [_siteId, cacheManager] of this.cacheManagers) {
154
+ if (cacheManager && typeof cacheManager.getStats === 'function') {
155
+ const stats = cacheManager.getStats();
156
+ aggregated.hits += stats.hits || 0;
157
+ aggregated.misses += stats.misses || 0;
158
+ aggregated.evictions += stats.evictions || 0;
159
+ aggregated.totalSize += stats.totalSize || 0;
160
+ }
161
+ }
162
+
163
+ // Calculate overall hit rate
164
+ const total = aggregated.hits + aggregated.misses;
165
+ aggregated.hitRate = total > 0 ? aggregated.hits / total : 0;
166
+
167
+ return aggregated;
168
+ }
169
+
170
+ /**
171
+ * Get aggregated client statistics
172
+ */
173
+ getAggregatedClientStats(): ClientStats {
174
+ const aggregated: ClientStats = {
175
+ totalRequests: 0,
176
+ successfulRequests: 0,
177
+ failedRequests: 0,
178
+ averageResponseTime: 0,
179
+ rateLimitHits: 0,
180
+ authFailures: 0
181
+ };
182
+
183
+ const responseTimes: number[] = [];
184
+
185
+ for (const [_siteId, client] of this.clientInstances) {
186
+ if (client && typeof client.getStats === 'function') {
187
+ const stats = client.getStats();
188
+ aggregated.totalRequests += stats.totalRequests || 0;
189
+ aggregated.successfulRequests += stats.successfulRequests || 0;
190
+ aggregated.failedRequests += stats.failedRequests || 0;
191
+ aggregated.rateLimitHits += stats.rateLimitHits || 0;
192
+ aggregated.authFailures += stats.authFailures || 0;
193
+
194
+ if (stats.averageResponseTime) {
195
+ responseTimes.push(stats.averageResponseTime);
196
+ }
197
+ }
198
+ }
199
+
200
+ // Calculate overall average response time
201
+ if (responseTimes.length > 0) {
202
+ aggregated.averageResponseTime = responseTimes.reduce((sum, time) => sum + time, 0) / responseTimes.length;
203
+ }
204
+
205
+ return aggregated;
206
+ }
207
+
208
+ /**
209
+ * Get performance summary for specific site
210
+ */
211
+ getSiteMetrics(siteId: string): {
212
+ cache?: CacheStats;
213
+ client?: ClientStats;
214
+ isActive: boolean;
215
+ } {
216
+ const result: any = { isActive: false };
217
+
218
+ const cacheManager = this.cacheManagers.get(siteId);
219
+ if (cacheManager && typeof cacheManager.getStats === 'function') {
220
+ result.cache = cacheManager.getStats();
221
+ result.isActive = true;
222
+ }
223
+
224
+ const client = this.clientInstances.get(siteId);
225
+ if (client && typeof client.getStats === 'function') {
226
+ result.client = client.getStats();
227
+ result.isActive = true;
228
+ }
229
+
230
+ return result;
231
+ }
232
+
233
+ /**
234
+ * Generate performance comparison between sites
235
+ */
236
+ compareSitePerformance(): {
237
+ sites: string[];
238
+ comparison: Record<string, {
239
+ responseTime: number;
240
+ cacheHitRate: number;
241
+ errorRate: number;
242
+ requestCount: number;
243
+ ranking: number;
244
+ }>;
245
+ bestPerforming: string;
246
+ worstPerforming: string;
247
+ } {
248
+ const sites = Array.from(this.clientInstances.keys());
249
+ const comparison: any = {};
250
+ const rankings: Array<{ site: string; score: number }> = [];
251
+
252
+ for (const siteId of sites) {
253
+ const metrics = this.getSiteMetrics(siteId);
254
+
255
+ const responseTime = metrics.client?.averageResponseTime || 0;
256
+ const cacheHitRate = metrics.cache?.hitRate || 0;
257
+ const errorRate = metrics.client
258
+ ? (metrics.client.failedRequests / Math.max(metrics.client.totalRequests, 1))
259
+ : 0;
260
+ const requestCount = metrics.client?.totalRequests || 0;
261
+
262
+ // Calculate performance score (lower is better for response time and error rate)
263
+ const score = (responseTime / 1000) + (errorRate * 100) - (cacheHitRate * 50) + (requestCount * 0.001);
264
+
265
+ comparison[siteId] = {
266
+ responseTime,
267
+ cacheHitRate,
268
+ errorRate,
269
+ requestCount,
270
+ ranking: 0 // Will be set after sorting
271
+ };
272
+
273
+ rankings.push({ site: siteId, score });
274
+ }
275
+
276
+ // Sort by performance score
277
+ rankings.sort((a, b) => a.score - b.score);
278
+
279
+ // Assign rankings
280
+ rankings.forEach((item, index) => {
281
+ comparison[item.site].ranking = index + 1;
282
+ });
283
+
284
+ return {
285
+ sites,
286
+ comparison,
287
+ bestPerforming: rankings[0]?.site || '',
288
+ worstPerforming: rankings[rankings.length - 1]?.site || ''
289
+ };
290
+ }
291
+
292
+ /**
293
+ * Generate optimization suggestions
294
+ */
295
+ generateOptimizationSuggestions(): {
296
+ critical: string[];
297
+ recommended: string[];
298
+ optional: string[];
299
+ } {
300
+ const metrics = this.collectCurrentMetrics();
301
+ const critical: string[] = [];
302
+ const recommended: string[] = [];
303
+ const optional: string[] = [];
304
+
305
+ // Critical issues
306
+ if (metrics.requests.averageResponseTime > 5000) {
307
+ critical.push('Response times are critically high (>5s). Enable caching immediately.');
308
+ }
309
+
310
+ const errorRate = metrics.requests.failed / Math.max(metrics.requests.total, 1);
311
+ if (errorRate > 0.1) {
312
+ critical.push('Error rate is critically high (>10%). Check WordPress connectivity.');
313
+ }
314
+
315
+ // Recommended optimizations
316
+ if (metrics.cache.hitRate < 0.8) {
317
+ recommended.push('Cache hit rate is below 80%. Consider cache warming or TTL adjustment.');
318
+ }
319
+
320
+ if (metrics.requests.averageResponseTime > 2000) {
321
+ recommended.push('Response times could be improved. Consider enabling more aggressive caching.');
322
+ }
323
+
324
+ if (metrics.system.memoryUsage > 80) {
325
+ recommended.push('Memory usage is high. Consider increasing cache size limits or server resources.');
326
+ }
327
+
328
+ // Optional optimizations
329
+ if (metrics.cache.totalSize < 100) {
330
+ optional.push('Cache utilization is low. Consider pre-warming with frequently accessed data.');
331
+ }
332
+
333
+ if (Object.keys(metrics.tools.toolUsageCount).length > 10) {
334
+ optional.push('Many tools are being used. Consider creating custom workflows for common operations.');
335
+ }
336
+
337
+ return { critical, recommended, optional };
338
+ }
339
+
340
+ /**
341
+ * Export detailed performance report
342
+ */
343
+ exportDetailedReport(): {
344
+ timestamp: string;
345
+ overview: PerformanceMetrics;
346
+ siteComparison: any;
347
+ aggregatedStats: {
348
+ cache: CacheStats;
349
+ client: ClientStats;
350
+ };
351
+ optimizations: any;
352
+ alerts: any[];
353
+ } {
354
+ return {
355
+ timestamp: new Date().toISOString(),
356
+ overview: this.collectCurrentMetrics(),
357
+ siteComparison: this.compareSitePerformance(),
358
+ aggregatedStats: {
359
+ cache: this.getAggregatedCacheStats(),
360
+ client: this.getAggregatedClientStats()
361
+ },
362
+ optimizations: this.generateOptimizationSuggestions(),
363
+ alerts: this.monitor.getAlerts()
364
+ };
365
+ }
366
+
367
+ /**
368
+ * Start real-time metric collection
369
+ */
370
+ private startRealTimeCollection(): void {
371
+ setInterval(() => {
372
+ this.updateCacheMetrics();
373
+ this.updateClientMetrics();
374
+ }, this.config.collectInterval);
375
+ }
376
+
377
+ /**
378
+ * Update cache metrics in performance monitor
379
+ */
380
+ private updateCacheMetrics(): void {
381
+ const aggregatedStats = this.getAggregatedCacheStats();
382
+ this.monitor.updateCacheMetrics(aggregatedStats);
383
+ }
384
+
385
+ /**
386
+ * Update client metrics in performance monitor
387
+ */
388
+ private updateClientMetrics(): void {
389
+ // Client metrics are updated through request interception
390
+ // This method can be used for additional client-specific metrics
391
+ }
392
+
393
+ /**
394
+ * Intercept client requests for automatic tracking
395
+ */
396
+ private interceptClientRequests(siteId: string, client: any): void {
397
+ if (!client.request || typeof client.request !== 'function') {
398
+ return;
399
+ }
400
+
401
+ const originalRequest = client.request.bind(client);
402
+
403
+ client.request = async (...args: any[]) => {
404
+ const startTime = Date.now();
405
+ const requestId = `${siteId}-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;
406
+
407
+ // Extract metadata
408
+ const metadata: RequestMetadata = {
409
+ siteId,
410
+ endpoint: args[0] || 'unknown',
411
+ method: args[1] || 'GET',
412
+ startTime,
413
+ fromCache: false
414
+ };
415
+
416
+ this.activeRequests.set(requestId, metadata);
417
+
418
+ try {
419
+ const result = await originalRequest(...args);
420
+ const responseTime = Date.now() - startTime;
421
+
422
+ // Check if response came from cache
423
+ const _fromCache = result.cached || false;
424
+
425
+ this.monitor.recordRequest(responseTime, true);
426
+ this.activeRequests.delete(requestId);
427
+
428
+ return result;
429
+ } catch (error) {
430
+ const responseTime = Date.now() - startTime;
431
+ this.monitor.recordRequest(responseTime, false);
432
+ this.activeRequests.delete(requestId);
433
+
434
+ throw error;
435
+ }
436
+ };
437
+ }
438
+
439
+ /**
440
+ * Stop all monitoring and cleanup
441
+ */
442
+ stop(): void {
443
+ this.monitor.stop();
444
+ this.activeRequests.clear();
445
+ this.activeTools.clear();
446
+ }
447
+ }