/** * Local-source POC sampling: pulls log lines directly from the * customer's own infrastructure (Kubernetes pods, local files/globs; * docker containers and journald in follow-up work) when no log * analyzer connection is available. * * Use cases: * - Prospect has no Datadog / Splunk / Elastic / etc. connection * - Prospect has the connection but is unwilling to share API * credentials yet (security review pending) * - The SIEM-attached path failed and the LLM agent has explicit * user consent to fall through (caller responsibility) * * Output framing in the renderer is different from SIEM-attached * mode: the dollar figure is NOT a prediction of the prospect's * actual bill, because we only see Kubernetes pod stdout — not * CloudTrail, ALB access logs, app logs from VMs, or anything else * the SIEM ingests. The local-source path renders an industry * pricing matrix ("at Datadog list price, this would be $X/yr; at * Splunk list price, $Y/yr") and forces the user to declare the * sample representative via the sample-composition table. */ export interface LocalSourceOptions { /** Kubernetes namespace; default 'default'. Pass '*' for all namespaces. */ namespace?: string; /** * How far back to read logs per pod. Translated to `kubectl logs * --since=`. Default '1h'. */ window?: string; /** Cap on log lines pulled per pod. Default 5000. */ perPodLimit?: number; /** Cap on number of pods sampled. Default 20. */ maxPods?: number; /** Per-pod kubectl timeout in ms. Default 10000. */ perPodTimeoutMs?: number; /** Override `kubectl` binary path (test seam). */ kubectlPath?: string; } export interface LocalSourceResult { /** Raw log lines pulled across all sampled sources. */ events: string[]; /** Total bytes pulled (sum of line lengths). */ totalBytes: number; /** Per-source breakdown for the sample-composition table. */ composition: Array<{ source: string; bytes: number; lines: number; pct: number; }>; /** Sources (pods / files) that were considered but failed (e.g., access denied). */ failedSources: string[]; /** Wall time spent pulling. */ wallTimeMs: number; /** Notes for the report (kubectl-not-installed, no-pods-found, etc.). */ notes: string[]; } export interface FileSourceOptions { /** * Files, directories, or glob patterns (`*`, `**`, `?`). A directory is * read one level deep (non-recursive); use `dir/**` for the full tree. */ paths: string[]; /** Cap on number of files sampled. Default 50. */ maxFiles?: number; /** Cap on log lines pulled per file (tail). Default 10000. */ perFileLimit?: number; /** Read at most this many bytes from the end of each file. Default 16 MiB. */ maxBytesPerFile?: number; } /** * Pull log lines from the customer's Kubernetes cluster and aggregate * them by pod for the sample-composition table. * * Failure modes (any of which set the appropriate note + return what * partial data was collected): * - kubectl not installed → returns empty result with note * - no pods in namespace → returns empty with note * - per-pod kubectl logs failure → skip pod, add to `failedSources` * - per-pod timeout → skip pod, add to `failedSources` */ export declare function sampleFromKubectl(opts?: LocalSourceOptions): Promise; /** * Pure helper: random subsample without replacement. Exported for tests. */ export declare function pickRandom(items: T[], n: number, rng?: () => number): T[]; /** * Pull log lines from local files — the serverless-estate analog of * `sampleFromKubectl`. A host with no cluster (100% Lambda shops, plain * VMs, a laptop with a downloaded log bundle) samples from files or glob * patterns instead. Reads the TAIL of each file so a multi-GB log costs * at most `maxBytesPerFile` of IO. * * Failure modes mirror the kubectl sampler: unmatched patterns and * unreadable files become notes / `failedSources`, never throws. */ export declare function sampleFromFiles(opts: FileSourceOptions): Promise; /** * Segment-wise glob match. `**` spans zero or more segments; `*` and `?` * stay within one segment. Exported for tests. */ export declare function globSegmentsMatch(pat: string[], segs: string[]): boolean; /** * Read up to `maxBytes` of a file as `STRIDE_WINDOWS` evenly-spaced chunks * (head … tail), so the sample covers the whole file's pattern space rather * than one contiguous slice. Small files (<= maxBytes) are read whole. The * leading partial line of each mid-file chunk is dropped. Returns at most * `maxLines`, drawn evenly from across the chunks so no single window * dominates. */ export declare function readStridedFileLines(path: string, maxLines: number, maxBytes: number): Promise;