claude-brain 0.17.10 → 0.17.11
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/VERSION +1 -1
- package/package.json +4 -5
- package/scripts/postinstall.mjs +43 -16
- package/src/automation/decision-detector.ts +2 -2
- package/src/automation/proactive-recall.ts +2 -2
- package/src/automation/project-detector.ts +10 -10
- package/src/automation/repo-scanner.ts +2 -2
- package/src/cli/bin.ts +20 -7
- package/src/cli/commands/chroma.ts +5 -1
- package/src/cli/commands/git-hook.ts +15 -21
- package/src/cli/commands/hooks.ts +5 -1
- package/src/cli/commands/init.ts +7 -6
- package/src/cli/commands/pack.ts +11 -8
- package/src/cli/commands/refresh.ts +2 -2
- package/src/cli/commands/serve.ts +1 -1
- package/src/cli/commands/start.ts +5 -1
- package/src/cli/commands/update.ts +2 -2
- package/src/cli/migrate-chroma.ts +1 -1
- package/src/config/defaults.ts +3 -1
- package/src/config/index.ts +0 -2
- package/src/config/loader.ts +36 -38
- package/src/config/schema.ts +30 -49
- package/src/config/validator.ts +4 -6
- package/src/context/assembler.ts +20 -18
- package/src/context/index.ts +0 -4
- package/src/context/progress-tracker.ts +9 -9
- package/src/context/standards-manager.ts +23 -23
- package/src/context/validator.ts +1 -1
- package/src/diagnostics/index.ts +2 -4
- package/src/health/index.ts +2 -2
- package/src/hooks/passive-classifier.ts +0 -7
- package/src/intelligence/cross-project/affinity.ts +4 -7
- package/src/intelligence/cross-project/generalizer.ts +1 -1
- package/src/intelligence/optimization/semantic-cache.ts +4 -4
- package/src/intelligence/prediction/decision-predictor.ts +2 -2
- package/src/intelligence/reasoning/counterfactual.ts +1 -1
- package/src/intelligence/reasoning/synthesizer.ts +3 -5
- package/src/intelligence/temporal/evolution.ts +6 -6
- package/src/intelligence/temporal/query-processor.ts +3 -3
- package/src/intelligence/temporal/trends.ts +2 -2
- package/src/knowledge/entity-extractor.ts +1 -4
- package/src/knowledge/graph/builder.ts +3 -3
- package/src/knowledge/graph/linker.ts +7 -7
- package/src/knowledge/graph/search.ts +1 -3
- package/src/memory/chroma/collection-manager.ts +1 -3
- package/src/memory/chroma/embeddings.ts +5 -7
- package/src/memory/chroma/migration.ts +1 -1
- package/src/memory/chroma/search.ts +6 -6
- package/src/memory/chroma/store.ts +7 -4
- package/src/memory/consolidation/archiver.ts +3 -2
- package/src/memory/consolidation/merger.ts +4 -4
- package/src/memory/consolidation/scorer.ts +1 -3
- package/src/memory/episodic/manager.ts +2 -2
- package/src/memory/index.ts +13 -4
- package/src/memory/patterns.ts +6 -4
- package/src/retrieval/bm25/index.ts +4 -7
- package/src/retrieval/feedback/adaptive.ts +2 -4
- package/src/retrieval/feedback/metrics.ts +3 -5
- package/src/retrieval/fusion/index.ts +1 -1
- package/src/retrieval/fusion/rrf.ts +6 -4
- package/src/retrieval/pipeline.ts +6 -6
- package/src/retrieval/query/intent-classifier.ts +3 -3
- package/src/retrieval/query/temporal-parser.ts +7 -7
- package/src/retrieval/reranker/index.ts +2 -2
- package/src/retrieval/service.ts +1 -1
- package/src/routing/router.ts +3 -4
- package/src/routing/search-engine.ts +4 -5
- package/src/scripts/health-check.ts +1 -1
- package/src/scripts/setup.ts +3 -3
- package/src/server/handlers/call-tool.ts +0 -4
- package/src/server/handlers/tools/auto-remember.ts +4 -39
- package/src/server/handlers/tools/get-code-standards.ts +0 -1
- package/src/server/handlers/tools/get-corrections.ts +1 -3
- package/src/server/handlers/tools/get-patterns.ts +1 -3
- package/src/server/handlers/tools/index.ts +1 -5
- package/src/server/handlers/tools/init-project.ts +8 -9
- package/src/server/handlers/tools/list-projects.ts +1 -0
- package/src/server/handlers/tools/recall-similar.ts +1 -1
- package/src/server/handlers/tools/recognize-pattern.ts +7 -1
- package/src/server/handlers/tools/record-correction.ts +7 -1
- package/src/server/handlers/tools/remember-decision.ts +17 -2
- package/src/server/handlers/tools/schemas.ts +0 -90
- package/src/server/handlers/tools/smart-context.ts +1 -1
- package/src/server/handlers/tools/update-progress.ts +2 -2
- package/src/server/http-api.ts +20 -38
- package/src/server/mcp-server.ts +2 -1
- package/src/server/providers/resources.ts +6 -6
- package/src/server/services.ts +67 -2
- package/src/setup/wizard.ts +2 -4
- package/src/utils/transaction.ts +1 -1
- package/src/cli/diagnose.ts +0 -4
- package/src/cli/health-check.ts +0 -4
- package/src/cli/setup.ts +0 -4
- package/src/config/migration.ts +0 -76
- package/src/config/watcher.ts +0 -86
- package/src/server/handlers/tools/analyze-decision-evolution.ts +0 -151
- package/src/server/handlers/tools/detect-trends.ts +0 -144
- package/src/server/handlers/tools/find-cross-project-patterns.ts +0 -168
- package/src/server/handlers/tools/get-activity-log.ts +0 -194
- package/src/server/handlers/tools/get-decision-timeline.ts +0 -172
- package/src/server/handlers/tools/get-episode.ts +0 -103
- package/src/server/handlers/tools/get-recommendations.ts +0 -145
- package/src/server/handlers/tools/list-episodes.ts +0 -90
- package/src/server/handlers/tools/rate-memory.ts +0 -101
- package/src/server/handlers/tools/search-knowledge-graph.ts +0 -102
- package/src/server/handlers/tools/what-if-analysis.ts +0 -135
package/VERSION
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
0.17.
|
|
1
|
+
0.17.11
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "claude-brain",
|
|
3
|
-
"version": "0.17.
|
|
3
|
+
"version": "0.17.11",
|
|
4
4
|
"description": "Local development assistant bridging Obsidian vaults with Claude Code via MCP",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "src/index.ts",
|
|
@@ -53,9 +53,8 @@
|
|
|
53
53
|
},
|
|
54
54
|
"devDependencies": {
|
|
55
55
|
"@types/bun": "latest",
|
|
56
|
-
"@types/node": "
|
|
57
|
-
"@types/prompts": "2.4.9"
|
|
58
|
-
"daisyui": "^5.5.14"
|
|
56
|
+
"@types/node": "25.2.2",
|
|
57
|
+
"@types/prompts": "2.4.9"
|
|
59
58
|
},
|
|
60
59
|
"peerDependencies": {
|
|
61
60
|
"typescript": "^5"
|
|
@@ -66,8 +65,8 @@
|
|
|
66
65
|
"@xenova/transformers": "2.17.2",
|
|
67
66
|
"chalk": "5.6.2",
|
|
68
67
|
"chromadb": "3.2.2",
|
|
69
|
-
"chromadb-default-embed": "2.14.0",
|
|
70
68
|
"chrono-node": "2.9.0",
|
|
69
|
+
"citty": "0.2.0",
|
|
71
70
|
"compromise": "^14.10.0",
|
|
72
71
|
"dotenv": "^17.2.3",
|
|
73
72
|
"gray-matter": "^4.0.3",
|
package/scripts/postinstall.mjs
CHANGED
|
@@ -260,32 +260,59 @@ function installHooks() {
|
|
|
260
260
|
)
|
|
261
261
|
}
|
|
262
262
|
|
|
263
|
-
if (settings.hooks &&
|
|
263
|
+
if (settings.hooks &&
|
|
264
|
+
hasOurHooks(settings.hooks.PostToolUse) &&
|
|
265
|
+
hasOurHooks(settings.hooks.Stop) &&
|
|
266
|
+
hasOurHooks(settings.hooks.UserPromptSubmit) &&
|
|
267
|
+
hasOurHooks(settings.hooks.SessionStart)) {
|
|
264
268
|
log('Hooks already installed')
|
|
265
269
|
return true
|
|
266
270
|
}
|
|
267
271
|
|
|
268
272
|
// Build hook command
|
|
269
|
-
const
|
|
270
|
-
|
|
273
|
+
const brainScriptPath = join(HOME, 'hooks', 'brain-hook.ts')
|
|
274
|
+
const contextScriptPath = join(HOME, 'hooks', 'context-hook.ts')
|
|
275
|
+
function buildCmd(event, scriptPath) {
|
|
271
276
|
return `bun "${scriptPath}" --event ${event} # ${HOOK_MARKER}`
|
|
272
277
|
}
|
|
273
278
|
|
|
274
279
|
if (!settings.hooks) settings.hooks = {}
|
|
275
280
|
|
|
276
|
-
// PostToolUse
|
|
277
|
-
if (!settings.hooks.PostToolUse)
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
281
|
+
// PostToolUse — captures tool events
|
|
282
|
+
if (!hasOurHooks(settings.hooks.PostToolUse)) {
|
|
283
|
+
if (!settings.hooks.PostToolUse) settings.hooks.PostToolUse = []
|
|
284
|
+
settings.hooks.PostToolUse.push({
|
|
285
|
+
matcher: '',
|
|
286
|
+
hooks: [{ type: 'command', command: buildCmd('PostToolUse', brainScriptPath) }],
|
|
287
|
+
})
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
// Stop — triggers session-end summary
|
|
291
|
+
if (!hasOurHooks(settings.hooks.Stop)) {
|
|
292
|
+
if (!settings.hooks.Stop) settings.hooks.Stop = []
|
|
293
|
+
settings.hooks.Stop.push({
|
|
294
|
+
matcher: '',
|
|
295
|
+
hooks: [{ type: 'command', command: buildCmd('Stop', brainScriptPath) }],
|
|
296
|
+
})
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
// UserPromptSubmit — injects relevant memories into every prompt
|
|
300
|
+
if (!hasOurHooks(settings.hooks.UserPromptSubmit)) {
|
|
301
|
+
if (!settings.hooks.UserPromptSubmit) settings.hooks.UserPromptSubmit = []
|
|
302
|
+
settings.hooks.UserPromptSubmit.push({
|
|
303
|
+
matcher: '',
|
|
304
|
+
hooks: [{ type: 'command', command: buildCmd('UserPromptSubmit', contextScriptPath) }],
|
|
305
|
+
})
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
// SessionStart — injects project context on session start/resume
|
|
309
|
+
if (!hasOurHooks(settings.hooks.SessionStart)) {
|
|
310
|
+
if (!settings.hooks.SessionStart) settings.hooks.SessionStart = []
|
|
311
|
+
settings.hooks.SessionStart.push({
|
|
312
|
+
matcher: 'startup,resume,compact',
|
|
313
|
+
hooks: [{ type: 'command', command: buildCmd('SessionStart', contextScriptPath) }],
|
|
314
|
+
})
|
|
315
|
+
}
|
|
289
316
|
|
|
290
317
|
// Write atomically
|
|
291
318
|
if (!existsSync(CLAUDE_DIR)) {
|
|
@@ -81,7 +81,7 @@ export class DecisionDetector {
|
|
|
81
81
|
/**
|
|
82
82
|
* Detect decision from text
|
|
83
83
|
*/
|
|
84
|
-
detectDecision(text: string,
|
|
84
|
+
detectDecision(text: string, _project?: string): DetectedDecision | null {
|
|
85
85
|
const textLower = text.toLowerCase()
|
|
86
86
|
|
|
87
87
|
// Check for decision phrases
|
|
@@ -133,7 +133,7 @@ export class DecisionDetector {
|
|
|
133
133
|
|
|
134
134
|
// Find sentence with decision phrase
|
|
135
135
|
for (let i = 0; i < sentences.length; i++) {
|
|
136
|
-
const sentence = sentences[i].toLowerCase()
|
|
136
|
+
const sentence = (sentences[i] ?? "").toLowerCase()
|
|
137
137
|
|
|
138
138
|
if (this.DECISION_PHRASES.some(p => sentence.includes(p))) {
|
|
139
139
|
// Context is likely in previous sentences
|
|
@@ -148,7 +148,7 @@ export class ProactiveRecallEngine {
|
|
|
148
148
|
// Also extract potential compound terms
|
|
149
149
|
const compounds: string[] = []
|
|
150
150
|
for (let i = 0; i < words.length - 1; i++) {
|
|
151
|
-
if (words[i]
|
|
151
|
+
if (words[i]!.length > 3 && words[i + 1]!.length > 3) {
|
|
152
152
|
compounds.push(`${words[i]} ${words[i + 1]}`)
|
|
153
153
|
}
|
|
154
154
|
}
|
|
@@ -256,7 +256,7 @@ export class ProactiveRecallEngine {
|
|
|
256
256
|
/**
|
|
257
257
|
* Calculate relevance score
|
|
258
258
|
*/
|
|
259
|
-
private calculateRelevance(
|
|
259
|
+
private calculateRelevance(_query: string, memories: MemorySearchResult[]): number {
|
|
260
260
|
if (memories.length === 0) return 0
|
|
261
261
|
|
|
262
262
|
// Average similarity score
|
|
@@ -112,7 +112,7 @@ export class ProjectDetector {
|
|
|
112
112
|
|
|
113
113
|
const nameMatch = pyprojectContent.match(/name\s*=\s*"([^"]+)"/)
|
|
114
114
|
if (nameMatch) {
|
|
115
|
-
return nameMatch[1]
|
|
115
|
+
return nameMatch[1] ?? null
|
|
116
116
|
}
|
|
117
117
|
} catch {
|
|
118
118
|
// No pyproject.toml
|
|
@@ -125,7 +125,7 @@ export class ProjectDetector {
|
|
|
125
125
|
|
|
126
126
|
const nameMatch = cargoContent.match(/name\s*=\s*"([^"]+)"/)
|
|
127
127
|
if (nameMatch) {
|
|
128
|
-
return nameMatch[1]
|
|
128
|
+
return nameMatch[1] ?? null
|
|
129
129
|
}
|
|
130
130
|
} catch {
|
|
131
131
|
// No Cargo.toml
|
|
@@ -139,7 +139,7 @@ export class ProjectDetector {
|
|
|
139
139
|
// Extract repo name from URL
|
|
140
140
|
const urlMatch = gitConfig.match(/url\s*=\s*.+\/([^/\n]+?)(?:\.git)?[\s\n]/)
|
|
141
141
|
if (urlMatch) {
|
|
142
|
-
return urlMatch[1]
|
|
142
|
+
return urlMatch[1]?.trim() ?? null
|
|
143
143
|
}
|
|
144
144
|
} catch {
|
|
145
145
|
// No .git/config
|
|
@@ -243,24 +243,24 @@ export class ProjectDetector {
|
|
|
243
243
|
}
|
|
244
244
|
|
|
245
245
|
for (let j = 0; j <= a.length; j++) {
|
|
246
|
-
matrix[0][j] = j
|
|
246
|
+
matrix[0]![j] = j
|
|
247
247
|
}
|
|
248
248
|
|
|
249
249
|
for (let i = 1; i <= b.length; i++) {
|
|
250
250
|
for (let j = 1; j <= a.length; j++) {
|
|
251
251
|
if (b.charAt(i - 1) === a.charAt(j - 1)) {
|
|
252
|
-
matrix[i][j] = matrix[i - 1][j - 1]
|
|
252
|
+
matrix[i]![j] = matrix[i - 1]![j - 1]!
|
|
253
253
|
} else {
|
|
254
|
-
matrix[i][j] = Math.min(
|
|
255
|
-
matrix[i - 1][j - 1] + 1,
|
|
256
|
-
matrix[i][j - 1] + 1,
|
|
257
|
-
matrix[i - 1][j] + 1
|
|
254
|
+
matrix[i]![j] = Math.min(
|
|
255
|
+
matrix[i - 1]![j - 1]! + 1,
|
|
256
|
+
matrix[i]![j - 1]! + 1,
|
|
257
|
+
matrix[i - 1]![j]! + 1
|
|
258
258
|
)
|
|
259
259
|
}
|
|
260
260
|
}
|
|
261
261
|
}
|
|
262
262
|
|
|
263
|
-
return matrix[b.length][a.length]
|
|
263
|
+
return matrix[b.length]![a.length]!
|
|
264
264
|
}
|
|
265
265
|
|
|
266
266
|
/**
|
|
@@ -153,9 +153,9 @@ async function getDirectoryTree(repoPath: string, maxDepth: number): Promise<str
|
|
|
153
153
|
async function walk(dir: string, depth: number, prefix: string) {
|
|
154
154
|
if (depth > maxDepth) return
|
|
155
155
|
|
|
156
|
-
let entries:
|
|
156
|
+
let entries: import("fs").Dirent[]
|
|
157
157
|
try {
|
|
158
|
-
entries = await fs.readdir(dir, { withFileTypes: true })
|
|
158
|
+
entries = await fs.readdir(dir, { withFileTypes: true, encoding: 'utf-8' })
|
|
159
159
|
} catch {
|
|
160
160
|
return
|
|
161
161
|
}
|
package/src/cli/bin.ts
CHANGED
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
import { readFileSync } from 'node:fs'
|
|
4
4
|
import { resolve, dirname } from 'node:path'
|
|
5
5
|
import { fileURLToPath } from 'node:url'
|
|
6
|
+
import { parseArgs } from 'citty'
|
|
6
7
|
import { renderLogo, theme, dimText, box, errorText } from '@/cli/ui/index.js'
|
|
7
8
|
|
|
8
9
|
const __filename = fileURLToPath(import.meta.url)
|
|
@@ -77,7 +78,23 @@ function printHelp() {
|
|
|
77
78
|
}
|
|
78
79
|
|
|
79
80
|
async function main() {
|
|
80
|
-
const
|
|
81
|
+
const args = parseArgs(process.argv.slice(2), {
|
|
82
|
+
command: { type: 'positional', required: false, description: 'Command to run' },
|
|
83
|
+
version: { type: 'boolean', alias: ['v'], description: 'Show version' },
|
|
84
|
+
help: { type: 'boolean', alias: ['h'], description: 'Show help' },
|
|
85
|
+
})
|
|
86
|
+
|
|
87
|
+
if (args.version) {
|
|
88
|
+
console.log(getVersion())
|
|
89
|
+
return
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
if (args.help) {
|
|
93
|
+
printHelp()
|
|
94
|
+
return
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
const command: string = args.command ?? 'serve'
|
|
81
98
|
|
|
82
99
|
switch (command) {
|
|
83
100
|
case 'start': {
|
|
@@ -179,16 +196,12 @@ async function main() {
|
|
|
179
196
|
break
|
|
180
197
|
}
|
|
181
198
|
|
|
182
|
-
case 'version':
|
|
183
|
-
case '-v':
|
|
184
|
-
case '--version': {
|
|
199
|
+
case 'version': {
|
|
185
200
|
console.log(getVersion())
|
|
186
201
|
break
|
|
187
202
|
}
|
|
188
203
|
|
|
189
|
-
case 'help':
|
|
190
|
-
case '-h':
|
|
191
|
-
case '--help': {
|
|
204
|
+
case 'help': {
|
|
192
205
|
printHelp()
|
|
193
206
|
break
|
|
194
207
|
}
|
|
@@ -6,6 +6,7 @@
|
|
|
6
6
|
import { spawn, execSync } from 'node:child_process'
|
|
7
7
|
import { existsSync, readFileSync, writeFileSync, unlinkSync } from 'node:fs'
|
|
8
8
|
import { join } from 'node:path'
|
|
9
|
+
import { parseArgs } from 'citty'
|
|
9
10
|
import { getHomePaths } from '@/config/home'
|
|
10
11
|
import {
|
|
11
12
|
theme, heading, successText, errorText, warningText, dimText,
|
|
@@ -544,7 +545,10 @@ export async function ensureChromaRunning(options?: { silent?: boolean }): Promi
|
|
|
544
545
|
// ── Entry Point ───────────────────────────────────────────
|
|
545
546
|
|
|
546
547
|
export async function runChroma(): Promise<void> {
|
|
547
|
-
const
|
|
548
|
+
const args = parseArgs(process.argv.slice(3), {
|
|
549
|
+
subcommand: { type: 'positional', required: false, description: 'start|stop|status|install|help' },
|
|
550
|
+
})
|
|
551
|
+
const subcommand: string = args.subcommand ?? 'help'
|
|
548
552
|
|
|
549
553
|
switch (subcommand) {
|
|
550
554
|
case 'start':
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
* Manages git post-commit hook installation (install/uninstall/status)
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
|
+
import { parseArgs } from 'citty'
|
|
6
7
|
import {
|
|
7
8
|
renderLogo, theme, heading, successText, warningText, errorText, dimText,
|
|
8
9
|
box, summaryPanel, withSpinner,
|
|
@@ -12,17 +13,22 @@ import {
|
|
|
12
13
|
} from '@/hooks/git-hook-installer'
|
|
13
14
|
|
|
14
15
|
export async function runGitHook() {
|
|
15
|
-
const
|
|
16
|
+
const args = parseArgs(process.argv.slice(3), {
|
|
17
|
+
subcommand: { type: 'positional', required: false, description: 'install|uninstall|status' },
|
|
18
|
+
path: { type: 'positional', required: false, description: 'Repository path' },
|
|
19
|
+
all: { type: 'string', required: false, description: 'Install in all repos under directory' },
|
|
20
|
+
})
|
|
21
|
+
const subcommand: string = args.subcommand ?? 'status'
|
|
16
22
|
|
|
17
23
|
switch (subcommand) {
|
|
18
24
|
case 'install':
|
|
19
|
-
await handleInstall()
|
|
25
|
+
await handleInstall(args.all, args.path)
|
|
20
26
|
break
|
|
21
27
|
case 'uninstall':
|
|
22
|
-
await handleUninstall()
|
|
28
|
+
await handleUninstall(args.path)
|
|
23
29
|
break
|
|
24
30
|
case 'status':
|
|
25
|
-
handleStatus()
|
|
31
|
+
handleStatus(args.path)
|
|
26
32
|
break
|
|
27
33
|
default:
|
|
28
34
|
console.log()
|
|
@@ -32,21 +38,15 @@ export async function runGitHook() {
|
|
|
32
38
|
}
|
|
33
39
|
}
|
|
34
40
|
|
|
35
|
-
async function handleInstall() {
|
|
41
|
+
async function handleInstall(allDir?: string, repoPath?: string) {
|
|
36
42
|
console.log()
|
|
37
43
|
console.log(renderLogo())
|
|
38
44
|
console.log()
|
|
39
45
|
console.log(heading('Install Git Hook'))
|
|
40
46
|
console.log()
|
|
41
47
|
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
if (allIdx >= 0) {
|
|
45
|
-
const dir = process.argv[allIdx + 1]
|
|
46
|
-
if (!dir) {
|
|
47
|
-
console.log(errorText('--all requires a directory path'))
|
|
48
|
-
process.exit(1)
|
|
49
|
-
}
|
|
48
|
+
if (allDir) {
|
|
49
|
+
const dir = allDir
|
|
50
50
|
|
|
51
51
|
let results: { installed: number; skipped: number; errors: number } | undefined
|
|
52
52
|
await withSpinner(`Installing git hooks in all repos under ${dir}`, async () => {
|
|
@@ -65,9 +65,6 @@ async function handleInstall() {
|
|
|
65
65
|
return
|
|
66
66
|
}
|
|
67
67
|
|
|
68
|
-
// Single repo install (current directory or specified path)
|
|
69
|
-
const repoPath = process.argv[4] || undefined
|
|
70
|
-
|
|
71
68
|
try {
|
|
72
69
|
let result: { installed: boolean; message: string; hookPath: string } | undefined
|
|
73
70
|
await withSpinner('Installing post-commit hook', async () => {
|
|
@@ -99,15 +96,13 @@ async function handleInstall() {
|
|
|
99
96
|
console.log()
|
|
100
97
|
}
|
|
101
98
|
|
|
102
|
-
async function handleUninstall() {
|
|
99
|
+
async function handleUninstall(repoPath?: string) {
|
|
103
100
|
console.log()
|
|
104
101
|
console.log(renderLogo())
|
|
105
102
|
console.log()
|
|
106
103
|
console.log(heading('Uninstall Git Hook'))
|
|
107
104
|
console.log()
|
|
108
105
|
|
|
109
|
-
const repoPath = process.argv[4] || undefined
|
|
110
|
-
|
|
111
106
|
try {
|
|
112
107
|
let result: { uninstalled: boolean; message: string } | undefined
|
|
113
108
|
await withSpinner('Removing post-commit hook', async () => {
|
|
@@ -129,14 +124,13 @@ async function handleUninstall() {
|
|
|
129
124
|
console.log()
|
|
130
125
|
}
|
|
131
126
|
|
|
132
|
-
function handleStatus() {
|
|
127
|
+
function handleStatus(repoPath?: string) {
|
|
133
128
|
console.log()
|
|
134
129
|
console.log(renderLogo())
|
|
135
130
|
console.log()
|
|
136
131
|
console.log(heading('Git Hook Status'))
|
|
137
132
|
console.log()
|
|
138
133
|
|
|
139
|
-
const repoPath = process.argv[4] || undefined
|
|
140
134
|
const installed = isGitHookInstalled(repoPath)
|
|
141
135
|
|
|
142
136
|
const items = [
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
* Manages passive learning hooks (install/uninstall/status/enable/disable)
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
|
+
import { parseArgs } from 'citty'
|
|
6
7
|
import {
|
|
7
8
|
renderLogo, theme, heading, successText, warningText, errorText, dimText,
|
|
8
9
|
box, summaryPanel, withSpinner,
|
|
@@ -11,7 +12,10 @@ import { installHooks, uninstallHooks, isHooksInstalled, getHookScriptPath } fro
|
|
|
11
12
|
import { readQueue } from '@/hooks/queue'
|
|
12
13
|
|
|
13
14
|
export async function runHooks() {
|
|
14
|
-
const
|
|
15
|
+
const args = parseArgs(process.argv.slice(3), {
|
|
16
|
+
subcommand: { type: 'positional', required: false, description: 'install|uninstall|status|enable|disable' },
|
|
17
|
+
})
|
|
18
|
+
const subcommand: string = args.subcommand ?? 'status'
|
|
15
19
|
|
|
16
20
|
switch (subcommand) {
|
|
17
21
|
case 'install':
|
package/src/cli/commands/init.ts
CHANGED
|
@@ -6,6 +6,7 @@
|
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
8
|
import path from 'path'
|
|
9
|
+
import { parseArgs } from 'citty'
|
|
9
10
|
import {
|
|
10
11
|
renderLogo, theme, heading, successText, warningText, dimText,
|
|
11
12
|
box, withSpinner,
|
|
@@ -19,12 +20,12 @@ export async function runInit() {
|
|
|
19
20
|
console.log(heading('Initialize Project'))
|
|
20
21
|
console.log()
|
|
21
22
|
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
)
|
|
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())
|
|
28
29
|
|
|
29
30
|
console.log(` ${theme.bold('Path:')} ${dimText(repoPath)}`)
|
|
30
31
|
if (force) {
|
package/src/cli/commands/pack.ts
CHANGED
|
@@ -3,11 +3,11 @@
|
|
|
3
3
|
* Manages knowledge packs (list/status/reload)
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
|
+
import { parseArgs } from 'citty'
|
|
6
7
|
import {
|
|
7
8
|
renderLogo, theme, heading, successText, warningText, errorText, dimText,
|
|
8
9
|
box, summaryPanel, withSpinner,
|
|
9
10
|
} from '@/cli/ui/index.js'
|
|
10
|
-
import { readFileSync } from 'node:fs'
|
|
11
11
|
import { resolve, dirname, join } from 'node:path'
|
|
12
12
|
import { fileURLToPath } from 'node:url'
|
|
13
13
|
import { PackManager } from '@/packs/manager'
|
|
@@ -49,17 +49,22 @@ function createPackManager(): PackManager {
|
|
|
49
49
|
}
|
|
50
50
|
|
|
51
51
|
export async function runPack() {
|
|
52
|
-
const
|
|
52
|
+
const args = parseArgs(process.argv.slice(3), {
|
|
53
|
+
subcommand: { type: 'positional', required: false, description: 'list|status|reload' },
|
|
54
|
+
project: { type: 'positional', required: false, description: 'Project name' },
|
|
55
|
+
})
|
|
56
|
+
|
|
57
|
+
const subcommand: string = args.subcommand ?? 'list'
|
|
53
58
|
|
|
54
59
|
switch (subcommand) {
|
|
55
60
|
case 'list':
|
|
56
61
|
await handleList()
|
|
57
62
|
break
|
|
58
63
|
case 'status':
|
|
59
|
-
await handleStatus()
|
|
64
|
+
await handleStatus(args.project)
|
|
60
65
|
break
|
|
61
66
|
case 'reload':
|
|
62
|
-
await handleReload()
|
|
67
|
+
await handleReload(args.project)
|
|
63
68
|
break
|
|
64
69
|
default:
|
|
65
70
|
console.log()
|
|
@@ -102,14 +107,13 @@ async function handleList() {
|
|
|
102
107
|
console.log()
|
|
103
108
|
}
|
|
104
109
|
|
|
105
|
-
async function handleStatus() {
|
|
110
|
+
async function handleStatus(project?: string) {
|
|
106
111
|
console.log()
|
|
107
112
|
console.log(renderLogo())
|
|
108
113
|
console.log()
|
|
109
114
|
console.log(heading('Pack Status'))
|
|
110
115
|
console.log()
|
|
111
116
|
|
|
112
|
-
const project = process.argv[4]
|
|
113
117
|
if (!project) {
|
|
114
118
|
console.log(warningText(' Usage: claude-brain pack status <project-name>'))
|
|
115
119
|
console.log(dimText(' Example: claude-brain pack status my-app'))
|
|
@@ -139,14 +143,13 @@ async function handleStatus() {
|
|
|
139
143
|
console.log()
|
|
140
144
|
}
|
|
141
145
|
|
|
142
|
-
async function handleReload() {
|
|
146
|
+
async function handleReload(project?: string) {
|
|
143
147
|
console.log()
|
|
144
148
|
console.log(renderLogo())
|
|
145
149
|
console.log()
|
|
146
150
|
console.log(heading('Reload Knowledge Packs'))
|
|
147
151
|
console.log()
|
|
148
152
|
|
|
149
|
-
const project = process.argv[4]
|
|
150
153
|
if (!project) {
|
|
151
154
|
console.log(warningText(' Usage: claude-brain pack reload <project-name>'))
|
|
152
155
|
console.log(dimText(' This clears the manifest so packs are re-loaded on next init_project'))
|
|
@@ -176,8 +176,8 @@ export async function runRefresh() {
|
|
|
176
176
|
killByPattern('chroma run')
|
|
177
177
|
}
|
|
178
178
|
|
|
179
|
-
// Kill by port (HTTP API
|
|
180
|
-
killByPort(
|
|
179
|
+
// Kill by port (HTTP API 3000, ChromaDB 8000)
|
|
180
|
+
killByPort(3000)
|
|
181
181
|
killByPort(8000)
|
|
182
182
|
|
|
183
183
|
// Clean up stale PID file
|
|
@@ -38,7 +38,7 @@ export async function runServe() {
|
|
|
38
38
|
const logger = createLogger(config.logLevel, config.logFilePath)
|
|
39
39
|
const mainLogger = createComponentLogger(logger, 'main')
|
|
40
40
|
|
|
41
|
-
|
|
41
|
+
new GlobalErrorHandler(logger)
|
|
42
42
|
const cleanup = new CleanupManager(logger)
|
|
43
43
|
|
|
44
44
|
mainLogger.info({
|
|
@@ -7,13 +7,17 @@
|
|
|
7
7
|
* claude-brain start --chroma-only Start only ChromaDB server
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
|
+
import { parseArgs } from 'citty'
|
|
10
11
|
import {
|
|
11
12
|
heading, successText, warningText, dimText,
|
|
12
13
|
} from '@/cli/ui/index.js'
|
|
13
14
|
import { ensureChromaRunning } from '@/cli/commands/chroma'
|
|
14
15
|
|
|
15
16
|
export async function runStart(): Promise<void> {
|
|
16
|
-
const
|
|
17
|
+
const args = parseArgs(process.argv.slice(3), {
|
|
18
|
+
'chroma-only': { type: 'boolean', default: false, description: 'Start only ChromaDB server' },
|
|
19
|
+
})
|
|
20
|
+
const chromaOnly = args['chroma-only']
|
|
17
21
|
|
|
18
22
|
if (chromaOnly) {
|
|
19
23
|
console.log()
|
|
@@ -44,7 +44,7 @@ export async function runUpdate() {
|
|
|
44
44
|
const currentVersion = getInstalledVersion()
|
|
45
45
|
console.log(` ${theme.bold('Installed:')} ${dimText('v' + currentVersion)}`)
|
|
46
46
|
|
|
47
|
-
const latestVersion = await withSpinner('Checking for updates', () => getLatestVersion())
|
|
47
|
+
const latestVersion = await withSpinner('Checking for updates', async () => getLatestVersion())
|
|
48
48
|
|
|
49
49
|
if (latestVersion) {
|
|
50
50
|
console.log(` ${theme.bold('Latest:')} ${dimText('v' + latestVersion)}`)
|
|
@@ -54,7 +54,7 @@ export async function runUpdate() {
|
|
|
54
54
|
// Step 1: Update package if newer version available
|
|
55
55
|
if (latestVersion && latestVersion !== currentVersion) {
|
|
56
56
|
try {
|
|
57
|
-
await withSpinner(`Updating claude-brain to v${latestVersion}`, () => {
|
|
57
|
+
await withSpinner(`Updating claude-brain to v${latestVersion}`, async () => {
|
|
58
58
|
execSync('bun update -g claude-brain', {
|
|
59
59
|
encoding: 'utf-8',
|
|
60
60
|
stdio: ['pipe', 'pipe', 'pipe'],
|
|
@@ -16,7 +16,7 @@ for (const arg of args) {
|
|
|
16
16
|
if (arg === '--validate-after') options.validateAfter = true
|
|
17
17
|
if (arg === '--verbose') options.verbose = true
|
|
18
18
|
const batchMatch = arg.match(/--batch-size=(\d+)/)
|
|
19
|
-
if (batchMatch) options.batchSize = parseInt(batchMatch[1])
|
|
19
|
+
if (batchMatch) options.batchSize = parseInt(batchMatch[1]!)
|
|
20
20
|
}
|
|
21
21
|
|
|
22
22
|
// Create dedicated migration logger
|
package/src/config/defaults.ts
CHANGED
|
@@ -1,9 +1,11 @@
|
|
|
1
|
+
import pkg from '../../package.json'
|
|
1
2
|
import type { PartialConfig } from './schema'
|
|
2
3
|
|
|
3
4
|
/** Default configuration values for Claude Brain */
|
|
4
5
|
export const defaultConfig: PartialConfig = {
|
|
6
|
+
vaultPath: '',
|
|
5
7
|
serverName: 'claude-brain',
|
|
6
|
-
serverVersion:
|
|
8
|
+
serverVersion: pkg.version,
|
|
7
9
|
logLevel: 'info',
|
|
8
10
|
logFilePath: './logs/claude-brain.log',
|
|
9
11
|
dbPath: './data/memory.db',
|
package/src/config/index.ts
CHANGED
|
@@ -1,7 +1,5 @@
|
|
|
1
1
|
export { ConfigSchema, LogLevelSchema, type Config, type LogLevel, type PartialConfig } from './schema'
|
|
2
2
|
export { defaultConfig } from './defaults'
|
|
3
3
|
export { loadConfig, validateConfig, getConfigFilePath } from './loader'
|
|
4
|
-
export { ConfigWatcher, createConfigWatcher, type ConfigWatcherEvents } from './watcher'
|
|
5
4
|
export { ConfigValidator, type ValidationResult, type ValidationError, type ValidationWarning } from './validator'
|
|
6
|
-
export { ConfigMigration } from './migration'
|
|
7
5
|
export { getClaudeBrainHome, resolveHomePath, isHomeInitialized, getHomePaths } from './home'
|