myaidev-method 0.2.11 → 0.2.12
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/CHANGELOG.md +164 -0
- package/README.md +25 -0
- package/USER_GUIDE.md +156 -0
- package/bin/cli.js +176 -0
- package/package.json +3 -2
- package/src/lib/update-manager.js +385 -0
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to the MyAIDev Method package will be documented in this file.
|
|
4
|
+
|
|
5
|
+
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
|
6
|
+
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
|
+
|
|
8
|
+
## [0.2.12] - 2025-11-10
|
|
9
|
+
|
|
10
|
+
### Added
|
|
11
|
+
- **Update Command**: `npx myaidev-method@latest update` for intelligent component updates
|
|
12
|
+
- Interactive conflict resolution for modified files
|
|
13
|
+
- Automatic backup creation before updates
|
|
14
|
+
- Dry-run mode to preview changes
|
|
15
|
+
- Force mode for clean updates
|
|
16
|
+
- Version tracking with `.claude/.myaidev-version`
|
|
17
|
+
- Updates all components: commands, agents, scripts, libs, docs, MCP configs
|
|
18
|
+
- Comprehensive update documentation in USER_GUIDE.md
|
|
19
|
+
- Update instructions in README.md
|
|
20
|
+
- CHANGELOG.md for version history tracking
|
|
21
|
+
|
|
22
|
+
### Changed
|
|
23
|
+
- Init command now saves installation version for update tracking
|
|
24
|
+
- Enhanced documentation with update best practices
|
|
25
|
+
|
|
26
|
+
## [0.2.11] - 2025-11-10
|
|
27
|
+
|
|
28
|
+
### Fixed
|
|
29
|
+
- Script installation for non-Node.js projects
|
|
30
|
+
- Scripts now installed to `.myaidev-method/` with self-contained dependencies
|
|
31
|
+
- No longer requires Node.js project structure (package.json in root)
|
|
32
|
+
- Works in any project type (WordPress themes, Hugo sites, plain folders)
|
|
33
|
+
- Agent documentation updated to reference `.myaidev-method/` paths
|
|
34
|
+
|
|
35
|
+
### Changed
|
|
36
|
+
- Scripts copied to `.myaidev-method/scripts/` directory
|
|
37
|
+
- Libraries copied to `.myaidev-method/lib/` directory
|
|
38
|
+
- Dependencies installed locally in `.myaidev-method/node_modules/`
|
|
39
|
+
- Added `.gitignore` guidance in CLAUDE.md template
|
|
40
|
+
|
|
41
|
+
## [0.2.10] - 2025-11-06
|
|
42
|
+
|
|
43
|
+
### Changed
|
|
44
|
+
- ⚠️ **Deprecated approach**: Attempted node_modules path (reverted in v0.2.11)
|
|
45
|
+
|
|
46
|
+
## [0.2.9] - 2025-11-06
|
|
47
|
+
|
|
48
|
+
### Added
|
|
49
|
+
- User Pathways section in USER_GUIDE.md
|
|
50
|
+
- Content Creator pathway with complete publishing pipeline
|
|
51
|
+
- Developer pathway with SPARC methodology guidance
|
|
52
|
+
- End-to-end workflow examples
|
|
53
|
+
|
|
54
|
+
### Changed
|
|
55
|
+
- Enhanced documentation structure
|
|
56
|
+
- Improved onboarding experience
|
|
57
|
+
|
|
58
|
+
## [0.2.8] - 2025-11-06
|
|
59
|
+
|
|
60
|
+
### Changed
|
|
61
|
+
- Package documentation distribution updates
|
|
62
|
+
- Fixed package.json files array
|
|
63
|
+
|
|
64
|
+
## [0.2.7] - 2025-11-06
|
|
65
|
+
|
|
66
|
+
### Added
|
|
67
|
+
- Comprehensive content creation pipeline examples
|
|
68
|
+
- Multi-platform publishing workflows
|
|
69
|
+
|
|
70
|
+
## [0.2.6] - 2025-11-05
|
|
71
|
+
|
|
72
|
+
### Changed
|
|
73
|
+
- Documentation updates and improvements
|
|
74
|
+
|
|
75
|
+
## [0.2.5] - 2025-11-04
|
|
76
|
+
|
|
77
|
+
### Added
|
|
78
|
+
- PayloadCMS authentication simplification
|
|
79
|
+
- JWT-based authentication for PayloadCMS
|
|
80
|
+
- Improved publishing workflows
|
|
81
|
+
|
|
82
|
+
## [0.2.4] - 2025-11-03
|
|
83
|
+
|
|
84
|
+
### Added
|
|
85
|
+
- Slash command fixes and improvements
|
|
86
|
+
- 14 command updates with proper Task tool invocations
|
|
87
|
+
|
|
88
|
+
## [0.2.3] - 2025-11-02
|
|
89
|
+
|
|
90
|
+
### Added
|
|
91
|
+
- Enhanced MCP server integration
|
|
92
|
+
- SPARC orchestrator improvements
|
|
93
|
+
|
|
94
|
+
## [0.2.2] - 2025-11-01
|
|
95
|
+
|
|
96
|
+
### Added
|
|
97
|
+
- WordPress admin utilities
|
|
98
|
+
- Security scanning scripts
|
|
99
|
+
- Performance checking tools
|
|
100
|
+
|
|
101
|
+
## [0.2.1] - 2025-10-31
|
|
102
|
+
|
|
103
|
+
### Added
|
|
104
|
+
- Coolify deployment integration
|
|
105
|
+
- Multi-platform publishing support
|
|
106
|
+
|
|
107
|
+
## [0.2.0] - 2025-10-30
|
|
108
|
+
|
|
109
|
+
### Added
|
|
110
|
+
- SPARC methodology implementation
|
|
111
|
+
- Development workflow agents
|
|
112
|
+
- Git & CI/CD workflows
|
|
113
|
+
|
|
114
|
+
## [0.1.0] - 2025-10-29
|
|
115
|
+
|
|
116
|
+
### Added
|
|
117
|
+
- Initial release
|
|
118
|
+
- Content writer agent
|
|
119
|
+
- WordPress publishing integration
|
|
120
|
+
- Basic slash commands
|
|
121
|
+
- MCP server foundation
|
|
122
|
+
|
|
123
|
+
---
|
|
124
|
+
|
|
125
|
+
## Release Notes
|
|
126
|
+
|
|
127
|
+
### Version 0.2.12 Highlights
|
|
128
|
+
|
|
129
|
+
**Major Feature: Update Command**
|
|
130
|
+
|
|
131
|
+
The highlight of this release is the new intelligent update system. Users can now easily keep their MyAIDev Method installation current while preserving customizations:
|
|
132
|
+
|
|
133
|
+
```bash
|
|
134
|
+
npx myaidev-method@latest update --claude
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
Key features:
|
|
138
|
+
- Interactive conflict resolution - choose what to update
|
|
139
|
+
- Automatic backups - safe rollback if needed
|
|
140
|
+
- Dry-run mode - preview changes first
|
|
141
|
+
- Version tracking - know what version you're running
|
|
142
|
+
|
|
143
|
+
This solves a major pain point where users had to manually track updates or risk losing customizations by re-running init.
|
|
144
|
+
|
|
145
|
+
### Migration Guide
|
|
146
|
+
|
|
147
|
+
**From v0.2.10 or earlier to v0.2.12**:
|
|
148
|
+
|
|
149
|
+
1. Your scripts are now in `.myaidev-method/` instead of `node_modules/`
|
|
150
|
+
2. If you have any custom scripts referencing the old path, update them
|
|
151
|
+
3. Add `.myaidev-method/node_modules/` to your `.gitignore`
|
|
152
|
+
4. Use the new update command going forward instead of re-running init
|
|
153
|
+
|
|
154
|
+
**Checking Your Version**:
|
|
155
|
+
```bash
|
|
156
|
+
cat .claude/.myaidev-version
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
**First-Time Update Setup**:
|
|
160
|
+
If you installed before v0.2.12, the version file won't exist. The update command will still work, but it won't know your current version. Consider it an upgrade from "unknown" to v0.2.12.
|
|
161
|
+
|
|
162
|
+
---
|
|
163
|
+
|
|
164
|
+
For more details on any release, see the [commit history](https://github.com/myaione/myaidev-method/commits/master) or [release notes](https://github.com/myaione/myaidev-method/releases).
|
package/README.md
CHANGED
|
@@ -29,6 +29,7 @@ The **MyAIDev Method** is a complete development framework for AI CLI tools (Cla
|
|
|
29
29
|
- [Features](#features)
|
|
30
30
|
- [Installation](#installation)
|
|
31
31
|
- [Quick Start](#quick-start)
|
|
32
|
+
- [Updating](#updating)
|
|
32
33
|
- [SPARC Development Workflow](#sparc-development-workflow)
|
|
33
34
|
- [Development Agents](#development-agents)
|
|
34
35
|
- [Content & Publishing Agents](#content--publishing-agents)
|
|
@@ -134,6 +135,30 @@ npx myaidev-method@latest init
|
|
|
134
135
|
/myai-wordpress-admin health-check
|
|
135
136
|
```
|
|
136
137
|
|
|
138
|
+
## 🔄 Updating
|
|
139
|
+
|
|
140
|
+
Keep your MyAIDev Method installation up to date with the latest features and bug fixes:
|
|
141
|
+
|
|
142
|
+
```bash
|
|
143
|
+
# Interactive update (recommended) - prompts for conflicts
|
|
144
|
+
npx myaidev-method@latest update --claude
|
|
145
|
+
|
|
146
|
+
# Force update - overwrites all files
|
|
147
|
+
npx myaidev-method@latest update --claude --force
|
|
148
|
+
|
|
149
|
+
# Preview changes without updating
|
|
150
|
+
npx myaidev-method@latest update --claude --dry-run
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
The update command:
|
|
154
|
+
- ✅ Detects your current version
|
|
155
|
+
- ✅ Updates commands, agents, scripts, and documentation
|
|
156
|
+
- ✅ Preserves your customizations (interactive conflict resolution)
|
|
157
|
+
- ✅ Creates automatic backups before updating
|
|
158
|
+
- ✅ Installs updated dependencies
|
|
159
|
+
|
|
160
|
+
See [USER_GUIDE.md - Updating Section](USER_GUIDE.md#-updating-myaidev-method) for detailed update instructions and best practices.
|
|
161
|
+
|
|
137
162
|
## 🏗️ SPARC Development Workflow
|
|
138
163
|
|
|
139
164
|
The **MyAIDev Method** implements the **SPARC methodology** - a systematic 5-phase approach to software development inspired by [GitHub Spec-Kit](https://github.com/github/spec-kit) patterns for agentic software development.
|
package/USER_GUIDE.md
CHANGED
|
@@ -7,6 +7,7 @@ This guide covers everything you need to know about using, customizing, and exte
|
|
|
7
7
|
## 📋 Table of Contents
|
|
8
8
|
|
|
9
9
|
- [Quick Start](#quick-start)
|
|
10
|
+
- [Updating MyAIDev Method](#-updating-myaidev-method)
|
|
10
11
|
- [Understanding the Structure](#understanding-the-structure)
|
|
11
12
|
- [👤 User Pathways](#-user-pathways)
|
|
12
13
|
- [Content Creator Pathway](#content-creator-pathway)
|
|
@@ -98,6 +99,161 @@ You'll have a `.claude` folder in your project:
|
|
|
98
99
|
/myai-configure agents --list
|
|
99
100
|
```
|
|
100
101
|
|
|
102
|
+
## 🔄 Updating MyAIDev Method
|
|
103
|
+
|
|
104
|
+
The MyAIDev Method package receives regular updates with new features, bug fixes, and improved agents. Keep your installation up to date to access the latest capabilities.
|
|
105
|
+
|
|
106
|
+
### Checking for Updates
|
|
107
|
+
|
|
108
|
+
Your current installation version is stored in `.claude/.myaidev-version`. When new versions are published to npm, you can update using the dedicated update command.
|
|
109
|
+
|
|
110
|
+
### Running Updates
|
|
111
|
+
|
|
112
|
+
```bash
|
|
113
|
+
# Interactive update (recommended) - prompts for conflicts
|
|
114
|
+
npx myaidev-method@latest update --claude
|
|
115
|
+
|
|
116
|
+
# Force update - overwrites all files without prompting
|
|
117
|
+
npx myaidev-method@latest update --claude --force
|
|
118
|
+
|
|
119
|
+
# Preview changes - see what would be updated without making changes
|
|
120
|
+
npx myaidev-method@latest update --claude --dry-run
|
|
121
|
+
|
|
122
|
+
# Verbose output - show detailed progress
|
|
123
|
+
npx myaidev-method@latest update --claude --verbose
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
### What Gets Updated
|
|
127
|
+
|
|
128
|
+
The update command updates all MyAIDev Method components:
|
|
129
|
+
|
|
130
|
+
- ✅ **Slash commands** (`.claude/commands/`) - New commands and improvements
|
|
131
|
+
- ✅ **Agent definitions** (`.claude/agents/`) - Enhanced prompts and capabilities
|
|
132
|
+
- ✅ **Executable scripts** (`.myaidev-method/scripts/`) - Bug fixes and new features
|
|
133
|
+
- ✅ **Utility libraries** (`.myaidev-method/lib/`) - Helper functions and utilities
|
|
134
|
+
- ✅ **Documentation files** (`USER_GUIDE.md`, `PUBLISHING_GUIDE.md`, etc.) - Updated guides
|
|
135
|
+
- ✅ **MCP configurations** (`.claude/mcp/`) - Server configurations and integrations
|
|
136
|
+
- ✅ **Dependencies** (`.myaidev-method/package.json`) - npm package updates
|
|
137
|
+
|
|
138
|
+
### Handling Customizations
|
|
139
|
+
|
|
140
|
+
If you've customized agents or commands, the update process intelligently handles conflicts:
|
|
141
|
+
|
|
142
|
+
1. **Detection**: The update command detects which files you've modified
|
|
143
|
+
2. **Diff Display**: Shows you the differences between your version and the new version
|
|
144
|
+
3. **User Choice**: You decide what to do for each modified file:
|
|
145
|
+
- **Keep current** - Skip this update, preserve your customizations
|
|
146
|
+
- **Use new version** - Overwrite with the latest version
|
|
147
|
+
- **View diff** - See detailed line-by-line differences
|
|
148
|
+
- **Keep + backup** - Update to new version and save your current version as `.bak`
|
|
149
|
+
|
|
150
|
+
Example update session:
|
|
151
|
+
|
|
152
|
+
```
|
|
153
|
+
$ npx myaidev-method@latest update --claude
|
|
154
|
+
|
|
155
|
+
🔍 Detecting MyAIDev Method installation...
|
|
156
|
+
|
|
157
|
+
✓ Found claude installation
|
|
158
|
+
Current version: 0.2.11
|
|
159
|
+
Latest version: 0.2.12
|
|
160
|
+
|
|
161
|
+
⚠️ This will update your MyAIDev Method installation
|
|
162
|
+
Modified files will require your confirmation
|
|
163
|
+
|
|
164
|
+
? Continue with update? Yes
|
|
165
|
+
|
|
166
|
+
💾 Creating backup...
|
|
167
|
+
✓ Backup created at: .myaidev-method-backup-2025-11-10T20-59-00
|
|
168
|
+
|
|
169
|
+
📦 Updating components...
|
|
170
|
+
|
|
171
|
+
Commands:
|
|
172
|
+
➕ myai-new-feature.md (new)
|
|
173
|
+
✓ myai-git-pr.md (unchanged)
|
|
174
|
+
|
|
175
|
+
Agents:
|
|
176
|
+
📝 content-writer.md has been modified
|
|
177
|
+
? What would you like to do?
|
|
178
|
+
❯ Keep current version (skip update)
|
|
179
|
+
Use new version (overwrite)
|
|
180
|
+
View diff
|
|
181
|
+
Keep current + backup (.bak)
|
|
182
|
+
|
|
183
|
+
✅ payloadcms-publish.md (updated)
|
|
184
|
+
|
|
185
|
+
Scripts:
|
|
186
|
+
✅ payloadcms-publish.js (updated)
|
|
187
|
+
✅ coolify-deploy-app.js (updated)
|
|
188
|
+
|
|
189
|
+
═══════════════════════════════════════
|
|
190
|
+
Update Summary
|
|
191
|
+
═══════════════════════════════════════
|
|
192
|
+
✅ Updated: 5 files
|
|
193
|
+
➕ Added: 2 new files
|
|
194
|
+
⏭️ Skipped: 1 files (kept current)
|
|
195
|
+
═══════════════════════════════════════
|
|
196
|
+
|
|
197
|
+
✅ Successfully updated to v0.2.12
|
|
198
|
+
Backup available at: .myaidev-method-backup-2025-11-10T20-59-00
|
|
199
|
+
```
|
|
200
|
+
|
|
201
|
+
### Safety Features
|
|
202
|
+
|
|
203
|
+
**Automatic Backups**: Before making any changes, the update command creates a complete backup:
|
|
204
|
+
```
|
|
205
|
+
.myaidev-method-backup-{timestamp}/
|
|
206
|
+
├── .claude/
|
|
207
|
+
├── .myaidev-method/
|
|
208
|
+
└── *.md (documentation files)
|
|
209
|
+
```
|
|
210
|
+
|
|
211
|
+
**Dry Run Mode**: Preview all changes without modifying any files:
|
|
212
|
+
```bash
|
|
213
|
+
npx myaidev-method@latest update --claude --dry-run
|
|
214
|
+
```
|
|
215
|
+
|
|
216
|
+
**Version Tracking**: The update command checks your current version and only proceeds if an update is available.
|
|
217
|
+
|
|
218
|
+
### Best Practices
|
|
219
|
+
|
|
220
|
+
1. **Review Release Notes**: Check the [CHANGELOG.md](CHANGELOG.md) before updating
|
|
221
|
+
2. **Use Dry Run**: Preview changes with `--dry-run` before actual update
|
|
222
|
+
3. **Backup Custom Work**: If you have heavily customized agents, create manual backups
|
|
223
|
+
4. **Update Regularly**: Stay current with latest features and security fixes
|
|
224
|
+
5. **Test After Update**: Verify your workflows still function as expected
|
|
225
|
+
|
|
226
|
+
### Troubleshooting Updates
|
|
227
|
+
|
|
228
|
+
**Update command not found**:
|
|
229
|
+
```bash
|
|
230
|
+
# Ensure you're using the latest package
|
|
231
|
+
npx myaidev-method@latest --version
|
|
232
|
+
```
|
|
233
|
+
|
|
234
|
+
**No installation detected**:
|
|
235
|
+
```bash
|
|
236
|
+
# Verify installation exists
|
|
237
|
+
ls -la .claude
|
|
238
|
+
|
|
239
|
+
# Reinstall if needed
|
|
240
|
+
npx myaidev-method@latest init --claude
|
|
241
|
+
```
|
|
242
|
+
|
|
243
|
+
**Dependency installation fails**:
|
|
244
|
+
```bash
|
|
245
|
+
# Manually install dependencies
|
|
246
|
+
cd .myaidev-method
|
|
247
|
+
npm install
|
|
248
|
+
```
|
|
249
|
+
|
|
250
|
+
**Want to rollback an update**:
|
|
251
|
+
```bash
|
|
252
|
+
# Restore from backup
|
|
253
|
+
rm -rf .claude .myaidev-method *.md
|
|
254
|
+
cp -r .myaidev-method-backup-{timestamp}/* .
|
|
255
|
+
```
|
|
256
|
+
|
|
101
257
|
## 🏗️ Understanding the Structure
|
|
102
258
|
|
|
103
259
|
### Commands Directory (`.claude/commands/`)
|
package/bin/cli.js
CHANGED
|
@@ -327,6 +327,29 @@ To update dependencies, run \`npm install\` inside the \`.myaidev-method/\` dire
|
|
|
327
327
|
.myaidev-method/node_modules/
|
|
328
328
|
\`\`\`
|
|
329
329
|
|
|
330
|
+
## Updating MyAIDev Method
|
|
331
|
+
|
|
332
|
+
To get the latest features, bug fixes, and improved agents:
|
|
333
|
+
|
|
334
|
+
\`\`\`bash
|
|
335
|
+
# Interactive update (recommended) - prompts for conflicts
|
|
336
|
+
npx myaidev-method@latest update --claude
|
|
337
|
+
|
|
338
|
+
# Force update - overwrites all files
|
|
339
|
+
npx myaidev-method@latest update --claude --force
|
|
340
|
+
|
|
341
|
+
# Preview changes without updating
|
|
342
|
+
npx myaidev-method@latest update --claude --dry-run
|
|
343
|
+
\`\`\`
|
|
344
|
+
|
|
345
|
+
The update command:
|
|
346
|
+
- ✅ Preserves your customizations (interactive conflict resolution)
|
|
347
|
+
- ✅ Creates automatic backups before updating
|
|
348
|
+
- ✅ Updates all components (commands, agents, scripts, docs)
|
|
349
|
+
- ✅ Installs updated dependencies
|
|
350
|
+
|
|
351
|
+
See \`USER_GUIDE.md\` for detailed update instructions and best practices.
|
|
352
|
+
|
|
330
353
|
## Notes
|
|
331
354
|
|
|
332
355
|
This configuration follows Claude Code's official standards for custom commands and agents.
|
|
@@ -424,6 +447,11 @@ This configuration follows Claude Code's official standards for custom commands
|
|
|
424
447
|
await fs.copy(sourcePath, path.join(projectDir, docFile));
|
|
425
448
|
}
|
|
426
449
|
}
|
|
450
|
+
|
|
451
|
+
// Save installation version for update tracking
|
|
452
|
+
const pkgJson = await fs.readJson(path.join(__dirname, '..', 'package.json'));
|
|
453
|
+
const versionFile = path.join(claudeDir, '.myaidev-version');
|
|
454
|
+
await fs.writeFile(versionFile, pkgJson.version);
|
|
427
455
|
}
|
|
428
456
|
|
|
429
457
|
async function setupGemini(projectDir) {
|
|
@@ -582,6 +610,154 @@ For full documentation, see the USER_GUIDE.md in your project root.
|
|
|
582
610
|
await fs.writeFile(path.join(codexDir, 'README.md'), opencodeReadme);
|
|
583
611
|
}
|
|
584
612
|
|
|
613
|
+
program
|
|
614
|
+
.command('update')
|
|
615
|
+
.description('Update MyAIDev Method components to latest version')
|
|
616
|
+
.option('--claude', 'Update Claude Code configuration')
|
|
617
|
+
.option('--gemini', 'Update Gemini CLI configuration')
|
|
618
|
+
.option('--codex', 'Update Codex CLI configuration')
|
|
619
|
+
.option('--force', 'Force update all files without prompting')
|
|
620
|
+
.option('--dry-run', 'Show what would be updated without making changes')
|
|
621
|
+
.option('--verbose', 'Show detailed progress')
|
|
622
|
+
.action(async (options) => {
|
|
623
|
+
const ora = (await import('ora')).default;
|
|
624
|
+
const { fileURLToPath } = await import('url');
|
|
625
|
+
const updateManager = await import('../src/lib/update-manager.js');
|
|
626
|
+
|
|
627
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
628
|
+
const __dirname = path.dirname(__filename);
|
|
629
|
+
const packageRoot = path.join(__dirname, '..');
|
|
630
|
+
|
|
631
|
+
try {
|
|
632
|
+
const cwd = process.cwd();
|
|
633
|
+
|
|
634
|
+
// Detect existing installation
|
|
635
|
+
console.log(chalk.cyan('\n🔍 Detecting MyAIDev Method installation...\n'));
|
|
636
|
+
const installation = await updateManager.detectExistingInstallation(cwd);
|
|
637
|
+
|
|
638
|
+
if (!installation) {
|
|
639
|
+
console.log(chalk.red('❌ No MyAIDev Method installation found'));
|
|
640
|
+
console.log(chalk.gray(' Run: npx myaidev-method@latest init --claude'));
|
|
641
|
+
process.exit(1);
|
|
642
|
+
}
|
|
643
|
+
|
|
644
|
+
console.log(chalk.green(`✓ Found ${installation.type} installation`));
|
|
645
|
+
console.log(chalk.gray(` Current version: ${installation.currentVersion}`));
|
|
646
|
+
|
|
647
|
+
// Get package version
|
|
648
|
+
const packageJson = await fs.readJson(path.join(packageRoot, 'package.json'));
|
|
649
|
+
const newVersion = packageJson.version;
|
|
650
|
+
|
|
651
|
+
console.log(chalk.gray(` Latest version: ${newVersion}`));
|
|
652
|
+
|
|
653
|
+
// Check if already up to date
|
|
654
|
+
if (installation.currentVersion === newVersion && !options.force) {
|
|
655
|
+
console.log(chalk.green('\n✅ Already up to date!'));
|
|
656
|
+
process.exit(0);
|
|
657
|
+
}
|
|
658
|
+
|
|
659
|
+
if (options.dryRun) {
|
|
660
|
+
console.log(chalk.yellow('\n📋 DRY RUN MODE - No changes will be made\n'));
|
|
661
|
+
} else if (!options.force) {
|
|
662
|
+
console.log(chalk.yellow('\n⚠️ This will update your MyAIDev Method installation'));
|
|
663
|
+
console.log(chalk.gray(' Modified files will require your confirmation\n'));
|
|
664
|
+
|
|
665
|
+
const { confirm } = await inquirer.prompt([
|
|
666
|
+
{
|
|
667
|
+
type: 'confirm',
|
|
668
|
+
name: 'confirm',
|
|
669
|
+
message: 'Continue with update?',
|
|
670
|
+
default: true
|
|
671
|
+
}
|
|
672
|
+
]);
|
|
673
|
+
|
|
674
|
+
if (!confirm) {
|
|
675
|
+
console.log(chalk.gray('Update cancelled'));
|
|
676
|
+
process.exit(0);
|
|
677
|
+
}
|
|
678
|
+
}
|
|
679
|
+
|
|
680
|
+
// Create backup unless dry-run
|
|
681
|
+
let backupDir;
|
|
682
|
+
if (!options.dryRun) {
|
|
683
|
+
console.log(chalk.cyan('\n💾 Creating backup...'));
|
|
684
|
+
backupDir = await updateManager.createBackup(cwd, installation.type);
|
|
685
|
+
console.log(chalk.green(`✓ Backup created at: ${path.basename(backupDir)}`));
|
|
686
|
+
}
|
|
687
|
+
|
|
688
|
+
// Update components
|
|
689
|
+
const allStats = {};
|
|
690
|
+
|
|
691
|
+
console.log(chalk.cyan('\n📦 Updating components...\n'));
|
|
692
|
+
|
|
693
|
+
// Commands
|
|
694
|
+
console.log(chalk.blue('Commands:'));
|
|
695
|
+
allStats.commands = await updateManager.updateComponent(
|
|
696
|
+
'commands', cwd, installation.type, packageRoot, options
|
|
697
|
+
);
|
|
698
|
+
|
|
699
|
+
// Agents
|
|
700
|
+
console.log(chalk.blue('\nAgents:'));
|
|
701
|
+
allStats.agents = await updateManager.updateComponent(
|
|
702
|
+
'agents', cwd, installation.type, packageRoot, options
|
|
703
|
+
);
|
|
704
|
+
|
|
705
|
+
// Scripts
|
|
706
|
+
console.log(chalk.blue('\nScripts:'));
|
|
707
|
+
allStats.scripts = await updateManager.updateComponent(
|
|
708
|
+
'scripts', cwd, installation.type, packageRoot, options
|
|
709
|
+
);
|
|
710
|
+
|
|
711
|
+
// Libraries
|
|
712
|
+
console.log(chalk.blue('\nLibraries:'));
|
|
713
|
+
allStats.lib = await updateManager.updateComponent(
|
|
714
|
+
'lib', cwd, installation.type, packageRoot, options
|
|
715
|
+
);
|
|
716
|
+
|
|
717
|
+
// MCP configurations
|
|
718
|
+
console.log(chalk.blue('\nMCP Configurations:'));
|
|
719
|
+
allStats.mcp = await updateManager.updateComponent(
|
|
720
|
+
'mcp', cwd, installation.type, packageRoot, options
|
|
721
|
+
);
|
|
722
|
+
|
|
723
|
+
// Documentation
|
|
724
|
+
console.log(chalk.blue('\nDocumentation:'));
|
|
725
|
+
allStats.docs = await updateManager.updateComponent(
|
|
726
|
+
'docs', cwd, installation.type, packageRoot, options
|
|
727
|
+
);
|
|
728
|
+
|
|
729
|
+
// Update dependencies
|
|
730
|
+
if (!options.dryRun) {
|
|
731
|
+
await updateManager.updateDependencies(cwd);
|
|
732
|
+
}
|
|
733
|
+
|
|
734
|
+
// Save new version
|
|
735
|
+
if (!options.dryRun) {
|
|
736
|
+
await updateManager.saveVersion(cwd, installation.type, newVersion);
|
|
737
|
+
}
|
|
738
|
+
|
|
739
|
+
// Show report
|
|
740
|
+
updateManager.generateUpdateReport(allStats);
|
|
741
|
+
|
|
742
|
+
if (options.dryRun) {
|
|
743
|
+
console.log(chalk.yellow('This was a dry run. No changes were made.'));
|
|
744
|
+
} else {
|
|
745
|
+
console.log(chalk.green(`✅ Successfully updated to v${newVersion}`));
|
|
746
|
+
if (backupDir) {
|
|
747
|
+
console.log(chalk.gray(` Backup available at: ${path.basename(backupDir)}`));
|
|
748
|
+
}
|
|
749
|
+
}
|
|
750
|
+
|
|
751
|
+
} catch (error) {
|
|
752
|
+
console.error(chalk.red('\n❌ Update failed:'));
|
|
753
|
+
console.error(error.message);
|
|
754
|
+
if (options.verbose) {
|
|
755
|
+
console.error(error);
|
|
756
|
+
}
|
|
757
|
+
process.exit(1);
|
|
758
|
+
}
|
|
759
|
+
});
|
|
760
|
+
|
|
585
761
|
program
|
|
586
762
|
.command('claudeweb')
|
|
587
763
|
.description('Start MyAIDev Method Web UI with Claude Code Viewer')
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "myaidev-method",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.12",
|
|
4
4
|
"description": "Comprehensive development framework with SPARC methodology for AI-assisted software development, multi-platform publishing (WordPress, PayloadCMS, Astro, Docusaurus, Mintlify), and Coolify deployment",
|
|
5
5
|
"mcpName": "io.github.myaione/myaidev-method",
|
|
6
6
|
"main": "src/index.js",
|
|
@@ -142,7 +142,8 @@
|
|
|
142
142
|
"PUBLISHING_GUIDE.md",
|
|
143
143
|
"TECHNICAL_ARCHITECTURE.md",
|
|
144
144
|
"PACKAGE_FIXES_SUMMARY.md",
|
|
145
|
-
"PAYLOADCMS_AUTH_UPDATE.md"
|
|
145
|
+
"PAYLOADCMS_AUTH_UPDATE.md",
|
|
146
|
+
"CHANGELOG.md"
|
|
146
147
|
],
|
|
147
148
|
"engines": {
|
|
148
149
|
"node": ">=18.0.0"
|
|
@@ -0,0 +1,385 @@
|
|
|
1
|
+
import fs from 'fs-extra';
|
|
2
|
+
import path from 'path';
|
|
3
|
+
import chalk from 'chalk';
|
|
4
|
+
import inquirer from 'inquirer';
|
|
5
|
+
import { createHash } from 'crypto';
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Update Manager for MyAIDev Method
|
|
9
|
+
* Handles intelligent updates with conflict resolution
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Detect existing MyAIDev Method installation
|
|
14
|
+
* @param {string} projectDir - Project directory path
|
|
15
|
+
* @returns {Object} Installation info or null
|
|
16
|
+
*/
|
|
17
|
+
export async function detectExistingInstallation(projectDir) {
|
|
18
|
+
const installations = {
|
|
19
|
+
claude: path.join(projectDir, '.claude'),
|
|
20
|
+
gemini: path.join(projectDir, '.gemini'),
|
|
21
|
+
codex: path.join(projectDir, '.codex')
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
for (const [type, dir] of Object.entries(installations)) {
|
|
25
|
+
if (await fs.pathExists(dir)) {
|
|
26
|
+
// Check for version file
|
|
27
|
+
const versionFile = path.join(dir, '.myaidev-version');
|
|
28
|
+
let currentVersion = 'unknown';
|
|
29
|
+
|
|
30
|
+
if (await fs.pathExists(versionFile)) {
|
|
31
|
+
currentVersion = (await fs.readFile(versionFile, 'utf-8')).trim();
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
return {
|
|
35
|
+
type,
|
|
36
|
+
dir,
|
|
37
|
+
currentVersion,
|
|
38
|
+
scriptsDir: path.join(projectDir, '.myaidev-method')
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
return null;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* Get file hash for comparison
|
|
48
|
+
* @param {string} filePath - Path to file
|
|
49
|
+
* @returns {string} File hash
|
|
50
|
+
*/
|
|
51
|
+
async function getFileHash(filePath) {
|
|
52
|
+
if (!await fs.pathExists(filePath)) {
|
|
53
|
+
return null;
|
|
54
|
+
}
|
|
55
|
+
const content = await fs.readFile(filePath);
|
|
56
|
+
return createHash('md5').update(content).digest('hex');
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* Compare two files
|
|
61
|
+
* @param {string} localFile - Local file path
|
|
62
|
+
* @param {string} newFile - New file path
|
|
63
|
+
* @returns {string} Status: 'identical', 'modified', 'new', 'deleted'
|
|
64
|
+
*/
|
|
65
|
+
export async function compareFiles(localFile, newFile) {
|
|
66
|
+
const localExists = await fs.pathExists(localFile);
|
|
67
|
+
const newExists = await fs.pathExists(newFile);
|
|
68
|
+
|
|
69
|
+
if (!localExists && newExists) return 'new';
|
|
70
|
+
if (localExists && !newExists) return 'deleted';
|
|
71
|
+
if (!localExists && !newExists) return 'none';
|
|
72
|
+
|
|
73
|
+
const localHash = await getFileHash(localFile);
|
|
74
|
+
const newHash = await getFileHash(newFile);
|
|
75
|
+
|
|
76
|
+
return localHash === newHash ? 'identical' : 'modified';
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
/**
|
|
80
|
+
* Show diff preview for a file
|
|
81
|
+
* @param {string} localFile - Local file path
|
|
82
|
+
* @param {string} newFile - New file path
|
|
83
|
+
*/
|
|
84
|
+
async function showDiff(localFile, newFile) {
|
|
85
|
+
const localContent = await fs.readFile(localFile, 'utf-8');
|
|
86
|
+
const newContent = await fs.readFile(newFile, 'utf-8');
|
|
87
|
+
|
|
88
|
+
const localLines = localContent.split('\n');
|
|
89
|
+
const newLines = newContent.split('\n');
|
|
90
|
+
|
|
91
|
+
console.log(chalk.cyan('\n Local version (first 10 lines):'));
|
|
92
|
+
localLines.slice(0, 10).forEach((line, i) => {
|
|
93
|
+
console.log(chalk.gray(` ${i + 1}: ${line.slice(0, 80)}`));
|
|
94
|
+
});
|
|
95
|
+
|
|
96
|
+
console.log(chalk.green('\n New version (first 10 lines):'));
|
|
97
|
+
newLines.slice(0, 10).forEach((line, i) => {
|
|
98
|
+
console.log(chalk.gray(` ${i + 1}: ${line.slice(0, 80)}`));
|
|
99
|
+
});
|
|
100
|
+
|
|
101
|
+
console.log(chalk.yellow(`\n Local: ${localLines.length} lines, New: ${newLines.length} lines\n`));
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
/**
|
|
105
|
+
* Prompt user for conflict resolution
|
|
106
|
+
* @param {string} file - File path relative to project
|
|
107
|
+
* @param {string} localPath - Local file absolute path
|
|
108
|
+
* @param {string} newPath - New file absolute path
|
|
109
|
+
* @returns {string} User choice: 'keep', 'replace', 'backup'
|
|
110
|
+
*/
|
|
111
|
+
export async function promptForConflict(file, localPath, newPath) {
|
|
112
|
+
console.log(chalk.yellow(`\n📝 ${file} has been modified`));
|
|
113
|
+
|
|
114
|
+
const answer = await inquirer.prompt([
|
|
115
|
+
{
|
|
116
|
+
type: 'list',
|
|
117
|
+
name: 'action',
|
|
118
|
+
message: 'What would you like to do?',
|
|
119
|
+
choices: [
|
|
120
|
+
{ name: 'Keep current version (skip update)', value: 'keep' },
|
|
121
|
+
{ name: 'Use new version (overwrite)', value: 'replace' },
|
|
122
|
+
{ name: 'View diff', value: 'diff' },
|
|
123
|
+
{ name: 'Keep current + backup (.bak)', value: 'backup' }
|
|
124
|
+
]
|
|
125
|
+
}
|
|
126
|
+
]);
|
|
127
|
+
|
|
128
|
+
if (answer.action === 'diff') {
|
|
129
|
+
await showDiff(localPath, newPath);
|
|
130
|
+
// Prompt again after showing diff
|
|
131
|
+
return promptForConflict(file, localPath, newPath);
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
return answer.action;
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
/**
|
|
138
|
+
* Create backup of installation
|
|
139
|
+
* @param {string} projectDir - Project directory
|
|
140
|
+
* @param {string} cliType - CLI type (claude/gemini/codex)
|
|
141
|
+
* @returns {string} Backup directory path
|
|
142
|
+
*/
|
|
143
|
+
export async function createBackup(projectDir, cliType) {
|
|
144
|
+
const timestamp = new Date().toISOString().replace(/[:.]/g, '-').slice(0, -5);
|
|
145
|
+
const backupDir = path.join(projectDir, `.myaidev-method-backup-${timestamp}`);
|
|
146
|
+
|
|
147
|
+
await fs.ensureDir(backupDir);
|
|
148
|
+
|
|
149
|
+
// Backup CLI directory
|
|
150
|
+
const cliDir = path.join(projectDir, `.${cliType}`);
|
|
151
|
+
if (await fs.pathExists(cliDir)) {
|
|
152
|
+
await fs.copy(cliDir, path.join(backupDir, `.${cliType}`));
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
// Backup scripts directory
|
|
156
|
+
const scriptsDir = path.join(projectDir, '.myaidev-method');
|
|
157
|
+
if (await fs.pathExists(scriptsDir)) {
|
|
158
|
+
await fs.copy(scriptsDir, path.join(backupDir, '.myaidev-method'));
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
// Backup documentation
|
|
162
|
+
const docs = [
|
|
163
|
+
'USER_GUIDE.md',
|
|
164
|
+
'PUBLISHING_GUIDE.md',
|
|
165
|
+
'COOLIFY_DEPLOYMENT.md',
|
|
166
|
+
'DEV_WORKFLOW_GUIDE.md',
|
|
167
|
+
'MCP_INTEGRATION.md',
|
|
168
|
+
'WORDPRESS_ADMIN_SCRIPTS.md',
|
|
169
|
+
'TECHNICAL_ARCHITECTURE.md'
|
|
170
|
+
];
|
|
171
|
+
|
|
172
|
+
for (const doc of docs) {
|
|
173
|
+
const docPath = path.join(projectDir, doc);
|
|
174
|
+
if (await fs.pathExists(docPath)) {
|
|
175
|
+
await fs.copy(docPath, path.join(backupDir, doc));
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
return backupDir;
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
/**
|
|
183
|
+
* Update a specific component
|
|
184
|
+
* @param {string} componentType - Type of component
|
|
185
|
+
* @param {string} projectDir - Project directory
|
|
186
|
+
* @param {string} cliType - CLI type
|
|
187
|
+
* @param {string} sourceDir - Source directory with new files
|
|
188
|
+
* @param {Object} options - Update options
|
|
189
|
+
* @returns {Object} Update statistics
|
|
190
|
+
*/
|
|
191
|
+
export async function updateComponent(componentType, projectDir, cliType, sourceDir, options = {}) {
|
|
192
|
+
const stats = {
|
|
193
|
+
updated: 0,
|
|
194
|
+
skipped: 0,
|
|
195
|
+
added: 0,
|
|
196
|
+
errors: 0
|
|
197
|
+
};
|
|
198
|
+
|
|
199
|
+
let targetDir, sourceSubDir;
|
|
200
|
+
|
|
201
|
+
switch (componentType) {
|
|
202
|
+
case 'commands':
|
|
203
|
+
targetDir = path.join(projectDir, `.${cliType}`, 'commands');
|
|
204
|
+
sourceSubDir = path.join(sourceDir, 'src', 'templates', cliType, 'commands');
|
|
205
|
+
break;
|
|
206
|
+
case 'agents':
|
|
207
|
+
targetDir = path.join(projectDir, `.${cliType}`, 'agents');
|
|
208
|
+
sourceSubDir = path.join(sourceDir, 'src', 'templates', 'claude', 'agents');
|
|
209
|
+
break;
|
|
210
|
+
case 'scripts':
|
|
211
|
+
targetDir = path.join(projectDir, '.myaidev-method', 'scripts');
|
|
212
|
+
sourceSubDir = path.join(sourceDir, 'src', 'scripts');
|
|
213
|
+
break;
|
|
214
|
+
case 'lib':
|
|
215
|
+
targetDir = path.join(projectDir, '.myaidev-method', 'lib');
|
|
216
|
+
sourceSubDir = path.join(sourceDir, 'src', 'lib');
|
|
217
|
+
break;
|
|
218
|
+
case 'mcp':
|
|
219
|
+
targetDir = path.join(projectDir, `.${cliType}`, 'mcp');
|
|
220
|
+
sourceSubDir = path.join(sourceDir, '.claude', 'mcp');
|
|
221
|
+
break;
|
|
222
|
+
case 'docs':
|
|
223
|
+
targetDir = projectDir;
|
|
224
|
+
sourceSubDir = sourceDir;
|
|
225
|
+
break;
|
|
226
|
+
default:
|
|
227
|
+
throw new Error(`Unknown component type: ${componentType}`);
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
if (!await fs.pathExists(sourceSubDir)) {
|
|
231
|
+
console.log(chalk.gray(` Skipping ${componentType} (not found in package)`));
|
|
232
|
+
return stats;
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
const files = componentType === 'docs'
|
|
236
|
+
? ['USER_GUIDE.md', 'PUBLISHING_GUIDE.md', 'COOLIFY_DEPLOYMENT.md', 'DEV_WORKFLOW_GUIDE.md',
|
|
237
|
+
'MCP_INTEGRATION.md', 'WORDPRESS_ADMIN_SCRIPTS.md', 'TECHNICAL_ARCHITECTURE.md']
|
|
238
|
+
: await fs.readdir(sourceSubDir);
|
|
239
|
+
|
|
240
|
+
for (const file of files) {
|
|
241
|
+
// Skip init-project.js from scripts
|
|
242
|
+
if (componentType === 'scripts' && file === 'init-project.js') continue;
|
|
243
|
+
|
|
244
|
+
const sourcePath = path.join(sourceSubDir, file);
|
|
245
|
+
const targetPath = path.join(targetDir, file);
|
|
246
|
+
|
|
247
|
+
// Skip if source doesn't exist (for docs)
|
|
248
|
+
if (!await fs.pathExists(sourcePath)) continue;
|
|
249
|
+
|
|
250
|
+
// Skip directories
|
|
251
|
+
const sourceStats = await fs.stat(sourcePath);
|
|
252
|
+
if (sourceStats.isDirectory()) continue;
|
|
253
|
+
|
|
254
|
+
// Skip non-relevant files for component type
|
|
255
|
+
if (componentType === 'commands' && !file.endsWith('.md') && !file.endsWith('.toml')) continue;
|
|
256
|
+
if (componentType === 'agents' && !file.endsWith('.md')) continue;
|
|
257
|
+
if (componentType === 'scripts' && !file.endsWith('.js')) continue;
|
|
258
|
+
if (componentType === 'mcp' && !file.endsWith('.js') && !file.endsWith('.json')) continue;
|
|
259
|
+
|
|
260
|
+
const status = await compareFiles(targetPath, sourcePath);
|
|
261
|
+
|
|
262
|
+
if (status === 'identical') {
|
|
263
|
+
if (options.verbose) {
|
|
264
|
+
console.log(chalk.gray(` ✓ ${file} (unchanged)`));
|
|
265
|
+
}
|
|
266
|
+
continue;
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
if (status === 'new') {
|
|
270
|
+
await fs.copy(sourcePath, targetPath);
|
|
271
|
+
console.log(chalk.green(` ➕ ${file} (new)`));
|
|
272
|
+
stats.added++;
|
|
273
|
+
continue;
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
if (status === 'modified') {
|
|
277
|
+
if (options.force) {
|
|
278
|
+
await fs.copy(sourcePath, targetPath);
|
|
279
|
+
console.log(chalk.blue(` ✅ ${file} (updated)`));
|
|
280
|
+
stats.updated++;
|
|
281
|
+
} else if (options.dryRun) {
|
|
282
|
+
console.log(chalk.yellow(` 📝 ${file} (would update)`));
|
|
283
|
+
} else {
|
|
284
|
+
const action = await promptForConflict(file, targetPath, sourcePath);
|
|
285
|
+
|
|
286
|
+
if (action === 'replace') {
|
|
287
|
+
await fs.copy(sourcePath, targetPath);
|
|
288
|
+
console.log(chalk.blue(` ✅ ${file} (updated)`));
|
|
289
|
+
stats.updated++;
|
|
290
|
+
} else if (action === 'backup') {
|
|
291
|
+
await fs.copy(targetPath, `${targetPath}.bak`);
|
|
292
|
+
await fs.copy(sourcePath, targetPath);
|
|
293
|
+
console.log(chalk.blue(` ✅ ${file} (updated, backup created)`));
|
|
294
|
+
stats.updated++;
|
|
295
|
+
} else {
|
|
296
|
+
console.log(chalk.gray(` ⏭️ ${file} (kept current)`));
|
|
297
|
+
stats.skipped++;
|
|
298
|
+
}
|
|
299
|
+
}
|
|
300
|
+
}
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
return stats;
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
/**
|
|
307
|
+
* Update dependencies in .myaidev-method
|
|
308
|
+
* @param {string} projectDir - Project directory
|
|
309
|
+
* @returns {boolean} Success status
|
|
310
|
+
*/
|
|
311
|
+
export async function updateDependencies(projectDir) {
|
|
312
|
+
const myaidevDir = path.join(projectDir, '.myaidev-method');
|
|
313
|
+
const packageJsonPath = path.join(myaidevDir, 'package.json');
|
|
314
|
+
|
|
315
|
+
if (!await fs.pathExists(packageJsonPath)) {
|
|
316
|
+
console.log(chalk.yellow(' ⚠️ No package.json found in .myaidev-method/'));
|
|
317
|
+
return false;
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
console.log(chalk.cyan('\n📦 Updating dependencies...'));
|
|
321
|
+
|
|
322
|
+
const { execSync } = await import('child_process');
|
|
323
|
+
try {
|
|
324
|
+
execSync('npm install', {
|
|
325
|
+
cwd: myaidevDir,
|
|
326
|
+
stdio: 'inherit'
|
|
327
|
+
});
|
|
328
|
+
console.log(chalk.green(' ✓ Dependencies updated successfully'));
|
|
329
|
+
return true;
|
|
330
|
+
} catch (error) {
|
|
331
|
+
console.log(chalk.red(' ✗ Failed to update dependencies'));
|
|
332
|
+
console.log(chalk.gray(' Run: cd .myaidev-method && npm install'));
|
|
333
|
+
return false;
|
|
334
|
+
}
|
|
335
|
+
}
|
|
336
|
+
|
|
337
|
+
/**
|
|
338
|
+
* Save version to installation
|
|
339
|
+
* @param {string} projectDir - Project directory
|
|
340
|
+
* @param {string} cliType - CLI type
|
|
341
|
+
* @param {string} version - Version to save
|
|
342
|
+
*/
|
|
343
|
+
export async function saveVersion(projectDir, cliType, version) {
|
|
344
|
+
const versionFile = path.join(projectDir, `.${cliType}`, '.myaidev-version');
|
|
345
|
+
await fs.writeFile(versionFile, version);
|
|
346
|
+
}
|
|
347
|
+
|
|
348
|
+
/**
|
|
349
|
+
* Generate update report
|
|
350
|
+
* @param {Object} allStats - Combined statistics from all components
|
|
351
|
+
*/
|
|
352
|
+
export function generateUpdateReport(allStats) {
|
|
353
|
+
const total = {
|
|
354
|
+
updated: 0,
|
|
355
|
+
skipped: 0,
|
|
356
|
+
added: 0,
|
|
357
|
+
errors: 0
|
|
358
|
+
};
|
|
359
|
+
|
|
360
|
+
for (const stats of Object.values(allStats)) {
|
|
361
|
+
total.updated += stats.updated;
|
|
362
|
+
total.skipped += stats.skipped;
|
|
363
|
+
total.added += stats.added;
|
|
364
|
+
total.errors += stats.errors;
|
|
365
|
+
}
|
|
366
|
+
|
|
367
|
+
console.log(chalk.cyan('\n═══════════════════════════════════════'));
|
|
368
|
+
console.log(chalk.cyan(' Update Summary'));
|
|
369
|
+
console.log(chalk.cyan('═══════════════════════════════════════'));
|
|
370
|
+
|
|
371
|
+
if (total.updated > 0) {
|
|
372
|
+
console.log(chalk.green(` ✅ Updated: ${total.updated} files`));
|
|
373
|
+
}
|
|
374
|
+
if (total.added > 0) {
|
|
375
|
+
console.log(chalk.green(` ➕ Added: ${total.added} new files`));
|
|
376
|
+
}
|
|
377
|
+
if (total.skipped > 0) {
|
|
378
|
+
console.log(chalk.gray(` ⏭️ Skipped: ${total.skipped} files (kept current)`));
|
|
379
|
+
}
|
|
380
|
+
if (total.errors > 0) {
|
|
381
|
+
console.log(chalk.red(` ✗ Errors: ${total.errors} files`));
|
|
382
|
+
}
|
|
383
|
+
|
|
384
|
+
console.log(chalk.cyan('═══════════════════════════════════════\n'));
|
|
385
|
+
}
|