@bywaretech/bysentinel-core 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (71) hide show
  1. package/LICENSE +202 -0
  2. package/README.md +36 -0
  3. package/dist/analysis/analyzer.d.ts +27 -0
  4. package/dist/analysis/analyzer.d.ts.map +1 -0
  5. package/dist/analysis/analyzer.js +204 -0
  6. package/dist/analysis/analyzer.js.map +1 -0
  7. package/dist/analysis/prompt.d.ts +16 -0
  8. package/dist/analysis/prompt.d.ts.map +1 -0
  9. package/dist/analysis/prompt.js +74 -0
  10. package/dist/analysis/prompt.js.map +1 -0
  11. package/dist/analysis/validate.d.ts +14 -0
  12. package/dist/analysis/validate.d.ts.map +1 -0
  13. package/dist/analysis/validate.js +116 -0
  14. package/dist/analysis/validate.js.map +1 -0
  15. package/dist/fingerprint.d.ts +19 -0
  16. package/dist/fingerprint.d.ts.map +1 -0
  17. package/dist/fingerprint.js +42 -0
  18. package/dist/fingerprint.js.map +1 -0
  19. package/dist/index.d.ts +11 -0
  20. package/dist/index.d.ts.map +1 -0
  21. package/dist/index.js +17 -0
  22. package/dist/index.js.map +1 -0
  23. package/dist/providers/types.d.ts +51 -0
  24. package/dist/providers/types.d.ts.map +1 -0
  25. package/dist/providers/types.js +2 -0
  26. package/dist/providers/types.js.map +1 -0
  27. package/dist/redaction/entropy.d.ts +11 -0
  28. package/dist/redaction/entropy.d.ts.map +1 -0
  29. package/dist/redaction/entropy.js +35 -0
  30. package/dist/redaction/entropy.js.map +1 -0
  31. package/dist/redaction/index.d.ts +4 -0
  32. package/dist/redaction/index.d.ts.map +1 -0
  33. package/dist/redaction/index.js +4 -0
  34. package/dist/redaction/index.js.map +1 -0
  35. package/dist/redaction/patterns.d.ts +35 -0
  36. package/dist/redaction/patterns.d.ts.map +1 -0
  37. package/dist/redaction/patterns.js +198 -0
  38. package/dist/redaction/patterns.js.map +1 -0
  39. package/dist/redaction/redactor.d.ts +19 -0
  40. package/dist/redaction/redactor.d.ts.map +1 -0
  41. package/dist/redaction/redactor.js +120 -0
  42. package/dist/redaction/redactor.js.map +1 -0
  43. package/dist/security/signals.d.ts +12 -0
  44. package/dist/security/signals.d.ts.map +1 -0
  45. package/dist/security/signals.js +123 -0
  46. package/dist/security/signals.js.map +1 -0
  47. package/dist/timeline/timeline.d.ts +61 -0
  48. package/dist/timeline/timeline.d.ts.map +1 -0
  49. package/dist/timeline/timeline.js +90 -0
  50. package/dist/timeline/timeline.js.map +1 -0
  51. package/dist/types/analysis.d.ts +46 -0
  52. package/dist/types/analysis.d.ts.map +1 -0
  53. package/dist/types/analysis.js +3 -0
  54. package/dist/types/analysis.js.map +1 -0
  55. package/dist/types/config.d.ts +54 -0
  56. package/dist/types/config.d.ts.map +1 -0
  57. package/dist/types/config.js +18 -0
  58. package/dist/types/config.js.map +1 -0
  59. package/dist/types/event.d.ts +80 -0
  60. package/dist/types/event.d.ts.map +1 -0
  61. package/dist/types/event.js +6 -0
  62. package/dist/types/event.js.map +1 -0
  63. package/dist/types/index.d.ts +4 -0
  64. package/dist/types/index.d.ts.map +1 -0
  65. package/dist/types/index.js +4 -0
  66. package/dist/types/index.js.map +1 -0
  67. package/dist/util/id.d.ts +4 -0
  68. package/dist/util/id.d.ts.map +1 -0
  69. package/dist/util/id.js +9 -0
  70. package/dist/util/id.js.map +1 -0
  71. package/package.json +55 -0
@@ -0,0 +1,116 @@
1
+ const SEVERITIES = ["low", "medium", "high", "critical"];
2
+ const CATEGORIES = [
3
+ "bug",
4
+ "performance",
5
+ "security",
6
+ "dependency",
7
+ "configuration",
8
+ "external-service",
9
+ "unknown",
10
+ ];
11
+ /**
12
+ * Validate a model's JSON output before it is trusted/stored. Accepts a raw
13
+ * string (possibly wrapped in ```json fences) or an already-parsed object.
14
+ */
15
+ export function validateAnalysis(input) {
16
+ let obj = input;
17
+ if (typeof input === "string") {
18
+ const parsed = safeParse(input);
19
+ if (!parsed.ok)
20
+ return { ok: false, errors: [parsed.error] };
21
+ obj = parsed.value;
22
+ }
23
+ if (typeof obj !== "object" || obj === null) {
24
+ return { ok: false, errors: ["analysis is not an object"] };
25
+ }
26
+ const o = obj;
27
+ const errors = [];
28
+ const str = (k, required) => {
29
+ const v = o[k];
30
+ if (v === undefined) {
31
+ if (required)
32
+ errors.push(`${k} is required`);
33
+ return undefined;
34
+ }
35
+ if (typeof v !== "string")
36
+ errors.push(`${k} must be a string`);
37
+ return v;
38
+ };
39
+ str("summary", true);
40
+ str("likelyCause", true);
41
+ str("suggestedFix", true);
42
+ str("examplePatch", false);
43
+ str("confidenceReason", false);
44
+ if (!SEVERITIES.includes(o.severity)) {
45
+ errors.push(`severity must be one of ${SEVERITIES.join(", ")}`);
46
+ }
47
+ if (!CATEGORIES.includes(o.category)) {
48
+ errors.push(`category must be one of ${CATEGORIES.join(", ")}`);
49
+ }
50
+ if (typeof o.confidence !== "number" || o.confidence < 0 || o.confidence > 1) {
51
+ errors.push("confidence must be a number between 0 and 1");
52
+ }
53
+ if (o.affectedArea !== undefined) {
54
+ if (typeof o.affectedArea !== "object" || o.affectedArea === null) {
55
+ errors.push("affectedArea must be an object");
56
+ }
57
+ }
58
+ if (o.securityImpact !== undefined) {
59
+ const si = o.securityImpact;
60
+ if (typeof si !== "object" || si === null || typeof si.hasSensitiveDataRisk !== "boolean") {
61
+ errors.push("securityImpact.hasSensitiveDataRisk must be a boolean");
62
+ }
63
+ }
64
+ if (o.causalChain !== undefined) {
65
+ if (!Array.isArray(o.causalChain) ||
66
+ !o.causalChain.every((l) => l != null && typeof l.cause === "string")) {
67
+ errors.push("causalChain must be an array of { cause: string }");
68
+ }
69
+ }
70
+ if (o.bottleneck !== undefined) {
71
+ const b = o.bottleneck;
72
+ if (typeof b !== "object" || b === null || typeof b.step !== "string") {
73
+ errors.push("bottleneck.step must be a string");
74
+ }
75
+ }
76
+ if (errors.length)
77
+ return { ok: false, errors };
78
+ return { ok: true, value: obj };
79
+ }
80
+ function tryParse(candidate) {
81
+ try {
82
+ return { ok: true, value: JSON.parse(candidate) };
83
+ }
84
+ catch {
85
+ return { ok: false };
86
+ }
87
+ }
88
+ function safeParse(input) {
89
+ const trimmed = input.trim();
90
+ // 1. Direct parse first. This is the common case and, crucially, handles
91
+ // clean JSON whose string values contain their own ``` fenced code blocks
92
+ // (e.g. examplePatch with a ```javascript snippet). Stripping fences first
93
+ // would wrongly extract that inner block.
94
+ const direct = tryParse(trimmed);
95
+ if (direct.ok)
96
+ return direct;
97
+ // 2. The whole response is wrapped in a fence: ```json { ... } ``` — strip it
98
+ // only when the fence encloses the entire message (anchored), not when a
99
+ // fence merely appears somewhere inside.
100
+ const fenced = trimmed.match(/^```(?:json)?\s*([\s\S]*?)```$/i);
101
+ if (fenced?.[1]) {
102
+ const inner = tryParse(fenced[1].trim());
103
+ if (inner.ok)
104
+ return inner;
105
+ }
106
+ // 3. Last resort: grab the outermost {...}.
107
+ const start = trimmed.indexOf("{");
108
+ const end = trimmed.lastIndexOf("}");
109
+ if (start >= 0 && end > start) {
110
+ const obj = tryParse(trimmed.slice(start, end + 1));
111
+ if (obj.ok)
112
+ return obj;
113
+ }
114
+ return { ok: false, error: "response is not valid JSON" };
115
+ }
116
+ //# sourceMappingURL=validate.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"validate.js","sourceRoot":"","sources":["../../src/analysis/validate.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,19 @@
1
+ import type { ErrorInfo } from "./types/event.js";
2
+ export interface FingerprintInput {
3
+ project: string;
4
+ environment: string;
5
+ error?: Pick<ErrorInfo, "type" | "stack">;
6
+ functionName?: string;
7
+ }
8
+ /**
9
+ * Normalize a stack trace so semantically-identical errors hash the same:
10
+ * strips line/column numbers, absolute paths, hex addresses, uuids and digits
11
+ * that vary per invocation. Keeps the top frames' call sites.
12
+ */
13
+ export declare function normalizeStack(stack: string | undefined, maxFrames?: number): string;
14
+ /**
15
+ * Stable fingerprint:
16
+ * project + environment + error.type + normalized stack + function name
17
+ */
18
+ export declare function fingerprint(input: FingerprintInput): string;
19
+ //# sourceMappingURL=fingerprint.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fingerprint.d.ts","sourceRoot":"","sources":["../src/fingerprint.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAElD,MAAM,WAAW,gBAAgB;IAC/B,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,EAAE,MAAM,CAAC;IACpB,KAAK,CAAC,EAAE,IAAI,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,CAAC;IAC1C,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,EAAE,SAAS,SAAI,GAAG,MAAM,CAuB/E;AAED;;;GAGG;AACH,wBAAgB,WAAW,CAAC,KAAK,EAAE,gBAAgB,GAAG,MAAM,CAS3D"}
@@ -0,0 +1,42 @@
1
+ import { createHash } from "node:crypto";
2
+ /**
3
+ * Normalize a stack trace so semantically-identical errors hash the same:
4
+ * strips line/column numbers, absolute paths, hex addresses, uuids and digits
5
+ * that vary per invocation. Keeps the top frames' call sites.
6
+ */
7
+ export function normalizeStack(stack, maxFrames = 5) {
8
+ if (!stack)
9
+ return "";
10
+ const frames = stack
11
+ .split("\n")
12
+ .map((l) => l.trim())
13
+ .filter((l) => l.startsWith("at "));
14
+ const normalized = (frames.length ? frames : stack.split("\n"))
15
+ .slice(0, maxFrames)
16
+ .map((line) => line
17
+ .replace(/\(.*?\)/g, "") // drop file location parens
18
+ .replace(/[A-Za-z]:\\[^\s)]+|\/[^\s):]+/g, "") // drop paths
19
+ .replace(/:\d+:\d+/g, "") // line:col
20
+ .replace(/0x[0-9a-f]+/gi, "") // addresses
21
+ .replace(/[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}/gi, "") // uuid
22
+ .replace(/\d+/g, "") // remaining digits
23
+ .replace(/\s+/g, " ")
24
+ .trim())
25
+ .filter(Boolean);
26
+ return normalized.join(" | ");
27
+ }
28
+ /**
29
+ * Stable fingerprint:
30
+ * project + environment + error.type + normalized stack + function name
31
+ */
32
+ export function fingerprint(input) {
33
+ const parts = [
34
+ input.project,
35
+ input.environment,
36
+ input.error?.type ?? "unknown",
37
+ normalizeStack(input.error?.stack),
38
+ input.functionName ?? "",
39
+ ];
40
+ return createHash("sha256").update(parts.join("\n")).digest("hex").slice(0, 32);
41
+ }
42
+ //# sourceMappingURL=fingerprint.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fingerprint.js","sourceRoot":"","sources":["../src/fingerprint.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAUzC;;;;GAIG;AACH,MAAM,UAAU,cAAc,CAAC,KAAyB,EAAE,SAAS,GAAG,CAAC;IACrE,IAAI,CAAC,KAAK;QAAE,OAAO,EAAE,CAAC;IACtB,MAAM,MAAM,GAAG,KAAK;SACjB,KAAK,CAAC,IAAI,CAAC;SACX,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;SACpB,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC,CAAC;IAEtC,MAAM,UAAU,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;SAC5D,KAAK,CAAC,CAAC,EAAE,SAAS,CAAC;SACnB,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CACZ,IAAI;SACD,OAAO,CAAC,UAAU,EAAE,EAAE,CAAC,CAAC,4BAA4B;SACpD,OAAO,CAAC,gCAAgC,EAAE,EAAE,CAAC,CAAC,aAAa;SAC3D,OAAO,CAAC,WAAW,EAAE,EAAE,CAAC,CAAC,WAAW;SACpC,OAAO,CAAC,eAAe,EAAE,EAAE,CAAC,CAAC,YAAY;SACzC,OAAO,CAAC,gEAAgE,EAAE,EAAE,CAAC,CAAC,OAAO;SACrF,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,mBAAmB;SACvC,OAAO,CAAC,MAAM,EAAE,GAAG,CAAC;SACpB,IAAI,EAAE,CACV;SACA,MAAM,CAAC,OAAO,CAAC,CAAC;IAEnB,OAAO,UAAU,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;AAChC,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,WAAW,CAAC,KAAuB;IACjD,MAAM,KAAK,GAAG;QACZ,KAAK,CAAC,OAAO;QACb,KAAK,CAAC,WAAW;QACjB,KAAK,CAAC,KAAK,EAAE,IAAI,IAAI,SAAS;QAC9B,cAAc,CAAC,KAAK,CAAC,KAAK,EAAE,KAAK,CAAC;QAClC,KAAK,CAAC,YAAY,IAAI,EAAE;KACzB,CAAC;IACF,OAAO,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;AAClF,CAAC"}
@@ -0,0 +1,11 @@
1
+ export * from "./types/index.js";
2
+ export * from "./redaction/index.js";
3
+ export { detectSecuritySignals } from "./security/signals.js";
4
+ export { fingerprint, normalizeStack, type FingerprintInput } from "./fingerprint.js";
5
+ export { Timeline, type ExecutionTimeline, type TimelineStep, type TimelineStepStatus, type TimelineBottleneck, type TimelineOptions, } from "./timeline/timeline.js";
6
+ export { ANALYZER_SYSTEM_PROMPT, buildAnalysisUserPrompt, type BuildPromptOptions, } from "./analysis/prompt.js";
7
+ export { analyzeIncident, buildHeuristicAnalysis, type AnalyzeIncidentOptions, type HeuristicAnalysisOptions, } from "./analysis/analyzer.js";
8
+ export { validateAnalysis, type ValidationResult } from "./analysis/validate.js";
9
+ export type { AIProvider, AICompletionRequest, AICompletionResult, ProviderConfig, ProviderFactory, AnalyzeOutcome, } from "./providers/types.js";
10
+ export { newEventId, nowIso } from "./util/id.js";
11
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,cAAc,kBAAkB,CAAC;AAGjC,cAAc,sBAAsB,CAAC;AAGrC,OAAO,EAAE,qBAAqB,EAAE,MAAM,uBAAuB,CAAC;AAG9D,OAAO,EAAE,WAAW,EAAE,cAAc,EAAE,KAAK,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AAGtF,OAAO,EACL,QAAQ,EACR,KAAK,iBAAiB,EACtB,KAAK,YAAY,EACjB,KAAK,kBAAkB,EACvB,KAAK,kBAAkB,EACvB,KAAK,eAAe,GACrB,MAAM,wBAAwB,CAAC;AAGhC,OAAO,EACL,sBAAsB,EACtB,uBAAuB,EACvB,KAAK,kBAAkB,GACxB,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EACL,eAAe,EACf,sBAAsB,EACtB,KAAK,sBAAsB,EAC3B,KAAK,wBAAwB,GAC9B,MAAM,wBAAwB,CAAC;AAChC,OAAO,EAAE,gBAAgB,EAAE,KAAK,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAGjF,YAAY,EACV,UAAU,EACV,mBAAmB,EACnB,kBAAkB,EAClB,cAAc,EACd,eAAe,EACf,cAAc,GACf,MAAM,sBAAsB,CAAC;AAG9B,OAAO,EAAE,UAAU,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,17 @@
1
+ // Types
2
+ export * from "./types/index.js";
3
+ // Redaction / secret detection
4
+ export * from "./redaction/index.js";
5
+ // Security signal detection
6
+ export { detectSecuritySignals } from "./security/signals.js";
7
+ // Fingerprinting
8
+ export { fingerprint, normalizeStack } from "./fingerprint.js";
9
+ // Execution timeline / bottleneck
10
+ export { Timeline, } from "./timeline/timeline.js";
11
+ // AI analysis helpers
12
+ export { ANALYZER_SYSTEM_PROMPT, buildAnalysisUserPrompt, } from "./analysis/prompt.js";
13
+ export { analyzeIncident, buildHeuristicAnalysis, } from "./analysis/analyzer.js";
14
+ export { validateAnalysis } from "./analysis/validate.js";
15
+ // Utilities
16
+ export { newEventId, nowIso } from "./util/id.js";
17
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,QAAQ;AACR,cAAc,kBAAkB,CAAC;AAEjC,+BAA+B;AAC/B,cAAc,sBAAsB,CAAC;AAErC,4BAA4B;AAC5B,OAAO,EAAE,qBAAqB,EAAE,MAAM,uBAAuB,CAAC;AAE9D,iBAAiB;AACjB,OAAO,EAAE,WAAW,EAAE,cAAc,EAAyB,MAAM,kBAAkB,CAAC;AAEtF,kCAAkC;AAClC,OAAO,EACL,QAAQ,GAMT,MAAM,wBAAwB,CAAC;AAEhC,sBAAsB;AACtB,OAAO,EACL,sBAAsB,EACtB,uBAAuB,GAExB,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EACL,eAAe,EACf,sBAAsB,GAGvB,MAAM,wBAAwB,CAAC;AAChC,OAAO,EAAE,gBAAgB,EAAyB,MAAM,wBAAwB,CAAC;AAYjF,YAAY;AACZ,OAAO,EAAE,UAAU,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC"}
@@ -0,0 +1,51 @@
1
+ import type { AIAnalysisResult } from "../types/analysis.js";
2
+ export interface AICompletionRequest {
3
+ systemPrompt: string;
4
+ userPrompt: string;
5
+ model: string;
6
+ /** 0..1, lower is more deterministic. */
7
+ temperature?: number;
8
+ maxTokens?: number;
9
+ /** Ask the provider for JSON output when supported. */
10
+ jsonMode?: boolean;
11
+ signal?: AbortSignal;
12
+ }
13
+ export interface AICompletionResult {
14
+ /** Raw text returned by the model (still needs validation). */
15
+ content: string;
16
+ model: string;
17
+ usage?: {
18
+ promptTokens?: number;
19
+ completionTokens?: number;
20
+ };
21
+ }
22
+ /**
23
+ * Common surface every provider (OpenAI, OpenRouter, Anthropic, Ollama, custom)
24
+ * implements. Providers only do transport; JSON parsing/validation lives in the
25
+ * worker via `validateAnalysis`.
26
+ */
27
+ export interface AIProvider {
28
+ readonly name: string;
29
+ /** True for providers that run locally (Ollama/LM Studio). Used by strict mode. */
30
+ readonly isLocal: boolean;
31
+ complete(request: AICompletionRequest): Promise<AICompletionResult>;
32
+ }
33
+ export interface ProviderFactory {
34
+ (config: ProviderConfig): AIProvider;
35
+ }
36
+ export interface ProviderConfig {
37
+ apiKey?: string;
38
+ baseUrl?: string;
39
+ /** Provider-specific extras. */
40
+ [key: string]: unknown;
41
+ }
42
+ /** Result type helper the worker uses after validation. */
43
+ export interface AnalyzeOutcome {
44
+ raw: string;
45
+ analysis?: AIAnalysisResult;
46
+ errors?: string[];
47
+ provider?: string;
48
+ model?: string;
49
+ usage?: AICompletionResult["usage"];
50
+ }
51
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/providers/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AAE7D,MAAM,WAAW,mBAAmB;IAClC,YAAY,EAAE,MAAM,CAAC;IACrB,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,EAAE,MAAM,CAAC;IACd,yCAAyC;IACzC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,uDAAuD;IACvD,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,MAAM,CAAC,EAAE,WAAW,CAAC;CACtB;AAED,MAAM,WAAW,kBAAkB;IACjC,+DAA+D;IAC/D,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE;QAAE,YAAY,CAAC,EAAE,MAAM,CAAC;QAAC,gBAAgB,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;CAC9D;AAED;;;;GAIG;AACH,MAAM,WAAW,UAAU;IACzB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,mFAAmF;IACnF,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;IAC1B,QAAQ,CAAC,OAAO,EAAE,mBAAmB,GAAG,OAAO,CAAC,kBAAkB,CAAC,CAAC;CACrE;AAED,MAAM,WAAW,eAAe;IAC9B,CAAC,MAAM,EAAE,cAAc,GAAG,UAAU,CAAC;CACtC;AAED,MAAM,WAAW,cAAc;IAC7B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,gCAAgC;IAChC,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB;AAED,2DAA2D;AAC3D,MAAM,WAAW,cAAc;IAC7B,GAAG,EAAE,MAAM,CAAC;IACZ,QAAQ,CAAC,EAAE,gBAAgB,CAAC;IAC5B,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,kBAAkB,CAAC,OAAO,CAAC,CAAC;CACrC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/providers/types.ts"],"names":[],"mappings":""}
@@ -0,0 +1,11 @@
1
+ /** Shannon entropy in bits-per-character for a string. */
2
+ export declare function shannonEntropy(value: string): number;
3
+ /**
4
+ * Heuristic: does this token look like an opaque high-entropy secret?
5
+ * Tuned to avoid flagging normal words, sentences and hex ids that are short.
6
+ */
7
+ export declare function looksHighEntropy(value: string, { minLength, minEntropy }?: {
8
+ minLength?: number;
9
+ minEntropy?: number;
10
+ }): boolean;
11
+ //# sourceMappingURL=entropy.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"entropy.d.ts","sourceRoot":"","sources":["../../src/redaction/entropy.ts"],"names":[],"mappings":"AAAA,0DAA0D;AAC1D,wBAAgB,cAAc,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAWpD;AAID;;;GAGG;AACH,wBAAgB,gBAAgB,CAC9B,KAAK,EAAE,MAAM,EACb,EAAE,SAAc,EAAE,UAAgB,EAAE,GAAE;IAAE,SAAS,CAAC,EAAE,MAAM,CAAC;IAAC,UAAU,CAAC,EAAE,MAAM,CAAA;CAAO,GACrF,OAAO,CAYT"}
@@ -0,0 +1,35 @@
1
+ /** Shannon entropy in bits-per-character for a string. */
2
+ export function shannonEntropy(value) {
3
+ if (value.length === 0)
4
+ return 0;
5
+ const freq = new Map();
6
+ for (const ch of value)
7
+ freq.set(ch, (freq.get(ch) ?? 0) + 1);
8
+ let entropy = 0;
9
+ for (const count of freq.values()) {
10
+ const p = count / value.length;
11
+ entropy -= p * Math.log2(p);
12
+ }
13
+ return entropy;
14
+ }
15
+ const TOKEN_CHARS = /^[A-Za-z0-9+/_=.-]+$/;
16
+ /**
17
+ * Heuristic: does this token look like an opaque high-entropy secret?
18
+ * Tuned to avoid flagging normal words, sentences and hex ids that are short.
19
+ */
20
+ export function looksHighEntropy(value, { minLength = 24, minEntropy = 4.0 } = {}) {
21
+ const token = value.trim();
22
+ if (token.length < minLength)
23
+ return false;
24
+ if (!TOKEN_CHARS.test(token))
25
+ return false;
26
+ // Require a mix of character classes so long slugs/paths don't trip it.
27
+ const classes = Number(/[a-z]/.test(token)) +
28
+ Number(/[A-Z]/.test(token)) +
29
+ Number(/[0-9]/.test(token)) +
30
+ Number(/[+/_=.-]/.test(token));
31
+ if (classes < 2)
32
+ return false;
33
+ return shannonEntropy(token) >= minEntropy;
34
+ }
35
+ //# sourceMappingURL=entropy.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"entropy.js","sourceRoot":"","sources":["../../src/redaction/entropy.ts"],"names":[],"mappings":"AAAA,0DAA0D;AAC1D,MAAM,UAAU,cAAc,CAAC,KAAa;IAC1C,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,CAAC,CAAC;IACjC,MAAM,IAAI,GAAG,IAAI,GAAG,EAAkB,CAAC;IACvC,KAAK,MAAM,EAAE,IAAI,KAAK;QAAE,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;IAE9D,IAAI,OAAO,GAAG,CAAC,CAAC;IAChB,KAAK,MAAM,KAAK,IAAI,IAAI,CAAC,MAAM,EAAE,EAAE,CAAC;QAClC,MAAM,CAAC,GAAG,KAAK,GAAG,KAAK,CAAC,MAAM,CAAC;QAC/B,OAAO,IAAI,CAAC,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAC9B,CAAC;IACD,OAAO,OAAO,CAAC;AACjB,CAAC;AAED,MAAM,WAAW,GAAG,sBAAsB,CAAC;AAE3C;;;GAGG;AACH,MAAM,UAAU,gBAAgB,CAC9B,KAAa,EACb,EAAE,SAAS,GAAG,EAAE,EAAE,UAAU,GAAG,GAAG,KAAkD,EAAE;IAEtF,MAAM,KAAK,GAAG,KAAK,CAAC,IAAI,EAAE,CAAC;IAC3B,IAAI,KAAK,CAAC,MAAM,GAAG,SAAS;QAAE,OAAO,KAAK,CAAC;IAC3C,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,KAAK,CAAC;QAAE,OAAO,KAAK,CAAC;IAC3C,wEAAwE;IACxE,MAAM,OAAO,GACX,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QAC3B,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QAC3B,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QAC3B,MAAM,CAAC,UAAU,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC;IACjC,IAAI,OAAO,GAAG,CAAC;QAAE,OAAO,KAAK,CAAC;IAC9B,OAAO,cAAc,CAAC,KAAK,CAAC,IAAI,UAAU,CAAC;AAC7C,CAAC"}
@@ -0,0 +1,4 @@
1
+ export { redact, redactString, KEY_RULES, VALUE_PATTERNS } from "./redactor.js";
2
+ export { luhnValid, normalizeKey, keyRuleFor, type RedactionCategory } from "./patterns.js";
3
+ export { shannonEntropy, looksHighEntropy } from "./entropy.js";
4
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/redaction/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,YAAY,EAAE,SAAS,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAChF,OAAO,EAAE,SAAS,EAAE,YAAY,EAAE,UAAU,EAAE,KAAK,iBAAiB,EAAE,MAAM,eAAe,CAAC;AAC5F,OAAO,EAAE,cAAc,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC"}
@@ -0,0 +1,4 @@
1
+ export { redact, redactString, KEY_RULES, VALUE_PATTERNS } from "./redactor.js";
2
+ export { luhnValid, normalizeKey, keyRuleFor } from "./patterns.js";
3
+ export { shannonEntropy, looksHighEntropy } from "./entropy.js";
4
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/redaction/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,YAAY,EAAE,SAAS,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAChF,OAAO,EAAE,SAAS,EAAE,YAAY,EAAE,UAAU,EAA0B,MAAM,eAAe,CAAC;AAC5F,OAAO,EAAE,cAAc,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC"}
@@ -0,0 +1,35 @@
1
+ /**
2
+ * Value- and key-based redaction rules.
3
+ *
4
+ * Ordering matters: more specific patterns must run before generic ones
5
+ * (e.g. `sk-ant-` before `sk-`, JWT before Bearer). The redactor applies
6
+ * `VALUE_PATTERNS` in array order.
7
+ */
8
+ export type RedactionCategory = "pii" | "secret" | "payment" | "email" | "phone";
9
+ export interface ValuePattern {
10
+ name: string;
11
+ category: RedactionCategory;
12
+ regex: RegExp;
13
+ replacement: string;
14
+ /** Optional guard: return false to keep the original match. */
15
+ validate?: (match: string) => boolean;
16
+ }
17
+ /** Luhn checksum used to avoid redacting arbitrary 16-digit numbers. */
18
+ export declare function luhnValid(digits: string): boolean;
19
+ /**
20
+ * Applied in order. All regexes are global so `String.replace` hits every match.
21
+ */
22
+ export declare const VALUE_PATTERNS: ValuePattern[];
23
+ /**
24
+ * Key-name rules. Keys are normalized (lowercased, non-alphanumerics stripped)
25
+ * before matching so `card_number`, `cardNumber` and `card-number` all match.
26
+ */
27
+ export interface KeyRule {
28
+ keys: string[];
29
+ category: RedactionCategory;
30
+ replacement: string;
31
+ }
32
+ export declare const KEY_RULES: KeyRule[];
33
+ export declare function normalizeKey(key: string): string;
34
+ export declare function keyRuleFor(key: string): KeyRule | undefined;
35
+ //# sourceMappingURL=patterns.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"patterns.d.ts","sourceRoot":"","sources":["../../src/redaction/patterns.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,MAAM,MAAM,iBAAiB,GAAG,KAAK,GAAG,QAAQ,GAAG,SAAS,GAAG,OAAO,GAAG,OAAO,CAAC;AAEjF,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,iBAAiB,CAAC;IAC5B,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,MAAM,CAAC;IACpB,+DAA+D;IAC/D,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,OAAO,CAAC;CACvC;AAED,wEAAwE;AACxE,wBAAgB,SAAS,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAejD;AAED;;GAEG;AACH,eAAO,MAAM,cAAc,EAAE,YAAY,EAkHxC,CAAC;AAEF;;;GAGG;AACH,MAAM,WAAW,OAAO;IACtB,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,QAAQ,EAAE,iBAAiB,CAAC;IAC5B,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,eAAO,MAAM,SAAS,EAAE,OAAO,EA6C9B,CAAC;AAEF,wBAAgB,YAAY,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAEhD;AAOD,wBAAgB,UAAU,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,GAAG,SAAS,CAE3D"}
@@ -0,0 +1,198 @@
1
+ /**
2
+ * Value- and key-based redaction rules.
3
+ *
4
+ * Ordering matters: more specific patterns must run before generic ones
5
+ * (e.g. `sk-ant-` before `sk-`, JWT before Bearer). The redactor applies
6
+ * `VALUE_PATTERNS` in array order.
7
+ */
8
+ /** Luhn checksum used to avoid redacting arbitrary 16-digit numbers. */
9
+ export function luhnValid(digits) {
10
+ const num = digits.replace(/\D/g, "");
11
+ if (num.length < 13 || num.length > 19)
12
+ return false;
13
+ let sum = 0;
14
+ let alt = false;
15
+ for (let i = num.length - 1; i >= 0; i--) {
16
+ let d = num.charCodeAt(i) - 48;
17
+ if (alt) {
18
+ d *= 2;
19
+ if (d > 9)
20
+ d -= 9;
21
+ }
22
+ sum += d;
23
+ alt = !alt;
24
+ }
25
+ return sum % 10 === 0;
26
+ }
27
+ /**
28
+ * Applied in order. All regexes are global so `String.replace` hits every match.
29
+ */
30
+ export const VALUE_PATTERNS = [
31
+ // ── Secrets (most specific first) ─────────────────────────────
32
+ {
33
+ name: "private-key",
34
+ category: "secret",
35
+ regex: /-----BEGIN (?:RSA |EC |DSA |OPENSSH |PGP |ENCRYPTED )?PRIVATE KEY-----[\s\S]*?-----END (?:RSA |EC |DSA |OPENSSH |PGP |ENCRYPTED )?PRIVATE KEY-----/g,
36
+ replacement: "[REDACTED_PRIVATE_KEY]",
37
+ },
38
+ {
39
+ name: "jwt",
40
+ category: "secret",
41
+ regex: /eyJ[A-Za-z0-9_-]+\.eyJ[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+/g,
42
+ replacement: "[REDACTED_JWT]",
43
+ },
44
+ {
45
+ name: "bearer-token",
46
+ category: "secret",
47
+ regex: /Bearer\s+[A-Za-z0-9\-._~+/]+=*/gi,
48
+ replacement: "[REDACTED_BEARER_TOKEN]",
49
+ },
50
+ {
51
+ name: "basic-auth",
52
+ category: "secret",
53
+ regex: /Basic\s+[A-Za-z0-9+/]+=*/g,
54
+ replacement: "[REDACTED_BASIC_AUTH]",
55
+ },
56
+ {
57
+ name: "aws-access-key-id",
58
+ category: "secret",
59
+ regex: /\b(?:AKIA|ASIA|AIDA|AROA)[0-9A-Z]{16}\b/g,
60
+ replacement: "[REDACTED_AWS_ACCESS_KEY_ID]",
61
+ },
62
+ {
63
+ name: "github-token",
64
+ category: "secret",
65
+ regex: /\bgh[pousr]_[A-Za-z0-9]{36,255}\b/g,
66
+ replacement: "[REDACTED_GITHUB_TOKEN]",
67
+ },
68
+ {
69
+ name: "gitlab-token",
70
+ category: "secret",
71
+ regex: /\bglpat-[A-Za-z0-9_-]{20,}\b/g,
72
+ replacement: "[REDACTED_GITLAB_TOKEN]",
73
+ },
74
+ {
75
+ name: "slack-token",
76
+ category: "secret",
77
+ regex: /\bxox[baprs]-[A-Za-z0-9-]{10,}\b/g,
78
+ replacement: "[REDACTED_SLACK_TOKEN]",
79
+ },
80
+ {
81
+ name: "stripe-key",
82
+ category: "secret",
83
+ regex: /\b(?:sk|rk|pk)_(?:live|test)_[A-Za-z0-9]{16,}\b/g,
84
+ replacement: "[REDACTED_STRIPE_KEY]",
85
+ },
86
+ {
87
+ name: "anthropic-key",
88
+ category: "secret",
89
+ regex: /\bsk-ant-[A-Za-z0-9_-]{20,}\b/g,
90
+ replacement: "[REDACTED_ANTHROPIC_KEY]",
91
+ },
92
+ {
93
+ name: "openai-key",
94
+ category: "secret",
95
+ regex: /\bsk-(?:proj-)?[A-Za-z0-9_-]{20,}\b/g,
96
+ replacement: "[REDACTED_OPENAI_KEY]",
97
+ },
98
+ {
99
+ name: "database-url",
100
+ category: "secret",
101
+ regex: /\b(?:postgres(?:ql)?|mysql|mongodb(?:\+srv)?|redis|rediss|amqp):\/\/[^\s"'<>]+/gi,
102
+ replacement: "[REDACTED_DATABASE_URL]",
103
+ },
104
+ // ── Payment ───────────────────────────────────────────────────
105
+ {
106
+ name: "credit-card",
107
+ category: "payment",
108
+ // 13–19 digits optionally grouped by spaces or dashes.
109
+ regex: /\b(?:\d[ -]?){13,19}\b/g,
110
+ replacement: "[REDACTED_CARD]",
111
+ validate: luhnValid,
112
+ },
113
+ // ── PII (Brazil-focused + general) ────────────────────────────
114
+ {
115
+ name: "cnpj",
116
+ category: "pii",
117
+ regex: /\b\d{2}\.?\d{3}\.?\d{3}\/?\d{4}-?\d{2}\b/g,
118
+ replacement: "[REDACTED_CNPJ]",
119
+ },
120
+ {
121
+ name: "cpf",
122
+ category: "pii",
123
+ regex: /\b\d{3}\.\d{3}\.\d{3}-\d{2}\b/g,
124
+ replacement: "[REDACTED_CPF]",
125
+ },
126
+ // ── Contact info (toggled separately) ─────────────────────────
127
+ {
128
+ name: "email",
129
+ category: "email",
130
+ regex: /\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,}\b/g,
131
+ replacement: "[REDACTED_EMAIL]",
132
+ },
133
+ {
134
+ name: "phone-br",
135
+ category: "phone",
136
+ // +55 (11) 91234-5678 and common variants.
137
+ regex: /\b(?:\+?55\s?)?(?:\(?\d{2}\)?[\s.-]?)?9?\d{4}[\s.-]?\d{4}\b/g,
138
+ replacement: "[REDACTED_PHONE]",
139
+ },
140
+ ];
141
+ export const KEY_RULES = [
142
+ { keys: ["password", "passwd", "pwd"], category: "secret", replacement: "[REDACTED_PASSWORD]" },
143
+ {
144
+ keys: ["authorization", "authtoken", "accesstoken", "refreshtoken", "idtoken"],
145
+ category: "secret",
146
+ replacement: "[REDACTED_AUTHORIZATION]",
147
+ },
148
+ { keys: ["cookie", "setcookie"], category: "secret", replacement: "[REDACTED_COOKIE]" },
149
+ {
150
+ keys: ["sessionid", "session", "sid"],
151
+ category: "secret",
152
+ replacement: "[REDACTED_SESSION_ID]",
153
+ },
154
+ {
155
+ keys: ["apikey", "secret", "clientsecret", "token", "webhooksecret", "privatekey"],
156
+ category: "secret",
157
+ replacement: "[REDACTED_SECRET]",
158
+ },
159
+ {
160
+ keys: ["awssecretaccesskey", "awssecretkey", "awssessiontoken"],
161
+ category: "secret",
162
+ replacement: "[REDACTED_AWS_SECRET]",
163
+ },
164
+ {
165
+ keys: ["databaseurl", "connectionstring", "dburl"],
166
+ category: "secret",
167
+ replacement: "[REDACTED_DATABASE_URL]",
168
+ },
169
+ // PII
170
+ { keys: ["cpf"], category: "pii", replacement: "[REDACTED_CPF]" },
171
+ { keys: ["cnpj"], category: "pii", replacement: "[REDACTED_CNPJ]" },
172
+ { keys: ["rg"], category: "pii", replacement: "[REDACTED_RG]" },
173
+ { keys: ["passport", "passaporte"], category: "pii", replacement: "[REDACTED_PASSPORT]" },
174
+ {
175
+ keys: ["bankaccount", "accountnumber", "iban", "agencia", "conta"],
176
+ category: "pii",
177
+ replacement: "[REDACTED_BANK_ACCOUNT]",
178
+ },
179
+ // Payment
180
+ { keys: ["cardnumber", "pan", "ccnumber"], category: "payment", replacement: "[REDACTED_CARD]" },
181
+ { keys: ["cvv", "cvc", "securitycode"], category: "payment", replacement: "[REDACTED_CVV]" },
182
+ { keys: ["pixkey", "pix"], category: "payment", replacement: "[REDACTED_PIX_KEY]" },
183
+ // Contact
184
+ { keys: ["email", "mail"], category: "email", replacement: "[REDACTED_EMAIL]" },
185
+ { keys: ["phone", "telefone", "celular", "mobile"], category: "phone", replacement: "[REDACTED_PHONE]" },
186
+ ];
187
+ export function normalizeKey(key) {
188
+ return key.toLowerCase().replace(/[^a-z0-9]/g, "");
189
+ }
190
+ const KEY_LOOKUP = new Map();
191
+ for (const rule of KEY_RULES) {
192
+ for (const k of rule.keys)
193
+ KEY_LOOKUP.set(k, rule);
194
+ }
195
+ export function keyRuleFor(key) {
196
+ return KEY_LOOKUP.get(normalizeKey(key));
197
+ }
198
+ //# sourceMappingURL=patterns.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"patterns.js","sourceRoot":"","sources":["../../src/redaction/patterns.ts"],"names":[],"mappings":"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"}