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
|
@@ -1,228 +1,228 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* DecisionLogger - Automatically capture and store project decisions
|
|
3
|
-
*/
|
|
4
|
-
|
|
5
|
-
import type { Logger } from 'pino'
|
|
6
|
-
import type { MemoryManager } from '@/memory'
|
|
7
|
-
import type { VaultWriter } from '@/vault'
|
|
8
|
-
import { randomUUID } from 'crypto'
|
|
9
|
-
|
|
10
|
-
export interface DecisionEntry {
|
|
11
|
-
id: string
|
|
12
|
-
project: string
|
|
13
|
-
title: string
|
|
14
|
-
context: string
|
|
15
|
-
decision: string
|
|
16
|
-
reasoning: string
|
|
17
|
-
alternatives?: string
|
|
18
|
-
impact?: string
|
|
19
|
-
outcome?: string
|
|
20
|
-
tags?: string[]
|
|
21
|
-
timestamp: Date
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
export class DecisionLogger {
|
|
25
|
-
private logger: Logger
|
|
26
|
-
private memory: MemoryManager
|
|
27
|
-
private vaultWriter: VaultWriter
|
|
28
|
-
|
|
29
|
-
constructor(
|
|
30
|
-
logger: Logger,
|
|
31
|
-
memory: MemoryManager,
|
|
32
|
-
vaultWriter: VaultWriter
|
|
33
|
-
) {
|
|
34
|
-
this.logger = logger.child({ component: 'decision-logger' })
|
|
35
|
-
this.memory = memory
|
|
36
|
-
this.vaultWriter = vaultWriter
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
/**
|
|
40
|
-
* Log a decision to both vault and memory
|
|
41
|
-
*/
|
|
42
|
-
async logDecision(
|
|
43
|
-
decision: Omit<DecisionEntry, 'id' | 'timestamp'>
|
|
44
|
-
): Promise<DecisionEntry> {
|
|
45
|
-
const fullDecision: DecisionEntry = {
|
|
46
|
-
...decision,
|
|
47
|
-
id: randomUUID(),
|
|
48
|
-
timestamp: new Date()
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
try {
|
|
52
|
-
this.logger.info(
|
|
53
|
-
{ decision: decision.title, project: decision.project },
|
|
54
|
-
'Logging decision'
|
|
55
|
-
)
|
|
56
|
-
|
|
57
|
-
// Store in memory system
|
|
58
|
-
await this.memory.rememberDecision(
|
|
59
|
-
fullDecision.project,
|
|
60
|
-
fullDecision.context,
|
|
61
|
-
fullDecision.decision,
|
|
62
|
-
fullDecision.reasoning,
|
|
63
|
-
{
|
|
64
|
-
alternatives: fullDecision.alternatives,
|
|
65
|
-
tags: fullDecision.tags
|
|
66
|
-
}
|
|
67
|
-
)
|
|
68
|
-
|
|
69
|
-
// Append to vault decisions file
|
|
70
|
-
await this.appendToVault(fullDecision)
|
|
71
|
-
|
|
72
|
-
this.logger.info(
|
|
73
|
-
{ decisionId: fullDecision.id, project: fullDecision.project },
|
|
74
|
-
'Decision logged successfully'
|
|
75
|
-
)
|
|
76
|
-
|
|
77
|
-
return fullDecision
|
|
78
|
-
} catch (error) {
|
|
79
|
-
this.logger.error(
|
|
80
|
-
{ error, decision: decision.title },
|
|
81
|
-
'Failed to log decision'
|
|
82
|
-
)
|
|
83
|
-
throw error
|
|
84
|
-
}
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
/**
|
|
88
|
-
* Append decision to vault decisions file
|
|
89
|
-
*/
|
|
90
|
-
private async appendToVault(decision: DecisionEntry): Promise<void> {
|
|
91
|
-
const filePath = `Projects/${decision.project}/decisions.md`
|
|
92
|
-
|
|
93
|
-
const entry = this.formatDecisionEntry(decision)
|
|
94
|
-
|
|
95
|
-
await this.vaultWriter.appendContent(filePath, entry)
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
/**
|
|
99
|
-
* Format decision as markdown
|
|
100
|
-
*/
|
|
101
|
-
private formatDecisionEntry(decision: DecisionEntry): string {
|
|
102
|
-
const date = decision.timestamp.toISOString().split('T')[0]
|
|
103
|
-
|
|
104
|
-
let entry = `### Decision: ${decision.title}\n\n`
|
|
105
|
-
entry += `**Date:** ${date}\n\n`
|
|
106
|
-
entry += `**Context:** ${decision.context}\n\n`
|
|
107
|
-
entry += `**Decision:** ${decision.decision}\n\n`
|
|
108
|
-
entry += `**Reasoning:** ${decision.reasoning}\n\n`
|
|
109
|
-
|
|
110
|
-
if (decision.alternatives) {
|
|
111
|
-
entry += `**Alternatives Considered:** ${decision.alternatives}\n\n`
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
if (decision.impact) {
|
|
115
|
-
entry += `**Expected Impact:** ${decision.impact}\n\n`
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
if (decision.outcome) {
|
|
119
|
-
entry += `**Outcome:** ${decision.outcome}\n\n`
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
if (decision.tags) {
|
|
123
|
-
const tags = Array.isArray(decision.tags)
|
|
124
|
-
? decision.tags.join(', ')
|
|
125
|
-
: decision.tags
|
|
126
|
-
entry += `**Tags:** ${tags}\n\n`
|
|
127
|
-
}
|
|
128
|
-
|
|
129
|
-
return entry + '---\n\n'
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
/**
|
|
133
|
-
* Detect decision patterns in text
|
|
134
|
-
*/
|
|
135
|
-
static detectDecision(text: string): boolean {
|
|
136
|
-
const decisionKeywords = [
|
|
137
|
-
'decided to',
|
|
138
|
-
'decision:',
|
|
139
|
-
'chose to',
|
|
140
|
-
'selected',
|
|
141
|
-
'went with',
|
|
142
|
-
'opted for',
|
|
143
|
-
'concluded that',
|
|
144
|
-
'we will use',
|
|
145
|
-
'adopting',
|
|
146
|
-
'implementing'
|
|
147
|
-
]
|
|
148
|
-
|
|
149
|
-
const lowerText = text.toLowerCase()
|
|
150
|
-
return decisionKeywords.some(keyword => lowerText.includes(keyword))
|
|
151
|
-
}
|
|
152
|
-
|
|
153
|
-
/**
|
|
154
|
-
* Extract decision from natural language
|
|
155
|
-
*/
|
|
156
|
-
static extractDecisionFromText(text: string): Partial<DecisionEntry> | null {
|
|
157
|
-
// Try to match common decision patterns
|
|
158
|
-
const patterns = [
|
|
159
|
-
/decided to (.+?)(?:\.|$)/i,
|
|
160
|
-
/chose to (.+?)(?:\.|$)/i,
|
|
161
|
-
/going with (.+?)(?:\.|$)/i,
|
|
162
|
-
/we will use (.+?)(?:\.|$)/i,
|
|
163
|
-
/adopting (.+?)(?:\.|$)/i
|
|
164
|
-
]
|
|
165
|
-
|
|
166
|
-
let decision: string | null = null
|
|
167
|
-
for (const pattern of patterns) {
|
|
168
|
-
const match = pattern.exec(text)
|
|
169
|
-
if (match?.[1]) {
|
|
170
|
-
decision = match[1].trim()
|
|
171
|
-
break
|
|
172
|
-
}
|
|
173
|
-
}
|
|
174
|
-
|
|
175
|
-
if (!decision) {
|
|
176
|
-
return null
|
|
177
|
-
}
|
|
178
|
-
|
|
179
|
-
// Try to extract reasoning
|
|
180
|
-
const reasoningPatterns = [
|
|
181
|
-
/because (.+?)(?:\.|$)/i,
|
|
182
|
-
/since (.+?)(?:\.|$)/i,
|
|
183
|
-
/due to (.+?)(?:\.|$)/i,
|
|
184
|
-
/as (.+?)(?:\.|$)/i
|
|
185
|
-
]
|
|
186
|
-
|
|
187
|
-
let reasoning: string | undefined
|
|
188
|
-
for (const pattern of reasoningPatterns) {
|
|
189
|
-
const match = pattern.exec(text)
|
|
190
|
-
if (match?.[1]) {
|
|
191
|
-
reasoning = match[1].trim()
|
|
192
|
-
break
|
|
193
|
-
}
|
|
194
|
-
}
|
|
195
|
-
|
|
196
|
-
return {
|
|
197
|
-
decision,
|
|
198
|
-
reasoning
|
|
199
|
-
}
|
|
200
|
-
}
|
|
201
|
-
|
|
202
|
-
/**
|
|
203
|
-
* Create a decision entry from minimal input
|
|
204
|
-
*/
|
|
205
|
-
static createDecisionEntry(
|
|
206
|
-
project: string,
|
|
207
|
-
title: string,
|
|
208
|
-
decision: string,
|
|
209
|
-
reasoning: string,
|
|
210
|
-
options?: {
|
|
211
|
-
context?: string
|
|
212
|
-
alternatives?: string
|
|
213
|
-
impact?: string
|
|
214
|
-
tags?: string[]
|
|
215
|
-
}
|
|
216
|
-
): Omit<DecisionEntry, 'id' | 'timestamp'> {
|
|
217
|
-
return {
|
|
218
|
-
project,
|
|
219
|
-
title,
|
|
220
|
-
context: options?.context || `Decision about ${title}`,
|
|
221
|
-
decision,
|
|
222
|
-
reasoning,
|
|
223
|
-
alternatives: options?.alternatives,
|
|
224
|
-
impact: options?.impact,
|
|
225
|
-
tags: options?.tags
|
|
226
|
-
}
|
|
227
|
-
}
|
|
228
|
-
}
|
|
1
|
+
/**
|
|
2
|
+
* DecisionLogger - Automatically capture and store project decisions
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
import type { Logger } from 'pino'
|
|
6
|
+
import type { MemoryManager } from '@/memory'
|
|
7
|
+
import type { VaultWriter } from '@/vault'
|
|
8
|
+
import { randomUUID } from 'crypto'
|
|
9
|
+
|
|
10
|
+
export interface DecisionEntry {
|
|
11
|
+
id: string
|
|
12
|
+
project: string
|
|
13
|
+
title: string
|
|
14
|
+
context: string
|
|
15
|
+
decision: string
|
|
16
|
+
reasoning: string
|
|
17
|
+
alternatives?: string
|
|
18
|
+
impact?: string
|
|
19
|
+
outcome?: string
|
|
20
|
+
tags?: string[]
|
|
21
|
+
timestamp: Date
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export class DecisionLogger {
|
|
25
|
+
private logger: Logger
|
|
26
|
+
private memory: MemoryManager
|
|
27
|
+
private vaultWriter: VaultWriter
|
|
28
|
+
|
|
29
|
+
constructor(
|
|
30
|
+
logger: Logger,
|
|
31
|
+
memory: MemoryManager,
|
|
32
|
+
vaultWriter: VaultWriter
|
|
33
|
+
) {
|
|
34
|
+
this.logger = logger.child({ component: 'decision-logger' })
|
|
35
|
+
this.memory = memory
|
|
36
|
+
this.vaultWriter = vaultWriter
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* Log a decision to both vault and memory
|
|
41
|
+
*/
|
|
42
|
+
async logDecision(
|
|
43
|
+
decision: Omit<DecisionEntry, 'id' | 'timestamp'>
|
|
44
|
+
): Promise<DecisionEntry> {
|
|
45
|
+
const fullDecision: DecisionEntry = {
|
|
46
|
+
...decision,
|
|
47
|
+
id: randomUUID(),
|
|
48
|
+
timestamp: new Date()
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
try {
|
|
52
|
+
this.logger.info(
|
|
53
|
+
{ decision: decision.title, project: decision.project },
|
|
54
|
+
'Logging decision'
|
|
55
|
+
)
|
|
56
|
+
|
|
57
|
+
// Store in memory system
|
|
58
|
+
await this.memory.rememberDecision(
|
|
59
|
+
fullDecision.project,
|
|
60
|
+
fullDecision.context,
|
|
61
|
+
fullDecision.decision,
|
|
62
|
+
fullDecision.reasoning,
|
|
63
|
+
{
|
|
64
|
+
alternatives: fullDecision.alternatives,
|
|
65
|
+
tags: fullDecision.tags
|
|
66
|
+
}
|
|
67
|
+
)
|
|
68
|
+
|
|
69
|
+
// Append to vault decisions file
|
|
70
|
+
await this.appendToVault(fullDecision)
|
|
71
|
+
|
|
72
|
+
this.logger.info(
|
|
73
|
+
{ decisionId: fullDecision.id, project: fullDecision.project },
|
|
74
|
+
'Decision logged successfully'
|
|
75
|
+
)
|
|
76
|
+
|
|
77
|
+
return fullDecision
|
|
78
|
+
} catch (error) {
|
|
79
|
+
this.logger.error(
|
|
80
|
+
{ error, decision: decision.title },
|
|
81
|
+
'Failed to log decision'
|
|
82
|
+
)
|
|
83
|
+
throw error
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
/**
|
|
88
|
+
* Append decision to vault decisions file
|
|
89
|
+
*/
|
|
90
|
+
private async appendToVault(decision: DecisionEntry): Promise<void> {
|
|
91
|
+
const filePath = `Projects/${decision.project}/decisions.md`
|
|
92
|
+
|
|
93
|
+
const entry = this.formatDecisionEntry(decision)
|
|
94
|
+
|
|
95
|
+
await this.vaultWriter.appendContent(filePath, entry)
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
/**
|
|
99
|
+
* Format decision as markdown
|
|
100
|
+
*/
|
|
101
|
+
private formatDecisionEntry(decision: DecisionEntry): string {
|
|
102
|
+
const date = decision.timestamp.toISOString().split('T')[0]
|
|
103
|
+
|
|
104
|
+
let entry = `### Decision: ${decision.title}\n\n`
|
|
105
|
+
entry += `**Date:** ${date}\n\n`
|
|
106
|
+
entry += `**Context:** ${decision.context}\n\n`
|
|
107
|
+
entry += `**Decision:** ${decision.decision}\n\n`
|
|
108
|
+
entry += `**Reasoning:** ${decision.reasoning}\n\n`
|
|
109
|
+
|
|
110
|
+
if (decision.alternatives) {
|
|
111
|
+
entry += `**Alternatives Considered:** ${decision.alternatives}\n\n`
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
if (decision.impact) {
|
|
115
|
+
entry += `**Expected Impact:** ${decision.impact}\n\n`
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
if (decision.outcome) {
|
|
119
|
+
entry += `**Outcome:** ${decision.outcome}\n\n`
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
if (decision.tags) {
|
|
123
|
+
const tags = Array.isArray(decision.tags)
|
|
124
|
+
? decision.tags.join(', ')
|
|
125
|
+
: decision.tags
|
|
126
|
+
entry += `**Tags:** ${tags}\n\n`
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
return entry + '---\n\n'
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
/**
|
|
133
|
+
* Detect decision patterns in text
|
|
134
|
+
*/
|
|
135
|
+
static detectDecision(text: string): boolean {
|
|
136
|
+
const decisionKeywords = [
|
|
137
|
+
'decided to',
|
|
138
|
+
'decision:',
|
|
139
|
+
'chose to',
|
|
140
|
+
'selected',
|
|
141
|
+
'went with',
|
|
142
|
+
'opted for',
|
|
143
|
+
'concluded that',
|
|
144
|
+
'we will use',
|
|
145
|
+
'adopting',
|
|
146
|
+
'implementing'
|
|
147
|
+
]
|
|
148
|
+
|
|
149
|
+
const lowerText = text.toLowerCase()
|
|
150
|
+
return decisionKeywords.some(keyword => lowerText.includes(keyword))
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
/**
|
|
154
|
+
* Extract decision from natural language
|
|
155
|
+
*/
|
|
156
|
+
static extractDecisionFromText(text: string): Partial<DecisionEntry> | null {
|
|
157
|
+
// Try to match common decision patterns
|
|
158
|
+
const patterns = [
|
|
159
|
+
/decided to (.+?)(?:\.|$)/i,
|
|
160
|
+
/chose to (.+?)(?:\.|$)/i,
|
|
161
|
+
/going with (.+?)(?:\.|$)/i,
|
|
162
|
+
/we will use (.+?)(?:\.|$)/i,
|
|
163
|
+
/adopting (.+?)(?:\.|$)/i
|
|
164
|
+
]
|
|
165
|
+
|
|
166
|
+
let decision: string | null = null
|
|
167
|
+
for (const pattern of patterns) {
|
|
168
|
+
const match = pattern.exec(text)
|
|
169
|
+
if (match?.[1]) {
|
|
170
|
+
decision = match[1].trim()
|
|
171
|
+
break
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
if (!decision) {
|
|
176
|
+
return null
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
// Try to extract reasoning
|
|
180
|
+
const reasoningPatterns = [
|
|
181
|
+
/because (.+?)(?:\.|$)/i,
|
|
182
|
+
/since (.+?)(?:\.|$)/i,
|
|
183
|
+
/due to (.+?)(?:\.|$)/i,
|
|
184
|
+
/as (.+?)(?:\.|$)/i
|
|
185
|
+
]
|
|
186
|
+
|
|
187
|
+
let reasoning: string | undefined
|
|
188
|
+
for (const pattern of reasoningPatterns) {
|
|
189
|
+
const match = pattern.exec(text)
|
|
190
|
+
if (match?.[1]) {
|
|
191
|
+
reasoning = match[1].trim()
|
|
192
|
+
break
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
return {
|
|
197
|
+
decision,
|
|
198
|
+
reasoning
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
/**
|
|
203
|
+
* Create a decision entry from minimal input
|
|
204
|
+
*/
|
|
205
|
+
static createDecisionEntry(
|
|
206
|
+
project: string,
|
|
207
|
+
title: string,
|
|
208
|
+
decision: string,
|
|
209
|
+
reasoning: string,
|
|
210
|
+
options?: {
|
|
211
|
+
context?: string
|
|
212
|
+
alternatives?: string
|
|
213
|
+
impact?: string
|
|
214
|
+
tags?: string[]
|
|
215
|
+
}
|
|
216
|
+
): Omit<DecisionEntry, 'id' | 'timestamp'> {
|
|
217
|
+
return {
|
|
218
|
+
project,
|
|
219
|
+
title,
|
|
220
|
+
context: options?.context || `Decision about ${title}`,
|
|
221
|
+
decision,
|
|
222
|
+
reasoning,
|
|
223
|
+
alternatives: options?.alternatives,
|
|
224
|
+
impact: options?.impact,
|
|
225
|
+
tags: options?.tags
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
}
|