myaidev-method 0.3.4 → 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 +776 -422
- 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.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
|
-
|
|
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);
|
|
556
|
+
}
|
|
557
|
+
|
|
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}`;
|
|
415
598
|
}
|
|
416
|
-
|
|
417
|
-
spinner.succeed(chalk.green(`Successfully initialized ${cliType} configuration!`));
|
|
418
599
|
|
|
419
|
-
//
|
|
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,56 +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
|
-
|
|
720
|
+
|
|
490
721
|
// Create CLAUDE.md configuration file from template
|
|
491
|
-
const claudeMdTemplate = path.join(
|
|
722
|
+
const claudeMdTemplate = path.join(
|
|
723
|
+
__dirname,
|
|
724
|
+
"..",
|
|
725
|
+
"src",
|
|
726
|
+
"templates",
|
|
727
|
+
"claude",
|
|
728
|
+
"CLAUDE.md",
|
|
729
|
+
);
|
|
492
730
|
if (await fs.pathExists(claudeMdTemplate)) {
|
|
493
|
-
await fs.copy(claudeMdTemplate, path.join(claudeDir,
|
|
731
|
+
await fs.copy(claudeMdTemplate, path.join(claudeDir, "CLAUDE.md"));
|
|
494
732
|
}
|
|
495
|
-
|
|
733
|
+
|
|
496
734
|
// Copy the comprehensive .env.example from package
|
|
497
|
-
const sourceEnvExample = path.join(__dirname,
|
|
735
|
+
const sourceEnvExample = path.join(__dirname, "..", ".env.example");
|
|
498
736
|
if (await fs.pathExists(sourceEnvExample)) {
|
|
499
|
-
await fs.copy(sourceEnvExample, path.join(projectDir,
|
|
737
|
+
await fs.copy(sourceEnvExample, path.join(projectDir, ".env.example"));
|
|
500
738
|
}
|
|
501
739
|
|
|
502
740
|
// Create .myaidev-method directory for scripts and utilities
|
|
503
741
|
// 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,
|
|
742
|
+
const myaidevDir = path.join(projectDir, ".myaidev-method");
|
|
743
|
+
const scriptsDir = path.join(myaidevDir, "scripts");
|
|
744
|
+
const libDir = path.join(myaidevDir, "lib");
|
|
507
745
|
|
|
508
746
|
await fs.ensureDir(scriptsDir);
|
|
509
747
|
await fs.ensureDir(libDir);
|
|
510
748
|
|
|
511
749
|
// Copy all executable scripts
|
|
512
|
-
const sourceScriptsDir = path.join(__dirname,
|
|
750
|
+
const sourceScriptsDir = path.join(__dirname, "..", "src", "scripts");
|
|
513
751
|
if (await fs.pathExists(sourceScriptsDir)) {
|
|
514
752
|
const scriptFiles = await fs.readdir(sourceScriptsDir);
|
|
515
753
|
for (const file of scriptFiles) {
|
|
516
|
-
if (file.endsWith(
|
|
754
|
+
if (file.endsWith(".js") && file !== "init-project.js") {
|
|
755
|
+
// Skip init script
|
|
517
756
|
await fs.copy(
|
|
518
757
|
path.join(sourceScriptsDir, file),
|
|
519
|
-
path.join(scriptsDir, file)
|
|
758
|
+
path.join(scriptsDir, file),
|
|
520
759
|
);
|
|
521
760
|
}
|
|
522
761
|
}
|
|
523
762
|
}
|
|
524
763
|
|
|
525
764
|
// Copy all utility libraries
|
|
526
|
-
const sourceLibDir = path.join(__dirname,
|
|
765
|
+
const sourceLibDir = path.join(__dirname, "..", "src", "lib");
|
|
527
766
|
if (await fs.pathExists(sourceLibDir)) {
|
|
528
767
|
await fs.copy(sourceLibDir, libDir);
|
|
529
768
|
}
|
|
@@ -531,99 +770,121 @@ async function setupClaude(projectDir) {
|
|
|
531
770
|
// Copy package.json and install dependencies in .myaidev-method
|
|
532
771
|
// This ensures scripts have access to required npm packages
|
|
533
772
|
const packageJson = {
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
773
|
+
name: "myaidev-method-scripts",
|
|
774
|
+
version: "1.0.0",
|
|
775
|
+
type: "module",
|
|
776
|
+
private: true,
|
|
777
|
+
dependencies: {
|
|
539
778
|
"node-fetch": "^3.3.2",
|
|
540
|
-
|
|
779
|
+
marked: "^11.0.0",
|
|
541
780
|
"gray-matter": "^4.0.3",
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
}
|
|
781
|
+
dotenv: "^16.4.1",
|
|
782
|
+
chalk: "^5.3.0",
|
|
783
|
+
ora: "^8.0.1",
|
|
784
|
+
},
|
|
546
785
|
};
|
|
547
786
|
|
|
548
787
|
await fs.writeFile(
|
|
549
|
-
path.join(myaidevDir,
|
|
550
|
-
JSON.stringify(packageJson, null, 2)
|
|
788
|
+
path.join(myaidevDir, "package.json"),
|
|
789
|
+
JSON.stringify(packageJson, null, 2),
|
|
551
790
|
);
|
|
552
791
|
|
|
553
792
|
// Install dependencies in .myaidev-method directory
|
|
554
|
-
console.log(chalk.gray(
|
|
555
|
-
const { execSync } = await import(
|
|
793
|
+
console.log(chalk.gray("\n Installing script dependencies..."));
|
|
794
|
+
const { execSync } = await import("child_process");
|
|
556
795
|
try {
|
|
557
|
-
execSync(
|
|
796
|
+
execSync("npm install", {
|
|
558
797
|
cwd: myaidevDir,
|
|
559
|
-
stdio:
|
|
798
|
+
stdio: "inherit",
|
|
560
799
|
});
|
|
561
|
-
console.log(chalk.green(
|
|
800
|
+
console.log(chalk.green(" ✓ Dependencies installed successfully"));
|
|
562
801
|
} catch (error) {
|
|
563
|
-
console.log(
|
|
564
|
-
|
|
802
|
+
console.log(
|
|
803
|
+
chalk.yellow(" ⚠ Failed to install dependencies automatically"),
|
|
804
|
+
);
|
|
805
|
+
console.log(chalk.gray(" Run: cd .myaidev-method && npm install"));
|
|
565
806
|
}
|
|
566
807
|
|
|
567
|
-
// 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
|
|
568
810
|
|
|
569
811
|
// Copy documentation files to project root (limited to essential guides)
|
|
570
812
|
const docsToMerge = [
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
813
|
+
"USER_GUIDE.md",
|
|
814
|
+
"DEV_WORKFLOW_GUIDE.md",
|
|
815
|
+
"PUBLISHING_GUIDE.md",
|
|
574
816
|
];
|
|
575
817
|
|
|
576
818
|
for (const docFile of docsToMerge) {
|
|
577
|
-
const sourcePath = path.join(__dirname,
|
|
819
|
+
const sourcePath = path.join(__dirname, "..", docFile);
|
|
578
820
|
if (await fs.pathExists(sourcePath)) {
|
|
579
821
|
await fs.copy(sourcePath, path.join(projectDir, docFile));
|
|
580
822
|
}
|
|
581
823
|
}
|
|
582
824
|
|
|
583
825
|
// Copy template documentation (WordPress integration, etc.)
|
|
584
|
-
const templateDocsDir = path.join(
|
|
826
|
+
const templateDocsDir = path.join(
|
|
827
|
+
__dirname,
|
|
828
|
+
"..",
|
|
829
|
+
"src",
|
|
830
|
+
"templates",
|
|
831
|
+
"docs",
|
|
832
|
+
);
|
|
585
833
|
if (await fs.pathExists(templateDocsDir)) {
|
|
586
834
|
const docFiles = await fs.readdir(templateDocsDir);
|
|
587
835
|
for (const file of docFiles) {
|
|
588
|
-
if (file.endsWith(
|
|
836
|
+
if (file.endsWith(".md")) {
|
|
589
837
|
const destPath = path.join(projectDir, file);
|
|
590
838
|
// 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
|
-
);
|
|
839
|
+
if (!(await fs.pathExists(destPath))) {
|
|
840
|
+
await fs.copy(path.join(templateDocsDir, file), destPath);
|
|
596
841
|
}
|
|
597
842
|
}
|
|
598
843
|
}
|
|
599
844
|
}
|
|
600
845
|
|
|
601
846
|
// 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(
|
|
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
|
+
);
|
|
605
854
|
if (await fs.pathExists(contentRulesTemplate)) {
|
|
606
855
|
await fs.copy(contentRulesTemplate, contentRulesPath);
|
|
607
|
-
console.log(
|
|
856
|
+
console.log(
|
|
857
|
+
chalk.green(
|
|
858
|
+
" ✓ Created content-rules.md for customizable content generation",
|
|
859
|
+
),
|
|
860
|
+
);
|
|
608
861
|
}
|
|
609
862
|
} else {
|
|
610
|
-
console.log(
|
|
863
|
+
console.log(
|
|
864
|
+
chalk.gray(" ℹ content-rules.md already exists, skipping creation"),
|
|
865
|
+
);
|
|
611
866
|
}
|
|
612
867
|
|
|
613
868
|
// Save installation version for update tracking
|
|
614
|
-
const pkgJson = await fs.readJson(path.join(__dirname,
|
|
615
|
-
const versionFile = path.join(claudeDir,
|
|
869
|
+
const pkgJson = await fs.readJson(path.join(__dirname, "..", "package.json"));
|
|
870
|
+
const versionFile = path.join(claudeDir, ".myaidev-version");
|
|
616
871
|
await fs.writeFile(versionFile, pkgJson.version);
|
|
617
872
|
|
|
618
873
|
// Copy statusline script and configure settings.json
|
|
619
|
-
const statuslineSrc = path.join(
|
|
620
|
-
|
|
874
|
+
const statuslineSrc = path.join(
|
|
875
|
+
__dirname,
|
|
876
|
+
"..",
|
|
877
|
+
"src",
|
|
878
|
+
"statusline",
|
|
879
|
+
"statusline.sh",
|
|
880
|
+
);
|
|
881
|
+
const statuslineDest = path.join(claudeDir, "statusline.sh");
|
|
621
882
|
if (await fs.pathExists(statuslineSrc)) {
|
|
622
883
|
await fs.copy(statuslineSrc, statuslineDest);
|
|
623
884
|
await fs.chmod(statuslineDest, 0o755);
|
|
624
885
|
|
|
625
886
|
// Create or merge .claude/settings.json with statusLine config
|
|
626
|
-
const settingsPath = path.join(claudeDir,
|
|
887
|
+
const settingsPath = path.join(claudeDir, "settings.json");
|
|
627
888
|
let settings = {};
|
|
628
889
|
if (await fs.pathExists(settingsPath)) {
|
|
629
890
|
try {
|
|
@@ -633,35 +894,51 @@ async function setupClaude(projectDir) {
|
|
|
633
894
|
}
|
|
634
895
|
}
|
|
635
896
|
settings.statusLine = {
|
|
636
|
-
type:
|
|
637
|
-
command:
|
|
897
|
+
type: "command",
|
|
898
|
+
command: ".claude/statusline.sh",
|
|
638
899
|
};
|
|
639
900
|
settings.extraKnownMarketplaces = {
|
|
640
|
-
|
|
901
|
+
"myaidev-marketplace": {
|
|
641
902
|
source: {
|
|
642
|
-
source:
|
|
643
|
-
repo:
|
|
644
|
-
}
|
|
645
|
-
}
|
|
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
|
+
},
|
|
646
916
|
};
|
|
647
917
|
await fs.writeJson(settingsPath, settings, { spaces: 2 });
|
|
648
|
-
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
|
+
);
|
|
649
924
|
}
|
|
650
925
|
}
|
|
651
926
|
|
|
652
|
-
async function setupGemini(projectDir) {
|
|
927
|
+
async function setupGemini(projectDir, skillFilter = null) {
|
|
653
928
|
// Setup Gemini CLI — skills-based architecture
|
|
654
929
|
// Gemini CLI supports Agent Skills standard natively (.gemini/skills/)
|
|
655
|
-
const geminiDir = path.join(projectDir,
|
|
930
|
+
const geminiDir = path.join(projectDir, ".gemini");
|
|
656
931
|
await fs.ensureDir(geminiDir);
|
|
657
932
|
|
|
658
933
|
// Copy skills (same SKILL.md format works cross-platform)
|
|
659
|
-
const sourceSkillsDir = path.join(__dirname,
|
|
934
|
+
const sourceSkillsDir = path.join(__dirname, "..", "skills");
|
|
660
935
|
if (await fs.pathExists(sourceSkillsDir)) {
|
|
661
|
-
const skillsDir = path.join(geminiDir,
|
|
936
|
+
const skillsDir = path.join(geminiDir, "skills");
|
|
662
937
|
await fs.ensureDir(skillsDir);
|
|
663
938
|
const skillDirs = await fs.readdir(sourceSkillsDir);
|
|
939
|
+
const allowedSkills = skillFilter ? new Set(skillFilter) : null;
|
|
664
940
|
for (const skillName of skillDirs) {
|
|
941
|
+
if (allowedSkills && !allowedSkills.has(skillName)) continue;
|
|
665
942
|
const skillPath = path.join(sourceSkillsDir, skillName);
|
|
666
943
|
const stat = await fs.stat(skillPath);
|
|
667
944
|
if (stat.isDirectory()) {
|
|
@@ -685,7 +962,7 @@ Skills are discovered automatically. Gemini activates them when relevant to your
|
|
|
685
962
|
|
|
686
963
|
### Content & Publishing
|
|
687
964
|
- \`content-writer\` - SEO-optimized content creation
|
|
688
|
-
- \`
|
|
965
|
+
- \`content-publisher\` - Multi-platform publishing (WordPress, PayloadCMS, Astro, Docusaurus, Mintlify)
|
|
689
966
|
|
|
690
967
|
### DevOps
|
|
691
968
|
- \`deployer\` / \`coolify-deployer\` - Multi-environment deployment
|
|
@@ -704,22 +981,24 @@ Skills are discovered automatically. Gemini activates them when relevant to your
|
|
|
704
981
|
\`\`\`
|
|
705
982
|
`;
|
|
706
983
|
|
|
707
|
-
await fs.writeFile(path.join(geminiDir,
|
|
984
|
+
await fs.writeFile(path.join(geminiDir, "GEMINI.md"), geminiMd);
|
|
708
985
|
}
|
|
709
986
|
|
|
710
|
-
async function setupCodex(projectDir) {
|
|
987
|
+
async function setupCodex(projectDir, skillFilter = null) {
|
|
711
988
|
// Setup Codex/OpenCode — skills-based architecture
|
|
712
989
|
// Codex supports Agent Skills standard (experimental via experimental.skills)
|
|
713
|
-
const codexDir = path.join(projectDir,
|
|
990
|
+
const codexDir = path.join(projectDir, ".codex");
|
|
714
991
|
await fs.ensureDir(codexDir);
|
|
715
992
|
|
|
716
993
|
// Copy skills (same SKILL.md format works cross-platform)
|
|
717
|
-
const sourceSkillsDir = path.join(__dirname,
|
|
994
|
+
const sourceSkillsDir = path.join(__dirname, "..", "skills");
|
|
718
995
|
if (await fs.pathExists(sourceSkillsDir)) {
|
|
719
|
-
const skillsDir = path.join(codexDir,
|
|
996
|
+
const skillsDir = path.join(codexDir, "skills");
|
|
720
997
|
await fs.ensureDir(skillsDir);
|
|
721
998
|
const skillDirs = await fs.readdir(sourceSkillsDir);
|
|
999
|
+
const allowedSkills = skillFilter ? new Set(skillFilter) : null;
|
|
722
1000
|
for (const skillName of skillDirs) {
|
|
1001
|
+
if (allowedSkills && !allowedSkills.has(skillName)) continue;
|
|
723
1002
|
const skillPath = path.join(sourceSkillsDir, skillName);
|
|
724
1003
|
const stat = await fs.stat(skillPath);
|
|
725
1004
|
if (stat.isDirectory()) {
|
|
@@ -743,7 +1022,7 @@ Enable experimental skills support: \`experimental.skills = true\` in settings.
|
|
|
743
1022
|
|
|
744
1023
|
### Content & Publishing
|
|
745
1024
|
- \`content-writer\` - SEO-optimized content creation
|
|
746
|
-
- \`
|
|
1025
|
+
- \`content-publisher\` - Multi-platform publishing (WordPress, PayloadCMS, Astro, Docusaurus, Mintlify)
|
|
747
1026
|
|
|
748
1027
|
### DevOps
|
|
749
1028
|
- \`deployer\` / \`coolify-deployer\` - Multi-environment deployment
|
|
@@ -753,115 +1032,159 @@ Enable experimental skills support: \`experimental.skills = true\` in settings.
|
|
|
753
1032
|
- \`security-tester\` / \`security-auditor\`
|
|
754
1033
|
`;
|
|
755
1034
|
|
|
756
|
-
await fs.writeFile(path.join(codexDir,
|
|
1035
|
+
await fs.writeFile(path.join(codexDir, "AGENTS.md"), agentsMd);
|
|
757
1036
|
}
|
|
758
1037
|
|
|
759
1038
|
program
|
|
760
|
-
.command(
|
|
761
|
-
.description(
|
|
762
|
-
.option(
|
|
763
|
-
.option(
|
|
764
|
-
.option(
|
|
765
|
-
.option(
|
|
766
|
-
.option(
|
|
767
|
-
.option(
|
|
768
|
-
.option(
|
|
769
|
-
|
|
770
|
-
|
|
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
|
+
)
|
|
771
1056
|
.action(async (options) => {
|
|
772
|
-
const ora = (await import(
|
|
773
|
-
const { fileURLToPath } = await import(
|
|
774
|
-
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");
|
|
775
1060
|
|
|
776
1061
|
const __filename = fileURLToPath(import.meta.url);
|
|
777
1062
|
const __dirname = path.dirname(__filename);
|
|
778
|
-
const packageRoot = path.join(__dirname,
|
|
1063
|
+
const packageRoot = path.join(__dirname, "..");
|
|
779
1064
|
|
|
780
1065
|
try {
|
|
781
1066
|
const cwd = process.cwd();
|
|
782
1067
|
|
|
783
1068
|
// Display branding banner
|
|
784
1069
|
console.log(getASCIIBanner());
|
|
785
|
-
console.log(
|
|
1070
|
+
console.log(
|
|
1071
|
+
chalk.cyan.bold(" ⚡ Update Manager\n"),
|
|
1072
|
+
);
|
|
786
1073
|
|
|
787
1074
|
// Detect existing installation
|
|
788
|
-
const spinner = ora(
|
|
1075
|
+
const spinner = ora("Detecting MyAIDev Method installation...").start();
|
|
789
1076
|
const installation = await updateManager.detectExistingInstallation(cwd);
|
|
790
1077
|
|
|
791
1078
|
if (!installation) {
|
|
792
|
-
spinner.fail(
|
|
793
|
-
console.log(
|
|
1079
|
+
spinner.fail("No MyAIDev Method installation found");
|
|
1080
|
+
console.log(
|
|
1081
|
+
chalk.gray(" Run: npx myaidev-method@latest init --claude"),
|
|
1082
|
+
);
|
|
794
1083
|
process.exit(1);
|
|
795
1084
|
}
|
|
796
1085
|
|
|
797
|
-
spinner.succeed(
|
|
1086
|
+
spinner.succeed(
|
|
1087
|
+
`Found ${installation.type} installation (v${installation.currentVersion})`,
|
|
1088
|
+
);
|
|
798
1089
|
|
|
799
1090
|
// Get package version
|
|
800
|
-
const packageJson = await fs.readJson(
|
|
1091
|
+
const packageJson = await fs.readJson(
|
|
1092
|
+
path.join(packageRoot, "package.json"),
|
|
1093
|
+
);
|
|
801
1094
|
const newVersion = packageJson.version;
|
|
802
1095
|
|
|
803
1096
|
// Check if already up to date
|
|
804
1097
|
if (installation.currentVersion === newVersion && !options.force) {
|
|
805
|
-
console.log(chalk.green(
|
|
1098
|
+
console.log(chalk.green("\n✅ Already up to date!\n"));
|
|
806
1099
|
process.exit(0);
|
|
807
1100
|
}
|
|
808
1101
|
|
|
809
1102
|
// Generate change summary
|
|
810
|
-
const summarySpinner = ora(
|
|
811
|
-
const components = [
|
|
1103
|
+
const summarySpinner = ora("Analyzing changes...").start();
|
|
1104
|
+
const components = ["skills", "scripts", "lib", "mcp", "config", "docs"];
|
|
812
1105
|
const summary = await updateManager.generateChangeSummary(
|
|
813
|
-
components,
|
|
1106
|
+
components,
|
|
1107
|
+
cwd,
|
|
1108
|
+
installation.type,
|
|
1109
|
+
packageRoot,
|
|
814
1110
|
);
|
|
815
|
-
summarySpinner.succeed(
|
|
1111
|
+
summarySpinner.succeed("Change analysis complete");
|
|
816
1112
|
|
|
817
1113
|
// Display summary dashboard
|
|
818
|
-
console.log(
|
|
819
|
-
updateManager.displayChangeSummary(
|
|
1114
|
+
console.log("");
|
|
1115
|
+
updateManager.displayChangeSummary(
|
|
1116
|
+
summary,
|
|
1117
|
+
installation.currentVersion,
|
|
1118
|
+
newVersion,
|
|
1119
|
+
);
|
|
820
1120
|
|
|
821
1121
|
// Dry run mode - just show summary and exit
|
|
822
1122
|
if (options.dryRun) {
|
|
823
|
-
console.log(chalk.yellow(
|
|
824
|
-
console.log(chalk.gray(
|
|
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"));
|
|
825
1125
|
process.exit(0);
|
|
826
1126
|
}
|
|
827
1127
|
|
|
828
1128
|
// Determine strategy (CLI flag or prompt)
|
|
829
1129
|
let strategy;
|
|
830
1130
|
if (options.smart) {
|
|
831
|
-
strategy =
|
|
832
|
-
console.log(
|
|
1131
|
+
strategy = "smart";
|
|
1132
|
+
console.log(
|
|
1133
|
+
chalk.cyan("\n🚀 Using Smart Update strategy (--smart flag)\n"),
|
|
1134
|
+
);
|
|
833
1135
|
} else if (options.acceptAll) {
|
|
834
|
-
strategy =
|
|
835
|
-
console.log(
|
|
1136
|
+
strategy = "accept-all";
|
|
1137
|
+
console.log(
|
|
1138
|
+
chalk.cyan("\n📥 Using Accept All strategy (--accept-all flag)\n"),
|
|
1139
|
+
);
|
|
836
1140
|
} else if (options.keepMine) {
|
|
837
|
-
strategy =
|
|
838
|
-
console.log(
|
|
1141
|
+
strategy = "keep-all";
|
|
1142
|
+
console.log(
|
|
1143
|
+
chalk.cyan("\n🛡️ Using Keep All strategy (--keep-mine flag)\n"),
|
|
1144
|
+
);
|
|
839
1145
|
} else if (options.force) {
|
|
840
|
-
strategy =
|
|
841
|
-
console.log(
|
|
1146
|
+
strategy = "accept-all";
|
|
1147
|
+
console.log(
|
|
1148
|
+
chalk.cyan("\n📥 Using Accept All strategy (--force flag)\n"),
|
|
1149
|
+
);
|
|
842
1150
|
} else {
|
|
843
1151
|
strategy = await updateManager.promptUpdateStrategy(summary);
|
|
844
1152
|
}
|
|
845
1153
|
|
|
846
1154
|
// Create timestamped backup directory
|
|
847
|
-
const backupDir = await updateManager.createTimestampedBackup(
|
|
1155
|
+
const backupDir = await updateManager.createTimestampedBackup(
|
|
1156
|
+
cwd,
|
|
1157
|
+
installation.type,
|
|
1158
|
+
);
|
|
848
1159
|
|
|
849
1160
|
// Execute selected strategy
|
|
850
1161
|
let results;
|
|
851
|
-
console.log(chalk.cyan(
|
|
1162
|
+
console.log(chalk.cyan("\n📦 Applying updates...\n"));
|
|
852
1163
|
|
|
853
|
-
if (strategy ===
|
|
1164
|
+
if (strategy === "auto" || summary.modified.length === 0) {
|
|
854
1165
|
// 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
|
-
|
|
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") {
|
|
865
1188
|
// Fall back to old file-by-file for this mode
|
|
866
1189
|
results = { updated: [], kept: [], added: [], backedUp: [] };
|
|
867
1190
|
for (const f of summary.new) {
|
|
@@ -873,11 +1196,15 @@ program
|
|
|
873
1196
|
}
|
|
874
1197
|
}
|
|
875
1198
|
for (const f of summary.modified) {
|
|
876
|
-
const action = await updateManager.promptForConflict(
|
|
877
|
-
|
|
1199
|
+
const action = await updateManager.promptForConflict(
|
|
1200
|
+
f.file,
|
|
1201
|
+
f.targetPath,
|
|
1202
|
+
f.sourcePath,
|
|
1203
|
+
);
|
|
1204
|
+
if (action === "replace") {
|
|
878
1205
|
await fs.copy(f.sourcePath, f.targetPath);
|
|
879
1206
|
results.updated.push(f.file);
|
|
880
|
-
} else if (action ===
|
|
1207
|
+
} else if (action === "backup") {
|
|
881
1208
|
const backupPath = path.join(backupDir, f.componentType, f.file);
|
|
882
1209
|
await fs.ensureDir(path.dirname(backupPath));
|
|
883
1210
|
await fs.copy(f.targetPath, backupPath);
|
|
@@ -898,9 +1225,8 @@ program
|
|
|
898
1225
|
|
|
899
1226
|
// Display final results
|
|
900
1227
|
updateManager.displayUpdateResults(results, backupDir, newVersion);
|
|
901
|
-
|
|
902
1228
|
} catch (error) {
|
|
903
|
-
console.error(chalk.red(
|
|
1229
|
+
console.error(chalk.red("\n❌ Update failed:"));
|
|
904
1230
|
console.error(error.message);
|
|
905
1231
|
if (options.verbose) {
|
|
906
1232
|
console.error(error);
|
|
@@ -910,49 +1236,52 @@ program
|
|
|
910
1236
|
});
|
|
911
1237
|
|
|
912
1238
|
program
|
|
913
|
-
.command(
|
|
914
|
-
.description(
|
|
915
|
-
.option(
|
|
916
|
-
.option(
|
|
917
|
-
.option(
|
|
918
|
-
.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")
|
|
919
1245
|
.action(async (options) => {
|
|
920
1246
|
console.log(getASCIIBanner());
|
|
921
|
-
console.log(chalk.blue(
|
|
1247
|
+
console.log(chalk.blue("\n🌐 Starting MyAIDev Method Web UI...\n"));
|
|
922
1248
|
|
|
923
1249
|
process.env.PORT = options.port;
|
|
924
1250
|
if (options.dbPath) {
|
|
925
1251
|
process.env.SQLITE_DB_PATH = options.dbPath;
|
|
926
1252
|
}
|
|
927
1253
|
if (options.singleUser) {
|
|
928
|
-
process.env.SINGLE_USER_MODE =
|
|
929
|
-
console.log(chalk.cyan(
|
|
1254
|
+
process.env.SINGLE_USER_MODE = "true";
|
|
1255
|
+
console.log(chalk.cyan("📌 Running in single-user mode"));
|
|
930
1256
|
}
|
|
931
1257
|
if (options.multiUser) {
|
|
932
|
-
process.env.MULTI_USER_MODE =
|
|
933
|
-
console.log(chalk.cyan(
|
|
1258
|
+
process.env.MULTI_USER_MODE = "true";
|
|
1259
|
+
console.log(chalk.cyan("📌 Running in multi-user mode"));
|
|
934
1260
|
}
|
|
935
1261
|
|
|
936
1262
|
try {
|
|
937
|
-
const serverModule = await import(
|
|
938
|
-
console.log(chalk.green(
|
|
1263
|
+
const serverModule = await import("../dist/server/main.js");
|
|
1264
|
+
console.log(chalk.green("\n✅ Server module loaded successfully"));
|
|
939
1265
|
} catch (error) {
|
|
940
|
-
console.error(chalk.red(
|
|
1266
|
+
console.error(chalk.red("\n❌ Failed to start server:"));
|
|
941
1267
|
console.error(error);
|
|
942
|
-
console.log(
|
|
943
|
-
|
|
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"));
|
|
944
1272
|
process.exit(1);
|
|
945
1273
|
}
|
|
946
1274
|
});
|
|
947
1275
|
|
|
948
1276
|
// Installation detection command (Plugin Architecture Support)
|
|
949
1277
|
program
|
|
950
|
-
.command(
|
|
951
|
-
.description(
|
|
952
|
-
.option(
|
|
1278
|
+
.command("detect")
|
|
1279
|
+
.description("Detect MyAIDev Method installation state (legacy vs plugin)")
|
|
1280
|
+
.option("--json", "Output as JSON")
|
|
953
1281
|
.action(async (options) => {
|
|
954
1282
|
try {
|
|
955
|
-
const { detectInstallation, getInstallationStatus } =
|
|
1283
|
+
const { detectInstallation, getInstallationStatus } =
|
|
1284
|
+
await import("../src/lib/installation-detector.js");
|
|
956
1285
|
|
|
957
1286
|
if (options.json) {
|
|
958
1287
|
const detection = await detectInstallation(process.cwd());
|
|
@@ -962,137 +1291,162 @@ program
|
|
|
962
1291
|
console.log(status);
|
|
963
1292
|
}
|
|
964
1293
|
} catch (error) {
|
|
965
|
-
console.error(chalk.red(
|
|
1294
|
+
console.error(chalk.red("Failed to detect installation:"), error.message);
|
|
966
1295
|
process.exit(1);
|
|
967
1296
|
}
|
|
968
1297
|
});
|
|
969
1298
|
|
|
970
1299
|
// Plugin information command
|
|
971
1300
|
program
|
|
972
|
-
.command(
|
|
973
|
-
.description(
|
|
1301
|
+
.command("plugin-info")
|
|
1302
|
+
.description("Show plugin architecture information and capabilities")
|
|
974
1303
|
.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(
|
|
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
|
+
);
|
|
1005
1342
|
});
|
|
1006
1343
|
|
|
1007
1344
|
// Upgrade command (legacy to plugin)
|
|
1008
1345
|
program
|
|
1009
|
-
.command(
|
|
1010
|
-
.description(
|
|
1011
|
-
.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")
|
|
1012
1349
|
.action(async (options) => {
|
|
1013
1350
|
try {
|
|
1014
|
-
const { detectInstallation, checkUpgradeAvailability } =
|
|
1351
|
+
const { detectInstallation, checkUpgradeAvailability } =
|
|
1352
|
+
await import("../src/lib/installation-detector.js");
|
|
1015
1353
|
const detection = await detectInstallation(process.cwd());
|
|
1016
1354
|
|
|
1017
|
-
console.log(chalk.cyan(
|
|
1355
|
+
console.log(chalk.cyan("\n🔄 MyAIDev Method Upgrade Check\n"));
|
|
1018
1356
|
|
|
1019
|
-
if (detection.installationType ===
|
|
1020
|
-
console.log(
|
|
1021
|
-
|
|
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
|
+
);
|
|
1022
1366
|
return;
|
|
1023
1367
|
}
|
|
1024
1368
|
|
|
1025
|
-
if (
|
|
1026
|
-
|
|
1027
|
-
|
|
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"));
|
|
1028
1375
|
return;
|
|
1029
1376
|
}
|
|
1030
1377
|
|
|
1031
1378
|
const upgrade = await checkUpgradeAvailability(process.cwd());
|
|
1032
1379
|
|
|
1033
|
-
console.log(
|
|
1380
|
+
console.log(
|
|
1381
|
+
chalk.yellow("📋 Current Installation: Legacy (npx-based)\n"),
|
|
1382
|
+
);
|
|
1034
1383
|
|
|
1035
|
-
console.log(chalk.green(
|
|
1384
|
+
console.log(chalk.green("✨ Upgrade Benefits:"));
|
|
1036
1385
|
for (const benefit of upgrade.upgradeBenefits) {
|
|
1037
1386
|
console.log(` • ${benefit}`);
|
|
1038
1387
|
}
|
|
1039
1388
|
|
|
1040
|
-
console.log(chalk.blue(
|
|
1389
|
+
console.log(chalk.blue("\n🔒 Preserved Features:"));
|
|
1041
1390
|
for (const feature of upgrade.preservedFeatures) {
|
|
1042
1391
|
console.log(` • ${feature}`);
|
|
1043
1392
|
}
|
|
1044
1393
|
|
|
1045
1394
|
if (options.dryRun) {
|
|
1046
|
-
console.log(chalk.yellow(
|
|
1047
|
-
console.log(
|
|
1048
|
-
console.log(
|
|
1049
|
-
console.log(
|
|
1050
|
-
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");
|
|
1051
1400
|
return;
|
|
1052
1401
|
}
|
|
1053
1402
|
|
|
1054
1403
|
// Prompt for confirmation
|
|
1055
1404
|
const answer = await inquirer.prompt([
|
|
1056
1405
|
{
|
|
1057
|
-
type:
|
|
1058
|
-
name:
|
|
1059
|
-
message:
|
|
1060
|
-
default: true
|
|
1061
|
-
}
|
|
1406
|
+
type: "confirm",
|
|
1407
|
+
name: "proceed",
|
|
1408
|
+
message: "Proceed with upgrade to plugin architecture?",
|
|
1409
|
+
default: true,
|
|
1410
|
+
},
|
|
1062
1411
|
]);
|
|
1063
1412
|
|
|
1064
1413
|
if (!answer.proceed) {
|
|
1065
|
-
console.log(chalk.gray(
|
|
1414
|
+
console.log(chalk.gray("\nUpgrade cancelled.\n"));
|
|
1066
1415
|
return;
|
|
1067
1416
|
}
|
|
1068
1417
|
|
|
1069
|
-
const spinner = ora(
|
|
1418
|
+
const spinner = ora("Upgrading to plugin architecture...").start();
|
|
1070
1419
|
|
|
1071
1420
|
// Copy plugin files from the package to the project
|
|
1072
1421
|
const packageRoot = path.dirname(__dirname);
|
|
1073
1422
|
|
|
1074
1423
|
// Create .claude-plugin directory
|
|
1075
|
-
await fs.ensureDir(path.join(process.cwd(),
|
|
1424
|
+
await fs.ensureDir(path.join(process.cwd(), ".claude-plugin"));
|
|
1076
1425
|
await fs.copy(
|
|
1077
|
-
path.join(packageRoot,
|
|
1078
|
-
path.join(process.cwd(),
|
|
1426
|
+
path.join(packageRoot, ".claude-plugin", "plugin.json"),
|
|
1427
|
+
path.join(process.cwd(), ".claude-plugin", "plugin.json"),
|
|
1079
1428
|
);
|
|
1080
1429
|
|
|
1081
1430
|
// Create hooks directory
|
|
1082
|
-
await fs.ensureDir(path.join(process.cwd(),
|
|
1431
|
+
await fs.ensureDir(path.join(process.cwd(), "hooks"));
|
|
1083
1432
|
await fs.copy(
|
|
1084
|
-
path.join(packageRoot,
|
|
1085
|
-
path.join(process.cwd(),
|
|
1433
|
+
path.join(packageRoot, "hooks", "hooks.json"),
|
|
1434
|
+
path.join(process.cwd(), "hooks", "hooks.json"),
|
|
1086
1435
|
);
|
|
1087
1436
|
|
|
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'));
|
|
1437
|
+
spinner.succeed(chalk.green("Upgrade complete!"));
|
|
1093
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
|
+
);
|
|
1094
1448
|
} catch (error) {
|
|
1095
|
-
console.error(chalk.red(
|
|
1449
|
+
console.error(chalk.red("Failed to upgrade:"), error.message);
|
|
1096
1450
|
process.exit(1);
|
|
1097
1451
|
}
|
|
1098
1452
|
});
|
|
@@ -1101,4 +1455,4 @@ program
|
|
|
1101
1455
|
registerAuthCommands(program);
|
|
1102
1456
|
registerAddonCommand(program);
|
|
1103
1457
|
|
|
1104
|
-
program.parse(process.argv);
|
|
1458
|
+
program.parse(process.argv);
|