myaidev-method 0.3.3 → 0.3.5
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/.claude-plugin/plugin.json +0 -1
- package/.env.example +5 -4
- package/CHANGELOG.md +2 -2
- package/CONTENT_CREATION_GUIDE.md +489 -3211
- package/DEVELOPER_USE_CASES.md +1 -1
- package/MODULAR_INSTALLATION.md +2 -2
- package/README.md +39 -33
- package/TECHNICAL_ARCHITECTURE.md +1 -1
- package/USER_GUIDE.md +242 -190
- package/agents/content-editor-agent.md +90 -0
- package/agents/content-planner-agent.md +97 -0
- package/agents/content-research-agent.md +62 -0
- package/agents/content-seo-agent.md +101 -0
- package/agents/content-writer-agent.md +69 -0
- package/agents/infographic-analyzer-agent.md +63 -0
- package/agents/infographic-designer-agent.md +72 -0
- package/bin/cli.js +777 -535
- package/{content-rules.example.md → content-rules-example.md} +2 -2
- package/dist/mcp/health-check.js +82 -68
- package/dist/mcp/mcp-config.json +8 -0
- package/dist/mcp/openstack-server.js +1746 -1262
- package/dist/server/.tsbuildinfo +1 -1
- package/extension.json +21 -4
- package/package.json +181 -184
- package/skills/company-config/SKILL.md +133 -0
- package/skills/configure/SKILL.md +1 -1
- package/skills/myai-configurator/SKILL.md +77 -0
- package/skills/myai-configurator/content-creation-configurator/SKILL.md +516 -0
- package/skills/myai-configurator/content-maintenance-configurator/SKILL.md +397 -0
- package/skills/myai-content-enrichment/SKILL.md +114 -0
- package/skills/myai-content-ideation/SKILL.md +288 -0
- package/skills/myai-content-ideation/evals/evals.json +182 -0
- package/skills/myai-content-production-coordinator/SKILL.md +946 -0
- package/skills/{content-rules-setup → myai-content-rules-setup}/SKILL.md +1 -1
- package/skills/{content-verifier → myai-content-verifier}/SKILL.md +1 -1
- package/skills/myai-content-writer/SKILL.md +333 -0
- package/skills/myai-content-writer/agents/editor-agent.md +138 -0
- package/skills/myai-content-writer/agents/planner-agent.md +121 -0
- package/skills/myai-content-writer/agents/research-agent.md +83 -0
- package/skills/myai-content-writer/agents/seo-agent.md +139 -0
- package/skills/myai-content-writer/agents/visual-planner-agent.md +110 -0
- package/skills/myai-content-writer/agents/writer-agent.md +85 -0
- package/skills/{infographic → myai-infographic}/SKILL.md +1 -1
- package/skills/myai-proprietary-content-verifier/SKILL.md +175 -0
- package/skills/myai-proprietary-content-verifier/evals/evals.json +36 -0
- package/skills/myai-skill-builder/SKILL.md +699 -0
- package/skills/myai-skill-builder/agents/analyzer-agent.md +137 -0
- package/skills/myai-skill-builder/agents/comparator-agent.md +77 -0
- package/skills/myai-skill-builder/agents/grader-agent.md +103 -0
- package/skills/myai-skill-builder/assets/eval_review.html +131 -0
- package/skills/myai-skill-builder/references/schemas.md +211 -0
- package/skills/myai-skill-builder/scripts/aggregate_benchmark.py +190 -0
- package/skills/myai-skill-builder/scripts/generate_review.py +381 -0
- package/skills/myai-skill-builder/scripts/package_skill.py +91 -0
- package/skills/myai-skill-builder/scripts/run_eval.py +105 -0
- package/skills/myai-skill-builder/scripts/run_loop.py +211 -0
- package/skills/myai-skill-builder/scripts/utils.py +123 -0
- package/skills/myai-visual-generator/SKILL.md +125 -0
- package/skills/myai-visual-generator/evals/evals.json +155 -0
- package/skills/myai-visual-generator/references/infographic-pipeline.md +73 -0
- package/skills/myai-visual-generator/references/research-visuals.md +57 -0
- package/skills/myai-visual-generator/references/services.md +89 -0
- package/skills/myai-visual-generator/scripts/visual-generation-utils.js +1272 -0
- package/skills/myaidev-analyze/agents/dependency-mapper-agent.md +236 -0
- package/skills/myaidev-analyze/agents/pattern-detector-agent.md +240 -0
- package/skills/myaidev-analyze/agents/structure-scanner-agent.md +171 -0
- package/skills/myaidev-analyze/agents/tech-profiler-agent.md +291 -0
- package/skills/myaidev-architect/agents/compliance-checker-agent.md +287 -0
- package/skills/myaidev-architect/agents/requirements-analyst-agent.md +194 -0
- package/skills/myaidev-architect/agents/system-designer-agent.md +315 -0
- package/skills/myaidev-coder/agents/implementer-agent.md +185 -0
- package/skills/myaidev-coder/agents/integration-agent.md +168 -0
- package/skills/myaidev-coder/agents/pattern-scanner-agent.md +161 -0
- package/skills/myaidev-coder/agents/self-reviewer-agent.md +168 -0
- package/skills/myaidev-debug/agents/fix-agent-debug.md +317 -0
- package/skills/myaidev-debug/agents/hypothesis-agent.md +226 -0
- package/skills/myaidev-debug/agents/investigator-agent.md +250 -0
- package/skills/myaidev-debug/agents/symptom-collector-agent.md +231 -0
- package/skills/myaidev-documenter/agents/code-reader-agent.md +172 -0
- package/skills/myaidev-documenter/agents/doc-validator-agent.md +174 -0
- package/skills/myaidev-documenter/agents/doc-writer-agent.md +379 -0
- package/skills/myaidev-figma/SKILL.md +212 -0
- package/skills/myaidev-figma/capture.js +133 -0
- package/skills/myaidev-figma/crawl.js +130 -0
- package/skills/myaidev-figma-configure/SKILL.md +130 -0
- package/skills/myaidev-migrate/agents/migration-planner-agent.md +237 -0
- package/skills/myaidev-migrate/agents/migration-writer-agent.md +248 -0
- package/skills/myaidev-migrate/agents/schema-analyzer-agent.md +190 -0
- package/skills/myaidev-performance/agents/benchmark-agent.md +281 -0
- package/skills/myaidev-performance/agents/optimizer-agent.md +277 -0
- package/skills/myaidev-performance/agents/profiler-agent.md +252 -0
- package/skills/myaidev-refactor/agents/refactor-executor-agent.md +221 -0
- package/skills/myaidev-refactor/agents/refactor-planner-agent.md +213 -0
- package/skills/myaidev-refactor/agents/regression-guard-agent.md +242 -0
- package/skills/myaidev-refactor/agents/smell-detector-agent.md +233 -0
- package/skills/myaidev-reviewer/agents/auto-fixer-agent.md +238 -0
- package/skills/myaidev-reviewer/agents/code-analyst-agent.md +220 -0
- package/skills/myaidev-reviewer/agents/security-scanner-agent.md +262 -0
- package/skills/myaidev-tester/agents/coverage-analyst-agent.md +163 -0
- package/skills/myaidev-tester/agents/tdd-driver-agent.md +242 -0
- package/skills/myaidev-tester/agents/test-runner-agent.md +176 -0
- package/skills/myaidev-tester/agents/test-strategist-agent.md +154 -0
- package/skills/myaidev-tester/agents/test-writer-agent.md +242 -0
- package/skills/myaidev-workflow/agents/analyzer-agent.md +317 -0
- package/skills/myaidev-workflow/agents/coordinator-agent.md +253 -0
- package/skills/openstack-manager/SKILL.md +1 -1
- package/skills/payloadcms-publisher/SKILL.md +141 -77
- package/skills/payloadcms-publisher/references/field-mapping.md +142 -0
- package/skills/payloadcms-publisher/references/lexical-format.md +97 -0
- package/skills/security-auditor/SKILL.md +1 -1
- package/src/cli/commands/addon.js +184 -123
- package/src/config/workflows.js +172 -228
- package/src/lib/ascii-banner.js +197 -182
- package/src/lib/{content-coordinator.js → content-production-coordinator.js} +649 -459
- package/src/lib/installation-detector.js +93 -59
- package/src/lib/payloadcms-utils.js +285 -510
- package/src/lib/update-manager.js +120 -61
- package/src/lib/workflow-installer.js +55 -0
- package/src/mcp/health-check.js +82 -68
- package/src/mcp/openstack-server.js +1746 -1262
- package/src/scripts/configure-visual-apis.js +224 -173
- package/src/scripts/configure-wordpress-mcp.js +96 -66
- package/src/scripts/init/install.js +109 -85
- package/src/scripts/init-project.js +138 -67
- package/src/scripts/utils/write-content.js +67 -52
- package/src/scripts/wordpress/publish-to-wordpress.js +128 -128
- package/src/templates/claude/CLAUDE.md +131 -0
- package/hooks/hooks.json +0 -26
- package/skills/content-coordinator/SKILL.md +0 -130
- package/skills/content-enrichment/SKILL.md +0 -80
- package/skills/content-writer/SKILL.md +0 -285
- package/skills/visual-generator/SKILL.md +0 -140
package/bin/cli.js
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
|
-
import { program } from
|
|
4
|
-
import chalk from
|
|
5
|
-
import ora from
|
|
6
|
-
import fs from
|
|
7
|
-
import path from
|
|
8
|
-
import { fileURLToPath } from
|
|
9
|
-
import inquirer from
|
|
3
|
+
import { program } from "commander";
|
|
4
|
+
import chalk from "chalk";
|
|
5
|
+
import ora from "ora";
|
|
6
|
+
import fs from "fs-extra";
|
|
7
|
+
import path from "path";
|
|
8
|
+
import { fileURLToPath } from "url";
|
|
9
|
+
import inquirer from "inquirer";
|
|
10
10
|
import {
|
|
11
11
|
getASCIIBanner,
|
|
12
12
|
getSPARCBreakdown,
|
|
@@ -16,14 +16,101 @@ import {
|
|
|
16
16
|
getVisualWorkflowSuccess,
|
|
17
17
|
getDevWorkflowSuccess,
|
|
18
18
|
getPublishWorkflowSuccess,
|
|
19
|
-
getDeployWorkflowSuccess
|
|
20
|
-
} from
|
|
21
|
-
import { registerAuthCommands } from
|
|
22
|
-
import { registerAddonCommand } from
|
|
19
|
+
getDeployWorkflowSuccess,
|
|
20
|
+
} from "../src/lib/ascii-banner.js";
|
|
21
|
+
import { registerAuthCommands } from "../src/cli/commands/auth.js";
|
|
22
|
+
import { registerAddonCommand } from "../src/cli/commands/addon.js";
|
|
23
23
|
|
|
24
24
|
const __filename = fileURLToPath(import.meta.url);
|
|
25
25
|
const __dirname = path.dirname(__filename);
|
|
26
26
|
|
|
27
|
+
// ── Installation Packs ─────────────────────────────────────────────────
|
|
28
|
+
// Skills shared across all packs (always installed)
|
|
29
|
+
const CORE_SKILLS = [
|
|
30
|
+
"configure",
|
|
31
|
+
"company-config",
|
|
32
|
+
"myai-configurator",
|
|
33
|
+
];
|
|
34
|
+
|
|
35
|
+
const INSTALL_PACKS = {
|
|
36
|
+
content: {
|
|
37
|
+
name: "Content Creation",
|
|
38
|
+
audience: "Marketers & Content Teams",
|
|
39
|
+
description: "Content writing, SEO, visual generation, and multi-platform publishing",
|
|
40
|
+
skills: [
|
|
41
|
+
...CORE_SKILLS,
|
|
42
|
+
"myai-content-writer",
|
|
43
|
+
"myai-content-rules-setup",
|
|
44
|
+
"myai-content-verifier",
|
|
45
|
+
"myai-proprietary-content-verifier",
|
|
46
|
+
"myai-content-production-coordinator",
|
|
47
|
+
"myai-content-enrichment",
|
|
48
|
+
"myai-content-ideation",
|
|
49
|
+
"myai-visual-generator",
|
|
50
|
+
"myai-infographic",
|
|
51
|
+
"wordpress-publisher",
|
|
52
|
+
"payloadcms-publisher",
|
|
53
|
+
"astro-publisher",
|
|
54
|
+
"docusaurus-publisher",
|
|
55
|
+
"mintlify-publisher",
|
|
56
|
+
"deployer",
|
|
57
|
+
"coolify-deployer",
|
|
58
|
+
],
|
|
59
|
+
},
|
|
60
|
+
design: {
|
|
61
|
+
name: "Design",
|
|
62
|
+
audience: "Designers & Creative Teams",
|
|
63
|
+
description: "Figma design capture, visual generation, and design tooling",
|
|
64
|
+
skills: [
|
|
65
|
+
...CORE_SKILLS,
|
|
66
|
+
"myaidev-figma",
|
|
67
|
+
"myaidev-figma-configure",
|
|
68
|
+
"myai-visual-generator",
|
|
69
|
+
"myai-infographic",
|
|
70
|
+
],
|
|
71
|
+
},
|
|
72
|
+
dev: {
|
|
73
|
+
name: "Development",
|
|
74
|
+
audience: "Software Engineers",
|
|
75
|
+
description: "SPARC methodology, security testing, deployment, publishing, and skill development",
|
|
76
|
+
skills: [
|
|
77
|
+
...CORE_SKILLS,
|
|
78
|
+
"myaidev-workflow",
|
|
79
|
+
"myaidev-architect",
|
|
80
|
+
"myaidev-coder",
|
|
81
|
+
"myaidev-tester",
|
|
82
|
+
"myaidev-reviewer",
|
|
83
|
+
"myaidev-documenter",
|
|
84
|
+
"myaidev-analyze",
|
|
85
|
+
"myaidev-debug",
|
|
86
|
+
"myaidev-refactor",
|
|
87
|
+
"myaidev-performance",
|
|
88
|
+
"myaidev-migrate",
|
|
89
|
+
"security-tester",
|
|
90
|
+
"security-auditor",
|
|
91
|
+
"git-workflow",
|
|
92
|
+
"deployer",
|
|
93
|
+
"coolify-deployer",
|
|
94
|
+
"openstack-manager",
|
|
95
|
+
"wordpress-publisher",
|
|
96
|
+
"payloadcms-publisher",
|
|
97
|
+
"astro-publisher",
|
|
98
|
+
"docusaurus-publisher",
|
|
99
|
+
"mintlify-publisher",
|
|
100
|
+
"myai-skill-builder",
|
|
101
|
+
"skill-contributor",
|
|
102
|
+
],
|
|
103
|
+
},
|
|
104
|
+
};
|
|
105
|
+
|
|
106
|
+
function getAllSkillNames() {
|
|
107
|
+
const all = new Set();
|
|
108
|
+
for (const pack of Object.values(INSTALL_PACKS)) {
|
|
109
|
+
for (const s of pack.skills) all.add(s);
|
|
110
|
+
}
|
|
111
|
+
return [...all];
|
|
112
|
+
}
|
|
113
|
+
|
|
27
114
|
// Import WorkflowInstaller dynamically for modular installation
|
|
28
115
|
let WorkflowInstaller;
|
|
29
116
|
let getWorkflowNames;
|
|
@@ -31,8 +118,9 @@ let getWorkflowsByCategory;
|
|
|
31
118
|
|
|
32
119
|
async function loadWorkflowSystem() {
|
|
33
120
|
if (!WorkflowInstaller) {
|
|
34
|
-
const { default: Installer } =
|
|
35
|
-
|
|
121
|
+
const { default: Installer } =
|
|
122
|
+
await import("../src/lib/workflow-installer.js");
|
|
123
|
+
const workflows = await import("../src/config/workflows.js");
|
|
36
124
|
WorkflowInstaller = Installer;
|
|
37
125
|
getWorkflowNames = workflows.getWorkflowNames;
|
|
38
126
|
getWorkflowsByCategory = workflows.getWorkflowsByCategory;
|
|
@@ -40,77 +128,89 @@ async function loadWorkflowSystem() {
|
|
|
40
128
|
}
|
|
41
129
|
|
|
42
130
|
program
|
|
43
|
-
.version(
|
|
131
|
+
.version("0.3.5")
|
|
44
132
|
.enablePositionalOptions()
|
|
45
|
-
.description(
|
|
133
|
+
.description(
|
|
134
|
+
"MyAIDev Method - Comprehensive development framework with SPARC methodology",
|
|
135
|
+
);
|
|
46
136
|
|
|
47
137
|
// Helper function for CLI type selection
|
|
48
138
|
async function selectCLIType(options) {
|
|
49
|
-
if (options.claude) return
|
|
50
|
-
if (options.gemini) return
|
|
51
|
-
if (options.codex) return
|
|
139
|
+
if (options.claude) return "claude";
|
|
140
|
+
if (options.gemini) return "gemini";
|
|
141
|
+
if (options.codex) return "codex";
|
|
52
142
|
|
|
53
143
|
// Interactive selection if no flag provided
|
|
54
144
|
const answer = await inquirer.prompt([
|
|
55
145
|
{
|
|
56
|
-
type:
|
|
57
|
-
name:
|
|
58
|
-
message:
|
|
146
|
+
type: "list",
|
|
147
|
+
name: "cliType",
|
|
148
|
+
message: "Which AI CLI are you configuring for?",
|
|
59
149
|
choices: [
|
|
60
|
-
{ name:
|
|
61
|
-
{ name:
|
|
62
|
-
{ name:
|
|
150
|
+
{ name: "Claude Code (Recommended)", value: "claude" },
|
|
151
|
+
{ name: "Gemini CLI", value: "gemini" },
|
|
152
|
+
{ name: "Codex CLI / OpenCode", value: "codex" },
|
|
63
153
|
],
|
|
64
|
-
default:
|
|
65
|
-
}
|
|
154
|
+
default: "claude",
|
|
155
|
+
},
|
|
66
156
|
]);
|
|
67
157
|
return answer.cliType;
|
|
68
158
|
}
|
|
69
159
|
|
|
70
160
|
// Modular workflow installation commands
|
|
71
161
|
program
|
|
72
|
-
.command(
|
|
73
|
-
.description(
|
|
74
|
-
.option(
|
|
75
|
-
.option(
|
|
76
|
-
.option(
|
|
77
|
-
.option(
|
|
78
|
-
.option(
|
|
162
|
+
.command("content")
|
|
163
|
+
.description("Install content creation workflow")
|
|
164
|
+
.option("--claude", "Install for Claude Code")
|
|
165
|
+
.option("--gemini", "Install for Gemini CLI")
|
|
166
|
+
.option("--codex", "Install for Codex CLI")
|
|
167
|
+
.option("--dry-run", "Show what would be installed without making changes")
|
|
168
|
+
.option("--verbose", "Show detailed progress")
|
|
79
169
|
.action(async (options) => {
|
|
80
170
|
// Display workflow banner
|
|
81
|
-
console.log(getWorkflowBanner(
|
|
171
|
+
console.log(getWorkflowBanner("content"));
|
|
82
172
|
|
|
83
173
|
const cliType = await selectCLIType(options);
|
|
84
174
|
|
|
85
175
|
// For non-Claude CLIs, inform user about limited support
|
|
86
|
-
if (cliType !==
|
|
87
|
-
console.log(
|
|
88
|
-
|
|
176
|
+
if (cliType !== "claude") {
|
|
177
|
+
console.log(
|
|
178
|
+
chalk.yellow(`\nNote: Content workflow is optimized for Claude Code.`),
|
|
179
|
+
);
|
|
180
|
+
console.log(
|
|
181
|
+
chalk.gray(`Some features may have limited support for ${cliType}.\n`),
|
|
182
|
+
);
|
|
89
183
|
}
|
|
90
184
|
|
|
91
|
-
const spinner = ora(
|
|
185
|
+
const spinner = ora("Installing content creation workflow...").start();
|
|
92
186
|
|
|
93
187
|
try {
|
|
94
188
|
await loadWorkflowSystem();
|
|
95
189
|
const installer = new WorkflowInstaller({
|
|
96
190
|
projectRoot: process.cwd(),
|
|
97
191
|
verbose: options.verbose,
|
|
98
|
-
dryRun: options.dryRun
|
|
192
|
+
dryRun: options.dryRun,
|
|
99
193
|
});
|
|
100
|
-
const result = await installer.install([
|
|
194
|
+
const result = await installer.install(["content"]);
|
|
101
195
|
|
|
102
196
|
if (options.dryRun) {
|
|
103
|
-
spinner.succeed(chalk.yellow(
|
|
197
|
+
spinner.succeed(chalk.yellow("Dry run complete - no changes made"));
|
|
104
198
|
} else {
|
|
105
|
-
spinner.succeed(
|
|
199
|
+
spinner.succeed(
|
|
200
|
+
chalk.green("Content workflow installed successfully!"),
|
|
201
|
+
);
|
|
106
202
|
|
|
107
203
|
// Display rich success message
|
|
108
204
|
console.log(getContentWorkflowSuccess(result.results || [], cliType));
|
|
109
205
|
|
|
110
|
-
console.log(
|
|
206
|
+
console.log(
|
|
207
|
+
chalk.cyan(
|
|
208
|
+
`\n🔄 Restart ${cliType} to load your new content commands!`,
|
|
209
|
+
),
|
|
210
|
+
);
|
|
111
211
|
}
|
|
112
212
|
} catch (error) {
|
|
113
|
-
spinner.fail(chalk.red(
|
|
213
|
+
spinner.fail(chalk.red("Failed to install content workflow"));
|
|
114
214
|
console.error(chalk.red(error.message));
|
|
115
215
|
if (options.verbose) console.error(error);
|
|
116
216
|
process.exit(1);
|
|
@@ -118,48 +218,58 @@ program
|
|
|
118
218
|
});
|
|
119
219
|
|
|
120
220
|
program
|
|
121
|
-
.command(
|
|
122
|
-
.description(
|
|
123
|
-
.option(
|
|
124
|
-
.option(
|
|
125
|
-
.option(
|
|
126
|
-
.option(
|
|
127
|
-
.option(
|
|
221
|
+
.command("visual")
|
|
222
|
+
.description("Install visual content generation workflow")
|
|
223
|
+
.option("--claude", "Install for Claude Code")
|
|
224
|
+
.option("--gemini", "Install for Gemini CLI")
|
|
225
|
+
.option("--codex", "Install for Codex CLI")
|
|
226
|
+
.option("--dry-run", "Show what would be installed without making changes")
|
|
227
|
+
.option("--verbose", "Show detailed progress")
|
|
128
228
|
.action(async (options) => {
|
|
129
229
|
// Display workflow banner
|
|
130
|
-
console.log(getWorkflowBanner(
|
|
230
|
+
console.log(getWorkflowBanner("visual"));
|
|
131
231
|
|
|
132
232
|
const cliType = await selectCLIType(options);
|
|
133
233
|
|
|
134
234
|
// For non-Claude CLIs, inform user about limited support
|
|
135
|
-
if (cliType !==
|
|
136
|
-
console.log(
|
|
137
|
-
|
|
235
|
+
if (cliType !== "claude") {
|
|
236
|
+
console.log(
|
|
237
|
+
chalk.yellow(`\nNote: Visual workflow is optimized for Claude Code.`),
|
|
238
|
+
);
|
|
239
|
+
console.log(
|
|
240
|
+
chalk.gray(`Some features may have limited support for ${cliType}.\n`),
|
|
241
|
+
);
|
|
138
242
|
}
|
|
139
243
|
|
|
140
|
-
const spinner = ora(
|
|
244
|
+
const spinner = ora(
|
|
245
|
+
"Installing visual content generation workflow...",
|
|
246
|
+
).start();
|
|
141
247
|
|
|
142
248
|
try {
|
|
143
249
|
await loadWorkflowSystem();
|
|
144
250
|
const installer = new WorkflowInstaller({
|
|
145
251
|
projectRoot: process.cwd(),
|
|
146
252
|
verbose: options.verbose,
|
|
147
|
-
dryRun: options.dryRun
|
|
253
|
+
dryRun: options.dryRun,
|
|
148
254
|
});
|
|
149
|
-
const result = await installer.install([
|
|
255
|
+
const result = await installer.install(["visual"]);
|
|
150
256
|
|
|
151
257
|
if (options.dryRun) {
|
|
152
|
-
spinner.succeed(chalk.yellow(
|
|
258
|
+
spinner.succeed(chalk.yellow("Dry run complete - no changes made"));
|
|
153
259
|
} else {
|
|
154
|
-
spinner.succeed(chalk.green(
|
|
260
|
+
spinner.succeed(chalk.green("Visual workflow installed successfully!"));
|
|
155
261
|
|
|
156
262
|
// Display rich success message
|
|
157
263
|
console.log(getVisualWorkflowSuccess(result.results || [], cliType));
|
|
158
264
|
|
|
159
|
-
console.log(
|
|
265
|
+
console.log(
|
|
266
|
+
chalk.cyan(
|
|
267
|
+
`\n🔄 Restart ${cliType} to load your new visual commands!`,
|
|
268
|
+
),
|
|
269
|
+
);
|
|
160
270
|
}
|
|
161
271
|
} catch (error) {
|
|
162
|
-
spinner.fail(chalk.red(
|
|
272
|
+
spinner.fail(chalk.red("Failed to install visual workflow"));
|
|
163
273
|
console.error(chalk.red(error.message));
|
|
164
274
|
if (options.verbose) console.error(error);
|
|
165
275
|
process.exit(1);
|
|
@@ -167,47 +277,59 @@ program
|
|
|
167
277
|
});
|
|
168
278
|
|
|
169
279
|
program
|
|
170
|
-
.command(
|
|
171
|
-
.description(
|
|
172
|
-
.option(
|
|
173
|
-
.option(
|
|
174
|
-
.option(
|
|
175
|
-
.option(
|
|
176
|
-
.option(
|
|
280
|
+
.command("dev")
|
|
281
|
+
.description("Install development workflow (SPARC methodology)")
|
|
282
|
+
.option("--claude", "Install for Claude Code")
|
|
283
|
+
.option("--gemini", "Install for Gemini CLI")
|
|
284
|
+
.option("--codex", "Install for Codex CLI")
|
|
285
|
+
.option("--dry-run", "Show what would be installed without making changes")
|
|
286
|
+
.option("--verbose", "Show detailed progress")
|
|
177
287
|
.action(async (options) => {
|
|
178
288
|
// Display workflow banner
|
|
179
|
-
console.log(getWorkflowBanner(
|
|
289
|
+
console.log(getWorkflowBanner("development"));
|
|
180
290
|
|
|
181
291
|
const cliType = await selectCLIType(options);
|
|
182
292
|
|
|
183
|
-
if (cliType !==
|
|
184
|
-
console.log(
|
|
185
|
-
|
|
293
|
+
if (cliType !== "claude") {
|
|
294
|
+
console.log(
|
|
295
|
+
chalk.yellow(
|
|
296
|
+
`\nNote: Development workflow is optimized for Claude Code.`,
|
|
297
|
+
),
|
|
298
|
+
);
|
|
299
|
+
console.log(
|
|
300
|
+
chalk.gray(`Some features may have limited support for ${cliType}.\n`),
|
|
301
|
+
);
|
|
186
302
|
}
|
|
187
303
|
|
|
188
|
-
const spinner = ora(
|
|
304
|
+
const spinner = ora("Installing SPARC development workflow...").start();
|
|
189
305
|
|
|
190
306
|
try {
|
|
191
307
|
await loadWorkflowSystem();
|
|
192
308
|
const installer = new WorkflowInstaller({
|
|
193
309
|
projectRoot: process.cwd(),
|
|
194
310
|
verbose: options.verbose,
|
|
195
|
-
dryRun: options.dryRun
|
|
311
|
+
dryRun: options.dryRun,
|
|
196
312
|
});
|
|
197
|
-
const result = await installer.install([
|
|
313
|
+
const result = await installer.install(["development"]);
|
|
198
314
|
|
|
199
315
|
if (options.dryRun) {
|
|
200
|
-
spinner.succeed(chalk.yellow(
|
|
316
|
+
spinner.succeed(chalk.yellow("Dry run complete - no changes made"));
|
|
201
317
|
} else {
|
|
202
|
-
spinner.succeed(
|
|
318
|
+
spinner.succeed(
|
|
319
|
+
chalk.green("Development workflow installed successfully!"),
|
|
320
|
+
);
|
|
203
321
|
|
|
204
322
|
// Display rich success message
|
|
205
323
|
console.log(getDevWorkflowSuccess(result.results || [], cliType));
|
|
206
324
|
|
|
207
|
-
console.log(
|
|
325
|
+
console.log(
|
|
326
|
+
chalk.cyan(
|
|
327
|
+
`\n🔄 Restart ${cliType} to load your new development commands!`,
|
|
328
|
+
),
|
|
329
|
+
);
|
|
208
330
|
}
|
|
209
331
|
} catch (error) {
|
|
210
|
-
spinner.fail(chalk.red(
|
|
332
|
+
spinner.fail(chalk.red("Failed to install development workflow"));
|
|
211
333
|
console.error(chalk.red(error.message));
|
|
212
334
|
if (options.verbose) console.error(error);
|
|
213
335
|
process.exit(1);
|
|
@@ -215,54 +337,70 @@ program
|
|
|
215
337
|
});
|
|
216
338
|
|
|
217
339
|
program
|
|
218
|
-
.command(
|
|
219
|
-
.description(
|
|
220
|
-
.option(
|
|
221
|
-
.option(
|
|
222
|
-
.option(
|
|
223
|
-
.option(
|
|
224
|
-
.option(
|
|
225
|
-
.option(
|
|
340
|
+
.command("publish")
|
|
341
|
+
.description("Install publishing workflows")
|
|
342
|
+
.option("--wordpress", "Install WordPress publishing")
|
|
343
|
+
.option("--payloadcms", "Install PayloadCMS publishing")
|
|
344
|
+
.option("--static", "Install static site publishing")
|
|
345
|
+
.option("--all", "Install all publishing workflows")
|
|
346
|
+
.option("--dry-run", "Show what would be installed without making changes")
|
|
347
|
+
.option("--verbose", "Show detailed progress")
|
|
226
348
|
.action(async (options) => {
|
|
227
349
|
// Display workflow banner
|
|
228
|
-
console.log(getWorkflowBanner(
|
|
350
|
+
console.log(getWorkflowBanner("publish"));
|
|
229
351
|
|
|
230
352
|
const workflows = [];
|
|
231
|
-
if (options.wordpress) workflows.push(
|
|
232
|
-
if (options.payloadcms) workflows.push(
|
|
233
|
-
if (options.static) workflows.push(
|
|
353
|
+
if (options.wordpress) workflows.push("publish-wordpress");
|
|
354
|
+
if (options.payloadcms) workflows.push("publish-payloadcms");
|
|
355
|
+
if (options.static) workflows.push("publish-static");
|
|
234
356
|
if (options.all) {
|
|
235
|
-
workflows.push(
|
|
357
|
+
workflows.push(
|
|
358
|
+
"publish-wordpress",
|
|
359
|
+
"publish-payloadcms",
|
|
360
|
+
"publish-static",
|
|
361
|
+
);
|
|
236
362
|
}
|
|
237
363
|
if (workflows.length === 0) {
|
|
238
|
-
console.log(
|
|
239
|
-
|
|
364
|
+
console.log(
|
|
365
|
+
chalk.yellow("Please specify at least one publishing workflow:"),
|
|
366
|
+
);
|
|
367
|
+
console.log(
|
|
368
|
+
chalk.gray(" --wordpress, --payloadcms, --static, or --all"),
|
|
369
|
+
);
|
|
240
370
|
process.exit(1);
|
|
241
371
|
}
|
|
242
372
|
|
|
243
|
-
const spinner = ora(
|
|
373
|
+
const spinner = ora("Installing publishing workflows...").start();
|
|
244
374
|
|
|
245
375
|
try {
|
|
246
376
|
await loadWorkflowSystem();
|
|
247
377
|
const installer = new WorkflowInstaller({
|
|
248
378
|
projectRoot: process.cwd(),
|
|
249
379
|
verbose: options.verbose,
|
|
250
|
-
dryRun: options.dryRun
|
|
380
|
+
dryRun: options.dryRun,
|
|
251
381
|
});
|
|
252
382
|
const result = await installer.install(workflows);
|
|
253
383
|
|
|
254
384
|
if (options.dryRun) {
|
|
255
|
-
spinner.succeed(chalk.yellow(
|
|
385
|
+
spinner.succeed(chalk.yellow("Dry run complete - no changes made"));
|
|
256
386
|
} else {
|
|
257
|
-
spinner.succeed(
|
|
387
|
+
spinner.succeed(
|
|
388
|
+
chalk.green("Publishing workflows installed successfully!"),
|
|
389
|
+
);
|
|
258
390
|
|
|
259
391
|
// Display rich success message
|
|
260
|
-
console.log(
|
|
392
|
+
console.log(
|
|
393
|
+
getPublishWorkflowSuccess(workflows, result.results || [], "claude"),
|
|
394
|
+
);
|
|
261
395
|
|
|
262
|
-
console.log(
|
|
396
|
+
console.log(
|
|
397
|
+
chalk.cyan(
|
|
398
|
+
`\n🔄 Restart Claude Code to load your new publishing commands!`,
|
|
399
|
+
),
|
|
400
|
+
);
|
|
263
401
|
}
|
|
264
402
|
} catch (error) {
|
|
265
|
-
spinner.fail(chalk.red(
|
|
403
|
+
spinner.fail(chalk.red("Failed to install publishing workflows"));
|
|
266
404
|
console.error(chalk.red(error.message));
|
|
267
405
|
if (options.verbose) console.error(error);
|
|
268
406
|
process.exit(1);
|
|
@@ -270,46 +408,54 @@ program
|
|
|
270
408
|
});
|
|
271
409
|
|
|
272
410
|
program
|
|
273
|
-
.command(
|
|
274
|
-
.description(
|
|
275
|
-
.option(
|
|
276
|
-
.option(
|
|
277
|
-
.option(
|
|
278
|
-
.option(
|
|
411
|
+
.command("deploy")
|
|
412
|
+
.description("Install deployment workflows")
|
|
413
|
+
.option("--coolify", "Install Coolify deployment")
|
|
414
|
+
.option("--all", "Install all deployment workflows")
|
|
415
|
+
.option("--dry-run", "Show what would be installed without making changes")
|
|
416
|
+
.option("--verbose", "Show detailed progress")
|
|
279
417
|
.action(async (options) => {
|
|
280
418
|
// Display workflow banner
|
|
281
|
-
console.log(getWorkflowBanner(
|
|
419
|
+
console.log(getWorkflowBanner("deploy"));
|
|
282
420
|
|
|
283
421
|
const workflows = [];
|
|
284
|
-
if (options.coolify) workflows.push(
|
|
285
|
-
if (options.all) workflows.push(
|
|
422
|
+
if (options.coolify) workflows.push("coolify");
|
|
423
|
+
if (options.all) workflows.push("deployment", "coolify");
|
|
286
424
|
if (workflows.length === 0) {
|
|
287
|
-
workflows.push(
|
|
425
|
+
workflows.push("deployment");
|
|
288
426
|
}
|
|
289
427
|
|
|
290
|
-
const spinner = ora(
|
|
428
|
+
const spinner = ora("Installing deployment workflows...").start();
|
|
291
429
|
|
|
292
430
|
try {
|
|
293
431
|
await loadWorkflowSystem();
|
|
294
432
|
const installer = new WorkflowInstaller({
|
|
295
433
|
projectRoot: process.cwd(),
|
|
296
434
|
verbose: options.verbose,
|
|
297
|
-
dryRun: options.dryRun
|
|
435
|
+
dryRun: options.dryRun,
|
|
298
436
|
});
|
|
299
437
|
const result = await installer.install(workflows);
|
|
300
438
|
|
|
301
439
|
if (options.dryRun) {
|
|
302
|
-
spinner.succeed(chalk.yellow(
|
|
440
|
+
spinner.succeed(chalk.yellow("Dry run complete - no changes made"));
|
|
303
441
|
} else {
|
|
304
|
-
spinner.succeed(
|
|
442
|
+
spinner.succeed(
|
|
443
|
+
chalk.green("Deployment workflows installed successfully!"),
|
|
444
|
+
);
|
|
305
445
|
|
|
306
446
|
// Display rich success message
|
|
307
|
-
console.log(
|
|
447
|
+
console.log(
|
|
448
|
+
getDeployWorkflowSuccess(workflows, result.results || [], "claude"),
|
|
449
|
+
);
|
|
308
450
|
|
|
309
|
-
console.log(
|
|
451
|
+
console.log(
|
|
452
|
+
chalk.cyan(
|
|
453
|
+
`\n🔄 Restart Claude Code to load your new deployment commands!`,
|
|
454
|
+
),
|
|
455
|
+
);
|
|
310
456
|
}
|
|
311
457
|
} catch (error) {
|
|
312
|
-
spinner.fail(chalk.red(
|
|
458
|
+
spinner.fail(chalk.red("Failed to install deployment workflows"));
|
|
313
459
|
console.error(chalk.red(error.message));
|
|
314
460
|
if (options.verbose) console.error(error);
|
|
315
461
|
process.exit(1);
|
|
@@ -318,38 +464,38 @@ program
|
|
|
318
464
|
|
|
319
465
|
// Workflow management commands
|
|
320
466
|
program
|
|
321
|
-
.command(
|
|
322
|
-
.description(
|
|
323
|
-
.option(
|
|
324
|
-
.option(
|
|
467
|
+
.command("add <workflow>")
|
|
468
|
+
.description("Add a workflow to your installation")
|
|
469
|
+
.option("--dry-run", "Show what would be installed without making changes")
|
|
470
|
+
.option("--verbose", "Show detailed progress")
|
|
325
471
|
.action(async (workflow, options) => {
|
|
326
472
|
await loadWorkflowSystem();
|
|
327
473
|
const installer = new WorkflowInstaller({
|
|
328
474
|
projectRoot: process.cwd(),
|
|
329
475
|
verbose: options.verbose,
|
|
330
|
-
dryRun: options.dryRun
|
|
476
|
+
dryRun: options.dryRun,
|
|
331
477
|
});
|
|
332
478
|
await installer.install([workflow]);
|
|
333
479
|
});
|
|
334
480
|
|
|
335
481
|
program
|
|
336
|
-
.command(
|
|
337
|
-
.description(
|
|
338
|
-
.option(
|
|
339
|
-
.option(
|
|
482
|
+
.command("remove <workflow>")
|
|
483
|
+
.description("Remove a workflow from your installation")
|
|
484
|
+
.option("--dry-run", "Show what would be removed without making changes")
|
|
485
|
+
.option("--verbose", "Show detailed progress")
|
|
340
486
|
.action(async (workflow, options) => {
|
|
341
487
|
await loadWorkflowSystem();
|
|
342
488
|
const installer = new WorkflowInstaller({
|
|
343
489
|
projectRoot: process.cwd(),
|
|
344
490
|
verbose: options.verbose,
|
|
345
|
-
dryRun: options.dryRun
|
|
491
|
+
dryRun: options.dryRun,
|
|
346
492
|
});
|
|
347
493
|
await installer.removeWorkflow(workflow);
|
|
348
494
|
});
|
|
349
495
|
|
|
350
496
|
program
|
|
351
|
-
.command(
|
|
352
|
-
.description(
|
|
497
|
+
.command("list")
|
|
498
|
+
.description("List installed workflows")
|
|
353
499
|
.action(async () => {
|
|
354
500
|
await loadWorkflowSystem();
|
|
355
501
|
const installer = new WorkflowInstaller({ projectRoot: process.cwd() });
|
|
@@ -357,8 +503,8 @@ program
|
|
|
357
503
|
});
|
|
358
504
|
|
|
359
505
|
program
|
|
360
|
-
.command(
|
|
361
|
-
.description(
|
|
506
|
+
.command("status")
|
|
507
|
+
.description("Show workflow installation status")
|
|
362
508
|
.action(async () => {
|
|
363
509
|
await loadWorkflowSystem();
|
|
364
510
|
const installer = new WorkflowInstaller({ projectRoot: process.cwd() });
|
|
@@ -366,105 +512,193 @@ program
|
|
|
366
512
|
});
|
|
367
513
|
|
|
368
514
|
program
|
|
369
|
-
.command(
|
|
370
|
-
.description(
|
|
371
|
-
.option(
|
|
372
|
-
.option(
|
|
373
|
-
.option(
|
|
515
|
+
.command("init")
|
|
516
|
+
.description("Initialize AI CLI configuration with a skill pack")
|
|
517
|
+
.option("--claude", "Initialize for Claude Code")
|
|
518
|
+
.option("--gemini", "Initialize for Gemini CLI")
|
|
519
|
+
.option("--codex", "Initialize for Codex CLI")
|
|
520
|
+
.option("--pack <pack>", "Install a specific pack: content, design, dev, or full")
|
|
374
521
|
.action(async (options) => {
|
|
375
|
-
const spinner = ora('Initializing AI CLI configuration...').start();
|
|
376
|
-
|
|
377
522
|
try {
|
|
378
523
|
const cwd = process.cwd();
|
|
524
|
+
|
|
525
|
+
// Step 1: Determine CLI type
|
|
379
526
|
let cliType = null;
|
|
380
|
-
|
|
381
|
-
// Determine CLI type
|
|
382
527
|
if (options.claude) {
|
|
383
|
-
cliType =
|
|
528
|
+
cliType = "claude";
|
|
384
529
|
} else if (options.gemini) {
|
|
385
|
-
cliType =
|
|
530
|
+
cliType = "gemini";
|
|
386
531
|
} else if (options.codex) {
|
|
387
|
-
cliType =
|
|
532
|
+
cliType = "codex";
|
|
388
533
|
} else {
|
|
389
|
-
spinner.stop();
|
|
390
|
-
// Interactive selection if no flag provided
|
|
391
534
|
const answer = await inquirer.prompt([
|
|
392
535
|
{
|
|
393
|
-
type:
|
|
394
|
-
name:
|
|
395
|
-
message:
|
|
536
|
+
type: "list",
|
|
537
|
+
name: "cliType",
|
|
538
|
+
message: "Which AI CLI are you configuring for?",
|
|
396
539
|
choices: [
|
|
397
|
-
{ name:
|
|
398
|
-
{ name:
|
|
399
|
-
{ name:
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
}
|
|
540
|
+
{ name: "Claude Code (Recommended)", value: "claude" },
|
|
541
|
+
{ name: "Gemini CLI", value: "gemini" },
|
|
542
|
+
{ name: "Codex CLI / OpenCode", value: "codex" },
|
|
543
|
+
],
|
|
544
|
+
default: "claude",
|
|
545
|
+
},
|
|
403
546
|
]);
|
|
404
547
|
cliType = answer.cliType;
|
|
405
|
-
spinner.start();
|
|
406
548
|
}
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
await setupCodex(cwd);
|
|
549
|
+
|
|
550
|
+
// Step 2: Determine pack
|
|
551
|
+
let pack = options.pack || null;
|
|
552
|
+
if (pack && !["content", "design", "dev", "full"].includes(pack)) {
|
|
553
|
+
console.log(chalk.red(`\nUnknown pack: "${pack}"`));
|
|
554
|
+
console.log(chalk.gray("Available packs: content, design, dev, full\n"));
|
|
555
|
+
process.exit(1);
|
|
415
556
|
}
|
|
416
|
-
|
|
417
|
-
spinner.succeed(chalk.green(`Successfully initialized ${cliType} configuration!`));
|
|
418
557
|
|
|
419
|
-
|
|
558
|
+
if (!pack) {
|
|
559
|
+
console.log("");
|
|
560
|
+
const answer = await inquirer.prompt([
|
|
561
|
+
{
|
|
562
|
+
type: "list",
|
|
563
|
+
name: "pack",
|
|
564
|
+
message: "What do you want to use MyAIDev Method for?",
|
|
565
|
+
choices: [
|
|
566
|
+
{
|
|
567
|
+
name: `${chalk.green("Content Creation")} ${chalk.gray("— For marketers: writing, SEO, visuals, publishing")}`,
|
|
568
|
+
value: "content",
|
|
569
|
+
},
|
|
570
|
+
{
|
|
571
|
+
name: `${chalk.magenta("Design")} ${chalk.gray("— For designers: Figma capture, visual generation")}`,
|
|
572
|
+
value: "design",
|
|
573
|
+
},
|
|
574
|
+
{
|
|
575
|
+
name: `${chalk.blue("Development")} ${chalk.gray("— For engineers: SPARC, security, deploy, git")}`,
|
|
576
|
+
value: "dev",
|
|
577
|
+
},
|
|
578
|
+
{
|
|
579
|
+
name: `${chalk.yellow("Full")} ${chalk.gray("— Everything (all skills)")}`,
|
|
580
|
+
value: "full",
|
|
581
|
+
},
|
|
582
|
+
],
|
|
583
|
+
},
|
|
584
|
+
]);
|
|
585
|
+
pack = answer.pack;
|
|
586
|
+
}
|
|
587
|
+
|
|
588
|
+
// Resolve skill list
|
|
589
|
+
let skillList;
|
|
590
|
+
let packLabel;
|
|
591
|
+
if (pack === "full") {
|
|
592
|
+
skillList = null; // null = install all
|
|
593
|
+
packLabel = "Full (all skills)";
|
|
594
|
+
} else {
|
|
595
|
+
const packDef = INSTALL_PACKS[pack];
|
|
596
|
+
skillList = packDef.skills;
|
|
597
|
+
packLabel = `${packDef.name} — ${packDef.audience}`;
|
|
598
|
+
}
|
|
599
|
+
|
|
600
|
+
// Step 3: Install
|
|
601
|
+
const spinner = ora(`Installing ${packLabel}...`).start();
|
|
602
|
+
|
|
603
|
+
if (cliType === "claude") {
|
|
604
|
+
await setupClaude(cwd, skillList);
|
|
605
|
+
} else if (cliType === "gemini") {
|
|
606
|
+
await setupGemini(cwd, skillList);
|
|
607
|
+
} else if (cliType === "codex") {
|
|
608
|
+
await setupCodex(cwd, skillList);
|
|
609
|
+
}
|
|
610
|
+
|
|
611
|
+
spinner.succeed(
|
|
612
|
+
chalk.green(`Successfully initialized ${cliType} with ${packLabel}!`),
|
|
613
|
+
);
|
|
614
|
+
|
|
615
|
+
// Display ASCII banner
|
|
420
616
|
console.log(getASCIIBanner());
|
|
421
617
|
console.log(getSPARCBreakdown());
|
|
422
618
|
console.log(getInitSuccessMessage(cliType));
|
|
423
619
|
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
console.log(chalk.
|
|
433
|
-
console.log(chalk.
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
620
|
+
// Display installed skills summary
|
|
621
|
+
if (cliType === "claude") {
|
|
622
|
+
const installedCount = skillList
|
|
623
|
+
? skillList.length
|
|
624
|
+
: (await fs.readdir(path.join(cwd, ".claude", "skills"))).filter(
|
|
625
|
+
async (d) => (await fs.stat(path.join(cwd, ".claude", "skills", d))).isDirectory()
|
|
626
|
+
).length;
|
|
627
|
+
|
|
628
|
+
console.log(chalk.magenta(`\n🧠 Skills Installed (.claude/skills/):`));
|
|
629
|
+
console.log(chalk.gray(` ${packLabel} — ${skillList ? skillList.length : 'all'} skills\n`));
|
|
630
|
+
|
|
631
|
+
if (pack === "content" || pack === "full") {
|
|
632
|
+
console.log(chalk.green(" Content: myai-content-writer, myai-content-production-coordinator, myai-content-ideation"));
|
|
633
|
+
console.log(chalk.green(" Visual: myai-visual-generator, myai-infographic"));
|
|
634
|
+
console.log(chalk.yellow(" Publishing: wordpress, payloadcms, docusaurus, mintlify, astro"));
|
|
635
|
+
}
|
|
636
|
+
if (pack === "design" || pack === "full") {
|
|
637
|
+
console.log(chalk.magenta(" Design: myaidev-figma, myaidev-figma-configure"));
|
|
638
|
+
console.log(chalk.magenta(" Visual: myai-visual-generator, myai-infographic"));
|
|
639
|
+
}
|
|
640
|
+
if (pack === "dev" || pack === "full") {
|
|
641
|
+
console.log(chalk.blue(" SPARC: myaidev-workflow, myaidev-architect, myaidev-coder, myaidev-tester"));
|
|
642
|
+
console.log(chalk.cyan(" Git: git-workflow (pr, release, sync, hotfix)"));
|
|
643
|
+
console.log(chalk.red(" Security: security-tester, security-auditor"));
|
|
644
|
+
console.log(chalk.blue(" Deploy: deployer, coolify-deployer, openstack-manager"));
|
|
645
|
+
console.log(chalk.blue(" Skills: myai-skill-builder, skill-contributor"));
|
|
646
|
+
}
|
|
647
|
+
console.log(chalk.gray(" Config: configure, company-config, myai-configurator"));
|
|
648
|
+
|
|
649
|
+
console.log(chalk.cyan("\n⚙️ Get started:"));
|
|
650
|
+
console.log(
|
|
651
|
+
chalk.white(" 1. npx myaidev-method login") +
|
|
652
|
+
chalk.gray(" — authenticate with the marketplace"),
|
|
653
|
+
);
|
|
654
|
+
console.log(
|
|
655
|
+
chalk.white(" 2. npx myaidev-method addon list") +
|
|
656
|
+
chalk.gray(" — browse available skills"),
|
|
657
|
+
);
|
|
658
|
+
console.log(
|
|
659
|
+
chalk.white(" 3. npx myaidev-method addon install <name>") +
|
|
660
|
+
chalk.gray(" — install a skill"),
|
|
661
|
+
);
|
|
662
|
+
console.log(
|
|
663
|
+
chalk.gray("\n • Use the configure skill to set up platform credentials"),
|
|
664
|
+
);
|
|
665
|
+
console.log(
|
|
666
|
+
chalk.gray(" • Add more skills later: npx myaidev-method init --claude --pack <pack>"),
|
|
667
|
+
);
|
|
668
|
+
console.log(
|
|
669
|
+
chalk.gray(" • Visit: https://github.com/myaione/myaidev-method"),
|
|
670
|
+
);
|
|
443
671
|
}
|
|
444
672
|
console.log(chalk.cyan(`\n🔄 Restart ${cliType} to load skills!`));
|
|
445
|
-
|
|
446
673
|
} catch (error) {
|
|
447
|
-
|
|
674
|
+
if (error.name === 'ExitPromptError') {
|
|
675
|
+
console.log(chalk.gray("\nCancelled.\n"));
|
|
676
|
+
return;
|
|
677
|
+
}
|
|
678
|
+
console.error(chalk.red("Failed to initialize configuration"));
|
|
448
679
|
console.error(error);
|
|
449
680
|
process.exit(1);
|
|
450
681
|
}
|
|
451
682
|
});
|
|
452
683
|
|
|
453
|
-
async function setupClaude(projectDir) {
|
|
684
|
+
async function setupClaude(projectDir, skillFilter = null) {
|
|
454
685
|
// Create .claude directory structure — skills-only architecture
|
|
455
|
-
const claudeDir = path.join(projectDir,
|
|
456
|
-
const mcpDir = path.join(claudeDir,
|
|
686
|
+
const claudeDir = path.join(projectDir, ".claude");
|
|
687
|
+
const mcpDir = path.join(claudeDir, "mcp");
|
|
457
688
|
|
|
458
689
|
await fs.ensureDir(claudeDir);
|
|
459
690
|
await fs.ensureDir(mcpDir);
|
|
460
691
|
|
|
461
692
|
// Copy skills (each skill is a directory with SKILL.md + optional agents/)
|
|
462
|
-
|
|
693
|
+
// If skillFilter is null, install all skills. Otherwise only install listed ones.
|
|
694
|
+
const sourceSkillsDir = path.join(__dirname, "..", "skills");
|
|
463
695
|
if (await fs.pathExists(sourceSkillsDir)) {
|
|
464
|
-
const skillsDir = path.join(claudeDir,
|
|
696
|
+
const skillsDir = path.join(claudeDir, "skills");
|
|
465
697
|
await fs.ensureDir(skillsDir);
|
|
466
698
|
const skillDirs = await fs.readdir(sourceSkillsDir);
|
|
699
|
+
const allowedSkills = skillFilter ? new Set(skillFilter) : null;
|
|
467
700
|
for (const skillName of skillDirs) {
|
|
701
|
+
if (allowedSkills && !allowedSkills.has(skillName)) continue;
|
|
468
702
|
const skillPath = path.join(sourceSkillsDir, skillName);
|
|
469
703
|
const stat = await fs.stat(skillPath);
|
|
470
704
|
if (stat.isDirectory()) {
|
|
@@ -474,164 +708,61 @@ async function setupClaude(projectDir) {
|
|
|
474
708
|
}
|
|
475
709
|
|
|
476
710
|
// Copy MCP server files
|
|
477
|
-
const templateMcpDir = path.join(__dirname,
|
|
711
|
+
const templateMcpDir = path.join(__dirname, "..", "src", "mcp");
|
|
478
712
|
if (await fs.pathExists(templateMcpDir)) {
|
|
479
713
|
const mcpFiles = await fs.readdir(templateMcpDir);
|
|
480
714
|
for (const file of mcpFiles) {
|
|
481
|
-
if (file.endsWith(
|
|
482
|
-
await fs.copy(
|
|
483
|
-
path.join(templateMcpDir, file),
|
|
484
|
-
path.join(mcpDir, file)
|
|
485
|
-
);
|
|
715
|
+
if (file.endsWith(".js") || file.endsWith(".json")) {
|
|
716
|
+
await fs.copy(path.join(templateMcpDir, file), path.join(mcpDir, file));
|
|
486
717
|
}
|
|
487
718
|
}
|
|
488
719
|
}
|
|
489
|
-
|
|
490
|
-
// Create CLAUDE.md configuration file
|
|
491
|
-
const claudeMd = `# Claude Code Configuration
|
|
492
|
-
|
|
493
|
-
This project uses the MyAIDev Method — a skills-based AI development framework.
|
|
494
720
|
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
### Content Creation
|
|
508
|
-
- \`content-writer\` - Multi-agent pipeline (research, plan, write, SEO, edit, visuals)
|
|
509
|
-
- \`content-rules-setup\` - Interactive brand voice configuration
|
|
510
|
-
- \`content-verifier\` - Content uniqueness and quality verification
|
|
511
|
-
- \`content-coordinator\` - Batch content verification and publishing
|
|
512
|
-
- \`content-enrichment\` - Enrich articles with real-time data and visuals
|
|
513
|
-
|
|
514
|
-
### Publishing
|
|
515
|
-
- \`wordpress-publisher\` - WordPress REST API publishing
|
|
516
|
-
- \`payloadcms-publisher\` - PayloadCMS with Lexical format
|
|
517
|
-
- \`docusaurus-publisher\` - Docusaurus with sidebar config
|
|
518
|
-
- \`mintlify-publisher\` - Mintlify with navigation updates
|
|
519
|
-
- \`astro-publisher\` - Astro content collections
|
|
520
|
-
|
|
521
|
-
### Visual & Media
|
|
522
|
-
- \`visual-generator\` - AI image/video generation (Gemini, DALL-E, FLUX, Veo)
|
|
523
|
-
|
|
524
|
-
### Deployment & Infrastructure
|
|
525
|
-
- \`deployer\` - Multi-environment deployment (dev/staging/prod)
|
|
526
|
-
- \`coolify-deployer\` - Coolify PaaS deployment
|
|
527
|
-
- \`openstack-manager\` - OpenStack VM management
|
|
528
|
-
|
|
529
|
-
### Git & CI/CD
|
|
530
|
-
- \`git-workflow\` - PRs, releases, hotfixes, branch sync
|
|
531
|
-
|
|
532
|
-
### Security
|
|
533
|
-
- \`security-tester\` - Penetration testing (PTES methodology)
|
|
534
|
-
- \`security-auditor\` - Compliance auditing (PCI-DSS, GDPR, SOC 2)
|
|
535
|
-
|
|
536
|
-
### Configuration
|
|
537
|
-
- \`configure\` - Interactive environment setup wizard
|
|
538
|
-
|
|
539
|
-
## Content Customization
|
|
540
|
-
|
|
541
|
-
- **content-rules.md** - Brand voice and writing guidelines
|
|
542
|
-
- Run the \`content-rules-setup\` skill to generate this interactively
|
|
543
|
-
|
|
544
|
-
## Platform Configuration
|
|
545
|
-
|
|
546
|
-
Run the \`configure\` skill to set up credentials, or manually edit \`.env\`:
|
|
547
|
-
|
|
548
|
-
\`\`\`bash
|
|
549
|
-
# WordPress
|
|
550
|
-
WORDPRESS_URL=https://your-site.com
|
|
551
|
-
WORDPRESS_USERNAME=your-username
|
|
552
|
-
WORDPRESS_APP_PASSWORD=your-app-password
|
|
553
|
-
|
|
554
|
-
# PayloadCMS
|
|
555
|
-
PAYLOADCMS_URL=https://cms.your-site.com
|
|
556
|
-
PAYLOADCMS_EMAIL=your-email
|
|
557
|
-
PAYLOADCMS_PASSWORD=your-password
|
|
558
|
-
|
|
559
|
-
# Visual APIs
|
|
560
|
-
GOOGLE_API_KEY=your-key
|
|
561
|
-
OPENAI_API_KEY=your-key
|
|
562
|
-
|
|
563
|
-
# Coolify
|
|
564
|
-
COOLIFY_URL=https://coolify.your-server.com
|
|
565
|
-
COOLIFY_API_KEY=your-key
|
|
566
|
-
\`\`\`
|
|
567
|
-
|
|
568
|
-
## Scripts and Utilities
|
|
569
|
-
|
|
570
|
-
The \`.myaidev-method/\` directory contains helper scripts that skills can invoke:
|
|
571
|
-
|
|
572
|
-
\`\`\`bash
|
|
573
|
-
node .myaidev-method/scripts/payloadcms-publish.js "article.md"
|
|
574
|
-
node .myaidev-method/scripts/wordpress-health-check.js
|
|
575
|
-
node .myaidev-method/scripts/coolify-deploy-app.js --name myapp
|
|
576
|
-
\`\`\`
|
|
577
|
-
|
|
578
|
-
## Project Structure
|
|
579
|
-
|
|
580
|
-
\`\`\`
|
|
581
|
-
.claude/
|
|
582
|
-
├── skills/ # All skill definitions (SKILL.md + agents/)
|
|
583
|
-
├── mcp/ # MCP server configurations
|
|
584
|
-
└── CLAUDE.md # This file
|
|
585
|
-
.myaidev-method/
|
|
586
|
-
├── scripts/ # Publishing and deployment scripts
|
|
587
|
-
├── lib/ # Utility libraries
|
|
588
|
-
└── package.json # Script dependencies
|
|
589
|
-
\`\`\`
|
|
590
|
-
|
|
591
|
-
## Updating
|
|
592
|
-
|
|
593
|
-
\`\`\`bash
|
|
594
|
-
npx myaidev-method@latest update --claude # Interactive update
|
|
595
|
-
npx myaidev-method@latest update --claude --force # Force overwrite
|
|
596
|
-
npx myaidev-method@latest update --claude --dry-run # Preview changes
|
|
597
|
-
\`\`\`
|
|
721
|
+
// Create CLAUDE.md configuration file from template
|
|
722
|
+
const claudeMdTemplate = path.join(
|
|
723
|
+
__dirname,
|
|
724
|
+
"..",
|
|
725
|
+
"src",
|
|
726
|
+
"templates",
|
|
727
|
+
"claude",
|
|
728
|
+
"CLAUDE.md",
|
|
729
|
+
);
|
|
730
|
+
if (await fs.pathExists(claudeMdTemplate)) {
|
|
731
|
+
await fs.copy(claudeMdTemplate, path.join(claudeDir, "CLAUDE.md"));
|
|
732
|
+
}
|
|
598
733
|
|
|
599
|
-
See \`USER_GUIDE.md\` for detailed instructions.
|
|
600
|
-
`;
|
|
601
|
-
|
|
602
|
-
await fs.writeFile(path.join(claudeDir, 'CLAUDE.md'), claudeMd);
|
|
603
|
-
|
|
604
734
|
// Copy the comprehensive .env.example from package
|
|
605
|
-
const sourceEnvExample = path.join(__dirname,
|
|
735
|
+
const sourceEnvExample = path.join(__dirname, "..", ".env.example");
|
|
606
736
|
if (await fs.pathExists(sourceEnvExample)) {
|
|
607
|
-
await fs.copy(sourceEnvExample, path.join(projectDir,
|
|
737
|
+
await fs.copy(sourceEnvExample, path.join(projectDir, ".env.example"));
|
|
608
738
|
}
|
|
609
739
|
|
|
610
740
|
// Create .myaidev-method directory for scripts and utilities
|
|
611
741
|
// This allows agents to access publishing/deployment scripts in non-Node.js projects
|
|
612
|
-
const myaidevDir = path.join(projectDir,
|
|
613
|
-
const scriptsDir = path.join(myaidevDir,
|
|
614
|
-
const libDir = path.join(myaidevDir,
|
|
742
|
+
const myaidevDir = path.join(projectDir, ".myaidev-method");
|
|
743
|
+
const scriptsDir = path.join(myaidevDir, "scripts");
|
|
744
|
+
const libDir = path.join(myaidevDir, "lib");
|
|
615
745
|
|
|
616
746
|
await fs.ensureDir(scriptsDir);
|
|
617
747
|
await fs.ensureDir(libDir);
|
|
618
748
|
|
|
619
749
|
// Copy all executable scripts
|
|
620
|
-
const sourceScriptsDir = path.join(__dirname,
|
|
750
|
+
const sourceScriptsDir = path.join(__dirname, "..", "src", "scripts");
|
|
621
751
|
if (await fs.pathExists(sourceScriptsDir)) {
|
|
622
752
|
const scriptFiles = await fs.readdir(sourceScriptsDir);
|
|
623
753
|
for (const file of scriptFiles) {
|
|
624
|
-
if (file.endsWith(
|
|
754
|
+
if (file.endsWith(".js") && file !== "init-project.js") {
|
|
755
|
+
// Skip init script
|
|
625
756
|
await fs.copy(
|
|
626
757
|
path.join(sourceScriptsDir, file),
|
|
627
|
-
path.join(scriptsDir, file)
|
|
758
|
+
path.join(scriptsDir, file),
|
|
628
759
|
);
|
|
629
760
|
}
|
|
630
761
|
}
|
|
631
762
|
}
|
|
632
763
|
|
|
633
764
|
// Copy all utility libraries
|
|
634
|
-
const sourceLibDir = path.join(__dirname,
|
|
765
|
+
const sourceLibDir = path.join(__dirname, "..", "src", "lib");
|
|
635
766
|
if (await fs.pathExists(sourceLibDir)) {
|
|
636
767
|
await fs.copy(sourceLibDir, libDir);
|
|
637
768
|
}
|
|
@@ -639,99 +770,121 @@ See \`USER_GUIDE.md\` for detailed instructions.
|
|
|
639
770
|
// Copy package.json and install dependencies in .myaidev-method
|
|
640
771
|
// This ensures scripts have access to required npm packages
|
|
641
772
|
const packageJson = {
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
773
|
+
name: "myaidev-method-scripts",
|
|
774
|
+
version: "1.0.0",
|
|
775
|
+
type: "module",
|
|
776
|
+
private: true,
|
|
777
|
+
dependencies: {
|
|
647
778
|
"node-fetch": "^3.3.2",
|
|
648
|
-
|
|
779
|
+
marked: "^11.0.0",
|
|
649
780
|
"gray-matter": "^4.0.3",
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
}
|
|
781
|
+
dotenv: "^16.4.1",
|
|
782
|
+
chalk: "^5.3.0",
|
|
783
|
+
ora: "^8.0.1",
|
|
784
|
+
},
|
|
654
785
|
};
|
|
655
786
|
|
|
656
787
|
await fs.writeFile(
|
|
657
|
-
path.join(myaidevDir,
|
|
658
|
-
JSON.stringify(packageJson, null, 2)
|
|
788
|
+
path.join(myaidevDir, "package.json"),
|
|
789
|
+
JSON.stringify(packageJson, null, 2),
|
|
659
790
|
);
|
|
660
791
|
|
|
661
792
|
// Install dependencies in .myaidev-method directory
|
|
662
|
-
console.log(chalk.gray(
|
|
663
|
-
const { execSync } = await import(
|
|
793
|
+
console.log(chalk.gray("\n Installing script dependencies..."));
|
|
794
|
+
const { execSync } = await import("child_process");
|
|
664
795
|
try {
|
|
665
|
-
execSync(
|
|
796
|
+
execSync("npm install", {
|
|
666
797
|
cwd: myaidevDir,
|
|
667
|
-
stdio:
|
|
798
|
+
stdio: "inherit",
|
|
668
799
|
});
|
|
669
|
-
console.log(chalk.green(
|
|
800
|
+
console.log(chalk.green(" ✓ Dependencies installed successfully"));
|
|
670
801
|
} catch (error) {
|
|
671
|
-
console.log(
|
|
672
|
-
|
|
802
|
+
console.log(
|
|
803
|
+
chalk.yellow(" ⚠ Failed to install dependencies automatically"),
|
|
804
|
+
);
|
|
805
|
+
console.log(chalk.gray(" Run: cd .myaidev-method && npm install"));
|
|
673
806
|
}
|
|
674
807
|
|
|
675
|
-
// Note: MCP
|
|
808
|
+
// Note: fal.ai MCP server configured in settings.json for visual generation
|
|
809
|
+
// WordPress MCP integration still uses native REST API approach
|
|
676
810
|
|
|
677
811
|
// Copy documentation files to project root (limited to essential guides)
|
|
678
812
|
const docsToMerge = [
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
813
|
+
"USER_GUIDE.md",
|
|
814
|
+
"DEV_WORKFLOW_GUIDE.md",
|
|
815
|
+
"PUBLISHING_GUIDE.md",
|
|
682
816
|
];
|
|
683
817
|
|
|
684
818
|
for (const docFile of docsToMerge) {
|
|
685
|
-
const sourcePath = path.join(__dirname,
|
|
819
|
+
const sourcePath = path.join(__dirname, "..", docFile);
|
|
686
820
|
if (await fs.pathExists(sourcePath)) {
|
|
687
821
|
await fs.copy(sourcePath, path.join(projectDir, docFile));
|
|
688
822
|
}
|
|
689
823
|
}
|
|
690
824
|
|
|
691
825
|
// Copy template documentation (WordPress integration, etc.)
|
|
692
|
-
const templateDocsDir = path.join(
|
|
826
|
+
const templateDocsDir = path.join(
|
|
827
|
+
__dirname,
|
|
828
|
+
"..",
|
|
829
|
+
"src",
|
|
830
|
+
"templates",
|
|
831
|
+
"docs",
|
|
832
|
+
);
|
|
693
833
|
if (await fs.pathExists(templateDocsDir)) {
|
|
694
834
|
const docFiles = await fs.readdir(templateDocsDir);
|
|
695
835
|
for (const file of docFiles) {
|
|
696
|
-
if (file.endsWith(
|
|
836
|
+
if (file.endsWith(".md")) {
|
|
697
837
|
const destPath = path.join(projectDir, file);
|
|
698
838
|
// Only copy if destination doesn't exist (don't overwrite user customizations)
|
|
699
|
-
if (!await fs.pathExists(destPath)) {
|
|
700
|
-
await fs.copy(
|
|
701
|
-
path.join(templateDocsDir, file),
|
|
702
|
-
destPath
|
|
703
|
-
);
|
|
839
|
+
if (!(await fs.pathExists(destPath))) {
|
|
840
|
+
await fs.copy(path.join(templateDocsDir, file), destPath);
|
|
704
841
|
}
|
|
705
842
|
}
|
|
706
843
|
}
|
|
707
844
|
}
|
|
708
845
|
|
|
709
846
|
// Create content-rules.md if it doesn't already exist
|
|
710
|
-
const contentRulesPath = path.join(projectDir,
|
|
711
|
-
if (!await fs.pathExists(contentRulesPath)) {
|
|
712
|
-
const contentRulesTemplate = path.join(
|
|
847
|
+
const contentRulesPath = path.join(projectDir, "content-rules.md");
|
|
848
|
+
if (!(await fs.pathExists(contentRulesPath))) {
|
|
849
|
+
const contentRulesTemplate = path.join(
|
|
850
|
+
__dirname,
|
|
851
|
+
"..",
|
|
852
|
+
"content-rules-example.md",
|
|
853
|
+
);
|
|
713
854
|
if (await fs.pathExists(contentRulesTemplate)) {
|
|
714
855
|
await fs.copy(contentRulesTemplate, contentRulesPath);
|
|
715
|
-
console.log(
|
|
856
|
+
console.log(
|
|
857
|
+
chalk.green(
|
|
858
|
+
" ✓ Created content-rules.md for customizable content generation",
|
|
859
|
+
),
|
|
860
|
+
);
|
|
716
861
|
}
|
|
717
862
|
} else {
|
|
718
|
-
console.log(
|
|
863
|
+
console.log(
|
|
864
|
+
chalk.gray(" ℹ content-rules.md already exists, skipping creation"),
|
|
865
|
+
);
|
|
719
866
|
}
|
|
720
867
|
|
|
721
868
|
// Save installation version for update tracking
|
|
722
|
-
const pkgJson = await fs.readJson(path.join(__dirname,
|
|
723
|
-
const versionFile = path.join(claudeDir,
|
|
869
|
+
const pkgJson = await fs.readJson(path.join(__dirname, "..", "package.json"));
|
|
870
|
+
const versionFile = path.join(claudeDir, ".myaidev-version");
|
|
724
871
|
await fs.writeFile(versionFile, pkgJson.version);
|
|
725
872
|
|
|
726
873
|
// Copy statusline script and configure settings.json
|
|
727
|
-
const statuslineSrc = path.join(
|
|
728
|
-
|
|
874
|
+
const statuslineSrc = path.join(
|
|
875
|
+
__dirname,
|
|
876
|
+
"..",
|
|
877
|
+
"src",
|
|
878
|
+
"statusline",
|
|
879
|
+
"statusline.sh",
|
|
880
|
+
);
|
|
881
|
+
const statuslineDest = path.join(claudeDir, "statusline.sh");
|
|
729
882
|
if (await fs.pathExists(statuslineSrc)) {
|
|
730
883
|
await fs.copy(statuslineSrc, statuslineDest);
|
|
731
884
|
await fs.chmod(statuslineDest, 0o755);
|
|
732
885
|
|
|
733
886
|
// Create or merge .claude/settings.json with statusLine config
|
|
734
|
-
const settingsPath = path.join(claudeDir,
|
|
887
|
+
const settingsPath = path.join(claudeDir, "settings.json");
|
|
735
888
|
let settings = {};
|
|
736
889
|
if (await fs.pathExists(settingsPath)) {
|
|
737
890
|
try {
|
|
@@ -741,35 +894,51 @@ See \`USER_GUIDE.md\` for detailed instructions.
|
|
|
741
894
|
}
|
|
742
895
|
}
|
|
743
896
|
settings.statusLine = {
|
|
744
|
-
type:
|
|
745
|
-
command:
|
|
897
|
+
type: "command",
|
|
898
|
+
command: ".claude/statusline.sh",
|
|
746
899
|
};
|
|
747
900
|
settings.extraKnownMarketplaces = {
|
|
748
|
-
|
|
901
|
+
"myaidev-marketplace": {
|
|
749
902
|
source: {
|
|
750
|
-
source:
|
|
751
|
-
repo:
|
|
752
|
-
}
|
|
753
|
-
}
|
|
903
|
+
source: "github",
|
|
904
|
+
repo: "myaione/myaidev-marketplace",
|
|
905
|
+
},
|
|
906
|
+
},
|
|
907
|
+
};
|
|
908
|
+
// Configure MCP servers for enhanced tool access
|
|
909
|
+
settings.mcpServers = settings.mcpServers || {};
|
|
910
|
+
settings.mcpServers["fal-ai"] = {
|
|
911
|
+
command: "npx",
|
|
912
|
+
args: ["-y", "fal-ai-mcp-server"],
|
|
913
|
+
env: {
|
|
914
|
+
FAL_KEY: "",
|
|
915
|
+
},
|
|
754
916
|
};
|
|
755
917
|
await fs.writeJson(settingsPath, settings, { spaces: 2 });
|
|
756
|
-
console.log(chalk.green(
|
|
918
|
+
console.log(chalk.green(" ✓ Status line configured"));
|
|
919
|
+
console.log(
|
|
920
|
+
chalk.green(
|
|
921
|
+
" ✓ fal.ai MCP server configured (set FAL_KEY to activate)",
|
|
922
|
+
),
|
|
923
|
+
);
|
|
757
924
|
}
|
|
758
925
|
}
|
|
759
926
|
|
|
760
|
-
async function setupGemini(projectDir) {
|
|
927
|
+
async function setupGemini(projectDir, skillFilter = null) {
|
|
761
928
|
// Setup Gemini CLI — skills-based architecture
|
|
762
929
|
// Gemini CLI supports Agent Skills standard natively (.gemini/skills/)
|
|
763
|
-
const geminiDir = path.join(projectDir,
|
|
930
|
+
const geminiDir = path.join(projectDir, ".gemini");
|
|
764
931
|
await fs.ensureDir(geminiDir);
|
|
765
932
|
|
|
766
933
|
// Copy skills (same SKILL.md format works cross-platform)
|
|
767
|
-
const sourceSkillsDir = path.join(__dirname,
|
|
934
|
+
const sourceSkillsDir = path.join(__dirname, "..", "skills");
|
|
768
935
|
if (await fs.pathExists(sourceSkillsDir)) {
|
|
769
|
-
const skillsDir = path.join(geminiDir,
|
|
936
|
+
const skillsDir = path.join(geminiDir, "skills");
|
|
770
937
|
await fs.ensureDir(skillsDir);
|
|
771
938
|
const skillDirs = await fs.readdir(sourceSkillsDir);
|
|
939
|
+
const allowedSkills = skillFilter ? new Set(skillFilter) : null;
|
|
772
940
|
for (const skillName of skillDirs) {
|
|
941
|
+
if (allowedSkills && !allowedSkills.has(skillName)) continue;
|
|
773
942
|
const skillPath = path.join(sourceSkillsDir, skillName);
|
|
774
943
|
const stat = await fs.stat(skillPath);
|
|
775
944
|
if (stat.isDirectory()) {
|
|
@@ -793,7 +962,7 @@ Skills are discovered automatically. Gemini activates them when relevant to your
|
|
|
793
962
|
|
|
794
963
|
### Content & Publishing
|
|
795
964
|
- \`content-writer\` - SEO-optimized content creation
|
|
796
|
-
- \`
|
|
965
|
+
- \`content-publisher\` - Multi-platform publishing (WordPress, PayloadCMS, Astro, Docusaurus, Mintlify)
|
|
797
966
|
|
|
798
967
|
### DevOps
|
|
799
968
|
- \`deployer\` / \`coolify-deployer\` - Multi-environment deployment
|
|
@@ -812,22 +981,24 @@ Skills are discovered automatically. Gemini activates them when relevant to your
|
|
|
812
981
|
\`\`\`
|
|
813
982
|
`;
|
|
814
983
|
|
|
815
|
-
await fs.writeFile(path.join(geminiDir,
|
|
984
|
+
await fs.writeFile(path.join(geminiDir, "GEMINI.md"), geminiMd);
|
|
816
985
|
}
|
|
817
986
|
|
|
818
|
-
async function setupCodex(projectDir) {
|
|
987
|
+
async function setupCodex(projectDir, skillFilter = null) {
|
|
819
988
|
// Setup Codex/OpenCode — skills-based architecture
|
|
820
989
|
// Codex supports Agent Skills standard (experimental via experimental.skills)
|
|
821
|
-
const codexDir = path.join(projectDir,
|
|
990
|
+
const codexDir = path.join(projectDir, ".codex");
|
|
822
991
|
await fs.ensureDir(codexDir);
|
|
823
992
|
|
|
824
993
|
// Copy skills (same SKILL.md format works cross-platform)
|
|
825
|
-
const sourceSkillsDir = path.join(__dirname,
|
|
994
|
+
const sourceSkillsDir = path.join(__dirname, "..", "skills");
|
|
826
995
|
if (await fs.pathExists(sourceSkillsDir)) {
|
|
827
|
-
const skillsDir = path.join(codexDir,
|
|
996
|
+
const skillsDir = path.join(codexDir, "skills");
|
|
828
997
|
await fs.ensureDir(skillsDir);
|
|
829
998
|
const skillDirs = await fs.readdir(sourceSkillsDir);
|
|
999
|
+
const allowedSkills = skillFilter ? new Set(skillFilter) : null;
|
|
830
1000
|
for (const skillName of skillDirs) {
|
|
1001
|
+
if (allowedSkills && !allowedSkills.has(skillName)) continue;
|
|
831
1002
|
const skillPath = path.join(sourceSkillsDir, skillName);
|
|
832
1003
|
const stat = await fs.stat(skillPath);
|
|
833
1004
|
if (stat.isDirectory()) {
|
|
@@ -851,7 +1022,7 @@ Enable experimental skills support: \`experimental.skills = true\` in settings.
|
|
|
851
1022
|
|
|
852
1023
|
### Content & Publishing
|
|
853
1024
|
- \`content-writer\` - SEO-optimized content creation
|
|
854
|
-
- \`
|
|
1025
|
+
- \`content-publisher\` - Multi-platform publishing (WordPress, PayloadCMS, Astro, Docusaurus, Mintlify)
|
|
855
1026
|
|
|
856
1027
|
### DevOps
|
|
857
1028
|
- \`deployer\` / \`coolify-deployer\` - Multi-environment deployment
|
|
@@ -861,119 +1032,159 @@ Enable experimental skills support: \`experimental.skills = true\` in settings.
|
|
|
861
1032
|
- \`security-tester\` / \`security-auditor\`
|
|
862
1033
|
`;
|
|
863
1034
|
|
|
864
|
-
await fs.writeFile(path.join(codexDir,
|
|
1035
|
+
await fs.writeFile(path.join(codexDir, "AGENTS.md"), agentsMd);
|
|
865
1036
|
}
|
|
866
1037
|
|
|
867
1038
|
program
|
|
868
|
-
.command(
|
|
869
|
-
.description(
|
|
870
|
-
.option(
|
|
871
|
-
.option(
|
|
872
|
-
.option(
|
|
873
|
-
.option(
|
|
874
|
-
.option(
|
|
875
|
-
.option(
|
|
876
|
-
.option(
|
|
877
|
-
|
|
878
|
-
|
|
1039
|
+
.command("update")
|
|
1040
|
+
.description("Update MyAIDev Method components to latest version")
|
|
1041
|
+
.option("--claude", "Update Claude Code configuration")
|
|
1042
|
+
.option("--gemini", "Update Gemini CLI configuration")
|
|
1043
|
+
.option("--codex", "Update Codex CLI configuration")
|
|
1044
|
+
.option("--force", "Force update all files without prompting")
|
|
1045
|
+
.option("--dry-run", "Show what would be updated without making changes")
|
|
1046
|
+
.option("--verbose", "Show detailed progress")
|
|
1047
|
+
.option(
|
|
1048
|
+
"--smart",
|
|
1049
|
+
"Smart update: keep customizations, add new files (no prompts)",
|
|
1050
|
+
)
|
|
1051
|
+
.option("--accept-all", "Accept all updates: replace all files (no prompts)")
|
|
1052
|
+
.option(
|
|
1053
|
+
"--keep-mine",
|
|
1054
|
+
"Keep all customizations: only add new files (no prompts)",
|
|
1055
|
+
)
|
|
879
1056
|
.action(async (options) => {
|
|
880
|
-
const ora = (await import(
|
|
881
|
-
const { fileURLToPath } = await import(
|
|
882
|
-
const updateManager = await import(
|
|
1057
|
+
const ora = (await import("ora")).default;
|
|
1058
|
+
const { fileURLToPath } = await import("url");
|
|
1059
|
+
const updateManager = await import("../src/lib/update-manager.js");
|
|
883
1060
|
|
|
884
1061
|
const __filename = fileURLToPath(import.meta.url);
|
|
885
1062
|
const __dirname = path.dirname(__filename);
|
|
886
|
-
const packageRoot = path.join(__dirname,
|
|
1063
|
+
const packageRoot = path.join(__dirname, "..");
|
|
887
1064
|
|
|
888
1065
|
try {
|
|
889
1066
|
const cwd = process.cwd();
|
|
890
1067
|
|
|
891
1068
|
// Display branding banner
|
|
892
1069
|
console.log(getASCIIBanner());
|
|
893
|
-
console.log(
|
|
1070
|
+
console.log(
|
|
1071
|
+
chalk.cyan.bold(" ⚡ Update Manager\n"),
|
|
1072
|
+
);
|
|
894
1073
|
|
|
895
1074
|
// Detect existing installation
|
|
896
|
-
const spinner = ora(
|
|
1075
|
+
const spinner = ora("Detecting MyAIDev Method installation...").start();
|
|
897
1076
|
const installation = await updateManager.detectExistingInstallation(cwd);
|
|
898
1077
|
|
|
899
1078
|
if (!installation) {
|
|
900
|
-
spinner.fail(
|
|
901
|
-
console.log(
|
|
1079
|
+
spinner.fail("No MyAIDev Method installation found");
|
|
1080
|
+
console.log(
|
|
1081
|
+
chalk.gray(" Run: npx myaidev-method@latest init --claude"),
|
|
1082
|
+
);
|
|
902
1083
|
process.exit(1);
|
|
903
1084
|
}
|
|
904
1085
|
|
|
905
|
-
spinner.succeed(
|
|
1086
|
+
spinner.succeed(
|
|
1087
|
+
`Found ${installation.type} installation (v${installation.currentVersion})`,
|
|
1088
|
+
);
|
|
906
1089
|
|
|
907
1090
|
// Get package version
|
|
908
|
-
const packageJson = await fs.readJson(
|
|
1091
|
+
const packageJson = await fs.readJson(
|
|
1092
|
+
path.join(packageRoot, "package.json"),
|
|
1093
|
+
);
|
|
909
1094
|
const newVersion = packageJson.version;
|
|
910
1095
|
|
|
911
1096
|
// Check if already up to date
|
|
912
1097
|
if (installation.currentVersion === newVersion && !options.force) {
|
|
913
|
-
console.log(chalk.green(
|
|
1098
|
+
console.log(chalk.green("\n✅ Already up to date!\n"));
|
|
914
1099
|
process.exit(0);
|
|
915
1100
|
}
|
|
916
1101
|
|
|
917
1102
|
// Generate change summary
|
|
918
|
-
const summarySpinner = ora(
|
|
919
|
-
const components = [
|
|
1103
|
+
const summarySpinner = ora("Analyzing changes...").start();
|
|
1104
|
+
const components = ["skills", "scripts", "lib", "mcp", "config", "docs"];
|
|
920
1105
|
const summary = await updateManager.generateChangeSummary(
|
|
921
|
-
components,
|
|
1106
|
+
components,
|
|
1107
|
+
cwd,
|
|
1108
|
+
installation.type,
|
|
1109
|
+
packageRoot,
|
|
922
1110
|
);
|
|
923
|
-
summarySpinner.succeed(
|
|
1111
|
+
summarySpinner.succeed("Change analysis complete");
|
|
924
1112
|
|
|
925
1113
|
// Display summary dashboard
|
|
926
|
-
console.log(
|
|
927
|
-
updateManager.displayChangeSummary(
|
|
1114
|
+
console.log("");
|
|
1115
|
+
updateManager.displayChangeSummary(
|
|
1116
|
+
summary,
|
|
1117
|
+
installation.currentVersion,
|
|
1118
|
+
newVersion,
|
|
1119
|
+
);
|
|
928
1120
|
|
|
929
1121
|
// Dry run mode - just show summary and exit
|
|
930
1122
|
if (options.dryRun) {
|
|
931
|
-
console.log(chalk.yellow(
|
|
932
|
-
console.log(chalk.gray(
|
|
933
|
-
console.log(chalk.gray(` • ${summary.unchanged.length} unchanged files (would skip)`));
|
|
934
|
-
console.log(chalk.gray(` • ${summary.new.length} new files (would add)`));
|
|
935
|
-
console.log(chalk.gray(` • ${summary.modified.length} modified files (would need decision)`));
|
|
936
|
-
console.log(chalk.gray(` • ${summary.deleted.length} removed files (would optionally delete)`));
|
|
1123
|
+
console.log(chalk.yellow("\n📋 DRY RUN — No changes were made."));
|
|
1124
|
+
console.log(chalk.gray(" Run without --dry-run to apply updates.\n"));
|
|
937
1125
|
process.exit(0);
|
|
938
1126
|
}
|
|
939
1127
|
|
|
940
1128
|
// Determine strategy (CLI flag or prompt)
|
|
941
1129
|
let strategy;
|
|
942
1130
|
if (options.smart) {
|
|
943
|
-
strategy =
|
|
944
|
-
console.log(
|
|
1131
|
+
strategy = "smart";
|
|
1132
|
+
console.log(
|
|
1133
|
+
chalk.cyan("\n🚀 Using Smart Update strategy (--smart flag)\n"),
|
|
1134
|
+
);
|
|
945
1135
|
} else if (options.acceptAll) {
|
|
946
|
-
strategy =
|
|
947
|
-
console.log(
|
|
1136
|
+
strategy = "accept-all";
|
|
1137
|
+
console.log(
|
|
1138
|
+
chalk.cyan("\n📥 Using Accept All strategy (--accept-all flag)\n"),
|
|
1139
|
+
);
|
|
948
1140
|
} else if (options.keepMine) {
|
|
949
|
-
strategy =
|
|
950
|
-
console.log(
|
|
1141
|
+
strategy = "keep-all";
|
|
1142
|
+
console.log(
|
|
1143
|
+
chalk.cyan("\n🛡️ Using Keep All strategy (--keep-mine flag)\n"),
|
|
1144
|
+
);
|
|
951
1145
|
} else if (options.force) {
|
|
952
|
-
strategy =
|
|
953
|
-
console.log(
|
|
1146
|
+
strategy = "accept-all";
|
|
1147
|
+
console.log(
|
|
1148
|
+
chalk.cyan("\n📥 Using Accept All strategy (--force flag)\n"),
|
|
1149
|
+
);
|
|
954
1150
|
} else {
|
|
955
1151
|
strategy = await updateManager.promptUpdateStrategy(summary);
|
|
956
1152
|
}
|
|
957
1153
|
|
|
958
1154
|
// Create timestamped backup directory
|
|
959
|
-
const backupDir = await updateManager.createTimestampedBackup(
|
|
1155
|
+
const backupDir = await updateManager.createTimestampedBackup(
|
|
1156
|
+
cwd,
|
|
1157
|
+
installation.type,
|
|
1158
|
+
);
|
|
960
1159
|
|
|
961
1160
|
// Execute selected strategy
|
|
962
1161
|
let results;
|
|
963
|
-
console.log(chalk.cyan(
|
|
1162
|
+
console.log(chalk.cyan("\n📦 Applying updates...\n"));
|
|
964
1163
|
|
|
965
|
-
if (strategy ===
|
|
1164
|
+
if (strategy === "auto" || summary.modified.length === 0) {
|
|
966
1165
|
// No conflicts - just add new files
|
|
967
|
-
results = await updateManager.executeKeepAll(summary, {
|
|
968
|
-
|
|
969
|
-
|
|
970
|
-
} else if (strategy ===
|
|
971
|
-
results = await updateManager.
|
|
972
|
-
|
|
973
|
-
|
|
974
|
-
} else if (strategy ===
|
|
975
|
-
results = await updateManager.
|
|
976
|
-
|
|
1166
|
+
results = await updateManager.executeKeepAll(summary, {
|
|
1167
|
+
verbose: options.verbose,
|
|
1168
|
+
});
|
|
1169
|
+
} else if (strategy === "smart") {
|
|
1170
|
+
results = await updateManager.executeSmartUpdate(summary, backupDir, {
|
|
1171
|
+
verbose: options.verbose,
|
|
1172
|
+
});
|
|
1173
|
+
} else if (strategy === "accept-all") {
|
|
1174
|
+
results = await updateManager.executeAcceptAll(summary, backupDir, {
|
|
1175
|
+
verbose: options.verbose,
|
|
1176
|
+
});
|
|
1177
|
+
} else if (strategy === "keep-all") {
|
|
1178
|
+
results = await updateManager.executeKeepAll(summary, {
|
|
1179
|
+
verbose: options.verbose,
|
|
1180
|
+
});
|
|
1181
|
+
} else if (strategy === "by-category") {
|
|
1182
|
+
results = await updateManager.executeCategoryUpdate(
|
|
1183
|
+
summary,
|
|
1184
|
+
backupDir,
|
|
1185
|
+
{ verbose: options.verbose },
|
|
1186
|
+
);
|
|
1187
|
+
} else if (strategy === "individual") {
|
|
977
1188
|
// Fall back to old file-by-file for this mode
|
|
978
1189
|
results = { updated: [], kept: [], added: [], backedUp: [] };
|
|
979
1190
|
for (const f of summary.new) {
|
|
@@ -985,11 +1196,15 @@ program
|
|
|
985
1196
|
}
|
|
986
1197
|
}
|
|
987
1198
|
for (const f of summary.modified) {
|
|
988
|
-
const action = await updateManager.promptForConflict(
|
|
989
|
-
|
|
1199
|
+
const action = await updateManager.promptForConflict(
|
|
1200
|
+
f.file,
|
|
1201
|
+
f.targetPath,
|
|
1202
|
+
f.sourcePath,
|
|
1203
|
+
);
|
|
1204
|
+
if (action === "replace") {
|
|
990
1205
|
await fs.copy(f.sourcePath, f.targetPath);
|
|
991
1206
|
results.updated.push(f.file);
|
|
992
|
-
} else if (action ===
|
|
1207
|
+
} else if (action === "backup") {
|
|
993
1208
|
const backupPath = path.join(backupDir, f.componentType, f.file);
|
|
994
1209
|
await fs.ensureDir(path.dirname(backupPath));
|
|
995
1210
|
await fs.copy(f.targetPath, backupPath);
|
|
@@ -1010,9 +1225,8 @@ program
|
|
|
1010
1225
|
|
|
1011
1226
|
// Display final results
|
|
1012
1227
|
updateManager.displayUpdateResults(results, backupDir, newVersion);
|
|
1013
|
-
|
|
1014
1228
|
} catch (error) {
|
|
1015
|
-
console.error(chalk.red(
|
|
1229
|
+
console.error(chalk.red("\n❌ Update failed:"));
|
|
1016
1230
|
console.error(error.message);
|
|
1017
1231
|
if (options.verbose) {
|
|
1018
1232
|
console.error(error);
|
|
@@ -1022,49 +1236,52 @@ program
|
|
|
1022
1236
|
});
|
|
1023
1237
|
|
|
1024
1238
|
program
|
|
1025
|
-
.command(
|
|
1026
|
-
.description(
|
|
1027
|
-
.option(
|
|
1028
|
-
.option(
|
|
1029
|
-
.option(
|
|
1030
|
-
.option(
|
|
1239
|
+
.command("claudeweb")
|
|
1240
|
+
.description("Start MyAIDev Method Web UI with Claude Code Viewer")
|
|
1241
|
+
.option("-p, --port <port>", "Port to run server on", "3400")
|
|
1242
|
+
.option("--single-user", "Run in single-user mode")
|
|
1243
|
+
.option("--multi-user", "Run in multi-user mode")
|
|
1244
|
+
.option("--db-path <path>", "SQLite database path")
|
|
1031
1245
|
.action(async (options) => {
|
|
1032
1246
|
console.log(getASCIIBanner());
|
|
1033
|
-
console.log(chalk.blue(
|
|
1247
|
+
console.log(chalk.blue("\n🌐 Starting MyAIDev Method Web UI...\n"));
|
|
1034
1248
|
|
|
1035
1249
|
process.env.PORT = options.port;
|
|
1036
1250
|
if (options.dbPath) {
|
|
1037
1251
|
process.env.SQLITE_DB_PATH = options.dbPath;
|
|
1038
1252
|
}
|
|
1039
1253
|
if (options.singleUser) {
|
|
1040
|
-
process.env.SINGLE_USER_MODE =
|
|
1041
|
-
console.log(chalk.cyan(
|
|
1254
|
+
process.env.SINGLE_USER_MODE = "true";
|
|
1255
|
+
console.log(chalk.cyan("📌 Running in single-user mode"));
|
|
1042
1256
|
}
|
|
1043
1257
|
if (options.multiUser) {
|
|
1044
|
-
process.env.MULTI_USER_MODE =
|
|
1045
|
-
console.log(chalk.cyan(
|
|
1258
|
+
process.env.MULTI_USER_MODE = "true";
|
|
1259
|
+
console.log(chalk.cyan("📌 Running in multi-user mode"));
|
|
1046
1260
|
}
|
|
1047
1261
|
|
|
1048
1262
|
try {
|
|
1049
|
-
const serverModule = await import(
|
|
1050
|
-
console.log(chalk.green(
|
|
1263
|
+
const serverModule = await import("../dist/server/main.js");
|
|
1264
|
+
console.log(chalk.green("\n✅ Server module loaded successfully"));
|
|
1051
1265
|
} catch (error) {
|
|
1052
|
-
console.error(chalk.red(
|
|
1266
|
+
console.error(chalk.red("\n❌ Failed to start server:"));
|
|
1053
1267
|
console.error(error);
|
|
1054
|
-
console.log(
|
|
1055
|
-
|
|
1268
|
+
console.log(
|
|
1269
|
+
chalk.yellow("\n💡 Make sure you have built the server first:"),
|
|
1270
|
+
);
|
|
1271
|
+
console.log(chalk.gray(" npm run build:server"));
|
|
1056
1272
|
process.exit(1);
|
|
1057
1273
|
}
|
|
1058
1274
|
});
|
|
1059
1275
|
|
|
1060
1276
|
// Installation detection command (Plugin Architecture Support)
|
|
1061
1277
|
program
|
|
1062
|
-
.command(
|
|
1063
|
-
.description(
|
|
1064
|
-
.option(
|
|
1278
|
+
.command("detect")
|
|
1279
|
+
.description("Detect MyAIDev Method installation state (legacy vs plugin)")
|
|
1280
|
+
.option("--json", "Output as JSON")
|
|
1065
1281
|
.action(async (options) => {
|
|
1066
1282
|
try {
|
|
1067
|
-
const { detectInstallation, getInstallationStatus } =
|
|
1283
|
+
const { detectInstallation, getInstallationStatus } =
|
|
1284
|
+
await import("../src/lib/installation-detector.js");
|
|
1068
1285
|
|
|
1069
1286
|
if (options.json) {
|
|
1070
1287
|
const detection = await detectInstallation(process.cwd());
|
|
@@ -1074,137 +1291,162 @@ program
|
|
|
1074
1291
|
console.log(status);
|
|
1075
1292
|
}
|
|
1076
1293
|
} catch (error) {
|
|
1077
|
-
console.error(chalk.red(
|
|
1294
|
+
console.error(chalk.red("Failed to detect installation:"), error.message);
|
|
1078
1295
|
process.exit(1);
|
|
1079
1296
|
}
|
|
1080
1297
|
});
|
|
1081
1298
|
|
|
1082
1299
|
// Plugin information command
|
|
1083
1300
|
program
|
|
1084
|
-
.command(
|
|
1085
|
-
.description(
|
|
1301
|
+
.command("plugin-info")
|
|
1302
|
+
.description("Show plugin architecture information and capabilities")
|
|
1086
1303
|
.action(async () => {
|
|
1087
|
-
console.log(chalk.cyan(
|
|
1088
|
-
console.log(
|
|
1089
|
-
|
|
1090
|
-
|
|
1091
|
-
|
|
1092
|
-
|
|
1093
|
-
|
|
1094
|
-
console.log(chalk.yellow(
|
|
1095
|
-
console.log(
|
|
1096
|
-
console.log(
|
|
1097
|
-
|
|
1098
|
-
console.log(chalk.yellow(
|
|
1099
|
-
console.log(
|
|
1100
|
-
console.log(
|
|
1101
|
-
|
|
1102
|
-
console.log(
|
|
1103
|
-
console.log(
|
|
1104
|
-
console.log(
|
|
1105
|
-
console.log(
|
|
1106
|
-
|
|
1107
|
-
|
|
1108
|
-
|
|
1109
|
-
console.log(
|
|
1110
|
-
console.log(
|
|
1111
|
-
console.log(
|
|
1112
|
-
|
|
1113
|
-
|
|
1114
|
-
console.log(
|
|
1115
|
-
console.log(
|
|
1116
|
-
console.log(
|
|
1304
|
+
console.log(chalk.cyan("\n🔌 MyAIDev Method Plugin Architecture\n"));
|
|
1305
|
+
console.log(
|
|
1306
|
+
chalk.white(
|
|
1307
|
+
"════════════════════════════════════════════════════════════════\n",
|
|
1308
|
+
),
|
|
1309
|
+
);
|
|
1310
|
+
|
|
1311
|
+
console.log(chalk.yellow("📦 Installation Methods:\n"));
|
|
1312
|
+
console.log(" 1. Legacy (npx): npx myaidev-method init --claude");
|
|
1313
|
+
console.log(" 2. Plugin: /plugin install myaidev-method\n");
|
|
1314
|
+
|
|
1315
|
+
console.log(chalk.yellow("🎯 Command Formats:\n"));
|
|
1316
|
+
console.log(" Legacy: /content-writer, /myai-configure");
|
|
1317
|
+
console.log(" Namespaced: /myaidev-method:content-writer\n");
|
|
1318
|
+
|
|
1319
|
+
console.log(chalk.yellow("📚 Available Skill Packs:\n"));
|
|
1320
|
+
console.log(" • content - Content creation & WordPress publishing");
|
|
1321
|
+
console.log(" • visual - AI image/video generation");
|
|
1322
|
+
console.log(" • development - SPARC methodology for software dev");
|
|
1323
|
+
console.log(
|
|
1324
|
+
" • publishing - Multi-platform publishing (WP, Payload, Static)",
|
|
1325
|
+
);
|
|
1326
|
+
console.log(" • deployment - Coolify deployment automation");
|
|
1327
|
+
console.log(" • security - Security testing & auditing");
|
|
1328
|
+
console.log(" • openstack - OpenStack VM management\n");
|
|
1329
|
+
|
|
1330
|
+
console.log(chalk.yellow("📁 Plugin Structure:\n"));
|
|
1331
|
+
console.log(" .claude-plugin/plugin.json - Plugin manifest");
|
|
1332
|
+
console.log(" skills/ - SKILL.md files");
|
|
1333
|
+
console.log(" commands/ - Command definitions");
|
|
1334
|
+
console.log(" agents/ - Agent definitions");
|
|
1335
|
+
console.log(" hooks/hooks.json - Lifecycle hooks\n");
|
|
1336
|
+
|
|
1337
|
+
console.log(chalk.yellow("🔗 More Information:\n"));
|
|
1338
|
+
console.log(" Documentation: https://github.com/myaione/myaidev-method");
|
|
1339
|
+
console.log(
|
|
1340
|
+
" Plugin Catalog: https://myaidev.com/plugins/myaidev-method\n",
|
|
1341
|
+
);
|
|
1117
1342
|
});
|
|
1118
1343
|
|
|
1119
1344
|
// Upgrade command (legacy to plugin)
|
|
1120
1345
|
program
|
|
1121
|
-
.command(
|
|
1122
|
-
.description(
|
|
1123
|
-
.option(
|
|
1346
|
+
.command("upgrade")
|
|
1347
|
+
.description("Upgrade from legacy installation to plugin architecture")
|
|
1348
|
+
.option("--dry-run", "Show what would be upgraded without making changes")
|
|
1124
1349
|
.action(async (options) => {
|
|
1125
1350
|
try {
|
|
1126
|
-
const { detectInstallation, checkUpgradeAvailability } =
|
|
1351
|
+
const { detectInstallation, checkUpgradeAvailability } =
|
|
1352
|
+
await import("../src/lib/installation-detector.js");
|
|
1127
1353
|
const detection = await detectInstallation(process.cwd());
|
|
1128
1354
|
|
|
1129
|
-
console.log(chalk.cyan(
|
|
1355
|
+
console.log(chalk.cyan("\n🔄 MyAIDev Method Upgrade Check\n"));
|
|
1130
1356
|
|
|
1131
|
-
if (detection.installationType ===
|
|
1132
|
-
console.log(
|
|
1133
|
-
|
|
1357
|
+
if (detection.installationType === "none") {
|
|
1358
|
+
console.log(
|
|
1359
|
+
chalk.yellow("⚠️ No MyAIDev Method installation detected."),
|
|
1360
|
+
);
|
|
1361
|
+
console.log(
|
|
1362
|
+
chalk.gray(
|
|
1363
|
+
'\nRun "npx myaidev-method init --claude" to install first.\n',
|
|
1364
|
+
),
|
|
1365
|
+
);
|
|
1134
1366
|
return;
|
|
1135
1367
|
}
|
|
1136
1368
|
|
|
1137
|
-
if (
|
|
1138
|
-
|
|
1139
|
-
|
|
1369
|
+
if (
|
|
1370
|
+
detection.installationType === "plugin" ||
|
|
1371
|
+
detection.installationType === "both"
|
|
1372
|
+
) {
|
|
1373
|
+
console.log(chalk.green("✅ Plugin architecture already enabled."));
|
|
1374
|
+
console.log(chalk.gray("\nNo upgrade needed.\n"));
|
|
1140
1375
|
return;
|
|
1141
1376
|
}
|
|
1142
1377
|
|
|
1143
1378
|
const upgrade = await checkUpgradeAvailability(process.cwd());
|
|
1144
1379
|
|
|
1145
|
-
console.log(
|
|
1380
|
+
console.log(
|
|
1381
|
+
chalk.yellow("📋 Current Installation: Legacy (npx-based)\n"),
|
|
1382
|
+
);
|
|
1146
1383
|
|
|
1147
|
-
console.log(chalk.green(
|
|
1384
|
+
console.log(chalk.green("✨ Upgrade Benefits:"));
|
|
1148
1385
|
for (const benefit of upgrade.upgradeBenefits) {
|
|
1149
1386
|
console.log(` • ${benefit}`);
|
|
1150
1387
|
}
|
|
1151
1388
|
|
|
1152
|
-
console.log(chalk.blue(
|
|
1389
|
+
console.log(chalk.blue("\n🔒 Preserved Features:"));
|
|
1153
1390
|
for (const feature of upgrade.preservedFeatures) {
|
|
1154
1391
|
console.log(` • ${feature}`);
|
|
1155
1392
|
}
|
|
1156
1393
|
|
|
1157
1394
|
if (options.dryRun) {
|
|
1158
|
-
console.log(chalk.yellow(
|
|
1159
|
-
console.log(
|
|
1160
|
-
console.log(
|
|
1161
|
-
console.log(
|
|
1162
|
-
console.log(
|
|
1395
|
+
console.log(chalk.yellow("\n[DRY RUN] Would create:"));
|
|
1396
|
+
console.log(" • .claude-plugin/plugin.json");
|
|
1397
|
+
console.log(" • skills/ directory with SKILL.md files");
|
|
1398
|
+
console.log(" • hooks/hooks.json");
|
|
1399
|
+
console.log("\n[DRY RUN] No changes made.\n");
|
|
1163
1400
|
return;
|
|
1164
1401
|
}
|
|
1165
1402
|
|
|
1166
1403
|
// Prompt for confirmation
|
|
1167
1404
|
const answer = await inquirer.prompt([
|
|
1168
1405
|
{
|
|
1169
|
-
type:
|
|
1170
|
-
name:
|
|
1171
|
-
message:
|
|
1172
|
-
default: true
|
|
1173
|
-
}
|
|
1406
|
+
type: "confirm",
|
|
1407
|
+
name: "proceed",
|
|
1408
|
+
message: "Proceed with upgrade to plugin architecture?",
|
|
1409
|
+
default: true,
|
|
1410
|
+
},
|
|
1174
1411
|
]);
|
|
1175
1412
|
|
|
1176
1413
|
if (!answer.proceed) {
|
|
1177
|
-
console.log(chalk.gray(
|
|
1414
|
+
console.log(chalk.gray("\nUpgrade cancelled.\n"));
|
|
1178
1415
|
return;
|
|
1179
1416
|
}
|
|
1180
1417
|
|
|
1181
|
-
const spinner = ora(
|
|
1418
|
+
const spinner = ora("Upgrading to plugin architecture...").start();
|
|
1182
1419
|
|
|
1183
1420
|
// Copy plugin files from the package to the project
|
|
1184
1421
|
const packageRoot = path.dirname(__dirname);
|
|
1185
1422
|
|
|
1186
1423
|
// Create .claude-plugin directory
|
|
1187
|
-
await fs.ensureDir(path.join(process.cwd(),
|
|
1424
|
+
await fs.ensureDir(path.join(process.cwd(), ".claude-plugin"));
|
|
1188
1425
|
await fs.copy(
|
|
1189
|
-
path.join(packageRoot,
|
|
1190
|
-
path.join(process.cwd(),
|
|
1426
|
+
path.join(packageRoot, ".claude-plugin", "plugin.json"),
|
|
1427
|
+
path.join(process.cwd(), ".claude-plugin", "plugin.json"),
|
|
1191
1428
|
);
|
|
1192
1429
|
|
|
1193
1430
|
// Create hooks directory
|
|
1194
|
-
await fs.ensureDir(path.join(process.cwd(),
|
|
1431
|
+
await fs.ensureDir(path.join(process.cwd(), "hooks"));
|
|
1195
1432
|
await fs.copy(
|
|
1196
|
-
path.join(packageRoot,
|
|
1197
|
-
path.join(process.cwd(),
|
|
1433
|
+
path.join(packageRoot, "hooks", "hooks.json"),
|
|
1434
|
+
path.join(process.cwd(), "hooks", "hooks.json"),
|
|
1198
1435
|
);
|
|
1199
1436
|
|
|
1200
|
-
spinner.succeed(chalk.green(
|
|
1201
|
-
|
|
1202
|
-
console.log(chalk.cyan('\n✅ Plugin architecture enabled.'));
|
|
1203
|
-
console.log(chalk.gray(' Both /myai-* and /myaidev-method:* commands now available.'));
|
|
1204
|
-
console.log(chalk.yellow('\n🔄 Restart Claude Code to load new capabilities.\n'));
|
|
1437
|
+
spinner.succeed(chalk.green("Upgrade complete!"));
|
|
1205
1438
|
|
|
1439
|
+
console.log(chalk.cyan("\n✅ Plugin architecture enabled."));
|
|
1440
|
+
console.log(
|
|
1441
|
+
chalk.gray(
|
|
1442
|
+
" Both /myai-* and /myaidev-method:* commands now available.",
|
|
1443
|
+
),
|
|
1444
|
+
);
|
|
1445
|
+
console.log(
|
|
1446
|
+
chalk.yellow("\n🔄 Restart Claude Code to load new capabilities.\n"),
|
|
1447
|
+
);
|
|
1206
1448
|
} catch (error) {
|
|
1207
|
-
console.error(chalk.red(
|
|
1449
|
+
console.error(chalk.red("Failed to upgrade:"), error.message);
|
|
1208
1450
|
process.exit(1);
|
|
1209
1451
|
}
|
|
1210
1452
|
});
|
|
@@ -1213,4 +1455,4 @@ program
|
|
|
1213
1455
|
registerAuthCommands(program);
|
|
1214
1456
|
registerAddonCommand(program);
|
|
1215
1457
|
|
|
1216
|
-
program.parse(process.argv);
|
|
1458
|
+
program.parse(process.argv);
|