@stackbilt/drift 0.1.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.
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=drift.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"drift.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/drift.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,108 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const vitest_1 = require("vitest");
4
+ const index_1 = require("../index");
5
+ (0, vitest_1.describe)('extractRules', () => {
6
+ (0, vitest_1.it)('parses regex literals', () => {
7
+ const rules = (0, index_1.extractRules)('Avoid /console\\.log/g in production');
8
+ (0, vitest_1.expect)(rules).toHaveLength(1);
9
+ (0, vitest_1.expect)(rules[0].test('console.log("test")')).toBe(true);
10
+ });
11
+ (0, vitest_1.it)('parses regex with flags', () => {
12
+ const rules = (0, index_1.extractRules)('Do not use /var\\s+/gi');
13
+ (0, vitest_1.expect)(rules).toHaveLength(1);
14
+ (0, vitest_1.expect)(rules[0].flags).toContain('g');
15
+ (0, vitest_1.expect)(rules[0].flags).toContain('i');
16
+ });
17
+ (0, vitest_1.it)('parses backtick keywords', () => {
18
+ const rules = (0, index_1.extractRules)('Do not use `eval` or `Function`');
19
+ (0, vitest_1.expect)(rules).toHaveLength(2);
20
+ (0, vitest_1.expect)(rules[0].test('eval("code")')).toBe(true);
21
+ (0, vitest_1.expect)(rules[1].test('new Function("x")')).toBe(true);
22
+ });
23
+ (0, vitest_1.it)('escapes special regex characters in keywords', () => {
24
+ const rules = (0, index_1.extractRules)('Avoid `foo.bar()`');
25
+ (0, vitest_1.expect)(rules).toHaveLength(1);
26
+ (0, vitest_1.expect)(rules[0].test('foo.bar()')).toBe(true);
27
+ (0, vitest_1.expect)(rules[0].test('fooXbar()')).toBe(false);
28
+ });
29
+ (0, vitest_1.it)('returns empty array for text with no patterns', () => {
30
+ const rules = (0, index_1.extractRules)('This is plain text advice');
31
+ (0, vitest_1.expect)(rules).toEqual([]);
32
+ });
33
+ (0, vitest_1.it)('handles both regex and backtick patterns', () => {
34
+ const rules = (0, index_1.extractRules)('Avoid /TODO/i and `FIXME`');
35
+ (0, vitest_1.expect)(rules).toHaveLength(2);
36
+ });
37
+ });
38
+ (0, vitest_1.describe)('scanForDrift', () => {
39
+ const makePattern = (name, antiPatterns) => ({
40
+ id: '1',
41
+ name,
42
+ category: 'SECURITY',
43
+ blessedSolution: 'Use approved method',
44
+ rationale: null,
45
+ antiPatterns,
46
+ documentationUrl: null,
47
+ relatedLedgerId: null,
48
+ status: 'ACTIVE',
49
+ createdAt: '2025-01-01',
50
+ projectId: null,
51
+ });
52
+ (0, vitest_1.it)('detects violations matching anti-patterns', () => {
53
+ const pattern = makePattern('no-eval', 'Do not use `eval`');
54
+ const files = { 'app.js': 'const result = eval("1+1");' };
55
+ const report = (0, index_1.scanForDrift)(files, [pattern]);
56
+ (0, vitest_1.expect)(report.violations).toHaveLength(1);
57
+ (0, vitest_1.expect)(report.violations[0].file).toBe('app.js');
58
+ (0, vitest_1.expect)(report.violations[0].patternName).toBe('no-eval');
59
+ });
60
+ (0, vitest_1.it)('reports correct line numbers', () => {
61
+ const pattern = makePattern('no-eval', 'Avoid `eval`');
62
+ const files = { 'app.js': 'line1\nline2\neval("bad")\nline4' };
63
+ const report = (0, index_1.scanForDrift)(files, [pattern]);
64
+ (0, vitest_1.expect)(report.violations[0].line).toBe(3);
65
+ });
66
+ (0, vitest_1.it)('returns clean report when no violations found', () => {
67
+ const pattern = makePattern('no-eval', 'Avoid `eval`');
68
+ const files = { 'app.js': 'const x = 1 + 1;' };
69
+ const report = (0, index_1.scanForDrift)(files, [pattern]);
70
+ (0, vitest_1.expect)(report.violations).toEqual([]);
71
+ (0, vitest_1.expect)(report.score).toBe(1.0);
72
+ });
73
+ (0, vitest_1.it)('skips files larger than 500K', () => {
74
+ const pattern = makePattern('no-eval', 'Avoid `eval`');
75
+ const largeContent = 'eval("bad")\n'.repeat(50000); // >500K
76
+ const files = { 'big.js': largeContent };
77
+ const report = (0, index_1.scanForDrift)(files, [pattern]);
78
+ (0, vitest_1.expect)(report.violations).toEqual([]);
79
+ });
80
+ (0, vitest_1.it)('calculates score as 1 - (violations * 0.1)', () => {
81
+ const pattern = makePattern('no-eval', 'Avoid `eval`');
82
+ const files = { 'a.js': 'eval(1)\neval(2)\neval(3)' };
83
+ const report = (0, index_1.scanForDrift)(files, [pattern]);
84
+ (0, vitest_1.expect)(report.violations).toHaveLength(3);
85
+ (0, vitest_1.expect)(report.score).toBeCloseTo(0.7);
86
+ });
87
+ (0, vitest_1.it)('clamps score at 0', () => {
88
+ const pattern = makePattern('no-eval', 'Avoid `eval`');
89
+ const lines = Array.from({ length: 15 }, () => 'eval("x")').join('\n');
90
+ const files = { 'a.js': lines };
91
+ const report = (0, index_1.scanForDrift)(files, [pattern]);
92
+ (0, vitest_1.expect)(report.score).toBe(0);
93
+ });
94
+ (0, vitest_1.it)('skips patterns with null antiPatterns', () => {
95
+ const pattern = makePattern('info-only', null);
96
+ const files = { 'app.js': 'eval("anything")' };
97
+ const report = (0, index_1.scanForDrift)(files, [pattern]);
98
+ (0, vitest_1.expect)(report.violations).toEqual([]);
99
+ });
100
+ (0, vitest_1.it)('tracks scannedFiles and scannedPatterns', () => {
101
+ const pattern = makePattern('test', 'Avoid `eval`');
102
+ const files = { 'a.js': 'ok', 'b.js': 'fine' };
103
+ const report = (0, index_1.scanForDrift)(files, [pattern]);
104
+ (0, vitest_1.expect)(report.scannedFiles).toBe(2);
105
+ (0, vitest_1.expect)(report.scannedPatterns).toBe(1);
106
+ });
107
+ });
108
+ //# sourceMappingURL=drift.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"drift.test.js","sourceRoot":"","sources":["../../src/__tests__/drift.test.ts"],"names":[],"mappings":";;AAAA,mCAA8C;AAC9C,oCAAsD;AAGtD,IAAA,iBAAQ,EAAC,cAAc,EAAE,GAAG,EAAE;IAC5B,IAAA,WAAE,EAAC,uBAAuB,EAAE,GAAG,EAAE;QAC/B,MAAM,KAAK,GAAG,IAAA,oBAAY,EAAC,sCAAsC,CAAC,CAAC;QACnE,IAAA,eAAM,EAAC,KAAK,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;QAC9B,IAAA,eAAM,EAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,qBAAqB,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAC1D,CAAC,CAAC,CAAC;IAEH,IAAA,WAAE,EAAC,yBAAyB,EAAE,GAAG,EAAE;QACjC,MAAM,KAAK,GAAG,IAAA,oBAAY,EAAC,wBAAwB,CAAC,CAAC;QACrD,IAAA,eAAM,EAAC,KAAK,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;QAC9B,IAAA,eAAM,EAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC;QACtC,IAAA,eAAM,EAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC;IACxC,CAAC,CAAC,CAAC;IAEH,IAAA,WAAE,EAAC,0BAA0B,EAAE,GAAG,EAAE;QAClC,MAAM,KAAK,GAAG,IAAA,oBAAY,EAAC,iCAAiC,CAAC,CAAC;QAC9D,IAAA,eAAM,EAAC,KAAK,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;QAC9B,IAAA,eAAM,EAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACjD,IAAA,eAAM,EAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,mBAAmB,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACxD,CAAC,CAAC,CAAC;IAEH,IAAA,WAAE,EAAC,8CAA8C,EAAE,GAAG,EAAE;QACtD,MAAM,KAAK,GAAG,IAAA,oBAAY,EAAC,mBAAmB,CAAC,CAAC;QAChD,IAAA,eAAM,EAAC,KAAK,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;QAC9B,IAAA,eAAM,EAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC9C,IAAA,eAAM,EAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IACjD,CAAC,CAAC,CAAC;IAEH,IAAA,WAAE,EAAC,+CAA+C,EAAE,GAAG,EAAE;QACvD,MAAM,KAAK,GAAG,IAAA,oBAAY,EAAC,2BAA2B,CAAC,CAAC;QACxD,IAAA,eAAM,EAAC,KAAK,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;IAC5B,CAAC,CAAC,CAAC;IAEH,IAAA,WAAE,EAAC,0CAA0C,EAAE,GAAG,EAAE;QAClD,MAAM,KAAK,GAAG,IAAA,oBAAY,EAAC,2BAA2B,CAAC,CAAC;QACxD,IAAA,eAAM,EAAC,KAAK,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;IAChC,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,IAAA,iBAAQ,EAAC,cAAc,EAAE,GAAG,EAAE;IAC5B,MAAM,WAAW,GAAG,CAAC,IAAY,EAAE,YAA2B,EAAW,EAAE,CAAC,CAAC;QAC3E,EAAE,EAAE,GAAG;QACP,IAAI;QACJ,QAAQ,EAAE,UAAU;QACpB,eAAe,EAAE,qBAAqB;QACtC,SAAS,EAAE,IAAI;QACf,YAAY;QACZ,gBAAgB,EAAE,IAAI;QACtB,eAAe,EAAE,IAAI;QACrB,MAAM,EAAE,QAAQ;QAChB,SAAS,EAAE,YAAY;QACvB,SAAS,EAAE,IAAI;KAChB,CAAC,CAAC;IAEH,IAAA,WAAE,EAAC,2CAA2C,EAAE,GAAG,EAAE;QACnD,MAAM,OAAO,GAAG,WAAW,CAAC,SAAS,EAAE,mBAAmB,CAAC,CAAC;QAC5D,MAAM,KAAK,GAAG,EAAE,QAAQ,EAAE,6BAA6B,EAAE,CAAC;QAC1D,MAAM,MAAM,GAAG,IAAA,oBAAY,EAAC,KAAK,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC;QAC9C,IAAA,eAAM,EAAC,MAAM,CAAC,UAAU,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;QAC1C,IAAA,eAAM,EAAC,MAAM,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QACjD,IAAA,eAAM,EAAC,MAAM,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;IAC3D,CAAC,CAAC,CAAC;IAEH,IAAA,WAAE,EAAC,8BAA8B,EAAE,GAAG,EAAE;QACtC,MAAM,OAAO,GAAG,WAAW,CAAC,SAAS,EAAE,cAAc,CAAC,CAAC;QACvD,MAAM,KAAK,GAAG,EAAE,QAAQ,EAAE,kCAAkC,EAAE,CAAC;QAC/D,MAAM,MAAM,GAAG,IAAA,oBAAY,EAAC,KAAK,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC;QAC9C,IAAA,eAAM,EAAC,MAAM,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAC5C,CAAC,CAAC,CAAC;IAEH,IAAA,WAAE,EAAC,+CAA+C,EAAE,GAAG,EAAE;QACvD,MAAM,OAAO,GAAG,WAAW,CAAC,SAAS,EAAE,cAAc,CAAC,CAAC;QACvD,MAAM,KAAK,GAAG,EAAE,QAAQ,EAAE,kBAAkB,EAAE,CAAC;QAC/C,MAAM,MAAM,GAAG,IAAA,oBAAY,EAAC,KAAK,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC;QAC9C,IAAA,eAAM,EAAC,MAAM,CAAC,UAAU,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;QACtC,IAAA,eAAM,EAAC,MAAM,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IACjC,CAAC,CAAC,CAAC;IAEH,IAAA,WAAE,EAAC,8BAA8B,EAAE,GAAG,EAAE;QACtC,MAAM,OAAO,GAAG,WAAW,CAAC,SAAS,EAAE,cAAc,CAAC,CAAC;QACvD,MAAM,YAAY,GAAG,eAAe,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,QAAQ;QAC5D,MAAM,KAAK,GAAG,EAAE,QAAQ,EAAE,YAAY,EAAE,CAAC;QACzC,MAAM,MAAM,GAAG,IAAA,oBAAY,EAAC,KAAK,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC;QAC9C,IAAA,eAAM,EAAC,MAAM,CAAC,UAAU,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;IACxC,CAAC,CAAC,CAAC;IAEH,IAAA,WAAE,EAAC,4CAA4C,EAAE,GAAG,EAAE;QACpD,MAAM,OAAO,GAAG,WAAW,CAAC,SAAS,EAAE,cAAc,CAAC,CAAC;QACvD,MAAM,KAAK,GAAG,EAAE,MAAM,EAAE,2BAA2B,EAAE,CAAC;QACtD,MAAM,MAAM,GAAG,IAAA,oBAAY,EAAC,KAAK,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC;QAC9C,IAAA,eAAM,EAAC,MAAM,CAAC,UAAU,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;QAC1C,IAAA,eAAM,EAAC,MAAM,CAAC,KAAK,CAAC,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC;IACxC,CAAC,CAAC,CAAC;IAEH,IAAA,WAAE,EAAC,mBAAmB,EAAE,GAAG,EAAE;QAC3B,MAAM,OAAO,GAAG,WAAW,CAAC,SAAS,EAAE,cAAc,CAAC,CAAC;QACvD,MAAM,KAAK,GAAG,KAAK,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,EAAE,EAAE,EAAE,GAAG,EAAE,CAAC,WAAW,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACvE,MAAM,KAAK,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC;QAChC,MAAM,MAAM,GAAG,IAAA,oBAAY,EAAC,KAAK,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC;QAC9C,IAAA,eAAM,EAAC,MAAM,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAC/B,CAAC,CAAC,CAAC;IAEH,IAAA,WAAE,EAAC,uCAAuC,EAAE,GAAG,EAAE;QAC/C,MAAM,OAAO,GAAG,WAAW,CAAC,WAAW,EAAE,IAAI,CAAC,CAAC;QAC/C,MAAM,KAAK,GAAG,EAAE,QAAQ,EAAE,kBAAkB,EAAE,CAAC;QAC/C,MAAM,MAAM,GAAG,IAAA,oBAAY,EAAC,KAAK,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC;QAC9C,IAAA,eAAM,EAAC,MAAM,CAAC,UAAU,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;IACxC,CAAC,CAAC,CAAC;IAEH,IAAA,WAAE,EAAC,yCAAyC,EAAE,GAAG,EAAE;QACjD,MAAM,OAAO,GAAG,WAAW,CAAC,MAAM,EAAE,cAAc,CAAC,CAAC;QACpD,MAAM,KAAK,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC;QAC/C,MAAM,MAAM,GAAG,IAAA,oBAAY,EAAC,KAAK,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC;QAC9C,IAAA,eAAM,EAAC,MAAM,CAAC,YAAY,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QACpC,IAAA,eAAM,EAAC,MAAM,CAAC,eAAe,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IACzC,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
@@ -0,0 +1,29 @@
1
+ /**
2
+ * Drift Scanner
3
+ *
4
+ * Detects state drift where actual codebase diverges from governance patterns.
5
+ * Scans file content against anti-pattern rules defined in blessed patterns.
6
+ *
7
+ * Extracted from Charter Cloud (ADR-001).
8
+ *
9
+ * Note: In the Cloud version, patterns are fetched from D1. In the Kit version,
10
+ * patterns are provided directly (loaded from .charter/patterns/ by the CLI).
11
+ */
12
+ import type { Pattern, DriftReport } from '@stackbilt/types';
13
+ /**
14
+ * Scan files for governance violations (drift) against provided patterns.
15
+ *
16
+ * @param files - Map of filename to file content
17
+ * @param patterns - Active blessed-stack patterns to check against
18
+ * @returns Drift report with score and violations
19
+ */
20
+ export declare function scanForDrift(files: Record<string, string>, patterns: Pattern[]): DriftReport;
21
+ /**
22
+ * Extract testable regexes from anti-pattern text.
23
+ *
24
+ * Supports:
25
+ * - Regex literals: /pattern/flags
26
+ * - Code tokens: `keyword`
27
+ */
28
+ export declare function extractRules(antiPatternText: string): RegExp[];
29
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAkB,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAM7E;;;;;;GAMG;AACH,wBAAgB,YAAY,CAC1B,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,EAC7B,QAAQ,EAAE,OAAO,EAAE,GAClB,WAAW,CA0Cb;AAMD;;;;;;GAMG;AACH,wBAAgB,YAAY,CAAC,eAAe,EAAE,MAAM,GAAG,MAAM,EAAE,CA4B9D"}
package/dist/index.js ADDED
@@ -0,0 +1,101 @@
1
+ "use strict";
2
+ /**
3
+ * Drift Scanner
4
+ *
5
+ * Detects state drift where actual codebase diverges from governance patterns.
6
+ * Scans file content against anti-pattern rules defined in blessed patterns.
7
+ *
8
+ * Extracted from Charter Cloud (ADR-001).
9
+ *
10
+ * Note: In the Cloud version, patterns are fetched from D1. In the Kit version,
11
+ * patterns are provided directly (loaded from .charter/patterns/ by the CLI).
12
+ */
13
+ Object.defineProperty(exports, "__esModule", { value: true });
14
+ exports.scanForDrift = scanForDrift;
15
+ exports.extractRules = extractRules;
16
+ // ============================================================================
17
+ // Public API
18
+ // ============================================================================
19
+ /**
20
+ * Scan files for governance violations (drift) against provided patterns.
21
+ *
22
+ * @param files - Map of filename to file content
23
+ * @param patterns - Active blessed-stack patterns to check against
24
+ * @returns Drift report with score and violations
25
+ */
26
+ function scanForDrift(files, patterns) {
27
+ const violations = [];
28
+ let totalFiles = 0;
29
+ for (const [filename, content] of Object.entries(files)) {
30
+ totalFiles++;
31
+ // Skip binary or large files
32
+ if (content.length > 500000)
33
+ continue;
34
+ for (const pattern of patterns) {
35
+ if (pattern.antiPatterns) {
36
+ const rules = extractRules(pattern.antiPatterns);
37
+ for (const rule of rules) {
38
+ const lines = content.split('\n');
39
+ lines.forEach((line, index) => {
40
+ if (rule.test(line)) {
41
+ violations.push({
42
+ file: filename,
43
+ line: index + 1,
44
+ snippet: line.trim().substring(0, 100),
45
+ patternName: pattern.name,
46
+ antiPattern: pattern.antiPatterns,
47
+ severity: 'MAJOR'
48
+ });
49
+ }
50
+ });
51
+ }
52
+ }
53
+ }
54
+ }
55
+ const score = Math.max(0, 1.0 - (violations.length * 0.1));
56
+ return {
57
+ score,
58
+ violations,
59
+ scannedFiles: totalFiles,
60
+ scannedPatterns: patterns.length,
61
+ timestamp: new Date().toISOString()
62
+ };
63
+ }
64
+ // ============================================================================
65
+ // Rule Extraction
66
+ // ============================================================================
67
+ /**
68
+ * Extract testable regexes from anti-pattern text.
69
+ *
70
+ * Supports:
71
+ * - Regex literals: /pattern/flags
72
+ * - Code tokens: `keyword`
73
+ */
74
+ function extractRules(antiPatternText) {
75
+ const rules = [];
76
+ // Look for regex-like strings: /regex/flags
77
+ const regexMatches = [...antiPatternText.matchAll(/\/([^\/]+)\/([gimsuy]*)/g)];
78
+ if (regexMatches.length > 0) {
79
+ regexMatches.forEach(match => {
80
+ const pattern = match[1];
81
+ const flags = match[2] || '';
82
+ try {
83
+ rules.push(new RegExp(pattern, flags));
84
+ }
85
+ catch {
86
+ // Ignore invalid regex
87
+ }
88
+ });
89
+ }
90
+ // Look for code-like tokens: `code`
91
+ const codeMatches = antiPatternText.match(/`([^`]+)`/g);
92
+ if (codeMatches) {
93
+ codeMatches.forEach(m => {
94
+ const keyword = m.slice(1, -1);
95
+ const escaped = keyword.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
96
+ rules.push(new RegExp(escaped));
97
+ });
98
+ }
99
+ return rules;
100
+ }
101
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,34 @@
1
+ {
2
+ "name": "@stackbilt/drift",
3
+ "version": "0.1.1",
4
+ "description": "Drift scanner — detects codebase divergence from governance patterns",
5
+ "main": "./dist/index.js",
6
+ "types": "./dist/index.d.ts",
7
+ "exports": {
8
+ ".": {
9
+ "types": "./dist/index.d.ts",
10
+ "default": "./dist/index.js"
11
+ }
12
+ },
13
+ "files": [
14
+ "dist",
15
+ "README.md",
16
+ "LICENSE"
17
+ ],
18
+ "engines": {
19
+ "node": ">=18.0.0"
20
+ },
21
+ "repository": {
22
+ "type": "git",
23
+ "url": "https://github.com/Stackbilt-dev/charter.git",
24
+ "directory": "packages/drift"
25
+ },
26
+ "bugs": {
27
+ "url": "https://github.com/Stackbilt-dev/charter/issues"
28
+ },
29
+ "homepage": "https://github.com/Stackbilt-dev/charter#readme",
30
+ "dependencies": {
31
+ "@stackbilt/types": "workspace:*"
32
+ },
33
+ "license": "Apache-2.0"
34
+ }