claude-brain 0.30.2 → 0.31.1
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 +59 -56
- package/src/config/index.ts +5 -5
- package/src/config/loader.ts +195 -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,287 +1,287 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Code Standards Manager
|
|
3
|
-
* Maintains and injects project coding standards consistently
|
|
4
|
-
*/
|
|
5
|
-
|
|
6
|
-
import type { Logger } from 'pino'
|
|
7
|
-
import type { VaultManager } from '@/vault'
|
|
8
|
-
import type { CodeStandards, LanguageStandards, FrameworkStandards, NamingConventions, FormattingRules, TestingStandards, DocumentationStandards, SecurityStandards } from './types'
|
|
9
|
-
|
|
10
|
-
export class StandardsManager {
|
|
11
|
-
private logger: Logger
|
|
12
|
-
private vault: VaultManager
|
|
13
|
-
private globalStandards: CodeStandards | null = null
|
|
14
|
-
private projectStandards: Map<string, CodeStandards> = new Map()
|
|
15
|
-
|
|
16
|
-
constructor(logger: Logger, vault: VaultManager) {
|
|
17
|
-
this.logger = logger.child({ component: 'standards-manager' })
|
|
18
|
-
this.vault = vault
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
async loadGlobalStandards(): Promise<CodeStandards> {
|
|
22
|
-
if (this.globalStandards) {
|
|
23
|
-
return this.globalStandards
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
try {
|
|
27
|
-
const globalPath = `${this.vault.paths.global}/standards.md`
|
|
28
|
-
const file = await this.vault.reader.readMarkdownFile(globalPath)
|
|
29
|
-
|
|
30
|
-
this.globalStandards = this.parseStandards(file.content)
|
|
31
|
-
this.logger.info('Global standards loaded')
|
|
32
|
-
|
|
33
|
-
return this.globalStandards
|
|
34
|
-
} catch (error) {
|
|
35
|
-
this.logger.warn('No global standards found, using defaults')
|
|
36
|
-
this.globalStandards = this.getDefaultStandards()
|
|
37
|
-
return this.globalStandards
|
|
38
|
-
}
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
async getProjectStandards(projectName: string): Promise<CodeStandards> {
|
|
42
|
-
if (this.projectStandards.has(projectName)) {
|
|
43
|
-
return this.projectStandards.get(projectName)!
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
try {
|
|
47
|
-
const projectPaths = this.vault.getProjectPaths(projectName)
|
|
48
|
-
const file = await this.vault.reader.readMarkdownFile(projectPaths.standards)
|
|
49
|
-
const projectStandards = this.parseStandards(file.content)
|
|
50
|
-
|
|
51
|
-
const globalStandards = await this.loadGlobalStandards()
|
|
52
|
-
|
|
53
|
-
const merged = this.mergeStandards(globalStandards, projectStandards)
|
|
54
|
-
|
|
55
|
-
this.projectStandards.set(projectName, merged)
|
|
56
|
-
|
|
57
|
-
this.logger.info({ projectName }, 'Project standards loaded')
|
|
58
|
-
return merged
|
|
59
|
-
|
|
60
|
-
} catch (error) {
|
|
61
|
-
this.logger.warn({ projectName }, 'No project standards found, using global')
|
|
62
|
-
return await this.loadGlobalStandards()
|
|
63
|
-
}
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
async getLanguageStandards(
|
|
67
|
-
projectName: string,
|
|
68
|
-
language: string
|
|
69
|
-
): Promise<LanguageStandards | null> {
|
|
70
|
-
const standards = await this.getProjectStandards(projectName)
|
|
71
|
-
return standards.languages.find(l => l.language === language) || null
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
async getFrameworkStandards(
|
|
75
|
-
projectName: string,
|
|
76
|
-
framework: string
|
|
77
|
-
): Promise<FrameworkStandards | null> {
|
|
78
|
-
const standards = await this.getProjectStandards(projectName)
|
|
79
|
-
return standards.frameworks.find(f => f.framework === framework) || null
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
private parseStandards(content: string): CodeStandards {
|
|
83
|
-
return {
|
|
84
|
-
languages: this.parseLanguageStandards(content),
|
|
85
|
-
frameworks: this.parseFrameworkStandards(content),
|
|
86
|
-
naming: this.parseNamingConventions(content) as unknown as NamingConventions,
|
|
87
|
-
formatting: this.parseFormattingRules(content) as unknown as FormattingRules,
|
|
88
|
-
testing: this.parseTestingStandards(content) as unknown as TestingStandards,
|
|
89
|
-
documentation: this.parseDocumentationStandards(content) as unknown as DocumentationStandards,
|
|
90
|
-
security: this.parseSecurityStandards(content) as unknown as SecurityStandards
|
|
91
|
-
}
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
private parseLanguageStandards(content: string): LanguageStandards[] {
|
|
95
|
-
const languages: LanguageStandards[] = []
|
|
96
|
-
|
|
97
|
-
const langRegex = /##\s+(TypeScript|Python|JavaScript|Java|Go|Rust)\s+/gi
|
|
98
|
-
|
|
99
|
-
let match
|
|
100
|
-
while ((match = langRegex.exec(content)) !== null) {
|
|
101
|
-
const language = match[1]!
|
|
102
|
-
const sectionStart = match.index
|
|
103
|
-
const nextSection = content.indexOf('##', sectionStart + 1)
|
|
104
|
-
const sectionEnd = nextSection === -1 ? content.length : nextSection
|
|
105
|
-
const section = content.slice(sectionStart, sectionEnd)
|
|
106
|
-
|
|
107
|
-
languages.push({
|
|
108
|
-
language,
|
|
109
|
-
version: this.extractVersion(section),
|
|
110
|
-
style: this.extractStyle(section),
|
|
111
|
-
linting: {},
|
|
112
|
-
conventions: this.extractConventions(section),
|
|
113
|
-
antiPatterns: this.extractAntiPatterns(section)
|
|
114
|
-
})
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
return languages
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
private parseFrameworkStandards(_content: string): FrameworkStandards[] {
|
|
121
|
-
return []
|
|
122
|
-
}
|
|
123
|
-
|
|
124
|
-
private extractVersion(section: string): string {
|
|
125
|
-
const match = /Version:\s*(.+?)(?:\n|$)/i.exec(section)
|
|
126
|
-
return match ? match[1]!.trim() : 'latest'
|
|
127
|
-
}
|
|
128
|
-
|
|
129
|
-
private extractStyle(section: string): string {
|
|
130
|
-
const match = /Style:\s*(.+?)(?:\n|$)/i.exec(section)
|
|
131
|
-
return match ? match[1]!.trim() : 'standard'
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
private extractConventions(section: string): string[] {
|
|
135
|
-
const conventions: string[] = []
|
|
136
|
-
const listRegex = /^[-*]\s+(.+)$/gm
|
|
137
|
-
|
|
138
|
-
let match
|
|
139
|
-
while ((match = listRegex.exec(section)) !== null) {
|
|
140
|
-
conventions.push(match[1]!.trim())
|
|
141
|
-
}
|
|
142
|
-
|
|
143
|
-
return conventions
|
|
144
|
-
}
|
|
145
|
-
|
|
146
|
-
private extractAntiPatterns(section: string): string[] {
|
|
147
|
-
const antiPatternsSection = /Anti-Patterns?:(.+?)(?=\n##|$)/is.exec(section)
|
|
148
|
-
if (!antiPatternsSection) return []
|
|
149
|
-
|
|
150
|
-
const patterns: string[] = []
|
|
151
|
-
const listRegex = /^[-*]\s+(.+)$/gm
|
|
152
|
-
|
|
153
|
-
let match
|
|
154
|
-
while ((match = listRegex.exec(antiPatternsSection[1]!)) !== null) {
|
|
155
|
-
patterns.push(match[1]!.trim())
|
|
156
|
-
}
|
|
157
|
-
|
|
158
|
-
return patterns
|
|
159
|
-
}
|
|
160
|
-
|
|
161
|
-
private parseNamingConventions(_content: string): Record<string, unknown> {
|
|
162
|
-
return {}
|
|
163
|
-
}
|
|
164
|
-
|
|
165
|
-
private parseFormattingRules(_content: string): Record<string, unknown> {
|
|
166
|
-
return {}
|
|
167
|
-
}
|
|
168
|
-
|
|
169
|
-
private parseTestingStandards(_content: string): Record<string, unknown> {
|
|
170
|
-
return {}
|
|
171
|
-
}
|
|
172
|
-
|
|
173
|
-
private parseDocumentationStandards(_content: string): Record<string, unknown> {
|
|
174
|
-
return {}
|
|
175
|
-
}
|
|
176
|
-
|
|
177
|
-
private parseSecurityStandards(_content: string): Record<string, unknown> {
|
|
178
|
-
return {}
|
|
179
|
-
}
|
|
180
|
-
|
|
181
|
-
private mergeStandards(
|
|
182
|
-
base: CodeStandards,
|
|
183
|
-
override: CodeStandards
|
|
184
|
-
): CodeStandards {
|
|
185
|
-
return {
|
|
186
|
-
languages: this.mergeLanguageStandards(base.languages, override.languages),
|
|
187
|
-
frameworks: this.mergeFrameworkStandards(base.frameworks, override.frameworks),
|
|
188
|
-
naming: { ...base.naming, ...override.naming },
|
|
189
|
-
formatting: { ...base.formatting, ...override.formatting },
|
|
190
|
-
testing: { ...base.testing, ...override.testing },
|
|
191
|
-
documentation: { ...base.documentation, ...override.documentation },
|
|
192
|
-
security: { ...base.security, ...override.security }
|
|
193
|
-
}
|
|
194
|
-
}
|
|
195
|
-
|
|
196
|
-
private mergeLanguageStandards(
|
|
197
|
-
base: LanguageStandards[],
|
|
198
|
-
override: LanguageStandards[]
|
|
199
|
-
): LanguageStandards[] {
|
|
200
|
-
const merged = [...base]
|
|
201
|
-
|
|
202
|
-
for (const overrideStd of override) {
|
|
203
|
-
const index = merged.findIndex(s => s.language === overrideStd.language)
|
|
204
|
-
if (index >= 0) {
|
|
205
|
-
merged[index] = overrideStd
|
|
206
|
-
} else {
|
|
207
|
-
merged.push(overrideStd)
|
|
208
|
-
}
|
|
209
|
-
}
|
|
210
|
-
|
|
211
|
-
return merged
|
|
212
|
-
}
|
|
213
|
-
|
|
214
|
-
private mergeFrameworkStandards(
|
|
215
|
-
base: FrameworkStandards[],
|
|
216
|
-
override: FrameworkStandards[]
|
|
217
|
-
): FrameworkStandards[] {
|
|
218
|
-
const merged = [...base]
|
|
219
|
-
|
|
220
|
-
for (const overrideStd of override) {
|
|
221
|
-
const index = merged.findIndex(s => s.framework === overrideStd.framework)
|
|
222
|
-
if (index >= 0) {
|
|
223
|
-
merged[index] = overrideStd
|
|
224
|
-
} else {
|
|
225
|
-
merged.push(overrideStd)
|
|
226
|
-
}
|
|
227
|
-
}
|
|
228
|
-
|
|
229
|
-
return merged
|
|
230
|
-
}
|
|
231
|
-
|
|
232
|
-
private getDefaultStandards(): CodeStandards {
|
|
233
|
-
return {
|
|
234
|
-
languages: [
|
|
235
|
-
{
|
|
236
|
-
language: 'TypeScript',
|
|
237
|
-
version: 'latest',
|
|
238
|
-
style: 'standard',
|
|
239
|
-
linting: {},
|
|
240
|
-
conventions: [
|
|
241
|
-
'Use strict mode',
|
|
242
|
-
'Prefer const over let',
|
|
243
|
-
'Use async/await over promises',
|
|
244
|
-
'Add JSDoc comments for public APIs'
|
|
245
|
-
],
|
|
246
|
-
antiPatterns: [
|
|
247
|
-
'Using any type',
|
|
248
|
-
'Ignoring error handling',
|
|
249
|
-
'Deep nesting'
|
|
250
|
-
]
|
|
251
|
-
},
|
|
252
|
-
{
|
|
253
|
-
language: 'JavaScript',
|
|
254
|
-
version: 'ES2022+',
|
|
255
|
-
style: 'standard',
|
|
256
|
-
linting: {},
|
|
257
|
-
conventions: [
|
|
258
|
-
'Use strict mode',
|
|
259
|
-
'Prefer const over let',
|
|
260
|
-
'Use async/await over promises',
|
|
261
|
-
'Use optional chaining and nullish coalescing',
|
|
262
|
-
'Add JSDoc comments for public APIs'
|
|
263
|
-
],
|
|
264
|
-
antiPatterns: [
|
|
265
|
-
'Using var',
|
|
266
|
-
'Callback hell',
|
|
267
|
-
'Ignoring error handling',
|
|
268
|
-
'Deep nesting',
|
|
269
|
-
'Mutating function arguments'
|
|
270
|
-
]
|
|
271
|
-
}
|
|
272
|
-
],
|
|
273
|
-
frameworks: [],
|
|
274
|
-
naming: {} as NamingConventions,
|
|
275
|
-
formatting: {} as FormattingRules,
|
|
276
|
-
testing: {} as TestingStandards,
|
|
277
|
-
documentation: {} as DocumentationStandards,
|
|
278
|
-
security: {} as SecurityStandards
|
|
279
|
-
}
|
|
280
|
-
}
|
|
281
|
-
|
|
282
|
-
clearCache(): void {
|
|
283
|
-
this.projectStandards.clear()
|
|
284
|
-
this.globalStandards = null
|
|
285
|
-
this.logger.debug('Standards cache cleared')
|
|
286
|
-
}
|
|
287
|
-
}
|
|
1
|
+
/**
|
|
2
|
+
* Code Standards Manager
|
|
3
|
+
* Maintains and injects project coding standards consistently
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import type { Logger } from 'pino'
|
|
7
|
+
import type { VaultManager } from '@/vault'
|
|
8
|
+
import type { CodeStandards, LanguageStandards, FrameworkStandards, NamingConventions, FormattingRules, TestingStandards, DocumentationStandards, SecurityStandards } from './types'
|
|
9
|
+
|
|
10
|
+
export class StandardsManager {
|
|
11
|
+
private logger: Logger
|
|
12
|
+
private vault: VaultManager
|
|
13
|
+
private globalStandards: CodeStandards | null = null
|
|
14
|
+
private projectStandards: Map<string, CodeStandards> = new Map()
|
|
15
|
+
|
|
16
|
+
constructor(logger: Logger, vault: VaultManager) {
|
|
17
|
+
this.logger = logger.child({ component: 'standards-manager' })
|
|
18
|
+
this.vault = vault
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
async loadGlobalStandards(): Promise<CodeStandards> {
|
|
22
|
+
if (this.globalStandards) {
|
|
23
|
+
return this.globalStandards
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
try {
|
|
27
|
+
const globalPath = `${this.vault.paths.global}/standards.md`
|
|
28
|
+
const file = await this.vault.reader.readMarkdownFile(globalPath)
|
|
29
|
+
|
|
30
|
+
this.globalStandards = this.parseStandards(file.content)
|
|
31
|
+
this.logger.info('Global standards loaded')
|
|
32
|
+
|
|
33
|
+
return this.globalStandards
|
|
34
|
+
} catch (error) {
|
|
35
|
+
this.logger.warn('No global standards found, using defaults')
|
|
36
|
+
this.globalStandards = this.getDefaultStandards()
|
|
37
|
+
return this.globalStandards
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
async getProjectStandards(projectName: string): Promise<CodeStandards> {
|
|
42
|
+
if (this.projectStandards.has(projectName)) {
|
|
43
|
+
return this.projectStandards.get(projectName)!
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
try {
|
|
47
|
+
const projectPaths = this.vault.getProjectPaths(projectName)
|
|
48
|
+
const file = await this.vault.reader.readMarkdownFile(projectPaths.standards)
|
|
49
|
+
const projectStandards = this.parseStandards(file.content)
|
|
50
|
+
|
|
51
|
+
const globalStandards = await this.loadGlobalStandards()
|
|
52
|
+
|
|
53
|
+
const merged = this.mergeStandards(globalStandards, projectStandards)
|
|
54
|
+
|
|
55
|
+
this.projectStandards.set(projectName, merged)
|
|
56
|
+
|
|
57
|
+
this.logger.info({ projectName }, 'Project standards loaded')
|
|
58
|
+
return merged
|
|
59
|
+
|
|
60
|
+
} catch (error) {
|
|
61
|
+
this.logger.warn({ projectName }, 'No project standards found, using global')
|
|
62
|
+
return await this.loadGlobalStandards()
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
async getLanguageStandards(
|
|
67
|
+
projectName: string,
|
|
68
|
+
language: string
|
|
69
|
+
): Promise<LanguageStandards | null> {
|
|
70
|
+
const standards = await this.getProjectStandards(projectName)
|
|
71
|
+
return standards.languages.find(l => l.language === language) || null
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
async getFrameworkStandards(
|
|
75
|
+
projectName: string,
|
|
76
|
+
framework: string
|
|
77
|
+
): Promise<FrameworkStandards | null> {
|
|
78
|
+
const standards = await this.getProjectStandards(projectName)
|
|
79
|
+
return standards.frameworks.find(f => f.framework === framework) || null
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
private parseStandards(content: string): CodeStandards {
|
|
83
|
+
return {
|
|
84
|
+
languages: this.parseLanguageStandards(content),
|
|
85
|
+
frameworks: this.parseFrameworkStandards(content),
|
|
86
|
+
naming: this.parseNamingConventions(content) as unknown as NamingConventions,
|
|
87
|
+
formatting: this.parseFormattingRules(content) as unknown as FormattingRules,
|
|
88
|
+
testing: this.parseTestingStandards(content) as unknown as TestingStandards,
|
|
89
|
+
documentation: this.parseDocumentationStandards(content) as unknown as DocumentationStandards,
|
|
90
|
+
security: this.parseSecurityStandards(content) as unknown as SecurityStandards
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
private parseLanguageStandards(content: string): LanguageStandards[] {
|
|
95
|
+
const languages: LanguageStandards[] = []
|
|
96
|
+
|
|
97
|
+
const langRegex = /##\s+(TypeScript|Python|JavaScript|Java|Go|Rust)\s+/gi
|
|
98
|
+
|
|
99
|
+
let match
|
|
100
|
+
while ((match = langRegex.exec(content)) !== null) {
|
|
101
|
+
const language = match[1]!
|
|
102
|
+
const sectionStart = match.index
|
|
103
|
+
const nextSection = content.indexOf('##', sectionStart + 1)
|
|
104
|
+
const sectionEnd = nextSection === -1 ? content.length : nextSection
|
|
105
|
+
const section = content.slice(sectionStart, sectionEnd)
|
|
106
|
+
|
|
107
|
+
languages.push({
|
|
108
|
+
language,
|
|
109
|
+
version: this.extractVersion(section),
|
|
110
|
+
style: this.extractStyle(section),
|
|
111
|
+
linting: {},
|
|
112
|
+
conventions: this.extractConventions(section),
|
|
113
|
+
antiPatterns: this.extractAntiPatterns(section)
|
|
114
|
+
})
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
return languages
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
private parseFrameworkStandards(_content: string): FrameworkStandards[] {
|
|
121
|
+
return []
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
private extractVersion(section: string): string {
|
|
125
|
+
const match = /Version:\s*(.+?)(?:\n|$)/i.exec(section)
|
|
126
|
+
return match ? match[1]!.trim() : 'latest'
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
private extractStyle(section: string): string {
|
|
130
|
+
const match = /Style:\s*(.+?)(?:\n|$)/i.exec(section)
|
|
131
|
+
return match ? match[1]!.trim() : 'standard'
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
private extractConventions(section: string): string[] {
|
|
135
|
+
const conventions: string[] = []
|
|
136
|
+
const listRegex = /^[-*]\s+(.+)$/gm
|
|
137
|
+
|
|
138
|
+
let match
|
|
139
|
+
while ((match = listRegex.exec(section)) !== null) {
|
|
140
|
+
conventions.push(match[1]!.trim())
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
return conventions
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
private extractAntiPatterns(section: string): string[] {
|
|
147
|
+
const antiPatternsSection = /Anti-Patterns?:(.+?)(?=\n##|$)/is.exec(section)
|
|
148
|
+
if (!antiPatternsSection) return []
|
|
149
|
+
|
|
150
|
+
const patterns: string[] = []
|
|
151
|
+
const listRegex = /^[-*]\s+(.+)$/gm
|
|
152
|
+
|
|
153
|
+
let match
|
|
154
|
+
while ((match = listRegex.exec(antiPatternsSection[1]!)) !== null) {
|
|
155
|
+
patterns.push(match[1]!.trim())
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
return patterns
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
private parseNamingConventions(_content: string): Record<string, unknown> {
|
|
162
|
+
return {}
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
private parseFormattingRules(_content: string): Record<string, unknown> {
|
|
166
|
+
return {}
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
private parseTestingStandards(_content: string): Record<string, unknown> {
|
|
170
|
+
return {}
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
private parseDocumentationStandards(_content: string): Record<string, unknown> {
|
|
174
|
+
return {}
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
private parseSecurityStandards(_content: string): Record<string, unknown> {
|
|
178
|
+
return {}
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
private mergeStandards(
|
|
182
|
+
base: CodeStandards,
|
|
183
|
+
override: CodeStandards
|
|
184
|
+
): CodeStandards {
|
|
185
|
+
return {
|
|
186
|
+
languages: this.mergeLanguageStandards(base.languages, override.languages),
|
|
187
|
+
frameworks: this.mergeFrameworkStandards(base.frameworks, override.frameworks),
|
|
188
|
+
naming: { ...base.naming, ...override.naming },
|
|
189
|
+
formatting: { ...base.formatting, ...override.formatting },
|
|
190
|
+
testing: { ...base.testing, ...override.testing },
|
|
191
|
+
documentation: { ...base.documentation, ...override.documentation },
|
|
192
|
+
security: { ...base.security, ...override.security }
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
private mergeLanguageStandards(
|
|
197
|
+
base: LanguageStandards[],
|
|
198
|
+
override: LanguageStandards[]
|
|
199
|
+
): LanguageStandards[] {
|
|
200
|
+
const merged = [...base]
|
|
201
|
+
|
|
202
|
+
for (const overrideStd of override) {
|
|
203
|
+
const index = merged.findIndex(s => s.language === overrideStd.language)
|
|
204
|
+
if (index >= 0) {
|
|
205
|
+
merged[index] = overrideStd
|
|
206
|
+
} else {
|
|
207
|
+
merged.push(overrideStd)
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
return merged
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
private mergeFrameworkStandards(
|
|
215
|
+
base: FrameworkStandards[],
|
|
216
|
+
override: FrameworkStandards[]
|
|
217
|
+
): FrameworkStandards[] {
|
|
218
|
+
const merged = [...base]
|
|
219
|
+
|
|
220
|
+
for (const overrideStd of override) {
|
|
221
|
+
const index = merged.findIndex(s => s.framework === overrideStd.framework)
|
|
222
|
+
if (index >= 0) {
|
|
223
|
+
merged[index] = overrideStd
|
|
224
|
+
} else {
|
|
225
|
+
merged.push(overrideStd)
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
return merged
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
private getDefaultStandards(): CodeStandards {
|
|
233
|
+
return {
|
|
234
|
+
languages: [
|
|
235
|
+
{
|
|
236
|
+
language: 'TypeScript',
|
|
237
|
+
version: 'latest',
|
|
238
|
+
style: 'standard',
|
|
239
|
+
linting: {},
|
|
240
|
+
conventions: [
|
|
241
|
+
'Use strict mode',
|
|
242
|
+
'Prefer const over let',
|
|
243
|
+
'Use async/await over promises',
|
|
244
|
+
'Add JSDoc comments for public APIs'
|
|
245
|
+
],
|
|
246
|
+
antiPatterns: [
|
|
247
|
+
'Using any type',
|
|
248
|
+
'Ignoring error handling',
|
|
249
|
+
'Deep nesting'
|
|
250
|
+
]
|
|
251
|
+
},
|
|
252
|
+
{
|
|
253
|
+
language: 'JavaScript',
|
|
254
|
+
version: 'ES2022+',
|
|
255
|
+
style: 'standard',
|
|
256
|
+
linting: {},
|
|
257
|
+
conventions: [
|
|
258
|
+
'Use strict mode',
|
|
259
|
+
'Prefer const over let',
|
|
260
|
+
'Use async/await over promises',
|
|
261
|
+
'Use optional chaining and nullish coalescing',
|
|
262
|
+
'Add JSDoc comments for public APIs'
|
|
263
|
+
],
|
|
264
|
+
antiPatterns: [
|
|
265
|
+
'Using var',
|
|
266
|
+
'Callback hell',
|
|
267
|
+
'Ignoring error handling',
|
|
268
|
+
'Deep nesting',
|
|
269
|
+
'Mutating function arguments'
|
|
270
|
+
]
|
|
271
|
+
}
|
|
272
|
+
],
|
|
273
|
+
frameworks: [],
|
|
274
|
+
naming: {} as NamingConventions,
|
|
275
|
+
formatting: {} as FormattingRules,
|
|
276
|
+
testing: {} as TestingStandards,
|
|
277
|
+
documentation: {} as DocumentationStandards,
|
|
278
|
+
security: {} as SecurityStandards
|
|
279
|
+
}
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
clearCache(): void {
|
|
283
|
+
this.projectStandards.clear()
|
|
284
|
+
this.globalStandards = null
|
|
285
|
+
this.logger.debug('Standards cache cleared')
|
|
286
|
+
}
|
|
287
|
+
}
|