agent-threat-rules 1.0.0 → 1.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.
Files changed (230) hide show
  1. package/README.md +9 -8
  2. package/dist/action-executor.d.ts +44 -0
  3. package/dist/action-executor.d.ts.map +1 -0
  4. package/dist/action-executor.js +130 -0
  5. package/dist/action-executor.js.map +1 -0
  6. package/dist/adapters/default-adapter.d.ts +24 -0
  7. package/dist/adapters/default-adapter.d.ts.map +1 -0
  8. package/dist/adapters/default-adapter.js +51 -0
  9. package/dist/adapters/default-adapter.js.map +1 -0
  10. package/dist/adapters/stdio-adapter.d.ts +30 -0
  11. package/dist/adapters/stdio-adapter.d.ts.map +1 -0
  12. package/dist/adapters/stdio-adapter.js +128 -0
  13. package/dist/adapters/stdio-adapter.js.map +1 -0
  14. package/dist/badge.d.ts +42 -0
  15. package/dist/badge.d.ts.map +1 -0
  16. package/dist/badge.js +163 -0
  17. package/dist/badge.js.map +1 -0
  18. package/dist/capability-extractor.d.ts +35 -0
  19. package/dist/capability-extractor.d.ts.map +1 -0
  20. package/dist/capability-extractor.js +91 -0
  21. package/dist/capability-extractor.js.map +1 -0
  22. package/dist/cli/scan-handler.d.ts +21 -0
  23. package/dist/cli/scan-handler.d.ts.map +1 -0
  24. package/dist/cli/scan-handler.js +276 -0
  25. package/dist/cli/scan-handler.js.map +1 -0
  26. package/dist/cli/tc-pipeline.d.ts +18 -0
  27. package/dist/cli/tc-pipeline.d.ts.map +1 -0
  28. package/dist/cli/tc-pipeline.js +295 -0
  29. package/dist/cli/tc-pipeline.js.map +1 -0
  30. package/dist/cli.d.ts +12 -0
  31. package/dist/cli.d.ts.map +1 -0
  32. package/dist/cli.js +884 -0
  33. package/dist/cli.js.map +1 -0
  34. package/dist/content-hash.d.ts +7 -0
  35. package/dist/content-hash.d.ts.map +1 -0
  36. package/dist/content-hash.js +10 -0
  37. package/dist/content-hash.js.map +1 -0
  38. package/dist/converters/elastic.d.ts +36 -0
  39. package/dist/converters/elastic.d.ts.map +1 -0
  40. package/dist/converters/elastic.js +125 -0
  41. package/dist/converters/elastic.js.map +1 -0
  42. package/dist/converters/generic-regex.d.ts +37 -0
  43. package/dist/converters/generic-regex.d.ts.map +1 -0
  44. package/dist/converters/generic-regex.js +59 -0
  45. package/dist/converters/generic-regex.js.map +1 -0
  46. package/dist/converters/index.d.ts +32 -0
  47. package/dist/converters/index.d.ts.map +1 -0
  48. package/dist/converters/index.js +38 -0
  49. package/dist/converters/index.js.map +1 -0
  50. package/dist/converters/sarif.d.ts +18 -0
  51. package/dist/converters/sarif.d.ts.map +1 -0
  52. package/dist/converters/sarif.js +142 -0
  53. package/dist/converters/sarif.js.map +1 -0
  54. package/dist/converters/splunk.d.ts +19 -0
  55. package/dist/converters/splunk.d.ts.map +1 -0
  56. package/dist/converters/splunk.js +148 -0
  57. package/dist/converters/splunk.js.map +1 -0
  58. package/dist/coverage-analyzer.d.ts +43 -0
  59. package/dist/coverage-analyzer.d.ts.map +1 -0
  60. package/dist/coverage-analyzer.js +329 -0
  61. package/dist/coverage-analyzer.js.map +1 -0
  62. package/dist/embedding/build-corpus.d.ts +15 -0
  63. package/dist/embedding/build-corpus.d.ts.map +1 -0
  64. package/dist/embedding/build-corpus.js +105 -0
  65. package/dist/embedding/build-corpus.js.map +1 -0
  66. package/dist/embedding/model-loader.d.ts +41 -0
  67. package/dist/embedding/model-loader.d.ts.map +1 -0
  68. package/dist/embedding/model-loader.js +90 -0
  69. package/dist/embedding/model-loader.js.map +1 -0
  70. package/dist/embedding/vector-store.d.ts +41 -0
  71. package/dist/embedding/vector-store.d.ts.map +1 -0
  72. package/dist/embedding/vector-store.js +70 -0
  73. package/dist/embedding/vector-store.js.map +1 -0
  74. package/dist/engine.d.ts +217 -0
  75. package/dist/engine.d.ts.map +1 -0
  76. package/dist/engine.js +1117 -0
  77. package/dist/engine.js.map +1 -0
  78. package/dist/eval/corpus.d.ts +42 -0
  79. package/dist/eval/corpus.d.ts.map +1 -0
  80. package/dist/eval/corpus.js +427 -0
  81. package/dist/eval/corpus.js.map +1 -0
  82. package/dist/eval/eval-harness.d.ts +44 -0
  83. package/dist/eval/eval-harness.d.ts.map +1 -0
  84. package/dist/eval/eval-harness.js +296 -0
  85. package/dist/eval/eval-harness.js.map +1 -0
  86. package/dist/eval/index.d.ts +13 -0
  87. package/dist/eval/index.d.ts.map +1 -0
  88. package/dist/eval/index.js +9 -0
  89. package/dist/eval/index.js.map +1 -0
  90. package/dist/eval/metrics.d.ts +74 -0
  91. package/dist/eval/metrics.d.ts.map +1 -0
  92. package/dist/eval/metrics.js +108 -0
  93. package/dist/eval/metrics.js.map +1 -0
  94. package/dist/eval/pint-corpus.d.ts +34 -0
  95. package/dist/eval/pint-corpus.d.ts.map +1 -0
  96. package/dist/eval/pint-corpus.js +113 -0
  97. package/dist/eval/pint-corpus.js.map +1 -0
  98. package/dist/eval/rule-corpus.d.ts +9 -0
  99. package/dist/eval/rule-corpus.d.ts.map +1 -0
  100. package/dist/eval/rule-corpus.js +4780 -0
  101. package/dist/eval/rule-corpus.js.map +1 -0
  102. package/dist/eval/rule-metrics.d.ts +34 -0
  103. package/dist/eval/rule-metrics.d.ts.map +1 -0
  104. package/dist/eval/rule-metrics.js +92 -0
  105. package/dist/eval/rule-metrics.js.map +1 -0
  106. package/dist/eval/run-eval.d.ts +7 -0
  107. package/dist/eval/run-eval.d.ts.map +1 -0
  108. package/dist/eval/run-eval.js +11 -0
  109. package/dist/eval/run-eval.js.map +1 -0
  110. package/dist/eval/run-pint-benchmark.d.ts +18 -0
  111. package/dist/eval/run-pint-benchmark.d.ts.map +1 -0
  112. package/dist/eval/run-pint-benchmark.js +159 -0
  113. package/dist/eval/run-pint-benchmark.js.map +1 -0
  114. package/dist/eval/skill-benchmark.d.ts +66 -0
  115. package/dist/eval/skill-benchmark.d.ts.map +1 -0
  116. package/dist/eval/skill-benchmark.js +194 -0
  117. package/dist/eval/skill-benchmark.js.map +1 -0
  118. package/dist/flywheel.d.ts +54 -0
  119. package/dist/flywheel.d.ts.map +1 -0
  120. package/dist/flywheel.js +121 -0
  121. package/dist/flywheel.js.map +1 -0
  122. package/dist/hook-handler.d.ts +61 -0
  123. package/dist/hook-handler.d.ts.map +1 -0
  124. package/dist/hook-handler.js +178 -0
  125. package/dist/hook-handler.js.map +1 -0
  126. package/dist/index.d.ts +66 -0
  127. package/dist/index.d.ts.map +1 -0
  128. package/dist/index.js +57 -0
  129. package/dist/index.js.map +1 -0
  130. package/dist/layer-integration.d.ts +55 -0
  131. package/dist/layer-integration.d.ts.map +1 -0
  132. package/dist/layer-integration.js +187 -0
  133. package/dist/layer-integration.js.map +1 -0
  134. package/dist/loader.d.ts +18 -0
  135. package/dist/loader.d.ts.map +1 -0
  136. package/dist/loader.js +129 -0
  137. package/dist/loader.js.map +1 -0
  138. package/dist/mcp-server.d.ts +13 -0
  139. package/dist/mcp-server.d.ts.map +1 -0
  140. package/dist/mcp-server.js +246 -0
  141. package/dist/mcp-server.js.map +1 -0
  142. package/dist/mcp-tools/coverage-gaps.d.ts +13 -0
  143. package/dist/mcp-tools/coverage-gaps.d.ts.map +1 -0
  144. package/dist/mcp-tools/coverage-gaps.js +55 -0
  145. package/dist/mcp-tools/coverage-gaps.js.map +1 -0
  146. package/dist/mcp-tools/list-rules.d.ts +17 -0
  147. package/dist/mcp-tools/list-rules.d.ts.map +1 -0
  148. package/dist/mcp-tools/list-rules.js +45 -0
  149. package/dist/mcp-tools/list-rules.js.map +1 -0
  150. package/dist/mcp-tools/scan-skill.d.ts +17 -0
  151. package/dist/mcp-tools/scan-skill.d.ts.map +1 -0
  152. package/dist/mcp-tools/scan-skill.js +65 -0
  153. package/dist/mcp-tools/scan-skill.js.map +1 -0
  154. package/dist/mcp-tools/scan.d.ts +24 -0
  155. package/dist/mcp-tools/scan.d.ts.map +1 -0
  156. package/dist/mcp-tools/scan.js +94 -0
  157. package/dist/mcp-tools/scan.js.map +1 -0
  158. package/dist/mcp-tools/submit-proposal.d.ts +12 -0
  159. package/dist/mcp-tools/submit-proposal.d.ts.map +1 -0
  160. package/dist/mcp-tools/submit-proposal.js +103 -0
  161. package/dist/mcp-tools/submit-proposal.js.map +1 -0
  162. package/dist/mcp-tools/threat-summary.d.ts +12 -0
  163. package/dist/mcp-tools/threat-summary.d.ts.map +1 -0
  164. package/dist/mcp-tools/threat-summary.js +74 -0
  165. package/dist/mcp-tools/threat-summary.js.map +1 -0
  166. package/dist/mcp-tools/validate.d.ts +15 -0
  167. package/dist/mcp-tools/validate.d.ts.map +1 -0
  168. package/dist/mcp-tools/validate.js +51 -0
  169. package/dist/mcp-tools/validate.js.map +1 -0
  170. package/dist/modules/embedding.d.ts +71 -0
  171. package/dist/modules/embedding.d.ts.map +1 -0
  172. package/dist/modules/embedding.js +141 -0
  173. package/dist/modules/embedding.js.map +1 -0
  174. package/dist/modules/index.d.ts +144 -0
  175. package/dist/modules/index.d.ts.map +1 -0
  176. package/dist/modules/index.js +82 -0
  177. package/dist/modules/index.js.map +1 -0
  178. package/dist/modules/semantic.d.ts +106 -0
  179. package/dist/modules/semantic.d.ts.map +1 -0
  180. package/dist/modules/semantic.js +359 -0
  181. package/dist/modules/semantic.js.map +1 -0
  182. package/dist/modules/session.d.ts +70 -0
  183. package/dist/modules/session.d.ts.map +1 -0
  184. package/dist/modules/session.js +128 -0
  185. package/dist/modules/session.js.map +1 -0
  186. package/dist/rule-scaffolder.d.ts +53 -0
  187. package/dist/rule-scaffolder.d.ts.map +1 -0
  188. package/dist/rule-scaffolder.js +301 -0
  189. package/dist/rule-scaffolder.js.map +1 -0
  190. package/dist/session-tracker.d.ts +58 -0
  191. package/dist/session-tracker.d.ts.map +1 -0
  192. package/dist/session-tracker.js +176 -0
  193. package/dist/session-tracker.js.map +1 -0
  194. package/dist/shadow-evaluator.d.ts +48 -0
  195. package/dist/shadow-evaluator.d.ts.map +1 -0
  196. package/dist/shadow-evaluator.js +129 -0
  197. package/dist/shadow-evaluator.js.map +1 -0
  198. package/dist/skill-fingerprint.d.ts +85 -0
  199. package/dist/skill-fingerprint.d.ts.map +1 -0
  200. package/dist/skill-fingerprint.js +284 -0
  201. package/dist/skill-fingerprint.js.map +1 -0
  202. package/dist/tc-reporter.d.ts +50 -0
  203. package/dist/tc-reporter.d.ts.map +1 -0
  204. package/dist/tc-reporter.js +164 -0
  205. package/dist/tc-reporter.js.map +1 -0
  206. package/dist/tier0-invariant.d.ts +49 -0
  207. package/dist/tier0-invariant.d.ts.map +1 -0
  208. package/dist/tier0-invariant.js +185 -0
  209. package/dist/tier0-invariant.js.map +1 -0
  210. package/dist/tier1-blacklist.d.ts +48 -0
  211. package/dist/tier1-blacklist.d.ts.map +1 -0
  212. package/dist/tier1-blacklist.js +92 -0
  213. package/dist/tier1-blacklist.js.map +1 -0
  214. package/dist/types.d.ts +212 -0
  215. package/dist/types.d.ts.map +1 -0
  216. package/dist/types.js +6 -0
  217. package/dist/types.js.map +1 -0
  218. package/dist/verdict.d.ts +26 -0
  219. package/dist/verdict.d.ts.map +1 -0
  220. package/dist/verdict.js +127 -0
  221. package/dist/verdict.js.map +1 -0
  222. package/package.json +1 -1
  223. package/rules/context-exfiltration/ATR-2026-00150-credential-in-tool-response.yaml +90 -0
  224. package/rules/context-exfiltration/ATR-2026-00152-obfuscated-credential-leak.yaml +81 -0
  225. package/rules/prompt-injection/ATR-2026-00153-tool-with-embedded-instruction-to-bypass.yaml +43 -0
  226. package/rules/prompt-injection/ATR-2026-00154-unauthorized-background-task-execution-v.yaml +43 -0
  227. package/rules/prompt-injection/ATR-2026-00155-hidden-llm-instructions-in-skill-descrip.yaml +43 -0
  228. package/rules/prompt-injection/ATR-2026-00156-ssh-remote-command-execution-with-creden.yaml +43 -0
  229. package/rules/skill-compromise/ATR-2026-00149-skill-exfil-compound.yaml +189 -0
  230. package/rules/skill-compromise/ATR-2026-00151-fork-impersonation-install.yaml +75 -0
package/dist/badge.js ADDED
@@ -0,0 +1,163 @@
1
+ /**
2
+ * ATR Badge Generator
3
+ *
4
+ * Generates shields.io-compatible SVG badges and JSON endpoints
5
+ * for ATR scan results.
6
+ *
7
+ * Badge states:
8
+ * - Green: "ATR Scanned - No Issues" (scan passed, no findings)
9
+ * - Yellow: "ATR Scanned - Issues Found" (scan found potential threats)
10
+ * - Red: "ATR Scanned - Critical" (critical threats detected)
11
+ * - Gray: "Not Yet Scanned" (no scan data available)
12
+ *
13
+ * @module agent-threat-rules/badge
14
+ */
15
+ import { readFileSync } from 'node:fs';
16
+ // ---------------------------------------------------------------------------
17
+ // Badge colors
18
+ // ---------------------------------------------------------------------------
19
+ const BADGE_COLORS = {
20
+ clean: '#2ea44f', // GitHub green
21
+ issues: '#dfb317', // Warning yellow
22
+ critical: '#e05d44', // Alert red
23
+ unknown: '#9f9f9f', // Gray
24
+ };
25
+ // ---------------------------------------------------------------------------
26
+ // Determine badge status from scan data
27
+ // ---------------------------------------------------------------------------
28
+ export function determineBadgeStatus(summary) {
29
+ // Check ATR rule findings first
30
+ if (summary.findings.critical > 0)
31
+ return 'critical';
32
+ if (summary.findings.high > 0)
33
+ return 'critical';
34
+ if (summary.findings.medium > 0)
35
+ return 'issues';
36
+ if (summary.findings.low > 0)
37
+ return 'issues';
38
+ // Fall back to overall risk assessment (from code analysis, supply chain, etc.)
39
+ const level = summary.riskLevel.toUpperCase();
40
+ if (level === 'CRITICAL' || level === 'HIGH')
41
+ return 'critical';
42
+ if (level === 'MEDIUM')
43
+ return 'issues';
44
+ if (level === 'LOW')
45
+ return 'issues';
46
+ return 'clean';
47
+ }
48
+ // ---------------------------------------------------------------------------
49
+ // Generate shields.io endpoint JSON
50
+ // ---------------------------------------------------------------------------
51
+ export function generateBadgeEndpoint(summary) {
52
+ if (!summary) {
53
+ return {
54
+ schemaVersion: 1,
55
+ label: 'ATR',
56
+ message: 'Not Yet Scanned',
57
+ color: BADGE_COLORS.unknown,
58
+ };
59
+ }
60
+ const status = determineBadgeStatus(summary);
61
+ const totalFindings = summary.findings.critical + summary.findings.high + summary.findings.medium + summary.findings.low;
62
+ const messages = {
63
+ clean: 'Scanned - No Issues',
64
+ issues: totalFindings > 0
65
+ ? `Scanned - ${totalFindings} Issue${totalFindings > 1 ? 's' : ''}`
66
+ : `Scanned - ${summary.riskLevel}`,
67
+ critical: totalFindings > 0
68
+ ? `Scanned - ${summary.findings.critical + summary.findings.high} Critical`
69
+ : `Scanned - ${summary.riskLevel}`,
70
+ unknown: 'Not Yet Scanned',
71
+ };
72
+ return {
73
+ schemaVersion: 1,
74
+ label: 'ATR',
75
+ message: messages[status],
76
+ color: BADGE_COLORS[status],
77
+ };
78
+ }
79
+ // ---------------------------------------------------------------------------
80
+ // Generate standalone SVG badge
81
+ // ---------------------------------------------------------------------------
82
+ function escapeXml(str) {
83
+ return str
84
+ .replace(/&/g, '&')
85
+ .replace(/</g, '&lt;')
86
+ .replace(/>/g, '&gt;')
87
+ .replace(/"/g, '&quot;')
88
+ .replace(/'/g, '&apos;');
89
+ }
90
+ function measureText(text) {
91
+ // Approximate character width for Verdana 11px (shields.io standard)
92
+ return text.length * 6.8 + 10;
93
+ }
94
+ export function generateBadgeSvg(summary) {
95
+ const data = generateBadgeEndpoint(summary);
96
+ const label = escapeXml(data.label);
97
+ const message = escapeXml(data.message);
98
+ const color = data.color;
99
+ const labelWidth = measureText(label);
100
+ const messageWidth = measureText(message);
101
+ const totalWidth = labelWidth + messageWidth;
102
+ return `<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="${totalWidth}" height="20" role="img" aria-label="${label}: ${message}">
103
+ <title>${label}: ${message}</title>
104
+ <linearGradient id="s" x2="0" y2="100%">
105
+ <stop offset="0" stop-color="#bbb" stop-opacity=".1"/>
106
+ <stop offset="1" stop-opacity=".1"/>
107
+ </linearGradient>
108
+ <clipPath id="r">
109
+ <rect width="${totalWidth}" height="20" rx="3" fill="#fff"/>
110
+ </clipPath>
111
+ <g clip-path="url(#r)">
112
+ <rect width="${labelWidth}" height="20" fill="#555"/>
113
+ <rect x="${labelWidth}" width="${messageWidth}" height="20" fill="${color}"/>
114
+ <rect width="${totalWidth}" height="20" fill="url(#s)"/>
115
+ </g>
116
+ <g fill="#fff" text-anchor="middle" font-family="Verdana,Geneva,DejaVu Sans,sans-serif" text-rendering="geometricPrecision" font-size="110">
117
+ <text aria-hidden="true" x="${labelWidth * 5}" y="150" fill="#010101" fill-opacity=".3" transform="scale(.1)">${label}</text>
118
+ <text x="${labelWidth * 5}" y="140" transform="scale(.1)" fill="#fff">${label}</text>
119
+ <text aria-hidden="true" x="${(labelWidth + messageWidth / 2) * 10}" y="150" fill="#010101" fill-opacity=".3" transform="scale(.1)">${message}</text>
120
+ <text x="${(labelWidth + messageWidth / 2) * 10}" y="140" transform="scale(.1)" fill="#fff">${message}</text>
121
+ </g>
122
+ </svg>`;
123
+ }
124
+ // ---------------------------------------------------------------------------
125
+ // Load scan result from audit data file
126
+ // ---------------------------------------------------------------------------
127
+ export function lookupPackageScan(auditDataPath, packageName) {
128
+ try {
129
+ const data = JSON.parse(readFileSync(auditDataPath, 'utf-8'));
130
+ const results = data.results ?? [];
131
+ const entry = results.find((r) => r.package === packageName);
132
+ if (!entry)
133
+ return null;
134
+ const atrMatches = entry.atrMatches ?? [];
135
+ const findings = { critical: 0, high: 0, medium: 0, low: 0 };
136
+ for (const m of atrMatches) {
137
+ const sev = (m.severity ?? m.rule?.severity ?? 'low').toLowerCase();
138
+ if (sev in findings) {
139
+ findings[sev]++;
140
+ }
141
+ }
142
+ return {
143
+ packageName: entry.package,
144
+ version: entry.version,
145
+ scannedAt: entry.auditedAt ?? data.auditedAt,
146
+ riskLevel: entry.riskLevel ?? 'UNKNOWN',
147
+ riskScore: entry.riskScore ?? 0,
148
+ findings,
149
+ };
150
+ }
151
+ catch {
152
+ return null;
153
+ }
154
+ }
155
+ // ---------------------------------------------------------------------------
156
+ // Generate markdown badge snippet
157
+ // ---------------------------------------------------------------------------
158
+ export function generateBadgeMarkdown(packageName, repoUrl = 'https://github.com/Agent-Threat-Rule/agent-threat-rules') {
159
+ // Static badge URL using shields.io
160
+ const encodedName = encodeURIComponent(packageName);
161
+ return `[![ATR Scanned](https://img.shields.io/badge/ATR-Scanned-2ea44f?style=flat-square)](${repoUrl})`;
162
+ }
163
+ //# sourceMappingURL=badge.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"badge.js","sourceRoot":"","sources":["../src/badge.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,35 @@
1
+ /**
2
+ * Shared capability extraction from text content.
3
+ *
4
+ * Used by both SkillFingerprintStore (behavioral drift detection)
5
+ * and InvariantChecker (manifest enforcement).
6
+ *
7
+ * Regex-based, no LLM needed. Analyzes first 10KB to prevent ReDoS.
8
+ *
9
+ * @module agent-threat-rules/capability-extractor
10
+ */
11
+ export declare const FS_WRITE_PATTERN: RegExp;
12
+ export declare const FS_READ_PATTERN: RegExp;
13
+ export declare const FS_DELETE_PATTERN: RegExp;
14
+ export declare const NETWORK_PATTERN: RegExp;
15
+ export declare const ENV_PATTERN: RegExp;
16
+ export declare const ENV_INLINE_PATTERN: RegExp;
17
+ export declare const EXEC_PATTERN: RegExp;
18
+ export declare const EXFIL_PATTERN: RegExp;
19
+ export declare const REDIRECT_PATTERN: RegExp;
20
+ /** Path extraction: find filesystem paths referenced in text (min 2 segments to reduce noise) */
21
+ export declare const PATH_PATTERN: RegExp;
22
+ /** Config file modification patterns */
23
+ export declare const CONFIG_MOD_PATTERN: RegExp;
24
+ export interface ExtractedCapabilities {
25
+ readonly filesystemOps: readonly string[];
26
+ readonly filesystemPaths: readonly string[];
27
+ readonly networkTargets: readonly string[];
28
+ readonly envAccesses: readonly string[];
29
+ readonly processExecs: readonly string[];
30
+ readonly outputPatterns: readonly string[];
31
+ readonly configModifications: boolean;
32
+ }
33
+ /** Classify text content into behavioral capabilities */
34
+ export declare function extractCapabilities(text: string): ExtractedCapabilities;
35
+ //# sourceMappingURL=capability-extractor.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"capability-extractor.d.ts","sourceRoot":"","sources":["../src/capability-extractor.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAMH,eAAO,MAAM,gBAAgB,QACkD,CAAC;AAChF,eAAO,MAAM,eAAe,QACiC,CAAC;AAC9D,eAAO,MAAM,iBAAiB,QAC0B,CAAC;AAEzD,eAAO,MAAM,eAAe,QAC0F,CAAC;AAEvH,eAAO,MAAM,WAAW,QAC0D,CAAC;AACnF,eAAO,MAAM,kBAAkB,QAAmC,CAAC;AAEnE,eAAO,MAAM,YAAY,QACiG,CAAC;AAE3H,eAAO,MAAM,aAAa,QAC6D,CAAC;AACxF,eAAO,MAAM,gBAAgB,QACqC,CAAC;AAEnE,iGAAiG;AACjG,eAAO,MAAM,YAAY,QACuB,CAAC;AASjD,wCAAwC;AACxC,eAAO,MAAM,kBAAkB,QACqD,CAAC;AAMrF,MAAM,WAAW,qBAAqB;IACpC,QAAQ,CAAC,aAAa,EAAE,SAAS,MAAM,EAAE,CAAC;IAC1C,QAAQ,CAAC,eAAe,EAAE,SAAS,MAAM,EAAE,CAAC;IAC5C,QAAQ,CAAC,cAAc,EAAE,SAAS,MAAM,EAAE,CAAC;IAC3C,QAAQ,CAAC,WAAW,EAAE,SAAS,MAAM,EAAE,CAAC;IACxC,QAAQ,CAAC,YAAY,EAAE,SAAS,MAAM,EAAE,CAAC;IACzC,QAAQ,CAAC,cAAc,EAAE,SAAS,MAAM,EAAE,CAAC;IAC3C,QAAQ,CAAC,mBAAmB,EAAE,OAAO,CAAC;CACvC;AAED,yDAAyD;AACzD,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,GAAG,qBAAqB,CAwDvE"}
@@ -0,0 +1,91 @@
1
+ /**
2
+ * Shared capability extraction from text content.
3
+ *
4
+ * Used by both SkillFingerprintStore (behavioral drift detection)
5
+ * and InvariantChecker (manifest enforcement).
6
+ *
7
+ * Regex-based, no LLM needed. Analyzes first 10KB to prevent ReDoS.
8
+ *
9
+ * @module agent-threat-rules/capability-extractor
10
+ */
11
+ // ---------------------------------------------------------------------------
12
+ // Pattern detectors
13
+ // ---------------------------------------------------------------------------
14
+ export const FS_WRITE_PATTERN = /(?:write(?:File)?|appendFile|fs\.write|truncate|mkdir|rmdir|unlink|rm\s+-)/i;
15
+ export const FS_READ_PATTERN = /(?:read(?:File)?|readdir|stat|access|exists|glob|find\s)/i;
16
+ export const FS_DELETE_PATTERN = /(?:unlink|rm\s+-rf|delete(?:File)?|removeDir|rmdir)/i;
17
+ export const NETWORK_PATTERN = /(?:https?:\/\/|fetch|curl|wget|axios|http\.request|net\.connect|socket)[\s('"]*([a-zA-Z0-9.-]+(?:\.[a-zA-Z]{2,}))/i;
18
+ export const ENV_PATTERN = /(?:process\.env|os\.environ|getenv|System\.getenv)\[?['"(]?([A-Z_][A-Z0-9_]*)/i;
19
+ export const ENV_INLINE_PATTERN = /\$\{?([A-Z_][A-Z0-9_]{2,})\}?/g;
20
+ export const EXEC_PATTERN = /(?:child_process|spawn|exec(?:File)?|system\(|popen|subprocess|shell_exec|os\.system)\s*\(\s*['"(]?([^\s'")\]]{1,80})/i;
21
+ export const EXFIL_PATTERN = /(?:base64|btoa|encode|compress|deflate|gzip).*(?:http|fetch|curl|send|post|upload)/i;
22
+ export const REDIRECT_PATTERN = /(?:redirect|forward|proxy|tunnel)\s+(?:to\s+)?(?:https?:\/\/)/i;
23
+ /** Path extraction: find filesystem paths referenced in text (min 2 segments to reduce noise) */
24
+ export const PATH_PATTERN = /(?:["'`]|^|\s)(\/(?:[\w.-]+\/){1,}[\w.-]+)/gm;
25
+ /** Common benign paths that appear in docs/version strings -- skip these */
26
+ const BENIGN_PATH_PREFIXES = [
27
+ '/usr/bin/', '/usr/lib/', '/usr/local/',
28
+ '/node_modules/', '/dist/', '/build/',
29
+ '/v1/', '/v2/', '/api/',
30
+ ];
31
+ /** Config file modification patterns */
32
+ export const CONFIG_MOD_PATTERN = /(?:\.mcp\.json|\.claude\/|\.cursor\/|mcp-config|settings\.json|\.env(?:\.\w+)?)/i;
33
+ /** Classify text content into behavioral capabilities */
34
+ export function extractCapabilities(text) {
35
+ const result = {
36
+ filesystemOps: [],
37
+ filesystemPaths: [],
38
+ networkTargets: [],
39
+ envAccesses: [],
40
+ processExecs: [],
41
+ outputPatterns: [],
42
+ configModifications: false,
43
+ };
44
+ if (!text || text.length === 0)
45
+ return result;
46
+ // Limit analysis to first 10KB to prevent ReDoS
47
+ const safeText = text.slice(0, 10_240);
48
+ // Filesystem operations
49
+ if (FS_WRITE_PATTERN.test(safeText))
50
+ result.filesystemOps.push('write');
51
+ if (FS_READ_PATTERN.test(safeText))
52
+ result.filesystemOps.push('read');
53
+ if (FS_DELETE_PATTERN.test(safeText))
54
+ result.filesystemOps.push('delete');
55
+ // Filesystem paths (filter out benign paths from docs/version strings)
56
+ for (const m of safeText.matchAll(PATH_PATTERN)) {
57
+ const path = m[1];
58
+ if (!path || result.filesystemPaths.includes(path))
59
+ continue;
60
+ const isBenign = BENIGN_PATH_PREFIXES.some((p) => path.startsWith(p));
61
+ if (!isBenign) {
62
+ result.filesystemPaths.push(path);
63
+ }
64
+ }
65
+ // Network targets
66
+ const netMatch = safeText.match(NETWORK_PATTERN);
67
+ if (netMatch?.[1])
68
+ result.networkTargets.push(netMatch[1]);
69
+ // Environment variable accesses
70
+ const envMatch = safeText.match(ENV_PATTERN);
71
+ if (envMatch?.[1])
72
+ result.envAccesses.push(envMatch[1]);
73
+ for (const m of safeText.matchAll(ENV_INLINE_PATTERN)) {
74
+ if (m[1] && !result.envAccesses.includes(m[1])) {
75
+ result.envAccesses.push(m[1]);
76
+ }
77
+ }
78
+ // Process executions
79
+ const execMatch = safeText.match(EXEC_PATTERN);
80
+ if (execMatch?.[1])
81
+ result.processExecs.push(execMatch[1]);
82
+ // Output patterns
83
+ if (EXFIL_PATTERN.test(safeText))
84
+ result.outputPatterns.push('exfiltration');
85
+ if (REDIRECT_PATTERN.test(safeText))
86
+ result.outputPatterns.push('redirect');
87
+ // Config modifications
88
+ result.configModifications = CONFIG_MOD_PATTERN.test(safeText);
89
+ return result;
90
+ }
91
+ //# sourceMappingURL=capability-extractor.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"capability-extractor.js","sourceRoot":"","sources":["../src/capability-extractor.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,21 @@
1
+ /**
2
+ * Unified scan handler for ATR CLI.
3
+ * Auto-detects input type: JSON → MCP scan, .md → SKILL.md scan.
4
+ *
5
+ * @module agent-threat-rules/cli/scan-handler
6
+ */
7
+ import type { ScanType } from '../types.js';
8
+ export interface ScanOptions {
9
+ readonly rules?: string;
10
+ readonly json?: boolean;
11
+ readonly sarif?: boolean;
12
+ readonly severity?: string;
13
+ readonly forceType?: ScanType;
14
+ readonly reportToCloud?: boolean;
15
+ readonly tcUrl?: string;
16
+ }
17
+ /** Detect whether the target is an MCP event JSON or SKILL.md file/directory. */
18
+ export declare function detectInputType(targetPath: string): ScanType;
19
+ /** Unified scan command: auto-detects MCP vs SKILL.md and runs the appropriate scan path. */
20
+ export declare function cmdScanUnified(target: string, rulesDir: string, options: ScanOptions): Promise<void>;
21
+ //# sourceMappingURL=scan-handler.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scan-handler.d.ts","sourceRoot":"","sources":["../../src/cli/scan-handler.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAKH,OAAO,KAAK,EAAoC,QAAQ,EAAE,MAAM,aAAa,CAAC;AAqB9E,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,IAAI,CAAC,EAAE,OAAO,CAAC;IACxB,QAAQ,CAAC,KAAK,CAAC,EAAE,OAAO,CAAC;IACzB,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,SAAS,CAAC,EAAE,QAAQ,CAAC;IAC9B,QAAQ,CAAC,aAAa,CAAC,EAAE,OAAO,CAAC;IACjC,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;CACzB;AAED,iFAAiF;AACjF,wBAAgB,eAAe,CAAC,UAAU,EAAE,MAAM,GAAG,QAAQ,CA0B5D;AAED,6FAA6F;AAC7F,wBAAsB,cAAc,CAClC,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,WAAW,GACnB,OAAO,CAAC,IAAI,CAAC,CAqCf"}
@@ -0,0 +1,276 @@
1
+ /**
2
+ * Unified scan handler for ATR CLI.
3
+ * Auto-detects input type: JSON → MCP scan, .md → SKILL.md scan.
4
+ *
5
+ * @module agent-threat-rules/cli/scan-handler
6
+ */
7
+ import { readFileSync, existsSync, statSync, readdirSync } from 'node:fs';
8
+ import { resolve } from 'node:path';
9
+ import { ATREngine } from '../engine.js';
10
+ import { scanResultToSARIF } from '../converters/sarif.js';
11
+ import { createTCReporter } from '../tc-reporter.js';
12
+ const SEVERITY_ORDER = ['informational', 'low', 'medium', 'high', 'critical'];
13
+ // ANSI colors
14
+ const RED = '\x1b[31m';
15
+ const GREEN = '\x1b[32m';
16
+ const DIM = '\x1b[2m';
17
+ const BOLD = '\x1b[1m';
18
+ const RESET = '\x1b[0m';
19
+ const SEVERITY_COLORS = {
20
+ critical: '\x1b[91m',
21
+ high: '\x1b[31m',
22
+ medium: '\x1b[33m',
23
+ low: '\x1b[36m',
24
+ informational: '\x1b[37m',
25
+ };
26
+ /** Detect whether the target is an MCP event JSON or SKILL.md file/directory. */
27
+ export function detectInputType(targetPath) {
28
+ if (targetPath.endsWith('.md'))
29
+ return 'skill';
30
+ if (targetPath.endsWith('.json'))
31
+ return 'mcp';
32
+ // Directory: inspect contents to decide
33
+ if (existsSync(targetPath) && statSync(targetPath).isDirectory()) {
34
+ const entries = readdirSync(targetPath);
35
+ const hasJson = entries.some((e) => e.endsWith('.json'));
36
+ const hasMd = entries.some((e) => e.endsWith('.md') || e.toLowerCase() === 'skill.md');
37
+ if (hasMd)
38
+ return 'skill';
39
+ if (hasJson)
40
+ return 'mcp';
41
+ return 'skill'; // default for empty or non-matching directories
42
+ }
43
+ // Attempt to detect by reading first bytes
44
+ if (existsSync(targetPath)) {
45
+ const head = readFileSync(targetPath, 'utf-8').slice(0, 100).trimStart();
46
+ if (head.startsWith('{') || head.startsWith('['))
47
+ return 'mcp';
48
+ if (head.startsWith('#') || head.startsWith('---'))
49
+ return 'skill';
50
+ }
51
+ throw new Error(`Cannot determine scan type for "${targetPath}". Use .json for MCP events or .md for SKILL.md files.`);
52
+ }
53
+ /** Unified scan command: auto-detects MCP vs SKILL.md and runs the appropriate scan path. */
54
+ export async function cmdScanUnified(target, rulesDir, options) {
55
+ if (!target) {
56
+ console.error(`${RED}Error: Missing target. Usage: atr scan <file|directory>${RESET}`);
57
+ process.exit(1);
58
+ }
59
+ const targetPath = resolve(target);
60
+ if (!existsSync(targetPath)) {
61
+ console.error(`${RED}Error: Path not found: ${targetPath}${RESET}`);
62
+ process.exit(1);
63
+ }
64
+ // Create TC reporter if --report-to-cloud is set
65
+ const reporter = options.reportToCloud
66
+ ? createTCReporter({
67
+ tcUrl: options.tcUrl,
68
+ onError: (err) => console.error(`${DIM}TC upload: ${err.message}${RESET}`),
69
+ })
70
+ : undefined;
71
+ const scanType = options.forceType ?? detectInputType(targetPath);
72
+ try {
73
+ if (scanType === 'skill') {
74
+ await scanSkillFiles(targetPath, rulesDir, options, reporter);
75
+ }
76
+ else {
77
+ await scanMcpEvents(targetPath, rulesDir, options, reporter);
78
+ }
79
+ }
80
+ finally {
81
+ // Flush remaining events before exit
82
+ if (reporter) {
83
+ await reporter.destroy();
84
+ if (!options.json && !options.sarif) {
85
+ console.log(`${DIM} Threat Cloud: detections reported to ${options.tcUrl ?? 'https://tc.panguard.ai'}${RESET}`);
86
+ }
87
+ }
88
+ }
89
+ }
90
+ // ── MCP Event Scan ─────────────────────────────────────────────
91
+ async function scanMcpEvents(eventsPath, rulesDir, options, reporter) {
92
+ const fileStat = statSync(eventsPath);
93
+ if (fileStat.size > 50 * 1024 * 1024) {
94
+ console.error(`${RED}Error: Events file exceeds 50MB limit${RESET}`);
95
+ process.exit(1);
96
+ }
97
+ const raw = readFileSync(eventsPath, 'utf-8');
98
+ let events;
99
+ try {
100
+ const parsed = JSON.parse(raw);
101
+ events = Array.isArray(parsed) ? parsed : [parsed];
102
+ }
103
+ catch {
104
+ console.error(`${RED}Error: Invalid JSON in ${eventsPath}${RESET}`);
105
+ process.exit(1);
106
+ }
107
+ const engine = new ATREngine({ rulesDir, reporter });
108
+ await engine.loadRules();
109
+ const minIdx = SEVERITY_ORDER.indexOf((options.severity ?? 'informational'));
110
+ const allResults = [];
111
+ let totalThreats = 0;
112
+ for (const event of events) {
113
+ if (!event.content)
114
+ continue; // skip malformed events
115
+ const result = engine.evaluateFull(event, eventsPath);
116
+ const filtered = result.matches.filter((m) => SEVERITY_ORDER.indexOf(m.rule.severity) >= minIdx);
117
+ if (filtered.length > 0) {
118
+ allResults.push({ event, result, filtered });
119
+ totalThreats += filtered.length;
120
+ }
121
+ }
122
+ if (options.sarif) {
123
+ const sarifResults = allResults.map(({ result, filtered }) => ({
124
+ ...result,
125
+ matches: filtered,
126
+ threat_count: filtered.length,
127
+ }));
128
+ const version = process.env['npm_package_version'] ?? '1.0.0';
129
+ console.log(JSON.stringify(scanResultToSARIF(sarifResults, version), null, 2));
130
+ return;
131
+ }
132
+ if (options.json) {
133
+ console.log(JSON.stringify({
134
+ scan_type: 'mcp',
135
+ events_scanned: events.length,
136
+ threats_detected: totalThreats,
137
+ rules_loaded: engine.getRuleCount(),
138
+ results: allResults.map(({ event, result, filtered }) => ({
139
+ content_hash: result.content_hash,
140
+ event: {
141
+ type: event.type,
142
+ timestamp: event.timestamp,
143
+ content_preview: event.content.slice(0, 100),
144
+ },
145
+ matches: filtered.map(formatMatchJson),
146
+ })),
147
+ }, null, 2));
148
+ return;
149
+ }
150
+ printScanHeader('MCP', events.length, engine.getRuleCount(), totalThreats);
151
+ if (totalThreats === 0) {
152
+ console.log(`${GREEN}No threats detected.${RESET}\n`);
153
+ return;
154
+ }
155
+ for (const { event, filtered } of allResults) {
156
+ const preview = event.content.slice(0, 80).replace(/\n/g, ' ');
157
+ console.log(` ${DIM}Event: [${event.type}] "${preview}..."${RESET}`);
158
+ for (const m of filtered) {
159
+ printMatch(m);
160
+ }
161
+ console.log('');
162
+ }
163
+ }
164
+ // ── SKILL.md Scan ──────────────────────────────────────────────
165
+ async function scanSkillFiles(targetPath, rulesDir, options, reporter) {
166
+ const skillFiles = collectSkillFiles(targetPath);
167
+ if (skillFiles.length === 0) {
168
+ console.error(`${RED}Error: No SKILL.md files found in ${targetPath}${RESET}`);
169
+ process.exit(1);
170
+ }
171
+ const engine = new ATREngine({ rulesDir, reporter });
172
+ await engine.loadRules();
173
+ const minIdx = SEVERITY_ORDER.indexOf((options.severity ?? 'informational'));
174
+ const allResults = [];
175
+ let totalThreats = 0;
176
+ for (const file of skillFiles) {
177
+ const fileSize = statSync(file).size;
178
+ if (fileSize > 1 * 1024 * 1024) {
179
+ console.error(`${RED}Warning: Skipping ${file} (${Math.round(fileSize / 1024)}KB exceeds 1MB limit)${RESET}`);
180
+ continue;
181
+ }
182
+ const content = readFileSync(file, 'utf-8');
183
+ const result = engine.scanSkillFull(content, file);
184
+ const filtered = result.matches.filter((m) => SEVERITY_ORDER.indexOf(m.rule.severity) >= minIdx);
185
+ if (filtered.length > 0) {
186
+ allResults.push({ file, result, filtered });
187
+ totalThreats += filtered.length;
188
+ }
189
+ }
190
+ if (options.sarif) {
191
+ const sarifResults = allResults.map(({ result, filtered }) => ({
192
+ ...result,
193
+ matches: filtered,
194
+ threat_count: filtered.length,
195
+ }));
196
+ const version = process.env['npm_package_version'] ?? '1.0.0';
197
+ console.log(JSON.stringify(scanResultToSARIF(sarifResults, version), null, 2));
198
+ return;
199
+ }
200
+ if (options.json) {
201
+ console.log(JSON.stringify({
202
+ scan_type: 'skill',
203
+ skills_scanned: skillFiles.length,
204
+ threats_detected: totalThreats,
205
+ rules_loaded: engine.getRuleCount(),
206
+ results: allResults.map(({ file, result, filtered }) => ({
207
+ file,
208
+ content_hash: result.content_hash,
209
+ matches: filtered.map(formatMatchJson),
210
+ })),
211
+ }, null, 2));
212
+ return;
213
+ }
214
+ printScanHeader('SKILL', skillFiles.length, engine.getRuleCount(), totalThreats);
215
+ if (totalThreats === 0) {
216
+ console.log(` ${GREEN}No threats detected.${RESET}\n`);
217
+ return;
218
+ }
219
+ for (const { file, filtered } of allResults) {
220
+ const relPath = file.replace(process.cwd() + '/', '');
221
+ console.log(` ${BOLD}${relPath}${RESET}`);
222
+ for (const m of filtered) {
223
+ printMatch(m);
224
+ }
225
+ console.log('');
226
+ }
227
+ }
228
+ // ── Shared Helpers ─────────────────────────────────────────────
229
+ function collectSkillFiles(targetPath) {
230
+ const files = [];
231
+ const stat = statSync(targetPath);
232
+ if (stat.isDirectory()) {
233
+ walkForSkills(targetPath, files);
234
+ }
235
+ else {
236
+ files.push(targetPath);
237
+ }
238
+ return files;
239
+ }
240
+ function walkForSkills(dir, out) {
241
+ for (const entry of readdirSync(dir, { withFileTypes: true })) {
242
+ const full = resolve(dir, entry.name);
243
+ if (entry.isDirectory()) {
244
+ walkForSkills(full, out);
245
+ }
246
+ else if (entry.name === 'SKILL.md' || entry.name === 'skill.md') {
247
+ out.push(full);
248
+ }
249
+ }
250
+ }
251
+ function formatMatchJson(m) {
252
+ return {
253
+ rule_id: m.rule.id,
254
+ title: m.rule.title,
255
+ severity: m.rule.severity,
256
+ confidence: m.confidence,
257
+ matched_conditions: m.matchedConditions,
258
+ };
259
+ }
260
+ function printScanHeader(type, scanned, rulesLoaded, threats) {
261
+ const label = type === 'MCP' ? 'Events' : 'Skills';
262
+ console.log(`\n${BOLD}ATR ${type} Scan Results${RESET}`);
263
+ console.log(`${DIM}${'─'.repeat(60)}${RESET}`);
264
+ console.log(` ${label} scanned: ${scanned}`);
265
+ console.log(` Rules loaded: ${rulesLoaded}`);
266
+ console.log(` Threats found: ${threats > 0 ? RED + threats + RESET : GREEN + '0' + RESET}`);
267
+ console.log(`${DIM}${'─'.repeat(60)}${RESET}`);
268
+ console.log(`${DIM} Open source (MIT). Star: https://github.com/Agent-Threat-Rule/agent-threat-rules${RESET}`);
269
+ console.log('');
270
+ }
271
+ function printMatch(m) {
272
+ const color = SEVERITY_COLORS[m.rule.severity] ?? '';
273
+ console.log(` ${color}${m.rule.severity.toUpperCase().padEnd(13)}${RESET} ${m.rule.id} - ${m.rule.title}`);
274
+ console.log(` ${DIM}Confidence: ${(m.confidence * 100).toFixed(0)}% | Conditions: ${m.matchedConditions.join(', ')}${RESET}`);
275
+ }
276
+ //# sourceMappingURL=scan-handler.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scan-handler.js","sourceRoot":"","sources":["../../src/cli/scan-handler.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,18 @@
1
+ /**
2
+ * Standardized Threat Cloud pipeline commands.
3
+ *
4
+ * atr tc sync Push repo rules → TC (updates metrics + website)
5
+ * atr tc pull Pull confirmed TC rules → repo (validate + write)
6
+ * atr tc crystallize Send missed attacks → TC LLM → new proposals
7
+ * atr tc status Show TC state (rules, proposals, threats)
8
+ *
9
+ * All commands are idempotent and safe to run repeatedly.
10
+ * CI workflows call these same commands — no ad-hoc scripts.
11
+ *
12
+ * @module agent-threat-rules/cli/tc-pipeline
13
+ */
14
+ export declare function cmdTCSync(options: Record<string, string | undefined>): Promise<void>;
15
+ export declare function cmdTCPull(options: Record<string, string | undefined>): Promise<void>;
16
+ export declare function cmdTCCrystallize(options: Record<string, string | undefined>): Promise<void>;
17
+ export declare function cmdTCStatus(options: Record<string, string | undefined>): Promise<void>;
18
+ //# sourceMappingURL=tc-pipeline.d.ts.map