claude-brain 0.17.5 → 0.17.7
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 +1 -1
- package/src/config/defaults.ts +1 -1
- package/src/config/schema.ts +1 -1
- package/src/hooks/context-hook.ts +60 -11
- package/src/hooks/installer.ts +1 -0
package/VERSION
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
0.17.
|
|
1
|
+
0.17.7
|
package/package.json
CHANGED
package/src/config/defaults.ts
CHANGED
|
@@ -3,7 +3,7 @@ import type { PartialConfig } from './schema'
|
|
|
3
3
|
/** Default configuration values for Claude Brain */
|
|
4
4
|
export const defaultConfig: PartialConfig = {
|
|
5
5
|
serverName: 'claude-brain',
|
|
6
|
-
serverVersion: '0.17.
|
|
6
|
+
serverVersion: '0.17.7',
|
|
7
7
|
logLevel: 'info',
|
|
8
8
|
logFilePath: './logs/claude-brain.log',
|
|
9
9
|
dbPath: './data/memory.db',
|
package/src/config/schema.ts
CHANGED
|
@@ -284,7 +284,7 @@ export const ConfigSchema = z.object({
|
|
|
284
284
|
serverName: z.string().default('claude-brain'),
|
|
285
285
|
|
|
286
286
|
/** Server version in semver format */
|
|
287
|
-
serverVersion: z.string().regex(/^\d+\.\d+\.\d+$/, 'Version must be semver format').default('0.17.
|
|
287
|
+
serverVersion: z.string().regex(/^\d+\.\d+\.\d+$/, 'Version must be semver format').default('0.17.7'),
|
|
288
288
|
|
|
289
289
|
/** Logging level */
|
|
290
290
|
logLevel: LogLevelSchema.default('info'),
|
|
@@ -1,16 +1,23 @@
|
|
|
1
1
|
#!/usr/bin/env bun
|
|
2
2
|
/**
|
|
3
|
-
* Phase 26
|
|
3
|
+
* Phase 26+: Context Injection Hook
|
|
4
4
|
* Runs on UserPromptSubmit and SessionStart to inject relevant memories
|
|
5
5
|
* into Claude's context via additionalContext.
|
|
6
6
|
*
|
|
7
|
+
* SessionStart also injects the static Claude Code Mastery guidelines
|
|
8
|
+
* (claude-code-mastery.md) to optimize Claude's behavior every session.
|
|
9
|
+
*
|
|
7
10
|
* CRITICAL CONSTRAINTS:
|
|
8
11
|
* - Must complete in <3s (blocks user prompt processing)
|
|
9
|
-
* - No heavy imports — just fetch + JSON parse
|
|
12
|
+
* - No heavy imports — just fetch + JSON parse + fs.readFileSync
|
|
10
13
|
* - All errors silently caught with process.exit(0)
|
|
11
14
|
* - Outputs JSON to stdout: { hookSpecificOutput: { additionalContext: "..." } }
|
|
12
15
|
*/
|
|
13
16
|
|
|
17
|
+
import { readFileSync, existsSync } from 'node:fs'
|
|
18
|
+
import { join, dirname } from 'node:path'
|
|
19
|
+
import { fileURLToPath } from 'node:url'
|
|
20
|
+
|
|
14
21
|
interface HookStdin {
|
|
15
22
|
session_id: string
|
|
16
23
|
hook_event_name: string
|
|
@@ -19,6 +26,30 @@ interface HookStdin {
|
|
|
19
26
|
source?: string
|
|
20
27
|
}
|
|
21
28
|
|
|
29
|
+
/** Cache the mastery doc in memory after first read */
|
|
30
|
+
let masteryCache: string | null = null
|
|
31
|
+
|
|
32
|
+
/** Read the static Claude Code Mastery guidelines from disk (once, then cached) */
|
|
33
|
+
function loadMasteryDoc(): string {
|
|
34
|
+
if (masteryCache !== null) return masteryCache
|
|
35
|
+
|
|
36
|
+
// Resolve relative to this script's location (works both in src/ and installed ~/.claude-brain/hooks/)
|
|
37
|
+
const scriptDir = (import.meta as any).dir ?? dirname(fileURLToPath(import.meta.url))
|
|
38
|
+
const masteryPath = join(scriptDir, 'claude-code-mastery.md')
|
|
39
|
+
|
|
40
|
+
try {
|
|
41
|
+
if (existsSync(masteryPath)) {
|
|
42
|
+
masteryCache = readFileSync(masteryPath, 'utf-8').trim()
|
|
43
|
+
} else {
|
|
44
|
+
masteryCache = ''
|
|
45
|
+
}
|
|
46
|
+
} catch {
|
|
47
|
+
masteryCache = ''
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
return masteryCache
|
|
51
|
+
}
|
|
52
|
+
|
|
22
53
|
async function main(): Promise<void> {
|
|
23
54
|
// Parse --event arg
|
|
24
55
|
const eventIdx = process.argv.indexOf('--event')
|
|
@@ -57,7 +88,7 @@ async function main(): Promise<void> {
|
|
|
57
88
|
const port = parseInt(process.env.CLAUDE_BRAIN_PORT || '3000', 10)
|
|
58
89
|
const baseUrl = `http://localhost:${port}`
|
|
59
90
|
|
|
60
|
-
let
|
|
91
|
+
let brainContext = ''
|
|
61
92
|
|
|
62
93
|
try {
|
|
63
94
|
if (event === 'UserPromptSubmit' && input.prompt) {
|
|
@@ -74,7 +105,7 @@ async function main(): Promise<void> {
|
|
|
74
105
|
|
|
75
106
|
if (res.ok) {
|
|
76
107
|
const data = await res.json() as { success: boolean; context: string }
|
|
77
|
-
|
|
108
|
+
brainContext = data.context || ''
|
|
78
109
|
}
|
|
79
110
|
} else if (event === 'SessionStart') {
|
|
80
111
|
// Load broader project context on session start
|
|
@@ -87,21 +118,39 @@ async function main(): Promise<void> {
|
|
|
87
118
|
|
|
88
119
|
if (res.ok) {
|
|
89
120
|
const data = await res.json() as { success: boolean; context: string }
|
|
90
|
-
|
|
121
|
+
brainContext = data.context || ''
|
|
91
122
|
}
|
|
92
123
|
}
|
|
93
124
|
} catch {
|
|
94
|
-
// Server unreachable or timeout —
|
|
95
|
-
|
|
96
|
-
|
|
125
|
+
// Server unreachable or timeout — continue with static content only for SessionStart
|
|
126
|
+
if (event !== 'SessionStart') {
|
|
127
|
+
process.exit(0)
|
|
128
|
+
return
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
// Build final injection content
|
|
133
|
+
const parts: string[] = []
|
|
134
|
+
|
|
135
|
+
// SessionStart: prepend static Claude Code Mastery guidelines
|
|
136
|
+
if (event === 'SessionStart') {
|
|
137
|
+
const mastery = loadMasteryDoc()
|
|
138
|
+
if (mastery) {
|
|
139
|
+
parts.push(`[Claude Code Mastery]\n${mastery}`)
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
// Append dynamic brain memories (both events)
|
|
144
|
+
if (brainContext.trim()) {
|
|
145
|
+
parts.push(`[Brain Memory]\n${brainContext}`)
|
|
97
146
|
}
|
|
98
147
|
|
|
99
|
-
//
|
|
100
|
-
if (
|
|
148
|
+
// Output combined context
|
|
149
|
+
if (parts.length > 0) {
|
|
101
150
|
const output = {
|
|
102
151
|
hookSpecificOutput: {
|
|
103
152
|
hookEventName: event,
|
|
104
|
-
additionalContext:
|
|
153
|
+
additionalContext: parts.join('\n\n'),
|
|
105
154
|
},
|
|
106
155
|
}
|
|
107
156
|
process.stdout.write(JSON.stringify(output))
|