claude-brain 0.17.13 → 0.22.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.
Files changed (46) hide show
  1. package/VERSION +1 -1
  2. package/package.json +3 -1
  3. package/scripts/postinstall.mjs +80 -104
  4. package/src/cli/auto-setup.ts +1 -9
  5. package/src/cli/bin.ts +23 -2
  6. package/src/cli/commands/export.ts +130 -0
  7. package/src/cli/commands/reindex.ts +107 -0
  8. package/src/cli/commands/serve.ts +54 -0
  9. package/src/cli/commands/status.ts +158 -0
  10. package/src/code-intelligence/indexer.ts +315 -0
  11. package/src/code-intelligence/linker.ts +178 -0
  12. package/src/code-intelligence/parser.ts +484 -0
  13. package/src/code-intelligence/query.ts +291 -0
  14. package/src/code-intelligence/schema.ts +83 -0
  15. package/src/code-intelligence/types.ts +95 -0
  16. package/src/config/defaults.ts +3 -3
  17. package/src/config/loader.ts +6 -0
  18. package/src/config/schema.ts +28 -2
  19. package/src/health/index.ts +5 -2
  20. package/src/hooks/brain-hook.ts +4 -1
  21. package/src/hooks/context-hook.ts +69 -10
  22. package/src/hooks/installer.ts +4 -7
  23. package/src/intelligence/cross-project/index.ts +1 -7
  24. package/src/intelligence/prediction/index.ts +1 -7
  25. package/src/intelligence/reasoning/index.ts +1 -7
  26. package/src/memory/compression.ts +105 -0
  27. package/src/memory/fts5-search.ts +456 -0
  28. package/src/memory/index.ts +342 -38
  29. package/src/memory/migrations/add-fts5.ts +98 -0
  30. package/src/memory/pruning.ts +60 -0
  31. package/src/routing/intent-classifier.ts +58 -1
  32. package/src/routing/response-filter.ts +128 -0
  33. package/src/routing/router.ts +457 -54
  34. package/src/server/http-api.ts +319 -1
  35. package/src/server/providers/resources.ts +1 -42
  36. package/src/server/services.ts +113 -12
  37. package/src/server/web-viewer.ts +1115 -0
  38. package/src/setup/index.ts +12 -22
  39. package/src/tools/schemas.ts +1 -1
  40. package/src/intelligence/cross-project/affinity.ts +0 -159
  41. package/src/intelligence/cross-project/transfer.ts +0 -201
  42. package/src/intelligence/prediction/context-anticipator.ts +0 -198
  43. package/src/intelligence/prediction/decision-predictor.ts +0 -184
  44. package/src/intelligence/reasoning/counterfactual.ts +0 -248
  45. package/src/intelligence/reasoning/synthesizer.ts +0 -167
  46. package/src/setup/wizard.ts +0 -459
@@ -1,459 +0,0 @@
1
- import prompts from 'prompts'
2
- import fs from 'fs/promises'
3
- import { existsSync } from 'fs'
4
- import { execSync } from 'child_process'
5
- import path from 'path'
6
- import os from 'os'
7
- import { fileURLToPath } from 'url'
8
- import type { Logger } from 'pino'
9
- import { getHomePaths } from '@/config/home'
10
- import {
11
- theme, heading, successText, errorText, warningText, dimText,
12
- box, stepIndicator, summaryPanel,
13
- withSpinner, transition,
14
- } from '@/cli/ui/index.js'
15
-
16
- const __filename = fileURLToPath(import.meta.url)
17
- const __dirname = path.dirname(__filename)
18
- // Package root is two levels up from src/setup/
19
- const PACKAGE_ROOT = path.resolve(__dirname, '..', '..')
20
-
21
- export interface SetupAnswers {
22
- vaultPath: string
23
- logLevel: string
24
- enableFileWatch: boolean
25
- enableChromaDB: boolean
26
- createSampleProject: boolean
27
- installClaudeMd: boolean
28
- }
29
-
30
- export class SetupWizard {
31
- constructor(_logger: Logger) {
32
- // Logger available for future use
33
- }
34
-
35
- async run(): Promise<SetupAnswers> {
36
- // Step 1: Detect Vaults
37
- console.log(stepIndicator(1, 6, 'Detecting Obsidian Vaults'))
38
- await transition()
39
-
40
- const suggestedPaths = await withSpinner('Scanning for Obsidian vaults', () =>
41
- this.detectVaultLocations()
42
- )
43
-
44
- if (suggestedPaths.length > 0) {
45
- console.log(successText(`Found ${suggestedPaths.length} vault${suggestedPaths.length > 1 ? 's' : ''}`))
46
- } else {
47
- console.log(warningText('No vaults auto-detected — enter path manually'))
48
- }
49
- console.log()
50
-
51
- // Step 2: Vault Configuration
52
- console.log(stepIndicator(2, 6, 'Vault Configuration'))
53
- await transition()
54
-
55
- const vaultAnswers = await prompts([
56
- {
57
- type: 'select',
58
- name: 'vaultPathChoice',
59
- message: 'Where is your Obsidian vault?',
60
- choices: [
61
- ...suggestedPaths.map(p => ({ title: p, value: p })),
62
- { title: 'Enter custom path', value: 'custom' }
63
- ],
64
- initial: 0
65
- },
66
- {
67
- type: (prev) => prev === 'custom' ? 'text' : null,
68
- name: 'vaultPath',
69
- message: 'Enter vault path:',
70
- validate: async (value: string) => {
71
- try {
72
- const stat = await fs.stat(value)
73
- return stat.isDirectory() || 'Path must be a directory'
74
- } catch {
75
- return 'Path does not exist'
76
- }
77
- }
78
- },
79
- ])
80
-
81
- if (!vaultAnswers.vaultPathChoice) {
82
- console.log('\n' + errorText('Setup cancelled.'))
83
- process.exit(0)
84
- }
85
-
86
- const finalVaultPath = vaultAnswers.vaultPath || vaultAnswers.vaultPathChoice
87
-
88
- // Step 3: Logging
89
- console.log(stepIndicator(3, 6, 'Logging Configuration'))
90
- await transition()
91
-
92
- const loggingAnswers = await prompts({
93
- type: 'select',
94
- name: 'logLevel',
95
- message: 'Select log level:',
96
- choices: [
97
- { title: 'Error (production)', value: 'error' },
98
- { title: 'Warn (recommended)', value: 'warn' },
99
- { title: 'Info', value: 'info' },
100
- { title: 'Debug (verbose)', value: 'debug' }
101
- ],
102
- initial: 1
103
- })
104
-
105
- // Step 4: Features
106
- console.log(stepIndicator(4, 6, 'Feature Selection'))
107
- await transition()
108
-
109
- const featureAnswers = await prompts([
110
- {
111
- type: 'confirm',
112
- name: 'enableFileWatch',
113
- message: 'Enable automatic file watching?',
114
- initial: true
115
- },
116
- {
117
- type: 'confirm',
118
- name: 'createSampleProject',
119
- message: 'Create a sample project to test with?',
120
- initial: true
121
- },
122
- {
123
- type: 'confirm',
124
- name: 'installClaudeMd',
125
- message: 'Install CLAUDE.md protocol file to ~/.claude/CLAUDE.md?',
126
- initial: true
127
- }
128
- ])
129
-
130
- // Step 5: ChromaDB
131
- console.log(stepIndicator(5, 6, 'ChromaDB (Vector Database)'))
132
- await transition()
133
-
134
- console.log(dimText('ChromaDB enables semantic search, knowledge graph,'))
135
- console.log(dimText('and advanced intelligence features. Requires Python 3.'))
136
- console.log()
137
-
138
- const chromaInstalled = this.isChromaInstalled()
139
- if (chromaInstalled) {
140
- console.log(successText('ChromaDB CLI detected'))
141
- } else {
142
- console.log(warningText('ChromaDB CLI not found — you can install it later'))
143
- }
144
- console.log()
145
-
146
- const chromaAnswers = await prompts({
147
- type: 'confirm',
148
- name: 'enableChromaDB',
149
- message: chromaInstalled
150
- ? 'Enable ChromaDB for advanced features?'
151
- : 'Enable ChromaDB? (install later: pip install chromadb)',
152
- initial: chromaInstalled
153
- })
154
-
155
- // Step 6: Review
156
- console.log(stepIndicator(6, 6, 'Review Configuration'))
157
- await transition()
158
-
159
- const answers: SetupAnswers = {
160
- vaultPath: finalVaultPath,
161
- logLevel: loggingAnswers.logLevel ?? 'warn',
162
- enableFileWatch: featureAnswers.enableFileWatch ?? true,
163
- enableChromaDB: chromaAnswers.enableChromaDB ?? false,
164
- createSampleProject: featureAnswers.createSampleProject ?? true,
165
- installClaudeMd: featureAnswers.installClaudeMd ?? true,
166
- }
167
-
168
- console.log(summaryPanel('Configuration Summary', [
169
- { label: 'Vault Path', value: answers.vaultPath, status: 'success' },
170
- { label: 'Log Level', value: answers.logLevel, status: 'info' },
171
- { label: 'File Watching', value: answers.enableFileWatch ? 'Enabled' : 'Disabled', status: answers.enableFileWatch ? 'success' : 'warning' },
172
- { label: 'ChromaDB', value: answers.enableChromaDB ? 'Enabled' : 'Disabled', status: answers.enableChromaDB ? 'success' : 'warning' },
173
- { label: 'Sample Project', value: answers.createSampleProject ? 'Yes' : 'No', status: 'info' },
174
- { label: 'Install CLAUDE.md', value: answers.installClaudeMd ? 'Yes' : 'No', status: 'info' },
175
- ]))
176
- console.log()
177
-
178
- const { confirm } = await prompts({
179
- type: 'confirm',
180
- name: 'confirm',
181
- message: 'Apply this configuration?',
182
- initial: true
183
- })
184
-
185
- if (!confirm) {
186
- console.log('\n' + errorText('Setup cancelled.'))
187
- process.exit(0)
188
- }
189
-
190
- return answers
191
- }
192
-
193
- private async detectVaultLocations(): Promise<string[]> {
194
- const locations: string[] = []
195
- const home = os.homedir()
196
- const homePaths = getHomePaths()
197
-
198
- const commonPaths = [
199
- homePaths.vault,
200
- path.join(home, 'Documents', 'Obsidian'),
201
- path.join(home, 'Obsidian'),
202
- path.join(home, 'vault'),
203
- path.join(home, 'Documents', 'vault'),
204
- path.join(home, 'iCloud', 'Obsidian'),
205
- path.join(home, 'Library', 'Mobile Documents', 'iCloud~md~obsidian', 'Documents')
206
- ]
207
-
208
- for (const loc of commonPaths) {
209
- try {
210
- const stat = await fs.stat(loc)
211
- if (stat.isDirectory()) {
212
- locations.push(loc)
213
- }
214
- } catch {
215
- }
216
- }
217
-
218
- return locations
219
- }
220
-
221
- private isChromaInstalled(): boolean {
222
- try {
223
- execSync('chroma --version', { stdio: 'pipe', timeout: 5000 })
224
- return true
225
- } catch {
226
- return false
227
- }
228
- }
229
-
230
- async applyConfiguration(answers: SetupAnswers): Promise<void> {
231
- console.log('\n' + heading('Applying configuration...') + '\n')
232
-
233
- const homePaths = getHomePaths()
234
-
235
- const chromaEnvLines = answers.enableChromaDB
236
- ? [
237
- '',
238
- '# ChromaDB Configuration',
239
- 'CHROMA_MODE=client-server',
240
- 'CHROMA_HOST=localhost',
241
- 'CHROMA_PORT=8000',
242
- 'CHROMA_EMBEDDING_PROVIDER=transformers',
243
- ].join('\n')
244
- : ''
245
-
246
- const envContent = `# Claude Brain Configuration
247
- VAULT_PATH=${answers.vaultPath}
248
- LOG_LEVEL=${answers.logLevel}
249
- ENABLE_FILE_WATCH=${answers.enableFileWatch}
250
- DB_PATH=./data/memory.db
251
- LOG_FILE_PATH=./logs/claude-brain.log
252
- SERVER_NAME=claude-brain
253
- ${chromaEnvLines}
254
- `
255
-
256
- await withSpinner('Writing .env configuration', async () => {
257
- await fs.writeFile(homePaths.env, envContent, 'utf-8')
258
- })
259
-
260
- await withSpinner('Creating data and log directories', async () => {
261
- await fs.mkdir(homePaths.data, { recursive: true })
262
- await fs.mkdir(homePaths.chroma, { recursive: true })
263
- await fs.mkdir(homePaths.logs, { recursive: true })
264
- })
265
-
266
- if (answers.createSampleProject) {
267
- await withSpinner('Creating sample project in vault', async () => {
268
- await this.createSampleProject(answers.vaultPath)
269
- })
270
- }
271
-
272
- if (answers.installClaudeMd) {
273
- const shouldInstall = await this.confirmClaudeMdInstall()
274
- if (shouldInstall) {
275
- await withSpinner('Installing CLAUDE.md', async () => {
276
- await this.copyClaudeMd()
277
- })
278
- }
279
- }
280
-
281
- const nextSteps: string[] = [
282
- heading('Setup complete!'),
283
- '',
284
- dimText('Next steps:'),
285
- ` ${theme.primary('1.')} ${theme.bold('claude-brain install')}`,
286
- ` ${dimText('Register as MCP server')}`,
287
- ]
288
-
289
- if (answers.enableChromaDB) {
290
- nextSteps.push(
291
- ` ${theme.primary('2.')} ${theme.bold('claude-brain chroma install')}`,
292
- ` ${dimText('Install ChromaDB (if not already installed)')}`,
293
- ` ${theme.primary('3.')} ${theme.bold('claude-brain chroma start')}`,
294
- ` ${dimText('Start the ChromaDB server')}`,
295
- ` ${theme.primary('4.')} ${theme.bold('claude-brain health')}`,
296
- ` ${dimText('Verify everything works')}`,
297
- )
298
- } else {
299
- nextSteps.push(
300
- ` ${theme.primary('2.')} ${theme.bold('claude-brain health')}`,
301
- ` ${dimText('Verify everything works')}`,
302
- '',
303
- dimText('Optional: Enable ChromaDB later for advanced features:'),
304
- ` ${dimText('claude-brain chroma install && claude-brain chroma start')}`,
305
- )
306
- }
307
-
308
- console.log()
309
- console.log(box(nextSteps.join('\n'), 'Done'))
310
- console.log()
311
- }
312
-
313
- private async confirmClaudeMdInstall(): Promise<boolean> {
314
- const sourcePath = path.join(PACKAGE_ROOT, 'assets', 'CLAUDE.md')
315
- const destPath = path.join(os.homedir(), '.claude', 'CLAUDE.md')
316
-
317
- if (!existsSync(sourcePath)) {
318
- console.log(warningText('CLAUDE.md asset not found, skipping'))
319
- return false
320
- }
321
-
322
- if (existsSync(destPath)) {
323
- const { overwrite } = await prompts({
324
- type: 'confirm',
325
- name: 'overwrite',
326
- message: '~/.claude/CLAUDE.md already exists. Overwrite?',
327
- initial: false,
328
- })
329
- if (!overwrite) {
330
- console.log(dimText(' Skipped CLAUDE.md installation'))
331
- return false
332
- }
333
- }
334
-
335
- return true
336
- }
337
-
338
- private async copyClaudeMd(): Promise<void> {
339
- const sourcePath = path.join(PACKAGE_ROOT, 'assets', 'CLAUDE.md')
340
- const claudeDir = path.join(os.homedir(), '.claude')
341
- const destPath = path.join(claudeDir, 'CLAUDE.md')
342
- await fs.mkdir(claudeDir, { recursive: true })
343
- await fs.copyFile(sourcePath, destPath)
344
- }
345
-
346
- private async createSampleProject(vaultPath: string): Promise<void> {
347
- const projectPath = path.join(vaultPath, 'Projects', 'sample-project')
348
-
349
- await fs.mkdir(projectPath, { recursive: true })
350
-
351
- await fs.writeFile(
352
- path.join(projectPath, 'context.md'),
353
- `---
354
- type: project-context
355
- project: sample-project
356
- status: active
357
- created: ${new Date().toISOString().split('T')[0]}
358
- updated: ${new Date().toISOString().split('T')[0]}
359
- tech_stack:
360
- - TypeScript
361
- - Node.js
362
- tags:
363
- - sample
364
- ---
365
-
366
- # Sample Project
367
-
368
- ## Overview
369
- This is a sample project created by Claude Brain setup wizard.
370
-
371
- ## Tech Stack
372
- - TypeScript
373
- - Node.js
374
- - Bun
375
-
376
- ## Goals
377
- - Test Claude Brain integration
378
- - Learn the workflow
379
- `,
380
- 'utf-8'
381
- )
382
-
383
- await fs.writeFile(
384
- path.join(projectPath, 'progress.md'),
385
- `---
386
- type: progress-tracker
387
- project: sample-project
388
- status: in-progress
389
- current_phase: setup
390
- completion_percentage: 0
391
- ---
392
-
393
- # Progress
394
-
395
- ## Next Steps
396
- - [ ] Configure Claude Brain
397
- - [ ] Test MCP integration
398
- - [ ] Try all tools
399
- `,
400
- 'utf-8'
401
- )
402
-
403
- await fs.writeFile(
404
- path.join(projectPath, 'decisions.md'),
405
- `---
406
- type: decision-log
407
- project: sample-project
408
- decision_count: 0
409
- ---
410
-
411
- # Decision Log
412
-
413
- This file will track important decisions for the project.
414
- `,
415
- 'utf-8'
416
- )
417
-
418
- await fs.writeFile(
419
- path.join(projectPath, 'standards.md'),
420
- `---
421
- type: coding-standards
422
- project: sample-project
423
- ---
424
-
425
- # Coding Standards
426
-
427
- ## TypeScript
428
- - Use strict mode
429
- - Prefer const over let
430
- `,
431
- 'utf-8'
432
- )
433
-
434
- const globalPath = path.join(vaultPath, 'Global')
435
- await fs.mkdir(globalPath, { recursive: true })
436
-
437
- const globalStandardsPath = path.join(globalPath, 'standards.md')
438
- try {
439
- await fs.access(globalStandardsPath)
440
- } catch {
441
- await fs.writeFile(
442
- globalStandardsPath,
443
- `---
444
- type: global-standards
445
- last_updated: ${new Date().toISOString().split('T')[0]}
446
- ---
447
-
448
- # Global Coding Standards
449
-
450
- ## TypeScript
451
- - Use strict mode
452
- - Prefer const over let
453
- - Add JSDoc comments for public APIs
454
- `,
455
- 'utf-8'
456
- )
457
- }
458
- }
459
- }