myaidev-method 0.0.8 → 0.2.0
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.
- package/.env.example +20 -0
- package/COOLIFY_DEPLOYMENT.md +750 -0
- package/PUBLISHING_GUIDE.md +521 -0
- package/README.md +125 -27
- package/WORDPRESS_ADMIN_SCRIPTS.md +474 -0
- package/package.json +36 -3
- package/src/lib/coolify-utils.js +380 -0
- package/src/lib/payloadcms-utils.js +394 -0
- package/src/lib/report-synthesizer.js +504 -0
- package/src/lib/static-site-utils.js +377 -0
- package/src/lib/wordpress-admin-utils.js +703 -0
- package/src/scripts/astro-publish.js +209 -0
- package/src/scripts/coolify-deploy-app.js +287 -0
- package/src/scripts/coolify-list-resources.js +199 -0
- package/src/scripts/coolify-status.js +97 -0
- package/src/scripts/docusaurus-publish.js +209 -0
- package/src/scripts/init-project.js +91 -0
- package/src/scripts/mintlify-publish.js +205 -0
- package/src/scripts/payloadcms-publish.js +202 -0
- package/src/scripts/test-coolify-deploy.js +47 -0
- package/src/scripts/wordpress-comprehensive-report.js +325 -0
- package/src/scripts/wordpress-health-check.js +175 -0
- package/src/scripts/wordpress-performance-check.js +461 -0
- package/src/scripts/wordpress-security-scan.js +221 -0
- package/src/templates/claude/agents/astro-publish.md +43 -0
- package/src/templates/claude/agents/coolify-deploy.md +563 -0
- package/src/templates/claude/agents/docusaurus-publish.md +42 -0
- package/src/templates/claude/agents/mintlify-publish.md +42 -0
- package/src/templates/claude/agents/payloadcms-publish.md +134 -0
- package/src/templates/claude/commands/myai-astro-publish.md +54 -0
- package/src/templates/claude/commands/myai-coolify-deploy.md +172 -0
- package/src/templates/claude/commands/myai-docusaurus-publish.md +45 -0
- package/src/templates/claude/commands/myai-mintlify-publish.md +45 -0
- package/src/templates/claude/commands/myai-payloadcms-publish.md +45 -0
|
@@ -0,0 +1,175 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* WordPress Health Check Script
|
|
5
|
+
* Scriptable health check with JSON output for agent processing
|
|
6
|
+
*
|
|
7
|
+
* Usage:
|
|
8
|
+
* npx myaidev-method wordpress:health-check [options]
|
|
9
|
+
* node src/scripts/wordpress-health-check.js [options]
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
import { WordPressAdminUtils } from '../lib/wordpress-admin-utils.js';
|
|
13
|
+
import { writeFileSync } from 'fs';
|
|
14
|
+
import { resolve } from 'path';
|
|
15
|
+
|
|
16
|
+
const args = process.argv.slice(2);
|
|
17
|
+
|
|
18
|
+
const options = {
|
|
19
|
+
format: 'json', // json or text
|
|
20
|
+
output: null, // file path for output
|
|
21
|
+
verbose: false
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
// Parse arguments
|
|
25
|
+
for (let i = 0; i < args.length; i++) {
|
|
26
|
+
switch (args[i]) {
|
|
27
|
+
case '--format':
|
|
28
|
+
options.format = args[++i] || 'json';
|
|
29
|
+
break;
|
|
30
|
+
case '--output':
|
|
31
|
+
case '-o':
|
|
32
|
+
options.output = args[++i];
|
|
33
|
+
break;
|
|
34
|
+
case '--verbose':
|
|
35
|
+
case '-v':
|
|
36
|
+
options.verbose = true;
|
|
37
|
+
break;
|
|
38
|
+
case '--help':
|
|
39
|
+
case '-h':
|
|
40
|
+
printHelp();
|
|
41
|
+
process.exit(0);
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
function printHelp() {
|
|
46
|
+
console.log(`
|
|
47
|
+
WordPress Health Check Script
|
|
48
|
+
|
|
49
|
+
Usage:
|
|
50
|
+
npx myaidev-method wordpress:health-check [options]
|
|
51
|
+
|
|
52
|
+
Options:
|
|
53
|
+
--format <type> Output format: json or text (default: json)
|
|
54
|
+
--output <file> Write output to file
|
|
55
|
+
-o <file> Alias for --output
|
|
56
|
+
--verbose Show detailed progress information
|
|
57
|
+
-v Alias for --verbose
|
|
58
|
+
--help Show this help message
|
|
59
|
+
-h Alias for --help
|
|
60
|
+
|
|
61
|
+
Environment Variables (from .env):
|
|
62
|
+
WORDPRESS_URL WordPress site URL
|
|
63
|
+
WORDPRESS_USERNAME Admin username
|
|
64
|
+
WORDPRESS_APP_PASSWORD Application password
|
|
65
|
+
|
|
66
|
+
Examples:
|
|
67
|
+
# Run health check with JSON output
|
|
68
|
+
npx myaidev-method wordpress:health-check
|
|
69
|
+
|
|
70
|
+
# Save JSON report to file
|
|
71
|
+
npx myaidev-method wordpress:health-check --output health-report.json
|
|
72
|
+
|
|
73
|
+
# Display human-readable text report
|
|
74
|
+
npx myaidev-method wordpress:health-check --format text
|
|
75
|
+
|
|
76
|
+
# Verbose mode with detailed progress
|
|
77
|
+
npx myaidev-method wordpress:health-check --verbose
|
|
78
|
+
|
|
79
|
+
Output Structure (JSON):
|
|
80
|
+
{
|
|
81
|
+
"success": true,
|
|
82
|
+
"timestamp": "2025-10-01T12:00:00.000Z",
|
|
83
|
+
"site": { "name": "...", "url": "..." },
|
|
84
|
+
"overall_health": {
|
|
85
|
+
"score": 85,
|
|
86
|
+
"grade": "B",
|
|
87
|
+
"status": "healthy"
|
|
88
|
+
},
|
|
89
|
+
"checks": [...],
|
|
90
|
+
"summary": { "total_checks": 5, "passed": 4, "warnings": 1 },
|
|
91
|
+
"recommendations": [...]
|
|
92
|
+
}
|
|
93
|
+
`);
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
async function runHealthCheck() {
|
|
97
|
+
try {
|
|
98
|
+
if (options.verbose) {
|
|
99
|
+
console.error('Initializing WordPress connection...');
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
const wpUtils = new WordPressAdminUtils();
|
|
103
|
+
|
|
104
|
+
if (options.verbose) {
|
|
105
|
+
console.error('Running health checks...');
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
const healthData = await wpUtils.runHealthCheck();
|
|
109
|
+
|
|
110
|
+
if (options.verbose) {
|
|
111
|
+
console.error('Health check completed.');
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
// Format output
|
|
115
|
+
let output;
|
|
116
|
+
if (options.format === 'text') {
|
|
117
|
+
output = wpUtils.formatHealthReport(healthData);
|
|
118
|
+
} else {
|
|
119
|
+
output = JSON.stringify(healthData, null, 2);
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
// Write to file or stdout
|
|
123
|
+
if (options.output) {
|
|
124
|
+
const outputPath = resolve(options.output);
|
|
125
|
+
writeFileSync(outputPath, output, 'utf8');
|
|
126
|
+
|
|
127
|
+
if (options.verbose) {
|
|
128
|
+
console.error(`Report written to: ${outputPath}`);
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
// Also output summary to stdout for piping
|
|
132
|
+
console.log(JSON.stringify({
|
|
133
|
+
success: true,
|
|
134
|
+
output_file: outputPath,
|
|
135
|
+
health_score: healthData.overall_health?.score,
|
|
136
|
+
health_grade: healthData.overall_health?.grade
|
|
137
|
+
}));
|
|
138
|
+
} else {
|
|
139
|
+
console.log(output);
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
// Exit with appropriate code
|
|
143
|
+
if (!healthData.success) {
|
|
144
|
+
process.exit(1);
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
const criticalIssues = healthData.checks?.filter(c => c.status === 'critical').length || 0;
|
|
148
|
+
if (criticalIssues > 0) {
|
|
149
|
+
process.exit(2); // Critical issues found
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
process.exit(0);
|
|
153
|
+
} catch (error) {
|
|
154
|
+
const errorOutput = {
|
|
155
|
+
success: false,
|
|
156
|
+
error: error.message,
|
|
157
|
+
timestamp: new Date().toISOString()
|
|
158
|
+
};
|
|
159
|
+
|
|
160
|
+
if (options.format === 'json') {
|
|
161
|
+
console.log(JSON.stringify(errorOutput, null, 2));
|
|
162
|
+
} else {
|
|
163
|
+
console.error(`ERROR: ${error.message}`);
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
process.exit(1);
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
// Run if called directly
|
|
171
|
+
if (import.meta.url === `file://${process.argv[1]}`) {
|
|
172
|
+
runHealthCheck();
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
export { runHealthCheck };
|
|
@@ -0,0 +1,461 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* WordPress Performance Analysis Script
|
|
5
|
+
* Scriptable performance check with JSON output for agent processing
|
|
6
|
+
*
|
|
7
|
+
* Usage:
|
|
8
|
+
* npx myaidev-method wordpress:performance-check [options]
|
|
9
|
+
* node src/scripts/wordpress-performance-check.js [options]
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
import { WordPressAdminUtils } from '../lib/wordpress-admin-utils.js';
|
|
13
|
+
import { writeFileSync } from 'fs';
|
|
14
|
+
import { resolve } from 'path';
|
|
15
|
+
|
|
16
|
+
const args = process.argv.slice(2);
|
|
17
|
+
|
|
18
|
+
const options = {
|
|
19
|
+
format: 'json', // json or text
|
|
20
|
+
output: null, // file path for output
|
|
21
|
+
verbose: false,
|
|
22
|
+
iterations: 3 // Number of iterations for timing measurements
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
// Parse arguments
|
|
26
|
+
for (let i = 0; i < args.length; i++) {
|
|
27
|
+
switch (args[i]) {
|
|
28
|
+
case '--format':
|
|
29
|
+
options.format = args[++i] || 'json';
|
|
30
|
+
break;
|
|
31
|
+
case '--output':
|
|
32
|
+
case '-o':
|
|
33
|
+
options.output = args[++i];
|
|
34
|
+
break;
|
|
35
|
+
case '--verbose':
|
|
36
|
+
case '-v':
|
|
37
|
+
options.verbose = true;
|
|
38
|
+
break;
|
|
39
|
+
case '--iterations':
|
|
40
|
+
case '-i':
|
|
41
|
+
options.iterations = parseInt(args[++i]) || 3;
|
|
42
|
+
break;
|
|
43
|
+
case '--help':
|
|
44
|
+
case '-h':
|
|
45
|
+
printHelp();
|
|
46
|
+
process.exit(0);
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
function printHelp() {
|
|
51
|
+
console.log(`
|
|
52
|
+
WordPress Performance Analysis Script
|
|
53
|
+
|
|
54
|
+
Usage:
|
|
55
|
+
npx myaidev-method wordpress:performance-check [options]
|
|
56
|
+
|
|
57
|
+
Options:
|
|
58
|
+
--format <type> Output format: json or text (default: json)
|
|
59
|
+
--output <file> Write output to file
|
|
60
|
+
-o <file> Alias for --output
|
|
61
|
+
--verbose Show detailed progress information
|
|
62
|
+
-v Alias for --verbose
|
|
63
|
+
--iterations <n> Number of timing test iterations (default: 3)
|
|
64
|
+
-i <n> Alias for --iterations
|
|
65
|
+
--help Show this help message
|
|
66
|
+
-h Alias for --help
|
|
67
|
+
|
|
68
|
+
Environment Variables (from .env):
|
|
69
|
+
WORDPRESS_URL WordPress site URL
|
|
70
|
+
WORDPRESS_USERNAME Admin username
|
|
71
|
+
WORDPRESS_APP_PASSWORD Application password
|
|
72
|
+
|
|
73
|
+
Performance Checks:
|
|
74
|
+
✓ API response time measurement
|
|
75
|
+
✓ Database content analysis
|
|
76
|
+
✓ Media file optimization opportunities
|
|
77
|
+
✓ Plugin performance impact
|
|
78
|
+
✓ Resource usage patterns
|
|
79
|
+
|
|
80
|
+
Examples:
|
|
81
|
+
# Run performance check with JSON output
|
|
82
|
+
npx myaidev-method wordpress:performance-check
|
|
83
|
+
|
|
84
|
+
# Save performance report to file
|
|
85
|
+
npx myaidev-method wordpress:performance-check --output perf-report.json
|
|
86
|
+
|
|
87
|
+
# Display human-readable text report
|
|
88
|
+
npx myaidev-method wordpress:performance-check --format text
|
|
89
|
+
|
|
90
|
+
# Run 5 timing iterations for more accurate measurements
|
|
91
|
+
npx myaidev-method wordpress:performance-check --iterations 5 --verbose
|
|
92
|
+
|
|
93
|
+
Output Structure (JSON):
|
|
94
|
+
{
|
|
95
|
+
"success": true,
|
|
96
|
+
"timestamp": "2025-10-01T12:00:00.000Z",
|
|
97
|
+
"site": { "name": "...", "url": "..." },
|
|
98
|
+
"performance_score": 85,
|
|
99
|
+
"metrics": {
|
|
100
|
+
"api_response_time_ms": 250,
|
|
101
|
+
"post_count": 150,
|
|
102
|
+
"media_count": 400,
|
|
103
|
+
"plugin_count": 15,
|
|
104
|
+
"active_plugins": 12
|
|
105
|
+
},
|
|
106
|
+
"analysis": {...},
|
|
107
|
+
"recommendations": [...]
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
Exit Codes:
|
|
111
|
+
0 - No performance issues
|
|
112
|
+
1 - Check error occurred
|
|
113
|
+
2 - Performance warnings
|
|
114
|
+
`);
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
async function measureResponseTime(wpUtils, iterations) {
|
|
118
|
+
const measurements = [];
|
|
119
|
+
|
|
120
|
+
for (let i = 0; i < iterations; i++) {
|
|
121
|
+
const start = Date.now();
|
|
122
|
+
try {
|
|
123
|
+
await wpUtils.request('/');
|
|
124
|
+
const duration = Date.now() - start;
|
|
125
|
+
measurements.push(duration);
|
|
126
|
+
} catch (error) {
|
|
127
|
+
// Skip failed measurements
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
// Small delay between iterations
|
|
131
|
+
if (i < iterations - 1) {
|
|
132
|
+
await new Promise(resolve => setTimeout(resolve, 100));
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
if (measurements.length === 0) {
|
|
137
|
+
return null;
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
// Calculate statistics
|
|
141
|
+
const avg = measurements.reduce((a, b) => a + b, 0) / measurements.length;
|
|
142
|
+
const sorted = measurements.sort((a, b) => a - b);
|
|
143
|
+
const median = sorted[Math.floor(sorted.length / 2)];
|
|
144
|
+
const min = sorted[0];
|
|
145
|
+
const max = sorted[sorted.length - 1];
|
|
146
|
+
|
|
147
|
+
return {
|
|
148
|
+
average: Math.round(avg),
|
|
149
|
+
median: Math.round(median),
|
|
150
|
+
min,
|
|
151
|
+
max,
|
|
152
|
+
measurements
|
|
153
|
+
};
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
function analyzePerformance(metrics, timing) {
|
|
157
|
+
const analysis = {
|
|
158
|
+
api_performance: { status: 'good', message: '' },
|
|
159
|
+
content_volume: { status: 'good', message: '' },
|
|
160
|
+
media_optimization: { status: 'good', message: '' },
|
|
161
|
+
plugin_impact: { status: 'good', message: '' }
|
|
162
|
+
};
|
|
163
|
+
|
|
164
|
+
// API performance
|
|
165
|
+
if (timing && timing.average > 1000) {
|
|
166
|
+
analysis.api_performance = {
|
|
167
|
+
status: 'critical',
|
|
168
|
+
message: `Slow API response time: ${timing.average}ms (target: <500ms)`
|
|
169
|
+
};
|
|
170
|
+
} else if (timing && timing.average > 500) {
|
|
171
|
+
analysis.api_performance = {
|
|
172
|
+
status: 'warning',
|
|
173
|
+
message: `Moderate API response time: ${timing.average}ms (target: <500ms)`
|
|
174
|
+
};
|
|
175
|
+
} else if (timing) {
|
|
176
|
+
analysis.api_performance = {
|
|
177
|
+
status: 'good',
|
|
178
|
+
message: `Good API response time: ${timing.average}ms`
|
|
179
|
+
};
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
// Content volume
|
|
183
|
+
const totalContent = metrics.post_count + metrics.media_count;
|
|
184
|
+
if (totalContent > 10000) {
|
|
185
|
+
analysis.content_volume = {
|
|
186
|
+
status: 'warning',
|
|
187
|
+
message: `High content volume: ${totalContent} items (consider archiving strategy)`
|
|
188
|
+
};
|
|
189
|
+
} else {
|
|
190
|
+
analysis.content_volume = {
|
|
191
|
+
status: 'good',
|
|
192
|
+
message: `Content volume: ${totalContent} items`
|
|
193
|
+
};
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
// Media optimization
|
|
197
|
+
if (metrics.media_count > 1000) {
|
|
198
|
+
analysis.media_optimization = {
|
|
199
|
+
status: 'warning',
|
|
200
|
+
message: `Large media library: ${metrics.media_count} files (consider CDN and optimization)`
|
|
201
|
+
};
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
// Plugin impact
|
|
205
|
+
if (metrics.active_plugins > 20) {
|
|
206
|
+
analysis.plugin_impact = {
|
|
207
|
+
status: 'warning',
|
|
208
|
+
message: `Many active plugins: ${metrics.active_plugins} (each adds overhead)`
|
|
209
|
+
};
|
|
210
|
+
} else if (metrics.active_plugins > 30) {
|
|
211
|
+
analysis.plugin_impact = {
|
|
212
|
+
status: 'critical',
|
|
213
|
+
message: `Excessive active plugins: ${metrics.active_plugins} (significant performance impact)`
|
|
214
|
+
};
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
return analysis;
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
function generateRecommendations(analysis, metrics) {
|
|
221
|
+
const recommendations = [];
|
|
222
|
+
|
|
223
|
+
if (analysis.api_performance.status !== 'good') {
|
|
224
|
+
recommendations.push({
|
|
225
|
+
priority: 'high',
|
|
226
|
+
area: 'API Performance',
|
|
227
|
+
action: 'Implement page caching and object caching',
|
|
228
|
+
impact: 'Reduce API response time by 50-80%'
|
|
229
|
+
});
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
if (analysis.plugin_impact.status !== 'good') {
|
|
233
|
+
recommendations.push({
|
|
234
|
+
priority: 'medium',
|
|
235
|
+
area: 'Plugin Optimization',
|
|
236
|
+
action: 'Audit and deactivate unused plugins',
|
|
237
|
+
impact: 'Reduce overhead and improve load times'
|
|
238
|
+
});
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
if (analysis.media_optimization.status !== 'good') {
|
|
242
|
+
recommendations.push({
|
|
243
|
+
priority: 'medium',
|
|
244
|
+
area: 'Media Optimization',
|
|
245
|
+
action: 'Implement image optimization and lazy loading',
|
|
246
|
+
impact: 'Reduce bandwidth usage and improve page speed'
|
|
247
|
+
});
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
if (metrics.post_count > 1000) {
|
|
251
|
+
recommendations.push({
|
|
252
|
+
priority: 'low',
|
|
253
|
+
area: 'Database Optimization',
|
|
254
|
+
action: 'Schedule regular database cleanup and optimization',
|
|
255
|
+
impact: 'Maintain query performance over time'
|
|
256
|
+
});
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
return recommendations;
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
function calculatePerformanceScore(analysis, timing) {
|
|
263
|
+
let score = 100;
|
|
264
|
+
|
|
265
|
+
// API performance impact (0-30 points)
|
|
266
|
+
if (timing) {
|
|
267
|
+
if (timing.average > 1000) {
|
|
268
|
+
score -= 30;
|
|
269
|
+
} else if (timing.average > 500) {
|
|
270
|
+
score -= 15;
|
|
271
|
+
} else if (timing.average > 300) {
|
|
272
|
+
score -= 5;
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
// Plugin impact (0-20 points)
|
|
277
|
+
if (analysis.plugin_impact.status === 'critical') {
|
|
278
|
+
score -= 20;
|
|
279
|
+
} else if (analysis.plugin_impact.status === 'warning') {
|
|
280
|
+
score -= 10;
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
// Media optimization (0-15 points)
|
|
284
|
+
if (analysis.media_optimization.status === 'warning') {
|
|
285
|
+
score -= 10;
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
// Content volume (0-10 points)
|
|
289
|
+
if (analysis.content_volume.status === 'warning') {
|
|
290
|
+
score -= 10;
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
return Math.max(0, score);
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
function formatPerformanceReport(perfData) {
|
|
297
|
+
if (!perfData.success) {
|
|
298
|
+
return `ERROR: ${perfData.error}`;
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
const lines = [];
|
|
302
|
+
lines.push('='.repeat(60));
|
|
303
|
+
lines.push('WordPress Performance Analysis Report');
|
|
304
|
+
lines.push('='.repeat(60));
|
|
305
|
+
lines.push(`Site: ${perfData.site.name || perfData.site.url}`);
|
|
306
|
+
lines.push(`Timestamp: ${perfData.timestamp}`);
|
|
307
|
+
lines.push('');
|
|
308
|
+
lines.push(`Performance Score: ${perfData.performance_score}/100`);
|
|
309
|
+
lines.push('');
|
|
310
|
+
|
|
311
|
+
if (perfData.timing) {
|
|
312
|
+
lines.push('API Response Time:');
|
|
313
|
+
lines.push(` Average: ${perfData.timing.average}ms`);
|
|
314
|
+
lines.push(` Median: ${perfData.timing.median}ms`);
|
|
315
|
+
lines.push(` Range: ${perfData.timing.min}ms - ${perfData.timing.max}ms`);
|
|
316
|
+
lines.push('');
|
|
317
|
+
}
|
|
318
|
+
|
|
319
|
+
lines.push('Performance Metrics:');
|
|
320
|
+
lines.push('-'.repeat(60));
|
|
321
|
+
lines.push(`Posts: ${perfData.metrics.post_count}`);
|
|
322
|
+
lines.push(`Media Files: ${perfData.metrics.media_count}`);
|
|
323
|
+
lines.push(`Plugins: ${perfData.metrics.plugin_count} (${perfData.metrics.active_plugins} active)`);
|
|
324
|
+
lines.push('');
|
|
325
|
+
|
|
326
|
+
lines.push('Performance Analysis:');
|
|
327
|
+
lines.push('-'.repeat(60));
|
|
328
|
+
Object.entries(perfData.analysis).forEach(([key, value]) => {
|
|
329
|
+
const statusIcon = {
|
|
330
|
+
good: '✓',
|
|
331
|
+
warning: '⚠',
|
|
332
|
+
critical: '✗'
|
|
333
|
+
}[value.status] || '?';
|
|
334
|
+
|
|
335
|
+
lines.push(`${statusIcon} ${key}: ${value.message}`);
|
|
336
|
+
});
|
|
337
|
+
|
|
338
|
+
if (perfData.recommendations.length > 0) {
|
|
339
|
+
lines.push('');
|
|
340
|
+
lines.push('Recommendations:');
|
|
341
|
+
lines.push('-'.repeat(60));
|
|
342
|
+
perfData.recommendations.forEach((rec, i) => {
|
|
343
|
+
lines.push(`${i + 1}. [${rec.priority.toUpperCase()}] ${rec.area}`);
|
|
344
|
+
lines.push(` Action: ${rec.action}`);
|
|
345
|
+
lines.push(` Impact: ${rec.impact}`);
|
|
346
|
+
});
|
|
347
|
+
}
|
|
348
|
+
|
|
349
|
+
lines.push('');
|
|
350
|
+
lines.push('='.repeat(60));
|
|
351
|
+
|
|
352
|
+
return lines.join('\n');
|
|
353
|
+
}
|
|
354
|
+
|
|
355
|
+
async function runPerformanceCheck() {
|
|
356
|
+
try {
|
|
357
|
+
if (options.verbose) {
|
|
358
|
+
console.error('Initializing WordPress connection...');
|
|
359
|
+
}
|
|
360
|
+
|
|
361
|
+
const wpUtils = new WordPressAdminUtils();
|
|
362
|
+
|
|
363
|
+
if (options.verbose) {
|
|
364
|
+
console.error(`Running performance tests (${options.iterations} iterations)...`);
|
|
365
|
+
}
|
|
366
|
+
|
|
367
|
+
// Measure response time
|
|
368
|
+
const timing = await measureResponseTime(wpUtils, options.iterations);
|
|
369
|
+
|
|
370
|
+
if (options.verbose) {
|
|
371
|
+
console.error('Collecting performance metrics...');
|
|
372
|
+
}
|
|
373
|
+
|
|
374
|
+
// Get performance metrics
|
|
375
|
+
const metrics = await wpUtils.getPerformanceMetrics();
|
|
376
|
+
|
|
377
|
+
if (options.verbose) {
|
|
378
|
+
console.error('Analyzing performance data...');
|
|
379
|
+
}
|
|
380
|
+
|
|
381
|
+
// Analyze results
|
|
382
|
+
const analysis = analyzePerformance(metrics, timing);
|
|
383
|
+
const recommendations = generateRecommendations(analysis, metrics);
|
|
384
|
+
const performanceScore = calculatePerformanceScore(analysis, timing);
|
|
385
|
+
|
|
386
|
+
const siteInfo = await wpUtils.getSiteInfo().catch(() => ({ url: wpUtils.url }));
|
|
387
|
+
|
|
388
|
+
const perfData = {
|
|
389
|
+
success: true,
|
|
390
|
+
timestamp: new Date().toISOString(),
|
|
391
|
+
site: siteInfo,
|
|
392
|
+
performance_score: performanceScore,
|
|
393
|
+
timing,
|
|
394
|
+
metrics,
|
|
395
|
+
analysis,
|
|
396
|
+
recommendations
|
|
397
|
+
};
|
|
398
|
+
|
|
399
|
+
if (options.verbose) {
|
|
400
|
+
console.error('Performance analysis completed.');
|
|
401
|
+
}
|
|
402
|
+
|
|
403
|
+
// Format output
|
|
404
|
+
let output;
|
|
405
|
+
if (options.format === 'text') {
|
|
406
|
+
output = formatPerformanceReport(perfData);
|
|
407
|
+
} else {
|
|
408
|
+
output = JSON.stringify(perfData, null, 2);
|
|
409
|
+
}
|
|
410
|
+
|
|
411
|
+
// Write to file or stdout
|
|
412
|
+
if (options.output) {
|
|
413
|
+
const outputPath = resolve(options.output);
|
|
414
|
+
writeFileSync(outputPath, output, 'utf8');
|
|
415
|
+
|
|
416
|
+
if (options.verbose) {
|
|
417
|
+
console.error(`Report written to: ${outputPath}`);
|
|
418
|
+
}
|
|
419
|
+
|
|
420
|
+
// Also output summary to stdout for piping
|
|
421
|
+
console.log(JSON.stringify({
|
|
422
|
+
success: true,
|
|
423
|
+
output_file: outputPath,
|
|
424
|
+
performance_score: perfData.performance_score,
|
|
425
|
+
avg_response_time: timing?.average
|
|
426
|
+
}));
|
|
427
|
+
} else {
|
|
428
|
+
console.log(output);
|
|
429
|
+
}
|
|
430
|
+
|
|
431
|
+
// Exit with appropriate code
|
|
432
|
+
const hasWarnings = Object.values(analysis).some(a => a.status === 'warning' || a.status === 'critical');
|
|
433
|
+
|
|
434
|
+
if (hasWarnings) {
|
|
435
|
+
process.exit(2); // Performance warnings
|
|
436
|
+
}
|
|
437
|
+
|
|
438
|
+
process.exit(0);
|
|
439
|
+
} catch (error) {
|
|
440
|
+
const errorOutput = {
|
|
441
|
+
success: false,
|
|
442
|
+
error: error.message,
|
|
443
|
+
timestamp: new Date().toISOString()
|
|
444
|
+
};
|
|
445
|
+
|
|
446
|
+
if (options.format === 'json') {
|
|
447
|
+
console.log(JSON.stringify(errorOutput, null, 2));
|
|
448
|
+
} else {
|
|
449
|
+
console.error(`ERROR: ${error.message}`);
|
|
450
|
+
}
|
|
451
|
+
|
|
452
|
+
process.exit(1);
|
|
453
|
+
}
|
|
454
|
+
}
|
|
455
|
+
|
|
456
|
+
// Run if called directly
|
|
457
|
+
if (import.meta.url === `file://${process.argv[1]}`) {
|
|
458
|
+
runPerformanceCheck();
|
|
459
|
+
}
|
|
460
|
+
|
|
461
|
+
export { runPerformanceCheck };
|