claude-brain 0.14.2 → 0.14.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/README.md +191 -191
- package/VERSION +1 -1
- package/assets/CLAUDE-unified.md +11 -11
- package/assets/CLAUDE.md +11 -11
- package/bunfig.toml +8 -8
- package/package.json +80 -80
- 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/src/automation/auto-context.ts +240 -240
- package/src/automation/decision-detector.ts +452 -452
- package/src/automation/index.ts +11 -11
- 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 +205 -205
- package/src/cli/auto-setup.ts +82 -82
- package/src/cli/bin.ts +202 -202
- package/src/cli/commands/chroma.ts +573 -573
- package/src/cli/commands/git-hook.ts +189 -189
- package/src/cli/commands/hooks.ts +213 -213
- package/src/cli/commands/init.ts +122 -122
- package/src/cli/commands/install-mcp.ts +92 -92
- package/src/cli/commands/pack.ts +197 -197
- package/src/cli/commands/serve.ts +167 -167
- package/src/cli/commands/start.ts +42 -42
- package/src/cli/commands/uninstall-mcp.ts +41 -41
- package/src/cli/commands/update.ts +121 -121
- package/src/cli/diagnose.ts +4 -4
- package/src/cli/health-check.ts +4 -4
- package/src/cli/migrate-chroma.ts +106 -106
- package/src/cli/setup.ts +4 -4
- 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/config/defaults.ts +50 -50
- package/src/config/home.ts +55 -55
- package/src/config/index.ts +7 -7
- package/src/config/loader.ts +166 -166
- package/src/config/migration.ts +76 -76
- package/src/config/schema.ts +360 -360
- package/src/config/validator.ts +184 -184
- package/src/config/watcher.ts +86 -86
- package/src/context/assembler.ts +398 -398
- package/src/context/cache-manager.ts +101 -101
- package/src/context/formatter.ts +84 -84
- package/src/context/hierarchy.ts +85 -85
- package/src/context/index.ts +83 -83
- package/src/context/progress-tracker.ts +174 -174
- package/src/context/standards-manager.ts +287 -287
- package/src/context/types.ts +252 -252
- package/src/context/validator.ts +58 -58
- package/src/diagnostics/index.ts +123 -123
- package/src/health/index.ts +229 -229
- package/src/hooks/brain-hook.ts +112 -112
- package/src/hooks/capture.ts +168 -168
- package/src/hooks/deduplicator.ts +72 -72
- package/src/hooks/git-capture.ts +109 -109
- package/src/hooks/git-hook-installer.ts +207 -207
- package/src/hooks/index.ts +20 -20
- package/src/hooks/installer.ts +191 -194
- package/src/hooks/passive-classifier.ts +366 -366
- package/src/hooks/queue.ts +129 -129
- package/src/hooks/session-tracker.ts +275 -275
- package/src/hooks/types.ts +47 -47
- package/src/index.ts +7 -7
- package/src/intelligence/cross-project/affinity.ts +162 -162
- package/src/intelligence/cross-project/generalizer.ts +283 -283
- package/src/intelligence/cross-project/index.ts +13 -13
- package/src/intelligence/cross-project/transfer.ts +201 -201
- package/src/intelligence/index.ts +24 -24
- package/src/intelligence/optimization/index.ts +10 -10
- package/src/intelligence/optimization/precompute.ts +202 -202
- package/src/intelligence/optimization/semantic-cache.ts +207 -207
- package/src/intelligence/prediction/context-anticipator.ts +198 -198
- package/src/intelligence/prediction/decision-predictor.ts +184 -184
- package/src/intelligence/prediction/index.ts +13 -13
- package/src/intelligence/prediction/recommender.ts +268 -268
- package/src/intelligence/reasoning/chain-retrieval.ts +247 -247
- package/src/intelligence/reasoning/counterfactual.ts +248 -248
- package/src/intelligence/reasoning/index.ts +13 -13
- package/src/intelligence/reasoning/synthesizer.ts +169 -169
- package/src/intelligence/temporal/evolution.ts +197 -197
- package/src/intelligence/temporal/index.ts +16 -16
- package/src/intelligence/temporal/query-processor.ts +190 -190
- package/src/intelligence/temporal/timeline.ts +259 -259
- package/src/intelligence/temporal/trends.ts +263 -263
- package/src/knowledge/entity-extractor.ts +416 -416
- 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 +168 -168
- package/src/knowledge/relationship-extractor.ts +108 -108
- package/src/memory/chroma/client.ts +174 -174
- package/src/memory/chroma/collection-manager.ts +94 -94
- package/src/memory/chroma/config.ts +57 -57
- package/src/memory/chroma/embeddings.ts +153 -153
- 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 +315 -315
- package/src/memory/chroma/store.ts +741 -741
- package/src/memory/consolidation/archiver.ts +164 -164
- package/src/memory/consolidation/merger.ts +186 -186
- package/src/memory/consolidation/scorer.ts +138 -138
- package/src/memory/context-builder.ts +236 -236
- package/src/memory/database.ts +169 -169
- package/src/memory/embedding-utils.ts +156 -156
- package/src/memory/embeddings.ts +226 -226
- package/src/memory/episodic/detector.ts +108 -108
- package/src/memory/episodic/manager.ts +351 -351
- package/src/memory/episodic/summarizer.ts +179 -179
- package/src/memory/episodic/types.ts +52 -52
- package/src/memory/index.ts +582 -582
- package/src/memory/knowledge-extractor.ts +455 -455
- package/src/memory/learning.ts +378 -378
- package/src/memory/patterns.ts +396 -396
- package/src/memory/schema.ts +88 -88
- package/src/memory/search.ts +309 -309
- package/src/memory/store.ts +787 -787
- package/src/memory/types.ts +121 -121
- package/src/orchestrator/coordinator.ts +272 -272
- package/src/orchestrator/decision-logger.ts +228 -228
- package/src/orchestrator/event-emitter.ts +198 -198
- package/src/orchestrator/event-queue.ts +184 -184
- package/src/orchestrator/handlers/base-handler.ts +70 -70
- package/src/orchestrator/handlers/context-handler.ts +73 -73
- package/src/orchestrator/handlers/decision-handler.ts +204 -204
- package/src/orchestrator/handlers/index.ts +10 -10
- package/src/orchestrator/handlers/status-handler.ts +131 -131
- package/src/orchestrator/handlers/task-handler.ts +171 -171
- package/src/orchestrator/index.ts +275 -275
- package/src/orchestrator/task-parser.ts +284 -284
- package/src/orchestrator/types.ts +98 -98
- 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 -300
- package/src/retrieval/bm25/tokenizer.ts +184 -184
- package/src/retrieval/feedback/adaptive.ts +223 -223
- package/src/retrieval/feedback/index.ts +16 -16
- package/src/retrieval/feedback/metrics.ts +223 -223
- package/src/retrieval/feedback/store.ts +283 -283
- package/src/retrieval/fusion/index.ts +194 -194
- package/src/retrieval/fusion/rrf.ts +163 -163
- package/src/retrieval/index.ts +12 -12
- package/src/retrieval/pipeline.ts +375 -375
- package/src/retrieval/query/expander.ts +198 -198
- package/src/retrieval/query/index.ts +27 -27
- package/src/retrieval/query/intent-classifier.ts +236 -236
- package/src/retrieval/query/temporal-parser.ts +295 -295
- package/src/retrieval/reranker/index.ts +188 -188
- package/src/retrieval/reranker/model.ts +95 -95
- package/src/retrieval/service.ts +125 -125
- package/src/retrieval/types.ts +162 -162
- package/src/routing/entity-extractor.ts +428 -428
- package/src/routing/intent-classifier.ts +436 -436
- package/src/routing/response-filter.ts +258 -254
- package/src/routing/router.ts +1322 -1314
- package/src/routing/search-engine.ts +475 -475
- package/src/routing/types.ts +94 -84
- package/src/scripts/health-check.ts +118 -118
- package/src/scripts/setup.ts +122 -122
- package/src/server/handlers/call-tool.ts +156 -156
- package/src/server/handlers/index.ts +9 -9
- package/src/server/handlers/list-tools.ts +35 -35
- package/src/server/handlers/tools/analyze-decision-evolution.ts +151 -151
- package/src/server/handlers/tools/auto-remember.ts +200 -200
- package/src/server/handlers/tools/brain.ts +85 -85
- package/src/server/handlers/tools/create-project.ts +135 -135
- package/src/server/handlers/tools/detect-trends.ts +144 -144
- package/src/server/handlers/tools/find-cross-project-patterns.ts +168 -168
- package/src/server/handlers/tools/get-activity-log.ts +194 -194
- package/src/server/handlers/tools/get-code-standards.ts +124 -124
- package/src/server/handlers/tools/get-corrections.ts +154 -154
- package/src/server/handlers/tools/get-decision-timeline.ts +172 -172
- package/src/server/handlers/tools/get-episode.ts +103 -103
- package/src/server/handlers/tools/get-patterns.ts +158 -158
- package/src/server/handlers/tools/get-phase12-status.ts +63 -63
- package/src/server/handlers/tools/get-project-context.ts +75 -75
- package/src/server/handlers/tools/get-recommendations.ts +145 -145
- package/src/server/handlers/tools/index.ts +31 -31
- package/src/server/handlers/tools/init-project.ts +757 -757
- package/src/server/handlers/tools/list-episodes.ts +90 -90
- package/src/server/handlers/tools/list-projects.ts +125 -125
- package/src/server/handlers/tools/rate-memory.ts +101 -101
- package/src/server/handlers/tools/recall-similar.ts +87 -87
- package/src/server/handlers/tools/recognize-pattern.ts +126 -126
- package/src/server/handlers/tools/record-correction.ts +125 -125
- package/src/server/handlers/tools/remember-decision.ts +153 -153
- package/src/server/handlers/tools/schemas.ts +253 -253
- package/src/server/handlers/tools/search-knowledge-graph.ts +102 -102
- package/src/server/handlers/tools/smart-context.ts +146 -146
- package/src/server/handlers/tools/update-progress.ts +131 -131
- package/src/server/handlers/tools/what-if-analysis.ts +135 -135
- package/src/server/http-api.ts +693 -693
- package/src/server/index.ts +40 -40
- package/src/server/mcp-server.ts +283 -283
- package/src/server/providers/index.ts +7 -7
- package/src/server/providers/prompts.ts +327 -327
- package/src/server/providers/resources.ts +622 -622
- package/src/server/services.ts +468 -468
- package/src/server/types.ts +39 -39
- package/src/server/utils/error-handler.ts +155 -155
- package/src/server/utils/index.ts +13 -13
- package/src/server/utils/memory-indicator.ts +83 -83
- package/src/server/utils/request-context.ts +122 -122
- package/src/server/utils/response-formatter.ts +129 -124
- package/src/server/utils/validators.ts +210 -210
- package/src/setup/index.ts +48 -48
- package/src/setup/wizard.ts +461 -461
- package/src/tools/index.ts +24 -24
- package/src/tools/registry.ts +115 -115
- package/src/tools/schemas.test.ts +30 -30
- package/src/tools/schemas.ts +617 -617
- package/src/tools/types.ts +412 -412
- package/src/utils/circuit-breaker.ts +130 -130
- package/src/utils/cleanup.ts +34 -34
- package/src/utils/error-handler.ts +132 -132
- package/src/utils/error-messages.ts +60 -60
- package/src/utils/fallback.ts +45 -45
- package/src/utils/index.ts +54 -54
- package/src/utils/logger-utils.ts +80 -80
- package/src/utils/logger.ts +88 -88
- package/src/utils/phase12-helper.ts +56 -56
- package/src/utils/retry.ts +94 -94
- package/src/utils/timing.ts +47 -47
- package/src/utils/transaction.ts +63 -63
- package/src/vault/frontmatter.ts +264 -264
- package/src/vault/index.ts +318 -318
- package/src/vault/paths.ts +106 -106
- package/src/vault/query.ts +422 -422
- package/src/vault/reader.ts +264 -264
- package/src/vault/templates.ts +186 -186
- package/src/vault/types.ts +73 -73
- package/src/vault/watcher.ts +277 -277
- package/src/vault/writer.ts +413 -413
- package/tsconfig.json +30 -30
package/src/config/validator.ts
CHANGED
|
@@ -1,184 +1,184 @@
|
|
|
1
|
-
import fs from 'fs/promises'
|
|
2
|
-
import path from 'path'
|
|
3
|
-
import type { Logger } from 'pino'
|
|
4
|
-
|
|
5
|
-
export interface ValidationResult {
|
|
6
|
-
valid: boolean
|
|
7
|
-
errors: ValidationError[]
|
|
8
|
-
warnings: ValidationWarning[]
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
export interface ValidationError {
|
|
12
|
-
field: string
|
|
13
|
-
message: string
|
|
14
|
-
severity: 'error'
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
export interface ValidationWarning {
|
|
18
|
-
field: string
|
|
19
|
-
message: string
|
|
20
|
-
severity: 'warning'
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
export class ConfigValidator {
|
|
24
|
-
private logger: Logger
|
|
25
|
-
|
|
26
|
-
constructor(logger: Logger) {
|
|
27
|
-
this.logger = logger.child({ component: 'config-validator' })
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
async validate(config: any): Promise<ValidationResult> {
|
|
31
|
-
const errors: ValidationError[] = []
|
|
32
|
-
const warnings: ValidationWarning[] = []
|
|
33
|
-
|
|
34
|
-
await this.validateVaultPath(config.vaultPath, errors, warnings)
|
|
35
|
-
await this.validateDatabasePath(config.dbPath, errors, warnings)
|
|
36
|
-
this.validateLogConfig(config, errors, warnings)
|
|
37
|
-
this.validateServerConfig(config, errors, warnings)
|
|
38
|
-
|
|
39
|
-
const valid = errors.length === 0
|
|
40
|
-
|
|
41
|
-
return { valid, errors, warnings }
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
private async validateVaultPath(
|
|
45
|
-
vaultPath: string,
|
|
46
|
-
errors: ValidationError[],
|
|
47
|
-
warnings: ValidationWarning[]
|
|
48
|
-
): Promise<void> {
|
|
49
|
-
if (!vaultPath) {
|
|
50
|
-
errors.push({
|
|
51
|
-
field: 'vaultPath',
|
|
52
|
-
message: 'Vault path is required',
|
|
53
|
-
severity: 'error'
|
|
54
|
-
})
|
|
55
|
-
return
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
try {
|
|
59
|
-
const stat = await fs.stat(vaultPath)
|
|
60
|
-
|
|
61
|
-
if (!stat.isDirectory()) {
|
|
62
|
-
errors.push({
|
|
63
|
-
field: 'vaultPath',
|
|
64
|
-
message: 'Vault path must be a directory',
|
|
65
|
-
severity: 'error'
|
|
66
|
-
})
|
|
67
|
-
return
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
const projectsPath = path.join(vaultPath, 'Projects')
|
|
71
|
-
try {
|
|
72
|
-
await fs.access(projectsPath)
|
|
73
|
-
} catch {
|
|
74
|
-
warnings.push({
|
|
75
|
-
field: 'vaultPath',
|
|
76
|
-
message: 'Projects directory not found. It will be created automatically.',
|
|
77
|
-
severity: 'warning'
|
|
78
|
-
})
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
try {
|
|
82
|
-
await fs.access(vaultPath, fs.constants.W_OK)
|
|
83
|
-
} catch {
|
|
84
|
-
errors.push({
|
|
85
|
-
field: 'vaultPath',
|
|
86
|
-
message: 'Vault path is not writable',
|
|
87
|
-
severity: 'error'
|
|
88
|
-
})
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
} catch (error) {
|
|
92
|
-
errors.push({
|
|
93
|
-
field: 'vaultPath',
|
|
94
|
-
message: `Vault path does not exist: ${vaultPath}`,
|
|
95
|
-
severity: 'error'
|
|
96
|
-
})
|
|
97
|
-
}
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
private async validateDatabasePath(
|
|
101
|
-
dbPath: string,
|
|
102
|
-
errors: ValidationError[],
|
|
103
|
-
warnings: ValidationWarning[]
|
|
104
|
-
): Promise<void> {
|
|
105
|
-
if (!dbPath) {
|
|
106
|
-
errors.push({
|
|
107
|
-
field: 'dbPath',
|
|
108
|
-
message: 'Database path is required',
|
|
109
|
-
severity: 'error'
|
|
110
|
-
})
|
|
111
|
-
return
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
const dbDir = path.dirname(dbPath)
|
|
115
|
-
|
|
116
|
-
try {
|
|
117
|
-
await fs.mkdir(dbDir, { recursive: true })
|
|
118
|
-
} catch (error) {
|
|
119
|
-
errors.push({
|
|
120
|
-
field: 'dbPath',
|
|
121
|
-
message: `Cannot create database directory: ${dbDir}`,
|
|
122
|
-
severity: 'error'
|
|
123
|
-
})
|
|
124
|
-
}
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
private validateLogConfig(
|
|
128
|
-
config: any,
|
|
129
|
-
errors: ValidationError[],
|
|
130
|
-
warnings: ValidationWarning[]
|
|
131
|
-
): void {
|
|
132
|
-
const validLevels = ['error', 'warn', 'info', 'debug']
|
|
133
|
-
|
|
134
|
-
if (config.logLevel && !validLevels.includes(config.logLevel)) {
|
|
135
|
-
warnings.push({
|
|
136
|
-
field: 'logLevel',
|
|
137
|
-
message: `Invalid log level: ${config.logLevel}. Using 'info' as default.`,
|
|
138
|
-
severity: 'warning'
|
|
139
|
-
})
|
|
140
|
-
}
|
|
141
|
-
}
|
|
142
|
-
|
|
143
|
-
private validateServerConfig(
|
|
144
|
-
config: any,
|
|
145
|
-
errors: ValidationError[],
|
|
146
|
-
warnings: ValidationWarning[]
|
|
147
|
-
): void {
|
|
148
|
-
if (!config.serverName) {
|
|
149
|
-
errors.push({
|
|
150
|
-
field: 'serverName',
|
|
151
|
-
message: 'Server name is required',
|
|
152
|
-
severity: 'error'
|
|
153
|
-
})
|
|
154
|
-
}
|
|
155
|
-
|
|
156
|
-
if (!config.serverVersion) {
|
|
157
|
-
warnings.push({
|
|
158
|
-
field: 'serverVersion',
|
|
159
|
-
message: 'Server version not specified',
|
|
160
|
-
severity: 'warning'
|
|
161
|
-
})
|
|
162
|
-
}
|
|
163
|
-
}
|
|
164
|
-
|
|
165
|
-
async checkSystemRequirements(): Promise<ValidationResult> {
|
|
166
|
-
const errors: ValidationError[] = []
|
|
167
|
-
const warnings: ValidationWarning[] = []
|
|
168
|
-
|
|
169
|
-
const bunVersion = process.versions.bun
|
|
170
|
-
if (!bunVersion) {
|
|
171
|
-
errors.push({
|
|
172
|
-
field: 'runtime',
|
|
173
|
-
message: 'Bun runtime not detected. Claude Brain requires Bun.',
|
|
174
|
-
severity: 'error'
|
|
175
|
-
})
|
|
176
|
-
}
|
|
177
|
-
|
|
178
|
-
return {
|
|
179
|
-
valid: errors.length === 0,
|
|
180
|
-
errors,
|
|
181
|
-
warnings
|
|
182
|
-
}
|
|
183
|
-
}
|
|
184
|
-
}
|
|
1
|
+
import fs from 'fs/promises'
|
|
2
|
+
import path from 'path'
|
|
3
|
+
import type { Logger } from 'pino'
|
|
4
|
+
|
|
5
|
+
export interface ValidationResult {
|
|
6
|
+
valid: boolean
|
|
7
|
+
errors: ValidationError[]
|
|
8
|
+
warnings: ValidationWarning[]
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export interface ValidationError {
|
|
12
|
+
field: string
|
|
13
|
+
message: string
|
|
14
|
+
severity: 'error'
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export interface ValidationWarning {
|
|
18
|
+
field: string
|
|
19
|
+
message: string
|
|
20
|
+
severity: 'warning'
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export class ConfigValidator {
|
|
24
|
+
private logger: Logger
|
|
25
|
+
|
|
26
|
+
constructor(logger: Logger) {
|
|
27
|
+
this.logger = logger.child({ component: 'config-validator' })
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
async validate(config: any): Promise<ValidationResult> {
|
|
31
|
+
const errors: ValidationError[] = []
|
|
32
|
+
const warnings: ValidationWarning[] = []
|
|
33
|
+
|
|
34
|
+
await this.validateVaultPath(config.vaultPath, errors, warnings)
|
|
35
|
+
await this.validateDatabasePath(config.dbPath, errors, warnings)
|
|
36
|
+
this.validateLogConfig(config, errors, warnings)
|
|
37
|
+
this.validateServerConfig(config, errors, warnings)
|
|
38
|
+
|
|
39
|
+
const valid = errors.length === 0
|
|
40
|
+
|
|
41
|
+
return { valid, errors, warnings }
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
private async validateVaultPath(
|
|
45
|
+
vaultPath: string,
|
|
46
|
+
errors: ValidationError[],
|
|
47
|
+
warnings: ValidationWarning[]
|
|
48
|
+
): Promise<void> {
|
|
49
|
+
if (!vaultPath) {
|
|
50
|
+
errors.push({
|
|
51
|
+
field: 'vaultPath',
|
|
52
|
+
message: 'Vault path is required',
|
|
53
|
+
severity: 'error'
|
|
54
|
+
})
|
|
55
|
+
return
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
try {
|
|
59
|
+
const stat = await fs.stat(vaultPath)
|
|
60
|
+
|
|
61
|
+
if (!stat.isDirectory()) {
|
|
62
|
+
errors.push({
|
|
63
|
+
field: 'vaultPath',
|
|
64
|
+
message: 'Vault path must be a directory',
|
|
65
|
+
severity: 'error'
|
|
66
|
+
})
|
|
67
|
+
return
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
const projectsPath = path.join(vaultPath, 'Projects')
|
|
71
|
+
try {
|
|
72
|
+
await fs.access(projectsPath)
|
|
73
|
+
} catch {
|
|
74
|
+
warnings.push({
|
|
75
|
+
field: 'vaultPath',
|
|
76
|
+
message: 'Projects directory not found. It will be created automatically.',
|
|
77
|
+
severity: 'warning'
|
|
78
|
+
})
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
try {
|
|
82
|
+
await fs.access(vaultPath, fs.constants.W_OK)
|
|
83
|
+
} catch {
|
|
84
|
+
errors.push({
|
|
85
|
+
field: 'vaultPath',
|
|
86
|
+
message: 'Vault path is not writable',
|
|
87
|
+
severity: 'error'
|
|
88
|
+
})
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
} catch (error) {
|
|
92
|
+
errors.push({
|
|
93
|
+
field: 'vaultPath',
|
|
94
|
+
message: `Vault path does not exist: ${vaultPath}`,
|
|
95
|
+
severity: 'error'
|
|
96
|
+
})
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
private async validateDatabasePath(
|
|
101
|
+
dbPath: string,
|
|
102
|
+
errors: ValidationError[],
|
|
103
|
+
warnings: ValidationWarning[]
|
|
104
|
+
): Promise<void> {
|
|
105
|
+
if (!dbPath) {
|
|
106
|
+
errors.push({
|
|
107
|
+
field: 'dbPath',
|
|
108
|
+
message: 'Database path is required',
|
|
109
|
+
severity: 'error'
|
|
110
|
+
})
|
|
111
|
+
return
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
const dbDir = path.dirname(dbPath)
|
|
115
|
+
|
|
116
|
+
try {
|
|
117
|
+
await fs.mkdir(dbDir, { recursive: true })
|
|
118
|
+
} catch (error) {
|
|
119
|
+
errors.push({
|
|
120
|
+
field: 'dbPath',
|
|
121
|
+
message: `Cannot create database directory: ${dbDir}`,
|
|
122
|
+
severity: 'error'
|
|
123
|
+
})
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
private validateLogConfig(
|
|
128
|
+
config: any,
|
|
129
|
+
errors: ValidationError[],
|
|
130
|
+
warnings: ValidationWarning[]
|
|
131
|
+
): void {
|
|
132
|
+
const validLevels = ['error', 'warn', 'info', 'debug']
|
|
133
|
+
|
|
134
|
+
if (config.logLevel && !validLevels.includes(config.logLevel)) {
|
|
135
|
+
warnings.push({
|
|
136
|
+
field: 'logLevel',
|
|
137
|
+
message: `Invalid log level: ${config.logLevel}. Using 'info' as default.`,
|
|
138
|
+
severity: 'warning'
|
|
139
|
+
})
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
private validateServerConfig(
|
|
144
|
+
config: any,
|
|
145
|
+
errors: ValidationError[],
|
|
146
|
+
warnings: ValidationWarning[]
|
|
147
|
+
): void {
|
|
148
|
+
if (!config.serverName) {
|
|
149
|
+
errors.push({
|
|
150
|
+
field: 'serverName',
|
|
151
|
+
message: 'Server name is required',
|
|
152
|
+
severity: 'error'
|
|
153
|
+
})
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
if (!config.serverVersion) {
|
|
157
|
+
warnings.push({
|
|
158
|
+
field: 'serverVersion',
|
|
159
|
+
message: 'Server version not specified',
|
|
160
|
+
severity: 'warning'
|
|
161
|
+
})
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
async checkSystemRequirements(): Promise<ValidationResult> {
|
|
166
|
+
const errors: ValidationError[] = []
|
|
167
|
+
const warnings: ValidationWarning[] = []
|
|
168
|
+
|
|
169
|
+
const bunVersion = process.versions.bun
|
|
170
|
+
if (!bunVersion) {
|
|
171
|
+
errors.push({
|
|
172
|
+
field: 'runtime',
|
|
173
|
+
message: 'Bun runtime not detected. Claude Brain requires Bun.',
|
|
174
|
+
severity: 'error'
|
|
175
|
+
})
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
return {
|
|
179
|
+
valid: errors.length === 0,
|
|
180
|
+
errors,
|
|
181
|
+
warnings
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
}
|
package/src/config/watcher.ts
CHANGED
|
@@ -1,86 +1,86 @@
|
|
|
1
|
-
import { watch, type FSWatcher } from 'node:fs'
|
|
2
|
-
import { EventEmitter } from 'node:events'
|
|
3
|
-
import { loadConfig, getConfigFilePath } from './loader'
|
|
4
|
-
import type { Config } from './schema'
|
|
5
|
-
|
|
6
|
-
export interface ConfigWatcherEvents {
|
|
7
|
-
change: (config: Config) => void
|
|
8
|
-
error: (error: Error) => void
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
/** Watches the config file for changes and emits events */
|
|
12
|
-
export class ConfigWatcher extends EventEmitter {
|
|
13
|
-
private watcher: FSWatcher | null = null
|
|
14
|
-
private configPath: string
|
|
15
|
-
private currentConfig: Config | null = null
|
|
16
|
-
private debounceTimer: Timer | null = null
|
|
17
|
-
private readonly debounceMs = 100
|
|
18
|
-
|
|
19
|
-
constructor(basePath: string = process.cwd()) {
|
|
20
|
-
super()
|
|
21
|
-
this.configPath = getConfigFilePath(basePath)
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
/** Start watching the config file */
|
|
25
|
-
async start(): Promise<void> {
|
|
26
|
-
try {
|
|
27
|
-
this.currentConfig = await loadConfig()
|
|
28
|
-
|
|
29
|
-
this.watcher = watch(this.configPath, (eventType) => {
|
|
30
|
-
if (eventType === 'change') {
|
|
31
|
-
this.handleChange()
|
|
32
|
-
}
|
|
33
|
-
})
|
|
34
|
-
|
|
35
|
-
this.watcher.on('error', (error) => {
|
|
36
|
-
this.emit('error', error)
|
|
37
|
-
})
|
|
38
|
-
} catch (error) {
|
|
39
|
-
// Config file might not exist yet, that's ok
|
|
40
|
-
if ((error as NodeJS.ErrnoException).code !== 'ENOENT') {
|
|
41
|
-
throw error
|
|
42
|
-
}
|
|
43
|
-
}
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
/** Stop watching the config file */
|
|
47
|
-
stop(): void {
|
|
48
|
-
if (this.watcher) {
|
|
49
|
-
this.watcher.close()
|
|
50
|
-
this.watcher = null
|
|
51
|
-
}
|
|
52
|
-
if (this.debounceTimer) {
|
|
53
|
-
clearTimeout(this.debounceTimer)
|
|
54
|
-
this.debounceTimer = null
|
|
55
|
-
}
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
/** Get the current configuration */
|
|
59
|
-
getConfig(): Config | null {
|
|
60
|
-
return this.currentConfig
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
private handleChange(): void {
|
|
64
|
-
// Debounce rapid changes
|
|
65
|
-
if (this.debounceTimer) {
|
|
66
|
-
clearTimeout(this.debounceTimer)
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
this.debounceTimer = setTimeout(async () => {
|
|
70
|
-
try {
|
|
71
|
-
const newConfig = await loadConfig()
|
|
72
|
-
this.currentConfig = newConfig
|
|
73
|
-
this.emit('change', newConfig)
|
|
74
|
-
} catch (error) {
|
|
75
|
-
this.emit('error', error instanceof Error ? error : new Error(String(error)))
|
|
76
|
-
}
|
|
77
|
-
}, this.debounceMs)
|
|
78
|
-
}
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
/** Create and start a config watcher */
|
|
82
|
-
export async function createConfigWatcher(basePath?: string): Promise<ConfigWatcher> {
|
|
83
|
-
const watcher = new ConfigWatcher(basePath)
|
|
84
|
-
await watcher.start()
|
|
85
|
-
return watcher
|
|
86
|
-
}
|
|
1
|
+
import { watch, type FSWatcher } from 'node:fs'
|
|
2
|
+
import { EventEmitter } from 'node:events'
|
|
3
|
+
import { loadConfig, getConfigFilePath } from './loader'
|
|
4
|
+
import type { Config } from './schema'
|
|
5
|
+
|
|
6
|
+
export interface ConfigWatcherEvents {
|
|
7
|
+
change: (config: Config) => void
|
|
8
|
+
error: (error: Error) => void
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
/** Watches the config file for changes and emits events */
|
|
12
|
+
export class ConfigWatcher extends EventEmitter {
|
|
13
|
+
private watcher: FSWatcher | null = null
|
|
14
|
+
private configPath: string
|
|
15
|
+
private currentConfig: Config | null = null
|
|
16
|
+
private debounceTimer: Timer | null = null
|
|
17
|
+
private readonly debounceMs = 100
|
|
18
|
+
|
|
19
|
+
constructor(basePath: string = process.cwd()) {
|
|
20
|
+
super()
|
|
21
|
+
this.configPath = getConfigFilePath(basePath)
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
/** Start watching the config file */
|
|
25
|
+
async start(): Promise<void> {
|
|
26
|
+
try {
|
|
27
|
+
this.currentConfig = await loadConfig()
|
|
28
|
+
|
|
29
|
+
this.watcher = watch(this.configPath, (eventType) => {
|
|
30
|
+
if (eventType === 'change') {
|
|
31
|
+
this.handleChange()
|
|
32
|
+
}
|
|
33
|
+
})
|
|
34
|
+
|
|
35
|
+
this.watcher.on('error', (error) => {
|
|
36
|
+
this.emit('error', error)
|
|
37
|
+
})
|
|
38
|
+
} catch (error) {
|
|
39
|
+
// Config file might not exist yet, that's ok
|
|
40
|
+
if ((error as NodeJS.ErrnoException).code !== 'ENOENT') {
|
|
41
|
+
throw error
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
/** Stop watching the config file */
|
|
47
|
+
stop(): void {
|
|
48
|
+
if (this.watcher) {
|
|
49
|
+
this.watcher.close()
|
|
50
|
+
this.watcher = null
|
|
51
|
+
}
|
|
52
|
+
if (this.debounceTimer) {
|
|
53
|
+
clearTimeout(this.debounceTimer)
|
|
54
|
+
this.debounceTimer = null
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
/** Get the current configuration */
|
|
59
|
+
getConfig(): Config | null {
|
|
60
|
+
return this.currentConfig
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
private handleChange(): void {
|
|
64
|
+
// Debounce rapid changes
|
|
65
|
+
if (this.debounceTimer) {
|
|
66
|
+
clearTimeout(this.debounceTimer)
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
this.debounceTimer = setTimeout(async () => {
|
|
70
|
+
try {
|
|
71
|
+
const newConfig = await loadConfig()
|
|
72
|
+
this.currentConfig = newConfig
|
|
73
|
+
this.emit('change', newConfig)
|
|
74
|
+
} catch (error) {
|
|
75
|
+
this.emit('error', error instanceof Error ? error : new Error(String(error)))
|
|
76
|
+
}
|
|
77
|
+
}, this.debounceMs)
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
/** Create and start a config watcher */
|
|
82
|
+
export async function createConfigWatcher(basePath?: string): Promise<ConfigWatcher> {
|
|
83
|
+
const watcher = new ConfigWatcher(basePath)
|
|
84
|
+
await watcher.start()
|
|
85
|
+
return watcher
|
|
86
|
+
}
|