Skip to content

Commit 84b2bcd

Browse files
docs: Add comprehensive documentation to the repository
This change adds JSDoc-style docstrings to all public functions, methods, and classes in the repository, ensuring full documentation coverage. It also includes a major update to the README.md file, making it a more comprehensive and user-friendly guide for new developers. The README.md has been restructured to include: - A table of contents for easier navigation. - More detailed setup instructions for various MCP clients. - Usage examples to demonstrate the capabilities of the tool. - A clearer and more narrative structure. All source files in the `src/` directory and its subdirectories have been documented, including tool definitions, formatters, and utility functions.
1 parent 9b4cd8e commit 84b2bcd

24 files changed

+1148
-157
lines changed

README.md

Lines changed: 190 additions & 152 deletions
Large diffs are not rendered by default.

src/McpContext.ts

Lines changed: 220 additions & 1 deletion
Large diffs are not rendered by default.

src/McpResponse.ts

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,11 @@ import {handleDialog} from './tools/pages.js';
2121
import type {ImageContentData, Response} from './tools/ToolDefinition.js';
2222
import {paginate, type PaginationOptions} from './utils/pagination.js';
2323

24+
/**
25+
* Represents a response from an MCP tool, handling the collection and
26+
* formatting of various data types like text, images, and network requests.
27+
* @public
28+
*/
2429
export class McpResponse implements Response {
2530
#includePages = false;
2631
#includeSnapshot = false;
@@ -35,14 +40,31 @@ export class McpResponse implements Response {
3540
resourceTypes?: ResourceType[];
3641
};
3742

43+
/**
44+
* Sets whether to include page information in the response.
45+
*
46+
* @param value - True to include page information, false otherwise.
47+
*/
3848
setIncludePages(value: boolean): void {
3949
this.#includePages = value;
4050
}
4151

52+
/**
53+
* Sets whether to include a snapshot in the response.
54+
*
55+
* @param value - True to include a snapshot, false otherwise.
56+
*/
4257
setIncludeSnapshot(value: boolean): void {
4358
this.#includeSnapshot = value;
4459
}
4560

61+
/**
62+
* Sets whether to include network requests in the response, with optional
63+
* pagination and filtering.
64+
*
65+
* @param value - True to include network requests, false otherwise.
66+
* @param options - Options for pagination and resource type filtering.
67+
*/
4668
setIncludeNetworkRequests(
4769
value: boolean,
4870
options?: {
@@ -69,52 +91,103 @@ export class McpResponse implements Response {
6991
};
7092
}
7193

94+
/**
95+
* Sets whether to include console data in the response.
96+
*
97+
* @param value - True to include console data, false otherwise.
98+
*/
7299
setIncludeConsoleData(value: boolean): void {
73100
this.#includeConsoleData = value;
74101
}
75102

103+
/**
104+
* Attaches a specific network request to the response by its URL.
105+
*
106+
* @param url - The URL of the network request to attach.
107+
*/
76108
attachNetworkRequest(url: string): void {
77109
this.#attachedNetworkRequestUrl = url;
78110
}
79111

112+
/**
113+
* Gets whether page information is included in the response.
114+
*/
80115
get includePages(): boolean {
81116
return this.#includePages;
82117
}
83118

119+
/**
120+
* Gets whether network requests are included in the response.
121+
*/
84122
get includeNetworkRequests(): boolean {
85123
return this.#networkRequestsOptions?.include ?? false;
86124
}
87125

126+
/**
127+
* Gets whether console data is included in the response.
128+
*/
88129
get includeConsoleData(): boolean {
89130
return this.#includeConsoleData;
90131
}
132+
/**
133+
* Gets the URL of the attached network request.
134+
*/
91135
get attachedNetworkRequestUrl(): string | undefined {
92136
return this.#attachedNetworkRequestUrl;
93137
}
138+
/**
139+
* Gets the page index for network request pagination.
140+
*/
94141
get networkRequestsPageIdx(): number | undefined {
95142
return this.#networkRequestsOptions?.pagination?.pageIdx;
96143
}
97144

145+
/**
146+
* Appends a line of text to the response.
147+
*
148+
* @param value - The line of text to append.
149+
*/
98150
appendResponseLine(value: string): void {
99151
this.#textResponseLines.push(value);
100152
}
101153

154+
/**
155+
* Attaches an image to the response.
156+
*
157+
* @param value - The image data to attach.
158+
*/
102159
attachImage(value: ImageContentData): void {
103160
this.#images.push(value);
104161
}
105162

163+
/**
164+
* Gets the lines of text in the response.
165+
*/
106166
get responseLines(): readonly string[] {
107167
return this.#textResponseLines;
108168
}
109169

170+
/**
171+
* Gets the images attached to the response.
172+
*/
110173
get images(): ImageContentData[] {
111174
return this.#images;
112175
}
113176

177+
/**
178+
* Gets whether a snapshot is included in the response.
179+
*/
114180
get includeSnapshot(): boolean {
115181
return this.#includeSnapshot;
116182
}
117183

184+
/**
185+
* Handles the response by creating snapshots and formatting the data.
186+
*
187+
* @param toolName - The name of the tool that generated the response.
188+
* @param context - The MCP context.
189+
* @returns A promise that resolves to an array of text and image content.
190+
*/
118191
async handle(
119192
toolName: string,
120193
context: McpContext,
@@ -140,6 +213,13 @@ export class McpResponse implements Response {
140213
return this.format(toolName, context);
141214
}
142215

216+
/**
217+
* Formats the response into an array of text and image content.
218+
*
219+
* @param toolName - The name of the tool that generated the response.
220+
* @param context - The MCP context.
221+
* @returns An array of text and image content.
222+
*/
143223
format(
144224
toolName: string,
145225
context: McpContext,
@@ -314,6 +394,10 @@ Call ${handleDialog.name} to handle it before continuing.`);
314394
return response;
315395
}
316396

397+
/**
398+
* Resets the response lines for testing purposes.
399+
* @internal
400+
*/
317401
resetResponseLineForTesting() {
318402
this.#textResponseLines = [];
319403
}

src/Mutex.ts

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,23 @@
44
* SPDX-License-Identifier: Apache-2.0
55
*/
66

7+
/**
8+
* A simple asynchronous mutex implementation.
9+
* @public
10+
*/
711
export class Mutex {
12+
/**
13+
* A guard that releases the mutex when disposed.
14+
* @public
15+
*/
816
static Guard = class Guard {
917
#mutex: Mutex;
1018
constructor(mutex: Mutex) {
1119
this.#mutex = mutex;
1220
}
21+
/**
22+
* Releases the mutex.
23+
*/
1324
dispose(): void {
1425
return this.#mutex.release();
1526
}
@@ -18,7 +29,12 @@ export class Mutex {
1829
#locked = false;
1930
#acquirers: Array<() => void> = [];
2031

21-
// This is FIFO.
32+
/**
33+
* Acquires the mutex, waiting if necessary. This is a FIFO queue.
34+
*
35+
* @returns A promise that resolves with a guard, which will release the
36+
* mutex when disposed.
37+
*/
2238
async acquire(): Promise<InstanceType<typeof Mutex.Guard>> {
2339
if (!this.#locked) {
2440
this.#locked = true;
@@ -30,6 +46,10 @@ export class Mutex {
3046
return new Mutex.Guard(this);
3147
}
3248

49+
/**
50+
* Releases the mutex.
51+
* @internal
52+
*/
3353
release(): void {
3454
const resolve = this.#acquirers.shift();
3555
if (!resolve) {

src/PageCollector.ts

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,16 +6,29 @@
66

77
import type {Browser, HTTPRequest, Page} from 'puppeteer-core';
88

9+
/**
10+
* A generic class for collecting data from Puppeteer pages. It handles page
11+
* creation and navigation to manage data collection lifecycle.
12+
*
13+
* @template T The type of data to collect.
14+
* @public
15+
*/
916
export class PageCollector<T> {
1017
#browser: Browser;
1118
#initializer: (page: Page, collector: (item: T) => void) => void;
1219
/**
1320
* The Array in this map should only be set once
1421
* As we use the reference to it.
1522
* Use methods that manipulate the array in place.
23+
* @protected
1624
*/
1725
protected storage = new WeakMap<Page, T[]>();
1826

27+
/**
28+
* @param browser - The Puppeteer browser instance.
29+
* @param initializer - A function that sets up the data collection for a
30+
* page.
31+
*/
1932
constructor(
2033
browser: Browser,
2134
initializer: (page: Page, collector: (item: T) => void) => void,
@@ -24,6 +37,10 @@ export class PageCollector<T> {
2437
this.#initializer = initializer;
2538
}
2639

40+
/**
41+
* Initializes the collector by setting up data collection for all existing
42+
* pages and listening for new pages.
43+
*/
2744
async init() {
2845
const pages = await this.#browser.pages();
2946
for (const page of pages) {
@@ -39,6 +56,11 @@ export class PageCollector<T> {
3956
});
4057
}
4158

59+
/**
60+
* Adds a new page to the collector and initializes it.
61+
*
62+
* @param page - The page to add.
63+
*/
4264
public addPage(page: Page) {
4365
this.#initializePage(page);
4466
}
@@ -63,6 +85,13 @@ export class PageCollector<T> {
6385
});
6486
}
6587

88+
/**
89+
* Cleans up the stored data for a page. By default, it clears the entire
90+
* collection.
91+
*
92+
* @param page - The page to clean up.
93+
* @protected
94+
*/
6695
protected cleanup(page: Page) {
6796
const collection = this.storage.get(page);
6897
if (collection) {
@@ -71,12 +100,29 @@ export class PageCollector<T> {
71100
}
72101
}
73102

103+
/**
104+
* Gets the collected data for a specific page.
105+
*
106+
* @param page - The page to get data for.
107+
* @returns The collected data, or an empty array if none.
108+
*/
74109
getData(page: Page): T[] {
75110
return this.storage.get(page) ?? [];
76111
}
77112
}
78113

114+
/**
115+
* A specific implementation of PageCollector for collecting network requests.
116+
* @public
117+
*/
79118
export class NetworkCollector extends PageCollector<HTTPRequest> {
119+
/**
120+
* Cleans up network requests by removing all requests before the last
121+
* navigation.
122+
*
123+
* @param page - The page to clean up.
124+
* @override
125+
*/
80126
override cleanup(page: Page) {
81127
const requests = this.storage.get(page) ?? [];
82128
if (!requests) {

src/WaitForHelper.ts

Lines changed: 35 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,11 @@ import type {CdpPage} from 'puppeteer-core/internal/cdp/Page.js';
88

99
import {logger} from './logger.js';
1010

11+
/**
12+
* A helper class for waiting for various page events, such as stable DOM and
13+
* navigation, after performing an action.
14+
* @public
15+
*/
1116
export class WaitForHelper {
1217
#abortController = new AbortController();
1318
#page: CdpPage;
@@ -16,6 +21,12 @@ export class WaitForHelper {
1621
#expectNavigationIn: number;
1722
#navigationTimeout: number;
1823

24+
/**
25+
* @param page - The Puppeteer page to wait for events on.
26+
* @param cpuTimeoutMultiplier - The multiplier for CPU-bound timeouts.
27+
* @param networkTimeoutMultiplier - The multiplier for network-bound
28+
* timeouts.
29+
*/
1930
constructor(
2031
page: Page,
2132
cpuTimeoutMultiplier: number,
@@ -29,9 +40,10 @@ export class WaitForHelper {
2940
}
3041

3142
/**
32-
* A wrapper that executes a action and waits for
33-
* a potential navigation, after which it waits
34-
* for the DOM to be stable before returning.
43+
* Waits for the DOM to be stable (i.e., no mutations for a certain period).
44+
*
45+
* @returns A promise that resolves when the DOM is stable.
46+
* @throws If the timeout is reached before the DOM becomes stable.
3547
*/
3648
async waitForStableDom(): Promise<void> {
3749
const stableDomObserver = await this.#page.evaluateHandle(timeout => {
@@ -82,6 +94,12 @@ export class WaitForHelper {
8294
]);
8395
}
8496

97+
/**
98+
* Waits for a navigation to start.
99+
*
100+
* @returns A promise that resolves to true if a navigation starts, and false
101+
* otherwise.
102+
*/
85103
async waitForNavigationStarted() {
86104
// Currently Puppeteer does not have API
87105
// For when a navigation is about to start
@@ -114,6 +132,12 @@ export class WaitForHelper {
114132
]);
115133
}
116134

135+
/**
136+
* Creates a timeout promise that can be aborted.
137+
*
138+
* @param time - The timeout in milliseconds.
139+
* @returns A promise that resolves after the timeout.
140+
*/
117141
timeout(time: number): Promise<void> {
118142
return new Promise<void>(res => {
119143
const id = setTimeout(res, time);
@@ -124,6 +148,14 @@ export class WaitForHelper {
124148
});
125149
}
126150

151+
/**
152+
* Executes an action and then waits for events to settle, such as navigation
153+
* and stable DOM.
154+
*
155+
* @param action - The action to perform.
156+
* @returns A promise that resolves when all events have settled.
157+
* @throws If the action throws an error.
158+
*/
127159
async waitForEventsAfterAction(
128160
action: () => Promise<unknown>,
129161
): Promise<void> {

0 commit comments

Comments
 (0)