claude-brain 0.30.2 → 0.30.3
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/README.md +241 -191
- package/VERSION +1 -1
- package/assets/CLAUDE-unified.md +11 -11
- package/assets/CLAUDE.md +29 -29
- package/package.json +7 -3
- package/packs/backend/node.json +173 -173
- package/packs/core/javascript.json +176 -176
- package/packs/core/typescript.json +222 -222
- package/packs/frontend/react.json +254 -254
- package/packs/meta/testing.json +172 -172
- package/scripts/postinstall.mjs +531 -531
- package/src/automation/decision-detector.ts +452 -452
- package/src/automation/phase12-manager.ts +456 -456
- package/src/automation/proactive-recall.ts +373 -373
- package/src/automation/project-detector.ts +310 -310
- package/src/automation/repo-scanner.ts +210 -205
- package/src/cli/auto-setup.ts +75 -75
- package/src/cli/auto-start.ts +266 -266
- package/src/cli/bin.ts +264 -264
- package/src/cli/commands/autostart.ts +90 -90
- package/src/cli/commands/chroma.ts +578 -577
- package/src/cli/commands/export-training.ts +70 -70
- package/src/cli/commands/export.ts +130 -130
- package/src/cli/commands/git-hook.ts +183 -183
- package/src/cli/commands/hooks.ts +217 -217
- package/src/cli/commands/init.ts +123 -123
- package/src/cli/commands/install-mcp.ts +122 -111
- package/src/cli/commands/models.ts +979 -979
- package/src/cli/commands/pack.ts +200 -200
- package/src/cli/commands/refresh.ts +344 -339
- package/src/cli/commands/reindex.ts +120 -120
- package/src/cli/commands/serve.ts +466 -463
- package/src/cli/commands/start.ts +44 -44
- package/src/cli/commands/status.ts +220 -203
- package/src/cli/commands/uninstall-mcp.ts +45 -41
- package/src/cli/commands/update.ts +130 -124
- package/src/cli/migrate-chroma.ts +106 -106
- package/src/cli/ui/animations.ts +80 -80
- package/src/cli/ui/components.ts +82 -82
- package/src/cli/ui/index.ts +4 -4
- package/src/cli/ui/logo.ts +36 -36
- package/src/cli/ui/theme.ts +55 -55
- package/src/code-intelligence/indexer.ts +352 -352
- package/src/code-intelligence/linker.ts +178 -178
- package/src/code-intelligence/parser.ts +484 -484
- package/src/code-intelligence/query.ts +291 -291
- package/src/code-intelligence/schema.ts +83 -83
- package/src/code-intelligence/types.ts +95 -95
- package/src/config/defaults.ts +52 -52
- package/src/config/home.ts +56 -56
- package/src/config/index.ts +5 -5
- package/src/config/loader.ts +192 -192
- package/src/config/schema.ts +446 -415
- package/src/config/validator.ts +182 -182
- package/src/context/assembler.ts +407 -400
- package/src/context/index.ts +79 -79
- package/src/context/progress-tracker.ts +174 -174
- package/src/context/standards-manager.ts +287 -287
- package/src/context/validator.ts +58 -58
- package/src/diagnostics/index.ts +122 -121
- package/src/health/index.ts +233 -232
- package/src/hooks/brain-hook.ts +134 -131
- package/src/hooks/capture.ts +168 -168
- package/src/hooks/claude-code-mastery.md +112 -112
- package/src/hooks/context-hook.ts +260 -245
- package/src/hooks/deduplicator.ts +72 -72
- package/src/hooks/git-capture.ts +109 -109
- package/src/hooks/git-hook-installer.ts +211 -207
- package/src/hooks/index.ts +20 -20
- package/src/hooks/installer.ts +306 -288
- package/src/hooks/interceptor-hook.ts +204 -201
- package/src/hooks/passive-classifier.ts +397 -397
- package/src/hooks/queue.ts +160 -129
- package/src/hooks/session-tracker.ts +312 -312
- package/src/hooks/types.ts +52 -52
- package/src/index.ts +7 -7
- package/src/intelligence/cross-project/generalizer.ts +283 -283
- package/src/intelligence/cross-project/index.ts +7 -7
- package/src/intelligence/hf-downloader.ts +222 -222
- package/src/intelligence/hf-manifest.json +78 -78
- package/src/intelligence/index.ts +24 -24
- package/src/intelligence/inference-router.ts +762 -762
- package/src/intelligence/model-manager.ts +263 -245
- package/src/intelligence/optimization/index.ts +10 -10
- package/src/intelligence/optimization/precompute.ts +202 -202
- package/src/intelligence/optimization/semantic-cache.ts +213 -207
- package/src/intelligence/prediction/index.ts +7 -7
- package/src/intelligence/prediction/recommender.ts +276 -268
- package/src/intelligence/reasoning/chain-retrieval.ts +243 -247
- package/src/intelligence/reasoning/index.ts +7 -7
- package/src/intelligence/temporal/evolution.ts +193 -197
- package/src/intelligence/temporal/index.ts +16 -16
- package/src/intelligence/temporal/query-processor.ts +190 -190
- package/src/intelligence/temporal/timeline.ts +272 -259
- package/src/intelligence/temporal/trends.ts +263 -263
- package/src/intelligence/tokenizer.ts +118 -118
- package/src/knowledge/entity-extractor.ts +447 -443
- package/src/knowledge/graph/builder.ts +185 -185
- package/src/knowledge/graph/linker.ts +201 -201
- package/src/knowledge/graph/memory-graph.ts +359 -359
- package/src/knowledge/graph/schema.ts +99 -99
- package/src/knowledge/graph/search.ts +166 -166
- package/src/knowledge/relationship-extractor.ts +108 -108
- package/src/memory/chroma/client.ts +211 -192
- package/src/memory/chroma/collection-manager.ts +92 -92
- package/src/memory/chroma/config.ts +57 -57
- package/src/memory/chroma/embeddings.ts +177 -175
- package/src/memory/chroma/index.ts +82 -82
- package/src/memory/chroma/migration.ts +270 -270
- package/src/memory/chroma/schemas.ts +69 -69
- package/src/memory/chroma/search.ts +319 -315
- package/src/memory/chroma/store.ts +755 -747
- package/src/memory/compression.ts +121 -121
- package/src/memory/consolidation/archiver.ts +162 -165
- package/src/memory/consolidation/merger.ts +182 -186
- package/src/memory/consolidation/scorer.ts +136 -136
- package/src/memory/database.ts +9 -0
- package/src/memory/dual-write.ts +145 -0
- package/src/memory/embeddings.ts +226 -226
- package/src/memory/episodic/detector.ts +108 -108
- package/src/memory/episodic/manager.ts +347 -351
- package/src/memory/episodic/summarizer.ts +179 -179
- package/src/memory/episodic/types.ts +52 -52
- package/src/memory/fts5-search.ts +692 -633
- package/src/memory/index.ts +943 -1060
- package/src/memory/migrations/add-fts5.ts +118 -108
- package/src/memory/patterns.ts +438 -438
- package/src/memory/pruning.ts +60 -60
- package/src/memory/schema.ts +88 -88
- package/src/memory/store.ts +911 -787
- package/src/orchestrator/handlers/decision-handler.ts +204 -204
- package/src/packs/index.ts +9 -9
- package/src/packs/loader.ts +134 -134
- package/src/packs/manager.ts +204 -204
- package/src/packs/ranker.ts +78 -78
- package/src/packs/types.ts +81 -81
- package/src/phase12/index.ts +5 -5
- package/src/retrieval/bm25/index.ts +300 -297
- package/src/retrieval/bm25/tokenizer.ts +184 -184
- package/src/retrieval/feedback/adaptive.ts +221 -221
- package/src/retrieval/feedback/index.ts +16 -16
- package/src/retrieval/feedback/metrics.ts +221 -221
- package/src/retrieval/feedback/store.ts +283 -283
- package/src/retrieval/fusion/index.ts +194 -194
- package/src/retrieval/fusion/rrf.ts +165 -165
- package/src/retrieval/index.ts +12 -12
- package/src/retrieval/pipeline.ts +375 -375
- package/src/retrieval/query/expander.ts +203 -203
- package/src/retrieval/query/index.ts +27 -27
- package/src/retrieval/query/intent-classifier.ts +252 -252
- package/src/retrieval/query/temporal-parser.ts +295 -295
- package/src/retrieval/reranker/index.ts +189 -188
- package/src/retrieval/reranker/model.ts +99 -95
- package/src/retrieval/service.ts +125 -125
- package/src/retrieval/types.ts +162 -162
- package/src/routing/entity-extractor.ts +454 -454
- package/src/routing/handlers/exploration-handler.ts +369 -0
- package/src/routing/handlers/index.ts +19 -0
- package/src/routing/handlers/memory-handler.ts +273 -0
- package/src/routing/handlers/mutation-handler.ts +241 -0
- package/src/routing/handlers/recall-handler.ts +642 -0
- package/src/routing/handlers/shared.ts +515 -0
- package/src/routing/handlers/types.ts +48 -0
- package/src/routing/intent-classifier.ts +552 -552
- package/src/routing/response-filter.ts +399 -391
- package/src/routing/router.ts +245 -2193
- package/src/routing/search-engine.ts +521 -514
- package/src/routing/types.ts +104 -94
- package/src/scripts/health-check.ts +118 -118
- package/src/scripts/setup.ts +122 -122
- package/src/server/auto-updater.ts +283 -276
- package/src/server/handlers/call-tool.ts +159 -159
- package/src/server/handlers/list-tools.ts +35 -35
- package/src/server/handlers/tools/auto-remember.ts +165 -165
- package/src/server/handlers/tools/brain.ts +86 -86
- package/src/server/handlers/tools/create-project.ts +135 -135
- package/src/server/handlers/tools/get-code-standards.ts +123 -123
- package/src/server/handlers/tools/get-corrections.ts +152 -152
- package/src/server/handlers/tools/get-patterns.ts +156 -156
- package/src/server/handlers/tools/get-project-context.ts +75 -75
- package/src/server/handlers/tools/index.ts +30 -30
- package/src/server/handlers/tools/init-project.ts +756 -756
- package/src/server/handlers/tools/list-projects.ts +126 -126
- package/src/server/handlers/tools/recall-similar.ts +87 -87
- package/src/server/handlers/tools/recognize-pattern.ts +132 -132
- package/src/server/handlers/tools/record-correction.ts +131 -131
- package/src/server/handlers/tools/remember-decision.ts +168 -168
- package/src/server/handlers/tools/schemas.ts +179 -179
- package/src/server/handlers/tools/search-code.ts +122 -122
- package/src/server/handlers/tools/smart-context.ts +146 -146
- package/src/server/handlers/tools/update-progress.ts +131 -131
- package/src/server/http-api.ts +215 -1229
- package/src/server/mcp-proxy.ts +85 -84
- package/src/server/mcp-server.ts +285 -284
- package/src/server/middleware/auth.ts +39 -0
- package/src/server/middleware/error-handler.ts +37 -0
- package/src/server/middleware/rate-limit.ts +53 -0
- package/src/server/middleware/validate.ts +42 -0
- package/src/server/pid-manager.ts +137 -136
- package/src/server/providers/resources.ts +581 -581
- package/src/server/routes/code.ts +228 -0
- package/src/server/routes/context.ts +26 -0
- package/src/server/routes/health.ts +19 -0
- package/src/server/routes/helpers.ts +100 -0
- package/src/server/routes/hooks.ts +197 -0
- package/src/server/routes/mcp.ts +47 -0
- package/src/server/routes/memory.ts +397 -0
- package/src/server/routes/models.ts +96 -0
- package/src/server/routes/projects.ts +89 -0
- package/src/server/routes/types.ts +21 -0
- package/src/server/schemas/api-schemas.ts +202 -0
- package/src/server/services.ts +720 -720
- package/src/server/utils/memory-indicator.ts +84 -84
- package/src/server/utils/response-formatter.ts +129 -129
- package/src/server/web-viewer.ts +1145 -1115
- package/src/setup/index.ts +38 -38
- package/src/tools/registry.ts +115 -115
- package/src/tools/schemas.ts +666 -666
- package/src/tools/types.ts +412 -412
- package/src/training/data-store.ts +320 -298
- package/src/training/retrain-pipeline.ts +399 -394
- package/src/utils/error-handler.ts +136 -136
- package/src/utils/index.ts +58 -58
- package/src/utils/kill-port.ts +55 -53
- package/src/utils/phase12-helper.ts +56 -56
- package/src/utils/safe-path.ts +43 -0
- package/src/utils/timing.ts +47 -47
- package/src/utils/transaction.ts +63 -63
- package/src/vault/index.ts +4 -3
- package/src/vault/paths.ts +106 -106
- package/src/vault/query.ts +4 -1
- package/src/vault/reader.ts +44 -1
- package/src/vault/watcher.ts +24 -1
- package/src/vault/writer.ts +487 -413
- package/skills/persistent-memory/SKILL.md +0 -148
- package/skills/persistent-memory/references/tool-reference.md +0 -90
package/src/cli/commands/init.ts
CHANGED
|
@@ -1,123 +1,123 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Init Command
|
|
3
|
-
* Phase 22: Scans a repository and stores initial project context.
|
|
4
|
-
*
|
|
5
|
-
* Usage: claude-brain init [path] [--force]
|
|
6
|
-
*/
|
|
7
|
-
|
|
8
|
-
import path from 'path'
|
|
9
|
-
import { parseArgs } from 'citty'
|
|
10
|
-
import {
|
|
11
|
-
renderLogo, theme, heading, successText, warningText, dimText,
|
|
12
|
-
box, withSpinner,
|
|
13
|
-
} from '@/cli/ui/index.js'
|
|
14
|
-
import { scanRepo } from '@/automation/repo-scanner'
|
|
15
|
-
|
|
16
|
-
export async function runInit() {
|
|
17
|
-
console.log()
|
|
18
|
-
console.log(renderLogo())
|
|
19
|
-
console.log()
|
|
20
|
-
console.log(heading('Initialize Project'))
|
|
21
|
-
console.log()
|
|
22
|
-
|
|
23
|
-
const args = parseArgs(process.argv.slice(3), {
|
|
24
|
-
path: { type: 'positional', required: false, description: 'Path to project directory' },
|
|
25
|
-
force: { type: 'boolean', default: false, description: 'Force re-scan even without project markers' },
|
|
26
|
-
})
|
|
27
|
-
const force = args.force
|
|
28
|
-
const repoPath = path.resolve(args.path || process.cwd())
|
|
29
|
-
|
|
30
|
-
console.log(` ${theme.bold('Path:')} ${dimText(repoPath)}`)
|
|
31
|
-
if (force) {
|
|
32
|
-
console.log(` ${theme.bold('Mode:')} ${dimText('Force re-scan')}`)
|
|
33
|
-
}
|
|
34
|
-
console.log()
|
|
35
|
-
|
|
36
|
-
// Phase 23b: Validate project directory
|
|
37
|
-
const { existsSync: dirExists } = await import('fs')
|
|
38
|
-
const homeDir = process.env.HOME || process.env.USERPROFILE || ''
|
|
39
|
-
if (repoPath === homeDir) {
|
|
40
|
-
console.log(warningText(' This is your home directory — not a project root.'))
|
|
41
|
-
console.log(dimText(' Run this inside a project directory, or pass a path: claude-brain init /path/to/project'))
|
|
42
|
-
console.log()
|
|
43
|
-
return
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
const hasGit = dirExists(path.join(repoPath, '.git'))
|
|
47
|
-
const hasPackageJson = dirExists(path.join(repoPath, 'package.json'))
|
|
48
|
-
const hasCargoToml = dirExists(path.join(repoPath, 'Cargo.toml'))
|
|
49
|
-
const hasPyproject = dirExists(path.join(repoPath, 'pyproject.toml'))
|
|
50
|
-
const hasGoMod = dirExists(path.join(repoPath, 'go.mod'))
|
|
51
|
-
const isProject = hasGit || hasPackageJson || hasCargoToml || hasPyproject || hasGoMod
|
|
52
|
-
|
|
53
|
-
if (!isProject && !force) {
|
|
54
|
-
console.log(warningText(' No project markers found (no .git, package.json, Cargo.toml, etc.)'))
|
|
55
|
-
console.log(dimText(' Use --force to scan anyway, or run inside a project directory.'))
|
|
56
|
-
console.log()
|
|
57
|
-
return
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
// Scan the repo
|
|
61
|
-
const context = await withSpinner('Scanning repository', () => scanRepo(repoPath))
|
|
62
|
-
|
|
63
|
-
if (!context.name) {
|
|
64
|
-
console.log(warningText(' Could not detect project name. Specify a path to a project root.'))
|
|
65
|
-
return
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
// Display results
|
|
69
|
-
console.log(successText(` Project: ${context.name}`))
|
|
70
|
-
|
|
71
|
-
if (context.techStack.length > 0) {
|
|
72
|
-
console.log(` ${theme.bold('Tech stack:')} ${dimText(context.techStack.join(', '))}`)
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
if (context.description) {
|
|
76
|
-
const desc = context.description.split('\n')[0]?.slice(0, 100) || ''
|
|
77
|
-
console.log(` ${theme.bold('Description:')} ${dimText(desc)}`)
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
if (context.recentActivity) {
|
|
81
|
-
const commits = context.recentActivity.split('\n').length
|
|
82
|
-
console.log(` ${theme.bold('Recent commits:')} ${dimText(String(commits))}`)
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
if (context.projectInstructions) {
|
|
86
|
-
console.log(` ${theme.bold('CLAUDE.md:')} ${dimText('found')}`)
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
// Try to store context via brain
|
|
90
|
-
try {
|
|
91
|
-
const summary = [
|
|
92
|
-
`Project "${context.name}" initialized.`,
|
|
93
|
-
context.techStack.length > 0 ? `Tech stack: ${context.techStack.join(', ')}.` : '',
|
|
94
|
-
context.description ? `Description: ${context.description.split('\n')[0]?.slice(0, 200)}` : '',
|
|
95
|
-
context.structure ? `Structure:\n${context.structure.split('\n').slice(0, 15).join('\n')}` : '',
|
|
96
|
-
context.recentActivity ? `Recent git activity:\n${context.recentActivity}` : '',
|
|
97
|
-
context.projectInstructions ? `CLAUDE.md contents:\n${context.projectInstructions.slice(0, 500)}` : ''
|
|
98
|
-
].filter(Boolean).join('\n\n')
|
|
99
|
-
|
|
100
|
-
// Write to a local init file so the MCP server can pick it up
|
|
101
|
-
const { existsSync, mkdirSync } = await import('fs')
|
|
102
|
-
const { writeFileSync } = await import('fs')
|
|
103
|
-
const dataDir = path.join(repoPath, '.claude-brain')
|
|
104
|
-
if (!existsSync(dataDir)) {
|
|
105
|
-
mkdirSync(dataDir, { recursive: true })
|
|
106
|
-
}
|
|
107
|
-
writeFileSync(path.join(dataDir, 'init-context.md'), summary)
|
|
108
|
-
|
|
109
|
-
console.log()
|
|
110
|
-
console.log(successText(` Initial context saved to .claude-brain/init-context.md`))
|
|
111
|
-
} catch (error) {
|
|
112
|
-
console.log(warningText(` Could not save context: ${error instanceof Error ? error.message : 'unknown error'}`))
|
|
113
|
-
}
|
|
114
|
-
|
|
115
|
-
console.log()
|
|
116
|
-
console.log(box([
|
|
117
|
-
heading('Project initialized!'),
|
|
118
|
-
'',
|
|
119
|
-
dimText('Brain will auto-load this context in future sessions.'),
|
|
120
|
-
dimText('Use brain tool to store additional decisions and patterns.'),
|
|
121
|
-
].join('\n'), 'Done'))
|
|
122
|
-
console.log()
|
|
123
|
-
}
|
|
1
|
+
/**
|
|
2
|
+
* Init Command
|
|
3
|
+
* Phase 22: Scans a repository and stores initial project context.
|
|
4
|
+
*
|
|
5
|
+
* Usage: claude-brain init [path] [--force]
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import path from 'path'
|
|
9
|
+
import { parseArgs } from 'citty'
|
|
10
|
+
import {
|
|
11
|
+
renderLogo, theme, heading, successText, warningText, dimText,
|
|
12
|
+
box, withSpinner,
|
|
13
|
+
} from '@/cli/ui/index.js'
|
|
14
|
+
import { scanRepo } from '@/automation/repo-scanner'
|
|
15
|
+
|
|
16
|
+
export async function runInit() {
|
|
17
|
+
console.log()
|
|
18
|
+
console.log(renderLogo())
|
|
19
|
+
console.log()
|
|
20
|
+
console.log(heading('Initialize Project'))
|
|
21
|
+
console.log()
|
|
22
|
+
|
|
23
|
+
const args = parseArgs(process.argv.slice(3), {
|
|
24
|
+
path: { type: 'positional', required: false, description: 'Path to project directory' },
|
|
25
|
+
force: { type: 'boolean', default: false, description: 'Force re-scan even without project markers' },
|
|
26
|
+
})
|
|
27
|
+
const force = args.force
|
|
28
|
+
const repoPath = path.resolve(args.path || process.cwd())
|
|
29
|
+
|
|
30
|
+
console.log(` ${theme.bold('Path:')} ${dimText(repoPath)}`)
|
|
31
|
+
if (force) {
|
|
32
|
+
console.log(` ${theme.bold('Mode:')} ${dimText('Force re-scan')}`)
|
|
33
|
+
}
|
|
34
|
+
console.log()
|
|
35
|
+
|
|
36
|
+
// Phase 23b: Validate project directory
|
|
37
|
+
const { existsSync: dirExists } = await import('fs')
|
|
38
|
+
const homeDir = process.env.HOME || process.env.USERPROFILE || ''
|
|
39
|
+
if (repoPath === homeDir) {
|
|
40
|
+
console.log(warningText(' This is your home directory — not a project root.'))
|
|
41
|
+
console.log(dimText(' Run this inside a project directory, or pass a path: claude-brain init /path/to/project'))
|
|
42
|
+
console.log()
|
|
43
|
+
return
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
const hasGit = dirExists(path.join(repoPath, '.git'))
|
|
47
|
+
const hasPackageJson = dirExists(path.join(repoPath, 'package.json'))
|
|
48
|
+
const hasCargoToml = dirExists(path.join(repoPath, 'Cargo.toml'))
|
|
49
|
+
const hasPyproject = dirExists(path.join(repoPath, 'pyproject.toml'))
|
|
50
|
+
const hasGoMod = dirExists(path.join(repoPath, 'go.mod'))
|
|
51
|
+
const isProject = hasGit || hasPackageJson || hasCargoToml || hasPyproject || hasGoMod
|
|
52
|
+
|
|
53
|
+
if (!isProject && !force) {
|
|
54
|
+
console.log(warningText(' No project markers found (no .git, package.json, Cargo.toml, etc.)'))
|
|
55
|
+
console.log(dimText(' Use --force to scan anyway, or run inside a project directory.'))
|
|
56
|
+
console.log()
|
|
57
|
+
return
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
// Scan the repo
|
|
61
|
+
const context = await withSpinner('Scanning repository', () => scanRepo(repoPath))
|
|
62
|
+
|
|
63
|
+
if (!context.name) {
|
|
64
|
+
console.log(warningText(' Could not detect project name. Specify a path to a project root.'))
|
|
65
|
+
return
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
// Display results
|
|
69
|
+
console.log(successText(` Project: ${context.name}`))
|
|
70
|
+
|
|
71
|
+
if (context.techStack.length > 0) {
|
|
72
|
+
console.log(` ${theme.bold('Tech stack:')} ${dimText(context.techStack.join(', '))}`)
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
if (context.description) {
|
|
76
|
+
const desc = context.description.split('\n')[0]?.slice(0, 100) || ''
|
|
77
|
+
console.log(` ${theme.bold('Description:')} ${dimText(desc)}`)
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
if (context.recentActivity) {
|
|
81
|
+
const commits = context.recentActivity.split('\n').length
|
|
82
|
+
console.log(` ${theme.bold('Recent commits:')} ${dimText(String(commits))}`)
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
if (context.projectInstructions) {
|
|
86
|
+
console.log(` ${theme.bold('CLAUDE.md:')} ${dimText('found')}`)
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
// Try to store context via brain
|
|
90
|
+
try {
|
|
91
|
+
const summary = [
|
|
92
|
+
`Project "${context.name}" initialized.`,
|
|
93
|
+
context.techStack.length > 0 ? `Tech stack: ${context.techStack.join(', ')}.` : '',
|
|
94
|
+
context.description ? `Description: ${context.description.split('\n')[0]?.slice(0, 200)}` : '',
|
|
95
|
+
context.structure ? `Structure:\n${context.structure.split('\n').slice(0, 15).join('\n')}` : '',
|
|
96
|
+
context.recentActivity ? `Recent git activity:\n${context.recentActivity}` : '',
|
|
97
|
+
context.projectInstructions ? `CLAUDE.md contents:\n${context.projectInstructions.slice(0, 500)}` : ''
|
|
98
|
+
].filter(Boolean).join('\n\n')
|
|
99
|
+
|
|
100
|
+
// Write to a local init file so the MCP server can pick it up
|
|
101
|
+
const { existsSync, mkdirSync } = await import('fs')
|
|
102
|
+
const { writeFileSync } = await import('fs')
|
|
103
|
+
const dataDir = path.join(repoPath, '.claude-brain')
|
|
104
|
+
if (!existsSync(dataDir)) {
|
|
105
|
+
mkdirSync(dataDir, { recursive: true })
|
|
106
|
+
}
|
|
107
|
+
writeFileSync(path.join(dataDir, 'init-context.md'), summary)
|
|
108
|
+
|
|
109
|
+
console.log()
|
|
110
|
+
console.log(successText(` Initial context saved to .claude-brain/init-context.md`))
|
|
111
|
+
} catch (error) {
|
|
112
|
+
console.log(warningText(` Could not save context: ${error instanceof Error ? error.message : 'unknown error'}`))
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
console.log()
|
|
116
|
+
console.log(box([
|
|
117
|
+
heading('Project initialized!'),
|
|
118
|
+
'',
|
|
119
|
+
dimText('Brain will auto-load this context in future sessions.'),
|
|
120
|
+
dimText('Use brain tool to store additional decisions and patterns.'),
|
|
121
|
+
].join('\n'), 'Done'))
|
|
122
|
+
console.log()
|
|
123
|
+
}
|
|
@@ -1,111 +1,122 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
renderLogo, theme, heading, successText, warningText, errorText, dimText,
|
|
4
|
-
box, withSpinner,
|
|
5
|
-
} from '@/cli/ui/index.js'
|
|
6
|
-
|
|
7
|
-
function isGloballyInstalled(): boolean {
|
|
8
|
-
const cmd = process.platform === 'win32' ? 'where
|
|
9
|
-
try {
|
|
10
|
-
const result =
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
return false
|
|
14
|
-
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
`
|
|
104
|
-
`
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
` ${theme.
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
}
|
|
1
|
+
import { spawnSync } from 'node:child_process'
|
|
2
|
+
import {
|
|
3
|
+
renderLogo, theme, heading, successText, warningText, errorText, dimText,
|
|
4
|
+
box, withSpinner,
|
|
5
|
+
} from '@/cli/ui/index.js'
|
|
6
|
+
|
|
7
|
+
function isGloballyInstalled(): boolean {
|
|
8
|
+
const cmd = process.platform === 'win32' ? 'where' : 'which'
|
|
9
|
+
try {
|
|
10
|
+
const result = spawnSync(cmd, ['claude-brain'], {
|
|
11
|
+
encoding: 'utf-8', stdio: ['pipe', 'pipe', 'pipe'], timeout: 5000,
|
|
12
|
+
})
|
|
13
|
+
if (result.error || result.status !== 0) return false
|
|
14
|
+
return (result.stdout?.trim() || '').length > 0
|
|
15
|
+
} catch {
|
|
16
|
+
return false
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
function isMcpAlreadyConfigured(): boolean {
|
|
21
|
+
try {
|
|
22
|
+
const result = spawnSync('claude', ['mcp', 'list'], {
|
|
23
|
+
encoding: 'utf-8', stdio: ['pipe', 'pipe', 'pipe'], timeout: 10_000,
|
|
24
|
+
})
|
|
25
|
+
if (result.error || result.status !== 0) return false
|
|
26
|
+
return (result.stdout || '').includes('claude-brain')
|
|
27
|
+
} catch {
|
|
28
|
+
return false
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export async function runInstall() {
|
|
33
|
+
console.log()
|
|
34
|
+
console.log(renderLogo())
|
|
35
|
+
console.log()
|
|
36
|
+
console.log(heading('MCP Installation'))
|
|
37
|
+
console.log()
|
|
38
|
+
|
|
39
|
+
const installed = isGloballyInstalled()
|
|
40
|
+
|
|
41
|
+
if (installed) {
|
|
42
|
+
console.log(successText('claude-brain is globally installed'))
|
|
43
|
+
console.log()
|
|
44
|
+
|
|
45
|
+
if (isMcpAlreadyConfigured()) {
|
|
46
|
+
// Ensure user scope — remove local/project scope if present, then register at user scope
|
|
47
|
+
for (const scope of ['local', 'project']) {
|
|
48
|
+
spawnSync('claude', ['mcp', 'remove', 'claude-brain', '-s', scope], {
|
|
49
|
+
encoding: 'utf-8',
|
|
50
|
+
stdio: ['pipe', 'pipe', 'pipe'],
|
|
51
|
+
timeout: 10_000,
|
|
52
|
+
})
|
|
53
|
+
// OK — may not exist at this scope
|
|
54
|
+
}
|
|
55
|
+
spawnSync('claude', ['mcp', 'add', 'claude-brain', '-s', 'user', '--', 'claude-brain', 'serve'], {
|
|
56
|
+
encoding: 'utf-8',
|
|
57
|
+
stdio: ['pipe', 'pipe', 'pipe'],
|
|
58
|
+
timeout: 10_000,
|
|
59
|
+
})
|
|
60
|
+
// OK — may already be registered at user scope
|
|
61
|
+
console.log(box(successText('MCP registered at user scope. Claude Brain is available in all projects.'), 'Success'))
|
|
62
|
+
} else {
|
|
63
|
+
try {
|
|
64
|
+
await withSpinner('Registering with Claude Code', async () => {
|
|
65
|
+
const result = spawnSync('claude', ['mcp', 'add', 'claude-brain', '-s', 'user', '--', 'claude-brain', 'serve'], {
|
|
66
|
+
encoding: 'utf-8',
|
|
67
|
+
stdio: ['pipe', 'pipe', 'pipe'],
|
|
68
|
+
timeout: 10_000,
|
|
69
|
+
})
|
|
70
|
+
if (result.error || result.status !== 0) {
|
|
71
|
+
const msg = result.stderr || ''
|
|
72
|
+
if (msg.includes('already') || msg.includes('exists')) {
|
|
73
|
+
// Already registered — not an error
|
|
74
|
+
return
|
|
75
|
+
}
|
|
76
|
+
throw new Error(msg || 'Registration failed')
|
|
77
|
+
}
|
|
78
|
+
})
|
|
79
|
+
console.log()
|
|
80
|
+
console.log(box(successText('Claude Brain registered as MCP server in Claude Code.'), 'Success'))
|
|
81
|
+
} catch (err) {
|
|
82
|
+
const errorMsg = err instanceof Error ? err.message : String(err)
|
|
83
|
+
if (errorMsg.includes('already') || errorMsg.includes('exists')) {
|
|
84
|
+
console.log()
|
|
85
|
+
console.log(box(successText('Already MCP configured. Claude Brain is registered as an MCP server.'), 'Success'))
|
|
86
|
+
} else {
|
|
87
|
+
console.log()
|
|
88
|
+
console.log(box([
|
|
89
|
+
errorText('Failed to register automatically.'),
|
|
90
|
+
'',
|
|
91
|
+
dimText('Run manually:'),
|
|
92
|
+
` ${theme.bold('claude mcp add claude-brain -s user -- claude-brain serve')}`,
|
|
93
|
+
].join('\n'), 'Error'))
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
} else {
|
|
98
|
+
console.log(warningText('claude-brain is not globally installed'))
|
|
99
|
+
console.log()
|
|
100
|
+
|
|
101
|
+
console.log(box([
|
|
102
|
+
`${theme.primary('Option 1:')} Install globally, then register`,
|
|
103
|
+
` ${theme.bold('bun install -g claude-brain')}`,
|
|
104
|
+
` ${theme.bold('claude mcp add claude-brain -s user -- claude-brain serve')}`,
|
|
105
|
+
'',
|
|
106
|
+
`${theme.primary('Option 2:')} Use bunx ${dimText('(zero-install)')}`,
|
|
107
|
+
` ${theme.bold('claude mcp add claude-brain -s user -- bunx claude-brain@latest')}`,
|
|
108
|
+
'',
|
|
109
|
+
`${theme.primary('Option 3:')} Add to Claude Code config manually`,
|
|
110
|
+
dimText(' Add to your Claude Code MCP settings:'),
|
|
111
|
+
` ${theme.dim('{')}`,
|
|
112
|
+
` ${theme.dim('"mcpServers": {')}`,
|
|
113
|
+
` ${theme.dim('"claude-brain": {')}`,
|
|
114
|
+
` ${theme.dim('"command": "bunx",')}`,
|
|
115
|
+
` ${theme.dim('"args": ["claude-brain@latest"]')}`,
|
|
116
|
+
` ${theme.dim('}')}`,
|
|
117
|
+
` ${theme.dim('}')}`,
|
|
118
|
+
` ${theme.dim('}')}`,
|
|
119
|
+
].join('\n'), 'Install Options'))
|
|
120
|
+
}
|
|
121
|
+
console.log()
|
|
122
|
+
}
|