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.
Files changed (34) hide show
  1. package/.env.example +20 -0
  2. package/COOLIFY_DEPLOYMENT.md +750 -0
  3. package/PUBLISHING_GUIDE.md +521 -0
  4. package/README.md +125 -27
  5. package/WORDPRESS_ADMIN_SCRIPTS.md +474 -0
  6. package/package.json +36 -3
  7. package/src/lib/coolify-utils.js +380 -0
  8. package/src/lib/payloadcms-utils.js +394 -0
  9. package/src/lib/report-synthesizer.js +504 -0
  10. package/src/lib/static-site-utils.js +377 -0
  11. package/src/lib/wordpress-admin-utils.js +703 -0
  12. package/src/scripts/astro-publish.js +209 -0
  13. package/src/scripts/coolify-deploy-app.js +287 -0
  14. package/src/scripts/coolify-list-resources.js +199 -0
  15. package/src/scripts/coolify-status.js +97 -0
  16. package/src/scripts/docusaurus-publish.js +209 -0
  17. package/src/scripts/init-project.js +91 -0
  18. package/src/scripts/mintlify-publish.js +205 -0
  19. package/src/scripts/payloadcms-publish.js +202 -0
  20. package/src/scripts/test-coolify-deploy.js +47 -0
  21. package/src/scripts/wordpress-comprehensive-report.js +325 -0
  22. package/src/scripts/wordpress-health-check.js +175 -0
  23. package/src/scripts/wordpress-performance-check.js +461 -0
  24. package/src/scripts/wordpress-security-scan.js +221 -0
  25. package/src/templates/claude/agents/astro-publish.md +43 -0
  26. package/src/templates/claude/agents/coolify-deploy.md +563 -0
  27. package/src/templates/claude/agents/docusaurus-publish.md +42 -0
  28. package/src/templates/claude/agents/mintlify-publish.md +42 -0
  29. package/src/templates/claude/agents/payloadcms-publish.md +134 -0
  30. package/src/templates/claude/commands/myai-astro-publish.md +54 -0
  31. package/src/templates/claude/commands/myai-coolify-deploy.md +172 -0
  32. package/src/templates/claude/commands/myai-docusaurus-publish.md +45 -0
  33. package/src/templates/claude/commands/myai-mintlify-publish.md +45 -0
  34. package/src/templates/claude/commands/myai-payloadcms-publish.md +45 -0
@@ -0,0 +1,380 @@
1
+ /**
2
+ * Coolify API Utilities
3
+ * Reusable functions for Coolify deployment and resource management
4
+ * Optimized for Claude Code 2.0 agent integration
5
+ */
6
+
7
+ import fetch from 'node-fetch';
8
+ import { readFileSync } from 'fs';
9
+ import { parse } from 'dotenv';
10
+
11
+ export class CoolifyUtils {
12
+ constructor(config = {}) {
13
+ // Load config from .env if not provided
14
+ if (!config.url || !config.apiKey) {
15
+ const envConfig = this.loadEnvConfig();
16
+ config = { ...envConfig, ...config };
17
+ }
18
+
19
+ this.url = config.url?.replace(/\/$/, '');
20
+ this.apiKey = config.apiKey;
21
+ this.headers = {
22
+ 'Authorization': `Bearer ${this.apiKey}`,
23
+ 'Content-Type': 'application/json',
24
+ 'Accept': 'application/json'
25
+ };
26
+ }
27
+
28
+ loadEnvConfig() {
29
+ try {
30
+ const envPath = process.env.ENV_PATH || '.env';
31
+ const envContent = readFileSync(envPath, 'utf8');
32
+ const parsed = parse(envContent);
33
+
34
+ return {
35
+ url: parsed.COOLIFY_URL,
36
+ apiKey: parsed.COOLIFY_API_KEY
37
+ };
38
+ } catch (error) {
39
+ throw new Error(`Failed to load Coolify configuration: ${error.message}`);
40
+ }
41
+ }
42
+
43
+ /**
44
+ * Make authenticated Coolify API request
45
+ */
46
+ async request(endpoint, options = {}) {
47
+ const url = `${this.url}${endpoint}`;
48
+
49
+ try {
50
+ const response = await fetch(url, {
51
+ ...options,
52
+ headers: { ...this.headers, ...options.headers }
53
+ });
54
+
55
+ const data = await response.json().catch(() => ({}));
56
+
57
+ if (!response.ok) {
58
+ throw new Error(`HTTP ${response.status}: ${data.message || response.statusText}`);
59
+ }
60
+
61
+ return data;
62
+ } catch (error) {
63
+ throw new Error(`Coolify API request failed: ${error.message}`);
64
+ }
65
+ }
66
+
67
+ /**
68
+ * Server Management
69
+ */
70
+ async listServers() {
71
+ return await this.request('/api/v1/servers');
72
+ }
73
+
74
+ async getServer(uuid) {
75
+ return await this.request(`/api/v1/servers/${uuid}`);
76
+ }
77
+
78
+ async getServerResources(uuid) {
79
+ return await this.request(`/api/v1/servers/${uuid}/resources`);
80
+ }
81
+
82
+ /**
83
+ * Project Management
84
+ */
85
+ async listProjects() {
86
+ return await this.request('/api/v1/projects');
87
+ }
88
+
89
+ async getProject(uuid) {
90
+ return await this.request(`/api/v1/projects/${uuid}`);
91
+ }
92
+
93
+ async createProject(data) {
94
+ return await this.request('/api/v1/projects', {
95
+ method: 'POST',
96
+ body: JSON.stringify(data)
97
+ });
98
+ }
99
+
100
+ /**
101
+ * Application Management
102
+ */
103
+ async listApplications() {
104
+ return await this.request('/api/v1/applications');
105
+ }
106
+
107
+ async getApplication(uuid) {
108
+ return await this.request(`/api/v1/applications/${uuid}`);
109
+ }
110
+
111
+ async createApplication(data) {
112
+ // Coolify API requires /applications/public endpoint
113
+ return await this.request('/api/v1/applications/public', {
114
+ method: 'POST',
115
+ body: JSON.stringify(data)
116
+ });
117
+ }
118
+
119
+ async updateApplication(uuid, data) {
120
+ return await this.request(`/api/v1/applications/${uuid}`, {
121
+ method: 'PATCH',
122
+ body: JSON.stringify(data)
123
+ });
124
+ }
125
+
126
+ async deleteApplication(uuid) {
127
+ return await this.request(`/api/v1/applications/${uuid}`, {
128
+ method: 'DELETE'
129
+ });
130
+ }
131
+
132
+ /**
133
+ * Deployment Operations
134
+ */
135
+ async deployApplication(uuid, options = {}) {
136
+ const endpoint = options.tag
137
+ ? `/api/v1/deploy?tag=${options.tag}`
138
+ : `/api/v1/deploy?uuid=${uuid}`;
139
+
140
+ return await this.request(endpoint, {
141
+ method: 'POST',
142
+ body: JSON.stringify({
143
+ force: options.force || false,
144
+ instant_deploy: options.instant || false,
145
+ ...options.deployConfig
146
+ })
147
+ });
148
+ }
149
+
150
+ async getDeploymentLogs(uuid) {
151
+ return await this.request(`/api/v1/applications/${uuid}/logs`);
152
+ }
153
+
154
+ async restartApplication(uuid) {
155
+ return await this.request(`/api/v1/applications/${uuid}/restart`, {
156
+ method: 'POST'
157
+ });
158
+ }
159
+
160
+ async stopApplication(uuid) {
161
+ return await this.request(`/api/v1/applications/${uuid}/stop`, {
162
+ method: 'POST'
163
+ });
164
+ }
165
+
166
+ /**
167
+ * Environment Variables
168
+ */
169
+ async getEnvironmentVariables(uuid) {
170
+ return await this.request(`/api/v1/applications/${uuid}/envs`);
171
+ }
172
+
173
+ async updateEnvironmentVariables(uuid, envVars) {
174
+ return await this.request(`/api/v1/applications/${uuid}/envs`, {
175
+ method: 'POST',
176
+ body: JSON.stringify(envVars)
177
+ });
178
+ }
179
+
180
+ /**
181
+ * Database Management
182
+ */
183
+ async listDatabases() {
184
+ return await this.request('/api/v1/databases');
185
+ }
186
+
187
+ async getDatabase(uuid) {
188
+ return await this.request(`/api/v1/databases/${uuid}`);
189
+ }
190
+
191
+ async createDatabase(data) {
192
+ return await this.request('/api/v1/databases', {
193
+ method: 'POST',
194
+ body: JSON.stringify(data)
195
+ });
196
+ }
197
+
198
+ /**
199
+ * Service Management
200
+ */
201
+ async listServices() {
202
+ return await this.request('/api/v1/services');
203
+ }
204
+
205
+ async getService(uuid) {
206
+ return await this.request(`/api/v1/services/${uuid}`);
207
+ }
208
+
209
+ /**
210
+ * Team Management
211
+ */
212
+ async listTeams() {
213
+ return await this.request('/api/v1/teams');
214
+ }
215
+
216
+ async getCurrentTeam() {
217
+ return await this.request('/api/v1/teams/current');
218
+ }
219
+
220
+ /**
221
+ * Health & Status
222
+ */
223
+ async healthCheck() {
224
+ try {
225
+ const response = await fetch(`${this.url}/api/health`);
226
+ return response.ok;
227
+ } catch (error) {
228
+ return false;
229
+ }
230
+ }
231
+
232
+ async getSystemStatus() {
233
+ const [servers, projects, applications] = await Promise.all([
234
+ this.listServers().catch(() => []),
235
+ this.listProjects().catch(() => []),
236
+ this.listApplications().catch(() => [])
237
+ ]);
238
+
239
+ return {
240
+ healthy: await this.healthCheck(),
241
+ servers: {
242
+ total: servers.length,
243
+ reachable: servers.filter(s => s.is_reachable).length,
244
+ usable: servers.filter(s => s.is_usable).length
245
+ },
246
+ projects: {
247
+ total: projects.length
248
+ },
249
+ applications: {
250
+ total: applications.length
251
+ }
252
+ };
253
+ }
254
+
255
+ /**
256
+ * Deployment Helpers
257
+ */
258
+ async findApplicationByName(name) {
259
+ const apps = await this.listApplications();
260
+ return apps.find(app => app.name === name);
261
+ }
262
+
263
+ async findServerByName(name) {
264
+ const servers = await this.listServers();
265
+ return servers.find(server => server.name === name);
266
+ }
267
+
268
+ async findProjectByName(name) {
269
+ const projects = await this.listProjects();
270
+ return projects.find(project => project.name === name);
271
+ }
272
+
273
+ async waitForDeployment(uuid, options = {}) {
274
+ const maxAttempts = options.maxAttempts || 60;
275
+ const interval = options.interval || 5000;
276
+
277
+ for (let i = 0; i < maxAttempts; i++) {
278
+ const app = await this.getApplication(uuid);
279
+
280
+ if (app.status === 'running') {
281
+ return { success: true, status: 'running', attempts: i + 1 };
282
+ }
283
+
284
+ if (app.status === 'error' || app.status === 'failed') {
285
+ return { success: false, status: app.status, attempts: i + 1 };
286
+ }
287
+
288
+ await new Promise(resolve => setTimeout(resolve, interval));
289
+ }
290
+
291
+ return { success: false, status: 'timeout', attempts: maxAttempts };
292
+ }
293
+
294
+ /**
295
+ * Deployment Configuration Builders
296
+ */
297
+ buildApplicationConfig(options) {
298
+ return {
299
+ name: options.name,
300
+ description: options.description || '',
301
+ project_uuid: options.projectUuid,
302
+ server_uuid: options.serverUuid,
303
+ destination_uuid: options.destinationUuid,
304
+ source: {
305
+ type: options.sourceType || 'git',
306
+ repository: options.repository,
307
+ branch: options.branch || 'main',
308
+ commit: options.commit || null
309
+ },
310
+ build_pack: options.buildPack || 'nixpacks',
311
+ ports_exposes: options.ports || '3000',
312
+ domains: options.domains || [],
313
+ environment_variables: options.envVars || {},
314
+ settings: {
315
+ instant_deploy: options.instantDeploy || false,
316
+ auto_deploy: options.autoDeploy || true,
317
+ ...options.settings
318
+ }
319
+ };
320
+ }
321
+
322
+ buildDatabaseConfig(options) {
323
+ return {
324
+ name: options.name,
325
+ description: options.description || '',
326
+ project_uuid: options.projectUuid,
327
+ server_uuid: options.serverUuid,
328
+ destination_uuid: options.destinationUuid,
329
+ type: options.type, // postgresql, mysql, mongodb, redis, etc.
330
+ version: options.version || 'latest',
331
+ public_port: options.publicPort || null,
332
+ environment_variables: options.envVars || {}
333
+ };
334
+ }
335
+
336
+ /**
337
+ * Formatted Output Helpers
338
+ */
339
+ formatServerList(servers) {
340
+ return servers.map(s => ({
341
+ name: s.name,
342
+ uuid: s.uuid,
343
+ ip: s.ip,
344
+ status: s.is_reachable ? '✓ Reachable' : '✗ Unreachable',
345
+ usable: s.is_usable ? '✓ Usable' : '✗ Not Usable',
346
+ description: s.description || 'No description'
347
+ }));
348
+ }
349
+
350
+ formatApplicationList(applications) {
351
+ return applications.map(a => ({
352
+ name: a.name,
353
+ uuid: a.uuid,
354
+ status: a.status,
355
+ url: a.fqdn || 'Not configured',
356
+ project: a.project?.name || 'Unknown'
357
+ }));
358
+ }
359
+
360
+ generateDeploymentReport(deployment, application) {
361
+ return {
362
+ timestamp: new Date().toISOString(),
363
+ application: {
364
+ name: application.name,
365
+ uuid: application.uuid,
366
+ url: application.fqdn
367
+ },
368
+ deployment: {
369
+ status: deployment.status,
370
+ commit: deployment.commit,
371
+ branch: deployment.branch,
372
+ started_at: deployment.started_at,
373
+ finished_at: deployment.finished_at
374
+ },
375
+ success: deployment.status === 'success'
376
+ };
377
+ }
378
+ }
379
+
380
+ export default CoolifyUtils;