@runhalo/engine 0.3.1 → 0.5.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/dist/ast-engine.d.ts +60 -0
- package/dist/ast-engine.js +653 -0
- package/dist/ast-engine.js.map +1 -0
- package/dist/context-analyzer.d.ts +209 -0
- package/dist/context-analyzer.js +401 -0
- package/dist/context-analyzer.js.map +1 -0
- package/dist/data-flow-tracer.d.ts +106 -0
- package/dist/data-flow-tracer.js +506 -0
- package/dist/data-flow-tracer.js.map +1 -0
- package/dist/frameworks/django.d.ts +11 -0
- package/dist/frameworks/django.js +57 -0
- package/dist/frameworks/django.js.map +1 -0
- package/dist/frameworks/index.d.ts +59 -0
- package/dist/frameworks/index.js +93 -0
- package/dist/frameworks/index.js.map +1 -0
- package/dist/frameworks/nextjs.d.ts +11 -0
- package/dist/frameworks/nextjs.js +59 -0
- package/dist/frameworks/nextjs.js.map +1 -0
- package/dist/frameworks/rails.d.ts +11 -0
- package/dist/frameworks/rails.js +58 -0
- package/dist/frameworks/rails.js.map +1 -0
- package/dist/frameworks/types.d.ts +29 -0
- package/dist/frameworks/types.js +11 -0
- package/dist/frameworks/types.js.map +1 -0
- package/dist/index.d.ts +74 -0
- package/dist/index.js +235 -28
- package/dist/index.js.map +1 -1
- package/dist/scope-analyzer.d.ts +91 -0
- package/dist/scope-analyzer.js +300 -0
- package/dist/scope-analyzer.js.map +1 -0
- package/package.json +6 -2
- package/rules/rules.json +2632 -0
- package/rules/validation-report.json +58 -0
|
@@ -0,0 +1,300 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Halo Scope Analyzer
|
|
4
|
+
* Determines the context of code being scanned to reduce false positives.
|
|
5
|
+
*
|
|
6
|
+
* Analyzes WHERE code lives (test file? admin route? type definition?)
|
|
7
|
+
* so that rule violations can be weighted or suppressed based on context.
|
|
8
|
+
*/
|
|
9
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
10
|
+
exports.ScopeAnalyzer = void 0;
|
|
11
|
+
// ---------------------------------------------------------------------------
|
|
12
|
+
// File path patterns
|
|
13
|
+
// ---------------------------------------------------------------------------
|
|
14
|
+
const TEST_FILE_PATTERNS = [
|
|
15
|
+
/_test\.go$/i,
|
|
16
|
+
/\.spec\.[tj]sx?$/i,
|
|
17
|
+
/\.test\.[tj]sx?$/i,
|
|
18
|
+
/(^|[/\\])__tests__[/\\]/i,
|
|
19
|
+
/(^|[/\\])test[/\\]/i,
|
|
20
|
+
/(^|[/\\])tests[/\\]/i,
|
|
21
|
+
/conftest\.py$/i,
|
|
22
|
+
/(^|[/\\])Test[A-Z][^/\\]*\.java$/,
|
|
23
|
+
];
|
|
24
|
+
const ADMIN_PATH_PATTERNS = [
|
|
25
|
+
/[/\\]admin[/\\]/i,
|
|
26
|
+
/[/\\]admin\.[a-z]+$/i,
|
|
27
|
+
/[/\\]dashboard[/\\]/i,
|
|
28
|
+
];
|
|
29
|
+
const ADMIN_CONTENT_PATTERNS = [
|
|
30
|
+
/\bAdminPanel\b/,
|
|
31
|
+
/\bAdminDashboard\b/,
|
|
32
|
+
/\bAdminLayout\b/,
|
|
33
|
+
/\bAdminRoute\b/,
|
|
34
|
+
/\bAdminPage\b/,
|
|
35
|
+
];
|
|
36
|
+
const USER_FACING_PATTERNS = [
|
|
37
|
+
/[/\\]pages[/\\]/i,
|
|
38
|
+
/[/\\]components[/\\]/i,
|
|
39
|
+
/[/\\]views[/\\]/i,
|
|
40
|
+
/[/\\]screens[/\\]/i,
|
|
41
|
+
/[/\\]app[/\\]/i,
|
|
42
|
+
/[/\\]src[/\\]components[/\\]/i,
|
|
43
|
+
];
|
|
44
|
+
const TYPE_DEF_PATH_PATTERNS = [
|
|
45
|
+
/\.d\.tsx?$/i,
|
|
46
|
+
];
|
|
47
|
+
const CONFIG_FILE_PATTERNS = [
|
|
48
|
+
/\.config\.[tj]sx?$/i,
|
|
49
|
+
/\.config\.[cm]?js$/i,
|
|
50
|
+
/(^|[/\\])config[/\\]/i,
|
|
51
|
+
/(^|[/\\])settings\.py$/i,
|
|
52
|
+
/(^|[/\\])\.env(\.|$)/i,
|
|
53
|
+
/\.config\./i,
|
|
54
|
+
];
|
|
55
|
+
// ---------------------------------------------------------------------------
|
|
56
|
+
// AST node types used for line context analysis
|
|
57
|
+
// ---------------------------------------------------------------------------
|
|
58
|
+
const INTERFACE_NODE_TYPES = new Set([
|
|
59
|
+
'interface_declaration',
|
|
60
|
+
]);
|
|
61
|
+
const FUNCTION_NODE_TYPES = new Set([
|
|
62
|
+
'function_declaration',
|
|
63
|
+
'arrow_function',
|
|
64
|
+
'function',
|
|
65
|
+
'method_definition',
|
|
66
|
+
'function_expression',
|
|
67
|
+
]);
|
|
68
|
+
const CLASS_NODE_TYPES = new Set([
|
|
69
|
+
'class_declaration',
|
|
70
|
+
'class',
|
|
71
|
+
]);
|
|
72
|
+
const METHOD_NODE_TYPES = new Set([
|
|
73
|
+
'method_definition',
|
|
74
|
+
]);
|
|
75
|
+
const JSX_NODE_TYPES = new Set([
|
|
76
|
+
'jsx_element',
|
|
77
|
+
'jsx_self_closing_element',
|
|
78
|
+
]);
|
|
79
|
+
// ---------------------------------------------------------------------------
|
|
80
|
+
// ScopeAnalyzer
|
|
81
|
+
// ---------------------------------------------------------------------------
|
|
82
|
+
/**
|
|
83
|
+
* Analyzes the scope/context of source files and individual lines
|
|
84
|
+
* to help the engine make smarter decisions about rule applicability.
|
|
85
|
+
*/
|
|
86
|
+
class ScopeAnalyzer {
|
|
87
|
+
/**
|
|
88
|
+
* Analyze file-level scope from path heuristics and optionally content/AST.
|
|
89
|
+
*
|
|
90
|
+
* @param filePath - Relative or absolute path to the source file
|
|
91
|
+
* @param content - Full text content of the file
|
|
92
|
+
* @param tree - Optional tree-sitter AST (used for deeper analysis)
|
|
93
|
+
* @returns ScopeContext describing the file's role
|
|
94
|
+
*/
|
|
95
|
+
analyzeFile(filePath, content, tree) {
|
|
96
|
+
const normalized = filePath.replace(/\\/g, '/');
|
|
97
|
+
return {
|
|
98
|
+
isTestFile: this.detectTestFile(normalized),
|
|
99
|
+
isAdminRoute: this.detectAdminRoute(normalized, content),
|
|
100
|
+
isUserFacing: this.detectUserFacing(normalized),
|
|
101
|
+
isTypeDefinition: this.detectTypeDefinition(normalized, content, tree),
|
|
102
|
+
isConfigFile: this.detectConfigFile(normalized),
|
|
103
|
+
};
|
|
104
|
+
}
|
|
105
|
+
/**
|
|
106
|
+
* Analyze what AST construct encloses a given line.
|
|
107
|
+
*
|
|
108
|
+
* Walks the tree to find the deepest node that contains the target line,
|
|
109
|
+
* then walks upward through ancestors to determine enclosing constructs.
|
|
110
|
+
*
|
|
111
|
+
* @param line - 1-based line number
|
|
112
|
+
* @param tree - tree-sitter AST
|
|
113
|
+
* @returns LineContext describing the enclosing constructs
|
|
114
|
+
*/
|
|
115
|
+
analyzeLineContext(line, tree) {
|
|
116
|
+
const context = {
|
|
117
|
+
inInterfaceDecl: false,
|
|
118
|
+
inFunctionBody: false,
|
|
119
|
+
inClassMethod: false,
|
|
120
|
+
inJSXElement: false,
|
|
121
|
+
};
|
|
122
|
+
// tree-sitter uses 0-based row indices
|
|
123
|
+
const targetRow = line - 1;
|
|
124
|
+
const node = this.findDeepestNodeAtLine(tree.rootNode, targetRow);
|
|
125
|
+
if (!node) {
|
|
126
|
+
return context;
|
|
127
|
+
}
|
|
128
|
+
// Walk ancestors from the deepest node upward
|
|
129
|
+
let current = node;
|
|
130
|
+
let insideClassBody = false;
|
|
131
|
+
while (current) {
|
|
132
|
+
const type = current.type;
|
|
133
|
+
if (INTERFACE_NODE_TYPES.has(type)) {
|
|
134
|
+
context.inInterfaceDecl = true;
|
|
135
|
+
}
|
|
136
|
+
if (FUNCTION_NODE_TYPES.has(type)) {
|
|
137
|
+
context.inFunctionBody = true;
|
|
138
|
+
// If we already saw a class ancestor, this function is a class method
|
|
139
|
+
if (insideClassBody || METHOD_NODE_TYPES.has(type)) {
|
|
140
|
+
context.inClassMethod = true;
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
if (CLASS_NODE_TYPES.has(type)) {
|
|
144
|
+
insideClassBody = true;
|
|
145
|
+
}
|
|
146
|
+
if (JSX_NODE_TYPES.has(type)) {
|
|
147
|
+
context.inJSXElement = true;
|
|
148
|
+
}
|
|
149
|
+
current = current.parent;
|
|
150
|
+
}
|
|
151
|
+
return context;
|
|
152
|
+
}
|
|
153
|
+
// -----------------------------------------------------------------------
|
|
154
|
+
// Private helpers — file scope detection
|
|
155
|
+
// -----------------------------------------------------------------------
|
|
156
|
+
detectTestFile(filePath) {
|
|
157
|
+
return TEST_FILE_PATTERNS.some(p => p.test(filePath));
|
|
158
|
+
}
|
|
159
|
+
detectAdminRoute(filePath, content) {
|
|
160
|
+
// Path-based detection
|
|
161
|
+
if (ADMIN_PATH_PATTERNS.some(p => p.test(filePath))) {
|
|
162
|
+
return true;
|
|
163
|
+
}
|
|
164
|
+
// Content-based detection (e.g., AdminPanel component)
|
|
165
|
+
if (ADMIN_CONTENT_PATTERNS.some(p => p.test(content))) {
|
|
166
|
+
// Only count if the path also suggests dashboard/admin context
|
|
167
|
+
// OR the component name is strongly admin-specific
|
|
168
|
+
return true;
|
|
169
|
+
}
|
|
170
|
+
return false;
|
|
171
|
+
}
|
|
172
|
+
detectUserFacing(filePath) {
|
|
173
|
+
return USER_FACING_PATTERNS.some(p => p.test(filePath));
|
|
174
|
+
}
|
|
175
|
+
detectTypeDefinition(filePath, content, tree) {
|
|
176
|
+
// .d.ts files are always type definitions
|
|
177
|
+
if (TYPE_DEF_PATH_PATTERNS.some(p => p.test(filePath))) {
|
|
178
|
+
return true;
|
|
179
|
+
}
|
|
180
|
+
// Heuristic: if the file content is predominantly interfaces/types
|
|
181
|
+
if (tree) {
|
|
182
|
+
return this.isAstPrimarilyTypes(tree);
|
|
183
|
+
}
|
|
184
|
+
// Fallback: content-based heuristic for non-AST path
|
|
185
|
+
return this.isContentPrimarilyTypes(content);
|
|
186
|
+
}
|
|
187
|
+
detectConfigFile(filePath) {
|
|
188
|
+
return CONFIG_FILE_PATTERNS.some(p => p.test(filePath));
|
|
189
|
+
}
|
|
190
|
+
// -----------------------------------------------------------------------
|
|
191
|
+
// Private helpers — type definition heuristics
|
|
192
|
+
// -----------------------------------------------------------------------
|
|
193
|
+
/**
|
|
194
|
+
* Check via AST whether the file consists primarily of type declarations.
|
|
195
|
+
* A file is considered primarily types if >= 80% of its top-level
|
|
196
|
+
* statements are interface/type declarations.
|
|
197
|
+
*/
|
|
198
|
+
isAstPrimarilyTypes(tree) {
|
|
199
|
+
const root = tree.rootNode;
|
|
200
|
+
let totalStatements = 0;
|
|
201
|
+
let typeStatements = 0;
|
|
202
|
+
for (let i = 0; i < root.childCount; i++) {
|
|
203
|
+
const child = root.child(i);
|
|
204
|
+
if (!child)
|
|
205
|
+
continue;
|
|
206
|
+
const type = child.type;
|
|
207
|
+
// Skip import/export wrapper nodes — look inside them
|
|
208
|
+
if (type === 'export_statement') {
|
|
209
|
+
const inner = child.namedChildren[0];
|
|
210
|
+
if (inner) {
|
|
211
|
+
totalStatements++;
|
|
212
|
+
if (this.isTypeNode(inner.type)) {
|
|
213
|
+
typeStatements++;
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
continue;
|
|
217
|
+
}
|
|
218
|
+
// Skip import statements — they don't count
|
|
219
|
+
if (type === 'import_statement')
|
|
220
|
+
continue;
|
|
221
|
+
totalStatements++;
|
|
222
|
+
if (this.isTypeNode(type)) {
|
|
223
|
+
typeStatements++;
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
if (totalStatements === 0)
|
|
227
|
+
return false;
|
|
228
|
+
return typeStatements / totalStatements >= 0.8;
|
|
229
|
+
}
|
|
230
|
+
isTypeNode(nodeType) {
|
|
231
|
+
return (nodeType === 'interface_declaration' ||
|
|
232
|
+
nodeType === 'type_alias_declaration');
|
|
233
|
+
}
|
|
234
|
+
/**
|
|
235
|
+
* Content-based fallback: count top-level interface/type declaration blocks
|
|
236
|
+
* vs total top-level statements (excluding imports and blanks).
|
|
237
|
+
*
|
|
238
|
+
* Uses a simple state machine: lines starting with `interface` or `type`
|
|
239
|
+
* keywords begin a type block. Lines that are clearly function/class/const
|
|
240
|
+
* declarations begin a non-type block. Lines inside a block (e.g., interface
|
|
241
|
+
* members) are attributed to whatever block they belong to.
|
|
242
|
+
*/
|
|
243
|
+
isContentPrimarilyTypes(content) {
|
|
244
|
+
const lines = content.split('\n');
|
|
245
|
+
let typeBlocks = 0;
|
|
246
|
+
let nonTypeBlocks = 0;
|
|
247
|
+
const typeStart = /^\s*(export\s+)?(interface|type)\s+\w+/;
|
|
248
|
+
const nonTypeStart = /^\s*(export\s+)?(function|class|const|let|var|enum|async\s+function)\s+\w+/;
|
|
249
|
+
const importPattern = /^\s*import\s/;
|
|
250
|
+
const blankOrComment = /^\s*(\/\/|\/\*|\*|$)/;
|
|
251
|
+
const closingBrace = /^\s*\};\s*$/;
|
|
252
|
+
for (const line of lines) {
|
|
253
|
+
if (blankOrComment.test(line))
|
|
254
|
+
continue;
|
|
255
|
+
if (importPattern.test(line))
|
|
256
|
+
continue;
|
|
257
|
+
if (closingBrace.test(line))
|
|
258
|
+
continue;
|
|
259
|
+
if (typeStart.test(line)) {
|
|
260
|
+
typeBlocks++;
|
|
261
|
+
}
|
|
262
|
+
else if (nonTypeStart.test(line)) {
|
|
263
|
+
nonTypeBlocks++;
|
|
264
|
+
}
|
|
265
|
+
// Lines inside a block (members, etc.) are ignored for counting
|
|
266
|
+
}
|
|
267
|
+
const totalBlocks = typeBlocks + nonTypeBlocks;
|
|
268
|
+
if (totalBlocks === 0)
|
|
269
|
+
return false;
|
|
270
|
+
return typeBlocks / totalBlocks >= 0.8;
|
|
271
|
+
}
|
|
272
|
+
// -----------------------------------------------------------------------
|
|
273
|
+
// Private helpers — AST traversal
|
|
274
|
+
// -----------------------------------------------------------------------
|
|
275
|
+
/**
|
|
276
|
+
* Find the deepest (most specific) AST node whose range contains the
|
|
277
|
+
* target row. This gives us a starting point for ancestor walking.
|
|
278
|
+
*/
|
|
279
|
+
findDeepestNodeAtLine(node, targetRow) {
|
|
280
|
+
// If this node doesn't span the target row, skip it
|
|
281
|
+
if (node.startPosition.row > targetRow || node.endPosition.row < targetRow) {
|
|
282
|
+
return null;
|
|
283
|
+
}
|
|
284
|
+
// Try to find a more specific child
|
|
285
|
+
for (let i = 0; i < node.childCount; i++) {
|
|
286
|
+
const child = node.child(i);
|
|
287
|
+
if (!child)
|
|
288
|
+
continue;
|
|
289
|
+
const deeper = this.findDeepestNodeAtLine(child, targetRow);
|
|
290
|
+
if (deeper) {
|
|
291
|
+
return deeper;
|
|
292
|
+
}
|
|
293
|
+
}
|
|
294
|
+
// No child matched — this node is the deepest
|
|
295
|
+
return node;
|
|
296
|
+
}
|
|
297
|
+
}
|
|
298
|
+
exports.ScopeAnalyzer = ScopeAnalyzer;
|
|
299
|
+
exports.default = ScopeAnalyzer;
|
|
300
|
+
//# sourceMappingURL=scope-analyzer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scope-analyzer.js","sourceRoot":"","sources":["../src/scope-analyzer.ts"],"names":[],"mappings":";AAAA;;;;;;GAMG;;;AAmCH,8EAA8E;AAC9E,qBAAqB;AACrB,8EAA8E;AAE9E,MAAM,kBAAkB,GAAa;IACnC,aAAa;IACb,mBAAmB;IACnB,mBAAmB;IACnB,0BAA0B;IAC1B,qBAAqB;IACrB,sBAAsB;IACtB,gBAAgB;IAChB,kCAAkC;CACnC,CAAC;AAEF,MAAM,mBAAmB,GAAa;IACpC,kBAAkB;IAClB,sBAAsB;IACtB,sBAAsB;CACvB,CAAC;AAEF,MAAM,sBAAsB,GAAa;IACvC,gBAAgB;IAChB,oBAAoB;IACpB,iBAAiB;IACjB,gBAAgB;IAChB,eAAe;CAChB,CAAC;AAEF,MAAM,oBAAoB,GAAa;IACrC,kBAAkB;IAClB,uBAAuB;IACvB,kBAAkB;IAClB,oBAAoB;IACpB,gBAAgB;IAChB,+BAA+B;CAChC,CAAC;AAEF,MAAM,sBAAsB,GAAa;IACvC,aAAa;CACd,CAAC;AAEF,MAAM,oBAAoB,GAAa;IACrC,qBAAqB;IACrB,qBAAqB;IACrB,uBAAuB;IACvB,yBAAyB;IACzB,uBAAuB;IACvB,aAAa;CACd,CAAC;AAEF,8EAA8E;AAC9E,gDAAgD;AAChD,8EAA8E;AAE9E,MAAM,oBAAoB,GAAG,IAAI,GAAG,CAAC;IACnC,uBAAuB;CACxB,CAAC,CAAC;AAEH,MAAM,mBAAmB,GAAG,IAAI,GAAG,CAAC;IAClC,sBAAsB;IACtB,gBAAgB;IAChB,UAAU;IACV,mBAAmB;IACnB,qBAAqB;CACtB,CAAC,CAAC;AAEH,MAAM,gBAAgB,GAAG,IAAI,GAAG,CAAC;IAC/B,mBAAmB;IACnB,OAAO;CACR,CAAC,CAAC;AAEH,MAAM,iBAAiB,GAAG,IAAI,GAAG,CAAC;IAChC,mBAAmB;CACpB,CAAC,CAAC;AAEH,MAAM,cAAc,GAAG,IAAI,GAAG,CAAC;IAC7B,aAAa;IACb,0BAA0B;CAC3B,CAAC,CAAC;AAEH,8EAA8E;AAC9E,gBAAgB;AAChB,8EAA8E;AAE9E;;;GAGG;AACH,MAAa,aAAa;IAExB;;;;;;;OAOG;IACH,WAAW,CAAC,QAAgB,EAAE,OAAe,EAAE,IAAkB;QAC/D,MAAM,UAAU,GAAG,QAAQ,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;QAEhD,OAAO;YACL,UAAU,EAAE,IAAI,CAAC,cAAc,CAAC,UAAU,CAAC;YAC3C,YAAY,EAAE,IAAI,CAAC,gBAAgB,CAAC,UAAU,EAAE,OAAO,CAAC;YACxD,YAAY,EAAE,IAAI,CAAC,gBAAgB,CAAC,UAAU,CAAC;YAC/C,gBAAgB,EAAE,IAAI,CAAC,oBAAoB,CAAC,UAAU,EAAE,OAAO,EAAE,IAAI,CAAC;YACtE,YAAY,EAAE,IAAI,CAAC,gBAAgB,CAAC,UAAU,CAAC;SAChD,CAAC;IACJ,CAAC;IAED;;;;;;;;;OASG;IACH,kBAAkB,CAAC,IAAY,EAAE,IAAiB;QAChD,MAAM,OAAO,GAAgB;YAC3B,eAAe,EAAE,KAAK;YACtB,cAAc,EAAE,KAAK;YACrB,aAAa,EAAE,KAAK;YACpB,YAAY,EAAE,KAAK;SACpB,CAAC;QAEF,uCAAuC;QACvC,MAAM,SAAS,GAAG,IAAI,GAAG,CAAC,CAAC;QAE3B,MAAM,IAAI,GAAG,IAAI,CAAC,qBAAqB,CAAC,IAAI,CAAC,QAAQ,EAAE,SAAS,CAAC,CAAC;QAClE,IAAI,CAAC,IAAI,EAAE,CAAC;YACV,OAAO,OAAO,CAAC;QACjB,CAAC;QAED,8CAA8C;QAC9C,IAAI,OAAO,GAA6B,IAAI,CAAC;QAC7C,IAAI,eAAe,GAAG,KAAK,CAAC;QAE5B,OAAO,OAAO,EAAE,CAAC;YACf,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC;YAE1B,IAAI,oBAAoB,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC;gBACnC,OAAO,CAAC,eAAe,GAAG,IAAI,CAAC;YACjC,CAAC;YAED,IAAI,mBAAmB,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC;gBAClC,OAAO,CAAC,cAAc,GAAG,IAAI,CAAC;gBAC9B,sEAAsE;gBACtE,IAAI,eAAe,IAAI,iBAAiB,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC;oBACnD,OAAO,CAAC,aAAa,GAAG,IAAI,CAAC;gBAC/B,CAAC;YACH,CAAC;YAED,IAAI,gBAAgB,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC;gBAC/B,eAAe,GAAG,IAAI,CAAC;YACzB,CAAC;YAED,IAAI,cAAc,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC;gBAC7B,OAAO,CAAC,YAAY,GAAG,IAAI,CAAC;YAC9B,CAAC;YAED,OAAO,GAAG,OAAO,CAAC,MAAM,CAAC;QAC3B,CAAC;QAED,OAAO,OAAO,CAAC;IACjB,CAAC;IAED,0EAA0E;IAC1E,yCAAyC;IACzC,0EAA0E;IAElE,cAAc,CAAC,QAAgB;QACrC,OAAO,kBAAkB,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC;IACxD,CAAC;IAEO,gBAAgB,CAAC,QAAgB,EAAE,OAAe;QACxD,uBAAuB;QACvB,IAAI,mBAAmB,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,EAAE,CAAC;YACpD,OAAO,IAAI,CAAC;QACd,CAAC;QACD,uDAAuD;QACvD,IAAI,sBAAsB,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,EAAE,CAAC;YACtD,+DAA+D;YAC/D,mDAAmD;YACnD,OAAO,IAAI,CAAC;QACd,CAAC;QACD,OAAO,KAAK,CAAC;IACf,CAAC;IAEO,gBAAgB,CAAC,QAAgB;QACvC,OAAO,oBAAoB,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC;IAC1D,CAAC;IAEO,oBAAoB,CAC1B,QAAgB,EAChB,OAAe,EACf,IAAkB;QAElB,0CAA0C;QAC1C,IAAI,sBAAsB,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,EAAE,CAAC;YACvD,OAAO,IAAI,CAAC;QACd,CAAC;QAED,mEAAmE;QACnE,IAAI,IAAI,EAAE,CAAC;YACT,OAAO,IAAI,CAAC,mBAAmB,CAAC,IAAI,CAAC,CAAC;QACxC,CAAC;QAED,qDAAqD;QACrD,OAAO,IAAI,CAAC,uBAAuB,CAAC,OAAO,CAAC,CAAC;IAC/C,CAAC;IAEO,gBAAgB,CAAC,QAAgB;QACvC,OAAO,oBAAoB,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC;IAC1D,CAAC;IAED,0EAA0E;IAC1E,+CAA+C;IAC/C,0EAA0E;IAE1E;;;;OAIG;IACK,mBAAmB,CAAC,IAAiB;QAC3C,MAAM,IAAI,GAAG,IAAI,CAAC,QAAQ,CAAC;QAC3B,IAAI,eAAe,GAAG,CAAC,CAAC;QACxB,IAAI,cAAc,GAAG,CAAC,CAAC;QAEvB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,UAAU,EAAE,CAAC,EAAE,EAAE,CAAC;YACzC,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;YAC5B,IAAI,CAAC,KAAK;gBAAE,SAAS;YAErB,MAAM,IAAI,GAAG,KAAK,CAAC,IAAI,CAAC;YAExB,sDAAsD;YACtD,IAAI,IAAI,KAAK,kBAAkB,EAAE,CAAC;gBAChC,MAAM,KAAK,GAAG,KAAK,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC;gBACrC,IAAI,KAAK,EAAE,CAAC;oBACV,eAAe,EAAE,CAAC;oBAClB,IAAI,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC;wBAChC,cAAc,EAAE,CAAC;oBACnB,CAAC;gBACH,CAAC;gBACD,SAAS;YACX,CAAC;YAED,4CAA4C;YAC5C,IAAI,IAAI,KAAK,kBAAkB;gBAAE,SAAS;YAE1C,eAAe,EAAE,CAAC;YAClB,IAAI,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC;gBAC1B,cAAc,EAAE,CAAC;YACnB,CAAC;QACH,CAAC;QAED,IAAI,eAAe,KAAK,CAAC;YAAE,OAAO,KAAK,CAAC;QACxC,OAAO,cAAc,GAAG,eAAe,IAAI,GAAG,CAAC;IACjD,CAAC;IAEO,UAAU,CAAC,QAAgB;QACjC,OAAO,CACL,QAAQ,KAAK,uBAAuB;YACpC,QAAQ,KAAK,wBAAwB,CACtC,CAAC;IACJ,CAAC;IAED;;;;;;;;OAQG;IACK,uBAAuB,CAAC,OAAe;QAC7C,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QAClC,IAAI,UAAU,GAAG,CAAC,CAAC;QACnB,IAAI,aAAa,GAAG,CAAC,CAAC;QAEtB,MAAM,SAAS,GAAG,wCAAwC,CAAC;QAC3D,MAAM,YAAY,GAAG,4EAA4E,CAAC;QAClG,MAAM,aAAa,GAAG,cAAc,CAAC;QACrC,MAAM,cAAc,GAAG,sBAAsB,CAAC;QAC9C,MAAM,YAAY,GAAG,aAAa,CAAC;QAEnC,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;YACzB,IAAI,cAAc,CAAC,IAAI,CAAC,IAAI,CAAC;gBAAE,SAAS;YACxC,IAAI,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC;gBAAE,SAAS;YACvC,IAAI,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC;gBAAE,SAAS;YAEtC,IAAI,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;gBACzB,UAAU,EAAE,CAAC;YACf,CAAC;iBAAM,IAAI,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;gBACnC,aAAa,EAAE,CAAC;YAClB,CAAC;YACD,gEAAgE;QAClE,CAAC;QAED,MAAM,WAAW,GAAG,UAAU,GAAG,aAAa,CAAC;QAC/C,IAAI,WAAW,KAAK,CAAC;YAAE,OAAO,KAAK,CAAC;QACpC,OAAO,UAAU,GAAG,WAAW,IAAI,GAAG,CAAC;IACzC,CAAC;IAED,0EAA0E;IAC1E,kCAAkC;IAClC,0EAA0E;IAE1E;;;OAGG;IACK,qBAAqB,CAC3B,IAAuB,EACvB,SAAiB;QAEjB,oDAAoD;QACpD,IAAI,IAAI,CAAC,aAAa,CAAC,GAAG,GAAG,SAAS,IAAI,IAAI,CAAC,WAAW,CAAC,GAAG,GAAG,SAAS,EAAE,CAAC;YAC3E,OAAO,IAAI,CAAC;QACd,CAAC;QAED,oCAAoC;QACpC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,UAAU,EAAE,CAAC,EAAE,EAAE,CAAC;YACzC,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;YAC5B,IAAI,CAAC,KAAK;gBAAE,SAAS;YACrB,MAAM,MAAM,GAAG,IAAI,CAAC,qBAAqB,CAAC,KAAK,EAAE,SAAS,CAAC,CAAC;YAC5D,IAAI,MAAM,EAAE,CAAC;gBACX,OAAO,MAAM,CAAC;YAChB,CAAC;QACH,CAAC;QAED,8CAA8C;QAC9C,OAAO,IAAI,CAAC;IACd,CAAC;CACF;AA1PD,sCA0PC;AAED,kBAAe,aAAa,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@runhalo/engine",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"description": "Halo rule engine —
|
|
3
|
+
"version": "0.5.0",
|
|
4
|
+
"description": "Halo rule engine — child online safety compliance detection with tree-sitter AST analysis. 114 rules across 10 jurisdictions including COPPA, UK AADC, EU DSA, EU AI Act, and more.",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
7
7
|
"files": [
|
|
@@ -17,6 +17,10 @@
|
|
|
17
17
|
"coppa",
|
|
18
18
|
"privacy",
|
|
19
19
|
"child-safety",
|
|
20
|
+
"compliance",
|
|
21
|
+
"aadc",
|
|
22
|
+
"dsa",
|
|
23
|
+
"online-safety",
|
|
20
24
|
"static-analysis",
|
|
21
25
|
"tree-sitter",
|
|
22
26
|
"ast",
|