@pan-sec/notebooklm-mcp 1.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.
- package/LICENSE +21 -0
- package/README.md +289 -0
- package/SECURITY.md +539 -0
- package/dist/auth/auth-manager.d.ts +137 -0
- package/dist/auth/auth-manager.d.ts.map +1 -0
- package/dist/auth/auth-manager.js +984 -0
- package/dist/auth/auth-manager.js.map +1 -0
- package/dist/auth/mcp-auth.d.ts +102 -0
- package/dist/auth/mcp-auth.d.ts.map +1 -0
- package/dist/auth/mcp-auth.js +286 -0
- package/dist/auth/mcp-auth.js.map +1 -0
- package/dist/config.d.ts +89 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +216 -0
- package/dist/config.js.map +1 -0
- package/dist/errors.d.ts +26 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/errors.js +41 -0
- package/dist/errors.js.map +1 -0
- package/dist/index.d.ts +32 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +371 -0
- package/dist/index.js.map +1 -0
- package/dist/library/notebook-library.d.ts +70 -0
- package/dist/library/notebook-library.d.ts.map +1 -0
- package/dist/library/notebook-library.js +279 -0
- package/dist/library/notebook-library.js.map +1 -0
- package/dist/library/types.d.ts +67 -0
- package/dist/library/types.d.ts.map +1 -0
- package/dist/library/types.js +8 -0
- package/dist/library/types.js.map +1 -0
- package/dist/resources/resource-handlers.d.ts +22 -0
- package/dist/resources/resource-handlers.d.ts.map +1 -0
- package/dist/resources/resource-handlers.js +216 -0
- package/dist/resources/resource-handlers.js.map +1 -0
- package/dist/session/browser-session.d.ts +108 -0
- package/dist/session/browser-session.d.ts.map +1 -0
- package/dist/session/browser-session.js +621 -0
- package/dist/session/browser-session.js.map +1 -0
- package/dist/session/session-manager.d.ts +77 -0
- package/dist/session/session-manager.d.ts.map +1 -0
- package/dist/session/session-manager.js +314 -0
- package/dist/session/session-manager.js.map +1 -0
- package/dist/session/session-timeout.d.ts +122 -0
- package/dist/session/session-timeout.d.ts.map +1 -0
- package/dist/session/session-timeout.js +281 -0
- package/dist/session/session-timeout.js.map +1 -0
- package/dist/session/shared-context-manager.d.ts +107 -0
- package/dist/session/shared-context-manager.d.ts.map +1 -0
- package/dist/session/shared-context-manager.js +447 -0
- package/dist/session/shared-context-manager.js.map +1 -0
- package/dist/tools/definitions/ask-question.d.ts +8 -0
- package/dist/tools/definitions/ask-question.d.ts.map +1 -0
- package/dist/tools/definitions/ask-question.js +211 -0
- package/dist/tools/definitions/ask-question.js.map +1 -0
- package/dist/tools/definitions/notebook-management.d.ts +3 -0
- package/dist/tools/definitions/notebook-management.d.ts.map +1 -0
- package/dist/tools/definitions/notebook-management.js +243 -0
- package/dist/tools/definitions/notebook-management.js.map +1 -0
- package/dist/tools/definitions/session-management.d.ts +3 -0
- package/dist/tools/definitions/session-management.d.ts.map +1 -0
- package/dist/tools/definitions/session-management.js +41 -0
- package/dist/tools/definitions/session-management.js.map +1 -0
- package/dist/tools/definitions/system.d.ts +3 -0
- package/dist/tools/definitions/system.d.ts.map +1 -0
- package/dist/tools/definitions/system.js +143 -0
- package/dist/tools/definitions/system.js.map +1 -0
- package/dist/tools/definitions.d.ts +12 -0
- package/dist/tools/definitions.d.ts.map +1 -0
- package/dist/tools/definitions.js +26 -0
- package/dist/tools/definitions.js.map +1 -0
- package/dist/tools/handlers.d.ts +213 -0
- package/dist/tools/handlers.d.ts.map +1 -0
- package/dist/tools/handlers.js +813 -0
- package/dist/tools/handlers.js.map +1 -0
- package/dist/tools/index.d.ts +8 -0
- package/dist/tools/index.d.ts.map +1 -0
- package/dist/tools/index.js +8 -0
- package/dist/tools/index.js.map +1 -0
- package/dist/types.d.ts +82 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +5 -0
- package/dist/types.js.map +1 -0
- package/dist/utils/audit-logger.d.ts +140 -0
- package/dist/utils/audit-logger.d.ts.map +1 -0
- package/dist/utils/audit-logger.js +361 -0
- package/dist/utils/audit-logger.js.map +1 -0
- package/dist/utils/cert-pinning.d.ts +97 -0
- package/dist/utils/cert-pinning.d.ts.map +1 -0
- package/dist/utils/cert-pinning.js +328 -0
- package/dist/utils/cert-pinning.js.map +1 -0
- package/dist/utils/cleanup-manager.d.ts +133 -0
- package/dist/utils/cleanup-manager.d.ts.map +1 -0
- package/dist/utils/cleanup-manager.js +673 -0
- package/dist/utils/cleanup-manager.js.map +1 -0
- package/dist/utils/cli-handler.d.ts +16 -0
- package/dist/utils/cli-handler.d.ts.map +1 -0
- package/dist/utils/cli-handler.js +102 -0
- package/dist/utils/cli-handler.js.map +1 -0
- package/dist/utils/crypto.d.ts +175 -0
- package/dist/utils/crypto.d.ts.map +1 -0
- package/dist/utils/crypto.js +612 -0
- package/dist/utils/crypto.js.map +1 -0
- package/dist/utils/logger.d.ts +61 -0
- package/dist/utils/logger.d.ts.map +1 -0
- package/dist/utils/logger.js +92 -0
- package/dist/utils/logger.js.map +1 -0
- package/dist/utils/page-utils.d.ts +54 -0
- package/dist/utils/page-utils.d.ts.map +1 -0
- package/dist/utils/page-utils.js +405 -0
- package/dist/utils/page-utils.js.map +1 -0
- package/dist/utils/response-validator.d.ts +98 -0
- package/dist/utils/response-validator.d.ts.map +1 -0
- package/dist/utils/response-validator.js +352 -0
- package/dist/utils/response-validator.js.map +1 -0
- package/dist/utils/secrets-scanner.d.ts +126 -0
- package/dist/utils/secrets-scanner.d.ts.map +1 -0
- package/dist/utils/secrets-scanner.js +443 -0
- package/dist/utils/secrets-scanner.js.map +1 -0
- package/dist/utils/secure-memory.d.ts +130 -0
- package/dist/utils/secure-memory.d.ts.map +1 -0
- package/dist/utils/secure-memory.js +279 -0
- package/dist/utils/secure-memory.js.map +1 -0
- package/dist/utils/security.d.ts +83 -0
- package/dist/utils/security.d.ts.map +1 -0
- package/dist/utils/security.js +272 -0
- package/dist/utils/security.js.map +1 -0
- package/dist/utils/settings-manager.d.ts +37 -0
- package/dist/utils/settings-manager.d.ts.map +1 -0
- package/dist/utils/settings-manager.js +125 -0
- package/dist/utils/settings-manager.js.map +1 -0
- package/dist/utils/stealth-utils.d.ts +135 -0
- package/dist/utils/stealth-utils.d.ts.map +1 -0
- package/dist/utils/stealth-utils.js +398 -0
- package/dist/utils/stealth-utils.js.map +1 -0
- package/dist/utils/tool-validation.d.ts +93 -0
- package/dist/utils/tool-validation.d.ts.map +1 -0
- package/dist/utils/tool-validation.js +277 -0
- package/dist/utils/tool-validation.js.map +1 -0
- package/docs/SECURITY_IMPLEMENTATION_PLAN.md +437 -0
- package/docs/configuration.md +94 -0
- package/docs/tools.md +34 -0
- package/docs/troubleshooting.md +59 -0
- package/docs/usage-guide.md +245 -0
- package/package.json +82 -0
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Console logging utilities with colors and formatting
|
|
3
|
+
* Similar to Python's rich.console
|
|
4
|
+
*/
|
|
5
|
+
type LogLevel = "info" | "success" | "warning" | "error" | "debug" | "dim";
|
|
6
|
+
/**
|
|
7
|
+
* Logger class for consistent console output
|
|
8
|
+
*/
|
|
9
|
+
export declare class Logger {
|
|
10
|
+
private enabled;
|
|
11
|
+
constructor(enabled?: boolean);
|
|
12
|
+
/**
|
|
13
|
+
* Log a message with a specific style
|
|
14
|
+
*/
|
|
15
|
+
log(message: string, level?: LogLevel): void;
|
|
16
|
+
/**
|
|
17
|
+
* Log info message
|
|
18
|
+
*/
|
|
19
|
+
info(message: string): void;
|
|
20
|
+
/**
|
|
21
|
+
* Log success message
|
|
22
|
+
*/
|
|
23
|
+
success(message: string): void;
|
|
24
|
+
/**
|
|
25
|
+
* Log warning message
|
|
26
|
+
*/
|
|
27
|
+
warning(message: string): void;
|
|
28
|
+
/**
|
|
29
|
+
* Log error message
|
|
30
|
+
*/
|
|
31
|
+
error(message: string): void;
|
|
32
|
+
/**
|
|
33
|
+
* Log debug message
|
|
34
|
+
*/
|
|
35
|
+
debug(message: string): void;
|
|
36
|
+
/**
|
|
37
|
+
* Log dim message (for less important info)
|
|
38
|
+
*/
|
|
39
|
+
dim(message: string): void;
|
|
40
|
+
/**
|
|
41
|
+
* Enable or disable logging
|
|
42
|
+
*/
|
|
43
|
+
setEnabled(enabled: boolean): void;
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Global logger instance
|
|
47
|
+
*/
|
|
48
|
+
export declare const logger: Logger;
|
|
49
|
+
/**
|
|
50
|
+
* Convenience functions for quick logging
|
|
51
|
+
*/
|
|
52
|
+
export declare const log: {
|
|
53
|
+
info: (msg: string) => void;
|
|
54
|
+
success: (msg: string) => void;
|
|
55
|
+
warning: (msg: string) => void;
|
|
56
|
+
error: (msg: string) => void;
|
|
57
|
+
debug: (msg: string) => void;
|
|
58
|
+
dim: (msg: string) => void;
|
|
59
|
+
};
|
|
60
|
+
export {};
|
|
61
|
+
//# sourceMappingURL=logger.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"logger.d.ts","sourceRoot":"","sources":["../../src/utils/logger.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,KAAK,QAAQ,GAAG,MAAM,GAAG,SAAS,GAAG,SAAS,GAAG,OAAO,GAAG,OAAO,GAAG,KAAK,CAAC;AAkB3E;;GAEG;AACH,qBAAa,MAAM;IACjB,OAAO,CAAC,OAAO,CAAU;gBAEb,OAAO,GAAE,OAAc;IAInC;;OAEG;IACH,GAAG,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,GAAE,QAAiB,GAAG,IAAI;IAWpD;;OAEG;IACH,IAAI,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI;IAI3B;;OAEG;IACH,OAAO,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI;IAI9B;;OAEG;IACH,OAAO,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI;IAI9B;;OAEG;IACH,KAAK,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI;IAI5B;;OAEG;IACH,KAAK,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI;IAI5B;;OAEG;IACH,GAAG,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI;IAI1B;;OAEG;IACH,UAAU,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI;CAGnC;AAED;;GAEG;AACH,eAAO,MAAM,MAAM,QAAe,CAAC;AAEnC;;GAEG;AACH,eAAO,MAAM,GAAG;gBACF,MAAM;mBACH,MAAM;mBACN,MAAM;iBACR,MAAM;iBACN,MAAM;eACR,MAAM;CAClB,CAAC"}
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Console logging utilities with colors and formatting
|
|
3
|
+
* Similar to Python's rich.console
|
|
4
|
+
*/
|
|
5
|
+
const STYLES = {
|
|
6
|
+
info: { prefix: "ℹ️", color: "\x1b[36m" }, // Cyan
|
|
7
|
+
success: { prefix: "✅", color: "\x1b[32m" }, // Green
|
|
8
|
+
warning: { prefix: "⚠️", color: "\x1b[33m" }, // Yellow
|
|
9
|
+
error: { prefix: "❌", color: "\x1b[31m" }, // Red
|
|
10
|
+
debug: { prefix: "🔍", color: "\x1b[35m" }, // Magenta
|
|
11
|
+
dim: { prefix: " ", color: "\x1b[2m" }, // Dim
|
|
12
|
+
};
|
|
13
|
+
const RESET = "\x1b[0m";
|
|
14
|
+
/**
|
|
15
|
+
* Logger class for consistent console output
|
|
16
|
+
*/
|
|
17
|
+
export class Logger {
|
|
18
|
+
enabled;
|
|
19
|
+
constructor(enabled = true) {
|
|
20
|
+
this.enabled = enabled;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Log a message with a specific style
|
|
24
|
+
*/
|
|
25
|
+
log(message, level = "info") {
|
|
26
|
+
if (!this.enabled)
|
|
27
|
+
return;
|
|
28
|
+
const style = STYLES[level];
|
|
29
|
+
const timestamp = new Date().toISOString().split("T")[1].slice(0, 8);
|
|
30
|
+
const formattedMessage = `${style.color}${style.prefix} [${timestamp}] ${message}${RESET}`;
|
|
31
|
+
// Use stderr for logs to keep stdout clean for MCP JSON-RPC
|
|
32
|
+
console.error(formattedMessage);
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Log info message
|
|
36
|
+
*/
|
|
37
|
+
info(message) {
|
|
38
|
+
this.log(message, "info");
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Log success message
|
|
42
|
+
*/
|
|
43
|
+
success(message) {
|
|
44
|
+
this.log(message, "success");
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Log warning message
|
|
48
|
+
*/
|
|
49
|
+
warning(message) {
|
|
50
|
+
this.log(message, "warning");
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Log error message
|
|
54
|
+
*/
|
|
55
|
+
error(message) {
|
|
56
|
+
this.log(message, "error");
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Log debug message
|
|
60
|
+
*/
|
|
61
|
+
debug(message) {
|
|
62
|
+
this.log(message, "debug");
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Log dim message (for less important info)
|
|
66
|
+
*/
|
|
67
|
+
dim(message) {
|
|
68
|
+
this.log(message, "dim");
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Enable or disable logging
|
|
72
|
+
*/
|
|
73
|
+
setEnabled(enabled) {
|
|
74
|
+
this.enabled = enabled;
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* Global logger instance
|
|
79
|
+
*/
|
|
80
|
+
export const logger = new Logger();
|
|
81
|
+
/**
|
|
82
|
+
* Convenience functions for quick logging
|
|
83
|
+
*/
|
|
84
|
+
export const log = {
|
|
85
|
+
info: (msg) => logger.info(msg),
|
|
86
|
+
success: (msg) => logger.success(msg),
|
|
87
|
+
warning: (msg) => logger.warning(msg),
|
|
88
|
+
error: (msg) => logger.error(msg),
|
|
89
|
+
debug: (msg) => logger.debug(msg),
|
|
90
|
+
dim: (msg) => logger.dim(msg),
|
|
91
|
+
};
|
|
92
|
+
//# sourceMappingURL=logger.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"logger.js","sourceRoot":"","sources":["../../src/utils/logger.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Page utilities for extracting responses from NotebookLM web UI
|
|
3
|
+
*
|
|
4
|
+
* This module provides functions to:
|
|
5
|
+
* - Extract latest assistant responses from the page
|
|
6
|
+
* - Wait for new responses with streaming detection
|
|
7
|
+
* - Detect placeholders and loading states
|
|
8
|
+
* - Snapshot existing responses for comparison
|
|
9
|
+
*
|
|
10
|
+
* Based on the Python implementation from page_utils.py
|
|
11
|
+
*/
|
|
12
|
+
import type { Page } from "patchright";
|
|
13
|
+
/**
|
|
14
|
+
* Snapshot the latest response text currently visible
|
|
15
|
+
* Returns null if no response found
|
|
16
|
+
*/
|
|
17
|
+
export declare function snapshotLatestResponse(page: Page): Promise<string | null>;
|
|
18
|
+
/**
|
|
19
|
+
* Snapshot ALL existing assistant response texts
|
|
20
|
+
* Used to capture visible responses BEFORE submitting a new question
|
|
21
|
+
*/
|
|
22
|
+
export declare function snapshotAllResponses(page: Page): Promise<string[]>;
|
|
23
|
+
/**
|
|
24
|
+
* Count the number of visible assistant response elements
|
|
25
|
+
*/
|
|
26
|
+
export declare function countResponseElements(page: Page): Promise<number>;
|
|
27
|
+
/**
|
|
28
|
+
* Wait for a new assistant response with streaming detection
|
|
29
|
+
*
|
|
30
|
+
* This function:
|
|
31
|
+
* 1. Polls the page for new response text
|
|
32
|
+
* 2. Detects streaming (text changes) vs. complete (text stable)
|
|
33
|
+
* 3. Requires text to be stable for 3 consecutive polls before returning
|
|
34
|
+
* 4. Ignores placeholders, question echoes, and known responses
|
|
35
|
+
*
|
|
36
|
+
* @param page Playwright page instance
|
|
37
|
+
* @param options Options for waiting
|
|
38
|
+
* @returns The new response text, or null if timeout
|
|
39
|
+
*/
|
|
40
|
+
export declare function waitForLatestAnswer(page: Page, options?: {
|
|
41
|
+
question?: string;
|
|
42
|
+
timeoutMs?: number;
|
|
43
|
+
pollIntervalMs?: number;
|
|
44
|
+
ignoreTexts?: string[];
|
|
45
|
+
debug?: boolean;
|
|
46
|
+
}): Promise<string | null>;
|
|
47
|
+
declare const _default: {
|
|
48
|
+
snapshotLatestResponse: typeof snapshotLatestResponse;
|
|
49
|
+
snapshotAllResponses: typeof snapshotAllResponses;
|
|
50
|
+
countResponseElements: typeof countResponseElements;
|
|
51
|
+
waitForLatestAnswer: typeof waitForLatestAnswer;
|
|
52
|
+
};
|
|
53
|
+
export default _default;
|
|
54
|
+
//# sourceMappingURL=page-utils.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"page-utils.d.ts","sourceRoot":"","sources":["../../src/utils/page-utils.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,YAAY,CAAC;AAkDvC;;;GAGG;AACH,wBAAsB,sBAAsB,CAAC,IAAI,EAAE,IAAI,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAE/E;AAED;;;GAGG;AACH,wBAAsB,oBAAoB,CAAC,IAAI,EAAE,IAAI,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CA4BxE;AAED;;GAEG;AACH,wBAAsB,qBAAqB,CAAC,IAAI,EAAE,IAAI,GAAG,OAAO,CAAC,MAAM,CAAC,CA2BvE;AAED;;;;;;;;;;;;GAYG;AACH,wBAAsB,mBAAmB,CACvC,IAAI,EAAE,IAAI,EACV,OAAO,GAAE;IACP,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,WAAW,CAAC,EAAE,MAAM,EAAE,CAAC;IACvB,KAAK,CAAC,EAAE,OAAO,CAAC;CACZ,GACL,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAiHxB;;;;;;;AAuMD,wBAKE"}
|
|
@@ -0,0 +1,405 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Page utilities for extracting responses from NotebookLM web UI
|
|
3
|
+
*
|
|
4
|
+
* This module provides functions to:
|
|
5
|
+
* - Extract latest assistant responses from the page
|
|
6
|
+
* - Wait for new responses with streaming detection
|
|
7
|
+
* - Detect placeholders and loading states
|
|
8
|
+
* - Snapshot existing responses for comparison
|
|
9
|
+
*
|
|
10
|
+
* Based on the Python implementation from page_utils.py
|
|
11
|
+
*/
|
|
12
|
+
import { log } from "./logger.js";
|
|
13
|
+
// ============================================================================
|
|
14
|
+
// Constants
|
|
15
|
+
// ============================================================================
|
|
16
|
+
/**
|
|
17
|
+
* CSS selectors to find assistant response elements
|
|
18
|
+
* Ordered by priority (most specific first)
|
|
19
|
+
*/
|
|
20
|
+
const RESPONSE_SELECTORS = [
|
|
21
|
+
".to-user-container .message-text-content",
|
|
22
|
+
"[data-message-author='bot']",
|
|
23
|
+
"[data-message-author='assistant']",
|
|
24
|
+
"[data-message-role='assistant']",
|
|
25
|
+
"[data-author='assistant']",
|
|
26
|
+
"[data-renderer*='assistant']",
|
|
27
|
+
"[data-automation-id='response-text']",
|
|
28
|
+
"[data-automation-id='assistant-response']",
|
|
29
|
+
"[data-automation-id='chat-response']",
|
|
30
|
+
"[data-testid*='assistant']",
|
|
31
|
+
"[data-testid*='response']",
|
|
32
|
+
"[aria-live='polite']",
|
|
33
|
+
"[role='listitem'][data-message-author]",
|
|
34
|
+
];
|
|
35
|
+
// ============================================================================
|
|
36
|
+
// Helper Functions
|
|
37
|
+
// ============================================================================
|
|
38
|
+
/**
|
|
39
|
+
* Simple string hash function (for efficient comparison)
|
|
40
|
+
*/
|
|
41
|
+
function hashString(str) {
|
|
42
|
+
let hash = 0;
|
|
43
|
+
for (let i = 0; i < str.length; i++) {
|
|
44
|
+
const char = str.charCodeAt(i);
|
|
45
|
+
hash = (hash << 5) - hash + char;
|
|
46
|
+
hash = hash & hash; // Convert to 32bit integer
|
|
47
|
+
}
|
|
48
|
+
return hash;
|
|
49
|
+
}
|
|
50
|
+
// ============================================================================
|
|
51
|
+
// Main Functions
|
|
52
|
+
// ============================================================================
|
|
53
|
+
/**
|
|
54
|
+
* Snapshot the latest response text currently visible
|
|
55
|
+
* Returns null if no response found
|
|
56
|
+
*/
|
|
57
|
+
export async function snapshotLatestResponse(page) {
|
|
58
|
+
return await extractLatestText(page, new Set(), false, 0);
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Snapshot ALL existing assistant response texts
|
|
62
|
+
* Used to capture visible responses BEFORE submitting a new question
|
|
63
|
+
*/
|
|
64
|
+
export async function snapshotAllResponses(page) {
|
|
65
|
+
const allTexts = [];
|
|
66
|
+
const primarySelector = ".to-user-container";
|
|
67
|
+
try {
|
|
68
|
+
const containers = await page.$$(primarySelector);
|
|
69
|
+
if (containers.length > 0) {
|
|
70
|
+
for (const container of containers) {
|
|
71
|
+
try {
|
|
72
|
+
const textElement = await container.$(".message-text-content");
|
|
73
|
+
if (textElement) {
|
|
74
|
+
const text = await textElement.innerText();
|
|
75
|
+
if (text && text.trim()) {
|
|
76
|
+
allTexts.push(text.trim());
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
catch {
|
|
81
|
+
continue;
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
log.info(`📸 [SNAPSHOT] Captured ${allTexts.length} existing responses`);
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
catch (error) {
|
|
88
|
+
log.warning(`⚠️ [SNAPSHOT] Failed to snapshot responses: ${error}`);
|
|
89
|
+
}
|
|
90
|
+
return allTexts;
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* Count the number of visible assistant response elements
|
|
94
|
+
*/
|
|
95
|
+
export async function countResponseElements(page) {
|
|
96
|
+
let count = 0;
|
|
97
|
+
for (const selector of RESPONSE_SELECTORS) {
|
|
98
|
+
try {
|
|
99
|
+
const elements = await page.$$(selector);
|
|
100
|
+
if (elements.length > 0) {
|
|
101
|
+
// Count only visible elements
|
|
102
|
+
for (const el of elements) {
|
|
103
|
+
try {
|
|
104
|
+
const isVisible = await el.isVisible();
|
|
105
|
+
if (isVisible) {
|
|
106
|
+
count++;
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
catch {
|
|
110
|
+
continue;
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
// If we found elements with this selector, stop trying others
|
|
114
|
+
if (count > 0) {
|
|
115
|
+
break;
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
catch {
|
|
120
|
+
continue;
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
return count;
|
|
124
|
+
}
|
|
125
|
+
/**
|
|
126
|
+
* Wait for a new assistant response with streaming detection
|
|
127
|
+
*
|
|
128
|
+
* This function:
|
|
129
|
+
* 1. Polls the page for new response text
|
|
130
|
+
* 2. Detects streaming (text changes) vs. complete (text stable)
|
|
131
|
+
* 3. Requires text to be stable for 3 consecutive polls before returning
|
|
132
|
+
* 4. Ignores placeholders, question echoes, and known responses
|
|
133
|
+
*
|
|
134
|
+
* @param page Playwright page instance
|
|
135
|
+
* @param options Options for waiting
|
|
136
|
+
* @returns The new response text, or null if timeout
|
|
137
|
+
*/
|
|
138
|
+
export async function waitForLatestAnswer(page, options = {}) {
|
|
139
|
+
const { question = "", timeoutMs = 120000, pollIntervalMs = 1000, ignoreTexts = [], debug = false, } = options;
|
|
140
|
+
const deadline = Date.now() + timeoutMs;
|
|
141
|
+
const sanitizedQuestion = question.trim().toLowerCase();
|
|
142
|
+
// Track ALL known texts as HASHES (memory efficient!)
|
|
143
|
+
const knownHashes = new Set();
|
|
144
|
+
for (const text of ignoreTexts) {
|
|
145
|
+
if (typeof text === "string" && text.trim()) {
|
|
146
|
+
knownHashes.add(hashString(text.trim()));
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
if (debug) {
|
|
150
|
+
log.debug(`🔍 [DEBUG] Waiting for NEW answer. Ignoring ${knownHashes.size} known responses`);
|
|
151
|
+
}
|
|
152
|
+
let pollCount = 0;
|
|
153
|
+
let lastCandidate = null;
|
|
154
|
+
let stableCount = 0; // Track how many times we see the same text
|
|
155
|
+
const requiredStablePolls = 3; // Text must be stable for 3 consecutive polls
|
|
156
|
+
while (Date.now() < deadline) {
|
|
157
|
+
pollCount++;
|
|
158
|
+
// Check if NotebookLM is still "thinking" (most reliable indicator)
|
|
159
|
+
try {
|
|
160
|
+
const thinkingElement = await page.$('div.thinking-message');
|
|
161
|
+
if (thinkingElement) {
|
|
162
|
+
const isVisible = await thinkingElement.isVisible();
|
|
163
|
+
if (isVisible) {
|
|
164
|
+
if (debug && pollCount % 5 === 0) {
|
|
165
|
+
log.debug("🔍 [DEBUG] NotebookLM still thinking (div.thinking-message visible)...");
|
|
166
|
+
}
|
|
167
|
+
await page.waitForTimeout(pollIntervalMs);
|
|
168
|
+
continue;
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
catch {
|
|
173
|
+
// Ignore errors checking thinking state
|
|
174
|
+
}
|
|
175
|
+
// Extract latest NEW text
|
|
176
|
+
const candidate = await extractLatestText(page, knownHashes, debug, pollCount);
|
|
177
|
+
if (candidate) {
|
|
178
|
+
const normalized = candidate.trim();
|
|
179
|
+
if (normalized) {
|
|
180
|
+
const lower = normalized.toLowerCase();
|
|
181
|
+
// Check if it's the question echo
|
|
182
|
+
if (lower === sanitizedQuestion) {
|
|
183
|
+
if (debug) {
|
|
184
|
+
log.debug("🔍 [DEBUG] Found question echo, ignoring");
|
|
185
|
+
}
|
|
186
|
+
knownHashes.add(hashString(normalized)); // Mark as seen
|
|
187
|
+
await page.waitForTimeout(pollIntervalMs);
|
|
188
|
+
continue;
|
|
189
|
+
}
|
|
190
|
+
// ========================================
|
|
191
|
+
// STREAMING DETECTION: Check if text is stable
|
|
192
|
+
// ========================================
|
|
193
|
+
if (normalized === lastCandidate) {
|
|
194
|
+
// Text hasn't changed - it's stable
|
|
195
|
+
stableCount++;
|
|
196
|
+
if (debug && stableCount === requiredStablePolls) {
|
|
197
|
+
log.debug(`✅ [DEBUG] Text stable for ${stableCount} polls (${normalized.length} chars)`);
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
else {
|
|
201
|
+
// Text changed - streaming in progress
|
|
202
|
+
if (debug && lastCandidate) {
|
|
203
|
+
log.debug(`🔄 [DEBUG] Text changed (${normalized.length} chars, was ${lastCandidate.length})`);
|
|
204
|
+
}
|
|
205
|
+
stableCount = 1;
|
|
206
|
+
lastCandidate = normalized;
|
|
207
|
+
}
|
|
208
|
+
// Only return once text is stable
|
|
209
|
+
if (stableCount >= requiredStablePolls) {
|
|
210
|
+
if (debug) {
|
|
211
|
+
log.debug(`✅ [DEBUG] Returning stable answer (${normalized.length} chars)`);
|
|
212
|
+
}
|
|
213
|
+
return normalized;
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
await page.waitForTimeout(pollIntervalMs);
|
|
218
|
+
}
|
|
219
|
+
if (debug) {
|
|
220
|
+
log.debug(`⏱️ [DEBUG] Timeout after ${pollCount} polls`);
|
|
221
|
+
}
|
|
222
|
+
return null;
|
|
223
|
+
}
|
|
224
|
+
/**
|
|
225
|
+
* Extract the latest NEW response text from the page
|
|
226
|
+
* Uses hash-based comparison for efficiency
|
|
227
|
+
*
|
|
228
|
+
* @param page Playwright page instance
|
|
229
|
+
* @param knownHashes Set of hashes of already-seen response texts
|
|
230
|
+
* @param debug Enable debug logging
|
|
231
|
+
* @param pollCount Current poll number (for conditional logging)
|
|
232
|
+
* @returns First NEW response text found, or null
|
|
233
|
+
*/
|
|
234
|
+
async function extractLatestText(page, knownHashes, debug, pollCount) {
|
|
235
|
+
// Try the primary selector first (most specific for NotebookLM)
|
|
236
|
+
const primarySelector = ".to-user-container";
|
|
237
|
+
try {
|
|
238
|
+
const containers = await page.$$(primarySelector);
|
|
239
|
+
const totalContainers = containers.length;
|
|
240
|
+
// Early exit if no new containers possible
|
|
241
|
+
if (totalContainers <= knownHashes.size) {
|
|
242
|
+
if (debug && pollCount % 5 === 0) {
|
|
243
|
+
log.dim(`⏭️ [EXTRACT] No new containers (${totalContainers} total, ${knownHashes.size} known)`);
|
|
244
|
+
}
|
|
245
|
+
return null;
|
|
246
|
+
}
|
|
247
|
+
if (containers.length > 0) {
|
|
248
|
+
// Only log every 5th poll to reduce noise
|
|
249
|
+
if (debug && pollCount % 5 === 0) {
|
|
250
|
+
log.dim(`🔍 [EXTRACT] Scanning ${totalContainers} containers (${knownHashes.size} known)`);
|
|
251
|
+
}
|
|
252
|
+
let skipped = 0;
|
|
253
|
+
let empty = 0;
|
|
254
|
+
// Scan ALL containers to find the FIRST with NEW text
|
|
255
|
+
for (let idx = 0; idx < containers.length; idx++) {
|
|
256
|
+
const container = containers[idx];
|
|
257
|
+
try {
|
|
258
|
+
const textElement = await container.$(".message-text-content");
|
|
259
|
+
if (textElement) {
|
|
260
|
+
const text = await textElement.innerText();
|
|
261
|
+
if (text && text.trim()) {
|
|
262
|
+
// Hash-based comparison (faster & less memory)
|
|
263
|
+
const textHash = hashString(text.trim());
|
|
264
|
+
if (!knownHashes.has(textHash)) {
|
|
265
|
+
log.success(`✅ [EXTRACT] Found NEW text in container[${idx}]: ${text.trim().length} chars`);
|
|
266
|
+
return text.trim();
|
|
267
|
+
}
|
|
268
|
+
else {
|
|
269
|
+
skipped++;
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
else {
|
|
273
|
+
empty++;
|
|
274
|
+
}
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
catch {
|
|
278
|
+
continue;
|
|
279
|
+
}
|
|
280
|
+
}
|
|
281
|
+
// Only log summary if debug enabled
|
|
282
|
+
if (debug && pollCount % 5 === 0) {
|
|
283
|
+
log.dim(`⏭️ [EXTRACT] No NEW text (skipped ${skipped} known, ${empty} empty)`);
|
|
284
|
+
}
|
|
285
|
+
return null; // Don't fall through to fallback!
|
|
286
|
+
}
|
|
287
|
+
else {
|
|
288
|
+
if (debug) {
|
|
289
|
+
log.warning("⚠️ [EXTRACT] No containers found");
|
|
290
|
+
}
|
|
291
|
+
}
|
|
292
|
+
}
|
|
293
|
+
catch (error) {
|
|
294
|
+
log.error(`❌ [EXTRACT] Primary selector failed: ${error}`);
|
|
295
|
+
}
|
|
296
|
+
// Fallback: Try other selectors (only if primary selector failed/found nothing)
|
|
297
|
+
if (debug) {
|
|
298
|
+
log.dim("🔄 [EXTRACT] Trying fallback selectors...");
|
|
299
|
+
}
|
|
300
|
+
for (const selector of RESPONSE_SELECTORS) {
|
|
301
|
+
try {
|
|
302
|
+
const elements = await page.$$(selector);
|
|
303
|
+
if (elements.length === 0)
|
|
304
|
+
continue;
|
|
305
|
+
// Scan ALL elements to find the first with NEW text
|
|
306
|
+
for (const element of elements) {
|
|
307
|
+
try {
|
|
308
|
+
// Prefer full container text when available
|
|
309
|
+
let container = element;
|
|
310
|
+
try {
|
|
311
|
+
const closest = await element.evaluateHandle((el) => {
|
|
312
|
+
return el.closest("[data-message-author], [data-message-role], [data-author], " +
|
|
313
|
+
"[data-testid*='assistant'], [data-automation-id*='response'], article, section");
|
|
314
|
+
});
|
|
315
|
+
if (closest) {
|
|
316
|
+
container = closest.asElement() || element;
|
|
317
|
+
}
|
|
318
|
+
}
|
|
319
|
+
catch {
|
|
320
|
+
container = element;
|
|
321
|
+
}
|
|
322
|
+
const text = await container.innerText();
|
|
323
|
+
if (text && text.trim() && !knownHashes.has(hashString(text.trim()))) {
|
|
324
|
+
return text.trim();
|
|
325
|
+
}
|
|
326
|
+
}
|
|
327
|
+
catch {
|
|
328
|
+
continue;
|
|
329
|
+
}
|
|
330
|
+
}
|
|
331
|
+
}
|
|
332
|
+
catch {
|
|
333
|
+
continue;
|
|
334
|
+
}
|
|
335
|
+
}
|
|
336
|
+
// Final fallback: JavaScript evaluation
|
|
337
|
+
try {
|
|
338
|
+
const fallbackText = await page.evaluate(() => {
|
|
339
|
+
// @ts-expect-error - DOM types available in browser context
|
|
340
|
+
const unique = new Set();
|
|
341
|
+
// @ts-expect-error - DOM types available in browser context
|
|
342
|
+
const isVisible = (el) => {
|
|
343
|
+
// @ts-expect-error - DOM types available in browser context
|
|
344
|
+
if (!el || !el.isConnected)
|
|
345
|
+
return false;
|
|
346
|
+
const rect = el.getBoundingClientRect();
|
|
347
|
+
if (rect.width === 0 || rect.height === 0)
|
|
348
|
+
return false;
|
|
349
|
+
// @ts-expect-error - window available in browser context
|
|
350
|
+
const style = window.getComputedStyle(el);
|
|
351
|
+
if (style.visibility === "hidden" ||
|
|
352
|
+
style.display === "none" ||
|
|
353
|
+
parseFloat(style.opacity || "1") === 0) {
|
|
354
|
+
return false;
|
|
355
|
+
}
|
|
356
|
+
return true;
|
|
357
|
+
};
|
|
358
|
+
const selectors = [
|
|
359
|
+
"[data-message-author]",
|
|
360
|
+
"[data-message-role]",
|
|
361
|
+
"[data-author]",
|
|
362
|
+
"[data-renderer*='assistant']",
|
|
363
|
+
"[data-testid*='assistant']",
|
|
364
|
+
"[data-automation-id*='response']",
|
|
365
|
+
];
|
|
366
|
+
const candidates = [];
|
|
367
|
+
for (const selector of selectors) {
|
|
368
|
+
// @ts-expect-error - document available in browser context
|
|
369
|
+
for (const el of document.querySelectorAll(selector)) {
|
|
370
|
+
if (!isVisible(el))
|
|
371
|
+
continue;
|
|
372
|
+
if (unique.has(el))
|
|
373
|
+
continue;
|
|
374
|
+
unique.add(el);
|
|
375
|
+
// @ts-expect-error - DOM types available in browser context
|
|
376
|
+
const text = el.innerText || el.textContent || "";
|
|
377
|
+
if (!text.trim())
|
|
378
|
+
continue;
|
|
379
|
+
candidates.push(text.trim());
|
|
380
|
+
}
|
|
381
|
+
}
|
|
382
|
+
if (candidates.length > 0) {
|
|
383
|
+
return candidates[candidates.length - 1];
|
|
384
|
+
}
|
|
385
|
+
return null;
|
|
386
|
+
});
|
|
387
|
+
if (typeof fallbackText === "string" && fallbackText.trim()) {
|
|
388
|
+
return fallbackText.trim();
|
|
389
|
+
}
|
|
390
|
+
}
|
|
391
|
+
catch {
|
|
392
|
+
// Ignore evaluation errors
|
|
393
|
+
}
|
|
394
|
+
return null;
|
|
395
|
+
}
|
|
396
|
+
// ============================================================================
|
|
397
|
+
// Exports
|
|
398
|
+
// ============================================================================
|
|
399
|
+
export default {
|
|
400
|
+
snapshotLatestResponse,
|
|
401
|
+
snapshotAllResponses,
|
|
402
|
+
countResponseElements,
|
|
403
|
+
waitForLatestAnswer,
|
|
404
|
+
};
|
|
405
|
+
//# sourceMappingURL=page-utils.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"page-utils.js","sourceRoot":"","sources":["../../src/utils/page-utils.ts"],"names":[],"mappings":"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"}
|