@lensmcp/protocol-types 1.25.11 → 1.25.13
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/bounded-clone.js +1 -1
- package/lib/bounded-map.js +1 -1
- package/lib/bounded-writer.js +1 -1
- package/lib/capture-demand.d.ts +4 -4
- package/lib/capture-demand.js +1 -1
- package/lib/dashboard.d.ts +119 -8
- package/lib/error-dismissal.d.ts +1 -1
- package/lib/error-dismissal.js +1 -1
- package/lib/flood-guard.js +1 -1
- package/lib/log-query.js +1 -1
- package/lib/perf-rules.js +1 -1
- package/lib/pod-memory.js +1 -1
- package/lib/producer-health.js +1 -1
- package/lib/sources.d.ts +3 -3
- package/lib/sources.js +1 -1
- package/package.json +1 -1
package/lib/bounded-clone.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";var T=Object.defineProperty;var
|
|
1
|
+
"use strict";var T=Object.defineProperty;var i=(e,t)=>T(e,"name",{value:t,configurable:!0});var h=Object.defineProperty,l=i((e,t)=>h(e,"name",{value:t,configurable:!0}),"_");export const DEFAULT_RAW_BYTE_LIMIT=32768,DEFAULT_MAX_STRING_BYTES=4096,DEFAULT_MAX_ARRAY_ITEMS=64,DEFAULT_MAX_DEPTH=12,CHEAP_ENTRY_BYTES=512,NOMINAL_DEEP_BYTES=32,DEEP_REPORT_DEPTH=64,SKELETON_STRING_BYTES=256,MAX_RECORDED_PATHS=20,TRUNCATION_MARKER_KEY="__lensmcpTruncation",TRUNCATED_VALUE_KEY="__lensmcpTruncated";export function estimateJsonBytes(e,t=Number.POSITIVE_INFINITY,r=12){return y(e,t,r,32)}i(estimateJsonBytes,"estimateJsonBytes"),l(estimateJsonBytes,"estimateJsonBytes");export function exceedsJsonByteBudget(e,t,r=12){return y(e,t,r,Number.POSITIVE_INFINITY)>t}i(exceedsJsonByteBudget,"exceedsJsonByteBudget"),l(exceedsJsonByteBudget,"exceedsJsonByteBudget");function y(e,t,r,a){switch(typeof e){case"undefined":case"function":case"symbol":return 0;case"boolean":return 5;case"number":return Number.isFinite(e)?8:4;case"bigint":return 20;case"string":return e.length+2;default:break}if(e===null)return 4;if(r<=0)return a;if(e instanceof Date)return 26;if(Array.isArray(e)){let n=2;for(let s=0;s<e.length;s++)if(n+=y(e[s],t-n,r-1,a)+1,n>t)return n;return n}let u=2;const o=e;for(const n in o){if(!Object.prototype.hasOwnProperty.call(o,n))continue;const s=y(o[n],t-u,r-1,a);if(s!==0&&(u+=n.length+4+s,u>t))return u}return u}i(y,"T"),l(y,"walk");function g(e,t){e.truncatedAnything=!0,e.paths.length<20&&e.paths.push(t||"<root>")}i(g,"A"),l(g,"record");function f(e,t,r){return g(e,r),{[TRUNCATED_VALUE_KEY]:!0,originalBytes:estimateJsonBytes(t,Number.POSITIVE_INFINITY,64)}}i(f,"I"),l(f,"stub");function p(e){if(e===null)return!0;const t=typeof e;return t==="number"||t==="boolean"||t==="string"||t==="bigint"}i(p,"y"),l(p,"isScalar");export function clampValue(e,t,r,a){if(typeof e=="string"){const u=t.budget<=0?256:t.maxStringBytes;if(e.length+2<=u)return t.budget-=e.length+2,e;const o=Math.max(0,u-64);return g(t,a),t.budget-=o,`${e.slice(0,o)}\u2026[lensmcp truncated: ${e.length-o} more chars]`}return e===null||typeof e!="object"?(t.budget-=y(e,Number.POSITIVE_INFINITY,1,32),e):r<=0?f(t,e,a):e instanceof Date?(t.budget-=26,e):Array.isArray(e)?m(e,t,r,a):b(e,t,r,a)}i(clampValue,"clampValue"),l(clampValue,"clampValue");function m(e,t,r,a){const u=[],o=Math.min(e.length,t.maxArrayItems);for(let n=0;n<o&&!(t.budget<=0);n++)u.push(clampValue(e[n],t,r-1,`${a}[${n}]`));return u.length<e.length&&g(t,`${a}[] (+${e.length-u.length} items dropped)`),u}i(m,"f"),l(m,"clampArray");function b(e,t,r,a){const u={};let o;const n=t.budget<=0;for(const s in e){if(!Object.prototype.hasOwnProperty.call(e,s))continue;const c=e[s],I=y(c,512,r-1,Number.POSITIVE_INFINITY);if(I<=512&&(!n||p(c))){u[s]=c,t.budget-=s.length+4+I;continue}(o??=[]).push({key:s,bytes:I})}if(!o)return u;o.sort((s,c)=>s.bytes===c.bytes?0:s.bytes<c.bytes?-1:1);for(const{key:s}of o){const c=a?`${a}.${s}`:s;u[s]=clampValue(e[s],t,r-1,c)}return u}i(b,"m"),l(b,"clampObject");export function boundedClone(e,t={}){const r=t.rawByteLimit??32768,a=t.maxDepth??12;if(r<=0)return{value:void 0,truncated:!1,originalBytes:0,keptBytes:0,paths:[]};if(e==null)return{value:e,truncated:!1,originalBytes:0,keptBytes:0,paths:[]};if(!exceedsJsonByteBudget(e,r,a)){const c=estimateJsonBytes(e,r,a),I={budget:r,maxStringBytes:t.maxStringBytes??4096,maxArrayItems:t.maxArrayItems??64,paths:[],truncatedAnything:!1};return{value:clampValue(e,I,a,""),truncated:!1,originalBytes:c,keptBytes:c,paths:[]}}const u=estimateJsonBytes(e,Number.POSITIVE_INFINITY,64),o={budget:r,maxStringBytes:t.maxStringBytes??4096,maxArrayItems:t.maxArrayItems??64,paths:[],truncatedAnything:!1},n=clampValue(e,o,a,""),s=estimateJsonBytes(n,Number.POSITIVE_INFINITY,a);if(o.truncatedAnything&&n!==null&&typeof n=="object"&&!Array.isArray(n)){const c={truncated:!0,originalBytes:u,keptBytes:s,paths:o.paths};n[TRUNCATION_MARKER_KEY]=c}return{value:n,truncated:o.truncatedAnything,originalBytes:u,keptBytes:s,paths:o.paths}}i(boundedClone,"boundedClone"),l(boundedClone,"boundedClone");
|
package/lib/bounded-map.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";var
|
|
1
|
+
"use strict";var c=Object.defineProperty;var t=(e,r)=>c(e,"name",{value:r,configurable:!0});var i=Object.defineProperty,s=t((e,r)=>i(e,"name",{value:r,configurable:!0}),"o");export function capMap(e,r){if(e.size<=r)return 0;let n=0;const o=e.keys();for(;e.size>r;){const a=o.next();if(a.done)break;e.delete(a.value)&&(n+=1)}return n}t(capMap,"capMap"),s(capMap,"capMap");export const MAX_PRODUCER_KEYS=256;
|
package/lib/bounded-writer.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";var
|
|
1
|
+
"use strict";var y=Object.defineProperty;var r=(e,t)=>y(e,"name",{value:t,configurable:!0});var v=Object.defineProperty,o=r((e,t)=>v(e,"name",{value:t,configurable:!0}),"c");import{renameSync as l,statSync as f,unlinkSync as x}from"node:fs";export function eventMaxBytes(e=process.env){const t=Number(e.LENSMCP_EVENT_MAX_BYTES);return Number.isFinite(t)&&t>0?t:50*1024*1024}r(eventMaxBytes,"eventMaxBytes"),o(eventMaxBytes,"eventMaxBytes");export function eventMaxFiles(e=process.env){const t=Number(e.LENSMCP_EVENT_MAX_FILES);return Number.isFinite(t)&&t>=1&&t<=20?Math.floor(t):5}r(eventMaxFiles,"eventMaxFiles"),o(eventMaxFiles,"eventMaxFiles");const E=1024*1024,a=new Map;export function maybeRotateEventFile(e,t,i){const s=(a.get(e)??0)+t,c=i?.maxBytes??eventMaxBytes(),u=i?.maxFiles??eventMaxFiles(),m=Math.min(E,c);if(s<m){a.set(e,s);return}try{const n=f(e).size;if(a.set(e,0),n<=c)return}catch{a.set(e,s);return}try{x(`${e}.${u}`)}catch{}for(let n=u-1;n>=1;n--)try{l(`${e}.${n}`,`${e}.${n+1}`)}catch{}try{l(e,`${e}.1`)}catch{}}r(maybeRotateEventFile,"maybeRotateEventFile"),o(maybeRotateEventFile,"maybeRotateEventFile");export function resetRotationThrottle(e){e===void 0?a.clear():a.delete(e)}r(resetRotationThrottle,"resetRotationThrottle"),o(resetRotationThrottle,"resetRotationThrottle");
|
package/lib/capture-demand.d.ts
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
* Why a file and not the event bus: the bus is ONE-WAY. Producers (the Vite
|
|
7
7
|
* plugin, the NestJS instrumentation, the capture runner) append to
|
|
8
8
|
* `LENSMCP_EVENT_FILE` / the UDS socket and the MCP session tails it — nothing
|
|
9
|
-
* flows back. So `
|
|
9
|
+
* flows back. So `visual_capture_frame` publishing a `visual-capture-request`
|
|
10
10
|
* onto the MCP's in-process bus was a DEAD LETTER: the runner never saw it,
|
|
11
11
|
* which is why capture had to poll a live Chrome forever (measured on a real
|
|
12
12
|
* machine, 2026-07-29: 2 runners + >1GB of Chrome resident for 1d8h with
|
|
@@ -26,7 +26,7 @@ export declare const CAPTURE_REQUEST_FILENAME = "capture-request.json";
|
|
|
26
26
|
* Presence-file name (same directory). The runner writes it at startup and
|
|
27
27
|
* removes it on a clean stop.
|
|
28
28
|
*
|
|
29
|
-
* Its job is to keep the requester honest: `
|
|
29
|
+
* Its job is to keep the requester honest: `visual_capture_frame` now WAITS for
|
|
30
30
|
* the fresh frame it asked for (a cold browser needs ~1s), and without a way to
|
|
31
31
|
* tell "a runner is warming up" from "no runner exists" that wait would also be
|
|
32
32
|
* paid by every workspace running with capture disabled or no Chrome installed
|
|
@@ -74,7 +74,7 @@ export declare function appMatchesPage(app: string, page: CapturePage): boolean;
|
|
|
74
74
|
/**
|
|
75
75
|
* Session-rules file name (same directory).
|
|
76
76
|
*
|
|
77
|
-
* `
|
|
77
|
+
* `visual_register_rule` had the dead-letter problem this module describes for
|
|
78
78
|
* capture requests, and kept it after they were fixed: it published
|
|
79
79
|
* `visual-rule-registered` onto the MCP's in-process bus, where only the
|
|
80
80
|
* reducer heard it. The reducer listed the rule and counted it ("1 rule
|
|
@@ -86,7 +86,7 @@ export declare function appMatchesPage(app: string, page: CapturePage): boolean;
|
|
|
86
86
|
* reads them before each capture.
|
|
87
87
|
*/
|
|
88
88
|
export declare const CAPTURE_RULES_FILENAME = "capture-rules.json";
|
|
89
|
-
/** One rule registered through `
|
|
89
|
+
/** One rule registered through `visual_register_rule`. */
|
|
90
90
|
export interface CaptureSessionRule {
|
|
91
91
|
/** The rule, in the `lensmcp.rules.json` shape. Validate on read — it crossed
|
|
92
92
|
* a process boundary, and a hand-edited file must not crash a capture. */
|
package/lib/capture-demand.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";var
|
|
1
|
+
"use strict";var c=Object.defineProperty;var o=(t,e)=>c(t,"name",{value:e,configurable:!0});var s=Object.defineProperty,u=o((t,e)=>s(t,"name",{value:e,configurable:!0}),"s");export const CAPTURE_REQUEST_FILENAME="capture-request.json",CAPTURE_PRESENCE_FILENAME="capture-runner.json";export function appMatchesPage(t,e){const r=t.trim().toLowerCase();if(!r)return!1;if(e.project&&e.project.toLowerCase()===r)return!0;const n=e.url.toLowerCase();if(n===r||n.replace(/\/+$/,"")===r.replace(/\/+$/,""))return!0;try{const a=new URL(e.url);return/^\d+$/.test(r)?a.port===r:a.origin.toLowerCase()===r.replace(/\/+$/,"")}catch{return!1}}o(appMatchesPage,"appMatchesPage"),u(appMatchesPage,"appMatchesPage");export const CAPTURE_RULES_FILENAME="capture-rules.json";
|
package/lib/dashboard.d.ts
CHANGED
|
@@ -1719,7 +1719,7 @@ export interface DashDbSchema {
|
|
|
1719
1719
|
/** The newest read failed, and this is the last one that did not: why the newer failed, and when. */
|
|
1720
1720
|
kept?: DashDbKept;
|
|
1721
1721
|
}
|
|
1722
|
-
/** One database's last read by LensMCP's own checks (`
|
|
1722
|
+
/** One database's last read by LensMCP's own checks (`db_schema`), as `db://analysis` names it beside the analyzer's runs. */
|
|
1723
1723
|
export interface DashDbChecksSeen {
|
|
1724
1724
|
store: string;
|
|
1725
1725
|
database: string;
|
|
@@ -2682,15 +2682,20 @@ export interface DashReviewMarks {
|
|
|
2682
2682
|
kind: DashAiRun['target']['kind'];
|
|
2683
2683
|
marks: Record<string, DashReviewStatus>;
|
|
2684
2684
|
}
|
|
2685
|
-
/**
|
|
2686
|
-
|
|
2685
|
+
/**
|
|
2686
|
+
* What became of a suggestion: new; accepted (for a coding agent to do); applied (the change is made, not yet
|
|
2687
|
+
* confirmed); closed (confirmed — a check passed, or someone closed it); dismissed (not to be done, and why).
|
|
2688
|
+
*/
|
|
2689
|
+
export type DashSuggestionState = 'new' | 'accepted' | 'applied' | 'closed' | 'dismissed';
|
|
2687
2690
|
/**
|
|
2688
2691
|
* One suggestion: a change a review asked for (a finding of the newest finished review of its target), with what
|
|
2689
2692
|
* became of it. A later review of the same target that asks for the same change keeps its state (`key`).
|
|
2690
2693
|
*/
|
|
2691
2694
|
export interface DashSuggestion {
|
|
2692
|
-
/**
|
|
2695
|
+
/** `sg-` and 10 hex of its key: the same across the reviews that ask for the same change — what a URL and the tools name. */
|
|
2693
2696
|
id: string;
|
|
2697
|
+
/** `<runId>#<n>` — the run that asks for it, and the finding's place in it (an older lens's id; still accepted). */
|
|
2698
|
+
place: string;
|
|
2694
2699
|
/** The finding as the state follows it: its analyzer, its target, its title with numbers folded. */
|
|
2695
2700
|
key: string;
|
|
2696
2701
|
runId: string;
|
|
@@ -2703,10 +2708,116 @@ export interface DashSuggestion {
|
|
|
2703
2708
|
/** When the review that asked for it finished. */
|
|
2704
2709
|
at: number;
|
|
2705
2710
|
state: DashSuggestionState;
|
|
2706
|
-
/** When the state was set, by whom (`developer`,
|
|
2711
|
+
/** When the state was set, by whom (`developer`, a coding agent's session, `check:<id>`), and why. */
|
|
2707
2712
|
stateAt?: number;
|
|
2708
2713
|
by?: string;
|
|
2709
2714
|
note?: string;
|
|
2715
|
+
/**
|
|
2716
|
+
* False: its target's newest review no longer asks for it — kept as it was, because someone said what became of it.
|
|
2717
|
+
*/
|
|
2718
|
+
current: boolean;
|
|
2719
|
+
/** A review newer than its state still asks for it — an applied change that did not do it (a closed one reopens as new). */
|
|
2720
|
+
askedAgainAt?: number;
|
|
2721
|
+
/** What it is about and where to read more (`suggestion_get`, the dashboard's detail): its target, what its review rested on, what it names. */
|
|
2722
|
+
refs?: DashSuggestionRef[];
|
|
2723
|
+
/** The checks scheduled on it, newest first (`suggestion_get`, the dashboard's detail); in a list, how many wait. */
|
|
2724
|
+
checks?: DashSuggestionCheck[];
|
|
2725
|
+
/** A check to start from, read from its verify line (`suggestion_get`, the dashboard's Check a number…) — never scheduled by itself. */
|
|
2726
|
+
proposedCheck?: DashCheckProposal;
|
|
2727
|
+
checksWaiting?: number;
|
|
2728
|
+
}
|
|
2729
|
+
/** One thing a suggestion is about, or rests on — and how to read it. */
|
|
2730
|
+
export interface DashSuggestionRef {
|
|
2731
|
+
kind: 'sql' | 'route' | 'flow' | 'page' | 'error' | 'queue' | 'kv' | 'db' | 'dbtable' | 'table' | 'external' | 'code' | 'run';
|
|
2732
|
+
id: string;
|
|
2733
|
+
label: string;
|
|
2734
|
+
/** `target`: what was reviewed; `reviewed-with`: a review its review was shown; `named`: the finding names it; `related`: the catalogs join it to the target. */
|
|
2735
|
+
why: 'target' | 'reviewed-with' | 'named' | 'related';
|
|
2736
|
+
/** How a coding agent reads it: a tool and its input, or a resource. */
|
|
2737
|
+
read?: {
|
|
2738
|
+
tool: string;
|
|
2739
|
+
input: Record<string, unknown>;
|
|
2740
|
+
} | {
|
|
2741
|
+
uri: string;
|
|
2742
|
+
};
|
|
2743
|
+
/** Where the dashboard shows it (under the workspace's prefix). */
|
|
2744
|
+
path?: string;
|
|
2745
|
+
}
|
|
2746
|
+
/** What a measure check reads: a number the lens records about a thing, counted only from what ran since the check began. */
|
|
2747
|
+
export type DashCheckMetric = 'runs' | 'errors' | 'p95Ms' | 'perRequestMax' | 'sqlPerRun' | 'loadMs' | 'sqlPerVisit' | 'requestsPerVisit' | 'occurrences' | 'waiting' | 'failed' | 'findings';
|
|
2748
|
+
/** One condition a measure check holds a thing to: `metric op value`, over what ran since the check began. */
|
|
2749
|
+
export interface DashCheckMeasure {
|
|
2750
|
+
/** What it measures: the suggestion's target or one of its refs. */
|
|
2751
|
+
on: {
|
|
2752
|
+
kind: 'sql' | 'route' | 'page' | 'error' | 'queue' | 'external' | 'db' | 'dbtable';
|
|
2753
|
+
id: string;
|
|
2754
|
+
};
|
|
2755
|
+
metric: DashCheckMetric;
|
|
2756
|
+
op: '<=' | '<' | '>=' | '>' | '==';
|
|
2757
|
+
value: number;
|
|
2758
|
+
/** `findings`: the lens's finding kind counted (`unindexed-foreign-key`, `seq-scan`…); absent, every kind. */
|
|
2759
|
+
finding?: string;
|
|
2760
|
+
/** How many runs (visits, calls…) since the check began it needs before it can pass — default 3; a level needs none. */
|
|
2761
|
+
minSamples?: number;
|
|
2762
|
+
/** How long since the check began before it can pass — an error not seen again needs time to pass (default 30 min for `occurrences`). */
|
|
2763
|
+
holdMs?: number;
|
|
2764
|
+
}
|
|
2765
|
+
/** A check read from a finding's own words: measures to schedule as they are, or its review run anew — and what they were read from. */
|
|
2766
|
+
export interface DashCheckProposal {
|
|
2767
|
+
measures?: DashCheckMeasure[];
|
|
2768
|
+
review?: true;
|
|
2769
|
+
from: string;
|
|
2770
|
+
}
|
|
2771
|
+
/** What one look of a check found. */
|
|
2772
|
+
export interface DashCheckResult {
|
|
2773
|
+
at: number;
|
|
2774
|
+
/** pass: every measure met (or the new review no longer asks for it); fail: one is not; wait: too little ran since it began. */
|
|
2775
|
+
outcome: 'pass' | 'fail' | 'wait' | 'error';
|
|
2776
|
+
measures?: Array<{
|
|
2777
|
+
measure: DashCheckMeasure;
|
|
2778
|
+
value?: number;
|
|
2779
|
+
samples: number;
|
|
2780
|
+
outcome: 'pass' | 'fail' | 'wait';
|
|
2781
|
+
text: string;
|
|
2782
|
+
}>;
|
|
2783
|
+
review?: {
|
|
2784
|
+
runId: string;
|
|
2785
|
+
asksStill: boolean;
|
|
2786
|
+
text: string;
|
|
2787
|
+
};
|
|
2788
|
+
text: string;
|
|
2789
|
+
}
|
|
2790
|
+
/**
|
|
2791
|
+
* A check scheduled on a suggestion (by a coding agent, `suggestion_check`, or a developer): LensMCP looks again — at
|
|
2792
|
+
* the lens's numbers since it began (`measure`), or by reviewing its target anew (`review`, a paid run) — and closes
|
|
2793
|
+
* the suggestion when it passes. It looks first at `after`, then every `everyMs`, and gives up at `until`.
|
|
2794
|
+
*/
|
|
2795
|
+
export interface DashSuggestionCheck {
|
|
2796
|
+
id: string;
|
|
2797
|
+
/** The suggestion's id, and its key (what the state follows). */
|
|
2798
|
+
suggestion: string;
|
|
2799
|
+
key: string;
|
|
2800
|
+
kind: 'measure' | 'review';
|
|
2801
|
+
measures?: DashCheckMeasure[];
|
|
2802
|
+
/** Counted from: what ran before it is not looked at. */
|
|
2803
|
+
since: number;
|
|
2804
|
+
after: number;
|
|
2805
|
+
everyMs: number;
|
|
2806
|
+
until: number;
|
|
2807
|
+
state: 'waiting' | 'running' | 'passed' | 'failed' | 'cancelled';
|
|
2808
|
+
/** Who scheduled it (`developer`, `agent:<who>`), why — and whose daily allowance its reviews spend. */
|
|
2809
|
+
by: string;
|
|
2810
|
+
note?: string;
|
|
2811
|
+
trigger: DashAiTrigger;
|
|
2812
|
+
at: number;
|
|
2813
|
+
/** How many times it looked, and the reviews it ran (a review check runs at most `maxReviews`). */
|
|
2814
|
+
attempts: number;
|
|
2815
|
+
reviews: number;
|
|
2816
|
+
maxReviews: number;
|
|
2817
|
+
nextAt?: number;
|
|
2818
|
+
last?: DashCheckResult;
|
|
2819
|
+
/** When it passed, failed or was cancelled. */
|
|
2820
|
+
endedAt?: number;
|
|
2710
2821
|
}
|
|
2711
2822
|
/** `/api/ai/suggestions` and `agent://suggestions`: every open suggestion, with what became of each. */
|
|
2712
2823
|
export interface DashSuggestions {
|
|
@@ -3277,7 +3388,7 @@ export interface DashAgentEvent {
|
|
|
3277
3388
|
at: number;
|
|
3278
3389
|
/** `ask`: a prompt the person gave it (the Claude Code plugin's hook) — `result` holds its first line. */
|
|
3279
3390
|
kind: 'tool' | 'read' | 'say' | 'ask';
|
|
3280
|
-
/** The tool or the resource URI; `
|
|
3391
|
+
/** The tool or the resource URI; `agent_task` for `say`; `prompt` for `ask`. */
|
|
3281
3392
|
name: string;
|
|
3282
3393
|
/** Its arguments, redacted, as JSON (at most 2 KB). */
|
|
3283
3394
|
args?: string;
|
|
@@ -3303,13 +3414,13 @@ export interface DashAgentSession {
|
|
|
3303
3414
|
lastSeenAt: number;
|
|
3304
3415
|
/** Ended: when its shim exited (or, without one, its last call). */
|
|
3305
3416
|
endedAt?: number;
|
|
3306
|
-
/** What it says it is doing (`
|
|
3417
|
+
/** What it says it is doing (`agent_task`): the task's first line, and the step it is on. */
|
|
3307
3418
|
task?: string;
|
|
3308
3419
|
step?: string;
|
|
3309
3420
|
saidAt?: number;
|
|
3310
3421
|
/**
|
|
3311
3422
|
* What the person last asked it — the prompt's first line, recorded by the LensMCP Claude Code plugin's
|
|
3312
|
-
* `UserPromptSubmit` hook, so a session shows its task even when the agent never calls `
|
|
3423
|
+
* `UserPromptSubmit` hook, so a session shows its task even when the agent never calls `agent_task`.
|
|
3313
3424
|
*/
|
|
3314
3425
|
asked?: string;
|
|
3315
3426
|
askedAt?: number;
|
package/lib/error-dismissal.d.ts
CHANGED
|
@@ -18,7 +18,7 @@ import type { BaseEvent } from './event.js';
|
|
|
18
18
|
* - **It is undone the same way** (`error-restored`), and what is hidden is still listed.
|
|
19
19
|
*
|
|
20
20
|
* WHO may write one: a person in the dashboard, a person at the CLI, and an agent through
|
|
21
|
-
* `
|
|
21
|
+
* `observe_dismiss_errors`. The last two name EVENTS, not a dashboard row, and must say why —
|
|
22
22
|
* `by` and `reason` travel with the dismissal and are shown wherever it is listed, so a status
|
|
23
23
|
* that went quiet because an agent dismissed something says exactly that.
|
|
24
24
|
*/
|
package/lib/error-dismissal.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";var
|
|
1
|
+
"use strict";var f=Object.defineProperty;var s=(t,r)=>f(t,"name",{value:r,configurable:!0});var E=Object.defineProperty,S=s((t,r)=>E(t,"name",{value:r,configurable:!0}),"s");export const ERROR_DISMISSED="error-dismissed",ERROR_RESTORED="error-restored",LENS_EVENT_SOURCE="lens",MAX_DISMISSAL_EVENT_IDS=200;const g=2048;export const MAX_DISMISSAL_REASON_CHARS=500;const m=300,I=new Set(["dashboard","cli","agent"]);export function readErrorDismissal(t){if(t.source!==LENS_EVENT_SOURCE||!t.raw||typeof t.raw!="object")return;const r=t.raw,i=r.groupId;if(typeof i!="string"||i.length===0||i.length>2048)return;if(r.kind===ERROR_RESTORED)return{kind:ERROR_RESTORED,groupId:i};if(r.kind!==ERROR_DISMISSED)return;const n=r.until;if(typeof n!="number"||!Number.isFinite(n))return;const c=Array.isArray(r.eventIds)?r.eventIds.filter(e=>typeof e=="string"&&e.length>0).slice(0,200):[],o=I.has(r.by)?r.by:void 0,a=S((e,l)=>typeof e=="string"&&e.trim()?e.trim().slice(0,l):void 0,"text"),d=a(r.reason,500),u=a(r.title,300);return{kind:ERROR_DISMISSED,groupId:i,until:Math.min(n,t.timestamp),eventIds:c,...o?{by:o}:{},...d?{reason:d}:{},...u?{title:u}:{}}}s(readErrorDismissal,"readErrorDismissal"),S(readErrorDismissal,"readErrorDismissal");
|
package/lib/flood-guard.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";var S=Object.defineProperty;var i=(t,
|
|
1
|
+
"use strict";var S=Object.defineProperty;var i=(t,n)=>S(t,"name",{value:n,configurable:!0});var m=Object.defineProperty,u=i((t,n)=>m(t,"name",{value:n,configurable:!0}),"o");function d(){const t=typeof process<"u"?process.env?.LENSMCP_EVENT_MAX_EPS:void 0;if(t===void 0||t==="")return;if(t==="off")return"off";const n=Number(t);if(Number.isFinite(n))return n<=0?"off":n}i(d,"S"),u(d,"envPerSec");export function createEventFloodGuard(t){const n=t?.envOverride===!1?void 0:d();if(n==="off")return{admit:u(()=>({ok:!0,suppressed:0}),"admit")};const l=n??t?.perSec??5,f=Math.max(1,t?.burst??Math.max(30,l*4)),c=t?.maxKeys??2048,r=new Map,p=u(o=>{for(const[s,e]of r)o-e.lastSeenAt>6e4&&r.delete(s);if(r.size>c){const s=[...r.entries()].sort((e,a)=>e[1].lastSeenAt-a[1].lastSeenAt);for(let e=0;e<s.length>>1;e++)r.delete(s[e][0])}},"evictStale");return{admit(o){const s=Date.now();let e=r.get(o);e||(r.size>=c&&p(s),e={tokens:f,lastRefillAt:s,suppressed:0,lastSeenAt:s},r.set(o,e)),e.lastSeenAt=s;const a=s-e.lastRefillAt;if(a>0&&(e.tokens=Math.min(f,e.tokens+a/1e3*l),e.lastRefillAt=s),e.tokens>=1){e.tokens-=1;const v=e.suppressed;return e.suppressed=0,{ok:!0,suppressed:v}}return e.suppressed+=1,{ok:!1,suppressed:0}}}}i(createEventFloodGuard,"createEventFloodGuard"),u(createEventFloodGuard,"createEventFloodGuard");
|
package/lib/log-query.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";var
|
|
1
|
+
"use strict";var m=Object.defineProperty;var a=(e,r)=>m(e,"name",{value:r,configurable:!0});var L=Object.defineProperty,c=a((e,r)=>L(e,"name",{value:r,configurable:!0}),"c");const d={level:"level",severity:"level",service:"service",svc:"service",src:"service",source:"service",flow:"flow",trace:"trace",request:"trace",category:"category",cat:"category",ms:"ms"},h={warn:"warning",err:"error"},p=/(-?)(?:([A-Za-z]+):)?(?:"([^"]*)"|(\S+))/g;export function parseLogQuery(e){const r=[],t=[];for(const s of e.matchAll(p)){const[o,n,f,w,g]=s,u=(w??g??"").trim(),i=f?d[f.toLowerCase()]:void 0;if(i&&u){const y=i==="level"?h[u.toLowerCase()]??u.toLowerCase():u;r.push({key:i,value:y,negate:n==="-"})}else o.trim()&&t.push(o.trim())}return{tokens:r,text:t.join(" ")}}a(parseLogQuery,"parseLogQuery"),c(parseLogQuery,"parseLogQuery");export function formatLogQuery(e){const r=c(t=>/\s/.test(t)?`"${t}"`:t,"quote");return[...e.tokens.map(t=>`${t.negate?"-":""}${t.key}:${r(t.value)}`),e.text].filter(Boolean).join(" ")}a(formatLogQuery,"formatLogQuery"),c(formatLogQuery,"formatLogQuery");function v(e,r){if(e===void 0)return!1;const t=/^(>=|<=|>|<|=)?\s*(\d+(?:\.\d+)?)$/.exec(r);if(!t)return!1;const s=Number(t[2]);switch(t[1]){case">":return e>s;case"<":return e<s;case"<=":return e<=s;case"=":return e===s;default:return e>=s}}a(v,"h"),c(v,"msMatches");function l(e,r){const t=r.value.toLowerCase();switch(r.key){case"level":return e.severity.toLowerCase()===t;case"service":return e.source.toLowerCase()===t;case"flow":return!!e.flowId&&e.flowId.toLowerCase().startsWith(t);case"trace":return!!e.requestId&&e.requestId.toLowerCase().startsWith(t);case"category":return e.category.toLowerCase()===t;case"ms":return v(e.durationMs,r.value)}}a(l,"i"),c(l,"tokenMatches");export function matchesLogQuery(e,r,t){const s=new Map;for(const o of r.tokens){if(o.negate){if(l(e,o))return!1;continue}const n=s.get(o.key);n?n.push(o):s.set(o.key,[o])}for(const o of s.values())if(!o.some(n=>l(e,n)))return!1;if(r.text){const o=`${e.title} ${e.message??""} ${e.source} ${e.flowId??""}`;return t?t(o):o.toLowerCase().includes(r.text.toLowerCase())}return!0}a(matchesLogQuery,"matchesLogQuery"),c(matchesLogQuery,"matchesLogQuery");
|
package/lib/perf-rules.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";var
|
|
1
|
+
"use strict";var u=Object.defineProperty;var o=(r,e)=>u(r,"name",{value:e,configurable:!0});var c=Object.defineProperty,a=o((r,e)=>c(r,"name",{value:e,configurable:!0}),"o");export const PERF_RULE_IDS=["bundle/heavy-barrel-import","pod/heap-budget","pod/retained-generation"],PERF_RULE_EVENT_KINDS=["perf-rule-finding","perf-rule-retracted","perf-rule-scan"],PERF_RULES_DOC="https://github.com/kiwiapps-ltd/lensmcp/blob/main/docs/lensmcp/concepts/memory-and-build-cost.mdx",PERF_RULE_DOCS={"bundle/heavy-barrel-import":`${PERF_RULES_DOC}#bundleheavy-barrel-import`,"pod/heap-budget":`${PERF_RULES_DOC}#podheap-budget`,"pod/retained-generation":`${PERF_RULES_DOC}#podretained-generation`};export function perfRuleFingerprint(r,e,n){return`perf-rule:${r}:${e}:${n}`}o(perfRuleFingerprint,"perfRuleFingerprint"),a(perfRuleFingerprint,"perfRuleFingerprint");export function perfRuleScanFingerprint(r,e){return`perf-rule-scan:${r}:${e}`}o(perfRuleScanFingerprint,"perfRuleScanFingerprint"),a(perfRuleScanFingerprint,"perfRuleScanFingerprint");const s=/^[a-z][a-z0-9-]*\/[a-z0-9][a-z0-9-]*$/,l=12,f=4e3,t=a((r,e=f)=>typeof r=="string"&&r.length>0&&r.length<=e,"isText");export function asPerfRuleRaw(r){if(!r||typeof r!="object")return;const e=r;if(!PERF_RULE_EVENT_KINDS.includes(e.kind)||typeof e.rule!="string"||!s.test(e.rule)||!t(e.project,512))return;if(e.kind==="perf-rule-scan"){const i=e.open;return!Array.isArray(i)||i.length>256||!i.every(p=>t(p,512))?void 0:r}if(!t(e.subject,512))return;if(e.kind==="perf-rule-retracted")return r;if(e.severity!=="warning"&&e.severity!=="error"||!t(e.title)||!t(e.summary)||!t(e.verify)||!t(e.docs,1024))return;const n=e.fix;if(!(!Array.isArray(n)||n.length===0||n.length>l||!n.every(i=>t(i)))&&!(!e.evidence||typeof e.evidence!="object"||Array.isArray(e.evidence))&&!(!e.cost||typeof e.cost!="object"||Array.isArray(e.cost)))return r}o(asPerfRuleRaw,"asPerfRuleRaw"),a(asPerfRuleRaw,"asPerfRuleRaw");
|
package/lib/pod-memory.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";var
|
|
1
|
+
"use strict";var t=Object.defineProperty;var r=(o,e)=>t(o,"name",{value:e,configurable:!0});var d=Object.defineProperty,m=r((o,e)=>d(o,"name",{value:e,configurable:!0}),"r");export const POD_MEMORY_KINDS=["pod-memory","pod-memory-retained","pod-memory-released","pod-memory-exited"];export function asPodMemoryRaw(o){if(!o||typeof o!="object")return;const e=o;if(POD_MEMORY_KINDS.includes(e.kind)&&!(typeof e.project!="string"||!e.project)&&!(typeof e.pod!="number"||typeof e.pid!="number")&&!(e.kind==="pod-memory"&&(typeof e.live!="number"||!Number.isFinite(e.live)))&&!((e.kind==="pod-memory-retained"||e.kind==="pod-memory-released")&&typeof e.gen!="number"))return o}r(asPodMemoryRaw,"asPodMemoryRaw"),m(asPodMemoryRaw,"asPodMemoryRaw");
|
package/lib/producer-health.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";var
|
|
1
|
+
"use strict";var m=Object.defineProperty;var i=(t,o)=>m(t,"name",{value:o,configurable:!0});var R=Object.defineProperty,p=i((t,o)=>R(t,"name",{value:o,configurable:!0}),"u");import{z as e}from"zod";export const ProducerStateSchema=e.enum(["none","connected"]),ProducerRunStatusSchema=e.enum(["running","clean","failing","error"]),ProducerReportSchema=e.object({id:e.string(),tool:e.string(),project:e.string().optional(),firstReportedAt:e.number().int().nonnegative(),lastReportedAt:e.number().int().nonnegative(),lastRunStatus:ProducerRunStatusSchema,lastRunDurationMs:e.number().int().nonnegative().optional(),errorCount:e.number().int().nonnegative(),warningCount:e.number().int().nonnegative().optional(),error:e.string().optional()}),ProducerHealthSchema=e.object({producer:ProducerStateSchema,producers:e.array(ProducerReportSchema),lastReportedAt:e.number().int().nonnegative().optional(),ageMs:e.number().int().nonnegative().optional(),stale:e.boolean(),detail:e.string()}),PRODUCER_STALE_AFTER_MS=10*6e4;export function summariseProducers(t){const o=t.now??Date.now(),n=[...t.producers].sort((r,h)=>h.lastReportedAt-r.lastReportedAt);if(n.length===0)return{producer:"none",producers:[],stale:!1,detail:`No ${t.domain} producer has ever reported into this session \u2014 this is NOT a clean result, nothing is watching. ${t.noProducerHint}`};const d=n[0].lastReportedAt,u=Math.max(0,o-d),l=u>PRODUCER_STALE_AFTER_MS,c=n.filter(r=>r.lastRunStatus==="failing"),s=n.filter(r=>r.lastRunStatus==="error"),a=[`${n.length} ${t.domain} producer${n.length===1?"":"s"} reporting (${n.map(r=>r.id).join(", ")}); newest report ${g(u)}.`];return s.length>0&&a.push(`${s.length} produced NO verdict (the tool itself failed): ${s.map(r=>`${r.id} \u2014 ${r.error??"unknown error"}`).join("; ")}.`),c.length>0&&a.push(`${c.length} reporting errors.`),l&&a.push(`Older than ${Math.round(PRODUCER_STALE_AFTER_MS/6e4)}m \u2014 the verdict may predate the current source.`),{producer:"connected",producers:n,lastReportedAt:d,ageMs:u,stale:l,detail:a.join(" ")}}i(summariseProducers,"summariseProducers"),p(summariseProducers,"summariseProducers");function g(t){return t<1e3?"just now":t<6e4?`${Math.round(t/1e3)}s ago`:t<36e5?`${Math.round(t/6e4)}m ago`:`${Math.round(t/36e5)}h ago`}i(g,"g"),p(g,"describeAge");
|
package/lib/sources.d.ts
CHANGED
|
@@ -16,8 +16,8 @@
|
|
|
16
16
|
* ({@link SourceDeclarationRaw}). A group's `key` travels as `group`: the bus redacts any field NAMED `key`
|
|
17
17
|
* (`@lensmcp/core` `isSecretParam`), which would have turned every group into `[REDACTED]`. The cluster MIRRORS
|
|
18
18
|
* these shapes (it does not depend on this package); a parity fixture pins both sides.
|
|
19
|
-
* 3. The READ — `apps/agent` folds them into `process://sources` ({@link SourcesReport}); the `
|
|
20
|
-
* `
|
|
19
|
+
* 3. The READ — `apps/agent` folds them into `process://sources` ({@link SourcesReport}); the `observe_sources` and
|
|
20
|
+
* `source_get` tools, the status signal and the dashboard read that.
|
|
21
21
|
*
|
|
22
22
|
* Phase 2 adds:
|
|
23
23
|
* - the `loop` kind — a background loop, scheduler or sweep answering `lensmcp.loop/v1` ({@link LoopSnapshotRaw});
|
|
@@ -546,7 +546,7 @@ export interface SourcePushedEvent {
|
|
|
546
546
|
counterpart?: string;
|
|
547
547
|
correlation?: string;
|
|
548
548
|
error?: string;
|
|
549
|
-
/** The flow it ran in — open it with
|
|
549
|
+
/** The flow it ran in — open it with flow_get. */
|
|
550
550
|
flowId?: string;
|
|
551
551
|
requestId?: string;
|
|
552
552
|
}
|
package/lib/sources.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";var
|
|
1
|
+
"use strict";var T=Object.defineProperty;var a=(t,r)=>T(t,"name",{value:r,configurable:!0});var U=Object.defineProperty,e=a((t,r)=>U(t,"name",{value:r,configurable:!0}),"r");export const SOURCE_KINDS=["queue","loop","store","traffic"],SOURCE_KINDS_READ=["queue","loop","store","traffic"],sourceWireSchema=e(t=>`lensmcp.${t}/v1`,"sourceWireSchema"),QUEUE_WIRE_SCHEMA="lensmcp.queue/v1",LOOP_WIRE_SCHEMA="lensmcp.loop/v1",STORE_WIRE_SCHEMA="lensmcp.store/v1",TRAFFIC_WIRE_SCHEMA="lensmcp.traffic/v1",SOURCE_SNAPSHOT_FIELD={queue:"snapshot",loop:"loop",store:"store",traffic:"traffic"},URI_SOURCES="process://sources",SOURCE_PROVENANCE="reported",QUEUE_OLDEST_WAIT_RULE="queue/oldest-wait",QUEUE_STALLED_RULE="queue/stalled",LOOP_OVERDUE_RULE="loop/overdue",LOOP_FAILING_RULE="loop/failing",LOOP_IDLE_RULE="loop/idle-while-fed",STORE_QUOTA_RULE="store/near-quota",STORE_ERRORS_RULE="store/errors",STORE_ORPHANS_RULE="store/orphans",TRAFFIC_FAILURES_RULE="traffic/failures",TRAFFIC_LATENCY_RULE="traffic/latency",TRAFFIC_RATE_LIMITED_RULE="traffic/rate-limited",SOURCE_RULES=[QUEUE_OLDEST_WAIT_RULE,QUEUE_STALLED_RULE,LOOP_OVERDUE_RULE,LOOP_FAILING_RULE,LOOP_IDLE_RULE,STORE_QUOTA_RULE,STORE_ERRORS_RULE,STORE_ORPHANS_RULE,TRAFFIC_FAILURES_RULE,TRAFFIC_LATENCY_RULE,TRAFFIC_RATE_LIMITED_RULE],SOURCE_EVENT_KINDS=["source-poll","source-declaration","source-event"],CUSTOM_EVENT_SOURCE="custom",QUEUE_EVENTS=["enqueued","admitted","completed","failed","parked"],LOOP_EVENTS=["run-start","run-end"],LOOP_OUTCOMES=["ok","failed","skipped"],STORE_EVENTS=["write","delete","error"],TRAFFIC_EVENTS=["inbound","outbound"],TRAFFIC_OUTCOMES=["ok","failed","rate-limited"],SOURCE_PUSH_EVENTS={queue:QUEUE_EVENTS,loop:LOOP_EVENTS,store:STORE_EVENTS,traffic:TRAFFIC_EVENTS},SOURCE_PUSH_OUTCOMES={queue:[],loop:LOOP_OUTCOMES,store:[],traffic:TRAFFIC_OUTCOMES},SOURCE_POLL_STATES=["current","unreachable","refused","malformed","not-running"],SOURCE_STATES=[...SOURCE_POLL_STATES,"stale","never-polled"],SOURCE_DEFAULT_INTERVAL_SEC=10,SOURCE_MIN_INTERVAL_SEC=2,QUEUE_DEFAULT_OLDEST_WAIT_MIN=10,QUEUE_DEFAULT_STALLED_MIN=15,LOOP_DEFAULT_IDLE_MIN=10,LOOP_OVERDUE_INTERVALS=2,LOOP_FAILING_RUNS=3,SOURCE_FULL_REPORT_MS=6e4,SOURCE_HISTORY_POINTS=60,SOURCE_RUNS_KEPT=30,SOURCE_PUSHED_KEPT=20,STORE_DEFAULT_QUOTA_PCT=90,STORE_DEFAULT_ERROR_RATE_PCT=5,STORE_DEFAULT_ORPHAN_MIN=60,TRAFFIC_DEFAULT_FAILURE_PCT=5,TRAFFIC_DEFAULT_P95_MS=2e3,TRAFFIC_DEFAULT_RATE_LIMITED=1,TRAFFIC_MIN_MESSAGES=10,TRAFFIC_PUSH_WINDOW_MS=10*6e4,TRAFFIC_PUSH_CHANNELS=50,TRAFFIC_PUSH_EVENTS_PER_CHANNEL=1e3,SOURCE_MAX_GROUPS=500,SOURCE_MAX_BYTES=256*1024,SOURCE_STALE_PERIODS=3,SOURCE_STALE_MIN_MS=3e4;export function sourceStaleAfterMs(t){return Math.max(SOURCE_STALE_MIN_MS,SOURCE_STALE_PERIODS*Math.max(0,t))}a(sourceStaleAfterMs,"sourceStaleAfterMs"),e(sourceStaleAfterMs,"sourceStaleAfterMs");const n=e(t=>typeof t=="object"&&t!==null&&!Array.isArray(t),"isObj"),s=e(t=>typeof t=="number"&&Number.isInteger(t)&&t>=0,"isCount"),E=e(t=>typeof t=="number"&&Number.isFinite(t)&&t>0,"isTime"),u=e((t,r)=>typeof t=="string"&&t.length>0&&t.length<=r,"isStr"),v=e(t=>t===void 0||typeof t=="number"&&t>0,"isMin");function _(t){if(!SOURCE_KINDS_READ.includes(t.sourceKind)||typeof t.path!="string"&&!(t.path===void 0&&(t.sourceKind==="traffic"||t.sourceKind==="loop"))||!u(t.name,200)||typeof t.intervalSec!="number"||t.feeds!==void 0&&!u(t.feeds,200))return!1;const r=t.thresholds;if(!n(r))return!1;for(const o of["stalledMin","idleMin","oldestWaitMin","quotaPct","errorRatePct","orphanMin","failurePct","p95Ms","rateLimited"])if(!v(r[o]))return!1;return t.sourceKind!=="queue"||typeof r.oldestWaitMin=="number"}a(_,"l"),e(_,"asDecl");const l=e(t=>t===null||typeof t=="string","isIsoOrNull"),c=e(t=>t===void 0||s(t),"isOptCount");function d(t){if(!n(t)||typeof t.at!="string"||!E(t.receivedAt)||!E(t.intervalSec)||!l(t.lastRunAt)||t.nextRunAt!==void 0&&!l(t.nextRunAt))return!1;for(const r of["lastDurationMs","lastItems","runsInWindow","itemsInWindow","failuresInWindow","windowSec"])if(!c(t[r]))return!1;return t.lastOutcome!==void 0&&!LOOP_OUTCOMES.includes(t.lastOutcome)?!1:t.lastError===void 0||typeof t.lastError=="string"}a(d,"_"),e(d,"asLoopSnapshot");const f=e(t=>t===void 0||n(t)&&Object.values(t).every(r=>typeof r=="string"),"isLabels");function S(t){if(!n(t)||typeof t.at!="string"||!E(t.receivedAt)||!s(t.objects)||!s(t.bytes)||t.quotaBytes!==void 0&&t.quotaBytes!==null&&!s(t.quotaBytes))return!1;for(const i of["opsInWindow","writesInWindow","deletesInWindow","errorsInWindow","windowSec"])if(!c(t[i]))return!1;if(t.lastWriteAt!==void 0&&!l(t.lastWriteAt)||t.lastError!==void 0&&typeof t.lastError!="string")return!1;const r=t.truncated;if(r!==void 0&&!(n(r)&&s(r.groups)))return!1;const o=t.groups;return o===void 0?!0:Array.isArray(o)&&o.length<=SOURCE_MAX_GROUPS&&o.every(i=>n(i)&&u(i.group,1e3)&&s(i.objects)&&s(i.bytes)&&f(i.labels))}a(S,"S"),e(S,"asStoreSnapshot");function p(t){if(!n(t)||typeof t.at!="string"||!E(t.receivedAt)||!Array.isArray(t.channels)||!c(t.windowSec))return!1;const r=t.truncated;return r!==void 0&&!(n(r)&&s(r.channels))?!1:t.channels.length<=SOURCE_MAX_GROUPS&&t.channels.every(o=>{if(!n(o)||!u(o.channel,1e3)||!f(o.labels)||o.direction!==void 0&&o.direction!=="inbound"&&o.direction!=="outbound"||o.counterpart!==void 0&&!u(o.counterpart,200))return!1;for(const i of["messagesInWindow","failuresInWindow","rateLimitedInWindow"])if(!c(o[i]))return!1;return o.p95Ms!==void 0&&!(typeof o.p95Ms=="number"&&Number.isFinite(o.p95Ms)&&o.p95Ms>=0)||o.lastAt!==void 0&&!l(o.lastAt)?!1:o.lastError===void 0||typeof o.lastError=="string"})}a(p,"R"),e(p,"asTrafficSnapshot");function R(t){return n(t)&&u(t.digest,100)&&typeof t.at=="string"&&E(t.receivedAt)}a(R,"A"),e(R,"asSame");function A(t){if(!n(t)||!u(t.group,1e3)||!s(t.pending))return!1;for(const i of["inFlight","failed","completedInWindow"])if(t[i]!==void 0&&!s(t[i]))return!1;const r=t.oldestPendingAt;if(r!=null&&typeof r!="string")return!1;const o=t.labels;return o===void 0||n(o)&&Object.values(o).every(i=>typeof i=="string")}a(A,"O"),e(A,"asGroup");function O(t){if(!n(t)||typeof t.at!="string"||!E(t.receivedAt)||!Array.isArray(t.groups))return!1;const r=t.totals;if(!n(r)||!s(r.groups)||!s(r.pending)||!s(r.inFlight)||!s(r.failed))return!1;const o=t.truncated;return o!==void 0&&!(n(o)&&s(o.groups))?!1:t.groups.length<=SOURCE_MAX_GROUPS&&t.groups.every(A)}a(O,"T"),e(O,"asSnapshot");export function asSourcePollRaw(t){if(!n(t)||t.kind!=="source-poll"||!u(t.project,200)||!_(t)||!SOURCE_POLL_STATES.includes(t.state)||!E(t.polledAt)||!E(t.reportEveryMs)||t.path===void 0)return;const r=SOURCE_SNAPSHOT_FIELD[t.sourceKind];for(const i of Object.values(SOURCE_SNAPSHOT_FIELD))if(i!==r&&t[i]!==void 0)return;const o={snapshot:O,loop:d,store:S,traffic:p}[r];if(!(t[r]!==void 0&&!o(t[r]))&&!(t.same!==void 0&&(!R(t.same)||t[r]!==void 0))&&!(t.state==="current"&&t[r]===void 0&&t.same===void 0))return t}a(asSourcePollRaw,"asSourcePollRaw"),e(asSourcePollRaw,"asSourcePollRaw");export function asSourceEventRaw(t){if(!n(t)||t.kind!=="source-event"||!u(t.project,200)||!u(t.name,200))return;const r=t.sourceKind;if(SOURCE_KINDS_READ.includes(r)&&SOURCE_PUSH_EVENTS[r].includes(t.event)&&!(t.item!==void 0&&!u(t.item,200)||t.group!==void 0&&!u(t.group,200))&&!(!c(t.items)||!c(t.durationMs)||!c(t.bytes))&&!(t.outcome!==void 0&&!SOURCE_PUSH_OUTCOMES[r].includes(t.outcome))){for(const o of["object","channel","counterpart","correlation"])if(t[o]!==void 0&&!u(t[o],200))return;if(!(t.error!==void 0&&typeof t.error!="string"))return t}}a(asSourceEventRaw,"asSourceEventRaw"),e(asSourceEventRaw,"asSourceEventRaw");export function asSourceDeclarationRaw(t){if(!(!n(t)||t.kind!=="source-declaration"||!u(t.project,200))&&!(!Array.isArray(t.sources)||!t.sources.every(r=>n(r)&&_(r)))&&!(!Array.isArray(t.problems)||!t.problems.every(r=>typeof r=="string")))return t}a(asSourceDeclarationRaw,"asSourceDeclarationRaw"),e(asSourceDeclarationRaw,"asSourceDeclarationRaw");
|