claude-brain 0.3.2 → 0.3.4
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/package.json +1 -1
- package/src/cli/bin.ts +7 -0
- package/src/cli/commands/uninstall-mcp.ts +41 -0
- package/src/cli/ui/components.ts +3 -3
- package/src/setup/wizard.ts +16 -7
package/package.json
CHANGED
package/src/cli/bin.ts
CHANGED
|
@@ -29,6 +29,7 @@ function printHelp() {
|
|
|
29
29
|
['serve', 'Start the MCP server (default)'],
|
|
30
30
|
['setup', 'Run interactive setup wizard'],
|
|
31
31
|
['install', 'Register as MCP server in Claude Code'],
|
|
32
|
+
['uninstall', 'Remove MCP server from Claude Code'],
|
|
32
33
|
['health', 'Run health checks'],
|
|
33
34
|
['diagnose', 'Run diagnostics'],
|
|
34
35
|
['version', 'Show version'],
|
|
@@ -87,6 +88,12 @@ async function main() {
|
|
|
87
88
|
break
|
|
88
89
|
}
|
|
89
90
|
|
|
91
|
+
case 'uninstall': {
|
|
92
|
+
const { runUninstall } = await import('./commands/uninstall-mcp')
|
|
93
|
+
await runUninstall()
|
|
94
|
+
break
|
|
95
|
+
}
|
|
96
|
+
|
|
90
97
|
case 'health': {
|
|
91
98
|
const { runHealthCheck } = await import('@/health')
|
|
92
99
|
await runHealthCheck()
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { execSync } from 'node:child_process'
|
|
2
|
+
import {
|
|
3
|
+
renderLogo, theme, heading, successText, errorText, dimText,
|
|
4
|
+
box, withSpinner,
|
|
5
|
+
} from '@/cli/ui/index.js'
|
|
6
|
+
|
|
7
|
+
export async function runUninstall() {
|
|
8
|
+
console.log()
|
|
9
|
+
console.log(renderLogo())
|
|
10
|
+
console.log()
|
|
11
|
+
console.log(heading('MCP Uninstall'))
|
|
12
|
+
console.log()
|
|
13
|
+
|
|
14
|
+
try {
|
|
15
|
+
await withSpinner('Removing Claude Brain from Claude Code', async () => {
|
|
16
|
+
try {
|
|
17
|
+
execSync('claude mcp remove claude-brain', {
|
|
18
|
+
encoding: 'utf-8',
|
|
19
|
+
stdio: ['pipe', 'pipe', 'pipe'],
|
|
20
|
+
})
|
|
21
|
+
} catch {
|
|
22
|
+
// Falls back to scoped removal when registered in multiple scopes
|
|
23
|
+
execSync('claude mcp remove claude-brain -s local', {
|
|
24
|
+
encoding: 'utf-8',
|
|
25
|
+
stdio: ['pipe', 'pipe', 'pipe'],
|
|
26
|
+
})
|
|
27
|
+
}
|
|
28
|
+
})
|
|
29
|
+
console.log()
|
|
30
|
+
console.log(box(successText('Claude Brain MCP server removed from Claude Code.'), 'Success'))
|
|
31
|
+
} catch {
|
|
32
|
+
console.log()
|
|
33
|
+
console.log(box([
|
|
34
|
+
errorText('Failed to remove automatically.'),
|
|
35
|
+
'',
|
|
36
|
+
dimText('Run manually:'),
|
|
37
|
+
` ${theme.bold('claude mcp remove claude-brain')}`,
|
|
38
|
+
].join('\n'), 'Error'))
|
|
39
|
+
}
|
|
40
|
+
console.log()
|
|
41
|
+
}
|
package/src/cli/ui/components.ts
CHANGED
|
@@ -21,8 +21,8 @@ export function box(content: string, title?: string): string {
|
|
|
21
21
|
const body = lines.map(line => {
|
|
22
22
|
// Strip ANSI codes to calculate visible length
|
|
23
23
|
const visible = stripAnsi(line)
|
|
24
|
-
const padding = Math.max(0, innerWidth - visible.length)
|
|
25
|
-
return theme.secondary('│') + ' ' + line + ' '.repeat(padding
|
|
24
|
+
const padding = Math.max(0, innerWidth - visible.length - 1)
|
|
25
|
+
return theme.secondary('│') + ' ' + line + ' '.repeat(padding) + theme.secondary('│')
|
|
26
26
|
})
|
|
27
27
|
|
|
28
28
|
return [top, ...body, bottom].join('\n')
|
|
@@ -78,5 +78,5 @@ export function summaryPanel(title: string, items: Array<{ label: string; value:
|
|
|
78
78
|
// Strip ANSI escape codes for length calculation
|
|
79
79
|
function stripAnsi(str: string): string {
|
|
80
80
|
// eslint-disable-next-line no-control-regex
|
|
81
|
-
return str.replace(/\u001B\[[0-9;]*
|
|
81
|
+
return str.replace(/\u001B\[[0-9;]*[a-zA-Z]/g, '')
|
|
82
82
|
}
|
package/src/setup/wizard.ts
CHANGED
|
@@ -221,9 +221,12 @@ SERVER_NAME=claude-brain
|
|
|
221
221
|
}
|
|
222
222
|
|
|
223
223
|
if (answers.installClaudeMd) {
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
224
|
+
const shouldInstall = await this.confirmClaudeMdInstall()
|
|
225
|
+
if (shouldInstall) {
|
|
226
|
+
await withSpinner('Installing CLAUDE.md', async () => {
|
|
227
|
+
await this.copyClaudeMd()
|
|
228
|
+
})
|
|
229
|
+
}
|
|
227
230
|
}
|
|
228
231
|
|
|
229
232
|
console.log()
|
|
@@ -237,13 +240,13 @@ SERVER_NAME=claude-brain
|
|
|
237
240
|
console.log()
|
|
238
241
|
}
|
|
239
242
|
|
|
240
|
-
private async
|
|
243
|
+
private async confirmClaudeMdInstall(): Promise<boolean> {
|
|
241
244
|
const sourcePath = path.join(PACKAGE_ROOT, 'assets', 'CLAUDE.md')
|
|
242
245
|
const destPath = path.join(os.homedir(), 'CLAUDE.md')
|
|
243
246
|
|
|
244
247
|
if (!existsSync(sourcePath)) {
|
|
245
248
|
console.log(warningText('CLAUDE.md asset not found, skipping'))
|
|
246
|
-
return
|
|
249
|
+
return false
|
|
247
250
|
}
|
|
248
251
|
|
|
249
252
|
if (existsSync(destPath)) {
|
|
@@ -251,14 +254,20 @@ SERVER_NAME=claude-brain
|
|
|
251
254
|
type: 'confirm',
|
|
252
255
|
name: 'overwrite',
|
|
253
256
|
message: '~/CLAUDE.md already exists. Overwrite?',
|
|
254
|
-
initial: false
|
|
257
|
+
initial: false,
|
|
255
258
|
})
|
|
256
259
|
if (!overwrite) {
|
|
257
260
|
console.log(dimText(' Skipped CLAUDE.md installation'))
|
|
258
|
-
return
|
|
261
|
+
return false
|
|
259
262
|
}
|
|
260
263
|
}
|
|
261
264
|
|
|
265
|
+
return true
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
private async copyClaudeMd(): Promise<void> {
|
|
269
|
+
const sourcePath = path.join(PACKAGE_ROOT, 'assets', 'CLAUDE.md')
|
|
270
|
+
const destPath = path.join(os.homedir(), 'CLAUDE.md')
|
|
262
271
|
await fs.copyFile(sourcePath, destPath)
|
|
263
272
|
}
|
|
264
273
|
|