myaidev-method 0.2.22 → 0.2.24-1

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 (59) hide show
  1. package/USER_GUIDE.md +453 -48
  2. package/bin/cli.js +236 -38
  3. package/content-rules.example.md +80 -0
  4. package/dist/mcp/mcp-launcher.js +237 -0
  5. package/dist/server/.tsbuildinfo +1 -1
  6. package/dist/server/auth/layers.d.ts +1 -1
  7. package/dist/server/auth/services/AuthService.d.ts +1 -1
  8. package/dist/server/auth/services/TokenService.js.map +1 -1
  9. package/dist/server/auth/services/example.d.ts +5 -5
  10. package/package.json +22 -17
  11. package/src/config/workflows.js +28 -44
  12. package/src/index.js +21 -8
  13. package/src/lib/ascii-banner.js +214 -0
  14. package/src/lib/config-manager.js +470 -0
  15. package/src/lib/content-generator.js +427 -0
  16. package/src/lib/html-conversion-utils.js +843 -0
  17. package/src/lib/seo-optimizer.js +515 -0
  18. package/src/lib/update-manager.js +2 -1
  19. package/src/lib/visual-config-utils.js +321 -295
  20. package/src/lib/visual-generation-utils.js +1000 -811
  21. package/src/lib/wordpress-client.js +633 -0
  22. package/src/lib/workflow-installer.js +3 -3
  23. package/src/scripts/configure-wordpress-mcp.js +8 -3
  24. package/src/scripts/generate-visual-cli.js +365 -235
  25. package/src/scripts/html-conversion-cli.js +526 -0
  26. package/src/scripts/init/configure.js +436 -0
  27. package/src/scripts/init/install.js +460 -0
  28. package/src/scripts/ping.js +250 -0
  29. package/src/scripts/utils/file-utils.js +404 -0
  30. package/src/scripts/utils/logger.js +300 -0
  31. package/src/scripts/utils/write-content.js +293 -0
  32. package/src/scripts/wordpress/publish-to-wordpress.js +165 -0
  33. package/src/server/auth/services/TokenService.ts +1 -1
  34. package/src/templates/claude/agents/content-rules-setup.md +657 -0
  35. package/src/templates/claude/agents/content-writer.md +328 -1
  36. package/src/templates/claude/agents/visual-content-generator.md +311 -8
  37. package/src/templates/claude/commands/myai-configure.md +1 -1
  38. package/src/templates/claude/commands/myai-content-rules-setup.md +204 -0
  39. package/src/templates/claude/commands/myai-convert-html.md +186 -0
  40. package/src/templates/codex/commands/myai-content-rules-setup.md +85 -0
  41. package/src/templates/diagrams/architecture.d2 +52 -0
  42. package/src/templates/diagrams/flowchart.d2 +42 -0
  43. package/src/templates/diagrams/sequence.d2 +47 -0
  44. package/src/templates/docs/content-creation-guide.md +164 -0
  45. package/src/templates/docs/deployment-guide.md +336 -0
  46. package/src/templates/docs/visual-generation-guide.md +248 -0
  47. package/src/templates/docs/wordpress-publishing-guide.md +208 -0
  48. package/src/templates/gemini/commands/myai-content-rules-setup.toml +57 -0
  49. package/src/templates/infographics/comparison-table.html +347 -0
  50. package/src/templates/infographics/data-chart.html +268 -0
  51. package/src/templates/infographics/process-flow.html +365 -0
  52. package/.claude/mcp/sparc-orchestrator-server.js +0 -607
  53. package/.claude/mcp/wordpress-server.js +0 -1277
  54. package/src/agents/content-writer-prompt.md +0 -164
  55. package/src/agents/content-writer.json +0 -70
  56. package/src/templates/claude/mcp_config.json +0 -74
  57. package/src/templates/claude/slash_commands.json +0 -166
  58. package/src/templates/scripts/configure-wordpress-mcp.js +0 -181
  59. /package/src/scripts/{wordpress-health-check.js → wordpress/wordpress-health-check.js} +0 -0
@@ -0,0 +1,436 @@
1
+ #!/usr/bin/env node
2
+
3
+ /**
4
+ * Configure Script
5
+ * Interactive configuration wizard for MyAIDev Method
6
+ * Handles: WordPress, OpenStack, Content, and General settings
7
+ */
8
+
9
+ import inquirer from 'inquirer';
10
+ import { ConfigManager, SCHEMAS } from '../../lib/config-manager.js';
11
+ import { WordPressClient } from '../../lib/wordpress-client.js';
12
+ import { logger, createSpinner } from '../utils/logger.js';
13
+ import chalk from 'chalk';
14
+
15
+ /**
16
+ * Configuration Wizard Class
17
+ */
18
+ class ConfigurationWizard {
19
+ constructor() {
20
+ this.configManager = new ConfigManager();
21
+ }
22
+
23
+ /**
24
+ * Run the configuration wizard
25
+ * @param {string} [section] - Specific section to configure
26
+ */
27
+ async run(section) {
28
+ logger.header('MyAIDev Method Configuration');
29
+
30
+ if (section) {
31
+ await this.configureSection(section);
32
+ } else {
33
+ await this.showMainMenu();
34
+ }
35
+ }
36
+
37
+ /**
38
+ * Show the main configuration menu
39
+ */
40
+ async showMainMenu() {
41
+ const config = await this.configManager.loadAll();
42
+
43
+ // Check which sections are configured
44
+ const wpStatus = this.getConfigStatus(config, 'wordpress');
45
+ const osStatus = this.getConfigStatus(config, 'openstack');
46
+ const contentStatus = this.getConfigStatus(config, 'content');
47
+
48
+ const { section } = await inquirer.prompt([
49
+ {
50
+ type: 'list',
51
+ name: 'section',
52
+ message: 'What would you like to configure?',
53
+ choices: [
54
+ {
55
+ name: `WordPress ${wpStatus}`,
56
+ value: 'wordpress'
57
+ },
58
+ {
59
+ name: `OpenStack ${osStatus}`,
60
+ value: 'openstack'
61
+ },
62
+ {
63
+ name: `Content Settings ${contentStatus}`,
64
+ value: 'content'
65
+ },
66
+ {
67
+ name: 'General Settings',
68
+ value: 'general'
69
+ },
70
+ {
71
+ name: 'View Current Configuration',
72
+ value: 'view'
73
+ },
74
+ new inquirer.Separator(),
75
+ {
76
+ name: 'Exit',
77
+ value: 'exit'
78
+ }
79
+ ]
80
+ }
81
+ ]);
82
+
83
+ if (section === 'exit') {
84
+ logger.info('Configuration complete.');
85
+ return;
86
+ }
87
+
88
+ if (section === 'view') {
89
+ await this.viewConfiguration();
90
+ await this.showMainMenu();
91
+ return;
92
+ }
93
+
94
+ await this.configureSection(section);
95
+
96
+ // Ask if user wants to continue
97
+ const { continueConfig } = await inquirer.prompt([
98
+ {
99
+ type: 'confirm',
100
+ name: 'continueConfig',
101
+ message: 'Would you like to configure something else?',
102
+ default: false
103
+ }
104
+ ]);
105
+
106
+ if (continueConfig) {
107
+ await this.showMainMenu();
108
+ }
109
+ }
110
+
111
+ /**
112
+ * Get status indicator for a configuration section
113
+ * @param {Object} config - Current configuration
114
+ * @param {string} section - Section name
115
+ * @returns {string} Status indicator
116
+ */
117
+ getConfigStatus(config, section) {
118
+ const validation = this.configManager.validateConfig(config, section);
119
+ if (validation.valid) {
120
+ return chalk.green('✓ Configured');
121
+ } else if (validation.missing.length < SCHEMAS[section]?.required?.length) {
122
+ return chalk.yellow('◐ Partial');
123
+ }
124
+ return chalk.gray('○ Not configured');
125
+ }
126
+
127
+ /**
128
+ * Configure a specific section
129
+ * @param {string} section - Section to configure
130
+ */
131
+ async configureSection(section) {
132
+ switch (section) {
133
+ case 'wordpress':
134
+ await this.configureWordPress();
135
+ break;
136
+ case 'openstack':
137
+ await this.configureOpenStack();
138
+ break;
139
+ case 'content':
140
+ await this.configureContent();
141
+ break;
142
+ case 'general':
143
+ await this.configureGeneral();
144
+ break;
145
+ default:
146
+ logger.error(`Unknown section: ${section}`);
147
+ }
148
+ }
149
+
150
+ /**
151
+ * Configure WordPress settings
152
+ */
153
+ async configureWordPress() {
154
+ logger.section('WordPress Configuration');
155
+ logger.info('Configure your WordPress site for content publishing.');
156
+ logger.blank();
157
+
158
+ const config = await this.configManager.loadAll();
159
+
160
+ const answers = await inquirer.prompt([
161
+ {
162
+ type: 'input',
163
+ name: 'WORDPRESS_URL',
164
+ message: 'WordPress site URL:',
165
+ default: config.WORDPRESS_URL || '',
166
+ validate: (input) => {
167
+ if (!input) return 'URL is required';
168
+ if (!input.includes('.')) return 'Please enter a valid URL';
169
+ return true;
170
+ }
171
+ },
172
+ {
173
+ type: 'input',
174
+ name: 'WORDPRESS_USERNAME',
175
+ message: 'WordPress username:',
176
+ default: config.WORDPRESS_USERNAME || '',
177
+ validate: (input) => input ? true : 'Username is required'
178
+ },
179
+ {
180
+ type: 'password',
181
+ name: 'WORDPRESS_APP_PASSWORD',
182
+ message: 'WordPress Application Password:',
183
+ mask: '*',
184
+ validate: (input) => input ? true : 'Application password is required'
185
+ },
186
+ {
187
+ type: 'list',
188
+ name: 'WORDPRESS_DEFAULT_STATUS',
189
+ message: 'Default post status:',
190
+ choices: ['draft', 'publish', 'pending'],
191
+ default: config.WORDPRESS_DEFAULT_STATUS || 'draft'
192
+ }
193
+ ]);
194
+
195
+ // Test connection
196
+ const spinner = createSpinner('Testing WordPress connection...');
197
+ spinner.start();
198
+
199
+ const client = new WordPressClient({
200
+ siteUrl: answers.WORDPRESS_URL,
201
+ username: answers.WORDPRESS_USERNAME,
202
+ appPassword: answers.WORDPRESS_APP_PASSWORD
203
+ });
204
+
205
+ const result = await client.validateConnection();
206
+
207
+ if (result.valid) {
208
+ spinner.succeed(result.message);
209
+
210
+ // Save configuration
211
+ await this.configManager.saveEnvConfig(answers);
212
+ logger.success('WordPress configuration saved!');
213
+ } else {
214
+ spinner.fail(result.message);
215
+
216
+ const { saveAnyway } = await inquirer.prompt([
217
+ {
218
+ type: 'confirm',
219
+ name: 'saveAnyway',
220
+ message: 'Save configuration anyway?',
221
+ default: false
222
+ }
223
+ ]);
224
+
225
+ if (saveAnyway) {
226
+ await this.configManager.saveEnvConfig(answers);
227
+ logger.warn('Configuration saved (connection not verified).');
228
+ }
229
+ }
230
+ }
231
+
232
+ /**
233
+ * Configure OpenStack settings
234
+ */
235
+ async configureOpenStack() {
236
+ logger.section('OpenStack Configuration');
237
+ logger.info('Configure your OpenStack cloud for VM management.');
238
+ logger.blank();
239
+
240
+ const config = await this.configManager.loadAll();
241
+
242
+ const answers = await inquirer.prompt([
243
+ {
244
+ type: 'input',
245
+ name: 'OS_AUTH_URL',
246
+ message: 'OpenStack Auth URL:',
247
+ default: config.OS_AUTH_URL || '',
248
+ validate: (input) => input ? true : 'Auth URL is required'
249
+ },
250
+ {
251
+ type: 'input',
252
+ name: 'OS_USERNAME',
253
+ message: 'OpenStack username:',
254
+ default: config.OS_USERNAME || '',
255
+ validate: (input) => input ? true : 'Username is required'
256
+ },
257
+ {
258
+ type: 'password',
259
+ name: 'OS_PASSWORD',
260
+ message: 'OpenStack password:',
261
+ mask: '*',
262
+ validate: (input) => input ? true : 'Password is required'
263
+ },
264
+ {
265
+ type: 'input',
266
+ name: 'OS_PROJECT_NAME',
267
+ message: 'Project name:',
268
+ default: config.OS_PROJECT_NAME || '',
269
+ validate: (input) => input ? true : 'Project name is required'
270
+ },
271
+ {
272
+ type: 'input',
273
+ name: 'OS_USER_DOMAIN_NAME',
274
+ message: 'User domain name:',
275
+ default: config.OS_USER_DOMAIN_NAME || 'Default'
276
+ },
277
+ {
278
+ type: 'input',
279
+ name: 'OS_PROJECT_DOMAIN_NAME',
280
+ message: 'Project domain name:',
281
+ default: config.OS_PROJECT_DOMAIN_NAME || 'Default'
282
+ },
283
+ {
284
+ type: 'input',
285
+ name: 'OS_REGION_NAME',
286
+ message: 'Region name (optional):',
287
+ default: config.OS_REGION_NAME || ''
288
+ }
289
+ ]);
290
+
291
+ // Save configuration
292
+ await this.configManager.saveEnvConfig(answers);
293
+ logger.success('OpenStack configuration saved!');
294
+ logger.info('Note: Run the health check to verify your connection.');
295
+ }
296
+
297
+ /**
298
+ * Configure content generation settings
299
+ */
300
+ async configureContent() {
301
+ logger.section('Content Settings');
302
+ logger.info('Configure default settings for content generation.');
303
+ logger.blank();
304
+
305
+ const config = await this.configManager.loadAll();
306
+
307
+ const answers = await inquirer.prompt([
308
+ {
309
+ type: 'number',
310
+ name: 'DEFAULT_WORD_COUNT',
311
+ message: 'Default word count:',
312
+ default: parseInt(config.DEFAULT_WORD_COUNT, 10) || 1500,
313
+ validate: (input) => {
314
+ if (input < 100 || input > 10000) {
315
+ return 'Word count must be between 100 and 10000';
316
+ }
317
+ return true;
318
+ }
319
+ },
320
+ {
321
+ type: 'list',
322
+ name: 'DEFAULT_TONE',
323
+ message: 'Default writing tone:',
324
+ choices: ['professional', 'conversational', 'technical', 'casual', 'authoritative'],
325
+ default: config.DEFAULT_TONE || 'professional'
326
+ },
327
+ {
328
+ type: 'input',
329
+ name: 'CONTENT_OUTPUT_DIR',
330
+ message: 'Default output directory:',
331
+ default: config.CONTENT_OUTPUT_DIR || './content'
332
+ }
333
+ ]);
334
+
335
+ // Save configuration
336
+ await this.configManager.saveEnvConfig(answers);
337
+ logger.success('Content settings saved!');
338
+ }
339
+
340
+ /**
341
+ * Configure general settings
342
+ */
343
+ async configureGeneral() {
344
+ logger.section('General Settings');
345
+ logger.blank();
346
+
347
+ const config = await this.configManager.loadAll();
348
+
349
+ const answers = await inquirer.prompt([
350
+ {
351
+ type: 'list',
352
+ name: 'CLI_TYPE',
353
+ message: 'AI CLI type:',
354
+ choices: [
355
+ { name: 'Claude Code (Recommended)', value: 'claude' },
356
+ { name: 'Gemini CLI', value: 'gemini' },
357
+ { name: 'Codex CLI / OpenCode', value: 'codex' }
358
+ ],
359
+ default: config.CLI_TYPE || 'claude'
360
+ },
361
+ {
362
+ type: 'list',
363
+ name: 'LOG_LEVEL',
364
+ message: 'Log level:',
365
+ choices: ['DEBUG', 'INFO', 'WARN', 'ERROR'],
366
+ default: config.LOG_LEVEL || 'INFO'
367
+ }
368
+ ]);
369
+
370
+ // Save configuration
371
+ await this.configManager.saveEnvConfig(answers);
372
+ logger.success('General settings saved!');
373
+ }
374
+
375
+ /**
376
+ * View current configuration
377
+ */
378
+ async viewConfiguration() {
379
+ logger.section('Current Configuration');
380
+
381
+ const config = await this.configManager.loadAll();
382
+ const keys = Object.keys(config).sort();
383
+
384
+ if (keys.length === 0) {
385
+ logger.info('No configuration found.');
386
+ return;
387
+ }
388
+
389
+ // Group by prefix
390
+ const groups = {};
391
+ for (const key of keys) {
392
+ const prefix = key.split('_')[0];
393
+ if (!groups[prefix]) groups[prefix] = [];
394
+
395
+ // Mask sensitive values
396
+ let value = config[key];
397
+ if (key.includes('PASSWORD') || key.includes('SECRET') || key.includes('TOKEN')) {
398
+ value = '********';
399
+ }
400
+
401
+ groups[prefix].push({ key, value });
402
+ }
403
+
404
+ for (const [prefix, items] of Object.entries(groups)) {
405
+ console.log(`\n${chalk.bold(prefix)}:`);
406
+ for (const item of items) {
407
+ console.log(` ${chalk.cyan(item.key)}: ${item.value}`);
408
+ }
409
+ }
410
+
411
+ logger.blank();
412
+ }
413
+ }
414
+
415
+ /**
416
+ * Main function
417
+ */
418
+ async function main() {
419
+ const args = process.argv.slice(2);
420
+ const section = args[0];
421
+
422
+ const wizard = new ConfigurationWizard();
423
+
424
+ try {
425
+ await wizard.run(section);
426
+ } catch (error) {
427
+ if (error.isTtyError) {
428
+ logger.error('This script requires an interactive terminal.');
429
+ } else {
430
+ logger.error(`Error: ${error.message}`);
431
+ }
432
+ process.exit(1);
433
+ }
434
+ }
435
+
436
+ main();