myaidev-method 0.3.1 → 0.3.3

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 (56) hide show
  1. package/.claude-plugin/plugin.json +52 -48
  2. package/CHANGELOG.md +5 -0
  3. package/DEV_WORKFLOW_GUIDE.md +6 -6
  4. package/MCP_INTEGRATION.md +4 -4
  5. package/README.md +140 -66
  6. package/TECHNICAL_ARCHITECTURE.md +112 -18
  7. package/USER_GUIDE.md +270 -39
  8. package/bin/cli.js +47 -13
  9. package/dist/mcp/gutenberg-converter.js +667 -413
  10. package/dist/mcp/wordpress-admin-mcp.js +0 -1
  11. package/dist/mcp/wordpress-integration.js +0 -1
  12. package/dist/mcp/wordpress-server.js +1558 -1182
  13. package/dist/server/.tsbuildinfo +1 -1
  14. package/extension.json +3 -3
  15. package/package.json +9 -2
  16. package/skills/content-writer/SKILL.md +130 -178
  17. package/skills/infographic/SKILL.md +191 -0
  18. package/skills/myaidev-analyze/SKILL.md +242 -0
  19. package/skills/myaidev-architect/SKILL.md +389 -0
  20. package/skills/myaidev-coder/SKILL.md +291 -0
  21. package/skills/myaidev-debug/SKILL.md +308 -0
  22. package/skills/myaidev-documenter/SKILL.md +194 -0
  23. package/skills/myaidev-migrate/SKILL.md +300 -0
  24. package/skills/myaidev-performance/SKILL.md +270 -0
  25. package/skills/myaidev-refactor/SKILL.md +296 -0
  26. package/skills/myaidev-reviewer/SKILL.md +385 -0
  27. package/skills/myaidev-tester/SKILL.md +331 -0
  28. package/skills/myaidev-workflow/SKILL.md +567 -0
  29. package/skills/security-auditor/SKILL.md +1 -1
  30. package/src/cli/commands/addon.js +60 -12
  31. package/src/cli/commands/auth.js +10 -2
  32. package/src/config/workflows.js +11 -6
  33. package/src/lib/ascii-banner.js +3 -3
  34. package/src/lib/coolify-utils.js +0 -1
  35. package/src/lib/payloadcms-utils.js +0 -1
  36. package/src/lib/visual-generation-utils.js +0 -1
  37. package/src/lib/wordpress-admin-utils.js +0 -1
  38. package/src/mcp/gutenberg-converter.js +667 -413
  39. package/src/mcp/wordpress-admin-mcp.js +0 -1
  40. package/src/mcp/wordpress-integration.js +0 -1
  41. package/src/mcp/wordpress-server.js +1558 -1182
  42. package/src/scripts/test-coolify-deploy.js +0 -1
  43. package/src/statusline/statusline.sh +279 -0
  44. package/skills/content-writer/agents/editor-agent.md +0 -138
  45. package/skills/content-writer/agents/planner-agent.md +0 -121
  46. package/skills/content-writer/agents/research-agent.md +0 -83
  47. package/skills/content-writer/agents/seo-agent.md +0 -139
  48. package/skills/content-writer/agents/visual-planner-agent.md +0 -110
  49. package/skills/content-writer/agents/writer-agent.md +0 -85
  50. package/skills/sparc-architect/SKILL.md +0 -127
  51. package/skills/sparc-coder/SKILL.md +0 -90
  52. package/skills/sparc-documenter/SKILL.md +0 -155
  53. package/skills/sparc-reviewer/SKILL.md +0 -138
  54. package/skills/sparc-tester/SKILL.md +0 -100
  55. package/skills/sparc-workflow/SKILL.md +0 -130
  56. /package/{marketplace.json → .claude-plugin/marketplace.json} +0 -0
@@ -24,9 +24,17 @@ import { validateSkill, generateSlug } from '../../lib/skill-validator.js';
24
24
 
25
25
  const API_BASE = 'https://dev.myai1.ai/api/skills';
26
26
  const MARKETPLACE_REPO = 'myaione/myaidev-marketplace';
27
+ const FETCH_TIMEOUT_MS = 10000;
27
28
 
28
29
  // ── Helpers ─────────────────────────────────────────────────────────────
29
30
 
31
+ function fetchWithTimeout(url, options = {}, timeoutMs = FETCH_TIMEOUT_MS) {
32
+ const controller = new AbortController();
33
+ const timeout = setTimeout(() => controller.abort(), timeoutMs);
34
+ return fetch(url, { ...options, signal: controller.signal })
35
+ .finally(() => clearTimeout(timeout));
36
+ }
37
+
30
38
  function projectSkillsDir() {
31
39
  return path.join(process.cwd(), '.claude', 'skills');
32
40
  }
@@ -57,6 +65,7 @@ async function requireAuth() {
57
65
  export function registerAddonCommand(program) {
58
66
  const addon = program
59
67
  .command('addon [name]')
68
+ .enablePositionalOptions()
60
69
  .description('Install a skill from the MyAIDev marketplace')
61
70
  .option('--project', 'Install to project .claude/skills/')
62
71
  .option('--global', 'Install to global ~/.claude/skills/')
@@ -68,6 +77,16 @@ export function registerAddonCommand(program) {
68
77
  await installSkill(name, options);
69
78
  });
70
79
 
80
+ // ── addon install ───────────────────────────────────────────────────
81
+ addon
82
+ .command('install <name>')
83
+ .description('Install a skill from the marketplace')
84
+ .option('--project', 'Install to project .claude/skills/')
85
+ .option('--global', 'Install to global ~/.claude/skills/')
86
+ .action(async (name, opts) => {
87
+ await installSkill(name, opts);
88
+ });
89
+
71
90
  // ── addon list ──────────────────────────────────────────────────────
72
91
  addon
73
92
  .command('list')
@@ -154,7 +173,7 @@ async function installSkill(name, options) {
154
173
 
155
174
  try {
156
175
  // Search for skill
157
- const res = await fetch(`${API_BASE}?search=${encodeURIComponent(name)}&limit=5`);
176
+ const res = await fetchWithTimeout(`${API_BASE}?search=${encodeURIComponent(name)}&limit=5`);
158
177
  if (!res.ok) throw new Error(`API error: ${res.status}`);
159
178
  const body = await res.json();
160
179
  const skills = body.skills || [];
@@ -210,14 +229,23 @@ async function installSkill(name, options) {
210
229
 
211
230
  // Download
212
231
  const dlSpinner = ora(`Downloading ${chalk.cyan(skill.name)}...`).start();
213
- const dlRes = await fetch(`${API_BASE}/${skill.id}/download`);
232
+ const dlRes = await fetchWithTimeout(`${API_BASE}/${skill.id}/download`);
214
233
  if (!dlRes.ok) throw new Error(`Download failed: ${dlRes.status}`);
215
- const dlBody = await dlRes.json();
216
234
 
217
- if (!dlBody.content) throw new Error('Skill content is empty');
235
+ // Handle both JSON and raw markdown responses
236
+ const contentType = dlRes.headers.get('content-type') || '';
237
+ let content;
238
+ if (contentType.includes('application/json')) {
239
+ const dlBody = await dlRes.json();
240
+ content = dlBody.content;
241
+ } else {
242
+ content = await dlRes.text();
243
+ }
244
+
245
+ if (!content) throw new Error('Skill content is empty');
218
246
 
219
247
  await fs.ensureDir(installPath);
220
- await fs.writeFile(path.join(installPath, 'SKILL.md'), dlBody.content, 'utf8');
248
+ await fs.writeFile(path.join(installPath, 'SKILL.md'), content, 'utf8');
221
249
 
222
250
  dlSpinner.succeed(chalk.green(`Installed ${chalk.bold(skill.name)}`));
223
251
 
@@ -225,7 +253,13 @@ async function installSkill(name, options) {
225
253
  console.log(chalk.gray(` → ${rel}/SKILL.md`));
226
254
  console.log(chalk.cyan('\n Restart Claude Code to load the new skill.\n'));
227
255
  } catch (err) {
228
- spinner.fail(chalk.red(`Failed to install: ${err.message}`));
256
+ if (err.name === 'AbortError') {
257
+ spinner.fail(chalk.red('Request timed out. Check your internet connection.'));
258
+ } else if (err.cause?.code === 'ENOTFOUND' || err.message?.includes('ENOTFOUND')) {
259
+ spinner.fail(chalk.red('Cannot reach marketplace API. Check your internet connection.'));
260
+ } else {
261
+ spinner.fail(chalk.red(`Failed to install: ${err.message}`));
262
+ }
229
263
  process.exit(1);
230
264
  }
231
265
  }
@@ -241,7 +275,7 @@ async function listMarketplace(opts) {
241
275
  if (opts.sort) params.set('sort', opts.sort);
242
276
  params.set('limit', opts.limit || '20');
243
277
 
244
- const res = await fetch(`${API_BASE}?${params}`);
278
+ const res = await fetchWithTimeout(`${API_BASE}?${params}`);
245
279
  if (!res.ok) throw new Error(`API error: ${res.status}`);
246
280
  const body = await res.json();
247
281
  const skills = body.skills || [];
@@ -264,15 +298,22 @@ async function listMarketplace(opts) {
264
298
  for (const s of skills) {
265
299
  const stars = String(s.stars ?? 0).padStart(3);
266
300
  const downloads = String(s.downloads ?? 0).padStart(5);
301
+ const author = s.authorName || s.author || 'unknown';
267
302
  console.log(
268
- ` ${chalk.green(pad(s.name, 24))} ${chalk.gray(pad(truncate(s.description, 38), 40))} ${chalk.white(pad(truncate(s.author, 14), 16))} ${chalk.yellow(stars)} ${chalk.blue(downloads)}`
303
+ ` ${chalk.green(pad(s.name, 24))} ${chalk.gray(pad(truncate(s.description, 38), 40))} ${chalk.white(pad(truncate(author, 14), 16))} ${chalk.yellow(stars)} ${chalk.blue(downloads)}`
269
304
  );
270
305
  }
271
306
 
272
307
  console.log(chalk.gray('\n Install: myaidev-method addon <name>'));
273
308
  console.log(chalk.gray(' Search: myaidev-method addon search <query>\n'));
274
309
  } catch (err) {
275
- spinner.fail(chalk.red(`Failed to fetch marketplace: ${err.message}`));
310
+ if (err.name === 'AbortError') {
311
+ spinner.fail(chalk.red('Request timed out. Check your internet connection.'));
312
+ } else if (err.cause?.code === 'ENOTFOUND' || err.message?.includes('ENOTFOUND')) {
313
+ spinner.fail(chalk.red('Cannot reach marketplace API. Check your internet connection.'));
314
+ } else {
315
+ spinner.fail(chalk.red(`Failed to fetch marketplace: ${err.message}`));
316
+ }
276
317
  process.exit(1);
277
318
  }
278
319
  }
@@ -284,7 +325,7 @@ async function searchMarketplace(query, opts) {
284
325
 
285
326
  try {
286
327
  const params = new URLSearchParams({ search: query, limit: opts.limit || '10' });
287
- const res = await fetch(`${API_BASE}?${params}`);
328
+ const res = await fetchWithTimeout(`${API_BASE}?${params}`);
288
329
  if (!res.ok) throw new Error(`API error: ${res.status}`);
289
330
  const body = await res.json();
290
331
  const skills = body.skills || [];
@@ -301,19 +342,26 @@ async function searchMarketplace(query, opts) {
301
342
  for (const s of skills) {
302
343
  const stars = s.stars ?? 0;
303
344
  const downloads = s.downloads ?? 0;
345
+ const author = s.authorName || s.author || 'unknown';
304
346
  // Highlight matching parts of the name
305
347
  const highlighted = s.name.replace(
306
348
  new RegExp(`(${query.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')})`, 'gi'),
307
349
  (m) => chalk.yellow.bold(m)
308
350
  );
309
351
 
310
- console.log(` ${chalk.green('●')} ${highlighted} ${chalk.gray(`by ${s.author}`)}`);
352
+ console.log(` ${chalk.green('●')} ${highlighted} ${chalk.gray(`by ${author}`)}`);
311
353
  console.log(` ${chalk.gray(truncate(s.description, 70))}`);
312
354
  console.log(` ${chalk.yellow(`⭐ ${stars}`)} ${chalk.blue(`⬇ ${downloads}`)} ${chalk.gray(`Install: myaidev-method addon ${s.slug || s.name.toLowerCase().replace(/\s+/g, '-')}`)}`);
313
355
  console.log('');
314
356
  }
315
357
  } catch (err) {
316
- spinner.fail(chalk.red(`Search failed: ${err.message}`));
358
+ if (err.name === 'AbortError') {
359
+ spinner.fail(chalk.red('Request timed out. Check your internet connection.'));
360
+ } else if (err.cause?.code === 'ENOTFOUND' || err.message?.includes('ENOTFOUND')) {
361
+ spinner.fail(chalk.red('Cannot reach marketplace API. Check your internet connection.'));
362
+ } else {
363
+ spinner.fail(chalk.red(`Search failed: ${err.message}`));
364
+ }
317
365
  process.exit(1);
318
366
  }
319
367
  }
@@ -9,6 +9,14 @@ import { getAuthData, saveAuth, clearAuth, isAuthenticated } from '../../lib/aut
9
9
 
10
10
  const API_BASE = 'https://dev.myai1.ai';
11
11
 
12
+ function ensureHttpsUrl(url) {
13
+ const value = String(url ?? '').trim();
14
+ if (!value) return value;
15
+ if (/^https:\/\//i.test(value)) return value;
16
+ if (/^http:\/\//i.test(value)) return value.replace(/^http:\/\//i, 'https://');
17
+ return `https://${value.replace(/^\/+/, '')}`;
18
+ }
19
+
12
20
  export function registerAuthCommands(program) {
13
21
  // ── login ───────────────────────────────────────────────────────────
14
22
  program
@@ -31,7 +39,7 @@ export function registerAuthCommands(program) {
31
39
  if (!initRes.ok) throw new Error(`Server returned ${initRes.status}`);
32
40
  const initData = await initRes.json();
33
41
  sessionId = initData.sessionId;
34
- authUrl = initData.authUrl;
42
+ authUrl = ensureHttpsUrl(initData.authUrl);
35
43
  } catch (err) {
36
44
  console.log(chalk.red(' ✗ Failed to connect to MyAIDev marketplace.'));
37
45
  console.log(chalk.gray(` ${err.message}\n`));
@@ -88,7 +96,7 @@ export function registerAuthCommands(program) {
88
96
  if (success) {
89
97
  const data = await getAuthData();
90
98
  spinner.succeed(chalk.green(`Logged in as ${chalk.bold(data?.user?.name || data?.user?.email)}`));
91
- console.log(chalk.gray('\nYou can now install and publish skills from the marketplace.\n'));
99
+ console.log(chalk.gray('\nWelcome! Enjoy the full MyAIDev ecosystem skills, tools, and cloud services included with your plan.\n'));
92
100
  } else {
93
101
  spinner.fail(chalk.red('Login timed out'));
94
102
  console.log(chalk.gray('Try again with: myaidev-method login\n'));
@@ -74,12 +74,17 @@ const WORKFLOWS = {
74
74
  name: 'Development Workflow',
75
75
  description: 'SPARC methodology for systematic software development',
76
76
  skills: [
77
- 'sparc-architect',
78
- 'sparc-coder',
79
- 'sparc-tester',
80
- 'sparc-reviewer',
81
- 'sparc-documenter',
82
- 'sparc-workflow'
77
+ 'myaidev-workflow',
78
+ 'myaidev-architect',
79
+ 'myaidev-coder',
80
+ 'myaidev-tester',
81
+ 'myaidev-reviewer',
82
+ 'myaidev-documenter',
83
+ 'myaidev-analyze',
84
+ 'myaidev-debug',
85
+ 'myaidev-refactor',
86
+ 'myaidev-performance',
87
+ 'myaidev-migrate'
83
88
  ],
84
89
  scripts: [],
85
90
  libs: [],
@@ -77,10 +77,10 @@ ${chalk.bold.hex('#808080')('─────────────────
77
77
  */
78
78
  export function getInitSuccessMessage(cliType) {
79
79
  const commands = cliType === 'claude'
80
- ? ' • View README: Press Ctrl+Shift+P → "Toggle Documentation"\n • Run workflow: /myai-sparc-workflow "Build your feature"'
80
+ ? ' • View README: Press Ctrl+Shift+P → "Toggle Documentation"\n • Run workflow: /myaidev-workflow "Build your feature"'
81
81
  : cliType === 'gemini'
82
- ? ' • View commands: ls .gemini/commands/\n • Run workflow: /myai-sparc-workflow "Build your feature"'
83
- : ' • View commands: ls .opencode/commands/\n • Run workflow: /myai-sparc-workflow "Build your feature"';
82
+ ? ' • View commands: ls .gemini/commands/\n • Run workflow: /myaidev-workflow "Build your feature"'
83
+ : ' • View commands: ls .opencode/commands/\n • Run workflow: /myaidev-workflow "Build your feature"';
84
84
 
85
85
  return `
86
86
  ${chalk.green.bold('✨ Installation Complete!')}
@@ -4,7 +4,6 @@
4
4
  * Optimized for Claude Code 2.0 agent integration
5
5
  */
6
6
 
7
- import fetch from 'node-fetch';
8
7
  import { readFileSync } from 'fs';
9
8
  import { parse } from 'dotenv';
10
9
 
@@ -4,7 +4,6 @@
4
4
  * Optimized for Claude Code 2.0 agent integration
5
5
  */
6
6
 
7
- import fetch from 'node-fetch';
8
7
  import { readFileSync } from 'fs';
9
8
  import { parse } from 'dotenv';
10
9
  import { marked } from 'marked';
@@ -19,7 +19,6 @@
19
19
  * @module visual-generation-utils
20
20
  */
21
21
 
22
- import fetch from "node-fetch";
23
22
  import fs from "fs-extra";
24
23
  import path from "path";
25
24
  import dotenv from "dotenv";
@@ -4,7 +4,6 @@
4
4
  * Supports scriptable operations with predictable JSON output
5
5
  */
6
6
 
7
- import fetch from 'node-fetch';
8
7
  import { readFileSync } from 'fs';
9
8
  import { parse } from 'dotenv';
10
9