neuronlayer 0.1.0
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/CONTRIBUTING.md +127 -0
- package/LICENSE +21 -0
- package/README.md +305 -0
- package/dist/index.js +38016 -0
- package/esbuild.config.js +26 -0
- package/package.json +63 -0
- package/src/cli/commands.ts +382 -0
- package/src/core/adr-exporter.ts +253 -0
- package/src/core/architecture/architecture-enforcement.ts +228 -0
- package/src/core/architecture/duplicate-detector.ts +288 -0
- package/src/core/architecture/index.ts +6 -0
- package/src/core/architecture/pattern-learner.ts +306 -0
- package/src/core/architecture/pattern-library.ts +403 -0
- package/src/core/architecture/pattern-validator.ts +324 -0
- package/src/core/change-intelligence/bug-correlator.ts +444 -0
- package/src/core/change-intelligence/change-intelligence.ts +221 -0
- package/src/core/change-intelligence/change-tracker.ts +334 -0
- package/src/core/change-intelligence/fix-suggester.ts +340 -0
- package/src/core/change-intelligence/index.ts +5 -0
- package/src/core/code-verifier.ts +843 -0
- package/src/core/confidence/confidence-scorer.ts +251 -0
- package/src/core/confidence/conflict-checker.ts +289 -0
- package/src/core/confidence/index.ts +5 -0
- package/src/core/confidence/source-tracker.ts +263 -0
- package/src/core/confidence/warning-detector.ts +241 -0
- package/src/core/context-rot/compaction.ts +284 -0
- package/src/core/context-rot/context-health.ts +243 -0
- package/src/core/context-rot/context-rot-prevention.ts +213 -0
- package/src/core/context-rot/critical-context.ts +221 -0
- package/src/core/context-rot/drift-detector.ts +255 -0
- package/src/core/context-rot/index.ts +7 -0
- package/src/core/context.ts +263 -0
- package/src/core/decision-extractor.ts +339 -0
- package/src/core/decisions.ts +69 -0
- package/src/core/deja-vu.ts +421 -0
- package/src/core/engine.ts +1455 -0
- package/src/core/feature-context.ts +726 -0
- package/src/core/ghost-mode.ts +412 -0
- package/src/core/learning.ts +485 -0
- package/src/core/living-docs/activity-tracker.ts +296 -0
- package/src/core/living-docs/architecture-generator.ts +428 -0
- package/src/core/living-docs/changelog-generator.ts +348 -0
- package/src/core/living-docs/component-generator.ts +230 -0
- package/src/core/living-docs/doc-engine.ts +110 -0
- package/src/core/living-docs/doc-validator.ts +282 -0
- package/src/core/living-docs/index.ts +8 -0
- package/src/core/project-manager.ts +297 -0
- package/src/core/summarizer.ts +267 -0
- package/src/core/test-awareness/change-validator.ts +499 -0
- package/src/core/test-awareness/index.ts +5 -0
- package/src/index.ts +49 -0
- package/src/indexing/ast.ts +563 -0
- package/src/indexing/embeddings.ts +85 -0
- package/src/indexing/indexer.ts +245 -0
- package/src/indexing/watcher.ts +78 -0
- package/src/server/gateways/aggregator.ts +374 -0
- package/src/server/gateways/index.ts +473 -0
- package/src/server/gateways/memory-ghost.ts +343 -0
- package/src/server/gateways/memory-query.ts +452 -0
- package/src/server/gateways/memory-record.ts +346 -0
- package/src/server/gateways/memory-review.ts +410 -0
- package/src/server/gateways/memory-status.ts +517 -0
- package/src/server/gateways/memory-verify.ts +392 -0
- package/src/server/gateways/router.ts +434 -0
- package/src/server/gateways/types.ts +610 -0
- package/src/server/mcp.ts +154 -0
- package/src/server/resources.ts +85 -0
- package/src/server/tools.ts +2261 -0
- package/src/storage/database.ts +262 -0
- package/src/storage/tier1.ts +135 -0
- package/src/storage/tier2.ts +764 -0
- package/src/storage/tier3.ts +123 -0
- package/src/types/documentation.ts +619 -0
- package/src/types/index.ts +222 -0
- package/src/utils/config.ts +193 -0
- package/src/utils/files.ts +117 -0
- package/src/utils/time.ts +37 -0
- package/src/utils/tokens.ts +52 -0
|
@@ -0,0 +1,392 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Memory Verify Gateway
|
|
3
|
+
*
|
|
4
|
+
* Pre-commit quality gate for AI-generated code.
|
|
5
|
+
*
|
|
6
|
+
* Checks:
|
|
7
|
+
* - imports: Do imports exist? Is the API being used correctly?
|
|
8
|
+
* - security: Common vulnerability patterns (OWASP Top 10)
|
|
9
|
+
* - dependencies: Is package in package.json? Is it installed?
|
|
10
|
+
* - patterns: Does code follow project patterns?
|
|
11
|
+
* - tests: Will this break tests?
|
|
12
|
+
* - all: Run all checks (default)
|
|
13
|
+
*
|
|
14
|
+
* Solves top vibe coder problems:
|
|
15
|
+
* - Hallucination detection (AI invents libraries that don't exist)
|
|
16
|
+
* - Security scanning (1.7x more vulnerabilities in AI code)
|
|
17
|
+
* - Pre-commit quality gate
|
|
18
|
+
*/
|
|
19
|
+
|
|
20
|
+
import type { MemoryLayerEngine } from '../../core/engine.js';
|
|
21
|
+
|
|
22
|
+
// ============================================================================
|
|
23
|
+
// Types
|
|
24
|
+
// ============================================================================
|
|
25
|
+
|
|
26
|
+
export type VerifyCheck = 'imports' | 'security' | 'dependencies' | 'patterns' | 'tests' | 'all';
|
|
27
|
+
|
|
28
|
+
export interface MemoryVerifyInput {
|
|
29
|
+
/** Code to verify */
|
|
30
|
+
code: string;
|
|
31
|
+
/** Target file path (enables import resolution and test checks) */
|
|
32
|
+
file?: string;
|
|
33
|
+
/** Specific checks to run (default: all) */
|
|
34
|
+
checks?: VerifyCheck[];
|
|
35
|
+
/** Intent/purpose of the code (improves suggestions) */
|
|
36
|
+
intent?: string;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
export interface MemoryVerifyResponse {
|
|
40
|
+
/** Overall verdict */
|
|
41
|
+
verdict: 'pass' | 'warning' | 'fail';
|
|
42
|
+
/** Quality score (0-100, higher is better) */
|
|
43
|
+
score: number;
|
|
44
|
+
/** Sources used for verification */
|
|
45
|
+
sources_used: string[];
|
|
46
|
+
/** Human-readable summary */
|
|
47
|
+
summary: string;
|
|
48
|
+
/** Import verification results */
|
|
49
|
+
imports?: {
|
|
50
|
+
valid: boolean;
|
|
51
|
+
issues: Array<{
|
|
52
|
+
import: string;
|
|
53
|
+
type: 'missing_package' | 'missing_file' | 'invalid_export' | 'deprecated' | 'hallucinated';
|
|
54
|
+
message: string;
|
|
55
|
+
suggestion?: string;
|
|
56
|
+
}>;
|
|
57
|
+
warnings: Array<{
|
|
58
|
+
import: string;
|
|
59
|
+
type: 'outdated' | 'security' | 'deprecated_api';
|
|
60
|
+
message: string;
|
|
61
|
+
suggestion?: string;
|
|
62
|
+
}>;
|
|
63
|
+
};
|
|
64
|
+
/** Security scan results */
|
|
65
|
+
security?: {
|
|
66
|
+
safe: boolean;
|
|
67
|
+
score: number;
|
|
68
|
+
issues: Array<{
|
|
69
|
+
type: string;
|
|
70
|
+
severity: 'low' | 'medium' | 'high' | 'critical';
|
|
71
|
+
line?: number;
|
|
72
|
+
code?: string;
|
|
73
|
+
message: string;
|
|
74
|
+
cwe?: string;
|
|
75
|
+
suggestion?: string;
|
|
76
|
+
}>;
|
|
77
|
+
};
|
|
78
|
+
/** Dependency check results */
|
|
79
|
+
dependencies?: {
|
|
80
|
+
valid: boolean;
|
|
81
|
+
issues: Array<{
|
|
82
|
+
package: string;
|
|
83
|
+
type: 'not_installed' | 'version_mismatch' | 'deprecated' | 'vulnerable' | 'unlisted';
|
|
84
|
+
message: string;
|
|
85
|
+
suggestion?: string;
|
|
86
|
+
}>;
|
|
87
|
+
};
|
|
88
|
+
/** Pattern validation results (from memory_review) */
|
|
89
|
+
patterns?: {
|
|
90
|
+
valid: boolean;
|
|
91
|
+
score: number;
|
|
92
|
+
matched_pattern?: string;
|
|
93
|
+
violations: Array<{
|
|
94
|
+
rule: string;
|
|
95
|
+
message: string;
|
|
96
|
+
severity: string;
|
|
97
|
+
suggestion?: string;
|
|
98
|
+
}>;
|
|
99
|
+
};
|
|
100
|
+
/** Test impact results (from memory_review) */
|
|
101
|
+
test_impact?: {
|
|
102
|
+
safe: boolean;
|
|
103
|
+
coverage_percent: number;
|
|
104
|
+
would_fail: Array<{
|
|
105
|
+
test_name: string;
|
|
106
|
+
test_file: string;
|
|
107
|
+
reason: string;
|
|
108
|
+
suggested_fix?: string;
|
|
109
|
+
}>;
|
|
110
|
+
};
|
|
111
|
+
/** Decision conflict warnings */
|
|
112
|
+
conflicts?: {
|
|
113
|
+
has_conflicts: boolean;
|
|
114
|
+
conflicts: Array<{
|
|
115
|
+
decision_id: string;
|
|
116
|
+
decision_title: string;
|
|
117
|
+
warning: string;
|
|
118
|
+
severity: 'low' | 'medium' | 'high';
|
|
119
|
+
}>;
|
|
120
|
+
};
|
|
121
|
+
/** Actionable suggestions to fix issues */
|
|
122
|
+
suggestions: string[];
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
// ============================================================================
|
|
126
|
+
// Handler
|
|
127
|
+
// ============================================================================
|
|
128
|
+
|
|
129
|
+
/**
|
|
130
|
+
* Handle a memory_verify gateway call
|
|
131
|
+
*/
|
|
132
|
+
export async function handleMemoryVerify(
|
|
133
|
+
engine: MemoryLayerEngine,
|
|
134
|
+
input: MemoryVerifyInput
|
|
135
|
+
): Promise<MemoryVerifyResponse> {
|
|
136
|
+
const checks = input.checks || ['all'];
|
|
137
|
+
const runAll = checks.includes('all');
|
|
138
|
+
const sourcesUsed: string[] = [];
|
|
139
|
+
const suggestions: string[] = [];
|
|
140
|
+
|
|
141
|
+
let totalScore = 100;
|
|
142
|
+
|
|
143
|
+
// Track file access for ghost mode
|
|
144
|
+
if (input.file) {
|
|
145
|
+
await engine.notifyFileAccess(input.file);
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
const response: MemoryVerifyResponse = {
|
|
149
|
+
verdict: 'pass',
|
|
150
|
+
score: 100,
|
|
151
|
+
sources_used: sourcesUsed,
|
|
152
|
+
summary: '',
|
|
153
|
+
suggestions: [],
|
|
154
|
+
};
|
|
155
|
+
|
|
156
|
+
// Run code verification (imports, security, dependencies)
|
|
157
|
+
if (runAll || checks.includes('imports') || checks.includes('security') || checks.includes('dependencies')) {
|
|
158
|
+
sourcesUsed.push('code_verifier');
|
|
159
|
+
|
|
160
|
+
const verifierChecks: ('imports' | 'security' | 'dependencies')[] = [];
|
|
161
|
+
if (runAll || checks.includes('imports')) verifierChecks.push('imports');
|
|
162
|
+
if (runAll || checks.includes('security')) verifierChecks.push('security');
|
|
163
|
+
if (runAll || checks.includes('dependencies')) verifierChecks.push('dependencies');
|
|
164
|
+
|
|
165
|
+
const verification = await engine.verifyCode(input.code, input.file, verifierChecks);
|
|
166
|
+
|
|
167
|
+
// Add import results
|
|
168
|
+
if (verification.imports) {
|
|
169
|
+
response.imports = {
|
|
170
|
+
valid: verification.imports.valid,
|
|
171
|
+
issues: verification.imports.issues,
|
|
172
|
+
warnings: verification.imports.warnings,
|
|
173
|
+
};
|
|
174
|
+
if (!verification.imports.valid) {
|
|
175
|
+
totalScore -= verification.imports.issues.length * 15;
|
|
176
|
+
suggestions.push(...verification.imports.issues.map(i => i.suggestion || i.message));
|
|
177
|
+
}
|
|
178
|
+
if (verification.imports.warnings.length > 0) {
|
|
179
|
+
totalScore -= verification.imports.warnings.length * 5;
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
// Add security results
|
|
184
|
+
if (verification.security) {
|
|
185
|
+
response.security = {
|
|
186
|
+
safe: verification.security.safe,
|
|
187
|
+
score: verification.security.score,
|
|
188
|
+
issues: verification.security.issues,
|
|
189
|
+
};
|
|
190
|
+
if (!verification.security.safe) {
|
|
191
|
+
totalScore = Math.min(totalScore, verification.security.score);
|
|
192
|
+
suggestions.push(...verification.security.issues.map(i => i.suggestion || i.message));
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
// Add dependency results
|
|
197
|
+
if (verification.dependencies) {
|
|
198
|
+
response.dependencies = {
|
|
199
|
+
valid: verification.dependencies.valid,
|
|
200
|
+
issues: verification.dependencies.issues,
|
|
201
|
+
};
|
|
202
|
+
if (!verification.dependencies.valid) {
|
|
203
|
+
totalScore -= verification.dependencies.issues.length * 10;
|
|
204
|
+
suggestions.push(...verification.dependencies.issues.map(d => d.suggestion || d.message));
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
// Run pattern validation
|
|
210
|
+
if (runAll || checks.includes('patterns')) {
|
|
211
|
+
sourcesUsed.push('validate_pattern');
|
|
212
|
+
|
|
213
|
+
const patternResult = engine.validatePattern(input.code);
|
|
214
|
+
|
|
215
|
+
response.patterns = {
|
|
216
|
+
valid: patternResult.valid,
|
|
217
|
+
score: patternResult.score,
|
|
218
|
+
matched_pattern: patternResult.matchedPattern,
|
|
219
|
+
violations: patternResult.violations,
|
|
220
|
+
};
|
|
221
|
+
|
|
222
|
+
if (!patternResult.valid) {
|
|
223
|
+
totalScore -= patternResult.violations.length * 10;
|
|
224
|
+
suggestions.push(...patternResult.violations
|
|
225
|
+
.filter(v => v.suggestion)
|
|
226
|
+
.map(v => v.suggestion!));
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
// Run test impact check
|
|
231
|
+
if ((runAll || checks.includes('tests')) && input.file) {
|
|
232
|
+
sourcesUsed.push('check_tests');
|
|
233
|
+
|
|
234
|
+
const testResult = engine.checkTests(input.code, input.file);
|
|
235
|
+
|
|
236
|
+
response.test_impact = {
|
|
237
|
+
safe: testResult.safe,
|
|
238
|
+
coverage_percent: testResult.coveragePercent,
|
|
239
|
+
would_fail: testResult.wouldFail.map(f => ({
|
|
240
|
+
test_name: f.test.name,
|
|
241
|
+
test_file: f.test.file,
|
|
242
|
+
reason: f.reason,
|
|
243
|
+
suggested_fix: f.suggestedFix,
|
|
244
|
+
})),
|
|
245
|
+
};
|
|
246
|
+
|
|
247
|
+
if (!testResult.safe) {
|
|
248
|
+
totalScore -= testResult.wouldFail.length * 15;
|
|
249
|
+
suggestions.push(...testResult.wouldFail.map(f => f.suggestedFix || `Test "${f.test.name}" would fail: ${f.reason}`));
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
// Check for decision conflicts (always run - it's cheap)
|
|
254
|
+
sourcesUsed.push('ghost_conflicts');
|
|
255
|
+
const conflicts = engine.checkGhostConflicts(input.code, input.file);
|
|
256
|
+
|
|
257
|
+
if (conflicts.length > 0) {
|
|
258
|
+
response.conflicts = {
|
|
259
|
+
has_conflicts: true,
|
|
260
|
+
conflicts: conflicts.map(c => ({
|
|
261
|
+
decision_id: c.decision.id,
|
|
262
|
+
decision_title: c.decision.title,
|
|
263
|
+
warning: c.warning,
|
|
264
|
+
severity: c.severity,
|
|
265
|
+
})),
|
|
266
|
+
};
|
|
267
|
+
|
|
268
|
+
const highSeverity = conflicts.filter(c => c.severity === 'high').length;
|
|
269
|
+
const mediumSeverity = conflicts.filter(c => c.severity === 'medium').length;
|
|
270
|
+
totalScore -= highSeverity * 20 + mediumSeverity * 10;
|
|
271
|
+
|
|
272
|
+
suggestions.push(...conflicts.map(c =>
|
|
273
|
+
`Potential conflict with decision "${c.decision.title}": ${c.warning}`
|
|
274
|
+
));
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
// Calculate final verdict
|
|
278
|
+
response.score = Math.max(0, Math.min(100, totalScore));
|
|
279
|
+
response.verdict = calculateVerdict(response);
|
|
280
|
+
response.summary = buildSummary(response);
|
|
281
|
+
response.suggestions = [...new Set(suggestions)].slice(0, 10);
|
|
282
|
+
|
|
283
|
+
return response;
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
// ============================================================================
|
|
287
|
+
// Helpers
|
|
288
|
+
// ============================================================================
|
|
289
|
+
|
|
290
|
+
function calculateVerdict(response: MemoryVerifyResponse): 'pass' | 'warning' | 'fail' {
|
|
291
|
+
// Critical security issues = fail
|
|
292
|
+
if (response.security?.issues.some(i => i.severity === 'critical')) {
|
|
293
|
+
return 'fail';
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
// Multiple high severity security issues = fail
|
|
297
|
+
const highSecurityCount = response.security?.issues.filter(i => i.severity === 'high').length || 0;
|
|
298
|
+
if (highSecurityCount >= 2) {
|
|
299
|
+
return 'fail';
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
// High severity conflicts = fail
|
|
303
|
+
if (response.conflicts?.conflicts.some(c => c.severity === 'high')) {
|
|
304
|
+
return 'fail';
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
// Missing packages (hallucination) = fail
|
|
308
|
+
const hallucinatedImports = response.imports?.issues.filter(i =>
|
|
309
|
+
i.type === 'missing_package' || i.type === 'hallucinated'
|
|
310
|
+
).length || 0;
|
|
311
|
+
if (hallucinatedImports >= 2) {
|
|
312
|
+
return 'fail';
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
// Score-based
|
|
316
|
+
if (response.score >= 70) return 'pass';
|
|
317
|
+
if (response.score >= 40) return 'warning';
|
|
318
|
+
return 'fail';
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
function buildSummary(response: MemoryVerifyResponse): string {
|
|
322
|
+
const parts: string[] = [];
|
|
323
|
+
|
|
324
|
+
// Imports
|
|
325
|
+
if (response.imports) {
|
|
326
|
+
if (response.imports.valid && response.imports.warnings.length === 0) {
|
|
327
|
+
parts.push('Imports: OK');
|
|
328
|
+
} else {
|
|
329
|
+
const issueCount = response.imports.issues.length;
|
|
330
|
+
const warnCount = response.imports.warnings.length;
|
|
331
|
+
if (issueCount > 0) {
|
|
332
|
+
parts.push(`Imports: ${issueCount} issue${issueCount > 1 ? 's' : ''}`);
|
|
333
|
+
}
|
|
334
|
+
if (warnCount > 0) {
|
|
335
|
+
parts.push(`${warnCount} warning${warnCount > 1 ? 's' : ''}`);
|
|
336
|
+
}
|
|
337
|
+
}
|
|
338
|
+
}
|
|
339
|
+
|
|
340
|
+
// Security
|
|
341
|
+
if (response.security) {
|
|
342
|
+
if (response.security.safe) {
|
|
343
|
+
parts.push('Security: OK');
|
|
344
|
+
} else {
|
|
345
|
+
const critical = response.security.issues.filter(i => i.severity === 'critical').length;
|
|
346
|
+
const high = response.security.issues.filter(i => i.severity === 'high').length;
|
|
347
|
+
const medium = response.security.issues.filter(i => i.severity === 'medium').length;
|
|
348
|
+
|
|
349
|
+
const secParts: string[] = [];
|
|
350
|
+
if (critical > 0) secParts.push(`${critical} critical`);
|
|
351
|
+
if (high > 0) secParts.push(`${high} high`);
|
|
352
|
+
if (medium > 0) secParts.push(`${medium} medium`);
|
|
353
|
+
parts.push(`Security: ${secParts.join(', ')}`);
|
|
354
|
+
}
|
|
355
|
+
}
|
|
356
|
+
|
|
357
|
+
// Dependencies
|
|
358
|
+
if (response.dependencies) {
|
|
359
|
+
if (response.dependencies.valid) {
|
|
360
|
+
parts.push('Deps: OK');
|
|
361
|
+
} else {
|
|
362
|
+
parts.push(`Deps: ${response.dependencies.issues.length} issue${response.dependencies.issues.length > 1 ? 's' : ''}`);
|
|
363
|
+
}
|
|
364
|
+
}
|
|
365
|
+
|
|
366
|
+
// Patterns
|
|
367
|
+
if (response.patterns) {
|
|
368
|
+
if (response.patterns.valid) {
|
|
369
|
+
parts.push('Patterns: OK');
|
|
370
|
+
} else {
|
|
371
|
+
parts.push(`Patterns: ${response.patterns.violations.length} violation${response.patterns.violations.length > 1 ? 's' : ''}`);
|
|
372
|
+
}
|
|
373
|
+
}
|
|
374
|
+
|
|
375
|
+
// Tests
|
|
376
|
+
if (response.test_impact) {
|
|
377
|
+
if (response.test_impact.safe) {
|
|
378
|
+
parts.push('Tests: OK');
|
|
379
|
+
} else {
|
|
380
|
+
parts.push(`Tests: ${response.test_impact.would_fail.length} would fail`);
|
|
381
|
+
}
|
|
382
|
+
}
|
|
383
|
+
|
|
384
|
+
// Conflicts
|
|
385
|
+
if (response.conflicts?.has_conflicts) {
|
|
386
|
+
parts.push(`Conflicts: ${response.conflicts.conflicts.length}`);
|
|
387
|
+
}
|
|
388
|
+
|
|
389
|
+
const verdictEmoji = response.verdict === 'pass' ? '✅' : response.verdict === 'warning' ? '⚠️' : '❌';
|
|
390
|
+
|
|
391
|
+
return `${verdictEmoji} [${response.verdict.toUpperCase()}] Score: ${response.score}/100 | ${parts.join(' | ')}`;
|
|
392
|
+
}
|