@monoes/monomindcli 2.13.0 → 2.14.1
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/.claude/skills/monodesign/scripts/context.mjs +1 -1
- package/.claude/skills/monodesign/scripts/detector/detect-antipatterns-browser.js +2 -2
- package/.claude/skills/monodesign/scripts/detector/rules/checks.mjs +2 -2
- package/.claude/skills/monodesign/scripts/live-browser.js +1 -1
- package/bin/cli.js +21 -1
- package/bin/mcp-server.js +21 -1
- package/dist/src/capabilities/cap-documents.d.ts.map +1 -1
- package/dist/src/capabilities/cap-documents.js +23 -0
- package/dist/src/capabilities/cap-documents.js.map +1 -1
- package/dist/src/commands/doc-filters.d.ts +19 -0
- package/dist/src/commands/doc-filters.d.ts.map +1 -0
- package/dist/src/commands/doc-filters.js +58 -0
- package/dist/src/commands/doc-filters.js.map +1 -0
- package/dist/src/commands/doc-library.d.ts +21 -0
- package/dist/src/commands/doc-library.d.ts.map +1 -0
- package/dist/src/commands/doc-library.js +390 -0
- package/dist/src/commands/doc-library.js.map +1 -0
- package/dist/src/commands/doc-list.d.ts +9 -0
- package/dist/src/commands/doc-list.d.ts.map +1 -0
- package/dist/src/commands/doc-list.js +99 -0
- package/dist/src/commands/doc-list.js.map +1 -0
- package/dist/src/commands/doc.d.ts.map +1 -1
- package/dist/src/commands/doc.js +49 -37
- package/dist/src/commands/doc.js.map +1 -1
- package/dist/src/commands/doctor-mcp-probe.d.ts +48 -0
- package/dist/src/commands/doctor-mcp-probe.d.ts.map +1 -0
- package/dist/src/commands/doctor-mcp-probe.js +205 -0
- package/dist/src/commands/doctor-mcp-probe.js.map +1 -0
- package/dist/src/commands/doctor-project-checks.d.ts +12 -1
- package/dist/src/commands/doctor-project-checks.d.ts.map +1 -1
- package/dist/src/commands/doctor-project-checks.js +55 -4
- package/dist/src/commands/doctor-project-checks.js.map +1 -1
- package/dist/src/commands/doctor.d.ts.map +1 -1
- package/dist/src/commands/doctor.js +10 -1
- package/dist/src/commands/doctor.js.map +1 -1
- package/dist/src/commands/init.d.ts.map +1 -1
- package/dist/src/commands/init.js +17 -0
- package/dist/src/commands/init.js.map +1 -1
- package/dist/src/commands/mcp.d.ts.map +1 -1
- package/dist/src/commands/mcp.js +4 -3
- package/dist/src/commands/mcp.js.map +1 -1
- package/dist/src/commands/org-observe.d.ts.map +1 -1
- package/dist/src/commands/org-observe.js +14 -0
- package/dist/src/commands/org-observe.js.map +1 -1
- package/dist/src/commands/org.d.ts.map +1 -1
- package/dist/src/commands/org.js +12 -2
- package/dist/src/commands/org.js.map +1 -1
- package/dist/src/init/claudemd-generator.d.ts.map +1 -1
- package/dist/src/init/claudemd-generator.js +2 -1
- package/dist/src/init/claudemd-generator.js.map +1 -1
- package/dist/src/init/mcp-generator.d.ts.map +1 -1
- package/dist/src/init/mcp-generator.js +3 -3
- package/dist/src/init/mcp-generator.js.map +1 -1
- package/dist/src/init/types.d.ts +6 -0
- package/dist/src/init/types.d.ts.map +1 -1
- package/dist/src/init/types.js.map +1 -1
- package/dist/src/init/write-runtime-config.d.ts.map +1 -1
- package/dist/src/init/write-runtime-config.js +12 -2
- package/dist/src/init/write-runtime-config.js.map +1 -1
- package/dist/src/knowledge/capture-envelope.d.ts +80 -0
- package/dist/src/knowledge/capture-envelope.d.ts.map +1 -0
- package/dist/src/knowledge/capture-envelope.js +165 -0
- package/dist/src/knowledge/capture-envelope.js.map +1 -0
- package/dist/src/knowledge/capture-text.d.ts +23 -0
- package/dist/src/knowledge/capture-text.d.ts.map +1 -0
- package/dist/src/knowledge/capture-text.js +49 -0
- package/dist/src/knowledge/capture-text.js.map +1 -0
- package/dist/src/knowledge/citation.d.ts +121 -0
- package/dist/src/knowledge/citation.d.ts.map +1 -0
- package/dist/src/knowledge/citation.js +252 -0
- package/dist/src/knowledge/citation.js.map +1 -0
- package/dist/src/knowledge/document-pipeline.d.ts +60 -0
- package/dist/src/knowledge/document-pipeline.d.ts.map +1 -1
- package/dist/src/knowledge/document-pipeline.js +188 -4
- package/dist/src/knowledge/document-pipeline.js.map +1 -1
- package/dist/src/knowledge/html-extract.d.ts +43 -0
- package/dist/src/knowledge/html-extract.d.ts.map +1 -0
- package/dist/src/knowledge/html-extract.js +286 -0
- package/dist/src/knowledge/html-extract.js.map +1 -0
- package/dist/src/knowledge/html-tags.d.ts +30 -0
- package/dist/src/knowledge/html-tags.d.ts.map +1 -0
- package/dist/src/knowledge/html-tags.js +229 -0
- package/dist/src/knowledge/html-tags.js.map +1 -0
- package/dist/src/knowledge/library.d.ts +106 -0
- package/dist/src/knowledge/library.d.ts.map +1 -0
- package/dist/src/knowledge/library.js +195 -0
- package/dist/src/knowledge/library.js.map +1 -0
- package/dist/src/knowledge/mhtml.d.ts +60 -0
- package/dist/src/knowledge/mhtml.d.ts.map +1 -0
- package/dist/src/knowledge/mhtml.js +154 -0
- package/dist/src/knowledge/mhtml.js.map +1 -0
- package/dist/src/knowledge/related.d.ts +58 -0
- package/dist/src/knowledge/related.d.ts.map +1 -0
- package/dist/src/knowledge/related.js +222 -0
- package/dist/src/knowledge/related.js.map +1 -0
- package/dist/src/knowledge/section-diff.d.ts +48 -0
- package/dist/src/knowledge/section-diff.d.ts.map +1 -0
- package/dist/src/knowledge/section-diff.js +151 -0
- package/dist/src/knowledge/section-diff.js.map +1 -0
- package/dist/src/knowledge/watch.d.ts +92 -0
- package/dist/src/knowledge/watch.d.ts.map +1 -0
- package/dist/src/knowledge/watch.js +221 -0
- package/dist/src/knowledge/watch.js.map +1 -0
- package/dist/src/mcp-server.d.ts.map +1 -1
- package/dist/src/mcp-server.js +44 -87
- package/dist/src/mcp-server.js.map +1 -1
- package/dist/src/mcp-tools/browser-instrument-tools.d.ts +35 -0
- package/dist/src/mcp-tools/browser-instrument-tools.d.ts.map +1 -0
- package/dist/src/mcp-tools/browser-instrument-tools.js +359 -0
- package/dist/src/mcp-tools/browser-instrument-tools.js.map +1 -0
- package/dist/src/mcp-tools/browser-metrics.d.ts +42 -0
- package/dist/src/mcp-tools/browser-metrics.d.ts.map +1 -0
- package/dist/src/mcp-tools/browser-metrics.js +91 -0
- package/dist/src/mcp-tools/browser-metrics.js.map +1 -0
- package/dist/src/mcp-tools/browser-profile-tools.d.ts +16 -0
- package/dist/src/mcp-tools/browser-profile-tools.d.ts.map +1 -0
- package/dist/src/mcp-tools/browser-profile-tools.js +324 -0
- package/dist/src/mcp-tools/browser-profile-tools.js.map +1 -0
- package/dist/src/mcp-tools/browser-session.d.ts +68 -0
- package/dist/src/mcp-tools/browser-session.d.ts.map +1 -0
- package/dist/src/mcp-tools/browser-session.js +224 -0
- package/dist/src/mcp-tools/browser-session.js.map +1 -0
- package/dist/src/mcp-tools/browser-tools.d.ts.map +1 -1
- package/dist/src/mcp-tools/browser-tools.js +10 -176
- package/dist/src/mcp-tools/browser-tools.js.map +1 -1
- package/dist/src/mcp-tools/capture-resource-read.d.ts +115 -0
- package/dist/src/mcp-tools/capture-resource-read.d.ts.map +1 -0
- package/dist/src/mcp-tools/capture-resource-read.js +296 -0
- package/dist/src/mcp-tools/capture-resource-read.js.map +1 -0
- package/dist/src/mcp-tools/capture-resource-tools.d.ts +22 -0
- package/dist/src/mcp-tools/capture-resource-tools.d.ts.map +1 -0
- package/dist/src/mcp-tools/capture-resource-tools.js +182 -0
- package/dist/src/mcp-tools/capture-resource-tools.js.map +1 -0
- package/dist/src/mcp-tools/capture-resources.d.ts +142 -0
- package/dist/src/mcp-tools/capture-resources.d.ts.map +1 -0
- package/dist/src/mcp-tools/capture-resources.js +289 -0
- package/dist/src/mcp-tools/capture-resources.js.map +1 -0
- package/dist/src/mcp-tools/index.d.ts +3 -0
- package/dist/src/mcp-tools/index.d.ts.map +1 -1
- package/dist/src/mcp-tools/index.js +6 -0
- package/dist/src/mcp-tools/index.js.map +1 -1
- package/dist/src/mcp-tools/knowledge-tools.d.ts.map +1 -1
- package/dist/src/mcp-tools/knowledge-tools.js +9 -1
- package/dist/src/mcp-tools/knowledge-tools.js.map +1 -1
- package/dist/src/mcp-tools/resource-router.d.ts +86 -0
- package/dist/src/mcp-tools/resource-router.d.ts.map +1 -0
- package/dist/src/mcp-tools/resource-router.js +181 -0
- package/dist/src/mcp-tools/resource-router.js.map +1 -0
- package/dist/src/memory/memory-bridge.js +1 -1
- package/dist/src/memory/memory-bridge.js.map +1 -1
- package/dist/src/orgrt/agent-runner.d.ts +38 -0
- package/dist/src/orgrt/agent-runner.d.ts.map +1 -1
- package/dist/src/orgrt/agent-runner.js +47 -0
- package/dist/src/orgrt/agent-runner.js.map +1 -1
- package/dist/src/orgrt/checkpoint.d.ts +12 -1
- package/dist/src/orgrt/checkpoint.d.ts.map +1 -1
- package/dist/src/orgrt/checkpoint.js +15 -6
- package/dist/src/orgrt/checkpoint.js.map +1 -1
- package/dist/src/orgrt/completion-gate.d.ts +74 -0
- package/dist/src/orgrt/completion-gate.d.ts.map +1 -1
- package/dist/src/orgrt/completion-gate.js +45 -0
- package/dist/src/orgrt/completion-gate.js.map +1 -1
- package/dist/src/orgrt/cost-tier.d.ts +144 -0
- package/dist/src/orgrt/cost-tier.d.ts.map +1 -0
- package/dist/src/orgrt/cost-tier.js +183 -0
- package/dist/src/orgrt/cost-tier.js.map +1 -0
- package/dist/src/orgrt/cross-org.d.ts.map +1 -1
- package/dist/src/orgrt/cross-org.js +14 -0
- package/dist/src/orgrt/cross-org.js.map +1 -1
- package/dist/src/orgrt/daemon.d.ts +12 -1
- package/dist/src/orgrt/daemon.d.ts.map +1 -1
- package/dist/src/orgrt/daemon.js +216 -49
- package/dist/src/orgrt/daemon.js.map +1 -1
- package/dist/src/orgrt/decisions.d.ts +14 -2
- package/dist/src/orgrt/decisions.d.ts.map +1 -1
- package/dist/src/orgrt/decisions.js +216 -10
- package/dist/src/orgrt/decisions.js.map +1 -1
- package/dist/src/orgrt/file-roots.d.ts +7 -0
- package/dist/src/orgrt/file-roots.d.ts.map +1 -1
- package/dist/src/orgrt/file-roots.js +38 -1
- package/dist/src/orgrt/file-roots.js.map +1 -1
- package/dist/src/orgrt/forwarder.d.ts.map +1 -1
- package/dist/src/orgrt/forwarder.js +16 -2
- package/dist/src/orgrt/forwarder.js.map +1 -1
- package/dist/src/orgrt/idle-deadline.d.ts +74 -1
- package/dist/src/orgrt/idle-deadline.d.ts.map +1 -1
- package/dist/src/orgrt/idle-deadline.js +52 -2
- package/dist/src/orgrt/idle-deadline.js.map +1 -1
- package/dist/src/orgrt/loadouts.d.ts +38 -0
- package/dist/src/orgrt/loadouts.d.ts.map +1 -0
- package/dist/src/orgrt/loadouts.js +129 -0
- package/dist/src/orgrt/loadouts.js.map +1 -0
- package/dist/src/orgrt/mailbox.d.ts +17 -1
- package/dist/src/orgrt/mailbox.d.ts.map +1 -1
- package/dist/src/orgrt/mailbox.js +50 -3
- package/dist/src/orgrt/mailbox.js.map +1 -1
- package/dist/src/orgrt/policy.d.ts +42 -2
- package/dist/src/orgrt/policy.d.ts.map +1 -1
- package/dist/src/orgrt/policy.js +53 -8
- package/dist/src/orgrt/policy.js.map +1 -1
- package/dist/src/orgrt/prompt-vars.d.ts +11 -0
- package/dist/src/orgrt/prompt-vars.d.ts.map +1 -0
- package/dist/src/orgrt/prompt-vars.js +49 -0
- package/dist/src/orgrt/prompt-vars.js.map +1 -0
- package/dist/src/orgrt/questions.d.ts +22 -1
- package/dist/src/orgrt/questions.d.ts.map +1 -1
- package/dist/src/orgrt/questions.js +24 -3
- package/dist/src/orgrt/questions.js.map +1 -1
- package/dist/src/orgrt/review-packet.d.ts +29 -0
- package/dist/src/orgrt/review-packet.d.ts.map +1 -0
- package/dist/src/orgrt/review-packet.js +67 -0
- package/dist/src/orgrt/review-packet.js.map +1 -0
- package/dist/src/orgrt/role-sandbox.d.ts.map +1 -1
- package/dist/src/orgrt/role-sandbox.js +16 -3
- package/dist/src/orgrt/role-sandbox.js.map +1 -1
- package/dist/src/orgrt/session-ledger.d.ts +68 -0
- package/dist/src/orgrt/session-ledger.d.ts.map +1 -0
- package/dist/src/orgrt/session-ledger.js +128 -0
- package/dist/src/orgrt/session-ledger.js.map +1 -0
- package/dist/src/orgrt/session.d.ts +45 -5
- package/dist/src/orgrt/session.d.ts.map +1 -1
- package/dist/src/orgrt/session.js +397 -27
- package/dist/src/orgrt/session.js.map +1 -1
- package/dist/src/orgrt/task-dag.d.ts +34 -1
- package/dist/src/orgrt/task-dag.d.ts.map +1 -1
- package/dist/src/orgrt/task-dag.js +58 -7
- package/dist/src/orgrt/task-dag.js.map +1 -1
- package/dist/src/orgrt/tool-spill.d.ts +94 -0
- package/dist/src/orgrt/tool-spill.d.ts.map +1 -0
- package/dist/src/orgrt/tool-spill.js +180 -0
- package/dist/src/orgrt/tool-spill.js.map +1 -0
- package/dist/src/orgrt/types.d.ts +138 -0
- package/dist/src/orgrt/types.d.ts.map +1 -1
- package/dist/src/orgrt/types.js +148 -0
- package/dist/src/orgrt/types.js.map +1 -1
- package/dist/src/platform-adapters/renderers/mcp.d.ts +20 -2
- package/dist/src/platform-adapters/renderers/mcp.d.ts.map +1 -1
- package/dist/src/platform-adapters/renderers/mcp.js +25 -5
- package/dist/src/platform-adapters/renderers/mcp.js.map +1 -1
- package/dist/src/protocol-capabilities.d.ts +2 -1
- package/dist/src/protocol-capabilities.d.ts.map +1 -1
- package/dist/src/protocol-capabilities.js +2 -1
- package/dist/src/protocol-capabilities.js.map +1 -1
- package/dist/src/ui/dashboard.html +450 -164
- package/dist/src/ui/org-hil.mjs +276 -0
- package/dist/src/ui/org-runtime.mjs +350 -0
- package/dist/src/ui/orgs.html +15 -4
- package/dist/src/ui/routes-org.mjs +290 -541
- package/dist/src/ui/server.mjs +25 -5
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +9 -8
|
@@ -0,0 +1,359 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Browser instrument tools: console output and network / HAR capture.
|
|
3
|
+
*
|
|
4
|
+
* monobrowse captures all of this already — these tools are the part an MCP
|
|
5
|
+
* client can reach. Output is shaped for an agent that has to decide what to
|
|
6
|
+
* do next: counts first, worst offenders first, long lists capped with an
|
|
7
|
+
* explicit note about what was dropped.
|
|
8
|
+
*
|
|
9
|
+
* Registered from `browser-tools.ts`; shared plumbing lives in
|
|
10
|
+
* `browser-session.ts`, and the performance/emulation half in
|
|
11
|
+
* `browser-profile-tools.ts`.
|
|
12
|
+
*/
|
|
13
|
+
import { fail, getConnection, ok, rejectFlagLike, resolveArtifactPath, touchSession, validateSessionId, } from './browser-session.js';
|
|
14
|
+
/** Longest console message text returned before it is elided. */
|
|
15
|
+
const MAX_MESSAGE_CHARS = 400;
|
|
16
|
+
const DEFAULT_LIMIT = 50;
|
|
17
|
+
const MAX_LIMIT = 500;
|
|
18
|
+
export function clampLimit(value, fallback = DEFAULT_LIMIT) {
|
|
19
|
+
const n = Number(value ?? fallback);
|
|
20
|
+
if (!Number.isFinite(n) || n <= 0)
|
|
21
|
+
return fallback;
|
|
22
|
+
return Math.min(Math.floor(n), MAX_LIMIT);
|
|
23
|
+
}
|
|
24
|
+
function elide(text) {
|
|
25
|
+
return text.length > MAX_MESSAGE_CHARS
|
|
26
|
+
? `${text.slice(0, MAX_MESSAGE_CHARS)}… (${text.length - MAX_MESSAGE_CHARS} more chars)`
|
|
27
|
+
: text;
|
|
28
|
+
}
|
|
29
|
+
const EXTENSION_TYPES = [
|
|
30
|
+
[/\.(js|mjs|cjs)$/, 'script'],
|
|
31
|
+
[/\.css$/, 'stylesheet'],
|
|
32
|
+
[/\.(png|jpe?g|gif|svg|webp|avif|ico|bmp)$/, 'image'],
|
|
33
|
+
[/\.(woff2?|ttf|otf|eot)$/, 'font'],
|
|
34
|
+
[/\.(mp4|webm|ogg|mp3|wav|m4a)$/, 'media'],
|
|
35
|
+
[/\.json$/, 'xhr'],
|
|
36
|
+
[/\.(html?|php)$/, 'document'],
|
|
37
|
+
];
|
|
38
|
+
/** Best-effort resource type — Chrome's capture records a MIME type, not a type. */
|
|
39
|
+
export function resourceType(url, mimeType) {
|
|
40
|
+
const m = (mimeType ?? '').toLowerCase();
|
|
41
|
+
if (m.startsWith('image/'))
|
|
42
|
+
return 'image';
|
|
43
|
+
if (m.startsWith('font/') || m.includes('font'))
|
|
44
|
+
return 'font';
|
|
45
|
+
if (m.startsWith('video/') || m.startsWith('audio/'))
|
|
46
|
+
return 'media';
|
|
47
|
+
if (m.includes('html'))
|
|
48
|
+
return 'document';
|
|
49
|
+
if (m.includes('css'))
|
|
50
|
+
return 'stylesheet';
|
|
51
|
+
if (m.includes('javascript') || m.includes('ecmascript'))
|
|
52
|
+
return 'script';
|
|
53
|
+
if (m.includes('json') || m.includes('xml') || m.includes('x-www-form'))
|
|
54
|
+
return 'xhr';
|
|
55
|
+
let pathname = url;
|
|
56
|
+
try {
|
|
57
|
+
pathname = new URL(url).pathname;
|
|
58
|
+
}
|
|
59
|
+
catch {
|
|
60
|
+
/* relative or data: URL — match against the raw string */
|
|
61
|
+
}
|
|
62
|
+
for (const [re, type] of EXTENSION_TYPES)
|
|
63
|
+
if (re.test(pathname.toLowerCase()))
|
|
64
|
+
return type;
|
|
65
|
+
return 'other';
|
|
66
|
+
}
|
|
67
|
+
function normalizeRequest(r) {
|
|
68
|
+
const url = r.url ?? '';
|
|
69
|
+
const duration = r.startTime !== undefined && r.endTime !== undefined
|
|
70
|
+
? Math.max(0, Math.round(r.endTime - r.startTime))
|
|
71
|
+
: undefined;
|
|
72
|
+
let outcome;
|
|
73
|
+
if (r.status === undefined)
|
|
74
|
+
outcome = r.endTime === undefined ? 'pending' : 'no-response';
|
|
75
|
+
else
|
|
76
|
+
outcome = r.status >= 400 ? 'http-error' : 'ok';
|
|
77
|
+
return {
|
|
78
|
+
url,
|
|
79
|
+
method: (r.method ?? 'GET').toUpperCase(),
|
|
80
|
+
status: r.status,
|
|
81
|
+
type: resourceType(url, r.mimeType),
|
|
82
|
+
durationMs: duration,
|
|
83
|
+
sizeBytes: r.encodedSize,
|
|
84
|
+
outcome,
|
|
85
|
+
};
|
|
86
|
+
}
|
|
87
|
+
function isFailure(r) {
|
|
88
|
+
return r.outcome === 'http-error' || r.outcome === 'no-response';
|
|
89
|
+
}
|
|
90
|
+
/** Glob → RegExp, matching the semantics monobrowse uses for route patterns. */
|
|
91
|
+
export function globToRegex(pattern) {
|
|
92
|
+
const escaped = pattern
|
|
93
|
+
.replace(/[-[\]{}()+.,\\^$|#\s]/g, '\\$&')
|
|
94
|
+
.replace(/\*\*/g, '\x00')
|
|
95
|
+
.replace(/\*/g, '[^/]*')
|
|
96
|
+
.replace(/\x00/g, '.*')
|
|
97
|
+
.replace(/\?/g, '[^/]');
|
|
98
|
+
return new RegExp(`^${escaped}$`);
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* Every request monobrowse holds for this CDP session: the live request
|
|
102
|
+
* capture plus anything the HAR recorder has buffered, deduped by id.
|
|
103
|
+
*/
|
|
104
|
+
export async function collectRequests(cdpSessionId) {
|
|
105
|
+
const { getCapturedRequests, getRequests } = await import('@monoes/monobrowse');
|
|
106
|
+
const byKey = new Map();
|
|
107
|
+
for (const r of getRequests(cdpSessionId))
|
|
108
|
+
byKey.set(r.id ?? `${r.method}|${r.url}`, r);
|
|
109
|
+
for (const r of getCapturedRequests(cdpSessionId))
|
|
110
|
+
byKey.set(r.id ?? `${r.method}|${r.url}`, r);
|
|
111
|
+
return [...byKey.values()].map(normalizeRequest);
|
|
112
|
+
}
|
|
113
|
+
// ---------------------------------------------------------------------------
|
|
114
|
+
// Tools
|
|
115
|
+
// ---------------------------------------------------------------------------
|
|
116
|
+
export const browserInstrumentTools = [
|
|
117
|
+
{
|
|
118
|
+
name: 'browser_console',
|
|
119
|
+
description: 'Read console output and uncaught page errors for a browser session — reach for this FIRST when a page misbehaves, before screenshotting or guessing. Capture is armed when the session connects (browser_open), so errors thrown during page load are included. Errors are listed before warnings before logs; filter with level, cap with limit, or clear the buffer to isolate the next interaction.',
|
|
120
|
+
category: 'browser',
|
|
121
|
+
tags: ['console', 'errors', 'debug'],
|
|
122
|
+
inputSchema: {
|
|
123
|
+
type: 'object',
|
|
124
|
+
properties: {
|
|
125
|
+
level: {
|
|
126
|
+
type: 'string',
|
|
127
|
+
enum: ['error', 'warning', 'all'],
|
|
128
|
+
description: 'error = errors only; warning = warnings and errors; all = everything (default)',
|
|
129
|
+
},
|
|
130
|
+
limit: { type: 'number', description: `Max messages to return (default ${DEFAULT_LIMIT})` },
|
|
131
|
+
clear: {
|
|
132
|
+
type: 'boolean',
|
|
133
|
+
description: 'Clear the buffers after reporting, so the next call shows only new output',
|
|
134
|
+
},
|
|
135
|
+
session: { type: 'string', description: 'Session ID' },
|
|
136
|
+
},
|
|
137
|
+
},
|
|
138
|
+
handler: async (input) => {
|
|
139
|
+
const raw = input;
|
|
140
|
+
let sessionId;
|
|
141
|
+
try {
|
|
142
|
+
sessionId = validateSessionId(raw.session);
|
|
143
|
+
}
|
|
144
|
+
catch (e) {
|
|
145
|
+
return fail(e.message);
|
|
146
|
+
}
|
|
147
|
+
const level = typeof raw.level === 'string' ? raw.level : 'all';
|
|
148
|
+
if (!['error', 'warning', 'all'].includes(level))
|
|
149
|
+
return fail('level: must be one of error|warning|all');
|
|
150
|
+
const limit = clampLimit(raw.limit);
|
|
151
|
+
try {
|
|
152
|
+
const { enableConsoleCapture, getConsoleMessages, getPageErrors, clearConsoleMessages, clearPageErrors, } = await import('@monoes/monobrowse');
|
|
153
|
+
const conn = await getConnection(sessionId);
|
|
154
|
+
// Idempotent: re-assert the domains in case the target dropped them.
|
|
155
|
+
// Never calls setupConsoleCapture — that resets the buffer, which
|
|
156
|
+
// would throw away exactly the load-time errors we are here for.
|
|
157
|
+
try {
|
|
158
|
+
await enableConsoleCapture(conn.client, conn.cdpSessionId);
|
|
159
|
+
}
|
|
160
|
+
catch {
|
|
161
|
+
/* best-effort */
|
|
162
|
+
}
|
|
163
|
+
const messages = getConsoleMessages(conn.cdpSessionId);
|
|
164
|
+
const pageErrors = getPageErrors(conn.cdpSessionId);
|
|
165
|
+
const counts = {
|
|
166
|
+
error: messages.filter((m) => m.type === 'error').length,
|
|
167
|
+
warning: messages.filter((m) => m.type === 'warn').length,
|
|
168
|
+
other: messages.filter((m) => m.type !== 'error' && m.type !== 'warn').length,
|
|
169
|
+
pageErrors: pageErrors.length,
|
|
170
|
+
total: messages.length + pageErrors.length,
|
|
171
|
+
};
|
|
172
|
+
const allowed = level === 'error'
|
|
173
|
+
? new Set(['error'])
|
|
174
|
+
: level === 'warning'
|
|
175
|
+
? new Set(['error', 'warn'])
|
|
176
|
+
: null;
|
|
177
|
+
const filtered = allowed ? messages.filter((m) => allowed.has(m.type)) : messages;
|
|
178
|
+
const severity = (t) => (t === 'error' ? 0 : t === 'warn' ? 1 : 2);
|
|
179
|
+
const ordered = [...filtered].sort((a, b) => severity(a.type) - severity(b.type) || a.timestamp - b.timestamp);
|
|
180
|
+
const shown = ordered.slice(0, limit);
|
|
181
|
+
if (raw.clear === true) {
|
|
182
|
+
clearConsoleMessages(conn.cdpSessionId);
|
|
183
|
+
clearPageErrors(conn.cdpSessionId);
|
|
184
|
+
}
|
|
185
|
+
touchSession(sessionId);
|
|
186
|
+
return ok({
|
|
187
|
+
session: sessionId,
|
|
188
|
+
// Buffers are armed when the CDP connection opens and keyed to it,
|
|
189
|
+
// so this is the true start of the window the output covers.
|
|
190
|
+
capturedSince: conn.openedAt,
|
|
191
|
+
counts,
|
|
192
|
+
pageErrors: pageErrors.slice(0, limit).map((e) => ({
|
|
193
|
+
text: elide(e.text),
|
|
194
|
+
url: e.url,
|
|
195
|
+
line: e.lineNumber,
|
|
196
|
+
})),
|
|
197
|
+
messages: shown.map((m) => ({
|
|
198
|
+
type: m.type,
|
|
199
|
+
text: elide(m.text),
|
|
200
|
+
url: m.url,
|
|
201
|
+
line: m.lineNumber,
|
|
202
|
+
})),
|
|
203
|
+
truncated: ordered.length - shown.length,
|
|
204
|
+
cleared: raw.clear === true,
|
|
205
|
+
});
|
|
206
|
+
}
|
|
207
|
+
catch (e) {
|
|
208
|
+
return fail(e.message);
|
|
209
|
+
}
|
|
210
|
+
},
|
|
211
|
+
},
|
|
212
|
+
{
|
|
213
|
+
name: 'browser_network',
|
|
214
|
+
description: 'Inspect the network traffic of a browser session: method, URL, status, type, duration and size, failures first. Call with action:"start" before the page load you care about (capture is off until then), then reload and list. Use failedOnly to see just broken requests, or action:"har" to write a .har file for a full trace. Reach for this when a page loads blank, data is missing, or something is slow.',
|
|
215
|
+
category: 'browser',
|
|
216
|
+
tags: ['network', 'har', 'debug'],
|
|
217
|
+
inputSchema: {
|
|
218
|
+
type: 'object',
|
|
219
|
+
properties: {
|
|
220
|
+
action: {
|
|
221
|
+
type: 'string',
|
|
222
|
+
enum: ['start', 'list', 'stop', 'har'],
|
|
223
|
+
description: 'start = begin capturing; list = report what was captured (default); stop = stop capturing; har = write a .har file and stop',
|
|
224
|
+
},
|
|
225
|
+
failedOnly: {
|
|
226
|
+
type: 'boolean',
|
|
227
|
+
description: 'Only requests that failed (status >= 400 or no response)',
|
|
228
|
+
},
|
|
229
|
+
method: { type: 'string', description: 'Filter by HTTP method (GET, POST, …)' },
|
|
230
|
+
type: {
|
|
231
|
+
type: 'string',
|
|
232
|
+
description: 'Filter by resource type: document|script|stylesheet|image|font|xhr|media|other',
|
|
233
|
+
},
|
|
234
|
+
url: {
|
|
235
|
+
type: 'string',
|
|
236
|
+
description: 'Filter by URL glob, e.g. "https://api.example.com/**"',
|
|
237
|
+
},
|
|
238
|
+
limit: { type: 'number', description: `Max requests to return (default ${DEFAULT_LIMIT})` },
|
|
239
|
+
path: {
|
|
240
|
+
type: 'string',
|
|
241
|
+
description: 'HAR output file, relative to .monomind/network/ (action:"har" only)',
|
|
242
|
+
},
|
|
243
|
+
session: { type: 'string', description: 'Session ID' },
|
|
244
|
+
},
|
|
245
|
+
},
|
|
246
|
+
handler: async (input) => {
|
|
247
|
+
const raw = input;
|
|
248
|
+
let sessionId;
|
|
249
|
+
try {
|
|
250
|
+
sessionId = validateSessionId(raw.session);
|
|
251
|
+
}
|
|
252
|
+
catch (e) {
|
|
253
|
+
return fail(e.message);
|
|
254
|
+
}
|
|
255
|
+
const action = typeof raw.action === 'string' ? raw.action : 'list';
|
|
256
|
+
if (!['start', 'list', 'stop', 'har'].includes(action))
|
|
257
|
+
return fail('action: must be one of start|list|stop|har');
|
|
258
|
+
const limit = clampLimit(raw.limit);
|
|
259
|
+
try {
|
|
260
|
+
const { startRequestCapture, stopRequestCapture, startHarRecording, stopHarRecording, getHarStatus, getRequests, } = await import('@monoes/monobrowse');
|
|
261
|
+
const conn = await getConnection(sessionId);
|
|
262
|
+
const sid = conn.cdpSessionId;
|
|
263
|
+
touchSession(sessionId);
|
|
264
|
+
if (action === 'start') {
|
|
265
|
+
startRequestCapture(conn.client, sid);
|
|
266
|
+
// HAR recording rides along so action:"har" can export later without
|
|
267
|
+
// a second arming step; both are stopped together.
|
|
268
|
+
try {
|
|
269
|
+
await startHarRecording(conn.client, sid);
|
|
270
|
+
}
|
|
271
|
+
catch (e) {
|
|
272
|
+
if (!/already in progress/i.test(e.message))
|
|
273
|
+
throw e;
|
|
274
|
+
}
|
|
275
|
+
return ok({
|
|
276
|
+
session: sessionId,
|
|
277
|
+
recording: true,
|
|
278
|
+
note: 'Capture is live. Reload the page (browser_reload) so its requests are recorded, then call browser_network again.',
|
|
279
|
+
});
|
|
280
|
+
}
|
|
281
|
+
if (action === 'stop' || action === 'har') {
|
|
282
|
+
const harActive = getHarStatus(sid).recording;
|
|
283
|
+
if (action === 'har' && !harActive) {
|
|
284
|
+
return fail('No HAR recording for this session. Call browser_network with action:"start", reload the page, then export.');
|
|
285
|
+
}
|
|
286
|
+
const entries = harActive ? getRequests(sid).length : 0;
|
|
287
|
+
let harPath;
|
|
288
|
+
if (harActive) {
|
|
289
|
+
const outPath = await resolveArtifactPath('network', raw.path, `session-${Date.now()}.har`);
|
|
290
|
+
harPath = await stopHarRecording(conn.client, sid, outPath);
|
|
291
|
+
}
|
|
292
|
+
stopRequestCapture(sid);
|
|
293
|
+
return ok({
|
|
294
|
+
session: sessionId,
|
|
295
|
+
recording: false,
|
|
296
|
+
path: harPath,
|
|
297
|
+
entries,
|
|
298
|
+
note: harPath
|
|
299
|
+
? 'HAR written; capture stopped and the in-memory request list was released. Call action:"start" again to record more.'
|
|
300
|
+
: 'Capture stopped.',
|
|
301
|
+
});
|
|
302
|
+
}
|
|
303
|
+
// action === 'list'
|
|
304
|
+
const recording = getHarStatus(sid).recording;
|
|
305
|
+
let requests = await collectRequests(sid);
|
|
306
|
+
const total = requests.length;
|
|
307
|
+
const failed = requests.filter(isFailure).length;
|
|
308
|
+
const byType = {};
|
|
309
|
+
for (const r of requests)
|
|
310
|
+
byType[r.type] = (byType[r.type] ?? 0) + 1;
|
|
311
|
+
if (raw.failedOnly === true)
|
|
312
|
+
requests = requests.filter(isFailure);
|
|
313
|
+
if (raw.method !== undefined) {
|
|
314
|
+
const want = rejectFlagLike(raw.method, 'method').toUpperCase();
|
|
315
|
+
requests = requests.filter((r) => r.method === want);
|
|
316
|
+
}
|
|
317
|
+
if (raw.type !== undefined) {
|
|
318
|
+
const want = rejectFlagLike(raw.type, 'type').toLowerCase();
|
|
319
|
+
requests = requests.filter((r) => r.type === want);
|
|
320
|
+
}
|
|
321
|
+
if (raw.url !== undefined) {
|
|
322
|
+
const re = globToRegex(rejectFlagLike(raw.url, 'url'));
|
|
323
|
+
requests = requests.filter((r) => re.test(r.url));
|
|
324
|
+
}
|
|
325
|
+
// Worst offenders first: failures, then the slowest.
|
|
326
|
+
const ordered = [...requests].sort((a, b) => Number(isFailure(b)) - Number(isFailure(a)) ||
|
|
327
|
+
(b.durationMs ?? 0) - (a.durationMs ?? 0));
|
|
328
|
+
const shown = ordered.slice(0, limit);
|
|
329
|
+
const withSize = requests.filter((r) => r.sizeBytes !== undefined);
|
|
330
|
+
return ok({
|
|
331
|
+
session: sessionId,
|
|
332
|
+
recording,
|
|
333
|
+
total,
|
|
334
|
+
failed,
|
|
335
|
+
matched: requests.length,
|
|
336
|
+
byType,
|
|
337
|
+
slowest: [...requests]
|
|
338
|
+
.sort((a, b) => (b.durationMs ?? 0) - (a.durationMs ?? 0))
|
|
339
|
+
.slice(0, 3)
|
|
340
|
+
.map((r) => ({ url: r.url, durationMs: r.durationMs })),
|
|
341
|
+
largest: withSize
|
|
342
|
+
.sort((a, b) => (b.sizeBytes ?? 0) - (a.sizeBytes ?? 0))
|
|
343
|
+
.slice(0, 3)
|
|
344
|
+
.map((r) => ({ url: r.url, sizeBytes: r.sizeBytes })),
|
|
345
|
+
requests: shown,
|
|
346
|
+
truncated: ordered.length - shown.length,
|
|
347
|
+
note: recording
|
|
348
|
+
? undefined
|
|
349
|
+
: 'Network capture is not running for this session — call browser_network with action:"start" and reload the page. An empty list here does not mean the page made no requests.',
|
|
350
|
+
});
|
|
351
|
+
}
|
|
352
|
+
catch (e) {
|
|
353
|
+
return fail(e.message);
|
|
354
|
+
}
|
|
355
|
+
},
|
|
356
|
+
},
|
|
357
|
+
];
|
|
358
|
+
export default browserInstrumentTools;
|
|
359
|
+
//# sourceMappingURL=browser-instrument-tools.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"browser-instrument-tools.js","sourceRoot":"","sources":["../../../src/mcp-tools/browser-instrument-tools.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Turning raw browser instrument output into a verdict.
|
|
3
|
+
*
|
|
4
|
+
* Pure functions only — no CDP, no session, no I/O — so the judgement calls
|
|
5
|
+
* (what counts as a poor LCP, which function is actually hot) can be read and
|
|
6
|
+
* tested on their own. Used by the tools in `browser-profile-tools.ts`.
|
|
7
|
+
*/
|
|
8
|
+
export declare function gradeVitals(vitals: Record<string, number | undefined>): {
|
|
9
|
+
assessment: Record<string, string>;
|
|
10
|
+
worst: string[];
|
|
11
|
+
};
|
|
12
|
+
interface CpuProfileNode {
|
|
13
|
+
id: number;
|
|
14
|
+
callFrame: {
|
|
15
|
+
functionName?: string;
|
|
16
|
+
url?: string;
|
|
17
|
+
lineNumber?: number;
|
|
18
|
+
};
|
|
19
|
+
hitCount?: number;
|
|
20
|
+
}
|
|
21
|
+
export interface TopFunction {
|
|
22
|
+
functionName: string;
|
|
23
|
+
url?: string;
|
|
24
|
+
line?: number;
|
|
25
|
+
selfMs: number;
|
|
26
|
+
selfPercent: number;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Self time per function from a V8 .cpuprofile. Sampling profiles record a hit
|
|
30
|
+
* count per node; self time is that share of the wall-clock window.
|
|
31
|
+
*/
|
|
32
|
+
export declare function summarizeCpuProfile(profile: {
|
|
33
|
+
nodes?: CpuProfileNode[];
|
|
34
|
+
startTime?: number;
|
|
35
|
+
endTime?: number;
|
|
36
|
+
}, top: number): {
|
|
37
|
+
durationMs: number;
|
|
38
|
+
totalSamples: number;
|
|
39
|
+
topFunctions: TopFunction[];
|
|
40
|
+
};
|
|
41
|
+
export {};
|
|
42
|
+
//# sourceMappingURL=browser-metrics.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"browser-metrics.d.ts","sourceRoot":"","sources":["../../../src/mcp-tools/browser-metrics.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAuBH,wBAAgB,WAAW,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,GAAG;IACvE,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACnC,KAAK,EAAE,MAAM,EAAE,CAAC;CACjB,CAkBA;AAMD,UAAU,cAAc;IACtB,EAAE,EAAE,MAAM,CAAC;IACX,SAAS,EAAE;QAAE,YAAY,CAAC,EAAE,MAAM,CAAC;QAAC,GAAG,CAAC,EAAE,MAAM,CAAC;QAAC,UAAU,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IACxE,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,WAAW;IAC1B,YAAY,EAAE,MAAM,CAAC;IACrB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,EAAE,MAAM,CAAC;CACrB;AAED;;;GAGG;AACH,wBAAgB,mBAAmB,CACjC,OAAO,EAAE;IAAE,KAAK,CAAC,EAAE,cAAc,EAAE,CAAC;IAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,CAAA;CAAE,EAC3E,GAAG,EAAE,MAAM,GACV;IAAE,UAAU,EAAE,MAAM,CAAC;IAAC,YAAY,EAAE,MAAM,CAAC;IAAC,YAAY,EAAE,WAAW,EAAE,CAAA;CAAE,CA2C3E"}
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Turning raw browser instrument output into a verdict.
|
|
3
|
+
*
|
|
4
|
+
* Pure functions only — no CDP, no session, no I/O — so the judgement calls
|
|
5
|
+
* (what counts as a poor LCP, which function is actually hot) can be read and
|
|
6
|
+
* tested on their own. Used by the tools in `browser-profile-tools.ts`.
|
|
7
|
+
*/
|
|
8
|
+
// ---------------------------------------------------------------------------
|
|
9
|
+
// Vitals grading
|
|
10
|
+
// ---------------------------------------------------------------------------
|
|
11
|
+
/** Core Web Vitals thresholds: [good below, poor at or above, unit]. */
|
|
12
|
+
const VITAL_BUDGETS = {
|
|
13
|
+
lcp: [2500, 4000, 'ms'],
|
|
14
|
+
fcp: [1800, 3000, 'ms'],
|
|
15
|
+
cls: [0.1, 0.25, ''],
|
|
16
|
+
inp: [200, 500, 'ms'],
|
|
17
|
+
ttfb: [800, 1800, 'ms'],
|
|
18
|
+
};
|
|
19
|
+
const VITAL_LABELS = {
|
|
20
|
+
lcp: 'LCP',
|
|
21
|
+
fcp: 'FCP',
|
|
22
|
+
cls: 'CLS',
|
|
23
|
+
inp: 'INP',
|
|
24
|
+
ttfb: 'TTFB',
|
|
25
|
+
};
|
|
26
|
+
export function gradeVitals(vitals) {
|
|
27
|
+
const assessment = {};
|
|
28
|
+
const worst = [];
|
|
29
|
+
for (const [key, [good, poor, unit]] of Object.entries(VITAL_BUDGETS)) {
|
|
30
|
+
const value = vitals[key];
|
|
31
|
+
if (typeof value !== 'number')
|
|
32
|
+
continue;
|
|
33
|
+
const grade = value < good ? 'good' : value < poor ? 'needs-improvement' : 'poor';
|
|
34
|
+
assessment[key] = grade;
|
|
35
|
+
if (grade === 'good')
|
|
36
|
+
continue;
|
|
37
|
+
const shown = unit === 'ms' ? `${Math.round(value)}ms` : value.toFixed(4);
|
|
38
|
+
// Poor before needs-improvement; within a grade, the biggest overshoot first.
|
|
39
|
+
worst.push({
|
|
40
|
+
line: `${VITAL_LABELS[key]} ${shown} — ${grade} (good is under ${good}${unit})`,
|
|
41
|
+
rank: (grade === 'poor' ? 0 : 1000) + good / Math.max(value, 0.0001),
|
|
42
|
+
});
|
|
43
|
+
}
|
|
44
|
+
worst.sort((a, b) => a.rank - b.rank);
|
|
45
|
+
return { assessment, worst: worst.map((w) => w.line) };
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Self time per function from a V8 .cpuprofile. Sampling profiles record a hit
|
|
49
|
+
* count per node; self time is that share of the wall-clock window.
|
|
50
|
+
*/
|
|
51
|
+
export function summarizeCpuProfile(profile, top) {
|
|
52
|
+
const nodes = profile.nodes ?? [];
|
|
53
|
+
const durationMs = Math.max(0, Math.round(((profile.endTime ?? 0) - (profile.startTime ?? 0)) / 1000));
|
|
54
|
+
const totalSamples = nodes.reduce((sum, n) => sum + (n.hitCount ?? 0), 0);
|
|
55
|
+
if (totalSamples === 0)
|
|
56
|
+
return { durationMs, totalSamples, topFunctions: [] };
|
|
57
|
+
const byFrame = new Map();
|
|
58
|
+
for (const node of nodes) {
|
|
59
|
+
const hits = node.hitCount ?? 0;
|
|
60
|
+
if (hits === 0)
|
|
61
|
+
continue;
|
|
62
|
+
const frame = node.callFrame ?? {};
|
|
63
|
+
const name = frame.functionName && frame.functionName.length > 0 ? frame.functionName : '(anonymous)';
|
|
64
|
+
const key = `${name}|${frame.url ?? ''}|${frame.lineNumber ?? -1}`;
|
|
65
|
+
const share = hits / totalSamples;
|
|
66
|
+
const existing = byFrame.get(key);
|
|
67
|
+
if (existing) {
|
|
68
|
+
existing.selfMs += share * durationMs;
|
|
69
|
+
existing.selfPercent += share * 100;
|
|
70
|
+
}
|
|
71
|
+
else {
|
|
72
|
+
byFrame.set(key, {
|
|
73
|
+
functionName: name,
|
|
74
|
+
url: frame.url || undefined,
|
|
75
|
+
line: frame.lineNumber !== undefined && frame.lineNumber >= 0 ? frame.lineNumber : undefined,
|
|
76
|
+
selfMs: share * durationMs,
|
|
77
|
+
selfPercent: share * 100,
|
|
78
|
+
});
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
const topFunctions = [...byFrame.values()]
|
|
82
|
+
.sort((a, b) => b.selfMs - a.selfMs)
|
|
83
|
+
.slice(0, top)
|
|
84
|
+
.map((f) => ({
|
|
85
|
+
...f,
|
|
86
|
+
selfMs: Math.round(f.selfMs * 10) / 10,
|
|
87
|
+
selfPercent: Math.round(f.selfPercent * 10) / 10,
|
|
88
|
+
}));
|
|
89
|
+
return { durationMs, totalSamples, topFunctions };
|
|
90
|
+
}
|
|
91
|
+
//# sourceMappingURL=browser-metrics.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"browser-metrics.js","sourceRoot":"","sources":["../../../src/mcp-tools/browser-metrics.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Browser performance tools: web vitals, CPU/heap profiling, device emulation.
|
|
3
|
+
*
|
|
4
|
+
* Profiles and heap snapshots are megabytes of JSON, so these tools write the
|
|
5
|
+
* artifact to a file under `.monomind/` and return the path plus a summary an
|
|
6
|
+
* agent can actually act on — never the raw dump.
|
|
7
|
+
*
|
|
8
|
+
* Registered from `browser-tools.ts`; shared plumbing lives in
|
|
9
|
+
* `browser-session.ts`, console/network capture in
|
|
10
|
+
* `browser-instrument-tools.ts`, and the grading/summarising in
|
|
11
|
+
* `browser-metrics.ts`.
|
|
12
|
+
*/
|
|
13
|
+
import type { MCPTool } from './types.js';
|
|
14
|
+
export declare const browserProfileTools: MCPTool[];
|
|
15
|
+
export default browserProfileTools;
|
|
16
|
+
//# sourceMappingURL=browser-profile-tools.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"browser-profile-tools.d.ts","sourceRoot":"","sources":["../../../src/mcp-tools/browser-profile-tools.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAcH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AAa1C,eAAO,MAAM,mBAAmB,EAAE,OAAO,EAuTxC,CAAC;eAmBa,mBAAmB"}
|