create-byan-agent 1.1.2 → 1.2.0
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 +250 -177
- package/LICENSE +21 -21
- package/README.md +1245 -421
- package/bin/create-byan-agent-backup.js +220 -220
- package/bin/create-byan-agent-fixed.js +301 -301
- package/bin/create-byan-agent.js +322 -301
- package/lib/errors.js +61 -0
- package/lib/exit-codes.js +54 -0
- package/lib/platforms/claude-code.js +113 -0
- package/lib/platforms/codex.js +92 -0
- package/lib/platforms/copilot-cli.js +123 -0
- package/lib/platforms/index.js +14 -0
- package/lib/platforms/vscode.js +51 -0
- package/lib/utils/config-loader.js +79 -0
- package/lib/utils/file-utils.js +104 -0
- package/lib/utils/git-detector.js +35 -0
- package/lib/utils/logger.js +64 -0
- package/lib/utils/node-detector.js +58 -0
- package/lib/utils/os-detector.js +74 -0
- package/lib/utils/yaml-utils.js +87 -0
- package/lib/yanstaller/backuper.js +308 -0
- package/lib/yanstaller/detector.js +141 -0
- package/lib/yanstaller/index.js +93 -0
- package/lib/yanstaller/installer.js +225 -0
- package/lib/yanstaller/interviewer.js +250 -0
- package/lib/yanstaller/recommender.js +298 -0
- package/lib/yanstaller/troubleshooter.js +498 -0
- package/lib/yanstaller/validator.js +578 -0
- package/lib/yanstaller/wizard.js +211 -0
- package/package.json +61 -55
- package/templates/.github/agents/bmad-agent-bmad-master.md +15 -15
- package/templates/.github/agents/bmad-agent-bmb-agent-builder.md +15 -15
- package/templates/.github/agents/bmad-agent-bmb-module-builder.md +15 -15
- package/templates/.github/agents/bmad-agent-bmb-workflow-builder.md +15 -15
- package/templates/.github/agents/bmad-agent-bmm-analyst.md +15 -15
- package/templates/.github/agents/bmad-agent-bmm-architect.md +15 -15
- package/templates/.github/agents/bmad-agent-bmm-dev.md +15 -15
- package/templates/.github/agents/bmad-agent-bmm-pm.md +15 -15
- package/templates/.github/agents/bmad-agent-bmm-quick-flow-solo-dev.md +15 -15
- package/templates/.github/agents/bmad-agent-bmm-quinn.md +15 -15
- package/templates/.github/agents/bmad-agent-bmm-sm.md +15 -15
- package/templates/.github/agents/bmad-agent-bmm-tech-writer.md +15 -15
- package/templates/.github/agents/bmad-agent-bmm-ux-designer.md +15 -15
- package/templates/.github/agents/bmad-agent-byan-test.md +32 -0
- package/templates/.github/agents/bmad-agent-byan.md +224 -224
- package/templates/.github/agents/bmad-agent-carmack.md +18 -0
- package/templates/.github/agents/bmad-agent-cis-brainstorming-coach.md +15 -15
- package/templates/.github/agents/bmad-agent-cis-creative-problem-solver.md +15 -15
- package/templates/.github/agents/bmad-agent-cis-design-thinking-coach.md +15 -15
- package/templates/.github/agents/bmad-agent-cis-innovation-strategist.md +15 -15
- package/templates/.github/agents/bmad-agent-cis-presentation-master.md +15 -15
- package/templates/.github/agents/bmad-agent-cis-storyteller.md +15 -15
- package/templates/.github/agents/bmad-agent-marc.md +48 -48
- package/templates/.github/agents/bmad-agent-patnote.md +48 -0
- package/templates/.github/agents/bmad-agent-rachid.md +47 -47
- package/templates/.github/agents/bmad-agent-tea-tea.md +15 -15
- package/templates/.github/agents/bmad-agent-test-dynamic.md +21 -0
- package/templates/.github/agents/expert-merise-agile.md +1 -0
- package/templates/.github/agents/franck.md +379 -0
- package/templates/_bmad/bmb/agents/agent-builder.md +59 -59
- package/templates/_bmad/bmb/agents/byan-test.md +116 -116
- package/templates/_bmad/bmb/agents/byan.md +215 -215
- package/templates/_bmad/bmb/agents/marc.md +303 -303
- package/templates/_bmad/bmb/agents/module-builder.md +60 -60
- package/templates/_bmad/bmb/agents/patnote.md +495 -495
- package/templates/_bmad/bmb/agents/rachid.md +184 -184
- package/templates/_bmad/bmb/agents/workflow-builder.md +61 -61
- package/templates/_bmad/bmb/workflows/byan/data/mantras.yaml +272 -272
- package/templates/_bmad/bmb/workflows/byan/data/templates.yaml +59 -59
- package/templates/_bmad/bmb/workflows/byan/delete-agent-workflow.md +657 -657
- package/templates/_bmad/bmb/workflows/byan/edit-agent-workflow.md +688 -688
- package/templates/_bmad/bmb/workflows/byan/interview-workflow.md +753 -753
- package/templates/_bmad/bmb/workflows/byan/quick-create-workflow.md +450 -450
- package/templates/_bmad/bmb/workflows/byan/templates/base-agent-template.md +79 -79
- package/templates/_bmad/bmb/workflows/byan/validate-agent-workflow.md +676 -676
- package/templates/_bmad/core/agents/carmack.md +238 -238
|
@@ -0,0 +1,498 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* TROUBLESHOOTER Module
|
|
3
|
+
*
|
|
4
|
+
* Diagnoses and fixes common installation errors.
|
|
5
|
+
*
|
|
6
|
+
* Phase 5: 40h development
|
|
7
|
+
*
|
|
8
|
+
* @module yanstaller/troubleshooter
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
const path = require('path');
|
|
12
|
+
const os = require('os');
|
|
13
|
+
const fs = require('fs-extra');
|
|
14
|
+
const { execSync } = require('child_process');
|
|
15
|
+
const fileUtils = require('../utils/file-utils');
|
|
16
|
+
const detector = require('./detector');
|
|
17
|
+
const validator = require('./validator');
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* @typedef {Object} DiagnosticResult
|
|
21
|
+
* @property {string} error - Error type
|
|
22
|
+
* @property {string} cause - Root cause
|
|
23
|
+
* @property {string} solution - Recommended solution
|
|
24
|
+
* @property {boolean} canAutoFix - Whether auto-fix is available
|
|
25
|
+
* @property {Function} [autoFix] - Auto-fix function
|
|
26
|
+
* @property {string} errorCode - Unique error code
|
|
27
|
+
* @property {string} severity - 'critical' | 'warning' | 'info'
|
|
28
|
+
*/
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* @typedef {Object} TroubleshootResult
|
|
32
|
+
* @property {boolean} success - All issues fixed
|
|
33
|
+
* @property {DiagnosticResult[]} diagnostics - Detected issues
|
|
34
|
+
* @property {string[]} fixed - Successfully fixed issues
|
|
35
|
+
* @property {string[]} pending - Issues requiring manual fix
|
|
36
|
+
*/
|
|
37
|
+
|
|
38
|
+
// Error code patterns
|
|
39
|
+
const ERROR_PATTERNS = {
|
|
40
|
+
NODE_VERSION: /node.*version|unsupported.*node/i,
|
|
41
|
+
PERMISSION: /EACCES|EPERM|permission denied/i,
|
|
42
|
+
NOT_FOUND: /ENOENT|not found|cannot find/i,
|
|
43
|
+
GIT_MISSING: /git.*not found|git.*command/i,
|
|
44
|
+
DISK_SPACE: /ENOSPC|no space left/i,
|
|
45
|
+
NETWORK: /ETIMEDOUT|ECONNREFUSED|network/i,
|
|
46
|
+
CORRUPTED: /corrupted|invalid.*format|parse error/i,
|
|
47
|
+
MISSING_DEP: /cannot find module|module not found/i
|
|
48
|
+
};
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* Diagnostic functions for specific error types
|
|
52
|
+
*/
|
|
53
|
+
|
|
54
|
+
async function diagnoseNodeVersion(error, context) {
|
|
55
|
+
const detectionResult = await detector.detect();
|
|
56
|
+
const currentVersion = detectionResult.node.version;
|
|
57
|
+
const requiredVersion = '16.0.0';
|
|
58
|
+
|
|
59
|
+
return {
|
|
60
|
+
error: error.message,
|
|
61
|
+
errorCode: 'NODE_VERSION',
|
|
62
|
+
cause: `Node.js version ${currentVersion} is too old`,
|
|
63
|
+
solution: suggestNodeUpgrade(currentVersion, requiredVersion),
|
|
64
|
+
canAutoFix: false,
|
|
65
|
+
severity: 'critical'
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
async function diagnosePermission(error, context) {
|
|
70
|
+
const projectRoot = context.projectRoot || process.cwd();
|
|
71
|
+
|
|
72
|
+
return {
|
|
73
|
+
error: error.message,
|
|
74
|
+
errorCode: 'PERMISSION',
|
|
75
|
+
cause: 'Insufficient file permissions',
|
|
76
|
+
solution: `Run with elevated permissions or fix permissions on: ${projectRoot}`,
|
|
77
|
+
canAutoFix: true,
|
|
78
|
+
autoFix: async () => await fixPermissions(projectRoot),
|
|
79
|
+
severity: 'critical'
|
|
80
|
+
};
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
async function diagnoseNotFound(error, context) {
|
|
84
|
+
// Extract file path from error if possible
|
|
85
|
+
const match = error.message.match(/['"]([^'"]+)['"]/);
|
|
86
|
+
const missingPath = match ? match[1] : 'unknown file';
|
|
87
|
+
|
|
88
|
+
return {
|
|
89
|
+
error: error.message,
|
|
90
|
+
errorCode: 'NOT_FOUND',
|
|
91
|
+
cause: `Required file or directory not found: ${missingPath}`,
|
|
92
|
+
solution: 'Re-run installation or check file paths',
|
|
93
|
+
canAutoFix: true,
|
|
94
|
+
autoFix: async () => await repairStructure(context.projectRoot),
|
|
95
|
+
severity: 'critical'
|
|
96
|
+
};
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
async function diagnoseGitMissing(error, context) {
|
|
100
|
+
return {
|
|
101
|
+
error: error.message,
|
|
102
|
+
errorCode: 'GIT_MISSING',
|
|
103
|
+
cause: 'Git is not installed or not in PATH',
|
|
104
|
+
solution: 'Install Git from https://git-scm.com/ and add to PATH',
|
|
105
|
+
canAutoFix: false,
|
|
106
|
+
severity: 'warning'
|
|
107
|
+
};
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
async function diagnoseDiskSpace(error, context) {
|
|
111
|
+
return {
|
|
112
|
+
error: error.message,
|
|
113
|
+
errorCode: 'DISK_SPACE',
|
|
114
|
+
cause: 'Insufficient disk space',
|
|
115
|
+
solution: 'Free up disk space and retry installation',
|
|
116
|
+
canAutoFix: false,
|
|
117
|
+
severity: 'critical'
|
|
118
|
+
};
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
async function diagnoseNetwork(error, context) {
|
|
122
|
+
return {
|
|
123
|
+
error: error.message,
|
|
124
|
+
errorCode: 'NETWORK',
|
|
125
|
+
cause: 'Network connection failed',
|
|
126
|
+
solution: 'Check internet connection and retry. If behind proxy, configure npm proxy settings',
|
|
127
|
+
canAutoFix: false,
|
|
128
|
+
severity: 'warning'
|
|
129
|
+
};
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
async function diagnoseCorrupted(error, context) {
|
|
133
|
+
return {
|
|
134
|
+
error: error.message,
|
|
135
|
+
errorCode: 'CORRUPTED',
|
|
136
|
+
cause: 'Configuration file or installation is corrupted',
|
|
137
|
+
solution: 'Delete corrupted files and reinstall',
|
|
138
|
+
canAutoFix: true,
|
|
139
|
+
autoFix: async () => await resetConfig(context.projectRoot),
|
|
140
|
+
severity: 'critical'
|
|
141
|
+
};
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
async function diagnoseMissingDep(error, context) {
|
|
145
|
+
// Extract module name from error
|
|
146
|
+
const match = error.message.match(/module ['"]([^'"]+)['"]/i);
|
|
147
|
+
const moduleName = match ? match[1] : 'unknown';
|
|
148
|
+
|
|
149
|
+
return {
|
|
150
|
+
error: error.message,
|
|
151
|
+
errorCode: 'MISSING_DEP',
|
|
152
|
+
cause: `Missing Node.js dependency: ${moduleName}`,
|
|
153
|
+
solution: 'Run: npm install',
|
|
154
|
+
canAutoFix: true,
|
|
155
|
+
autoFix: async () => await reinstallDependencies(context.projectRoot),
|
|
156
|
+
severity: 'critical'
|
|
157
|
+
};
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
/**
|
|
161
|
+
* Diagnose installation error
|
|
162
|
+
*
|
|
163
|
+
* @param {Error} error - Installation error
|
|
164
|
+
* @param {Object} context - Installation context
|
|
165
|
+
* @returns {Promise<DiagnosticResult>}
|
|
166
|
+
*/
|
|
167
|
+
async function diagnose(error, context = {}) {
|
|
168
|
+
const errorMsg = error.message || String(error);
|
|
169
|
+
|
|
170
|
+
// Pattern match against known errors
|
|
171
|
+
if (ERROR_PATTERNS.NODE_VERSION.test(errorMsg)) {
|
|
172
|
+
return diagnoseNodeVersion(error, context);
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
if (ERROR_PATTERNS.PERMISSION.test(errorMsg)) {
|
|
176
|
+
return diagnosePermission(error, context);
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
if (ERROR_PATTERNS.NOT_FOUND.test(errorMsg)) {
|
|
180
|
+
return diagnoseNotFound(error, context);
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
if (ERROR_PATTERNS.GIT_MISSING.test(errorMsg)) {
|
|
184
|
+
return diagnoseGitMissing(error, context);
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
if (ERROR_PATTERNS.DISK_SPACE.test(errorMsg)) {
|
|
188
|
+
return diagnoseDiskSpace(error, context);
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
if (ERROR_PATTERNS.NETWORK.test(errorMsg)) {
|
|
192
|
+
return diagnoseNetwork(error, context);
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
if (ERROR_PATTERNS.CORRUPTED.test(errorMsg)) {
|
|
196
|
+
return diagnoseCorrupted(error, context);
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
if (ERROR_PATTERNS.MISSING_DEP.test(errorMsg)) {
|
|
200
|
+
return diagnoseMissingDep(error, context);
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
// Unknown error
|
|
204
|
+
return {
|
|
205
|
+
error: errorMsg,
|
|
206
|
+
errorCode: 'UNKNOWN',
|
|
207
|
+
cause: 'Unknown error type',
|
|
208
|
+
solution: 'Check error message and logs for details',
|
|
209
|
+
canAutoFix: false,
|
|
210
|
+
severity: 'warning'
|
|
211
|
+
};
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
/**
|
|
215
|
+
* Auto-fix permission error
|
|
216
|
+
*
|
|
217
|
+
* @param {string} targetPath - File path with permission issue
|
|
218
|
+
* @returns {Promise<void>}
|
|
219
|
+
*/
|
|
220
|
+
async function fixPermissions(targetPath) {
|
|
221
|
+
const platform = os.platform();
|
|
222
|
+
|
|
223
|
+
try {
|
|
224
|
+
if (platform === 'win32') {
|
|
225
|
+
// Windows: Use icacls to grant full control
|
|
226
|
+
execSync(`icacls "${targetPath}" /grant ${os.userInfo().username}:F /T`, {
|
|
227
|
+
stdio: 'ignore'
|
|
228
|
+
});
|
|
229
|
+
} else {
|
|
230
|
+
// Unix/macOS: Use chmod
|
|
231
|
+
await fs.chmod(targetPath, 0o755);
|
|
232
|
+
|
|
233
|
+
// Recursively fix subdirectories
|
|
234
|
+
const stat = await fs.stat(targetPath);
|
|
235
|
+
if (stat.isDirectory()) {
|
|
236
|
+
const items = await fs.readdir(targetPath);
|
|
237
|
+
for (const item of items) {
|
|
238
|
+
await fixPermissions(path.join(targetPath, item));
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
} catch (error) {
|
|
243
|
+
throw new Error(`Failed to fix permissions: ${error.message}`);
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
/**
|
|
248
|
+
* Suggest Node.js upgrade
|
|
249
|
+
*
|
|
250
|
+
* @param {string} currentVersion - Current Node version
|
|
251
|
+
* @param {string} requiredVersion - Required Node version
|
|
252
|
+
* @returns {string} - Upgrade instructions
|
|
253
|
+
*/
|
|
254
|
+
function suggestNodeUpgrade(currentVersion, requiredVersion) {
|
|
255
|
+
const platform = os.platform();
|
|
256
|
+
|
|
257
|
+
let instructions = `Current Node.js: ${currentVersion}, Required: ${requiredVersion}+\n\n`;
|
|
258
|
+
|
|
259
|
+
switch (platform) {
|
|
260
|
+
case 'win32':
|
|
261
|
+
instructions += 'Windows: Download from https://nodejs.org/ or use:\n';
|
|
262
|
+
instructions += ' winget install OpenJS.NodeJS.LTS';
|
|
263
|
+
break;
|
|
264
|
+
case 'darwin':
|
|
265
|
+
instructions += 'macOS:\n';
|
|
266
|
+
instructions += ' brew upgrade node\n';
|
|
267
|
+
instructions += ' Or download from https://nodejs.org/';
|
|
268
|
+
break;
|
|
269
|
+
case 'linux':
|
|
270
|
+
instructions += 'Linux:\n';
|
|
271
|
+
instructions += ' # Using nvm (recommended):\n';
|
|
272
|
+
instructions += ' nvm install --lts\n';
|
|
273
|
+
instructions += ' # Or using apt:\n';
|
|
274
|
+
instructions += ' curl -fsSL https://deb.nodesource.com/setup_lts.x | sudo -E bash -\n';
|
|
275
|
+
instructions += ' sudo apt-get install -y nodejs';
|
|
276
|
+
break;
|
|
277
|
+
default:
|
|
278
|
+
instructions += 'Download from https://nodejs.org/';
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
return instructions;
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
/**
|
|
285
|
+
* Check common issues
|
|
286
|
+
*
|
|
287
|
+
* @param {Object} config - Installation config
|
|
288
|
+
* @returns {Promise<string[]>} - List of detected issues
|
|
289
|
+
*/
|
|
290
|
+
async function checkCommonIssues(config = {}) {
|
|
291
|
+
const issues = [];
|
|
292
|
+
|
|
293
|
+
try {
|
|
294
|
+
// Check 1: Node.js version
|
|
295
|
+
const detectionResult = await detector.detect();
|
|
296
|
+
const nodeVersion = detectionResult.node.version;
|
|
297
|
+
const majorVersion = parseInt(nodeVersion.split('.')[0]);
|
|
298
|
+
|
|
299
|
+
if (majorVersion < 16) {
|
|
300
|
+
issues.push(`Node.js ${nodeVersion} is outdated (require 16+)`);
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
// Check 2: Git availability
|
|
304
|
+
if (!detectionResult.git.detected) {
|
|
305
|
+
issues.push('Git is not installed');
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
// Check 3: Write permission
|
|
309
|
+
const projectRoot = config.projectRoot || process.cwd();
|
|
310
|
+
try {
|
|
311
|
+
await fs.access(projectRoot, fs.constants.W_OK);
|
|
312
|
+
} catch {
|
|
313
|
+
issues.push(`No write permission in ${projectRoot}`);
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
// Check 4: Disk space (at least 100MB)
|
|
317
|
+
try {
|
|
318
|
+
const stats = await fs.statfs || await fs.stat(projectRoot);
|
|
319
|
+
// This is a rough check, might not work on all platforms
|
|
320
|
+
if (stats.bavail && stats.bsize) {
|
|
321
|
+
const availableSpace = stats.bavail * stats.bsize;
|
|
322
|
+
if (availableSpace < 100 * 1024 * 1024) {
|
|
323
|
+
issues.push('Low disk space (< 100MB available)');
|
|
324
|
+
}
|
|
325
|
+
}
|
|
326
|
+
} catch {
|
|
327
|
+
// Disk space check failed, skip
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
// Check 5: Network connectivity (optional check)
|
|
331
|
+
try {
|
|
332
|
+
// Simple check: try to resolve nodejs.org
|
|
333
|
+
require('dns').resolve('nodejs.org', (err) => {
|
|
334
|
+
if (err) {
|
|
335
|
+
issues.push('Network connectivity issue');
|
|
336
|
+
}
|
|
337
|
+
});
|
|
338
|
+
} catch {
|
|
339
|
+
// Network check failed, skip
|
|
340
|
+
}
|
|
341
|
+
|
|
342
|
+
// Check 6: Dependencies installed
|
|
343
|
+
const requiredDeps = ['fs-extra', 'js-yaml', 'chalk'];
|
|
344
|
+
for (const dep of requiredDeps) {
|
|
345
|
+
try {
|
|
346
|
+
require.resolve(dep);
|
|
347
|
+
} catch {
|
|
348
|
+
issues.push(`Missing dependency: ${dep}`);
|
|
349
|
+
}
|
|
350
|
+
}
|
|
351
|
+
|
|
352
|
+
} catch (error) {
|
|
353
|
+
issues.push(`Health check error: ${error.message}`);
|
|
354
|
+
}
|
|
355
|
+
|
|
356
|
+
return issues;
|
|
357
|
+
}
|
|
358
|
+
|
|
359
|
+
/**
|
|
360
|
+
* Repair _bmad/ directory structure
|
|
361
|
+
*
|
|
362
|
+
* @param {string} projectRoot - Project root directory
|
|
363
|
+
* @returns {Promise<void>}
|
|
364
|
+
*/
|
|
365
|
+
async function repairStructure(projectRoot) {
|
|
366
|
+
const installer = require('./installer');
|
|
367
|
+
|
|
368
|
+
try {
|
|
369
|
+
await installer.createBmadStructure(projectRoot);
|
|
370
|
+
} catch (error) {
|
|
371
|
+
throw new Error(`Failed to repair structure: ${error.message}`);
|
|
372
|
+
}
|
|
373
|
+
}
|
|
374
|
+
|
|
375
|
+
/**
|
|
376
|
+
* Reset corrupted config files
|
|
377
|
+
*
|
|
378
|
+
* @param {string} projectRoot - Project root directory
|
|
379
|
+
* @returns {Promise<void>}
|
|
380
|
+
*/
|
|
381
|
+
async function resetConfig(projectRoot) {
|
|
382
|
+
const installer = require('./installer');
|
|
383
|
+
|
|
384
|
+
try {
|
|
385
|
+
// Recreate default config
|
|
386
|
+
const defaultConfig = {
|
|
387
|
+
userName: 'User',
|
|
388
|
+
language: 'English',
|
|
389
|
+
mode: 'minimal',
|
|
390
|
+
agents: []
|
|
391
|
+
};
|
|
392
|
+
|
|
393
|
+
await installer.createModuleConfig('bmb', defaultConfig, projectRoot);
|
|
394
|
+
} catch (error) {
|
|
395
|
+
throw new Error(`Failed to reset config: ${error.message}`);
|
|
396
|
+
}
|
|
397
|
+
}
|
|
398
|
+
|
|
399
|
+
/**
|
|
400
|
+
* Reinstall npm dependencies
|
|
401
|
+
*
|
|
402
|
+
* @param {string} projectRoot - Project root directory
|
|
403
|
+
* @returns {Promise<void>}
|
|
404
|
+
*/
|
|
405
|
+
async function reinstallDependencies(projectRoot) {
|
|
406
|
+
try {
|
|
407
|
+
execSync('npm install', {
|
|
408
|
+
cwd: projectRoot,
|
|
409
|
+
stdio: 'inherit'
|
|
410
|
+
});
|
|
411
|
+
} catch (error) {
|
|
412
|
+
throw new Error(`Failed to reinstall dependencies: ${error.message}`);
|
|
413
|
+
}
|
|
414
|
+
}
|
|
415
|
+
|
|
416
|
+
/**
|
|
417
|
+
* Reinstall missing agents
|
|
418
|
+
*
|
|
419
|
+
* @param {string[]} agents - Agent names to reinstall
|
|
420
|
+
* @param {string} projectRoot - Project root directory
|
|
421
|
+
* @returns {Promise<void>}
|
|
422
|
+
*/
|
|
423
|
+
async function reinstallAgents(agents, projectRoot) {
|
|
424
|
+
const installer = require('./installer');
|
|
425
|
+
|
|
426
|
+
for (const agentName of agents) {
|
|
427
|
+
try {
|
|
428
|
+
await installer.copyAgentFile(agentName, projectRoot);
|
|
429
|
+
} catch (error) {
|
|
430
|
+
// Continue with other agents even if one fails
|
|
431
|
+
console.warn(`Failed to reinstall ${agentName}: ${error.message}`);
|
|
432
|
+
}
|
|
433
|
+
}
|
|
434
|
+
}
|
|
435
|
+
|
|
436
|
+
/**
|
|
437
|
+
* Run full troubleshooting with auto-fixes
|
|
438
|
+
*
|
|
439
|
+
* @param {Object} config - Installation config
|
|
440
|
+
* @returns {Promise<TroubleshootResult>}
|
|
441
|
+
*/
|
|
442
|
+
async function troubleshoot(config) {
|
|
443
|
+
const diagnostics = [];
|
|
444
|
+
const fixed = [];
|
|
445
|
+
const pending = [];
|
|
446
|
+
|
|
447
|
+
// Run validation first
|
|
448
|
+
const validationResult = await validator.validate(config);
|
|
449
|
+
|
|
450
|
+
if (validationResult.success) {
|
|
451
|
+
return {
|
|
452
|
+
success: true,
|
|
453
|
+
diagnostics: [],
|
|
454
|
+
fixed: [],
|
|
455
|
+
pending: []
|
|
456
|
+
};
|
|
457
|
+
}
|
|
458
|
+
|
|
459
|
+
// Diagnose each error
|
|
460
|
+
for (const check of validationResult.checks) {
|
|
461
|
+
if (!check.passed) {
|
|
462
|
+
const error = new Error(check.message || `${check.name} failed`);
|
|
463
|
+
const diagnostic = await diagnose(error, config);
|
|
464
|
+
diagnostics.push(diagnostic);
|
|
465
|
+
|
|
466
|
+
// Try auto-fix if available
|
|
467
|
+
if (diagnostic.canAutoFix && diagnostic.autoFix) {
|
|
468
|
+
try {
|
|
469
|
+
await diagnostic.autoFix();
|
|
470
|
+
fixed.push(diagnostic.errorCode);
|
|
471
|
+
} catch (fixError) {
|
|
472
|
+
pending.push(`${diagnostic.errorCode}: ${fixError.message}`);
|
|
473
|
+
}
|
|
474
|
+
} else {
|
|
475
|
+
pending.push(diagnostic.errorCode);
|
|
476
|
+
}
|
|
477
|
+
}
|
|
478
|
+
}
|
|
479
|
+
|
|
480
|
+
return {
|
|
481
|
+
success: pending.length === 0,
|
|
482
|
+
diagnostics,
|
|
483
|
+
fixed,
|
|
484
|
+
pending
|
|
485
|
+
};
|
|
486
|
+
}
|
|
487
|
+
|
|
488
|
+
module.exports = {
|
|
489
|
+
diagnose,
|
|
490
|
+
fixPermissions,
|
|
491
|
+
suggestNodeUpgrade,
|
|
492
|
+
checkCommonIssues,
|
|
493
|
+
repairStructure,
|
|
494
|
+
resetConfig,
|
|
495
|
+
reinstallDependencies,
|
|
496
|
+
reinstallAgents,
|
|
497
|
+
troubleshoot
|
|
498
|
+
};
|