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
|
@@ -1,204 +1,204 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* DecisionDetectionHandler - Auto-detects and stores decisions from decisions.md files
|
|
3
|
-
*/
|
|
4
|
-
|
|
5
|
-
import type { Logger } from 'pino'
|
|
6
|
-
import type { Event, EventType, EventPriority } from '../types'
|
|
7
|
-
import type { VaultReader } from '@/vault'
|
|
8
|
-
import type { MemoryManager } from '@/memory'
|
|
9
|
-
import { BaseHandler } from './base-handler'
|
|
10
|
-
import type { EventBus } from '../event-emitter'
|
|
11
|
-
|
|
12
|
-
export interface ExtractedDecision {
|
|
13
|
-
context: string
|
|
14
|
-
decision: string
|
|
15
|
-
reasoning: string
|
|
16
|
-
alternatives?: string
|
|
17
|
-
tags?: string[]
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
export class DecisionDetectionHandler extends BaseHandler {
|
|
21
|
-
name = 'decision-detection-handler'
|
|
22
|
-
types: EventType[] = ['file:modified']
|
|
23
|
-
priority: EventPriority = 'high'
|
|
24
|
-
|
|
25
|
-
private vaultReader: VaultReader
|
|
26
|
-
private memory: MemoryManager
|
|
27
|
-
private lastProcessed: Map<string, Date>
|
|
28
|
-
private eventBus: EventBus | null = null
|
|
29
|
-
private debounceMs: number
|
|
30
|
-
|
|
31
|
-
constructor(
|
|
32
|
-
logger: Logger,
|
|
33
|
-
vaultReader: VaultReader,
|
|
34
|
-
memory: MemoryManager,
|
|
35
|
-
debounceMs: number = 5000
|
|
36
|
-
) {
|
|
37
|
-
super(logger)
|
|
38
|
-
this.initLogger(logger)
|
|
39
|
-
this.vaultReader = vaultReader
|
|
40
|
-
this.memory = memory
|
|
41
|
-
this.lastProcessed = new Map()
|
|
42
|
-
this.debounceMs = debounceMs
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
/**
|
|
46
|
-
* Set the event bus for emitting decision events
|
|
47
|
-
*/
|
|
48
|
-
setEventBus(eventBus: EventBus): void {
|
|
49
|
-
this.eventBus = eventBus
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
async handle(event: Event): Promise<void> {
|
|
53
|
-
this.logHandling(event)
|
|
54
|
-
|
|
55
|
-
const filePath = event.payload.path as string
|
|
56
|
-
|
|
57
|
-
// Only process decisions.md files
|
|
58
|
-
if (!this.shouldHandleFile(filePath, ['decisions.md'])) {
|
|
59
|
-
return
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
try {
|
|
63
|
-
// Check if we've processed recently (debounce)
|
|
64
|
-
const lastTime = this.lastProcessed.get(filePath)
|
|
65
|
-
if (lastTime && Date.now() - lastTime.getTime() < this.debounceMs) {
|
|
66
|
-
this.logger.debug({ filePath }, 'Debounced, skipping')
|
|
67
|
-
return
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
const file = await this.vaultReader.readMarkdownFile(filePath, false)
|
|
71
|
-
const project = file.frontmatter.project as string | undefined
|
|
72
|
-
|
|
73
|
-
if (!project) {
|
|
74
|
-
this.logger.warn({ filePath }, 'No project in frontmatter, skipping')
|
|
75
|
-
return
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
// Extract new decisions from content
|
|
79
|
-
const decisions = this.extractDecisions(file.content)
|
|
80
|
-
|
|
81
|
-
if (decisions.length === 0) {
|
|
82
|
-
return
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
let storedCount = 0
|
|
86
|
-
for (const decision of decisions) {
|
|
87
|
-
try {
|
|
88
|
-
// Check for duplicates before storing
|
|
89
|
-
const existing = await this.memory.searchRaw(decision.decision, {
|
|
90
|
-
project,
|
|
91
|
-
limit: 1,
|
|
92
|
-
minSimilarity: 0.9
|
|
93
|
-
})
|
|
94
|
-
|
|
95
|
-
if (existing.length > 0 && existing[0].similarity >= 0.9) {
|
|
96
|
-
this.logger.debug(
|
|
97
|
-
{ existingId: existing[0].memory?.id, similarity: existing[0].similarity },
|
|
98
|
-
'Skipping duplicate decision'
|
|
99
|
-
)
|
|
100
|
-
continue
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
// Store in memory system
|
|
104
|
-
await this.memory.rememberDecision(
|
|
105
|
-
project,
|
|
106
|
-
decision.context,
|
|
107
|
-
decision.decision,
|
|
108
|
-
decision.reasoning,
|
|
109
|
-
{
|
|
110
|
-
alternatives: decision.alternatives,
|
|
111
|
-
tags: decision.tags
|
|
112
|
-
}
|
|
113
|
-
)
|
|
114
|
-
|
|
115
|
-
storedCount++
|
|
116
|
-
|
|
117
|
-
this.logger.info(
|
|
118
|
-
{ project, decision: decision.decision.slice(0, 50) },
|
|
119
|
-
'Decision auto-stored in memory'
|
|
120
|
-
)
|
|
121
|
-
|
|
122
|
-
// Emit decision event if event bus is available
|
|
123
|
-
if (this.eventBus) {
|
|
124
|
-
this.eventBus.emitEvent(
|
|
125
|
-
'decision:made',
|
|
126
|
-
{
|
|
127
|
-
decision,
|
|
128
|
-
filePath,
|
|
129
|
-
project
|
|
130
|
-
},
|
|
131
|
-
this.name
|
|
132
|
-
)
|
|
133
|
-
}
|
|
134
|
-
} catch (error) {
|
|
135
|
-
this.logger.error(
|
|
136
|
-
{ error, decision: decision.decision.slice(0, 50) },
|
|
137
|
-
'Failed to store decision'
|
|
138
|
-
)
|
|
139
|
-
}
|
|
140
|
-
}
|
|
141
|
-
|
|
142
|
-
this.lastProcessed.set(filePath, new Date())
|
|
143
|
-
this.logSuccess(event, { decisionsStored: storedCount })
|
|
144
|
-
} catch (error) {
|
|
145
|
-
this.logError(event, error)
|
|
146
|
-
}
|
|
147
|
-
}
|
|
148
|
-
|
|
149
|
-
/**
|
|
150
|
-
* Extract decisions from markdown content
|
|
151
|
-
*/
|
|
152
|
-
private extractDecisions(content: string): ExtractedDecision[] {
|
|
153
|
-
const decisions: ExtractedDecision[] = []
|
|
154
|
-
|
|
155
|
-
// Look for decision entries in format:
|
|
156
|
-
// ### Decision: [title]
|
|
157
|
-
// **Context:** [context]
|
|
158
|
-
// **Decision:** [decision]
|
|
159
|
-
// **Reasoning:** [reasoning]
|
|
160
|
-
const decisionRegex = /###\s+Decision[:\s]+(.+?)(?:\n|$)/gi
|
|
161
|
-
|
|
162
|
-
let match
|
|
163
|
-
while ((match = decisionRegex.exec(content)) !== null) {
|
|
164
|
-
const sectionStart = match.index
|
|
165
|
-
const nextSection = content.indexOf('###', sectionStart + 1)
|
|
166
|
-
const sectionEnd = nextSection === -1 ? content.length : nextSection
|
|
167
|
-
const section = content.slice(sectionStart, sectionEnd)
|
|
168
|
-
|
|
169
|
-
// Extract fields
|
|
170
|
-
const contextMatch = /\*\*Context:\*\*\s*(.+?)(?:\n\n|\n\*\*|$)/is.exec(section)
|
|
171
|
-
const decisionMatch = /\*\*Decision:\*\*\s*(.+?)(?:\n\n|\n\*\*|$)/is.exec(section)
|
|
172
|
-
const reasoningMatch = /\*\*Reasoning:\*\*\s*(.+?)(?:\n\n|\n\*\*|$)/is.exec(section)
|
|
173
|
-
const alternativesMatch = /\*\*Alternatives(?:\s+Considered)?:\*\*\s*(.+?)(?:\n\n|\n\*\*|$)/is.exec(section)
|
|
174
|
-
const tagsMatch = /\*\*Tags:\*\*\s*(.+?)(?:\n|$)/i.exec(section)
|
|
175
|
-
|
|
176
|
-
if (contextMatch?.[1] && decisionMatch?.[1] && reasoningMatch?.[1]) {
|
|
177
|
-
decisions.push({
|
|
178
|
-
context: contextMatch[1].trim(),
|
|
179
|
-
decision: decisionMatch[1].trim(),
|
|
180
|
-
reasoning: reasoningMatch[1].trim(),
|
|
181
|
-
alternatives: alternativesMatch?.[1]?.trim(),
|
|
182
|
-
tags: tagsMatch?.[1]?.split(',').map(t => t.trim())
|
|
183
|
-
})
|
|
184
|
-
}
|
|
185
|
-
}
|
|
186
|
-
|
|
187
|
-
return decisions
|
|
188
|
-
}
|
|
189
|
-
|
|
190
|
-
/**
|
|
191
|
-
* Get last processed time for a file
|
|
192
|
-
*/
|
|
193
|
-
getLastProcessedTime(filePath: string): Date | undefined {
|
|
194
|
-
return this.lastProcessed.get(filePath)
|
|
195
|
-
}
|
|
196
|
-
|
|
197
|
-
/**
|
|
198
|
-
* Clear processing history
|
|
199
|
-
*/
|
|
200
|
-
clearProcessingHistory(): void {
|
|
201
|
-
this.lastProcessed.clear()
|
|
202
|
-
this.logger.debug('Processing history cleared')
|
|
203
|
-
}
|
|
204
|
-
}
|
|
1
|
+
/**
|
|
2
|
+
* DecisionDetectionHandler - Auto-detects and stores decisions from decisions.md files
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
import type { Logger } from 'pino'
|
|
6
|
+
import type { Event, EventType, EventPriority } from '../types'
|
|
7
|
+
import type { VaultReader } from '@/vault'
|
|
8
|
+
import type { MemoryManager } from '@/memory'
|
|
9
|
+
import { BaseHandler } from './base-handler'
|
|
10
|
+
import type { EventBus } from '../event-emitter'
|
|
11
|
+
|
|
12
|
+
export interface ExtractedDecision {
|
|
13
|
+
context: string
|
|
14
|
+
decision: string
|
|
15
|
+
reasoning: string
|
|
16
|
+
alternatives?: string
|
|
17
|
+
tags?: string[]
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export class DecisionDetectionHandler extends BaseHandler {
|
|
21
|
+
name = 'decision-detection-handler'
|
|
22
|
+
types: EventType[] = ['file:modified']
|
|
23
|
+
priority: EventPriority = 'high'
|
|
24
|
+
|
|
25
|
+
private vaultReader: VaultReader
|
|
26
|
+
private memory: MemoryManager
|
|
27
|
+
private lastProcessed: Map<string, Date>
|
|
28
|
+
private eventBus: EventBus | null = null
|
|
29
|
+
private debounceMs: number
|
|
30
|
+
|
|
31
|
+
constructor(
|
|
32
|
+
logger: Logger,
|
|
33
|
+
vaultReader: VaultReader,
|
|
34
|
+
memory: MemoryManager,
|
|
35
|
+
debounceMs: number = 5000
|
|
36
|
+
) {
|
|
37
|
+
super(logger)
|
|
38
|
+
this.initLogger(logger)
|
|
39
|
+
this.vaultReader = vaultReader
|
|
40
|
+
this.memory = memory
|
|
41
|
+
this.lastProcessed = new Map()
|
|
42
|
+
this.debounceMs = debounceMs
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* Set the event bus for emitting decision events
|
|
47
|
+
*/
|
|
48
|
+
setEventBus(eventBus: EventBus): void {
|
|
49
|
+
this.eventBus = eventBus
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
async handle(event: Event): Promise<void> {
|
|
53
|
+
this.logHandling(event)
|
|
54
|
+
|
|
55
|
+
const filePath = event.payload.path as string
|
|
56
|
+
|
|
57
|
+
// Only process decisions.md files
|
|
58
|
+
if (!this.shouldHandleFile(filePath, ['decisions.md'])) {
|
|
59
|
+
return
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
try {
|
|
63
|
+
// Check if we've processed recently (debounce)
|
|
64
|
+
const lastTime = this.lastProcessed.get(filePath)
|
|
65
|
+
if (lastTime && Date.now() - lastTime.getTime() < this.debounceMs) {
|
|
66
|
+
this.logger.debug({ filePath }, 'Debounced, skipping')
|
|
67
|
+
return
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
const file = await this.vaultReader.readMarkdownFile(filePath, false)
|
|
71
|
+
const project = file.frontmatter.project as string | undefined
|
|
72
|
+
|
|
73
|
+
if (!project) {
|
|
74
|
+
this.logger.warn({ filePath }, 'No project in frontmatter, skipping')
|
|
75
|
+
return
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
// Extract new decisions from content
|
|
79
|
+
const decisions = this.extractDecisions(file.content)
|
|
80
|
+
|
|
81
|
+
if (decisions.length === 0) {
|
|
82
|
+
return
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
let storedCount = 0
|
|
86
|
+
for (const decision of decisions) {
|
|
87
|
+
try {
|
|
88
|
+
// Check for duplicates before storing
|
|
89
|
+
const existing = await this.memory.searchRaw(decision.decision, {
|
|
90
|
+
project,
|
|
91
|
+
limit: 1,
|
|
92
|
+
minSimilarity: 0.9
|
|
93
|
+
})
|
|
94
|
+
|
|
95
|
+
if (existing.length > 0 && existing[0].similarity >= 0.9) {
|
|
96
|
+
this.logger.debug(
|
|
97
|
+
{ existingId: existing[0].memory?.id, similarity: existing[0].similarity },
|
|
98
|
+
'Skipping duplicate decision'
|
|
99
|
+
)
|
|
100
|
+
continue
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
// Store in memory system
|
|
104
|
+
await this.memory.rememberDecision(
|
|
105
|
+
project,
|
|
106
|
+
decision.context,
|
|
107
|
+
decision.decision,
|
|
108
|
+
decision.reasoning,
|
|
109
|
+
{
|
|
110
|
+
alternatives: decision.alternatives,
|
|
111
|
+
tags: decision.tags
|
|
112
|
+
}
|
|
113
|
+
)
|
|
114
|
+
|
|
115
|
+
storedCount++
|
|
116
|
+
|
|
117
|
+
this.logger.info(
|
|
118
|
+
{ project, decision: decision.decision.slice(0, 50) },
|
|
119
|
+
'Decision auto-stored in memory'
|
|
120
|
+
)
|
|
121
|
+
|
|
122
|
+
// Emit decision event if event bus is available
|
|
123
|
+
if (this.eventBus) {
|
|
124
|
+
this.eventBus.emitEvent(
|
|
125
|
+
'decision:made',
|
|
126
|
+
{
|
|
127
|
+
decision,
|
|
128
|
+
filePath,
|
|
129
|
+
project
|
|
130
|
+
},
|
|
131
|
+
this.name
|
|
132
|
+
)
|
|
133
|
+
}
|
|
134
|
+
} catch (error) {
|
|
135
|
+
this.logger.error(
|
|
136
|
+
{ error, decision: decision.decision.slice(0, 50) },
|
|
137
|
+
'Failed to store decision'
|
|
138
|
+
)
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
this.lastProcessed.set(filePath, new Date())
|
|
143
|
+
this.logSuccess(event, { decisionsStored: storedCount })
|
|
144
|
+
} catch (error) {
|
|
145
|
+
this.logError(event, error)
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
/**
|
|
150
|
+
* Extract decisions from markdown content
|
|
151
|
+
*/
|
|
152
|
+
private extractDecisions(content: string): ExtractedDecision[] {
|
|
153
|
+
const decisions: ExtractedDecision[] = []
|
|
154
|
+
|
|
155
|
+
// Look for decision entries in format:
|
|
156
|
+
// ### Decision: [title]
|
|
157
|
+
// **Context:** [context]
|
|
158
|
+
// **Decision:** [decision]
|
|
159
|
+
// **Reasoning:** [reasoning]
|
|
160
|
+
const decisionRegex = /###\s+Decision[:\s]+(.+?)(?:\n|$)/gi
|
|
161
|
+
|
|
162
|
+
let match
|
|
163
|
+
while ((match = decisionRegex.exec(content)) !== null) {
|
|
164
|
+
const sectionStart = match.index
|
|
165
|
+
const nextSection = content.indexOf('###', sectionStart + 1)
|
|
166
|
+
const sectionEnd = nextSection === -1 ? content.length : nextSection
|
|
167
|
+
const section = content.slice(sectionStart, sectionEnd)
|
|
168
|
+
|
|
169
|
+
// Extract fields
|
|
170
|
+
const contextMatch = /\*\*Context:\*\*\s*(.+?)(?:\n\n|\n\*\*|$)/is.exec(section)
|
|
171
|
+
const decisionMatch = /\*\*Decision:\*\*\s*(.+?)(?:\n\n|\n\*\*|$)/is.exec(section)
|
|
172
|
+
const reasoningMatch = /\*\*Reasoning:\*\*\s*(.+?)(?:\n\n|\n\*\*|$)/is.exec(section)
|
|
173
|
+
const alternativesMatch = /\*\*Alternatives(?:\s+Considered)?:\*\*\s*(.+?)(?:\n\n|\n\*\*|$)/is.exec(section)
|
|
174
|
+
const tagsMatch = /\*\*Tags:\*\*\s*(.+?)(?:\n|$)/i.exec(section)
|
|
175
|
+
|
|
176
|
+
if (contextMatch?.[1] && decisionMatch?.[1] && reasoningMatch?.[1]) {
|
|
177
|
+
decisions.push({
|
|
178
|
+
context: contextMatch[1].trim(),
|
|
179
|
+
decision: decisionMatch[1].trim(),
|
|
180
|
+
reasoning: reasoningMatch[1].trim(),
|
|
181
|
+
alternatives: alternativesMatch?.[1]?.trim(),
|
|
182
|
+
tags: tagsMatch?.[1]?.split(',').map(t => t.trim())
|
|
183
|
+
})
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
return decisions
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
/**
|
|
191
|
+
* Get last processed time for a file
|
|
192
|
+
*/
|
|
193
|
+
getLastProcessedTime(filePath: string): Date | undefined {
|
|
194
|
+
return this.lastProcessed.get(filePath)
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
/**
|
|
198
|
+
* Clear processing history
|
|
199
|
+
*/
|
|
200
|
+
clearProcessingHistory(): void {
|
|
201
|
+
this.lastProcessed.clear()
|
|
202
|
+
this.logger.debug('Processing history cleared')
|
|
203
|
+
}
|
|
204
|
+
}
|
package/src/packs/index.ts
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Phase 18: Knowledge Packs
|
|
3
|
-
* Pre-seeded knowledge for zero cold-start experience
|
|
4
|
-
*/
|
|
5
|
-
|
|
6
|
-
export * from './types'
|
|
7
|
-
export { PackManager } from './manager'
|
|
8
|
-
export { PackLoader } from './loader'
|
|
9
|
-
export { KnowledgeRanker, type RankedResult } from './ranker'
|
|
1
|
+
/**
|
|
2
|
+
* Phase 18: Knowledge Packs
|
|
3
|
+
* Pre-seeded knowledge for zero cold-start experience
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
export * from './types'
|
|
7
|
+
export { PackManager } from './manager'
|
|
8
|
+
export { PackLoader } from './loader'
|
|
9
|
+
export { KnowledgeRanker, type RankedResult } from './ranker'
|