driftdetect-core 0.1.1 → 0.1.2
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/dist/index.d.ts +4 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +5 -0
- package/dist/index.js.map +1 -1
- package/dist/learning/index.d.ts +8 -0
- package/dist/learning/index.d.ts.map +1 -0
- package/dist/learning/index.js +8 -0
- package/dist/learning/index.js.map +1 -0
- package/dist/learning/learning-store.d.ts +63 -0
- package/dist/learning/learning-store.d.ts.map +1 -0
- package/dist/learning/learning-store.js +168 -0
- package/dist/learning/learning-store.js.map +1 -0
- package/dist/learning/types.d.ts +178 -0
- package/dist/learning/types.d.ts.map +1 -0
- package/dist/learning/types.js +28 -0
- package/dist/learning/types.js.map +1 -0
- package/dist/store/contract-store.d.ts +79 -0
- package/dist/store/contract-store.d.ts.map +1 -0
- package/dist/store/contract-store.js +506 -0
- package/dist/store/contract-store.js.map +1 -0
- package/dist/types/contracts.d.ts +280 -0
- package/dist/types/contracts.d.ts.map +1 -0
- package/dist/types/contracts.js +14 -0
- package/dist/types/contracts.js.map +1 -0
- package/package.json +8 -2
package/dist/index.d.ts
CHANGED
|
@@ -28,10 +28,14 @@ export type { PatternFile, StoredPattern, DetectorConfig, ConfidenceInfo, Patter
|
|
|
28
28
|
export { CacheManager } from './store/cache-manager.js';
|
|
29
29
|
export type { CacheManagerOptions, CacheEntry, CacheStats } from './store/cache-manager.js';
|
|
30
30
|
export { PatternStore, PatternNotFoundError, InvalidStateTransitionError, PatternStoreError } from './store/pattern-store.js';
|
|
31
|
+
export * from './types/contracts.js';
|
|
32
|
+
export { ContractStore, ContractNotFoundError, InvalidContractTransitionError, ContractStoreError } from './store/contract-store.js';
|
|
33
|
+
export type { ContractStoreConfig, ContractStoreEvent, ContractStoreEventType } from './store/contract-store.js';
|
|
31
34
|
export type { Position as RulePosition, Violation, QuickFix, Range, Severity, ViolationInput, RuleEvaluationResult, RuleEvaluationSummary, RuleEvaluationError } from './rules/types.js';
|
|
32
35
|
export { Evaluator, createEvaluator, createEvaluatorWithConfig, createEvaluatorWithAI, type EvaluatorConfig, type EvaluationInput, type EvaluationResult, type EvaluationSummary } from './rules/evaluator.js';
|
|
33
36
|
export { RuleEngine, createRuleEngine, createRuleEngineWithConfig, createRuleEngineWithAI, type RuleEngineConfig, type RuleEvaluationInput, type PatternWithContext } from './rules/rule-engine.js';
|
|
34
37
|
export { VariantManager, VariantNotFoundError, VariantManagerError, InvalidVariantInputError, type CreateVariantInput, type UpdateVariantInput, type VariantQuery, type VariantManagerEvent, type VariantManagerEventType, type VariantManagerConfig } from './rules/variant-manager.js';
|
|
35
38
|
export * from './config/index.js';
|
|
36
39
|
export * from './manifest/index.js';
|
|
40
|
+
export * from './learning/index.js';
|
|
37
41
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAGH,eAAO,MAAM,OAAO,UAAU,CAAC;AAG/B,cAAc,kBAAkB,CAAC;AAGjC,cAAc,oBAAoB,CAAC;AAGnC,YAAY,EACV,QAAQ,EACR,GAAG,EACH,OAAO,EACP,WAAW,EACX,UAAU,EACV,QAAQ,IAAI,cAAc,GAC3B,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAAE,UAAU,EAAE,MAAM,0BAA0B,CAAC;AACtD,OAAO,EAAE,aAAa,EAAE,MAAM,6BAA6B,CAAC;AAC5D,OAAO,EAAE,gBAAgB,EAAE,MAAM,gCAAgC,CAAC;AAClE,OAAO,EAAE,YAAY,EAAE,MAAM,4BAA4B,CAAC;AAC1D,OAAO,EAAE,SAAS,EAAE,MAAM,yBAAyB,CAAC;AACpD,OAAO,EAAE,UAAU,EAAE,MAAM,0BAA0B,CAAC;AACtD,OAAO,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAC;AAG9D,cAAc,sBAAsB,CAAC;AAGrC,YAAY,EAEV,YAAY,EACZ,kBAAkB,EAClB,qBAAqB,EACrB,QAAQ,IAAI,aAAa,EACzB,WAAW,EAGX,SAAS,EACT,iBAAiB,EAGjB,eAAe,EACf,eAAe,EACf,iBAAiB,EACjB,eAAe,EAGf,iBAAiB,EACjB,cAAc,EACd,gBAAgB,EAChB,qBAAqB,EACrB,eAAe,IAAI,sBAAsB,EAGzC,WAAW,EACX,WAAW,EACX,mBAAmB,EACnB,cAAc,EACd,iBAAiB,EACjB,sBAAsB,EACtB,sBAAsB,EAGtB,aAAa,EACb,kBAAkB,EAClB,cAAc,EACd,cAAc,EACd,aAAa,GACd,MAAM,oBAAoB,CAAC;AAG5B,OAAO,EACL,qBAAqB,EACrB,0BAA0B,GAC3B,MAAM,oBAAoB,CAAC;AAG5B,YAAY,EAAE,WAAW,EAAE,aAAa,EAAE,cAAc,EAAE,cAAc,EAAE,eAAe,EAAE,eAAe,EAAE,kBAAkB,EAAE,eAAe,EAAE,aAAa,EAAE,OAAO,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAChO,OAAO,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAC;AACxD,YAAY,EAAE,mBAAmB,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,0BAA0B,CAAC;AAC5F,OAAO,EAAE,YAAY,EAAE,oBAAoB,EAAE,2BAA2B,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAG9H,YAAY,EAAE,QAAQ,IAAI,YAAY,EAAE,SAAS,EAAE,QAAQ,EAAE,KAAK,EAAE,QAAQ,EAAE,cAAc,EAAE,oBAAoB,EAAE,qBAAqB,EAAE,mBAAmB,EAAE,MAAM,kBAAkB,CAAC;AACzL,OAAO,EAAE,SAAS,EAAE,eAAe,EAAE,yBAAyB,EAAE,qBAAqB,EAAE,KAAK,eAAe,EAAE,KAAK,eAAe,EAAE,KAAK,gBAAgB,EAAE,KAAK,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AAC/M,OAAO,EAAE,UAAU,EAAE,gBAAgB,EAAE,0BAA0B,EAAE,sBAAsB,EAAE,KAAK,gBAAgB,EAAE,KAAK,mBAAmB,EAAE,KAAK,kBAAkB,EAAE,MAAM,wBAAwB,CAAC;AACpM,OAAO,EAAE,cAAc,EAAE,oBAAoB,EAAE,mBAAmB,EAAE,wBAAwB,EAAE,KAAK,kBAAkB,EAAE,KAAK,kBAAkB,EAAE,KAAK,YAAY,EAAE,KAAK,mBAAmB,EAAE,KAAK,uBAAuB,EAAE,KAAK,oBAAoB,EAAE,MAAM,4BAA4B,CAAC;AAGzR,cAAc,mBAAmB,CAAC;AAGlC,cAAc,qBAAqB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/dist/index.js
CHANGED
|
@@ -29,6 +29,9 @@ export * from './analyzers/index.js';
|
|
|
29
29
|
export { CONFIDENCE_THRESHOLDS, DEFAULT_CONFIDENCE_WEIGHTS, } from './matcher/types.js';
|
|
30
30
|
export { CacheManager } from './store/cache-manager.js';
|
|
31
31
|
export { PatternStore, PatternNotFoundError, InvalidStateTransitionError, PatternStoreError } from './store/pattern-store.js';
|
|
32
|
+
// Contract exports (BE↔FE mismatch detection)
|
|
33
|
+
export * from './types/contracts.js';
|
|
34
|
+
export { ContractStore, ContractNotFoundError, InvalidContractTransitionError, ContractStoreError } from './store/contract-store.js';
|
|
32
35
|
export { Evaluator, createEvaluator, createEvaluatorWithConfig, createEvaluatorWithAI } from './rules/evaluator.js';
|
|
33
36
|
export { RuleEngine, createRuleEngine, createRuleEngineWithConfig, createRuleEngineWithAI } from './rules/rule-engine.js';
|
|
34
37
|
export { VariantManager, VariantNotFoundError, VariantManagerError, InvalidVariantInputError } from './rules/variant-manager.js';
|
|
@@ -36,4 +39,6 @@ export { VariantManager, VariantNotFoundError, VariantManagerError, InvalidVaria
|
|
|
36
39
|
export * from './config/index.js';
|
|
37
40
|
// Manifest exports (pattern location discovery)
|
|
38
41
|
export * from './manifest/index.js';
|
|
42
|
+
// Learning exports (pattern learning system)
|
|
43
|
+
export * from './learning/index.js';
|
|
39
44
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,iBAAiB;AACjB,MAAM,CAAC,MAAM,OAAO,GAAG,OAAO,CAAC;AAE/B,iCAAiC;AACjC,cAAc,kBAAkB,CAAC;AAEjC,kBAAkB;AAClB,cAAc,oBAAoB,CAAC;AAWnC,OAAO,EAAE,UAAU,EAAE,MAAM,0BAA0B,CAAC;AACtD,OAAO,EAAE,aAAa,EAAE,MAAM,6BAA6B,CAAC;AAC5D,OAAO,EAAE,gBAAgB,EAAE,MAAM,gCAAgC,CAAC;AAClE,OAAO,EAAE,YAAY,EAAE,MAAM,4BAA4B,CAAC;AAC1D,OAAO,EAAE,SAAS,EAAE,MAAM,yBAAyB,CAAC;AACpD,OAAO,EAAE,UAAU,EAAE,MAAM,0BAA0B,CAAC;AACtD,OAAO,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAC;AAE9D,mBAAmB;AACnB,cAAc,sBAAsB,CAAC;AA6CrC,oBAAoB;AACpB,OAAO,EACL,qBAAqB,EACrB,0BAA0B,GAC3B,MAAM,oBAAoB,CAAC;AAI5B,OAAO,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAC;AAExD,OAAO,EAAE,YAAY,EAAE,oBAAoB,EAAE,2BAA2B,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,iBAAiB;AACjB,MAAM,CAAC,MAAM,OAAO,GAAG,OAAO,CAAC;AAE/B,iCAAiC;AACjC,cAAc,kBAAkB,CAAC;AAEjC,kBAAkB;AAClB,cAAc,oBAAoB,CAAC;AAWnC,OAAO,EAAE,UAAU,EAAE,MAAM,0BAA0B,CAAC;AACtD,OAAO,EAAE,aAAa,EAAE,MAAM,6BAA6B,CAAC;AAC5D,OAAO,EAAE,gBAAgB,EAAE,MAAM,gCAAgC,CAAC;AAClE,OAAO,EAAE,YAAY,EAAE,MAAM,4BAA4B,CAAC;AAC1D,OAAO,EAAE,SAAS,EAAE,MAAM,yBAAyB,CAAC;AACpD,OAAO,EAAE,UAAU,EAAE,MAAM,0BAA0B,CAAC;AACtD,OAAO,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAC;AAE9D,mBAAmB;AACnB,cAAc,sBAAsB,CAAC;AA6CrC,oBAAoB;AACpB,OAAO,EACL,qBAAqB,EACrB,0BAA0B,GAC3B,MAAM,oBAAoB,CAAC;AAI5B,OAAO,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAC;AAExD,OAAO,EAAE,YAAY,EAAE,oBAAoB,EAAE,2BAA2B,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAE9H,8CAA8C;AAC9C,cAAc,sBAAsB,CAAC;AACrC,OAAO,EAAE,aAAa,EAAE,qBAAqB,EAAE,8BAA8B,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;AAKrI,OAAO,EAAE,SAAS,EAAE,eAAe,EAAE,yBAAyB,EAAE,qBAAqB,EAA6F,MAAM,sBAAsB,CAAC;AAC/M,OAAO,EAAE,UAAU,EAAE,gBAAgB,EAAE,0BAA0B,EAAE,sBAAsB,EAA4E,MAAM,wBAAwB,CAAC;AACpM,OAAO,EAAE,cAAc,EAAE,oBAAoB,EAAE,mBAAmB,EAAE,wBAAwB,EAA0J,MAAM,4BAA4B,CAAC;AAEzR,iBAAiB;AACjB,cAAc,mBAAmB,CAAC;AAElC,gDAAgD;AAChD,cAAc,qBAAqB,CAAC;AAEpC,6CAA6C;AAC7C,cAAc,qBAAqB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/learning/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,cAAc,YAAY,CAAC;AAC3B,cAAc,qBAAqB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/learning/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,cAAc,YAAY,CAAC;AAC3B,cAAc,qBAAqB,CAAC"}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Learning Store
|
|
3
|
+
*
|
|
4
|
+
* Persists and retrieves learned patterns from .drift/learned/
|
|
5
|
+
*
|
|
6
|
+
* @requirements DRIFT-CORE - Store learned conventions for reuse
|
|
7
|
+
*/
|
|
8
|
+
import type { StoredLearnedPatterns, PatternLearningConfig } from './types.js';
|
|
9
|
+
export declare class LearningStore {
|
|
10
|
+
private rootDir;
|
|
11
|
+
private cache;
|
|
12
|
+
constructor(rootDir?: string);
|
|
13
|
+
/**
|
|
14
|
+
* Get the path to the learned patterns directory
|
|
15
|
+
*/
|
|
16
|
+
private getLearnedDir;
|
|
17
|
+
/**
|
|
18
|
+
* Get the path to a detector's learned patterns file
|
|
19
|
+
*/
|
|
20
|
+
private getDetectorPath;
|
|
21
|
+
/**
|
|
22
|
+
* Ensure the learned directory exists
|
|
23
|
+
*/
|
|
24
|
+
private ensureDir;
|
|
25
|
+
/**
|
|
26
|
+
* Load learned patterns for a detector
|
|
27
|
+
*/
|
|
28
|
+
load(detectorId: string): Promise<StoredLearnedPatterns | null>;
|
|
29
|
+
/**
|
|
30
|
+
* Save learned patterns for a detector
|
|
31
|
+
*/
|
|
32
|
+
save(patterns: StoredLearnedPatterns): Promise<void>;
|
|
33
|
+
/**
|
|
34
|
+
* Check if learned patterns exist and are fresh
|
|
35
|
+
*/
|
|
36
|
+
hasFreshPatterns(detectorId: string, maxAgeMs?: number): Promise<boolean>;
|
|
37
|
+
/**
|
|
38
|
+
* Clear learned patterns for a detector
|
|
39
|
+
*/
|
|
40
|
+
clear(detectorId: string): Promise<void>;
|
|
41
|
+
/**
|
|
42
|
+
* Clear all learned patterns
|
|
43
|
+
*/
|
|
44
|
+
clearAll(): Promise<void>;
|
|
45
|
+
/**
|
|
46
|
+
* List all detectors with learned patterns
|
|
47
|
+
*/
|
|
48
|
+
listDetectors(): Promise<string[]>;
|
|
49
|
+
/**
|
|
50
|
+
* Create a StoredLearnedPatterns object
|
|
51
|
+
*/
|
|
52
|
+
static createStoredPatterns(detectorId: string, conventions: Record<string, unknown>, metadata: {
|
|
53
|
+
filesAnalyzed: number;
|
|
54
|
+
relevantFiles: number;
|
|
55
|
+
hasEnoughData: boolean;
|
|
56
|
+
configUsed: PatternLearningConfig;
|
|
57
|
+
}): StoredLearnedPatterns;
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* Create a learning store instance
|
|
61
|
+
*/
|
|
62
|
+
export declare function createLearningStore(rootDir?: string): LearningStore;
|
|
63
|
+
//# sourceMappingURL=learning-store.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"learning-store.d.ts","sourceRoot":"","sources":["../../src/learning/learning-store.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAIH,OAAO,KAAK,EAAE,qBAAqB,EAAE,qBAAqB,EAAE,MAAM,YAAY,CAAC;AAa/E,qBAAa,aAAa;IACxB,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,KAAK,CAAiD;gBAElD,OAAO,GAAE,MAAY;IAIjC;;OAEG;IACH,OAAO,CAAC,aAAa;IAIrB;;OAEG;IACH,OAAO,CAAC,eAAe;IAMvB;;OAEG;YACW,SAAS;IAKvB;;OAEG;IACG,IAAI,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,qBAAqB,GAAG,IAAI,CAAC;IA6BrE;;OAEG;IACG,IAAI,CAAC,QAAQ,EAAE,qBAAqB,GAAG,OAAO,CAAC,IAAI,CAAC;IAU1D;;OAEG;IACG,gBAAgB,CACpB,UAAU,EAAE,MAAM,EAClB,QAAQ,GAAE,MAA4B,GACrC,OAAO,CAAC,OAAO,CAAC;IAYnB;;OAEG;IACG,KAAK,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAa9C;;OAEG;IACG,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC;IAkB/B;;OAEG;IACG,aAAa,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;IAgBxC;;OAEG;IACH,MAAM,CAAC,oBAAoB,CACzB,UAAU,EAAE,MAAM,EAClB,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EACpC,QAAQ,EAAE;QACR,aAAa,EAAE,MAAM,CAAC;QACtB,aAAa,EAAE,MAAM,CAAC;QACtB,aAAa,EAAE,OAAO,CAAC;QACvB,UAAU,EAAE,qBAAqB,CAAC;KACnC,GACA,qBAAqB;CAWzB;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,OAAO,GAAE,MAAY,GAAG,aAAa,CAExE"}
|
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Learning Store
|
|
3
|
+
*
|
|
4
|
+
* Persists and retrieves learned patterns from .drift/learned/
|
|
5
|
+
*
|
|
6
|
+
* @requirements DRIFT-CORE - Store learned conventions for reuse
|
|
7
|
+
*/
|
|
8
|
+
import { promises as fs } from 'fs';
|
|
9
|
+
import * as path from 'path';
|
|
10
|
+
// ============================================================================
|
|
11
|
+
// Constants
|
|
12
|
+
// ============================================================================
|
|
13
|
+
const LEARNED_DIR = '.drift/learned';
|
|
14
|
+
const SCHEMA_VERSION = '1.0.0';
|
|
15
|
+
// ============================================================================
|
|
16
|
+
// Learning Store
|
|
17
|
+
// ============================================================================
|
|
18
|
+
export class LearningStore {
|
|
19
|
+
rootDir;
|
|
20
|
+
cache = new Map();
|
|
21
|
+
constructor(rootDir = '.') {
|
|
22
|
+
this.rootDir = rootDir;
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Get the path to the learned patterns directory
|
|
26
|
+
*/
|
|
27
|
+
getLearnedDir() {
|
|
28
|
+
return path.join(this.rootDir, LEARNED_DIR);
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Get the path to a detector's learned patterns file
|
|
32
|
+
*/
|
|
33
|
+
getDetectorPath(detectorId) {
|
|
34
|
+
// Convert detector ID to safe filename (e.g., "api/route-structure" -> "api-route-structure.json")
|
|
35
|
+
const safeId = detectorId.replace(/\//g, '-');
|
|
36
|
+
return path.join(this.getLearnedDir(), `${safeId}.json`);
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Ensure the learned directory exists
|
|
40
|
+
*/
|
|
41
|
+
async ensureDir() {
|
|
42
|
+
const dir = this.getLearnedDir();
|
|
43
|
+
await fs.mkdir(dir, { recursive: true });
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Load learned patterns for a detector
|
|
47
|
+
*/
|
|
48
|
+
async load(detectorId) {
|
|
49
|
+
// Check cache first
|
|
50
|
+
const cached = this.cache.get(detectorId);
|
|
51
|
+
if (cached) {
|
|
52
|
+
return cached;
|
|
53
|
+
}
|
|
54
|
+
const filePath = this.getDetectorPath(detectorId);
|
|
55
|
+
try {
|
|
56
|
+
const content = await fs.readFile(filePath, 'utf-8');
|
|
57
|
+
const data = JSON.parse(content);
|
|
58
|
+
// Validate version
|
|
59
|
+
if (data.version !== SCHEMA_VERSION) {
|
|
60
|
+
console.warn(`Learned patterns for ${detectorId} have outdated schema version`);
|
|
61
|
+
return null;
|
|
62
|
+
}
|
|
63
|
+
this.cache.set(detectorId, data);
|
|
64
|
+
return data;
|
|
65
|
+
}
|
|
66
|
+
catch (error) {
|
|
67
|
+
if (error.code === 'ENOENT') {
|
|
68
|
+
return null; // File doesn't exist, need to learn
|
|
69
|
+
}
|
|
70
|
+
throw error;
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* Save learned patterns for a detector
|
|
75
|
+
*/
|
|
76
|
+
async save(patterns) {
|
|
77
|
+
await this.ensureDir();
|
|
78
|
+
const filePath = this.getDetectorPath(patterns.detectorId);
|
|
79
|
+
const content = JSON.stringify(patterns, null, 2);
|
|
80
|
+
await fs.writeFile(filePath, content, 'utf-8');
|
|
81
|
+
this.cache.set(patterns.detectorId, patterns);
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* Check if learned patterns exist and are fresh
|
|
85
|
+
*/
|
|
86
|
+
async hasFreshPatterns(detectorId, maxAgeMs = 24 * 60 * 60 * 1000 // 24 hours default
|
|
87
|
+
) {
|
|
88
|
+
const patterns = await this.load(detectorId);
|
|
89
|
+
if (!patterns) {
|
|
90
|
+
return false;
|
|
91
|
+
}
|
|
92
|
+
const learnedAt = new Date(patterns.metadata.learnedAt).getTime();
|
|
93
|
+
const age = Date.now() - learnedAt;
|
|
94
|
+
return age < maxAgeMs;
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
97
|
+
* Clear learned patterns for a detector
|
|
98
|
+
*/
|
|
99
|
+
async clear(detectorId) {
|
|
100
|
+
const filePath = this.getDetectorPath(detectorId);
|
|
101
|
+
this.cache.delete(detectorId);
|
|
102
|
+
try {
|
|
103
|
+
await fs.unlink(filePath);
|
|
104
|
+
}
|
|
105
|
+
catch (error) {
|
|
106
|
+
if (error.code !== 'ENOENT') {
|
|
107
|
+
throw error;
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
/**
|
|
112
|
+
* Clear all learned patterns
|
|
113
|
+
*/
|
|
114
|
+
async clearAll() {
|
|
115
|
+
this.cache.clear();
|
|
116
|
+
const dir = this.getLearnedDir();
|
|
117
|
+
try {
|
|
118
|
+
const files = await fs.readdir(dir);
|
|
119
|
+
await Promise.all(files
|
|
120
|
+
.filter(f => f.endsWith('.json'))
|
|
121
|
+
.map(f => fs.unlink(path.join(dir, f))));
|
|
122
|
+
}
|
|
123
|
+
catch (error) {
|
|
124
|
+
if (error.code !== 'ENOENT') {
|
|
125
|
+
throw error;
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
/**
|
|
130
|
+
* List all detectors with learned patterns
|
|
131
|
+
*/
|
|
132
|
+
async listDetectors() {
|
|
133
|
+
const dir = this.getLearnedDir();
|
|
134
|
+
try {
|
|
135
|
+
const files = await fs.readdir(dir);
|
|
136
|
+
return files
|
|
137
|
+
.filter(f => f.endsWith('.json'))
|
|
138
|
+
.map(f => f.replace('.json', '').replace(/-/g, '/'));
|
|
139
|
+
}
|
|
140
|
+
catch (error) {
|
|
141
|
+
if (error.code === 'ENOENT') {
|
|
142
|
+
return [];
|
|
143
|
+
}
|
|
144
|
+
throw error;
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
/**
|
|
148
|
+
* Create a StoredLearnedPatterns object
|
|
149
|
+
*/
|
|
150
|
+
static createStoredPatterns(detectorId, conventions, metadata) {
|
|
151
|
+
return {
|
|
152
|
+
detectorId,
|
|
153
|
+
version: SCHEMA_VERSION,
|
|
154
|
+
conventions: conventions,
|
|
155
|
+
metadata: {
|
|
156
|
+
...metadata,
|
|
157
|
+
learnedAt: new Date().toISOString(),
|
|
158
|
+
},
|
|
159
|
+
};
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
/**
|
|
163
|
+
* Create a learning store instance
|
|
164
|
+
*/
|
|
165
|
+
export function createLearningStore(rootDir = '.') {
|
|
166
|
+
return new LearningStore(rootDir);
|
|
167
|
+
}
|
|
168
|
+
//# sourceMappingURL=learning-store.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"learning-store.js","sourceRoot":"","sources":["../../src/learning/learning-store.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,QAAQ,IAAI,EAAE,EAAE,MAAM,IAAI,CAAC;AACpC,OAAO,KAAK,IAAI,MAAM,MAAM,CAAC;AAG7B,+EAA+E;AAC/E,YAAY;AACZ,+EAA+E;AAE/E,MAAM,WAAW,GAAG,gBAAgB,CAAC;AACrC,MAAM,cAAc,GAAG,OAAO,CAAC;AAE/B,+EAA+E;AAC/E,iBAAiB;AACjB,+EAA+E;AAE/E,MAAM,OAAO,aAAa;IAChB,OAAO,CAAS;IAChB,KAAK,GAAuC,IAAI,GAAG,EAAE,CAAC;IAE9D,YAAY,UAAkB,GAAG;QAC/B,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;IACzB,CAAC;IAED;;OAEG;IACK,aAAa;QACnB,OAAO,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,WAAW,CAAC,CAAC;IAC9C,CAAC;IAED;;OAEG;IACK,eAAe,CAAC,UAAkB;QACxC,mGAAmG;QACnG,MAAM,MAAM,GAAG,UAAU,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;QAC9C,OAAO,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,aAAa,EAAE,EAAE,GAAG,MAAM,OAAO,CAAC,CAAC;IAC3D,CAAC;IAED;;OAEG;IACK,KAAK,CAAC,SAAS;QACrB,MAAM,GAAG,GAAG,IAAI,CAAC,aAAa,EAAE,CAAC;QACjC,MAAM,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAC3C,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,IAAI,CAAC,UAAkB;QAC3B,oBAAoB;QACpB,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;QAC1C,IAAI,MAAM,EAAE,CAAC;YACX,OAAO,MAAM,CAAC;QAChB,CAAC;QAED,MAAM,QAAQ,GAAG,IAAI,CAAC,eAAe,CAAC,UAAU,CAAC,CAAC;QAElD,IAAI,CAAC;YACH,MAAM,OAAO,GAAG,MAAM,EAAE,CAAC,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;YACrD,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,CAA0B,CAAC;YAE1D,mBAAmB;YACnB,IAAI,IAAI,CAAC,OAAO,KAAK,cAAc,EAAE,CAAC;gBACpC,OAAO,CAAC,IAAI,CAAC,wBAAwB,UAAU,+BAA+B,CAAC,CAAC;gBAChF,OAAO,IAAI,CAAC;YACd,CAAC;YAED,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,UAAU,EAAE,IAAI,CAAC,CAAC;YACjC,OAAO,IAAI,CAAC;QACd,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,IAAK,KAA+B,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;gBACvD,OAAO,IAAI,CAAC,CAAC,oCAAoC;YACnD,CAAC;YACD,MAAM,KAAK,CAAC;QACd,CAAC;IACH,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,IAAI,CAAC,QAA+B;QACxC,MAAM,IAAI,CAAC,SAAS,EAAE,CAAC;QAEvB,MAAM,QAAQ,GAAG,IAAI,CAAC,eAAe,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAC;QAC3D,MAAM,OAAO,GAAG,IAAI,CAAC,SAAS,CAAC,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC;QAElD,MAAM,EAAE,CAAC,SAAS,CAAC,QAAQ,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC;QAC/C,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,QAAQ,CAAC,UAAU,EAAE,QAAQ,CAAC,CAAC;IAChD,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,gBAAgB,CACpB,UAAkB,EAClB,WAAmB,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC,mBAAmB;;QAE1D,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;QAC7C,IAAI,CAAC,QAAQ,EAAE,CAAC;YACd,OAAO,KAAK,CAAC;QACf,CAAC;QAED,MAAM,SAAS,GAAG,IAAI,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC,OAAO,EAAE,CAAC;QAClE,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,SAAS,CAAC;QAEnC,OAAO,GAAG,GAAG,QAAQ,CAAC;IACxB,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,KAAK,CAAC,UAAkB;QAC5B,MAAM,QAAQ,GAAG,IAAI,CAAC,eAAe,CAAC,UAAU,CAAC,CAAC;QAClD,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC;QAE9B,IAAI,CAAC;YACH,MAAM,EAAE,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;QAC5B,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,IAAK,KAA+B,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;gBACvD,MAAM,KAAK,CAAC;YACd,CAAC;QACH,CAAC;IACH,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,QAAQ;QACZ,IAAI,CAAC,KAAK,CAAC,KAAK,EAAE,CAAC;QACnB,MAAM,GAAG,GAAG,IAAI,CAAC,aAAa,EAAE,CAAC;QAEjC,IAAI,CAAC;YACH,MAAM,KAAK,GAAG,MAAM,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;YACpC,MAAM,OAAO,CAAC,GAAG,CACf,KAAK;iBACF,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;iBAChC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC,CAC1C,CAAC;QACJ,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,IAAK,KAA+B,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;gBACvD,MAAM,KAAK,CAAC;YACd,CAAC;QACH,CAAC;IACH,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,aAAa;QACjB,MAAM,GAAG,GAAG,IAAI,CAAC,aAAa,EAAE,CAAC;QAEjC,IAAI,CAAC;YACH,MAAM,KAAK,GAAG,MAAM,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;YACpC,OAAO,KAAK;iBACT,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;iBAChC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC,CAAC;QACzD,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,IAAK,KAA+B,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;gBACvD,OAAO,EAAE,CAAC;YACZ,CAAC;YACD,MAAM,KAAK,CAAC;QACd,CAAC;IACH,CAAC;IAED;;OAEG;IACH,MAAM,CAAC,oBAAoB,CACzB,UAAkB,EAClB,WAAoC,EACpC,QAKC;QAED,OAAO;YACL,UAAU;YACV,OAAO,EAAE,cAAc;YACvB,WAAW,EAAE,WAAwE;YACrF,QAAQ,EAAE;gBACR,GAAG,QAAQ;gBACX,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;aACpC;SACF,CAAC;IACJ,CAAC;CACF;AAED;;GAEG;AACH,MAAM,UAAU,mBAAmB,CAAC,UAAkB,GAAG;IACvD,OAAO,IAAI,aAAa,CAAC,OAAO,CAAC,CAAC;AACpC,CAAC"}
|
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Learned Patterns Type System
|
|
3
|
+
*
|
|
4
|
+
* Types for pattern learning - detectors learn from the user's codebase
|
|
5
|
+
* rather than enforcing hardcoded conventions.
|
|
6
|
+
*
|
|
7
|
+
* @requirements DRIFT-CORE - Detectors learn patterns from user's code, not enforce arbitrary rules
|
|
8
|
+
*/
|
|
9
|
+
/**
|
|
10
|
+
* A convention learned from analyzing the codebase
|
|
11
|
+
*/
|
|
12
|
+
export interface LearnedConvention<T = unknown> {
|
|
13
|
+
/** The learned value/pattern */
|
|
14
|
+
value: T;
|
|
15
|
+
/** Number of occurrences found */
|
|
16
|
+
occurrences: number;
|
|
17
|
+
/** Files where this convention was found */
|
|
18
|
+
files: string[];
|
|
19
|
+
/** First line where this was seen (for reference) */
|
|
20
|
+
firstSeenAt?: {
|
|
21
|
+
file: string;
|
|
22
|
+
line: number;
|
|
23
|
+
};
|
|
24
|
+
/** Confidence that this is the dominant convention (0-1) */
|
|
25
|
+
confidence: number;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Result of learning conventions from a codebase
|
|
29
|
+
*/
|
|
30
|
+
export interface LearnedConventions<T extends Record<string, unknown> = Record<string, unknown>> {
|
|
31
|
+
/** The learned conventions by key */
|
|
32
|
+
conventions: {
|
|
33
|
+
[K in keyof T]: LearnedConvention<T[K]>;
|
|
34
|
+
};
|
|
35
|
+
/** Total files analyzed */
|
|
36
|
+
filesAnalyzed: number;
|
|
37
|
+
/** Files that matched the detector's scope */
|
|
38
|
+
relevantFiles: number;
|
|
39
|
+
/** When the learning was performed */
|
|
40
|
+
learnedAt: string;
|
|
41
|
+
/** Whether enough data was found to establish conventions */
|
|
42
|
+
hasEnoughData: boolean;
|
|
43
|
+
/** Minimum occurrences needed to establish a convention */
|
|
44
|
+
minOccurrencesRequired: number;
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Statistics about a learned value distribution
|
|
48
|
+
*/
|
|
49
|
+
export interface ValueDistribution<T = unknown> {
|
|
50
|
+
/** All values found with their counts */
|
|
51
|
+
values: Map<T, number>;
|
|
52
|
+
/** The dominant value (most common) */
|
|
53
|
+
dominant: T | null;
|
|
54
|
+
/** Percentage of occurrences that use the dominant value */
|
|
55
|
+
dominantPercentage: number;
|
|
56
|
+
/** Total occurrences across all values */
|
|
57
|
+
totalOccurrences: number;
|
|
58
|
+
/** Number of unique values found */
|
|
59
|
+
uniqueValues: number;
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Configuration for the learning process
|
|
63
|
+
*/
|
|
64
|
+
export interface PatternLearningConfig {
|
|
65
|
+
/** Minimum occurrences to consider a pattern established */
|
|
66
|
+
minOccurrences: number;
|
|
67
|
+
/** Minimum percentage to consider a value "dominant" (0-1) */
|
|
68
|
+
dominanceThreshold: number;
|
|
69
|
+
/** Minimum files that must contain the pattern */
|
|
70
|
+
minFiles: number;
|
|
71
|
+
/** Maximum files to analyze (for performance) */
|
|
72
|
+
maxFilesToAnalyze: number;
|
|
73
|
+
/** File patterns to include */
|
|
74
|
+
includePatterns: string[];
|
|
75
|
+
/** File patterns to exclude */
|
|
76
|
+
excludePatterns: string[];
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* Default learning configuration
|
|
80
|
+
*/
|
|
81
|
+
export declare const DEFAULT_PATTERN_LEARNING_CONFIG: PatternLearningConfig;
|
|
82
|
+
/**
|
|
83
|
+
* Stored learned patterns for a detector
|
|
84
|
+
*/
|
|
85
|
+
export interface StoredLearnedPatterns {
|
|
86
|
+
/** Detector ID */
|
|
87
|
+
detectorId: string;
|
|
88
|
+
/** Version of the learning algorithm */
|
|
89
|
+
version: string;
|
|
90
|
+
/** The learned conventions (serializable) */
|
|
91
|
+
conventions: Record<string, SerializedConvention>;
|
|
92
|
+
/** Learning metadata */
|
|
93
|
+
metadata: {
|
|
94
|
+
filesAnalyzed: number;
|
|
95
|
+
relevantFiles: number;
|
|
96
|
+
learnedAt: string;
|
|
97
|
+
hasEnoughData: boolean;
|
|
98
|
+
configUsed: PatternLearningConfig;
|
|
99
|
+
};
|
|
100
|
+
}
|
|
101
|
+
/**
|
|
102
|
+
* Serialized convention for JSON storage
|
|
103
|
+
*/
|
|
104
|
+
export interface SerializedConvention {
|
|
105
|
+
value: unknown;
|
|
106
|
+
occurrences: number;
|
|
107
|
+
files: string[];
|
|
108
|
+
firstSeenAt?: {
|
|
109
|
+
file: string;
|
|
110
|
+
line: number;
|
|
111
|
+
};
|
|
112
|
+
confidence: number;
|
|
113
|
+
}
|
|
114
|
+
/**
|
|
115
|
+
* Events emitted during learning
|
|
116
|
+
*/
|
|
117
|
+
export type LearningEventType = 'learning:started' | 'learning:file-analyzed' | 'learning:completed' | 'learning:failed' | 'learning:convention-found' | 'learning:no-data';
|
|
118
|
+
/**
|
|
119
|
+
* Learning event payload
|
|
120
|
+
*/
|
|
121
|
+
export interface LearningEvent {
|
|
122
|
+
type: LearningEventType;
|
|
123
|
+
detectorId: string;
|
|
124
|
+
timestamp: string;
|
|
125
|
+
data?: {
|
|
126
|
+
file?: string;
|
|
127
|
+
conventionKey?: string;
|
|
128
|
+
conventionValue?: unknown;
|
|
129
|
+
filesAnalyzed?: number;
|
|
130
|
+
error?: string;
|
|
131
|
+
};
|
|
132
|
+
}
|
|
133
|
+
/**
|
|
134
|
+
* Naming convention types
|
|
135
|
+
*/
|
|
136
|
+
export type NamingConvention = 'camelCase' | 'PascalCase' | 'snake_case' | 'kebab-case' | 'SCREAMING_SNAKE_CASE' | 'lowercase' | 'mixed';
|
|
137
|
+
/**
|
|
138
|
+
* Learned naming conventions
|
|
139
|
+
*/
|
|
140
|
+
export interface LearnedNamingConventions {
|
|
141
|
+
/** File naming convention */
|
|
142
|
+
fileNaming?: NamingConvention;
|
|
143
|
+
/** Function naming convention */
|
|
144
|
+
functionNaming?: NamingConvention;
|
|
145
|
+
/** Variable naming convention */
|
|
146
|
+
variableNaming?: NamingConvention;
|
|
147
|
+
/** Class naming convention */
|
|
148
|
+
classNaming?: NamingConvention;
|
|
149
|
+
/** Constant naming convention */
|
|
150
|
+
constantNaming?: NamingConvention;
|
|
151
|
+
/** Component naming convention */
|
|
152
|
+
componentNaming?: NamingConvention;
|
|
153
|
+
}
|
|
154
|
+
/**
|
|
155
|
+
* Learned string patterns (for things like error codes, route prefixes, etc.)
|
|
156
|
+
*/
|
|
157
|
+
export interface LearnedStringPatterns {
|
|
158
|
+
/** Common prefixes found */
|
|
159
|
+
prefixes: string[];
|
|
160
|
+
/** Common suffixes found */
|
|
161
|
+
suffixes: string[];
|
|
162
|
+
/** Regex pattern that matches the learned format */
|
|
163
|
+
pattern?: string;
|
|
164
|
+
/** Example values */
|
|
165
|
+
examples: string[];
|
|
166
|
+
}
|
|
167
|
+
/**
|
|
168
|
+
* Learned structural patterns
|
|
169
|
+
*/
|
|
170
|
+
export interface LearnedStructuralPatterns {
|
|
171
|
+
/** Directory structure patterns */
|
|
172
|
+
directories: string[];
|
|
173
|
+
/** Co-location patterns (what files are typically together) */
|
|
174
|
+
coLocatedFiles: string[][];
|
|
175
|
+
/** Import patterns */
|
|
176
|
+
importPatterns: string[];
|
|
177
|
+
}
|
|
178
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/learning/types.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Learned Patterns Type System
|
|
3
|
+
*
|
|
4
|
+
* Types for pattern learning - detectors learn from the user's codebase
|
|
5
|
+
* rather than enforcing hardcoded conventions.
|
|
6
|
+
*
|
|
7
|
+
* @requirements DRIFT-CORE - Detectors learn patterns from user's code, not enforce arbitrary rules
|
|
8
|
+
*/
|
|
9
|
+
/**
|
|
10
|
+
* Default learning configuration
|
|
11
|
+
*/
|
|
12
|
+
export const DEFAULT_PATTERN_LEARNING_CONFIG = {
|
|
13
|
+
minOccurrences: 3,
|
|
14
|
+
dominanceThreshold: 0.6, // 60% must use the same convention
|
|
15
|
+
minFiles: 2,
|
|
16
|
+
maxFilesToAnalyze: 1000,
|
|
17
|
+
includePatterns: ['**/*.ts', '**/*.tsx', '**/*.js', '**/*.jsx', '**/*.py'],
|
|
18
|
+
excludePatterns: [
|
|
19
|
+
'**/node_modules/**',
|
|
20
|
+
'**/dist/**',
|
|
21
|
+
'**/build/**',
|
|
22
|
+
'**/.git/**',
|
|
23
|
+
'**/*.test.*',
|
|
24
|
+
'**/*.spec.*',
|
|
25
|
+
'**/__tests__/**',
|
|
26
|
+
],
|
|
27
|
+
};
|
|
28
|
+
//# sourceMappingURL=types.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/learning/types.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAqGH;;GAEG;AACH,MAAM,CAAC,MAAM,+BAA+B,GAA0B;IACpE,cAAc,EAAE,CAAC;IACjB,kBAAkB,EAAE,GAAG,EAAE,mCAAmC;IAC5D,QAAQ,EAAE,CAAC;IACX,iBAAiB,EAAE,IAAI;IACvB,eAAe,EAAE,CAAC,SAAS,EAAE,UAAU,EAAE,SAAS,EAAE,UAAU,EAAE,SAAS,CAAC;IAC1E,eAAe,EAAE;QACf,oBAAoB;QACpB,YAAY;QACZ,aAAa;QACb,YAAY;QACZ,aAAa;QACb,aAAa;QACb,iBAAiB;KAClB;CACF,CAAC"}
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Contract Store - Contract persistence and querying
|
|
3
|
+
*
|
|
4
|
+
* Loads and saves contracts to .drift/contracts/ directory.
|
|
5
|
+
* Supports querying by status, method, endpoint, and mismatches.
|
|
6
|
+
* Handles contract state transitions (discovered → verified/mismatch/ignored).
|
|
7
|
+
*/
|
|
8
|
+
import { EventEmitter } from 'node:events';
|
|
9
|
+
import type { Contract, ContractStatus, ContractQueryOptions, ContractQueryResult, ContractStats, HttpMethod } from '../types/contracts.js';
|
|
10
|
+
export declare class ContractNotFoundError extends Error {
|
|
11
|
+
readonly contractId: string;
|
|
12
|
+
constructor(contractId: string);
|
|
13
|
+
}
|
|
14
|
+
export declare class InvalidContractTransitionError extends Error {
|
|
15
|
+
readonly contractId: string;
|
|
16
|
+
readonly fromStatus: ContractStatus;
|
|
17
|
+
readonly toStatus: ContractStatus;
|
|
18
|
+
constructor(contractId: string, fromStatus: ContractStatus, toStatus: ContractStatus);
|
|
19
|
+
}
|
|
20
|
+
export declare class ContractStoreError extends Error {
|
|
21
|
+
readonly errorCause: Error | undefined;
|
|
22
|
+
constructor(message: string, errorCause?: Error);
|
|
23
|
+
}
|
|
24
|
+
export interface ContractStoreConfig {
|
|
25
|
+
rootDir: string;
|
|
26
|
+
autoSave: boolean;
|
|
27
|
+
autoSaveDebounce: number;
|
|
28
|
+
createBackup: boolean;
|
|
29
|
+
maxBackups: number;
|
|
30
|
+
}
|
|
31
|
+
export declare const DEFAULT_CONTRACT_STORE_CONFIG: ContractStoreConfig;
|
|
32
|
+
export type ContractStoreEventType = 'contract:created' | 'contract:updated' | 'contract:deleted' | 'contract:verified' | 'contract:mismatch' | 'contract:ignored' | 'file:loaded' | 'file:saved' | 'error';
|
|
33
|
+
export interface ContractStoreEvent {
|
|
34
|
+
type: ContractStoreEventType;
|
|
35
|
+
contractId?: string;
|
|
36
|
+
data?: Record<string, unknown>;
|
|
37
|
+
timestamp: string;
|
|
38
|
+
}
|
|
39
|
+
export declare class ContractStore extends EventEmitter {
|
|
40
|
+
private readonly config;
|
|
41
|
+
private readonly contractsDir;
|
|
42
|
+
private contracts;
|
|
43
|
+
private dirty;
|
|
44
|
+
private saveTimeout;
|
|
45
|
+
constructor(config?: Partial<ContractStoreConfig>);
|
|
46
|
+
initialize(): Promise<void>;
|
|
47
|
+
private ensureDirectoryStructure;
|
|
48
|
+
loadAll(): Promise<void>;
|
|
49
|
+
private loadByStatus;
|
|
50
|
+
saveAll(): Promise<void>;
|
|
51
|
+
private groupContractsByStatus;
|
|
52
|
+
private saveStatusFile;
|
|
53
|
+
private createBackup;
|
|
54
|
+
private cleanupBackups;
|
|
55
|
+
private scheduleAutoSave;
|
|
56
|
+
get(id: string): Contract | undefined;
|
|
57
|
+
getOrThrow(id: string): Contract;
|
|
58
|
+
has(id: string): boolean;
|
|
59
|
+
add(contract: Contract): void;
|
|
60
|
+
update(id: string, updates: Partial<Omit<Contract, 'id'>>): Contract;
|
|
61
|
+
delete(id: string): boolean;
|
|
62
|
+
verify(id: string, verifiedBy?: string): Contract;
|
|
63
|
+
markMismatch(id: string): Contract;
|
|
64
|
+
ignore(id: string): Contract;
|
|
65
|
+
private transitionStatus;
|
|
66
|
+
query(options?: ContractQueryOptions): ContractQueryResult;
|
|
67
|
+
private applyFilters;
|
|
68
|
+
private applySorting;
|
|
69
|
+
getAll(): Contract[];
|
|
70
|
+
getByStatus(status: ContractStatus): Contract[];
|
|
71
|
+
getByMethod(method: HttpMethod): Contract[];
|
|
72
|
+
getWithMismatches(): Contract[];
|
|
73
|
+
getVerified(): Contract[];
|
|
74
|
+
getDiscovered(): Contract[];
|
|
75
|
+
getMismatched(): Contract[];
|
|
76
|
+
getStats(): ContractStats;
|
|
77
|
+
private emitEvent;
|
|
78
|
+
}
|
|
79
|
+
//# sourceMappingURL=contract-store.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"contract-store.d.ts","sourceRoot":"","sources":["../../src/store/contract-store.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAKH,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAE3C,OAAO,KAAK,EACV,QAAQ,EAGR,cAAc,EAEd,oBAAoB,EACpB,mBAAmB,EAEnB,aAAa,EACb,UAAU,EACX,MAAM,uBAAuB,CAAC;AA6B/B,qBAAa,qBAAsB,SAAQ,KAAK;aAClB,UAAU,EAAE,MAAM;gBAAlB,UAAU,EAAE,MAAM;CAI/C;AAED,qBAAa,8BAA+B,SAAQ,KAAK;aAErC,UAAU,EAAE,MAAM;aAClB,UAAU,EAAE,cAAc;aAC1B,QAAQ,EAAE,cAAc;gBAFxB,UAAU,EAAE,MAAM,EAClB,UAAU,EAAE,cAAc,EAC1B,QAAQ,EAAE,cAAc;CAK3C;AAED,qBAAa,kBAAmB,SAAQ,KAAK;IAC3C,SAAgB,UAAU,EAAE,KAAK,GAAG,SAAS,CAAC;gBAElC,OAAO,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,KAAK;CAKhD;AAqCD,MAAM,WAAW,mBAAmB;IAClC,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,OAAO,CAAC;IAClB,gBAAgB,EAAE,MAAM,CAAC;IACzB,YAAY,EAAE,OAAO,CAAC;IACtB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,eAAO,MAAM,6BAA6B,EAAE,mBAM3C,CAAC;AAMF,MAAM,MAAM,sBAAsB,GAC9B,kBAAkB,GAClB,kBAAkB,GAClB,kBAAkB,GAClB,mBAAmB,GACnB,mBAAmB,GACnB,kBAAkB,GAClB,aAAa,GACb,YAAY,GACZ,OAAO,CAAC;AAEZ,MAAM,WAAW,kBAAkB;IACjC,IAAI,EAAE,sBAAsB,CAAC;IAC7B,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC/B,SAAS,EAAE,MAAM,CAAC;CACnB;AAMD,qBAAa,aAAc,SAAQ,YAAY;IAC7C,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAsB;IAC7C,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAS;IACtC,OAAO,CAAC,SAAS,CAAoC;IACrD,OAAO,CAAC,KAAK,CAAkB;IAC/B,OAAO,CAAC,WAAW,CAA+B;gBAEtC,MAAM,GAAE,OAAO,CAAC,mBAAmB,CAAM;IAU/C,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;YAKnB,wBAAwB;IAUhC,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;YAUhB,YAAY;IA4BpB,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;IAW9B,OAAO,CAAC,sBAAsB;YAchB,cAAc;YA6Bd,YAAY;YAWZ,cAAc;IAgB5B,OAAO,CAAC,gBAAgB;IAkBxB,GAAG,CAAC,EAAE,EAAE,MAAM,GAAG,QAAQ,GAAG,SAAS;IAIrC,UAAU,CAAC,EAAE,EAAE,MAAM,GAAG,QAAQ;IAQhC,GAAG,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO;IAIxB,GAAG,CAAC,QAAQ,EAAE,QAAQ,GAAG,IAAI;IAW7B,MAAM,CAAC,EAAE,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,CAAC,IAAI,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC,GAAG,QAAQ;IAiBpE,MAAM,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO;IAgB3B,MAAM,CAAC,EAAE,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,MAAM,GAAG,QAAQ;IAIjD,YAAY,CAAC,EAAE,EAAE,MAAM,GAAG,QAAQ;IAIlC,MAAM,CAAC,EAAE,EAAE,MAAM,GAAG,QAAQ;IAI5B,OAAO,CAAC,gBAAgB;IA8CxB,KAAK,CAAC,OAAO,GAAE,oBAAyB,GAAG,mBAAmB;IA6B9D,OAAO,CAAC,YAAY;IA6CpB,OAAO,CAAC,YAAY;IAoCpB,MAAM,IAAI,QAAQ,EAAE;IAIpB,WAAW,CAAC,MAAM,EAAE,cAAc,GAAG,QAAQ,EAAE;IAI/C,WAAW,CAAC,MAAM,EAAE,UAAU,GAAG,QAAQ,EAAE;IAI3C,iBAAiB,IAAI,QAAQ,EAAE;IAI/B,WAAW,IAAI,QAAQ,EAAE;IAIzB,aAAa,IAAI,QAAQ,EAAE;IAI3B,aAAa,IAAI,QAAQ,EAAE;IAQ3B,QAAQ,IAAI,aAAa;IAoDzB,OAAO,CAAC,SAAS;CAgBlB"}
|