@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,19 @@
1
+ import type { RedactionOptions } from "../types/config.js";
2
+ import { KEY_RULES, VALUE_PATTERNS } from "./patterns.js";
3
+ /**
4
+ * Redact sensitive substrings inside a single string value.
5
+ *
6
+ * `applyHighEntropyFallback` (default true) controls the generic opaque-token
7
+ * guess. Named secret/PII patterns always run. Callers pass `false` for known
8
+ * structured-metadata fields (see `LOW_ENTROPY_METADATA_KEYS`).
9
+ */
10
+ export declare function redactString(input: string, options?: RedactionOptions, applyHighEntropyFallback?: boolean): string;
11
+ /**
12
+ * Deep-redact an arbitrary value (object/array/scalar). Keys matching a
13
+ * `KeyRule` have their whole value replaced; remaining strings are scanned for
14
+ * embedded secrets/PII. Handles cycles and depth/size limits.
15
+ */
16
+ export declare function redact<T>(value: T, options?: RedactionOptions): T;
17
+ /** Convenience re-exports for consumers building custom flows. */
18
+ export { KEY_RULES, VALUE_PATTERNS };
19
+ //# sourceMappingURL=redactor.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"redactor.d.ts","sourceRoot":"","sources":["../../src/redaction/redactor.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAE3D,OAAO,EACL,SAAS,EACT,cAAc,EAIf,MAAM,eAAe,CAAC;AA4CvB;;;;;;GAMG;AACH,wBAAgB,YAAY,CAC1B,KAAK,EAAE,MAAM,EACb,OAAO,GAAE,gBAAqB,EAC9B,wBAAwB,UAAO,GAC9B,MAAM,CAmBR;AASD;;;;GAIG;AACH,wBAAgB,MAAM,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,OAAO,GAAE,gBAAqB,GAAG,CAAC,CAIrE;AA6CD,kEAAkE;AAClE,OAAO,EAAE,SAAS,EAAE,cAAc,EAAE,CAAC"}
@@ -0,0 +1,120 @@
1
+ import { looksHighEntropy } from "./entropy.js";
2
+ import { KEY_RULES, VALUE_PATTERNS, keyRuleFor, } from "./patterns.js";
3
+ const DEFAULTS = {
4
+ redactPII: true,
5
+ redactSecrets: true,
6
+ redactPaymentData: true,
7
+ redactEmails: true,
8
+ redactPhones: true,
9
+ maxDepth: 12,
10
+ maxStringLength: 20_000,
11
+ };
12
+ /**
13
+ * Structured deploy metadata: repository URLs, commit hashes, versions. Named
14
+ * secret/PII patterns still run on these; only the generic high-entropy
15
+ * fallback is skipped, so a plain `https://github.com/org/repo` or a 40-char
16
+ * commit SHA is not mistaken for an opaque token and wiped out.
17
+ */
18
+ const LOW_ENTROPY_METADATA_KEYS = new Set([
19
+ "repositoryUrl",
20
+ "commitSha",
21
+ "branch",
22
+ "version",
23
+ "release",
24
+ "buildTimestamp",
25
+ "requestId",
26
+ "functionName",
27
+ ]);
28
+ function categoryEnabled(cat, opts) {
29
+ switch (cat) {
30
+ case "pii":
31
+ return opts.redactPII;
32
+ case "secret":
33
+ return opts.redactSecrets;
34
+ case "payment":
35
+ return opts.redactPaymentData;
36
+ case "email":
37
+ return opts.redactEmails;
38
+ case "phone":
39
+ return opts.redactPhones;
40
+ }
41
+ }
42
+ /**
43
+ * Redact sensitive substrings inside a single string value.
44
+ *
45
+ * `applyHighEntropyFallback` (default true) controls the generic opaque-token
46
+ * guess. Named secret/PII patterns always run. Callers pass `false` for known
47
+ * structured-metadata fields (see `LOW_ENTROPY_METADATA_KEYS`).
48
+ */
49
+ export function redactString(input, options = {}, applyHighEntropyFallback = true) {
50
+ const opts = { ...DEFAULTS, ...options };
51
+ let value = input.length > opts.maxStringLength ? input.slice(0, opts.maxStringLength) : input;
52
+ for (const pattern of VALUE_PATTERNS) {
53
+ if (!categoryEnabled(pattern.category, opts))
54
+ continue;
55
+ value = applyPattern(value, pattern);
56
+ }
57
+ // Generic high-entropy fallback for opaque secrets that no named rule caught.
58
+ if (opts.redactSecrets && applyHighEntropyFallback) {
59
+ value = value.replace(/[A-Za-z0-9+/_=.-]{24,}/g, (token) => token.startsWith("[REDACTED") || !looksHighEntropy(token)
60
+ ? token
61
+ : "[REDACTED_HIGH_ENTROPY]");
62
+ }
63
+ return value;
64
+ }
65
+ function applyPattern(value, pattern) {
66
+ pattern.regex.lastIndex = 0;
67
+ return value.replace(pattern.regex, (match) => pattern.validate && !pattern.validate(match) ? match : pattern.replacement);
68
+ }
69
+ /**
70
+ * Deep-redact an arbitrary value (object/array/scalar). Keys matching a
71
+ * `KeyRule` have their whole value replaced; remaining strings are scanned for
72
+ * embedded secrets/PII. Handles cycles and depth/size limits.
73
+ */
74
+ export function redact(value, options = {}) {
75
+ const opts = { ...DEFAULTS, ...options };
76
+ const seen = new WeakSet();
77
+ return walk(value, opts, seen, 0);
78
+ }
79
+ function walk(value, opts, seen, depth) {
80
+ if (value == null)
81
+ return value;
82
+ if (typeof value === "string")
83
+ return redactString(value, opts);
84
+ if (typeof value === "number" || typeof value === "boolean" || typeof value === "bigint") {
85
+ return value;
86
+ }
87
+ if (depth >= opts.maxDepth)
88
+ return "[REDACTED_MAX_DEPTH]";
89
+ if (Array.isArray(value)) {
90
+ if (seen.has(value))
91
+ return "[REDACTED_CIRCULAR]";
92
+ seen.add(value);
93
+ return value.map((item) => walk(item, opts, seen, depth + 1));
94
+ }
95
+ if (typeof value === "object") {
96
+ if (seen.has(value))
97
+ return "[REDACTED_CIRCULAR]";
98
+ seen.add(value);
99
+ const out = {};
100
+ for (const [key, child] of Object.entries(value)) {
101
+ const rule = keyRuleFor(key);
102
+ if (rule && categoryEnabled(rule.category, opts)) {
103
+ out[key] = rule.replacement;
104
+ }
105
+ else if (typeof child === "string" && LOW_ENTROPY_METADATA_KEYS.has(key)) {
106
+ // Structured metadata: keep named-pattern redaction, skip the entropy guess.
107
+ out[key] = redactString(child, opts, false);
108
+ }
109
+ else {
110
+ out[key] = walk(child, opts, seen, depth + 1);
111
+ }
112
+ }
113
+ return out;
114
+ }
115
+ // functions, symbols, etc. are dropped.
116
+ return "[REDACTED_UNSUPPORTED]";
117
+ }
118
+ /** Convenience re-exports for consumers building custom flows. */
119
+ export { KEY_RULES, VALUE_PATTERNS };
120
+ //# sourceMappingURL=redactor.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"redactor.js","sourceRoot":"","sources":["../../src/redaction/redactor.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,12 @@
1
+ import type { RequestInfo, ErrorInfo, SecuritySignal } from "../types/event.js";
2
+ interface DetectInput {
3
+ request?: RequestInfo;
4
+ error?: ErrorInfo;
5
+ }
6
+ /**
7
+ * Scan (pre-redaction) request/error data for attack indicators and accidental
8
+ * secret exposure. Returns signals with descriptions only — never raw values.
9
+ */
10
+ export declare function detectSecuritySignals(input: DetectInput): SecuritySignal[];
11
+ export {};
12
+ //# sourceMappingURL=signals.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"signals.d.ts","sourceRoot":"","sources":["../../src/security/signals.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,SAAS,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AAGhF,UAAU,WAAW;IACnB,OAAO,CAAC,EAAE,WAAW,CAAC;IACtB,KAAK,CAAC,EAAE,SAAS,CAAC;CACnB;AA2BD;;;GAGG;AACH,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,WAAW,GAAG,cAAc,EAAE,CA6F1E"}
@@ -0,0 +1,123 @@
1
+ import { VALUE_PATTERNS } from "../redaction/patterns.js";
2
+ const SUSPICIOUS_UA = /\b(sqlmap|nikto|nmap|masscan|acunetix|nessus|dirbuster|gobuster|wpscan|havij|hydra)\b/i;
3
+ const SQL_ERROR = /\b(sql syntax|syntax error at or near|unclosed quotation mark|ora-\d{5}|pg_query|mysqli?_|sqlstate|unterminated quoted string|column .* does not exist)\b/i;
4
+ const COMMAND_INJECTION = /(;|\||&&|`|\$\(|\|\||>\s*\/|<\s*\/)\s*(cat|ls|rm|curl|wget|bash|sh|nc|whoami|id)\b/i;
5
+ const PATH_TRAVERSAL = /(\.\.\/|\.\.\\|%2e%2e%2f|%2e%2e\/|\/etc\/passwd|\/proc\/self)/i;
6
+ // Private ranges + AWS/GCP metadata endpoints commonly hit by SSRF.
7
+ const SSRF_URL = /https?:\/\/(?:127\.0\.0\.1|localhost|0\.0\.0\.0|169\.254\.169\.254|metadata\.google\.internal|10\.\d{1,3}\.\d{1,3}\.\d{1,3}|192\.168\.\d{1,3}\.\d{1,3}|172\.(?:1[6-9]|2\d|3[01])\.\d{1,3}\.\d{1,3})/i;
8
+ const SECRET_PATTERNS = VALUE_PATTERNS.filter((p) => p.category === "secret");
9
+ function flatten(value, out, depth = 0) {
10
+ if (depth > 8 || value == null)
11
+ return;
12
+ if (typeof value === "string")
13
+ out.push(value);
14
+ else if (Array.isArray(value))
15
+ value.forEach((v) => flatten(v, out, depth + 1));
16
+ else if (typeof value === "object") {
17
+ for (const v of Object.values(value))
18
+ flatten(v, out, depth + 1);
19
+ }
20
+ }
21
+ /**
22
+ * Scan (pre-redaction) request/error data for attack indicators and accidental
23
+ * secret exposure. Returns signals with descriptions only — never raw values.
24
+ */
25
+ export function detectSecuritySignals(input) {
26
+ const signals = [];
27
+ const { request, error } = input;
28
+ const bodyStrings = [];
29
+ flatten(request?.body, bodyStrings);
30
+ flatten(request?.query, bodyStrings);
31
+ const headerStrings = [];
32
+ flatten(request?.headers, headerStrings);
33
+ const allInput = [...bodyStrings, ...headerStrings];
34
+ // Accidental secret in body/headers.
35
+ for (const pattern of SECRET_PATTERNS) {
36
+ if (bodyStrings.some((s) => testOnce(pattern.regex, s))) {
37
+ signals.push({
38
+ type: "sensitive-data-in-body",
39
+ severity: "high",
40
+ message: `Possible ${pattern.name} present in request body`,
41
+ location: "request.body",
42
+ });
43
+ break;
44
+ }
45
+ }
46
+ for (const pattern of SECRET_PATTERNS) {
47
+ if (headerStrings.some((s) => testOnce(pattern.regex, s)) &&
48
+ pattern.name !== "bearer-token" &&
49
+ pattern.name !== "basic-auth") {
50
+ signals.push({
51
+ type: "secret-in-log",
52
+ severity: "high",
53
+ message: `Possible ${pattern.name} present in request headers`,
54
+ location: "request.headers",
55
+ });
56
+ break;
57
+ }
58
+ }
59
+ const ua = getHeader(request?.headers, "user-agent");
60
+ if (ua && SUSPICIOUS_UA.test(ua)) {
61
+ signals.push({
62
+ type: "suspicious-user-agent",
63
+ severity: "medium",
64
+ message: "Request user-agent matches a known scanning tool",
65
+ location: "request.headers.user-agent",
66
+ });
67
+ }
68
+ if (request?.path && /\/(admin|internal|_debug|actuator)\b/i.test(request.path)) {
69
+ signals.push({
70
+ type: "admin-route-access",
71
+ severity: "medium",
72
+ message: "Access to an administrative/internal route",
73
+ location: "request.path",
74
+ });
75
+ }
76
+ if (error?.message && SQL_ERROR.test(error.message)) {
77
+ signals.push({
78
+ type: "sql-error-leakage",
79
+ severity: "high",
80
+ message: "Database error text leaked in the error message",
81
+ location: "error.message",
82
+ });
83
+ }
84
+ if (allInput.some((s) => COMMAND_INJECTION.test(s))) {
85
+ signals.push({
86
+ type: "command-injection",
87
+ severity: "critical",
88
+ message: "Input contains shell command-injection patterns",
89
+ location: "request",
90
+ });
91
+ }
92
+ if (allInput.some((s) => PATH_TRAVERSAL.test(s))) {
93
+ signals.push({
94
+ type: "path-traversal",
95
+ severity: "high",
96
+ message: "Input contains path-traversal sequences",
97
+ location: "request",
98
+ });
99
+ }
100
+ if (allInput.some((s) => SSRF_URL.test(s))) {
101
+ signals.push({
102
+ type: "ssrf-like-url",
103
+ severity: "high",
104
+ message: "Input references an internal/metadata URL (possible SSRF)",
105
+ location: "request",
106
+ });
107
+ }
108
+ return signals;
109
+ }
110
+ function testOnce(regex, value) {
111
+ regex.lastIndex = 0;
112
+ return regex.test(value);
113
+ }
114
+ function getHeader(headers, name) {
115
+ if (!headers)
116
+ return undefined;
117
+ for (const [k, v] of Object.entries(headers)) {
118
+ if (k.toLowerCase() === name && typeof v === "string")
119
+ return v;
120
+ }
121
+ return undefined;
122
+ }
123
+ //# sourceMappingURL=signals.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"signals.js","sourceRoot":"","sources":["../../src/security/signals.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,61 @@
1
+ /**
2
+ * Execution timeline: a lightweight sequential span recorder.
3
+ *
4
+ * `step(name)` closes the previous running step and opens a new one, so the
5
+ * duration of a step is the wall-clock time until the next `step()`/`finish()`.
6
+ * This matches the roadmap's dashboard model (per-step ms + a single bottleneck)
7
+ * and, because each step carries an absolute timestamp, it doubles as the
8
+ * chronological "incident timeline".
9
+ */
10
+ export type TimelineStepStatus = "completed" | "running" | "failed";
11
+ export interface TimelineStep {
12
+ name: string;
13
+ /** Absolute ISO time the step started. */
14
+ startedAt: string;
15
+ /** Milliseconds from the timeline start to this step's start. */
16
+ startOffsetMs: number;
17
+ /** Filled once the step is closed. */
18
+ durationMs?: number;
19
+ status: TimelineStepStatus;
20
+ meta?: Record<string, unknown>;
21
+ }
22
+ export interface TimelineBottleneck {
23
+ name: string;
24
+ durationMs: number;
25
+ /** Share of the total timeline duration, 0..100. */
26
+ percentOfTotal: number;
27
+ }
28
+ export interface ExecutionTimeline {
29
+ startedAt: string;
30
+ totalMs: number;
31
+ steps: TimelineStep[];
32
+ bottleneck?: TimelineBottleneck;
33
+ /** True when the timeline was finalized abnormally (error/timeout). */
34
+ aborted: boolean;
35
+ }
36
+ export interface TimelineOptions {
37
+ /** Injectable monotonic-ish clock for tests. Defaults to `Date.now`. */
38
+ clock?: () => number;
39
+ }
40
+ export declare class Timeline {
41
+ private readonly clock;
42
+ private readonly startMs;
43
+ private readonly startedAtIso;
44
+ private readonly steps;
45
+ private finalized;
46
+ constructor(options?: TimelineOptions);
47
+ /** Open a new step, closing any currently running one. */
48
+ step(name: string, meta?: Record<string, unknown>): this;
49
+ /** Attach metadata to the currently running step. */
50
+ annotate(meta: Record<string, unknown>): this;
51
+ /** Mark the running step as failed (used on exception/timeout). */
52
+ fail(meta?: Record<string, unknown>): this;
53
+ /** Close the timeline and return the immutable snapshot. Idempotent. */
54
+ finish(status?: "completed" | "failed"): ExecutionTimeline;
55
+ /** Snapshot without finalizing (for capturing mid-flight, e.g. on error). */
56
+ toJSON(aborted?: boolean): ExecutionTimeline;
57
+ get hasSteps(): boolean;
58
+ private closeRunning;
59
+ private snapshot;
60
+ }
61
+ //# sourceMappingURL=timeline.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"timeline.d.ts","sourceRoot":"","sources":["../../src/timeline/timeline.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,MAAM,MAAM,kBAAkB,GAAG,WAAW,GAAG,SAAS,GAAG,QAAQ,CAAC;AAEpE,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,0CAA0C;IAC1C,SAAS,EAAE,MAAM,CAAC;IAClB,iEAAiE;IACjE,aAAa,EAAE,MAAM,CAAC;IACtB,sCAAsC;IACtC,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,kBAAkB,CAAC;IAC3B,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAChC;AAED,MAAM,WAAW,kBAAkB;IACjC,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,EAAE,MAAM,CAAC;IACnB,oDAAoD;IACpD,cAAc,EAAE,MAAM,CAAC;CACxB;AAED,MAAM,WAAW,iBAAiB;IAChC,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,YAAY,EAAE,CAAC;IACtB,UAAU,CAAC,EAAE,kBAAkB,CAAC;IAChC,uEAAuE;IACvE,OAAO,EAAE,OAAO,CAAC;CAClB;AAED,MAAM,WAAW,eAAe;IAC9B,wEAAwE;IACxE,KAAK,CAAC,EAAE,MAAM,MAAM,CAAC;CACtB;AAED,qBAAa,QAAQ;IACnB,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAe;IACrC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;IACjC,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAS;IACtC,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAsB;IAC5C,OAAO,CAAC,SAAS,CAAS;gBAEd,OAAO,GAAE,eAAoB;IAMzC,0DAA0D;IAC1D,IAAI,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI;IAaxD,qDAAqD;IACrD,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI;IAQ7C,mEAAmE;IACnE,IAAI,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI;IAO1C,wEAAwE;IACxE,MAAM,CAAC,MAAM,GAAE,WAAW,GAAG,QAAsB,GAAG,iBAAiB;IAOvE,6EAA6E;IAC7E,MAAM,CAAC,OAAO,UAAQ,GAAG,iBAAiB;IAK1C,IAAI,QAAQ,IAAI,OAAO,CAEtB;IAED,OAAO,CAAC,YAAY;IAQpB,OAAO,CAAC,QAAQ;CAkBjB"}
@@ -0,0 +1,90 @@
1
+ /**
2
+ * Execution timeline: a lightweight sequential span recorder.
3
+ *
4
+ * `step(name)` closes the previous running step and opens a new one, so the
5
+ * duration of a step is the wall-clock time until the next `step()`/`finish()`.
6
+ * This matches the roadmap's dashboard model (per-step ms + a single bottleneck)
7
+ * and, because each step carries an absolute timestamp, it doubles as the
8
+ * chronological "incident timeline".
9
+ */
10
+ export class Timeline {
11
+ clock;
12
+ startMs;
13
+ startedAtIso;
14
+ steps = [];
15
+ finalized = false;
16
+ constructor(options = {}) {
17
+ this.clock = options.clock ?? Date.now;
18
+ this.startMs = this.clock();
19
+ this.startedAtIso = new Date(this.startMs).toISOString();
20
+ }
21
+ /** Open a new step, closing any currently running one. */
22
+ step(name, meta) {
23
+ const at = this.clock();
24
+ this.closeRunning(at, "completed");
25
+ this.steps.push({
26
+ name,
27
+ startedAt: new Date(at).toISOString(),
28
+ startOffsetMs: at - this.startMs,
29
+ status: "running",
30
+ meta,
31
+ });
32
+ return this;
33
+ }
34
+ /** Attach metadata to the currently running step. */
35
+ annotate(meta) {
36
+ const current = this.steps.at(-1);
37
+ if (current && current.status === "running") {
38
+ current.meta = { ...current.meta, ...meta };
39
+ }
40
+ return this;
41
+ }
42
+ /** Mark the running step as failed (used on exception/timeout). */
43
+ fail(meta) {
44
+ const at = this.clock();
45
+ if (meta)
46
+ this.annotate(meta);
47
+ this.closeRunning(at, "failed");
48
+ return this;
49
+ }
50
+ /** Close the timeline and return the immutable snapshot. Idempotent. */
51
+ finish(status = "completed") {
52
+ const at = this.clock();
53
+ this.closeRunning(at, status === "failed" ? "failed" : "completed");
54
+ this.finalized = true;
55
+ return this.snapshot(at, status === "failed");
56
+ }
57
+ /** Snapshot without finalizing (for capturing mid-flight, e.g. on error). */
58
+ toJSON(aborted = false) {
59
+ const at = this.clock();
60
+ return this.snapshot(at, aborted || !this.finalized);
61
+ }
62
+ get hasSteps() {
63
+ return this.steps.length > 0;
64
+ }
65
+ closeRunning(at, status) {
66
+ const current = this.steps.at(-1);
67
+ if (current && current.status === "running") {
68
+ current.durationMs = at - (this.startMs + current.startOffsetMs);
69
+ current.status = status;
70
+ }
71
+ }
72
+ snapshot(at, aborted) {
73
+ const totalMs = at - this.startMs;
74
+ const steps = this.steps.map((s) => ({ ...s }));
75
+ let bottleneck;
76
+ for (const s of steps) {
77
+ if (s.durationMs == null)
78
+ continue;
79
+ if (!bottleneck || s.durationMs > bottleneck.durationMs) {
80
+ bottleneck = {
81
+ name: s.name,
82
+ durationMs: s.durationMs,
83
+ percentOfTotal: totalMs > 0 ? Math.round((s.durationMs / totalMs) * 1000) / 10 : 0,
84
+ };
85
+ }
86
+ }
87
+ return { startedAt: this.startedAtIso, totalMs, steps, bottleneck, aborted };
88
+ }
89
+ }
90
+ //# sourceMappingURL=timeline.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"timeline.js","sourceRoot":"","sources":["../../src/timeline/timeline.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,46 @@
1
+ /** Structured result the AI analyzer must return. Validated before storage. */
2
+ export type AISeverity = "low" | "medium" | "high" | "critical";
3
+ export type AICategory = "bug" | "performance" | "security" | "dependency" | "configuration" | "external-service" | "unknown";
4
+ export interface AIAffectedArea {
5
+ file?: string;
6
+ functionName?: string;
7
+ line?: number;
8
+ }
9
+ export interface AISecurityImpact {
10
+ hasSensitiveDataRisk: boolean;
11
+ description?: string;
12
+ recommendedAction?: string;
13
+ }
14
+ /** One link in the upstream causal chain (roadmap #6). */
15
+ export interface AICausalLink {
16
+ /** What happened at this stage, e.g. "API returned HTTP 429". */
17
+ cause: string;
18
+ /** Optional evidence from the incident that supports this link. */
19
+ evidence?: string;
20
+ }
21
+ /** Bottleneck attribution derived from the execution timeline (roadmap #2). */
22
+ export interface AIBottleneck {
23
+ step: string;
24
+ durationMs?: number;
25
+ percentOfTotal?: number;
26
+ description?: string;
27
+ }
28
+ export interface AIAnalysisResult {
29
+ summary: string;
30
+ likelyCause: string;
31
+ severity: AISeverity;
32
+ category: AICategory;
33
+ affectedArea?: AIAffectedArea;
34
+ suggestedFix: string;
35
+ examplePatch?: string;
36
+ securityImpact?: AISecurityImpact;
37
+ /** Ordered upstream causes, root cause first (roadmap #6). */
38
+ causalChain?: AICausalLink[];
39
+ /** Slowest step attribution when a timeline is present (roadmap #2). */
40
+ bottleneck?: AIBottleneck;
41
+ /** 0..1 */
42
+ confidence: number;
43
+ /** Human explanation of the confidence score (roadmap #11). */
44
+ confidenceReason?: string;
45
+ }
46
+ //# sourceMappingURL=analysis.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"analysis.d.ts","sourceRoot":"","sources":["../../src/types/analysis.ts"],"names":[],"mappings":"AAAA,+EAA+E;AAE/E,MAAM,MAAM,UAAU,GAAG,KAAK,GAAG,QAAQ,GAAG,MAAM,GAAG,UAAU,CAAC;AAEhE,MAAM,MAAM,UAAU,GAClB,KAAK,GACL,aAAa,GACb,UAAU,GACV,YAAY,GACZ,eAAe,GACf,kBAAkB,GAClB,SAAS,CAAC;AAEd,MAAM,WAAW,cAAc;IAC7B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,gBAAgB;IAC/B,oBAAoB,EAAE,OAAO,CAAC;IAC9B,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,iBAAiB,CAAC,EAAE,MAAM,CAAC;CAC5B;AAED,0DAA0D;AAC1D,MAAM,WAAW,YAAY;IAC3B,iEAAiE;IACjE,KAAK,EAAE,MAAM,CAAC;IACd,mEAAmE;IACnE,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,+EAA+E;AAC/E,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,gBAAgB;IAC/B,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,UAAU,CAAC;IACrB,QAAQ,EAAE,UAAU,CAAC;IACrB,YAAY,CAAC,EAAE,cAAc,CAAC;IAC9B,YAAY,EAAE,MAAM,CAAC;IACrB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,cAAc,CAAC,EAAE,gBAAgB,CAAC;IAClC,8DAA8D;IAC9D,WAAW,CAAC,EAAE,YAAY,EAAE,CAAC;IAC7B,wEAAwE;IACxE,UAAU,CAAC,EAAE,YAAY,CAAC;IAC1B,WAAW;IACX,UAAU,EAAE,MAAM,CAAC;IACnB,+DAA+D;IAC/D,gBAAgB,CAAC,EAAE,MAAM,CAAC;CAC3B"}
@@ -0,0 +1,3 @@
1
+ /** Structured result the AI analyzer must return. Validated before storage. */
2
+ export {};
3
+ //# sourceMappingURL=analysis.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"analysis.js","sourceRoot":"","sources":["../../src/types/analysis.ts"],"names":[],"mappings":"AAAA,+EAA+E"}
@@ -0,0 +1,54 @@
1
+ /** Configuration shared between the SDK and the collector's second-stage sanitizer. */
2
+ export interface CaptureOptions {
3
+ /** Include the request body in the event. Default: false (security-first). */
4
+ requestBody?: boolean;
5
+ /** Include request headers. Default: false. */
6
+ headers?: boolean;
7
+ /** Include the query string. Default: true. */
8
+ query?: boolean;
9
+ /** Include the error stack trace. Default: true. */
10
+ stackTrace?: boolean;
11
+ /** Collect performance metadata (duration, memory, timeout risk). Default: true. */
12
+ performance?: boolean;
13
+ }
14
+ export interface SecurityOptions {
15
+ /** Master switch for the redaction engine. Default: true. */
16
+ sanitize?: boolean;
17
+ /** Redact PII (CPF, CNPJ, RG, passport, bank data, ...). Default: true. */
18
+ redactPII?: boolean;
19
+ /** Redact detected secrets/tokens/keys. Default: true. */
20
+ redactSecrets?: boolean;
21
+ /** Redact card numbers, CVV, Pix keys and payment tokens. Default: true. */
22
+ redactPaymentData?: boolean;
23
+ /** Redact email addresses. Default: true. */
24
+ redactEmails?: boolean;
25
+ /** Redact phone numbers. Default: true. */
26
+ redactPhones?: boolean;
27
+ /**
28
+ * Strict mode: never let request bodies/headers leave the process even if
29
+ * `capture.requestBody`/`capture.headers` are true. Default: false.
30
+ */
31
+ strictMode?: boolean;
32
+ }
33
+ export type AIMode = "disabled" | "local-only" | "self-hosted" | "cloud";
34
+ export interface AIOptions {
35
+ enabled?: boolean;
36
+ mode?: AIMode;
37
+ provider?: string;
38
+ model?: string;
39
+ /** When false, request bodies are stripped before reaching the provider. */
40
+ sendBodyToAI?: boolean;
41
+ /** When false, request headers are stripped before reaching the provider. */
42
+ sendHeadersToAI?: boolean;
43
+ /** Refuse any external provider when true (paired with local-only mode). */
44
+ allowExternalProvider?: boolean;
45
+ }
46
+ export interface RedactionOptions extends Pick<SecurityOptions, "redactPII" | "redactSecrets" | "redactPaymentData" | "redactEmails" | "redactPhones"> {
47
+ /** Placeholder used when a whole value is redacted by key match. */
48
+ maxDepth?: number;
49
+ /** Strings longer than this are truncated before scanning (DoS guard). */
50
+ maxStringLength?: number;
51
+ }
52
+ export declare const DEFAULT_SECURITY_OPTIONS: Required<SecurityOptions>;
53
+ export declare const DEFAULT_CAPTURE_OPTIONS: Required<CaptureOptions>;
54
+ //# sourceMappingURL=config.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/types/config.ts"],"names":[],"mappings":"AAAA,uFAAuF;AAEvF,MAAM,WAAW,cAAc;IAC7B,8EAA8E;IAC9E,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,+CAA+C;IAC/C,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,+CAA+C;IAC/C,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,oDAAoD;IACpD,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,oFAAoF;IACpF,WAAW,CAAC,EAAE,OAAO,CAAC;CACvB;AAED,MAAM,WAAW,eAAe;IAC9B,6DAA6D;IAC7D,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,2EAA2E;IAC3E,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,0DAA0D;IAC1D,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,4EAA4E;IAC5E,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAC5B,6CAA6C;IAC7C,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,2CAA2C;IAC3C,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB;;;OAGG;IACH,UAAU,CAAC,EAAE,OAAO,CAAC;CACtB;AAED,MAAM,MAAM,MAAM,GAAG,UAAU,GAAG,YAAY,GAAG,aAAa,GAAG,OAAO,CAAC;AAEzE,MAAM,WAAW,SAAS;IACxB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,4EAA4E;IAC5E,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,6EAA6E;IAC7E,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,4EAA4E;IAC5E,qBAAqB,CAAC,EAAE,OAAO,CAAC;CACjC;AAED,MAAM,WAAW,gBACf,SAAQ,IAAI,CACV,eAAe,EACf,WAAW,GAAG,eAAe,GAAG,mBAAmB,GAAG,cAAc,GAAG,cAAc,CACtF;IACD,oEAAoE;IACpE,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,0EAA0E;IAC1E,eAAe,CAAC,EAAE,MAAM,CAAC;CAC1B;AAED,eAAO,MAAM,wBAAwB,EAAE,QAAQ,CAAC,eAAe,CAQ9D,CAAC;AAEF,eAAO,MAAM,uBAAuB,EAAE,QAAQ,CAAC,cAAc,CAM5D,CAAC"}
@@ -0,0 +1,18 @@
1
+ /** Configuration shared between the SDK and the collector's second-stage sanitizer. */
2
+ export const DEFAULT_SECURITY_OPTIONS = {
3
+ sanitize: true,
4
+ redactPII: true,
5
+ redactSecrets: true,
6
+ redactPaymentData: true,
7
+ redactEmails: true,
8
+ redactPhones: true,
9
+ strictMode: false,
10
+ };
11
+ export const DEFAULT_CAPTURE_OPTIONS = {
12
+ requestBody: false,
13
+ headers: false,
14
+ query: true,
15
+ stackTrace: true,
16
+ performance: true,
17
+ };
18
+ //# sourceMappingURL=config.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/types/config.ts"],"names":[],"mappings":"AAAA,uFAAuF;AA6DvF,MAAM,CAAC,MAAM,wBAAwB,GAA8B;IACjE,QAAQ,EAAE,IAAI;IACd,SAAS,EAAE,IAAI;IACf,aAAa,EAAE,IAAI;IACnB,iBAAiB,EAAE,IAAI;IACvB,YAAY,EAAE,IAAI;IAClB,YAAY,EAAE,IAAI;IAClB,UAAU,EAAE,KAAK;CAClB,CAAC;AAEF,MAAM,CAAC,MAAM,uBAAuB,GAA6B;IAC/D,WAAW,EAAE,KAAK;IAClB,OAAO,EAAE,KAAK;IACd,KAAK,EAAE,IAAI;IACX,UAAU,EAAE,IAAI;IAChB,WAAW,EAAE,IAAI;CAClB,CAAC"}