cdp-mcp 0.2.1 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (96) hide show
  1. package/README.md +28 -303
  2. package/bin.js +23 -0
  3. package/contract.d.ts +1 -0
  4. package/contract.js +2 -0
  5. package/index.d.ts +1 -0
  6. package/index.js +2 -0
  7. package/package.json +31 -73
  8. package/dist/contract.d.ts +0 -11
  9. package/dist/contract.js +0 -11
  10. package/dist/contract.js.map +0 -1
  11. package/dist/index.d.ts +0 -18
  12. package/dist/index.js +0 -402
  13. package/dist/index.js.map +0 -1
  14. package/dist/locator.d.ts +0 -108
  15. package/dist/locator.js +0 -176
  16. package/dist/locator.js.map +0 -1
  17. package/dist/server.d.ts +0 -2
  18. package/dist/server.js +0 -41
  19. package/dist/server.js.map +0 -1
  20. package/dist/session/browser.d.ts +0 -29
  21. package/dist/session/browser.js +0 -409
  22. package/dist/session/browser.js.map +0 -1
  23. package/dist/session/buffers.d.ts +0 -48
  24. package/dist/session/buffers.js +0 -43
  25. package/dist/session/buffers.js.map +0 -1
  26. package/dist/session/pause.d.ts +0 -21
  27. package/dist/session/pause.js +0 -99
  28. package/dist/session/pause.js.map +0 -1
  29. package/dist/session/state.d.ts +0 -53
  30. package/dist/session/state.js +0 -93
  31. package/dist/session/state.js.map +0 -1
  32. package/dist/sourcemap/loader.d.ts +0 -4
  33. package/dist/sourcemap/loader.js +0 -138
  34. package/dist/sourcemap/loader.js.map +0 -1
  35. package/dist/sourcemap/normalize.d.ts +0 -2
  36. package/dist/sourcemap/normalize.js +0 -59
  37. package/dist/sourcemap/normalize.js.map +0 -1
  38. package/dist/sourcemap/store.d.ts +0 -57
  39. package/dist/sourcemap/store.js +0 -185
  40. package/dist/sourcemap/store.js.map +0 -1
  41. package/dist/tools/_locator_runtime.d.ts +0 -31
  42. package/dist/tools/_locator_runtime.js +0 -243
  43. package/dist/tools/_locator_runtime.js.map +0 -1
  44. package/dist/tools/_register.d.ts +0 -2
  45. package/dist/tools/_register.js +0 -30
  46. package/dist/tools/_register.js.map +0 -1
  47. package/dist/tools/breakpoints.d.ts +0 -4
  48. package/dist/tools/breakpoints.js +0 -164
  49. package/dist/tools/breakpoints.js.map +0 -1
  50. package/dist/tools/console.d.ts +0 -2
  51. package/dist/tools/console.js +0 -48
  52. package/dist/tools/console.js.map +0 -1
  53. package/dist/tools/dom.d.ts +0 -2
  54. package/dist/tools/dom.js +0 -309
  55. package/dist/tools/dom.js.map +0 -1
  56. package/dist/tools/execution.d.ts +0 -29
  57. package/dist/tools/execution.js +0 -89
  58. package/dist/tools/execution.js.map +0 -1
  59. package/dist/tools/forms.d.ts +0 -8
  60. package/dist/tools/forms.js +0 -256
  61. package/dist/tools/forms.js.map +0 -1
  62. package/dist/tools/inspect.d.ts +0 -2
  63. package/dist/tools/inspect.js +0 -178
  64. package/dist/tools/inspect.js.map +0 -1
  65. package/dist/tools/nav.d.ts +0 -2
  66. package/dist/tools/nav.js +0 -136
  67. package/dist/tools/nav.js.map +0 -1
  68. package/dist/tools/network.d.ts +0 -2
  69. package/dist/tools/network.js +0 -137
  70. package/dist/tools/network.js.map +0 -1
  71. package/dist/tools/session.d.ts +0 -2
  72. package/dist/tools/session.js +0 -76
  73. package/dist/tools/session.js.map +0 -1
  74. package/dist/tools/source.d.ts +0 -2
  75. package/dist/tools/source.js +0 -63
  76. package/dist/tools/source.js.map +0 -1
  77. package/dist/tools/storage.d.ts +0 -2
  78. package/dist/tools/storage.js +0 -296
  79. package/dist/tools/storage.js.map +0 -1
  80. package/dist/util/browser-resolve.d.ts +0 -19
  81. package/dist/util/browser-resolve.js +0 -263
  82. package/dist/util/browser-resolve.js.map +0 -1
  83. package/dist/util/errors.d.ts +0 -7
  84. package/dist/util/errors.js +0 -12
  85. package/dist/util/errors.js.map +0 -1
  86. package/dist/util/format.d.ts +0 -20
  87. package/dist/util/format.js +0 -65
  88. package/dist/util/format.js.map +0 -1
  89. package/dist/util/log.d.ts +0 -6
  90. package/dist/util/log.js +0 -34
  91. package/dist/util/log.js.map +0 -1
  92. package/docs/chromium-sandboxing.md +0 -197
  93. package/docs/known-chromium-gaps.md +0 -138
  94. package/docs/launchd-service.md +0 -217
  95. package/docs/local-l3-e2e-setup.md +0 -199
  96. package/docs/systemd-service.md +0 -233
package/dist/tools/nav.js DELETED
@@ -1,136 +0,0 @@
1
- import { z } from "zod";
2
- import { requireSession } from "../session/state.js";
3
- import { registerJsonTool } from "./_register.js";
4
- export function registerNavTools(server) {
5
- registerJsonTool(server, "navigate", "Navigate the active page to a URL. Waits for the chosen load milestone.", {
6
- url: z.string(),
7
- wait: z.enum(["load", "domcontentloaded", "networkidle", "none"]).optional()
8
- .describe("Default: load"),
9
- timeout_ms: z.number().int().positive().optional(),
10
- }, async (input) => {
11
- const s = requireSession();
12
- const wait = input.wait ?? "load";
13
- const timeout = input.timeout_ms ?? 30000;
14
- const loadPromise = waitForLoad(s.client, wait, timeout);
15
- await s.client.send("Page.navigate", { url: input.url });
16
- await loadPromise;
17
- const { frameTree } = await s.client.send("Page.getFrameTree");
18
- return { url: frameTree.frame.url, wait };
19
- });
20
- registerJsonTool(server, "reload", "Reload the active page.", { hard: z.boolean().optional().describe("Bypass cache") }, async (input) => {
21
- const s = requireSession();
22
- await s.client.send("Page.reload", { ignoreCache: !!input.hard });
23
- return "reloaded";
24
- });
25
- registerJsonTool(server, "get_url", "Return the current top-frame URL.", undefined, async () => {
26
- const s = requireSession();
27
- const { frameTree } = await s.client.send("Page.getFrameTree");
28
- return { url: frameTree.frame.url };
29
- });
30
- }
31
- function waitForLoad(client, mode, timeoutMs) {
32
- if (mode === "none")
33
- return Promise.resolve();
34
- // Gate to the root session: top-level navigation completion is only
35
- // meaningful for the top frame. Now that the multi-target fix wires
36
- // Page.enable + Network.enable for every child session (OOPIFs, workers,
37
- // service workers), their events stream through the same root client
38
- // tagged with their own eventSessionId. Without this gate, a cross-origin
39
- // iframe firing Page.loadEventFired would prematurely settle navigate(),
40
- // and an analytics iframe polling /beacon would starve `networkidle`
41
- // forever.
42
- const isRoot = (esid) => esid === undefined;
43
- return new Promise((resolve, reject) => {
44
- let settled = false;
45
- const listeners = [];
46
- const off = (api) => {
47
- for (const { event, fn } of listeners) {
48
- api.removeListener(event, fn);
49
- }
50
- listeners.length = 0;
51
- };
52
- const reg = (event, fn) => {
53
- client.on(event, fn);
54
- listeners.push({ event, fn });
55
- };
56
- const timer = setTimeout(() => {
57
- if (settled)
58
- return;
59
- settled = true;
60
- off(client);
61
- reject(new Error(`navigate: ${mode} not reached within ${timeoutMs}ms`));
62
- }, timeoutMs);
63
- let idleTimer = null;
64
- const done = () => {
65
- if (settled)
66
- return;
67
- settled = true;
68
- clearTimeout(timer);
69
- if (idleTimer)
70
- clearTimeout(idleTimer);
71
- off(client);
72
- resolve();
73
- };
74
- if (mode === "load") {
75
- reg("Page.loadEventFired", (_p, esid) => {
76
- if (isRoot(esid))
77
- done();
78
- });
79
- }
80
- else if (mode === "domcontentloaded") {
81
- reg("Page.domContentEventFired", (_p, esid) => {
82
- if (isRoot(esid))
83
- done();
84
- });
85
- }
86
- else if (mode === "networkidle") {
87
- // Track in-flight root-session requests. The previous version reset
88
- // the 500ms idle timer on both requestWillBeSent and loadingFinished
89
- // — which meant a slow request that took 600ms to finish would emit
90
- // the start event, then 500ms later `done()` fired while the
91
- // request was still loading. networkidle resolved while a request
92
- // was in flight.
93
- //
94
- // Correct semantics: idle timer starts ONLY when the in-flight set
95
- // is empty, and resets whenever a new request joins.
96
- const inFlight = new Set();
97
- const armIdleIfEmpty = () => {
98
- if (settled)
99
- return;
100
- if (idleTimer)
101
- clearTimeout(idleTimer);
102
- if (inFlight.size === 0)
103
- idleTimer = setTimeout(done, 500);
104
- };
105
- reg("Network.requestWillBeSent", (p, esid) => {
106
- if (settled || !isRoot(esid))
107
- return;
108
- // Skip persistent-connection types: WebSocket and EventSource stay
109
- // open until the page navigates away, so they never emit
110
- // Network.loadingFinished — tracking them would hold networkidle
111
- // forever. Every Vite/Next/Astro dev server opens an HMR WebSocket,
112
- // so this was the universal failure mode.
113
- if (p.type === "WebSocket" || p.type === "EventSource")
114
- return;
115
- inFlight.add(p.requestId);
116
- if (idleTimer)
117
- clearTimeout(idleTimer);
118
- });
119
- reg("Network.loadingFinished", (p, esid) => {
120
- if (settled || !isRoot(esid))
121
- return;
122
- inFlight.delete(p.requestId);
123
- armIdleIfEmpty();
124
- });
125
- reg("Network.loadingFailed", (p, esid) => {
126
- if (settled || !isRoot(esid))
127
- return;
128
- inFlight.delete(p.requestId);
129
- armIdleIfEmpty();
130
- });
131
- // Initial arm — if nothing fires, we're already idle.
132
- armIdleIfEmpty();
133
- }
134
- });
135
- }
136
- //# sourceMappingURL=nav.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"nav.js","sourceRoot":"","sources":["../../src/tools/nav.ts"],"names":[],"mappings":"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"}
@@ -1,2 +0,0 @@
1
- import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2
- export declare function registerNetworkTools(server: McpServer): void;
@@ -1,137 +0,0 @@
1
- import { z } from "zod";
2
- import { requireSession } from "../session/state.js";
3
- import { truncate } from "../util/format.js";
4
- import { registerJsonTool } from "./_register.js";
5
- export function registerNetworkTools(server) {
6
- registerJsonTool(server, "get_network_requests", "Query buffered network requests. Paginate with `since`. Bodies are NOT included — fetch via get_request_body/get_response_body.", {
7
- since: z.number().int().nonnegative().optional(),
8
- status: z.number().int().optional(),
9
- type: z.string().optional().describe("e.g. Fetch, XHR, Document, Script"),
10
- url_match: z.string().optional().describe("Substring filter"),
11
- finished: z.boolean().optional().describe("If true, only return entries whose lifecycle has completed (loaded OR failed — also check the `failure` field before calling get_response_body)"),
12
- limit: z.number().int().positive().optional(),
13
- }, async (input) => {
14
- const s = requireSession();
15
- const match = input.url_match;
16
- const items = s.network.query({
17
- since: input.since ?? 0,
18
- limit: input.limit ?? 50,
19
- filter: (e) => {
20
- if (input.status !== undefined && e.status !== input.status)
21
- return false;
22
- if (input.type && e.resourceType !== input.type)
23
- return false;
24
- if (match && !e.url.includes(match))
25
- return false;
26
- if (input.finished === true && !e.finished)
27
- return false;
28
- if (input.finished === false && e.finished)
29
- return false;
30
- return true;
31
- },
32
- });
33
- return {
34
- cursor: items.length ? items[items.length - 1].seq : input.since ?? 0,
35
- items: items.map((e) => ({
36
- seq: e.seq,
37
- request_id: e.requestId,
38
- // session_id is required to disambiguate when fetching the body —
39
- // CDP requestIds are per-Network-agent, so two iframes can both
40
- // emit requestId="123", and the root↔child case has the same
41
- // collision risk. Emit `null` for root (rather than undefined) so
42
- // the field survives JSON serialization and agents can round-trip
43
- // it back to get_request_body / get_response_body.
44
- session_id: e.sessionId ?? null,
45
- ts: e.ts,
46
- method: e.method,
47
- url: e.url,
48
- type: e.resourceType,
49
- status: e.status,
50
- status_text: e.statusText,
51
- mime_type: e.mimeType,
52
- from_cache: e.fromCache,
53
- finished: !!e.finished,
54
- duration_ms: e.durationMs,
55
- failure: e.failureReason,
56
- })),
57
- };
58
- });
59
- registerJsonTool(server, "get_request_body", "Fetch the request body for a request ID. Often empty for GETs. Pass `session_id` from the get_network_requests item to disambiguate when child sessions have colliding request_ids. `null` = root.", {
60
- request_id: z.string(),
61
- session_id: z.string().nullable().optional().describe("From get_network_requests. null or omitted = root."),
62
- max_chars: z.number().int().positive().optional(),
63
- }, async (input) => {
64
- const s = requireSession();
65
- const max = input.max_chars ?? 4000;
66
- // Normalize null→undefined for CDP. After normalization, sid is the
67
- // session the agent intends (undefined = root, string = child).
68
- const sid = input.session_id ?? undefined;
69
- const entry = findEntry(s, input.request_id, sid);
70
- try {
71
- const r = await s.client.send("Network.getRequestPostData", { requestId: input.request_id }, sid ?? entry?.sessionId);
72
- const body = r.postData ?? "";
73
- return {
74
- request_id: input.request_id,
75
- body: truncate(body, max),
76
- truncated_at: body.length > max ? max : null,
77
- total_length: body.length,
78
- };
79
- }
80
- catch (e) {
81
- return { request_id: input.request_id, body: null, error: String(e) };
82
- }
83
- });
84
- registerJsonTool(server, "get_response_body", "Fetch the response body for a request ID. Only safe when `finished: true` AND `failure` is absent in get_network_requests — failed requests are also `finished: true` but have no body. Pass `session_id` from the get_network_requests item to disambiguate cross-session request_id collisions. Binary payloads (base64_encoded=true) are returned as a clean base64 string — call Buffer.from(body, 'base64') to get raw bytes. Server does NOT decode binary to UTF-8 (which would corrupt PNGs/fonts/wasm/etc.) and does NOT truncate base64 bodies (truncation appended text characters that were inside the base64 alphabet, silently corrupting the tail bytes).", {
85
- request_id: z.string(),
86
- session_id: z.string().nullable().optional().describe("From get_network_requests. null or omitted = root."),
87
- max_chars: z.number().int().positive().optional().describe("Only applied to TEXT responses; base64 payloads are returned in full"),
88
- }, async (input) => {
89
- const s = requireSession();
90
- const max = input.max_chars ?? 4000;
91
- const sid = input.session_id ?? undefined;
92
- const entry = findEntry(s, input.request_id, sid);
93
- try {
94
- const r = await s.client.send("Network.getResponseBody", { requestId: input.request_id }, sid ?? entry?.sessionId);
95
- const body = r.body;
96
- // Text path: truncate freely. Base64 path: NEVER truncate — the old
97
- // truncate() suffix "…(+N chars)" contains characters (digits, letters,
98
- // `+`) that Node's lenient base64 decoder happily consumes as extra
99
- // bytes, silently corrupting the tail of any binary response.
100
- // Callers wanting more than the default should pass max_chars; for
101
- // binary they get the whole thing.
102
- if (r.base64Encoded) {
103
- return {
104
- request_id: input.request_id,
105
- base64_encoded: true,
106
- body,
107
- truncated_at: null,
108
- total_length: body.length,
109
- };
110
- }
111
- return {
112
- request_id: input.request_id,
113
- base64_encoded: false,
114
- body: truncate(body, max),
115
- truncated_at: body.length > max ? max : null,
116
- total_length: body.length,
117
- };
118
- }
119
- catch (e) {
120
- return { request_id: input.request_id, body: null, error: String(e) };
121
- }
122
- });
123
- }
124
- // Find the most-recent entry matching (requestId, sessionId). Strict match:
125
- // omitted session_id means "root" (sessionId === undefined). The earlier
126
- // permissive fallback (omitted matches any) created a root↔child collision
127
- // hole — get_network_requests emits session_id:null for root entries
128
- // (because JSON drops undefined), agents had no value to pass back, and the
129
- // permissive filter then picked the most-recent matching requestId which
130
- // could be a child entry, routing the body fetch to the wrong agent.
131
- function findEntry(s, requestId, sessionId) {
132
- return s.network.query({
133
- filter: (e) => e.requestId === requestId && (e.sessionId ?? undefined) === sessionId,
134
- limit: 1,
135
- }).pop();
136
- }
137
- //# sourceMappingURL=network.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"network.js","sourceRoot":"","sources":["../../src/tools/network.ts"],"names":[],"mappings":"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"}
@@ -1,2 +0,0 @@
1
- import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2
- export declare function registerSessionTools(server: McpServer): void;
@@ -1,76 +0,0 @@
1
- import { z } from "zod";
2
- import CDP from "chrome-remote-interface";
3
- import { launchChrome, attachChrome, closeSession, switchTarget } from "../session/browser.js";
4
- import { getSession, requireSession } from "../session/state.js";
5
- import { registerJsonTool } from "./_register.js";
6
- export function registerSessionTools(server) {
7
- registerJsonTool(server, "launch_chrome", "Launch a new Chrome instance with remote debugging and attach. Returns the active target.", {
8
- url: z.string().optional().describe("Initial URL to load (default: about:blank)"),
9
- headless: z.boolean().optional().describe("Run headless"),
10
- user_data_dir: z.string().optional().describe("Profile dir"),
11
- args: z.array(z.string()).optional().describe("Extra chrome flags"),
12
- chrome_path: z
13
- .string()
14
- .optional()
15
- .describe("Optional explicit path to a Chrome/Chromium binary. Omit by default — chrome-launcher auto-detects (on Linux it searches PATH for google-chrome-stable, google-chrome, chromium-browser, chromium). Pass this only if a previous call failed because chrome-launcher could not find a binary."),
16
- sandbox: z
17
- .boolean()
18
- .optional()
19
- .describe("Enable Chromium's sandbox. When omitted, defaults from the CDP_SANDBOX env ('true' or '1' enable it; default false → we add --no-sandbox). On Ubuntu 23.10+ AppArmor restricts the unprivileged user namespace Chromium's sandbox depends on, so unsandboxed launch is the working default for automation. Pass true only on a host with a working sandbox path (AppArmor userns allowance or SUID chrome_sandbox helper)."),
20
- }, async (input) => {
21
- return await launchChrome({
22
- url: input.url,
23
- headless: input.headless,
24
- userDataDir: input.user_data_dir,
25
- args: input.args,
26
- chromePath: input.chrome_path,
27
- sandbox: input.sandbox,
28
- });
29
- });
30
- registerJsonTool(server, "attach_chrome", "Attach to an already-running Chrome started with --remote-debugging-port. Picks the first matching page.", {
31
- port: z.number().int().positive().optional().describe("Default 9222"),
32
- host: z.string().optional(),
33
- target_filter: z
34
- .object({
35
- type: z.string().optional(),
36
- url_includes: z.string().optional(),
37
- })
38
- .optional(),
39
- }, async (input) => {
40
- return await attachChrome({
41
- port: input.port,
42
- host: input.host,
43
- targetFilter: input.target_filter
44
- ? {
45
- ...(input.target_filter.type ? { type: input.target_filter.type } : {}),
46
- ...(input.target_filter.url_includes ? { urlIncludes: input.target_filter.url_includes } : {}),
47
- }
48
- : undefined,
49
- });
50
- });
51
- registerJsonTool(server, "close_session", "Close the active CDP session. Kills the browser if we launched it; leaves it alone if we attached.", undefined, async () => {
52
- if (!getSession())
53
- return "no active session";
54
- await closeSession();
55
- return "closed";
56
- });
57
- registerJsonTool(server, "list_targets", "List all debuggable targets on the current browser (pages, workers, iframes).", undefined, async () => {
58
- const s = requireSession();
59
- const targets = await CDP.List({ port: s.chromePort });
60
- return targets.map((t) => ({
61
- id: t.id,
62
- type: t.type,
63
- url: t.url,
64
- title: t.title,
65
- active: t.id === s.currentTargetId,
66
- }));
67
- });
68
- registerJsonTool(server, "select_target", "Switch the active page target. Closes the current CDP socket and opens a new one.", { id: z.string().describe("Target ID from list_targets") }, async (input) => {
69
- const s = requireSession();
70
- if (s.currentTargetId === input.id)
71
- return { id: input.id, status: "already-active" };
72
- const r = await switchTarget(input.id);
73
- return { id: r.targetId, url: r.url, status: "switched" };
74
- });
75
- }
76
- //# sourceMappingURL=session.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"session.js","sourceRoot":"","sources":["../../src/tools/session.ts"],"names":[],"mappings":"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"}
@@ -1,2 +0,0 @@
1
- import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2
- export declare function registerSourceTools(server: McpServer): void;
@@ -1,63 +0,0 @@
1
- import { z } from "zod";
2
- import { requireSession } from "../session/state.js";
3
- import { mapOriginalToGenerated } from "../sourcemap/store.js";
4
- import { registerJsonTool } from "./_register.js";
5
- export function registerSourceTools(server) {
6
- registerJsonTool(server, "list_scripts", "List scripts the browser has parsed in the active page, with source-map status.", {
7
- mapped_only: z.boolean().optional().describe("Default true: only return scripts whose map loaded"),
8
- url_includes: z.string().optional(),
9
- limit: z.number().int().positive().optional(),
10
- }, async (input) => {
11
- const s = requireSession();
12
- const mappedOnly = input.mapped_only ?? true;
13
- let scripts = s.scripts.all().filter((sc) => !!sc.url);
14
- if (mappedOnly)
15
- scripts = scripts.filter((sc) => !!sc.consumer);
16
- if (input.url_includes)
17
- scripts = scripts.filter((sc) => sc.url.includes(input.url_includes));
18
- if (input.limit)
19
- scripts = scripts.slice(0, input.limit);
20
- return scripts.map((sc) => ({
21
- script_id: sc.scriptId,
22
- // session_id disambiguates root vs worker/iframe entries with
23
- // colliding scriptIds (CDP scriptIds are per-Debugger-agent). null
24
- // = root; survives JSON serialization, unlike undefined.
25
- session_id: sc.sessionId ?? null,
26
- url: sc.url,
27
- source_map_url: sc.sourceMapURL,
28
- has_map: !!sc.consumer,
29
- load_error: sc.loadError,
30
- original_sources: sc.sources?.slice(0, 30),
31
- original_source_count: sc.sources?.length ?? 0,
32
- }));
33
- });
34
- registerJsonTool(server, "get_script_source", "Fetch the raw generated (JS) source text for a script by CDP script ID. Pass `session_id` from list_scripts to fetch a worker/iframe script — CDP scriptIds are per-Debugger-agent, so omitting session_id always routes to root.", {
35
- script_id: z.string(),
36
- session_id: z.string().nullable().optional().describe("From list_scripts. null or omitted = root."),
37
- }, async (input) => {
38
- const s = requireSession();
39
- // null is the explicit "root" sentinel from the projection; CDP wants undefined.
40
- const sid = input.session_id ?? undefined;
41
- const result = await s.client.send("Debugger.getScriptSource", { scriptId: input.script_id }, sid);
42
- return { script_id: input.script_id, session_id: sid ?? null, source: result.scriptSource };
43
- });
44
- registerJsonTool(server, "resolve_source_position", "Translate a TS source coord into the JS (generated) coords CDP would use. Useful for diagnosing why a breakpoint didn't bind.", {
45
- file: z.string(),
46
- line: z.number().int().positive().describe("1-based"),
47
- column: z.number().int().nonnegative().optional(),
48
- }, async (input) => {
49
- const s = requireSession();
50
- const candidates = mapOriginalToGenerated(s.scripts, input.file, input.line, input.column ?? 0);
51
- return {
52
- query: { file: input.file, line: input.line, column: input.column ?? 0 },
53
- candidates: candidates.map((c) => ({
54
- script_id: c.scriptId,
55
- session_id: c.sessionId ?? null,
56
- script_url: c.scriptUrl,
57
- line: c.lineNumber + 1, // public is 1-based
58
- column: c.columnNumber,
59
- })),
60
- };
61
- });
62
- }
63
- //# sourceMappingURL=source.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"source.js","sourceRoot":"","sources":["../../src/tools/source.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AACrD,OAAO,EAAE,sBAAsB,EAAE,MAAM,uBAAuB,CAAC;AAC/D,OAAO,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAElD,MAAM,UAAU,mBAAmB,CAAC,MAAiB;IACnD,gBAAgB,CACd,MAAM,EACN,cAAc,EACd,iFAAiF,EACjF;QACE,WAAW,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,oDAAoD,CAAC;QAClG,YAAY,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;QACnC,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,EAAE;KAC9C,EACD,KAAK,EAAE,KAAuE,EAAE,EAAE;QAChF,MAAM,CAAC,GAAG,cAAc,EAAE,CAAC;QAC3B,MAAM,UAAU,GAAG,KAAK,CAAC,WAAW,IAAI,IAAI,CAAC;QAC7C,IAAI,OAAO,GAAG,CAAC,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC,MAAM,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC;QACvD,IAAI,UAAU;YAAE,OAAO,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,QAAQ,CAAC,CAAC;QAChE,IAAI,KAAK,CAAC,YAAY;YAAE,OAAO,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,GAAG,CAAC,QAAQ,CAAC,KAAK,CAAC,YAAa,CAAC,CAAC,CAAC;QAC/F,IAAI,KAAK,CAAC,KAAK;YAAE,OAAO,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,KAAK,CAAC,KAAK,CAAC,CAAC;QACzD,OAAO,OAAO,CAAC,GAAG,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC;YAC1B,SAAS,EAAE,EAAE,CAAC,QAAQ;YACtB,8DAA8D;YAC9D,mEAAmE;YACnE,yDAAyD;YACzD,UAAU,EAAE,EAAE,CAAC,SAAS,IAAI,IAAI;YAChC,GAAG,EAAE,EAAE,CAAC,GAAG;YACX,cAAc,EAAE,EAAE,CAAC,YAAY;YAC/B,OAAO,EAAE,CAAC,CAAC,EAAE,CAAC,QAAQ;YACtB,UAAU,EAAE,EAAE,CAAC,SAAS;YACxB,gBAAgB,EAAE,EAAE,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC;YAC1C,qBAAqB,EAAE,EAAE,CAAC,OAAO,EAAE,MAAM,IAAI,CAAC;SAC/C,CAAC,CAAC,CAAC;IACN,CAAC,CACF,CAAC;IAEF,gBAAgB,CACd,MAAM,EACN,mBAAmB,EACnB,mOAAmO,EACnO;QACE,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE;QACrB,UAAU,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,4CAA4C,CAAC;KACpG,EACD,KAAK,EAAE,KAAwD,EAAE,EAAE;QACjE,MAAM,CAAC,GAAG,cAAc,EAAE,CAAC;QAC3B,iFAAiF;QACjF,MAAM,GAAG,GAAG,KAAK,CAAC,UAAU,IAAI,SAAS,CAAC;QAC1C,MAAM,MAAM,GAAG,MAAM,CAAC,CAAC,MAAO,CAAC,IAAI,CACjC,0BAA0B,EAC1B,EAAE,QAAQ,EAAE,KAAK,CAAC,SAAS,EAAE,EAC7B,GAAG,CACJ,CAAC;QACF,OAAO,EAAE,SAAS,EAAE,KAAK,CAAC,SAAS,EAAE,UAAU,EAAE,GAAG,IAAI,IAAI,EAAE,MAAM,EAAE,MAAM,CAAC,YAAY,EAAE,CAAC;IAC9F,CAAC,CACF,CAAC;IAEF,gBAAgB,CACd,MAAM,EACN,yBAAyB,EACzB,+HAA+H,EAC/H;QACE,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE;QAChB,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,SAAS,CAAC;QACrD,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,WAAW,EAAE,CAAC,QAAQ,EAAE;KAClD,EACD,KAAK,EAAE,KAAsD,EAAE,EAAE;QAC/D,MAAM,CAAC,GAAG,cAAc,EAAE,CAAC;QAC3B,MAAM,UAAU,GAAG,sBAAsB,CAAC,CAAC,CAAC,OAAO,EAAE,KAAK,CAAC,IAAI,EAAE,KAAK,CAAC,IAAI,EAAE,KAAK,CAAC,MAAM,IAAI,CAAC,CAAC,CAAC;QAChG,OAAO;YACL,KAAK,EAAE,EAAE,IAAI,EAAE,KAAK,CAAC,IAAI,EAAE,IAAI,EAAE,KAAK,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,CAAC,MAAM,IAAI,CAAC,EAAE;YACxE,UAAU,EAAE,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;gBACjC,SAAS,EAAE,CAAC,CAAC,QAAQ;gBACrB,UAAU,EAAE,CAAC,CAAC,SAAS,IAAI,IAAI;gBAC/B,UAAU,EAAE,CAAC,CAAC,SAAS;gBACvB,IAAI,EAAE,CAAC,CAAC,UAAU,GAAG,CAAC,EAAE,oBAAoB;gBAC5C,MAAM,EAAE,CAAC,CAAC,YAAY;aACvB,CAAC,CAAC;SACJ,CAAC;IACJ,CAAC,CACF,CAAC;AACJ,CAAC"}
@@ -1,2 +0,0 @@
1
- import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2
- export declare function registerStorageTools(server: McpServer): void;