lensmcp 1.16.6 → 1.16.9
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.
|
@@ -33558,7 +33558,7 @@ var require_chrome_remote_interface = __commonJS({
|
|
|
33558
33558
|
});
|
|
33559
33559
|
|
|
33560
33560
|
// libs/browser-capture/src/capture-runner.ts
|
|
33561
|
-
import { appendFileSync, readFileSync } from "node:fs";
|
|
33561
|
+
import { appendFileSync, readFileSync, renameSync, statSync } from "node:fs";
|
|
33562
33562
|
|
|
33563
33563
|
// libs/visual-engine/dist/lib/diff.js
|
|
33564
33564
|
var LAYOUT_TOLERANCE_PX = 0.5;
|
|
@@ -34709,6 +34709,21 @@ function safe(fn) {
|
|
|
34709
34709
|
}
|
|
34710
34710
|
|
|
34711
34711
|
// libs/browser-capture/src/capture-runner.ts
|
|
34712
|
+
var MAX_EVENT_BYTES = (() => {
|
|
34713
|
+
const n = Number(process.env["LENSMCP_EVENT_MAX_BYTES"]);
|
|
34714
|
+
return Number.isFinite(n) && n > 0 ? n : 256 * 1024 * 1024;
|
|
34715
|
+
})();
|
|
34716
|
+
var ROTATE_CHECK_BYTES = 1024 * 1024;
|
|
34717
|
+
var bytesSinceCheck = 0;
|
|
34718
|
+
function rotateIfLarge(file, lineBytes) {
|
|
34719
|
+
bytesSinceCheck += lineBytes;
|
|
34720
|
+
if (bytesSinceCheck < ROTATE_CHECK_BYTES) return;
|
|
34721
|
+
bytesSinceCheck = 0;
|
|
34722
|
+
try {
|
|
34723
|
+
if (statSync(file).size > MAX_EVENT_BYTES) renameSync(file, `${file}.1`);
|
|
34724
|
+
} catch {
|
|
34725
|
+
}
|
|
34726
|
+
}
|
|
34712
34727
|
async function main() {
|
|
34713
34728
|
const url = process.env["LENSMCP_DEV_URL"];
|
|
34714
34729
|
const eventFile = process.env["LENSMCP_EVENT_FILE"];
|
|
@@ -34718,7 +34733,9 @@ async function main() {
|
|
|
34718
34733
|
}
|
|
34719
34734
|
const sink = eventFile ? (e) => {
|
|
34720
34735
|
try {
|
|
34721
|
-
|
|
34736
|
+
const line = JSON.stringify(e) + "\n";
|
|
34737
|
+
rotateIfLarge(eventFile, line.length);
|
|
34738
|
+
appendFileSync(eventFile, line);
|
|
34722
34739
|
} catch {
|
|
34723
34740
|
}
|
|
34724
34741
|
} : (e) => {
|
package/bundled/dashboard.js
CHANGED
|
@@ -19859,17 +19859,21 @@ function trimFlowEvent(event) {
|
|
|
19859
19859
|
const toolCalls = Array.isArray(raw["toolCalls"]) ? raw["toolCalls"] : [];
|
|
19860
19860
|
const tok = `${num(usage["promptTokens"]) ?? "?"}\u2192${num(usage["completionTokens"]) ?? "?"} tok`;
|
|
19861
19861
|
const tools = toolCalls.length ? ` \xB7 ${toolCalls.length} tool call${toolCalls.length === 1 ? "" : "s"}` : "";
|
|
19862
|
-
|
|
19862
|
+
const latency = num(raw["durationMs"]) !== void 0 ? ` \xB7 ${(num(raw["durationMs"]) / 1e3).toFixed(1)}s` : "";
|
|
19863
|
+
detail = `${model["provider"] ?? ""}/${model["model"] ?? ""} \xB7 ${tok}${tools}${latency}`;
|
|
19863
19864
|
} else if (kind === "ai-turn-start") {
|
|
19864
19865
|
const tools = Array.isArray(raw["tools"]) ? raw["tools"] : [];
|
|
19865
19866
|
detail = `skill ${raw["skill"] ?? ""} \xB7 ${raw["output"] ?? ""}${tools.length ? " \xB7 tools: " + tools.join(", ") : ""}`;
|
|
19866
19867
|
} else if (kind === "ai-tool-call") {
|
|
19867
19868
|
const call = raw["call"] ?? {};
|
|
19868
19869
|
const result = raw["result"] ?? {};
|
|
19869
|
-
|
|
19870
|
+
const took = num(raw["durationMs"]) !== void 0 ? ` \xB7 ${(num(raw["durationMs"]) / 1e3).toFixed(1)}s` : "";
|
|
19871
|
+
detail = `${call["name"] ?? "tool"} ${result["error"] != null ? "\u2717 " + String(result["error"]) : "\u2713"}${took}`;
|
|
19870
19872
|
} else if (kind === "ai-turn-end") {
|
|
19871
19873
|
const usage = raw["usage"] ?? {};
|
|
19872
|
-
|
|
19874
|
+
const rounds = num(raw["rounds"]) !== void 0 ? ` \xB7 ${num(raw["rounds"])} round${num(raw["rounds"]) === 1 ? "" : "s"}` : "";
|
|
19875
|
+
const total = num(raw["durationMs"]) !== void 0 ? ` \xB7 ${(num(raw["durationMs"]) / 1e3).toFixed(1)}s` : "";
|
|
19876
|
+
detail = `${raw["ok"] === false ? "FAILED" : "ok"} \xB7 ${num(usage["promptTokens"]) ?? "?"}+${num(usage["completionTokens"]) ?? "?"} tok${rounds}${total}`;
|
|
19873
19877
|
}
|
|
19874
19878
|
}
|
|
19875
19879
|
let sig;
|
|
@@ -21074,7 +21078,7 @@ var PAGE = `<!doctype html>
|
|
|
21074
21078
|
var model = ai.model || {};
|
|
21075
21079
|
meta('round ' + (ai.round != null ? ai.round : '?') + ' \xB7 ' + (model.provider || '') + '/' + (model.model || '') + (model.promptVersion ? ' \xB7 ' + model.promptVersion : ''));
|
|
21076
21080
|
var u = ai.usage || {};
|
|
21077
|
-
meta('tokens: ' + (u.promptTokens != null ? u.promptTokens : '?') + ' prompt \u2192 ' + (u.completionTokens != null ? u.completionTokens : '?') + ' completion' + (u.costCents != null ? ' \xB7 ' + u.costCents + '\xA2' : ''));
|
|
21081
|
+
meta('tokens: ' + (u.promptTokens != null ? u.promptTokens : '?') + ' prompt \u2192 ' + (u.completionTokens != null ? u.completionTokens : '?') + ' completion' + (u.costCents != null ? ' \xB7 ' + u.costCents + '\xA2' : '') + (ai.durationMs != null ? ' \xB7 ' + (ai.durationMs / 1000).toFixed(1) + 's LLM latency' : ''));
|
|
21078
21082
|
var prompt = Array.isArray(ai.prompt) ? ai.prompt : [];
|
|
21079
21083
|
label('Prompt \xB7 ' + prompt.length + ' message' + (prompt.length === 1 ? '' : 's'));
|
|
21080
21084
|
prompt.forEach(function (m) {
|
|
@@ -21092,18 +21096,20 @@ var PAGE = `<!doctype html>
|
|
|
21092
21096
|
if (Array.isArray(ai.capabilities) && ai.capabilities.length) meta('capabilities: ' + ai.capabilities.join(', '));
|
|
21093
21097
|
meta('tenant: ' + (ai.tenantId || '\u2014') + ' \xB7 caller: ' + ((ai.caller && ai.caller.callerKind) || '\u2014') + (ai.caller && ai.caller.userId ? ' (' + ai.caller.userId + ')' : ''));
|
|
21094
21098
|
if (Array.isArray(ai.tools) && ai.tools.length) { label('Tools \xB7 ' + ai.tools.length); block(ai.tools.join('\\n')); }
|
|
21099
|
+
if (ai.skillPlan != null) { label('Skill plan (converse)'); block(aiText(ai.skillPlan)); }
|
|
21100
|
+
if (ai.signals != null && String(ai.signals).length) { label('Live signals (the knowledge this turn caught)'); block(aiText(ai.signals)); }
|
|
21095
21101
|
if (ai.systemPrompt != null) { label('System prompt' + (ai.promptVersion ? ' \xB7 ' + ai.promptVersion : '')); block(aiText(ai.systemPrompt)); }
|
|
21096
21102
|
if (ai.input != null) { label('Input'); block(aiText(ai.input)); }
|
|
21097
21103
|
} else if (kind === 'ai-tool-call') {
|
|
21098
21104
|
var call = ai.call || {}; var result = ai.result || {};
|
|
21099
|
-
meta('tool: ' + (call.name || '') + ' \xB7 round ' + (ai.round != null ? ai.round : '?'));
|
|
21105
|
+
meta('tool: ' + (call.name || '') + ' \xB7 round ' + (ai.round != null ? ai.round : '?') + (ai.durationMs != null ? ' \xB7 took ' + (ai.durationMs / 1000).toFixed(1) + 's' : ''));
|
|
21100
21106
|
label('Input'); block(aiText(call.input));
|
|
21101
21107
|
if (result.error != null) { label('Error'); block(aiText(result.error)); }
|
|
21102
21108
|
else { label('Output'); block(aiText(result.output)); }
|
|
21103
21109
|
} else if (kind === 'ai-turn-end') {
|
|
21104
21110
|
meta((ai.ok === false ? 'FAILED' : 'ok') + ' \xB7 skill: ' + (ai.skill || ''));
|
|
21105
21111
|
var ue = ai.usage || {};
|
|
21106
|
-
meta('totals: ' + (ue.promptTokens != null ? ue.promptTokens : '?') + ' prompt + ' + (ue.completionTokens != null ? ue.completionTokens : '?') + ' completion' + (ue.costCents != null ? ' \xB7 ' + ue.costCents + '\xA2' : ''));
|
|
21112
|
+
meta('totals: ' + (ue.promptTokens != null ? ue.promptTokens : '?') + ' prompt + ' + (ue.completionTokens != null ? ue.completionTokens : '?') + ' completion' + (ue.costCents != null ? ' \xB7 ' + ue.costCents + '\xA2' : '') + (ai.rounds != null ? ' \xB7 ' + ai.rounds + ' round' + (ai.rounds === 1 ? '' : 's') : '') + (ai.durationMs != null ? ' \xB7 ' + (ai.durationMs / 1000).toFixed(1) + 's total' : ''));
|
|
21107
21113
|
if (Array.isArray(ai.modelPins) && ai.modelPins.length) { label('Model pins \xB7 per round'); block(aiText(ai.modelPins)); }
|
|
21108
21114
|
if (ai.output != null) { label('Output'); block(aiText(ai.output)); }
|
|
21109
21115
|
if (ai.error != null) { label('Error'); block(aiText(ai.error)); }
|
package/package.json
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"name": "lensmcp",
|
|
3
3
|
"displayName": "LensMCP",
|
|
4
4
|
"description": "The observability lens for coding agents. One command brings up the dev cluster gateway (every project.json `cluster` decl → its host on :443), the per-project lens dashboard at https://lensmcp.local/<project>/, and the MCP server your agent connects to — scoped automatically to whatever project you opened Claude Code in.",
|
|
5
|
-
"version": "1.16.
|
|
5
|
+
"version": "1.16.9",
|
|
6
6
|
"author": {
|
|
7
7
|
"name": "David Antoon",
|
|
8
8
|
"email": "davidmantoon@gmail.com"
|
|
@@ -54,6 +54,12 @@ bootstrap stay available even while the gate is closed.
|
|
|
54
54
|
|
|
55
55
|
4. Watch it as a human anytime with `/lensmcp:dashboard`.
|
|
56
56
|
|
|
57
|
+
**Reading `input-change` flows:** one flow = one EDITING BURST, not one keystroke — trusted typing on the
|
|
58
|
+
same element coalesces under a sliding ~2s window, and a PROGRAMMATIC value stream (an AI assistant
|
|
59
|
+
streaming text into an input — untrusted events) mints no flow at all: its effects attribute to the
|
|
60
|
+
interaction that triggered it (the "send" click's flow). If you expect per-keystroke granularity, look at
|
|
61
|
+
the events INSIDE the burst flow instead of counting flows.
|
|
62
|
+
|
|
57
63
|
## Tips
|
|
58
64
|
|
|
59
65
|
- If a tool returns nothing, no events have been produced yet — start the gateway (or an
|