myaidev-method 0.3.4 → 0.3.6
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 +846 -427
- 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/{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-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/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 +105 -7
- 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/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 +19 -12
- 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/skill-builder/SKILL.md +0 -417
- package/skills/visual-generator/SKILL.md +0 -140
- /package/skills/{content-writer → myai-content-writer}/agents/editor-agent.md +0 -0
- /package/skills/{content-writer → myai-content-writer}/agents/planner-agent.md +0 -0
- /package/skills/{content-writer → myai-content-writer}/agents/research-agent.md +0 -0
- /package/skills/{content-writer → myai-content-writer}/agents/seo-agent.md +0 -0
- /package/skills/{content-writer → myai-content-writer}/agents/visual-planner-agent.md +0 -0
- /package/skills/{content-writer → myai-content-writer}/agents/writer-agent.md +0 -0
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.6")
|
|
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,258 @@ 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
|
|
376
|
-
|
|
522
|
+
const pkgJson = await fs.readJson(path.join(__dirname, "..", "package.json"));
|
|
523
|
+
const version = pkgJson.version;
|
|
524
|
+
const orange = chalk.hex("#FFA500");
|
|
525
|
+
const dim = chalk.dim;
|
|
526
|
+
|
|
377
527
|
try {
|
|
378
528
|
const cwd = process.cwd();
|
|
529
|
+
|
|
530
|
+
// ── Welcome screen ──────────────────────────────────────────────
|
|
531
|
+
console.log(getASCIIBanner());
|
|
532
|
+
console.log(
|
|
533
|
+
chalk.bold.white(" Welcome to ") +
|
|
534
|
+
orange.bold(`MyAIDev Method v${version}`) +
|
|
535
|
+
chalk.bold.white("!\n"),
|
|
536
|
+
);
|
|
537
|
+
console.log(
|
|
538
|
+
dim(" AI-powered skills for content creation, design, software\n") +
|
|
539
|
+
dim(" development, security, and deployment — installed directly\n") +
|
|
540
|
+
dim(" into your AI coding assistant.\n"),
|
|
541
|
+
);
|
|
542
|
+
console.log(
|
|
543
|
+
chalk.white(" ════════════════════════════════════════════════════════\n"),
|
|
544
|
+
);
|
|
545
|
+
|
|
546
|
+
// ── Step 1: CLI type ────────────────────────────────────────────
|
|
379
547
|
let cliType = null;
|
|
380
|
-
|
|
381
|
-
// Determine CLI type
|
|
382
548
|
if (options.claude) {
|
|
383
|
-
cliType =
|
|
549
|
+
cliType = "claude";
|
|
384
550
|
} else if (options.gemini) {
|
|
385
|
-
cliType =
|
|
551
|
+
cliType = "gemini";
|
|
386
552
|
} else if (options.codex) {
|
|
387
|
-
cliType =
|
|
553
|
+
cliType = "codex";
|
|
388
554
|
} else {
|
|
389
|
-
spinner.stop();
|
|
390
|
-
// Interactive selection if no flag provided
|
|
391
555
|
const answer = await inquirer.prompt([
|
|
392
556
|
{
|
|
393
|
-
type:
|
|
394
|
-
name:
|
|
395
|
-
message:
|
|
557
|
+
type: "list",
|
|
558
|
+
name: "cliType",
|
|
559
|
+
message: "Which AI CLI are you using?",
|
|
396
560
|
choices: [
|
|
397
|
-
{ name:
|
|
398
|
-
{ name:
|
|
399
|
-
{ name:
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
}
|
|
561
|
+
{ name: `${chalk.bold.cyan("Claude Code")} ${dim("(Recommended)")}`, value: "claude" },
|
|
562
|
+
{ name: `${chalk.bold.white("Gemini CLI")}`, value: "gemini" },
|
|
563
|
+
{ name: `${chalk.bold.white("Codex CLI")} ${dim("/ OpenCode")}`, value: "codex" },
|
|
564
|
+
],
|
|
565
|
+
default: "claude",
|
|
566
|
+
},
|
|
403
567
|
]);
|
|
404
568
|
cliType = answer.cliType;
|
|
405
|
-
spinner.start();
|
|
406
569
|
}
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
await setupCodex(cwd);
|
|
570
|
+
|
|
571
|
+
// ── Step 2: Pack selection ──────────────────────────────────────
|
|
572
|
+
let pack = options.pack || null;
|
|
573
|
+
if (pack && !["content", "design", "dev", "full"].includes(pack)) {
|
|
574
|
+
console.log(chalk.red(`\n Unknown pack: "${pack}"`));
|
|
575
|
+
console.log(dim(" Available packs: content, design, dev, full\n"));
|
|
576
|
+
process.exit(1);
|
|
415
577
|
}
|
|
416
|
-
|
|
417
|
-
spinner.succeed(chalk.green(`Successfully initialized ${cliType} configuration!`));
|
|
418
578
|
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
579
|
+
if (!pack) {
|
|
580
|
+
console.log(
|
|
581
|
+
dim("\n Choose a skill pack based on your role. You can always\n") +
|
|
582
|
+
dim(" add more packs later with: ") +
|
|
583
|
+
chalk.white("npx myaidev-method init --pack <name>\n"),
|
|
584
|
+
);
|
|
585
|
+
|
|
586
|
+
// Build rich pack descriptions
|
|
587
|
+
const contentPack = INSTALL_PACKS.content;
|
|
588
|
+
const designPack = INSTALL_PACKS.design;
|
|
589
|
+
const devPack = INSTALL_PACKS.dev;
|
|
590
|
+
|
|
591
|
+
const answer = await inquirer.prompt([
|
|
592
|
+
{
|
|
593
|
+
type: "list",
|
|
594
|
+
name: "pack",
|
|
595
|
+
message: "Select a skill pack to install:",
|
|
596
|
+
choices: [
|
|
597
|
+
new inquirer.Separator(dim(" ─── Skill Packs ──────────────────────────────────────")),
|
|
598
|
+
{
|
|
599
|
+
name: [
|
|
600
|
+
` ${chalk.green.bold("📝 Content Creation")} ${dim(`${contentPack.skills.length} skills`)}`,
|
|
601
|
+
` ${dim("For marketers & content teams")}`,
|
|
602
|
+
` ${dim("Writing, SEO, visuals, infographics, multi-platform publishing")}`,
|
|
603
|
+
].join("\n"),
|
|
604
|
+
value: "content",
|
|
605
|
+
short: "Content Creation",
|
|
606
|
+
},
|
|
607
|
+
{
|
|
608
|
+
name: [
|
|
609
|
+
` ${chalk.magenta.bold("🎨 Design")} ${dim(`${designPack.skills.length} skills`)}`,
|
|
610
|
+
` ${dim("For designers & creative teams")}`,
|
|
611
|
+
` ${dim("Figma capture, visual generation, infographics")}`,
|
|
612
|
+
].join("\n"),
|
|
613
|
+
value: "design",
|
|
614
|
+
short: "Design",
|
|
615
|
+
},
|
|
616
|
+
{
|
|
617
|
+
name: [
|
|
618
|
+
` ${chalk.blue.bold("⚡ Development")} ${dim(`${devPack.skills.length} skills`)}`,
|
|
619
|
+
` ${dim("For software engineers")}`,
|
|
620
|
+
` ${dim("SPARC workflow, security testing, deployment, git, publishing")}`,
|
|
621
|
+
].join("\n"),
|
|
622
|
+
value: "dev",
|
|
623
|
+
short: "Development",
|
|
624
|
+
},
|
|
625
|
+
new inquirer.Separator(""),
|
|
626
|
+
{
|
|
627
|
+
name: [
|
|
628
|
+
` ${orange.bold("🚀 Full")} ${dim("38 skills")}`,
|
|
629
|
+
` ${dim("Everything — all packs combined")}`,
|
|
630
|
+
].join("\n"),
|
|
631
|
+
value: "full",
|
|
632
|
+
short: "Full",
|
|
633
|
+
},
|
|
634
|
+
new inquirer.Separator(dim(" ──────────────────────────────────────────────────────")),
|
|
635
|
+
],
|
|
636
|
+
},
|
|
637
|
+
]);
|
|
638
|
+
pack = answer.pack;
|
|
443
639
|
}
|
|
444
|
-
|
|
445
|
-
|
|
640
|
+
|
|
641
|
+
// Resolve skill list
|
|
642
|
+
let skillList;
|
|
643
|
+
let packLabel;
|
|
644
|
+
let packEmoji;
|
|
645
|
+
if (pack === "full") {
|
|
646
|
+
skillList = null;
|
|
647
|
+
packLabel = "Full";
|
|
648
|
+
packEmoji = "🚀";
|
|
649
|
+
} else {
|
|
650
|
+
const packDef = INSTALL_PACKS[pack];
|
|
651
|
+
skillList = packDef.skills;
|
|
652
|
+
packLabel = packDef.name;
|
|
653
|
+
packEmoji = pack === "content" ? "📝" : pack === "design" ? "🎨" : "⚡";
|
|
654
|
+
}
|
|
655
|
+
|
|
656
|
+
// ── Step 3: Install ─────────────────────────────────────────────
|
|
657
|
+
console.log("");
|
|
658
|
+
const spinner = ora({
|
|
659
|
+
text: `Installing ${packEmoji} ${packLabel} pack for ${cliType}...`,
|
|
660
|
+
color: "cyan",
|
|
661
|
+
}).start();
|
|
662
|
+
|
|
663
|
+
if (cliType === "claude") {
|
|
664
|
+
await setupClaude(cwd, skillList);
|
|
665
|
+
} else if (cliType === "gemini") {
|
|
666
|
+
await setupGemini(cwd, skillList);
|
|
667
|
+
} else if (cliType === "codex") {
|
|
668
|
+
await setupCodex(cwd, skillList);
|
|
669
|
+
}
|
|
670
|
+
|
|
671
|
+
const skillCount = skillList ? skillList.length : 38;
|
|
672
|
+
spinner.succeed(
|
|
673
|
+
chalk.green(`${packEmoji} ${packLabel} pack installed — ${skillCount} skills ready!`),
|
|
674
|
+
);
|
|
675
|
+
|
|
676
|
+
// ── Summary ─────────────────────────────────────────────────────
|
|
677
|
+
console.log(
|
|
678
|
+
chalk.white("\n ════════════════════════════════════════════════════════\n"),
|
|
679
|
+
);
|
|
680
|
+
console.log(chalk.bold.white(" Installed Skills:\n"));
|
|
681
|
+
|
|
682
|
+
if (pack === "content" || pack === "full") {
|
|
683
|
+
console.log(chalk.green(" 📝 Content ") + dim("myai-content-writer, myai-content-production-coordinator"));
|
|
684
|
+
console.log(chalk.green(" 🎯 SEO/Quality ") + dim("myai-content-verifier, myai-content-ideation"));
|
|
685
|
+
console.log(chalk.green(" 🖼 Visual ") + dim("myai-visual-generator, myai-infographic"));
|
|
686
|
+
console.log(chalk.yellow(" 📤 Publishing ") + dim("wordpress, payloadcms, docusaurus, mintlify, astro"));
|
|
687
|
+
}
|
|
688
|
+
if (pack === "design" || pack === "full") {
|
|
689
|
+
console.log(chalk.magenta(" 🎨 Design ") + dim("myaidev-figma, myaidev-figma-configure"));
|
|
690
|
+
if (pack === "design") {
|
|
691
|
+
console.log(chalk.magenta(" 🖼 Visual ") + dim("myai-visual-generator, myai-infographic"));
|
|
692
|
+
}
|
|
693
|
+
}
|
|
694
|
+
if (pack === "dev" || pack === "full") {
|
|
695
|
+
console.log(chalk.blue(" ⚡ SPARC ") + dim("myaidev-workflow, architect, coder, tester, reviewer, documenter"));
|
|
696
|
+
console.log(chalk.blue(" 🔧 Tools ") + dim("analyze, debug, refactor, performance, migrate"));
|
|
697
|
+
console.log(chalk.cyan(" 🔀 Git ") + dim("git-workflow (pr, release, sync, hotfix)"));
|
|
698
|
+
console.log(chalk.red(" 🛡 Security ") + dim("security-tester, security-auditor"));
|
|
699
|
+
console.log(chalk.blue(" 📦 Deploy ") + dim("deployer, coolify-deployer, openstack-manager"));
|
|
700
|
+
console.log(chalk.blue(" 🧰 Skill Dev ") + dim("myai-skill-builder, skill-contributor"));
|
|
701
|
+
}
|
|
702
|
+
console.log(dim(" ⚙️ Config configure, company-config, myai-configurator"));
|
|
703
|
+
|
|
704
|
+
// ── Next steps ──────────────────────────────────────────────────
|
|
705
|
+
console.log(
|
|
706
|
+
chalk.white("\n ════════════════════════════════════════════════════════\n"),
|
|
707
|
+
);
|
|
708
|
+
console.log(chalk.bold.white(" Next Steps:\n"));
|
|
709
|
+
console.log(
|
|
710
|
+
chalk.white(" 1. ") + chalk.cyan("Restart your AI CLI") + dim(" to load the new skills"),
|
|
711
|
+
);
|
|
712
|
+
console.log(
|
|
713
|
+
chalk.white(" 2. ") + chalk.cyan("npx myaidev-method login") + dim(" — connect to the marketplace"),
|
|
714
|
+
);
|
|
715
|
+
console.log(
|
|
716
|
+
chalk.white(" 3. ") + dim("Start using skills naturally in conversation, e.g.:"),
|
|
717
|
+
);
|
|
718
|
+
|
|
719
|
+
if (pack === "content") {
|
|
720
|
+
console.log(dim(' "Write a blog post about AI in healthcare"'));
|
|
721
|
+
} else if (pack === "design") {
|
|
722
|
+
console.log(dim(' "Capture the homepage of stripe.com into Figma"'));
|
|
723
|
+
} else if (pack === "dev") {
|
|
724
|
+
console.log(dim(' "Build a REST API for user management"'));
|
|
725
|
+
} else {
|
|
726
|
+
console.log(dim(' "Build a REST API" or "Write a blog post about AI"'));
|
|
727
|
+
}
|
|
728
|
+
|
|
729
|
+
console.log(
|
|
730
|
+
dim("\n • Add more packs: ") + chalk.white("npx myaidev-method init --pack <name>"),
|
|
731
|
+
);
|
|
732
|
+
console.log(
|
|
733
|
+
dim(" • Browse skills: ") + chalk.white("npx myaidev-method addon list"),
|
|
734
|
+
);
|
|
735
|
+
console.log(
|
|
736
|
+
dim(" • Documentation: ") + chalk.white("https://github.com/myaione/myaidev-method\n"),
|
|
737
|
+
);
|
|
446
738
|
} catch (error) {
|
|
447
|
-
|
|
739
|
+
if (error.name === 'ExitPromptError') {
|
|
740
|
+
console.log(chalk.gray("\nCancelled.\n"));
|
|
741
|
+
return;
|
|
742
|
+
}
|
|
743
|
+
console.error(chalk.red("Failed to initialize configuration"));
|
|
448
744
|
console.error(error);
|
|
449
745
|
process.exit(1);
|
|
450
746
|
}
|
|
451
747
|
});
|
|
452
748
|
|
|
453
|
-
async function setupClaude(projectDir) {
|
|
749
|
+
async function setupClaude(projectDir, skillFilter = null) {
|
|
454
750
|
// Create .claude directory structure — skills-only architecture
|
|
455
|
-
const claudeDir = path.join(projectDir,
|
|
456
|
-
const mcpDir = path.join(claudeDir,
|
|
751
|
+
const claudeDir = path.join(projectDir, ".claude");
|
|
752
|
+
const mcpDir = path.join(claudeDir, "mcp");
|
|
457
753
|
|
|
458
754
|
await fs.ensureDir(claudeDir);
|
|
459
755
|
await fs.ensureDir(mcpDir);
|
|
460
756
|
|
|
461
757
|
// Copy skills (each skill is a directory with SKILL.md + optional agents/)
|
|
462
|
-
|
|
758
|
+
// If skillFilter is null, install all skills. Otherwise only install listed ones.
|
|
759
|
+
const sourceSkillsDir = path.join(__dirname, "..", "skills");
|
|
463
760
|
if (await fs.pathExists(sourceSkillsDir)) {
|
|
464
|
-
const skillsDir = path.join(claudeDir,
|
|
761
|
+
const skillsDir = path.join(claudeDir, "skills");
|
|
465
762
|
await fs.ensureDir(skillsDir);
|
|
466
763
|
const skillDirs = await fs.readdir(sourceSkillsDir);
|
|
764
|
+
const allowedSkills = skillFilter ? new Set(skillFilter) : null;
|
|
467
765
|
for (const skillName of skillDirs) {
|
|
766
|
+
if (allowedSkills && !allowedSkills.has(skillName)) continue;
|
|
468
767
|
const skillPath = path.join(sourceSkillsDir, skillName);
|
|
469
768
|
const stat = await fs.stat(skillPath);
|
|
470
769
|
if (stat.isDirectory()) {
|
|
@@ -474,56 +773,61 @@ async function setupClaude(projectDir) {
|
|
|
474
773
|
}
|
|
475
774
|
|
|
476
775
|
// Copy MCP server files
|
|
477
|
-
const templateMcpDir = path.join(__dirname,
|
|
776
|
+
const templateMcpDir = path.join(__dirname, "..", "src", "mcp");
|
|
478
777
|
if (await fs.pathExists(templateMcpDir)) {
|
|
479
778
|
const mcpFiles = await fs.readdir(templateMcpDir);
|
|
480
779
|
for (const file of mcpFiles) {
|
|
481
|
-
if (file.endsWith(
|
|
482
|
-
await fs.copy(
|
|
483
|
-
path.join(templateMcpDir, file),
|
|
484
|
-
path.join(mcpDir, file)
|
|
485
|
-
);
|
|
780
|
+
if (file.endsWith(".js") || file.endsWith(".json")) {
|
|
781
|
+
await fs.copy(path.join(templateMcpDir, file), path.join(mcpDir, file));
|
|
486
782
|
}
|
|
487
783
|
}
|
|
488
784
|
}
|
|
489
|
-
|
|
785
|
+
|
|
490
786
|
// Create CLAUDE.md configuration file from template
|
|
491
|
-
const claudeMdTemplate = path.join(
|
|
787
|
+
const claudeMdTemplate = path.join(
|
|
788
|
+
__dirname,
|
|
789
|
+
"..",
|
|
790
|
+
"src",
|
|
791
|
+
"templates",
|
|
792
|
+
"claude",
|
|
793
|
+
"CLAUDE.md",
|
|
794
|
+
);
|
|
492
795
|
if (await fs.pathExists(claudeMdTemplate)) {
|
|
493
|
-
await fs.copy(claudeMdTemplate, path.join(claudeDir,
|
|
796
|
+
await fs.copy(claudeMdTemplate, path.join(claudeDir, "CLAUDE.md"));
|
|
494
797
|
}
|
|
495
|
-
|
|
798
|
+
|
|
496
799
|
// Copy the comprehensive .env.example from package
|
|
497
|
-
const sourceEnvExample = path.join(__dirname,
|
|
800
|
+
const sourceEnvExample = path.join(__dirname, "..", ".env.example");
|
|
498
801
|
if (await fs.pathExists(sourceEnvExample)) {
|
|
499
|
-
await fs.copy(sourceEnvExample, path.join(projectDir,
|
|
802
|
+
await fs.copy(sourceEnvExample, path.join(projectDir, ".env.example"));
|
|
500
803
|
}
|
|
501
804
|
|
|
502
805
|
// Create .myaidev-method directory for scripts and utilities
|
|
503
806
|
// This allows agents to access publishing/deployment scripts in non-Node.js projects
|
|
504
|
-
const myaidevDir = path.join(projectDir,
|
|
505
|
-
const scriptsDir = path.join(myaidevDir,
|
|
506
|
-
const libDir = path.join(myaidevDir,
|
|
807
|
+
const myaidevDir = path.join(projectDir, ".myaidev-method");
|
|
808
|
+
const scriptsDir = path.join(myaidevDir, "scripts");
|
|
809
|
+
const libDir = path.join(myaidevDir, "lib");
|
|
507
810
|
|
|
508
811
|
await fs.ensureDir(scriptsDir);
|
|
509
812
|
await fs.ensureDir(libDir);
|
|
510
813
|
|
|
511
814
|
// Copy all executable scripts
|
|
512
|
-
const sourceScriptsDir = path.join(__dirname,
|
|
815
|
+
const sourceScriptsDir = path.join(__dirname, "..", "src", "scripts");
|
|
513
816
|
if (await fs.pathExists(sourceScriptsDir)) {
|
|
514
817
|
const scriptFiles = await fs.readdir(sourceScriptsDir);
|
|
515
818
|
for (const file of scriptFiles) {
|
|
516
|
-
if (file.endsWith(
|
|
819
|
+
if (file.endsWith(".js") && file !== "init-project.js") {
|
|
820
|
+
// Skip init script
|
|
517
821
|
await fs.copy(
|
|
518
822
|
path.join(sourceScriptsDir, file),
|
|
519
|
-
path.join(scriptsDir, file)
|
|
823
|
+
path.join(scriptsDir, file),
|
|
520
824
|
);
|
|
521
825
|
}
|
|
522
826
|
}
|
|
523
827
|
}
|
|
524
828
|
|
|
525
829
|
// Copy all utility libraries
|
|
526
|
-
const sourceLibDir = path.join(__dirname,
|
|
830
|
+
const sourceLibDir = path.join(__dirname, "..", "src", "lib");
|
|
527
831
|
if (await fs.pathExists(sourceLibDir)) {
|
|
528
832
|
await fs.copy(sourceLibDir, libDir);
|
|
529
833
|
}
|
|
@@ -531,99 +835,121 @@ async function setupClaude(projectDir) {
|
|
|
531
835
|
// Copy package.json and install dependencies in .myaidev-method
|
|
532
836
|
// This ensures scripts have access to required npm packages
|
|
533
837
|
const packageJson = {
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
838
|
+
name: "myaidev-method-scripts",
|
|
839
|
+
version: "1.0.0",
|
|
840
|
+
type: "module",
|
|
841
|
+
private: true,
|
|
842
|
+
dependencies: {
|
|
539
843
|
"node-fetch": "^3.3.2",
|
|
540
|
-
|
|
844
|
+
marked: "^11.0.0",
|
|
541
845
|
"gray-matter": "^4.0.3",
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
}
|
|
846
|
+
dotenv: "^16.4.1",
|
|
847
|
+
chalk: "^5.3.0",
|
|
848
|
+
ora: "^8.0.1",
|
|
849
|
+
},
|
|
546
850
|
};
|
|
547
851
|
|
|
548
852
|
await fs.writeFile(
|
|
549
|
-
path.join(myaidevDir,
|
|
550
|
-
JSON.stringify(packageJson, null, 2)
|
|
853
|
+
path.join(myaidevDir, "package.json"),
|
|
854
|
+
JSON.stringify(packageJson, null, 2),
|
|
551
855
|
);
|
|
552
856
|
|
|
553
857
|
// Install dependencies in .myaidev-method directory
|
|
554
|
-
console.log(chalk.gray(
|
|
555
|
-
const { execSync } = await import(
|
|
858
|
+
console.log(chalk.gray("\n Installing script dependencies..."));
|
|
859
|
+
const { execSync } = await import("child_process");
|
|
556
860
|
try {
|
|
557
|
-
execSync(
|
|
861
|
+
execSync("npm install", {
|
|
558
862
|
cwd: myaidevDir,
|
|
559
|
-
stdio:
|
|
863
|
+
stdio: "inherit",
|
|
560
864
|
});
|
|
561
|
-
console.log(chalk.green(
|
|
865
|
+
console.log(chalk.green(" ✓ Dependencies installed successfully"));
|
|
562
866
|
} catch (error) {
|
|
563
|
-
console.log(
|
|
564
|
-
|
|
867
|
+
console.log(
|
|
868
|
+
chalk.yellow(" ⚠ Failed to install dependencies automatically"),
|
|
869
|
+
);
|
|
870
|
+
console.log(chalk.gray(" Run: cd .myaidev-method && npm install"));
|
|
565
871
|
}
|
|
566
872
|
|
|
567
|
-
// Note: MCP
|
|
873
|
+
// Note: fal.ai MCP server configured in settings.json for visual generation
|
|
874
|
+
// WordPress MCP integration still uses native REST API approach
|
|
568
875
|
|
|
569
876
|
// Copy documentation files to project root (limited to essential guides)
|
|
570
877
|
const docsToMerge = [
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
878
|
+
"USER_GUIDE.md",
|
|
879
|
+
"DEV_WORKFLOW_GUIDE.md",
|
|
880
|
+
"PUBLISHING_GUIDE.md",
|
|
574
881
|
];
|
|
575
882
|
|
|
576
883
|
for (const docFile of docsToMerge) {
|
|
577
|
-
const sourcePath = path.join(__dirname,
|
|
884
|
+
const sourcePath = path.join(__dirname, "..", docFile);
|
|
578
885
|
if (await fs.pathExists(sourcePath)) {
|
|
579
886
|
await fs.copy(sourcePath, path.join(projectDir, docFile));
|
|
580
887
|
}
|
|
581
888
|
}
|
|
582
889
|
|
|
583
890
|
// Copy template documentation (WordPress integration, etc.)
|
|
584
|
-
const templateDocsDir = path.join(
|
|
891
|
+
const templateDocsDir = path.join(
|
|
892
|
+
__dirname,
|
|
893
|
+
"..",
|
|
894
|
+
"src",
|
|
895
|
+
"templates",
|
|
896
|
+
"docs",
|
|
897
|
+
);
|
|
585
898
|
if (await fs.pathExists(templateDocsDir)) {
|
|
586
899
|
const docFiles = await fs.readdir(templateDocsDir);
|
|
587
900
|
for (const file of docFiles) {
|
|
588
|
-
if (file.endsWith(
|
|
901
|
+
if (file.endsWith(".md")) {
|
|
589
902
|
const destPath = path.join(projectDir, file);
|
|
590
903
|
// Only copy if destination doesn't exist (don't overwrite user customizations)
|
|
591
|
-
if (!await fs.pathExists(destPath)) {
|
|
592
|
-
await fs.copy(
|
|
593
|
-
path.join(templateDocsDir, file),
|
|
594
|
-
destPath
|
|
595
|
-
);
|
|
904
|
+
if (!(await fs.pathExists(destPath))) {
|
|
905
|
+
await fs.copy(path.join(templateDocsDir, file), destPath);
|
|
596
906
|
}
|
|
597
907
|
}
|
|
598
908
|
}
|
|
599
909
|
}
|
|
600
910
|
|
|
601
911
|
// Create content-rules.md if it doesn't already exist
|
|
602
|
-
const contentRulesPath = path.join(projectDir,
|
|
603
|
-
if (!await fs.pathExists(contentRulesPath)) {
|
|
604
|
-
const contentRulesTemplate = path.join(
|
|
912
|
+
const contentRulesPath = path.join(projectDir, "content-rules.md");
|
|
913
|
+
if (!(await fs.pathExists(contentRulesPath))) {
|
|
914
|
+
const contentRulesTemplate = path.join(
|
|
915
|
+
__dirname,
|
|
916
|
+
"..",
|
|
917
|
+
"content-rules-example.md",
|
|
918
|
+
);
|
|
605
919
|
if (await fs.pathExists(contentRulesTemplate)) {
|
|
606
920
|
await fs.copy(contentRulesTemplate, contentRulesPath);
|
|
607
|
-
console.log(
|
|
921
|
+
console.log(
|
|
922
|
+
chalk.green(
|
|
923
|
+
" ✓ Created content-rules.md for customizable content generation",
|
|
924
|
+
),
|
|
925
|
+
);
|
|
608
926
|
}
|
|
609
927
|
} else {
|
|
610
|
-
console.log(
|
|
928
|
+
console.log(
|
|
929
|
+
chalk.gray(" ℹ content-rules.md already exists, skipping creation"),
|
|
930
|
+
);
|
|
611
931
|
}
|
|
612
932
|
|
|
613
933
|
// Save installation version for update tracking
|
|
614
|
-
const pkgJson = await fs.readJson(path.join(__dirname,
|
|
615
|
-
const versionFile = path.join(claudeDir,
|
|
934
|
+
const pkgJson = await fs.readJson(path.join(__dirname, "..", "package.json"));
|
|
935
|
+
const versionFile = path.join(claudeDir, ".myaidev-version");
|
|
616
936
|
await fs.writeFile(versionFile, pkgJson.version);
|
|
617
937
|
|
|
618
938
|
// Copy statusline script and configure settings.json
|
|
619
|
-
const statuslineSrc = path.join(
|
|
620
|
-
|
|
939
|
+
const statuslineSrc = path.join(
|
|
940
|
+
__dirname,
|
|
941
|
+
"..",
|
|
942
|
+
"src",
|
|
943
|
+
"statusline",
|
|
944
|
+
"statusline.sh",
|
|
945
|
+
);
|
|
946
|
+
const statuslineDest = path.join(claudeDir, "statusline.sh");
|
|
621
947
|
if (await fs.pathExists(statuslineSrc)) {
|
|
622
948
|
await fs.copy(statuslineSrc, statuslineDest);
|
|
623
949
|
await fs.chmod(statuslineDest, 0o755);
|
|
624
950
|
|
|
625
951
|
// Create or merge .claude/settings.json with statusLine config
|
|
626
|
-
const settingsPath = path.join(claudeDir,
|
|
952
|
+
const settingsPath = path.join(claudeDir, "settings.json");
|
|
627
953
|
let settings = {};
|
|
628
954
|
if (await fs.pathExists(settingsPath)) {
|
|
629
955
|
try {
|
|
@@ -633,35 +959,51 @@ async function setupClaude(projectDir) {
|
|
|
633
959
|
}
|
|
634
960
|
}
|
|
635
961
|
settings.statusLine = {
|
|
636
|
-
type:
|
|
637
|
-
command:
|
|
962
|
+
type: "command",
|
|
963
|
+
command: ".claude/statusline.sh",
|
|
638
964
|
};
|
|
639
965
|
settings.extraKnownMarketplaces = {
|
|
640
|
-
|
|
966
|
+
"myaidev-marketplace": {
|
|
641
967
|
source: {
|
|
642
|
-
source:
|
|
643
|
-
repo:
|
|
644
|
-
}
|
|
645
|
-
}
|
|
968
|
+
source: "github",
|
|
969
|
+
repo: "myaione/myaidev-marketplace",
|
|
970
|
+
},
|
|
971
|
+
},
|
|
972
|
+
};
|
|
973
|
+
// Configure MCP servers for enhanced tool access
|
|
974
|
+
settings.mcpServers = settings.mcpServers || {};
|
|
975
|
+
settings.mcpServers["fal-ai"] = {
|
|
976
|
+
command: "npx",
|
|
977
|
+
args: ["-y", "fal-ai-mcp-server"],
|
|
978
|
+
env: {
|
|
979
|
+
FAL_KEY: "",
|
|
980
|
+
},
|
|
646
981
|
};
|
|
647
982
|
await fs.writeJson(settingsPath, settings, { spaces: 2 });
|
|
648
|
-
console.log(chalk.green(
|
|
983
|
+
console.log(chalk.green(" ✓ Status line configured"));
|
|
984
|
+
console.log(
|
|
985
|
+
chalk.green(
|
|
986
|
+
" ✓ fal.ai MCP server configured (set FAL_KEY to activate)",
|
|
987
|
+
),
|
|
988
|
+
);
|
|
649
989
|
}
|
|
650
990
|
}
|
|
651
991
|
|
|
652
|
-
async function setupGemini(projectDir) {
|
|
992
|
+
async function setupGemini(projectDir, skillFilter = null) {
|
|
653
993
|
// Setup Gemini CLI — skills-based architecture
|
|
654
994
|
// Gemini CLI supports Agent Skills standard natively (.gemini/skills/)
|
|
655
|
-
const geminiDir = path.join(projectDir,
|
|
995
|
+
const geminiDir = path.join(projectDir, ".gemini");
|
|
656
996
|
await fs.ensureDir(geminiDir);
|
|
657
997
|
|
|
658
998
|
// Copy skills (same SKILL.md format works cross-platform)
|
|
659
|
-
const sourceSkillsDir = path.join(__dirname,
|
|
999
|
+
const sourceSkillsDir = path.join(__dirname, "..", "skills");
|
|
660
1000
|
if (await fs.pathExists(sourceSkillsDir)) {
|
|
661
|
-
const skillsDir = path.join(geminiDir,
|
|
1001
|
+
const skillsDir = path.join(geminiDir, "skills");
|
|
662
1002
|
await fs.ensureDir(skillsDir);
|
|
663
1003
|
const skillDirs = await fs.readdir(sourceSkillsDir);
|
|
1004
|
+
const allowedSkills = skillFilter ? new Set(skillFilter) : null;
|
|
664
1005
|
for (const skillName of skillDirs) {
|
|
1006
|
+
if (allowedSkills && !allowedSkills.has(skillName)) continue;
|
|
665
1007
|
const skillPath = path.join(sourceSkillsDir, skillName);
|
|
666
1008
|
const stat = await fs.stat(skillPath);
|
|
667
1009
|
if (stat.isDirectory()) {
|
|
@@ -685,7 +1027,7 @@ Skills are discovered automatically. Gemini activates them when relevant to your
|
|
|
685
1027
|
|
|
686
1028
|
### Content & Publishing
|
|
687
1029
|
- \`content-writer\` - SEO-optimized content creation
|
|
688
|
-
- \`
|
|
1030
|
+
- \`content-publisher\` - Multi-platform publishing (WordPress, PayloadCMS, Astro, Docusaurus, Mintlify)
|
|
689
1031
|
|
|
690
1032
|
### DevOps
|
|
691
1033
|
- \`deployer\` / \`coolify-deployer\` - Multi-environment deployment
|
|
@@ -704,22 +1046,24 @@ Skills are discovered automatically. Gemini activates them when relevant to your
|
|
|
704
1046
|
\`\`\`
|
|
705
1047
|
`;
|
|
706
1048
|
|
|
707
|
-
await fs.writeFile(path.join(geminiDir,
|
|
1049
|
+
await fs.writeFile(path.join(geminiDir, "GEMINI.md"), geminiMd);
|
|
708
1050
|
}
|
|
709
1051
|
|
|
710
|
-
async function setupCodex(projectDir) {
|
|
1052
|
+
async function setupCodex(projectDir, skillFilter = null) {
|
|
711
1053
|
// Setup Codex/OpenCode — skills-based architecture
|
|
712
1054
|
// Codex supports Agent Skills standard (experimental via experimental.skills)
|
|
713
|
-
const codexDir = path.join(projectDir,
|
|
1055
|
+
const codexDir = path.join(projectDir, ".codex");
|
|
714
1056
|
await fs.ensureDir(codexDir);
|
|
715
1057
|
|
|
716
1058
|
// Copy skills (same SKILL.md format works cross-platform)
|
|
717
|
-
const sourceSkillsDir = path.join(__dirname,
|
|
1059
|
+
const sourceSkillsDir = path.join(__dirname, "..", "skills");
|
|
718
1060
|
if (await fs.pathExists(sourceSkillsDir)) {
|
|
719
|
-
const skillsDir = path.join(codexDir,
|
|
1061
|
+
const skillsDir = path.join(codexDir, "skills");
|
|
720
1062
|
await fs.ensureDir(skillsDir);
|
|
721
1063
|
const skillDirs = await fs.readdir(sourceSkillsDir);
|
|
1064
|
+
const allowedSkills = skillFilter ? new Set(skillFilter) : null;
|
|
722
1065
|
for (const skillName of skillDirs) {
|
|
1066
|
+
if (allowedSkills && !allowedSkills.has(skillName)) continue;
|
|
723
1067
|
const skillPath = path.join(sourceSkillsDir, skillName);
|
|
724
1068
|
const stat = await fs.stat(skillPath);
|
|
725
1069
|
if (stat.isDirectory()) {
|
|
@@ -743,7 +1087,7 @@ Enable experimental skills support: \`experimental.skills = true\` in settings.
|
|
|
743
1087
|
|
|
744
1088
|
### Content & Publishing
|
|
745
1089
|
- \`content-writer\` - SEO-optimized content creation
|
|
746
|
-
- \`
|
|
1090
|
+
- \`content-publisher\` - Multi-platform publishing (WordPress, PayloadCMS, Astro, Docusaurus, Mintlify)
|
|
747
1091
|
|
|
748
1092
|
### DevOps
|
|
749
1093
|
- \`deployer\` / \`coolify-deployer\` - Multi-environment deployment
|
|
@@ -753,115 +1097,159 @@ Enable experimental skills support: \`experimental.skills = true\` in settings.
|
|
|
753
1097
|
- \`security-tester\` / \`security-auditor\`
|
|
754
1098
|
`;
|
|
755
1099
|
|
|
756
|
-
await fs.writeFile(path.join(codexDir,
|
|
1100
|
+
await fs.writeFile(path.join(codexDir, "AGENTS.md"), agentsMd);
|
|
757
1101
|
}
|
|
758
1102
|
|
|
759
1103
|
program
|
|
760
|
-
.command(
|
|
761
|
-
.description(
|
|
762
|
-
.option(
|
|
763
|
-
.option(
|
|
764
|
-
.option(
|
|
765
|
-
.option(
|
|
766
|
-
.option(
|
|
767
|
-
.option(
|
|
768
|
-
.option(
|
|
769
|
-
|
|
770
|
-
|
|
1104
|
+
.command("update")
|
|
1105
|
+
.description("Update MyAIDev Method components to latest version")
|
|
1106
|
+
.option("--claude", "Update Claude Code configuration")
|
|
1107
|
+
.option("--gemini", "Update Gemini CLI configuration")
|
|
1108
|
+
.option("--codex", "Update Codex CLI configuration")
|
|
1109
|
+
.option("--force", "Force update all files without prompting")
|
|
1110
|
+
.option("--dry-run", "Show what would be updated without making changes")
|
|
1111
|
+
.option("--verbose", "Show detailed progress")
|
|
1112
|
+
.option(
|
|
1113
|
+
"--smart",
|
|
1114
|
+
"Smart update: keep customizations, add new files (no prompts)",
|
|
1115
|
+
)
|
|
1116
|
+
.option("--accept-all", "Accept all updates: replace all files (no prompts)")
|
|
1117
|
+
.option(
|
|
1118
|
+
"--keep-mine",
|
|
1119
|
+
"Keep all customizations: only add new files (no prompts)",
|
|
1120
|
+
)
|
|
771
1121
|
.action(async (options) => {
|
|
772
|
-
const ora = (await import(
|
|
773
|
-
const { fileURLToPath } = await import(
|
|
774
|
-
const updateManager = await import(
|
|
1122
|
+
const ora = (await import("ora")).default;
|
|
1123
|
+
const { fileURLToPath } = await import("url");
|
|
1124
|
+
const updateManager = await import("../src/lib/update-manager.js");
|
|
775
1125
|
|
|
776
1126
|
const __filename = fileURLToPath(import.meta.url);
|
|
777
1127
|
const __dirname = path.dirname(__filename);
|
|
778
|
-
const packageRoot = path.join(__dirname,
|
|
1128
|
+
const packageRoot = path.join(__dirname, "..");
|
|
779
1129
|
|
|
780
1130
|
try {
|
|
781
1131
|
const cwd = process.cwd();
|
|
782
1132
|
|
|
783
1133
|
// Display branding banner
|
|
784
1134
|
console.log(getASCIIBanner());
|
|
785
|
-
console.log(
|
|
1135
|
+
console.log(
|
|
1136
|
+
chalk.cyan.bold(" ⚡ Update Manager\n"),
|
|
1137
|
+
);
|
|
786
1138
|
|
|
787
1139
|
// Detect existing installation
|
|
788
|
-
const spinner = ora(
|
|
1140
|
+
const spinner = ora("Detecting MyAIDev Method installation...").start();
|
|
789
1141
|
const installation = await updateManager.detectExistingInstallation(cwd);
|
|
790
1142
|
|
|
791
1143
|
if (!installation) {
|
|
792
|
-
spinner.fail(
|
|
793
|
-
console.log(
|
|
1144
|
+
spinner.fail("No MyAIDev Method installation found");
|
|
1145
|
+
console.log(
|
|
1146
|
+
chalk.gray(" Run: npx myaidev-method@latest init --claude"),
|
|
1147
|
+
);
|
|
794
1148
|
process.exit(1);
|
|
795
1149
|
}
|
|
796
1150
|
|
|
797
|
-
spinner.succeed(
|
|
1151
|
+
spinner.succeed(
|
|
1152
|
+
`Found ${installation.type} installation (v${installation.currentVersion})`,
|
|
1153
|
+
);
|
|
798
1154
|
|
|
799
1155
|
// Get package version
|
|
800
|
-
const packageJson = await fs.readJson(
|
|
1156
|
+
const packageJson = await fs.readJson(
|
|
1157
|
+
path.join(packageRoot, "package.json"),
|
|
1158
|
+
);
|
|
801
1159
|
const newVersion = packageJson.version;
|
|
802
1160
|
|
|
803
1161
|
// Check if already up to date
|
|
804
1162
|
if (installation.currentVersion === newVersion && !options.force) {
|
|
805
|
-
console.log(chalk.green(
|
|
1163
|
+
console.log(chalk.green("\n✅ Already up to date!\n"));
|
|
806
1164
|
process.exit(0);
|
|
807
1165
|
}
|
|
808
1166
|
|
|
809
1167
|
// Generate change summary
|
|
810
|
-
const summarySpinner = ora(
|
|
811
|
-
const components = [
|
|
1168
|
+
const summarySpinner = ora("Analyzing changes...").start();
|
|
1169
|
+
const components = ["skills", "scripts", "lib", "mcp", "config", "docs"];
|
|
812
1170
|
const summary = await updateManager.generateChangeSummary(
|
|
813
|
-
components,
|
|
1171
|
+
components,
|
|
1172
|
+
cwd,
|
|
1173
|
+
installation.type,
|
|
1174
|
+
packageRoot,
|
|
814
1175
|
);
|
|
815
|
-
summarySpinner.succeed(
|
|
1176
|
+
summarySpinner.succeed("Change analysis complete");
|
|
816
1177
|
|
|
817
1178
|
// Display summary dashboard
|
|
818
|
-
console.log(
|
|
819
|
-
updateManager.displayChangeSummary(
|
|
1179
|
+
console.log("");
|
|
1180
|
+
updateManager.displayChangeSummary(
|
|
1181
|
+
summary,
|
|
1182
|
+
installation.currentVersion,
|
|
1183
|
+
newVersion,
|
|
1184
|
+
);
|
|
820
1185
|
|
|
821
1186
|
// Dry run mode - just show summary and exit
|
|
822
1187
|
if (options.dryRun) {
|
|
823
|
-
console.log(chalk.yellow(
|
|
824
|
-
console.log(chalk.gray(
|
|
1188
|
+
console.log(chalk.yellow("\n📋 DRY RUN — No changes were made."));
|
|
1189
|
+
console.log(chalk.gray(" Run without --dry-run to apply updates.\n"));
|
|
825
1190
|
process.exit(0);
|
|
826
1191
|
}
|
|
827
1192
|
|
|
828
1193
|
// Determine strategy (CLI flag or prompt)
|
|
829
1194
|
let strategy;
|
|
830
1195
|
if (options.smart) {
|
|
831
|
-
strategy =
|
|
832
|
-
console.log(
|
|
1196
|
+
strategy = "smart";
|
|
1197
|
+
console.log(
|
|
1198
|
+
chalk.cyan("\n🚀 Using Smart Update strategy (--smart flag)\n"),
|
|
1199
|
+
);
|
|
833
1200
|
} else if (options.acceptAll) {
|
|
834
|
-
strategy =
|
|
835
|
-
console.log(
|
|
1201
|
+
strategy = "accept-all";
|
|
1202
|
+
console.log(
|
|
1203
|
+
chalk.cyan("\n📥 Using Accept All strategy (--accept-all flag)\n"),
|
|
1204
|
+
);
|
|
836
1205
|
} else if (options.keepMine) {
|
|
837
|
-
strategy =
|
|
838
|
-
console.log(
|
|
1206
|
+
strategy = "keep-all";
|
|
1207
|
+
console.log(
|
|
1208
|
+
chalk.cyan("\n🛡️ Using Keep All strategy (--keep-mine flag)\n"),
|
|
1209
|
+
);
|
|
839
1210
|
} else if (options.force) {
|
|
840
|
-
strategy =
|
|
841
|
-
console.log(
|
|
1211
|
+
strategy = "accept-all";
|
|
1212
|
+
console.log(
|
|
1213
|
+
chalk.cyan("\n📥 Using Accept All strategy (--force flag)\n"),
|
|
1214
|
+
);
|
|
842
1215
|
} else {
|
|
843
1216
|
strategy = await updateManager.promptUpdateStrategy(summary);
|
|
844
1217
|
}
|
|
845
1218
|
|
|
846
1219
|
// Create timestamped backup directory
|
|
847
|
-
const backupDir = await updateManager.createTimestampedBackup(
|
|
1220
|
+
const backupDir = await updateManager.createTimestampedBackup(
|
|
1221
|
+
cwd,
|
|
1222
|
+
installation.type,
|
|
1223
|
+
);
|
|
848
1224
|
|
|
849
1225
|
// Execute selected strategy
|
|
850
1226
|
let results;
|
|
851
|
-
console.log(chalk.cyan(
|
|
1227
|
+
console.log(chalk.cyan("\n📦 Applying updates...\n"));
|
|
852
1228
|
|
|
853
|
-
if (strategy ===
|
|
1229
|
+
if (strategy === "auto" || summary.modified.length === 0) {
|
|
854
1230
|
// No conflicts - just add new files
|
|
855
|
-
results = await updateManager.executeKeepAll(summary, {
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
} else if (strategy ===
|
|
859
|
-
results = await updateManager.
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
} else if (strategy ===
|
|
863
|
-
results = await updateManager.
|
|
864
|
-
|
|
1231
|
+
results = await updateManager.executeKeepAll(summary, {
|
|
1232
|
+
verbose: options.verbose,
|
|
1233
|
+
});
|
|
1234
|
+
} else if (strategy === "smart") {
|
|
1235
|
+
results = await updateManager.executeSmartUpdate(summary, backupDir, {
|
|
1236
|
+
verbose: options.verbose,
|
|
1237
|
+
});
|
|
1238
|
+
} else if (strategy === "accept-all") {
|
|
1239
|
+
results = await updateManager.executeAcceptAll(summary, backupDir, {
|
|
1240
|
+
verbose: options.verbose,
|
|
1241
|
+
});
|
|
1242
|
+
} else if (strategy === "keep-all") {
|
|
1243
|
+
results = await updateManager.executeKeepAll(summary, {
|
|
1244
|
+
verbose: options.verbose,
|
|
1245
|
+
});
|
|
1246
|
+
} else if (strategy === "by-category") {
|
|
1247
|
+
results = await updateManager.executeCategoryUpdate(
|
|
1248
|
+
summary,
|
|
1249
|
+
backupDir,
|
|
1250
|
+
{ verbose: options.verbose },
|
|
1251
|
+
);
|
|
1252
|
+
} else if (strategy === "individual") {
|
|
865
1253
|
// Fall back to old file-by-file for this mode
|
|
866
1254
|
results = { updated: [], kept: [], added: [], backedUp: [] };
|
|
867
1255
|
for (const f of summary.new) {
|
|
@@ -873,11 +1261,15 @@ program
|
|
|
873
1261
|
}
|
|
874
1262
|
}
|
|
875
1263
|
for (const f of summary.modified) {
|
|
876
|
-
const action = await updateManager.promptForConflict(
|
|
877
|
-
|
|
1264
|
+
const action = await updateManager.promptForConflict(
|
|
1265
|
+
f.file,
|
|
1266
|
+
f.targetPath,
|
|
1267
|
+
f.sourcePath,
|
|
1268
|
+
);
|
|
1269
|
+
if (action === "replace") {
|
|
878
1270
|
await fs.copy(f.sourcePath, f.targetPath);
|
|
879
1271
|
results.updated.push(f.file);
|
|
880
|
-
} else if (action ===
|
|
1272
|
+
} else if (action === "backup") {
|
|
881
1273
|
const backupPath = path.join(backupDir, f.componentType, f.file);
|
|
882
1274
|
await fs.ensureDir(path.dirname(backupPath));
|
|
883
1275
|
await fs.copy(f.targetPath, backupPath);
|
|
@@ -898,9 +1290,8 @@ program
|
|
|
898
1290
|
|
|
899
1291
|
// Display final results
|
|
900
1292
|
updateManager.displayUpdateResults(results, backupDir, newVersion);
|
|
901
|
-
|
|
902
1293
|
} catch (error) {
|
|
903
|
-
console.error(chalk.red(
|
|
1294
|
+
console.error(chalk.red("\n❌ Update failed:"));
|
|
904
1295
|
console.error(error.message);
|
|
905
1296
|
if (options.verbose) {
|
|
906
1297
|
console.error(error);
|
|
@@ -910,49 +1301,52 @@ program
|
|
|
910
1301
|
});
|
|
911
1302
|
|
|
912
1303
|
program
|
|
913
|
-
.command(
|
|
914
|
-
.description(
|
|
915
|
-
.option(
|
|
916
|
-
.option(
|
|
917
|
-
.option(
|
|
918
|
-
.option(
|
|
1304
|
+
.command("claudeweb")
|
|
1305
|
+
.description("Start MyAIDev Method Web UI with Claude Code Viewer")
|
|
1306
|
+
.option("-p, --port <port>", "Port to run server on", "3400")
|
|
1307
|
+
.option("--single-user", "Run in single-user mode")
|
|
1308
|
+
.option("--multi-user", "Run in multi-user mode")
|
|
1309
|
+
.option("--db-path <path>", "SQLite database path")
|
|
919
1310
|
.action(async (options) => {
|
|
920
1311
|
console.log(getASCIIBanner());
|
|
921
|
-
console.log(chalk.blue(
|
|
1312
|
+
console.log(chalk.blue("\n🌐 Starting MyAIDev Method Web UI...\n"));
|
|
922
1313
|
|
|
923
1314
|
process.env.PORT = options.port;
|
|
924
1315
|
if (options.dbPath) {
|
|
925
1316
|
process.env.SQLITE_DB_PATH = options.dbPath;
|
|
926
1317
|
}
|
|
927
1318
|
if (options.singleUser) {
|
|
928
|
-
process.env.SINGLE_USER_MODE =
|
|
929
|
-
console.log(chalk.cyan(
|
|
1319
|
+
process.env.SINGLE_USER_MODE = "true";
|
|
1320
|
+
console.log(chalk.cyan("📌 Running in single-user mode"));
|
|
930
1321
|
}
|
|
931
1322
|
if (options.multiUser) {
|
|
932
|
-
process.env.MULTI_USER_MODE =
|
|
933
|
-
console.log(chalk.cyan(
|
|
1323
|
+
process.env.MULTI_USER_MODE = "true";
|
|
1324
|
+
console.log(chalk.cyan("📌 Running in multi-user mode"));
|
|
934
1325
|
}
|
|
935
1326
|
|
|
936
1327
|
try {
|
|
937
|
-
const serverModule = await import(
|
|
938
|
-
console.log(chalk.green(
|
|
1328
|
+
const serverModule = await import("../dist/server/main.js");
|
|
1329
|
+
console.log(chalk.green("\n✅ Server module loaded successfully"));
|
|
939
1330
|
} catch (error) {
|
|
940
|
-
console.error(chalk.red(
|
|
1331
|
+
console.error(chalk.red("\n❌ Failed to start server:"));
|
|
941
1332
|
console.error(error);
|
|
942
|
-
console.log(
|
|
943
|
-
|
|
1333
|
+
console.log(
|
|
1334
|
+
chalk.yellow("\n💡 Make sure you have built the server first:"),
|
|
1335
|
+
);
|
|
1336
|
+
console.log(chalk.gray(" npm run build:server"));
|
|
944
1337
|
process.exit(1);
|
|
945
1338
|
}
|
|
946
1339
|
});
|
|
947
1340
|
|
|
948
1341
|
// Installation detection command (Plugin Architecture Support)
|
|
949
1342
|
program
|
|
950
|
-
.command(
|
|
951
|
-
.description(
|
|
952
|
-
.option(
|
|
1343
|
+
.command("detect")
|
|
1344
|
+
.description("Detect MyAIDev Method installation state (legacy vs plugin)")
|
|
1345
|
+
.option("--json", "Output as JSON")
|
|
953
1346
|
.action(async (options) => {
|
|
954
1347
|
try {
|
|
955
|
-
const { detectInstallation, getInstallationStatus } =
|
|
1348
|
+
const { detectInstallation, getInstallationStatus } =
|
|
1349
|
+
await import("../src/lib/installation-detector.js");
|
|
956
1350
|
|
|
957
1351
|
if (options.json) {
|
|
958
1352
|
const detection = await detectInstallation(process.cwd());
|
|
@@ -962,137 +1356,162 @@ program
|
|
|
962
1356
|
console.log(status);
|
|
963
1357
|
}
|
|
964
1358
|
} catch (error) {
|
|
965
|
-
console.error(chalk.red(
|
|
1359
|
+
console.error(chalk.red("Failed to detect installation:"), error.message);
|
|
966
1360
|
process.exit(1);
|
|
967
1361
|
}
|
|
968
1362
|
});
|
|
969
1363
|
|
|
970
1364
|
// Plugin information command
|
|
971
1365
|
program
|
|
972
|
-
.command(
|
|
973
|
-
.description(
|
|
1366
|
+
.command("plugin-info")
|
|
1367
|
+
.description("Show plugin architecture information and capabilities")
|
|
974
1368
|
.action(async () => {
|
|
975
|
-
console.log(chalk.cyan(
|
|
976
|
-
console.log(
|
|
977
|
-
|
|
978
|
-
|
|
979
|
-
|
|
980
|
-
|
|
981
|
-
|
|
982
|
-
console.log(chalk.yellow(
|
|
983
|
-
console.log(
|
|
984
|
-
console.log(
|
|
985
|
-
|
|
986
|
-
console.log(chalk.yellow(
|
|
987
|
-
console.log(
|
|
988
|
-
console.log(
|
|
989
|
-
|
|
990
|
-
console.log(
|
|
991
|
-
console.log(
|
|
992
|
-
console.log(
|
|
993
|
-
console.log(
|
|
994
|
-
|
|
995
|
-
|
|
996
|
-
|
|
997
|
-
console.log(
|
|
998
|
-
console.log(
|
|
999
|
-
console.log(
|
|
1000
|
-
|
|
1001
|
-
|
|
1002
|
-
console.log(
|
|
1003
|
-
console.log(
|
|
1004
|
-
console.log(
|
|
1369
|
+
console.log(chalk.cyan("\n🔌 MyAIDev Method Plugin Architecture\n"));
|
|
1370
|
+
console.log(
|
|
1371
|
+
chalk.white(
|
|
1372
|
+
"════════════════════════════════════════════════════════════════\n",
|
|
1373
|
+
),
|
|
1374
|
+
);
|
|
1375
|
+
|
|
1376
|
+
console.log(chalk.yellow("📦 Installation Methods:\n"));
|
|
1377
|
+
console.log(" 1. Legacy (npx): npx myaidev-method init --claude");
|
|
1378
|
+
console.log(" 2. Plugin: /plugin install myaidev-method\n");
|
|
1379
|
+
|
|
1380
|
+
console.log(chalk.yellow("🎯 Command Formats:\n"));
|
|
1381
|
+
console.log(" Legacy: /content-writer, /myai-configure");
|
|
1382
|
+
console.log(" Namespaced: /myaidev-method:content-writer\n");
|
|
1383
|
+
|
|
1384
|
+
console.log(chalk.yellow("📚 Available Skill Packs:\n"));
|
|
1385
|
+
console.log(" • content - Content creation & WordPress publishing");
|
|
1386
|
+
console.log(" • visual - AI image/video generation");
|
|
1387
|
+
console.log(" • development - SPARC methodology for software dev");
|
|
1388
|
+
console.log(
|
|
1389
|
+
" • publishing - Multi-platform publishing (WP, Payload, Static)",
|
|
1390
|
+
);
|
|
1391
|
+
console.log(" • deployment - Coolify deployment automation");
|
|
1392
|
+
console.log(" • security - Security testing & auditing");
|
|
1393
|
+
console.log(" • openstack - OpenStack VM management\n");
|
|
1394
|
+
|
|
1395
|
+
console.log(chalk.yellow("📁 Plugin Structure:\n"));
|
|
1396
|
+
console.log(" .claude-plugin/plugin.json - Plugin manifest");
|
|
1397
|
+
console.log(" skills/ - SKILL.md files");
|
|
1398
|
+
console.log(" commands/ - Command definitions");
|
|
1399
|
+
console.log(" agents/ - Agent definitions");
|
|
1400
|
+
console.log(" hooks/hooks.json - Lifecycle hooks\n");
|
|
1401
|
+
|
|
1402
|
+
console.log(chalk.yellow("🔗 More Information:\n"));
|
|
1403
|
+
console.log(" Documentation: https://github.com/myaione/myaidev-method");
|
|
1404
|
+
console.log(
|
|
1405
|
+
" Plugin Catalog: https://myaidev.com/plugins/myaidev-method\n",
|
|
1406
|
+
);
|
|
1005
1407
|
});
|
|
1006
1408
|
|
|
1007
1409
|
// Upgrade command (legacy to plugin)
|
|
1008
1410
|
program
|
|
1009
|
-
.command(
|
|
1010
|
-
.description(
|
|
1011
|
-
.option(
|
|
1411
|
+
.command("upgrade")
|
|
1412
|
+
.description("Upgrade from legacy installation to plugin architecture")
|
|
1413
|
+
.option("--dry-run", "Show what would be upgraded without making changes")
|
|
1012
1414
|
.action(async (options) => {
|
|
1013
1415
|
try {
|
|
1014
|
-
const { detectInstallation, checkUpgradeAvailability } =
|
|
1416
|
+
const { detectInstallation, checkUpgradeAvailability } =
|
|
1417
|
+
await import("../src/lib/installation-detector.js");
|
|
1015
1418
|
const detection = await detectInstallation(process.cwd());
|
|
1016
1419
|
|
|
1017
|
-
console.log(chalk.cyan(
|
|
1420
|
+
console.log(chalk.cyan("\n🔄 MyAIDev Method Upgrade Check\n"));
|
|
1018
1421
|
|
|
1019
|
-
if (detection.installationType ===
|
|
1020
|
-
console.log(
|
|
1021
|
-
|
|
1422
|
+
if (detection.installationType === "none") {
|
|
1423
|
+
console.log(
|
|
1424
|
+
chalk.yellow("⚠️ No MyAIDev Method installation detected."),
|
|
1425
|
+
);
|
|
1426
|
+
console.log(
|
|
1427
|
+
chalk.gray(
|
|
1428
|
+
'\nRun "npx myaidev-method init --claude" to install first.\n',
|
|
1429
|
+
),
|
|
1430
|
+
);
|
|
1022
1431
|
return;
|
|
1023
1432
|
}
|
|
1024
1433
|
|
|
1025
|
-
if (
|
|
1026
|
-
|
|
1027
|
-
|
|
1434
|
+
if (
|
|
1435
|
+
detection.installationType === "plugin" ||
|
|
1436
|
+
detection.installationType === "both"
|
|
1437
|
+
) {
|
|
1438
|
+
console.log(chalk.green("✅ Plugin architecture already enabled."));
|
|
1439
|
+
console.log(chalk.gray("\nNo upgrade needed.\n"));
|
|
1028
1440
|
return;
|
|
1029
1441
|
}
|
|
1030
1442
|
|
|
1031
1443
|
const upgrade = await checkUpgradeAvailability(process.cwd());
|
|
1032
1444
|
|
|
1033
|
-
console.log(
|
|
1445
|
+
console.log(
|
|
1446
|
+
chalk.yellow("📋 Current Installation: Legacy (npx-based)\n"),
|
|
1447
|
+
);
|
|
1034
1448
|
|
|
1035
|
-
console.log(chalk.green(
|
|
1449
|
+
console.log(chalk.green("✨ Upgrade Benefits:"));
|
|
1036
1450
|
for (const benefit of upgrade.upgradeBenefits) {
|
|
1037
1451
|
console.log(` • ${benefit}`);
|
|
1038
1452
|
}
|
|
1039
1453
|
|
|
1040
|
-
console.log(chalk.blue(
|
|
1454
|
+
console.log(chalk.blue("\n🔒 Preserved Features:"));
|
|
1041
1455
|
for (const feature of upgrade.preservedFeatures) {
|
|
1042
1456
|
console.log(` • ${feature}`);
|
|
1043
1457
|
}
|
|
1044
1458
|
|
|
1045
1459
|
if (options.dryRun) {
|
|
1046
|
-
console.log(chalk.yellow(
|
|
1047
|
-
console.log(
|
|
1048
|
-
console.log(
|
|
1049
|
-
console.log(
|
|
1050
|
-
console.log(
|
|
1460
|
+
console.log(chalk.yellow("\n[DRY RUN] Would create:"));
|
|
1461
|
+
console.log(" • .claude-plugin/plugin.json");
|
|
1462
|
+
console.log(" • skills/ directory with SKILL.md files");
|
|
1463
|
+
console.log(" • hooks/hooks.json");
|
|
1464
|
+
console.log("\n[DRY RUN] No changes made.\n");
|
|
1051
1465
|
return;
|
|
1052
1466
|
}
|
|
1053
1467
|
|
|
1054
1468
|
// Prompt for confirmation
|
|
1055
1469
|
const answer = await inquirer.prompt([
|
|
1056
1470
|
{
|
|
1057
|
-
type:
|
|
1058
|
-
name:
|
|
1059
|
-
message:
|
|
1060
|
-
default: true
|
|
1061
|
-
}
|
|
1471
|
+
type: "confirm",
|
|
1472
|
+
name: "proceed",
|
|
1473
|
+
message: "Proceed with upgrade to plugin architecture?",
|
|
1474
|
+
default: true,
|
|
1475
|
+
},
|
|
1062
1476
|
]);
|
|
1063
1477
|
|
|
1064
1478
|
if (!answer.proceed) {
|
|
1065
|
-
console.log(chalk.gray(
|
|
1479
|
+
console.log(chalk.gray("\nUpgrade cancelled.\n"));
|
|
1066
1480
|
return;
|
|
1067
1481
|
}
|
|
1068
1482
|
|
|
1069
|
-
const spinner = ora(
|
|
1483
|
+
const spinner = ora("Upgrading to plugin architecture...").start();
|
|
1070
1484
|
|
|
1071
1485
|
// Copy plugin files from the package to the project
|
|
1072
1486
|
const packageRoot = path.dirname(__dirname);
|
|
1073
1487
|
|
|
1074
1488
|
// Create .claude-plugin directory
|
|
1075
|
-
await fs.ensureDir(path.join(process.cwd(),
|
|
1489
|
+
await fs.ensureDir(path.join(process.cwd(), ".claude-plugin"));
|
|
1076
1490
|
await fs.copy(
|
|
1077
|
-
path.join(packageRoot,
|
|
1078
|
-
path.join(process.cwd(),
|
|
1491
|
+
path.join(packageRoot, ".claude-plugin", "plugin.json"),
|
|
1492
|
+
path.join(process.cwd(), ".claude-plugin", "plugin.json"),
|
|
1079
1493
|
);
|
|
1080
1494
|
|
|
1081
1495
|
// Create hooks directory
|
|
1082
|
-
await fs.ensureDir(path.join(process.cwd(),
|
|
1496
|
+
await fs.ensureDir(path.join(process.cwd(), "hooks"));
|
|
1083
1497
|
await fs.copy(
|
|
1084
|
-
path.join(packageRoot,
|
|
1085
|
-
path.join(process.cwd(),
|
|
1498
|
+
path.join(packageRoot, "hooks", "hooks.json"),
|
|
1499
|
+
path.join(process.cwd(), "hooks", "hooks.json"),
|
|
1086
1500
|
);
|
|
1087
1501
|
|
|
1088
|
-
spinner.succeed(chalk.green(
|
|
1089
|
-
|
|
1090
|
-
console.log(chalk.cyan('\n✅ Plugin architecture enabled.'));
|
|
1091
|
-
console.log(chalk.gray(' Both /myai-* and /myaidev-method:* commands now available.'));
|
|
1092
|
-
console.log(chalk.yellow('\n🔄 Restart Claude Code to load new capabilities.\n'));
|
|
1502
|
+
spinner.succeed(chalk.green("Upgrade complete!"));
|
|
1093
1503
|
|
|
1504
|
+
console.log(chalk.cyan("\n✅ Plugin architecture enabled."));
|
|
1505
|
+
console.log(
|
|
1506
|
+
chalk.gray(
|
|
1507
|
+
" Both /myai-* and /myaidev-method:* commands now available.",
|
|
1508
|
+
),
|
|
1509
|
+
);
|
|
1510
|
+
console.log(
|
|
1511
|
+
chalk.yellow("\n🔄 Restart Claude Code to load new capabilities.\n"),
|
|
1512
|
+
);
|
|
1094
1513
|
} catch (error) {
|
|
1095
|
-
console.error(chalk.red(
|
|
1514
|
+
console.error(chalk.red("Failed to upgrade:"), error.message);
|
|
1096
1515
|
process.exit(1);
|
|
1097
1516
|
}
|
|
1098
1517
|
});
|
|
@@ -1101,4 +1520,4 @@ program
|
|
|
1101
1520
|
registerAuthCommands(program);
|
|
1102
1521
|
registerAddonCommand(program);
|
|
1103
1522
|
|
|
1104
|
-
program.parse(process.argv);
|
|
1523
|
+
program.parse(process.argv);
|