@pan-sec/notebooklm-mcp 1.10.5 → 1.10.8
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/dist/auth/auth-manager.d.ts +3 -0
- package/dist/auth/auth-manager.d.ts.map +1 -1
- package/dist/auth/auth-manager.js +87 -70
- package/dist/auth/auth-manager.js.map +1 -1
- package/dist/index.js +5 -1
- package/dist/index.js.map +1 -1
- package/dist/logging/index.d.ts +7 -0
- package/dist/logging/index.d.ts.map +1 -0
- package/dist/logging/index.js +7 -0
- package/dist/logging/index.js.map +1 -0
- package/dist/logging/query-logger.d.ts +144 -0
- package/dist/logging/query-logger.d.ts.map +1 -0
- package/dist/logging/query-logger.js +282 -0
- package/dist/logging/query-logger.js.map +1 -0
- package/dist/quota/quota-manager.d.ts +66 -2
- package/dist/quota/quota-manager.d.ts.map +1 -1
- package/dist/quota/quota-manager.js +220 -2
- package/dist/quota/quota-manager.js.map +1 -1
- package/dist/session/shared-context-manager.d.ts +4 -0
- package/dist/session/shared-context-manager.d.ts.map +1 -1
- package/dist/session/shared-context-manager.js +43 -11
- package/dist/session/shared-context-manager.js.map +1 -1
- package/dist/tools/definitions/query-history.d.ts +9 -0
- package/dist/tools/definitions/query-history.d.ts.map +1 -0
- package/dist/tools/definitions/query-history.js +44 -0
- package/dist/tools/definitions/query-history.js.map +1 -0
- package/dist/tools/definitions/system.d.ts.map +1 -1
- package/dist/tools/definitions/system.js +12 -4
- package/dist/tools/definitions/system.js.map +1 -1
- package/dist/tools/definitions.d.ts.map +1 -1
- package/dist/tools/definitions.js +2 -0
- package/dist/tools/definitions.js.map +1 -1
- package/dist/tools/handlers.d.ts +47 -1
- package/dist/tools/handlers.d.ts.map +1 -1
- package/dist/tools/handlers.js +152 -10
- package/dist/tools/handlers.js.map +1 -1
- package/dist/types.d.ts +13 -0
- package/dist/types.d.ts.map +1 -1
- package/dist/utils/file-lock.d.ts +79 -0
- package/dist/utils/file-lock.d.ts.map +1 -0
- package/dist/utils/file-lock.js +222 -0
- package/dist/utils/file-lock.js.map +1 -0
- package/package.json +1 -1
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Cross-Platform File Locking for NotebookLM MCP Server
|
|
3
|
+
*
|
|
4
|
+
* Provides advisory file locking to prevent race conditions when
|
|
5
|
+
* multiple concurrent sessions access shared state files.
|
|
6
|
+
*
|
|
7
|
+
* Features:
|
|
8
|
+
* - Cross-platform (Linux, macOS, Windows)
|
|
9
|
+
* - Stale lock detection and cleanup
|
|
10
|
+
* - Timeout with retry
|
|
11
|
+
* - Process ID tracking
|
|
12
|
+
*
|
|
13
|
+
* Used for:
|
|
14
|
+
* - Quota file updates (prevent concurrent increment race)
|
|
15
|
+
* - Auth state save/load (prevent corruption)
|
|
16
|
+
* - Browser context creation (prevent parallel recreations)
|
|
17
|
+
*/
|
|
18
|
+
/**
|
|
19
|
+
* Lock options
|
|
20
|
+
*/
|
|
21
|
+
export interface LockOptions {
|
|
22
|
+
/** Max time to wait for lock (ms) */
|
|
23
|
+
timeout?: number;
|
|
24
|
+
/** Time between retry attempts (ms) */
|
|
25
|
+
retryInterval?: number;
|
|
26
|
+
/** Lock considered stale after this time (ms) */
|
|
27
|
+
staleThreshold?: number;
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* File Lock Class
|
|
31
|
+
*
|
|
32
|
+
* Simple cross-platform file locking using lock files.
|
|
33
|
+
* Works on Linux, macOS, and Windows.
|
|
34
|
+
*/
|
|
35
|
+
export declare class FileLock {
|
|
36
|
+
private lockPath;
|
|
37
|
+
private acquired;
|
|
38
|
+
private lockId;
|
|
39
|
+
constructor(filePath: string);
|
|
40
|
+
/**
|
|
41
|
+
* Acquire lock with retry and timeout
|
|
42
|
+
*/
|
|
43
|
+
acquire(options?: LockOptions): Promise<boolean>;
|
|
44
|
+
/**
|
|
45
|
+
* Release lock
|
|
46
|
+
*/
|
|
47
|
+
release(): void;
|
|
48
|
+
/**
|
|
49
|
+
* Check if lock is acquired
|
|
50
|
+
*/
|
|
51
|
+
isAcquired(): boolean;
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Execute operation with file lock
|
|
55
|
+
*
|
|
56
|
+
* Acquires lock, executes operation, releases lock.
|
|
57
|
+
* Ensures lock is always released even if operation throws.
|
|
58
|
+
*
|
|
59
|
+
* @param filePath - Path to the file to lock (lock file will be filePath + ".lock")
|
|
60
|
+
* @param operation - Async operation to execute while holding lock
|
|
61
|
+
* @param options - Lock options
|
|
62
|
+
* @returns Result of the operation
|
|
63
|
+
* @throws Error if lock cannot be acquired within timeout
|
|
64
|
+
*/
|
|
65
|
+
export declare function withLock<T>(filePath: string, operation: () => Promise<T>, options?: LockOptions): Promise<T>;
|
|
66
|
+
/**
|
|
67
|
+
* Check if a file is currently locked
|
|
68
|
+
*
|
|
69
|
+
* Note: This is a point-in-time check and may be stale immediately after.
|
|
70
|
+
* Only use for informational purposes.
|
|
71
|
+
*/
|
|
72
|
+
export declare function isLocked(filePath: string, staleThreshold?: number): boolean;
|
|
73
|
+
/**
|
|
74
|
+
* Force remove a lock file (use with caution)
|
|
75
|
+
*
|
|
76
|
+
* Only use when you're certain the lock is orphaned.
|
|
77
|
+
*/
|
|
78
|
+
export declare function forceUnlock(filePath: string): boolean;
|
|
79
|
+
//# sourceMappingURL=file-lock.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"file-lock.d.ts","sourceRoot":"","sources":["../../src/utils/file-lock.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAMH;;GAEG;AACH,MAAM,WAAW,WAAW;IAC1B,qCAAqC;IACrC,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,uCAAuC;IACvC,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,iDAAiD;IACjD,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AA4BD;;;;;GAKG;AACH,qBAAa,QAAQ;IACnB,OAAO,CAAC,QAAQ,CAAS;IACzB,OAAO,CAAC,QAAQ,CAAkB;IAClC,OAAO,CAAC,MAAM,CAAS;gBAEX,QAAQ,EAAE,MAAM;IAK5B;;OAEG;IACG,OAAO,CAAC,OAAO,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,OAAO,CAAC;IAwEtD;;OAEG;IACH,OAAO,IAAI,IAAI;IA0Bf;;OAEG;IACH,UAAU,IAAI,OAAO;CAGtB;AAED;;;;;;;;;;;GAWG;AACH,wBAAsB,QAAQ,CAAC,CAAC,EAC9B,QAAQ,EAAE,MAAM,EAChB,SAAS,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,EAC3B,OAAO,CAAC,EAAE,WAAW,GACpB,OAAO,CAAC,CAAC,CAAC,CAYZ;AAED;;;;;GAKG;AACH,wBAAgB,QAAQ,CAAC,QAAQ,EAAE,MAAM,EAAE,cAAc,CAAC,EAAE,MAAM,GAAG,OAAO,CAkB3E;AAED;;;;GAIG;AACH,wBAAgB,WAAW,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAcrD"}
|
|
@@ -0,0 +1,222 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Cross-Platform File Locking for NotebookLM MCP Server
|
|
3
|
+
*
|
|
4
|
+
* Provides advisory file locking to prevent race conditions when
|
|
5
|
+
* multiple concurrent sessions access shared state files.
|
|
6
|
+
*
|
|
7
|
+
* Features:
|
|
8
|
+
* - Cross-platform (Linux, macOS, Windows)
|
|
9
|
+
* - Stale lock detection and cleanup
|
|
10
|
+
* - Timeout with retry
|
|
11
|
+
* - Process ID tracking
|
|
12
|
+
*
|
|
13
|
+
* Used for:
|
|
14
|
+
* - Quota file updates (prevent concurrent increment race)
|
|
15
|
+
* - Auth state save/load (prevent corruption)
|
|
16
|
+
* - Browser context creation (prevent parallel recreations)
|
|
17
|
+
*/
|
|
18
|
+
import fs from "fs";
|
|
19
|
+
import path from "path";
|
|
20
|
+
import { log } from "./logger.js";
|
|
21
|
+
/**
|
|
22
|
+
* Default lock options
|
|
23
|
+
*/
|
|
24
|
+
const DEFAULT_OPTIONS = {
|
|
25
|
+
timeout: parseInt(process.env.NLMCP_LOCK_TIMEOUT_MS || "10000", 10),
|
|
26
|
+
retryInterval: 100,
|
|
27
|
+
staleThreshold: parseInt(process.env.NLMCP_LOCK_STALE_MS || "30000", 10),
|
|
28
|
+
};
|
|
29
|
+
/**
|
|
30
|
+
* Generate unique lock ID
|
|
31
|
+
*/
|
|
32
|
+
function generateLockId() {
|
|
33
|
+
return `${process.pid}-${Date.now()}-${Math.random().toString(36).slice(2, 10)}`;
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* File Lock Class
|
|
37
|
+
*
|
|
38
|
+
* Simple cross-platform file locking using lock files.
|
|
39
|
+
* Works on Linux, macOS, and Windows.
|
|
40
|
+
*/
|
|
41
|
+
export class FileLock {
|
|
42
|
+
lockPath;
|
|
43
|
+
acquired = false;
|
|
44
|
+
lockId;
|
|
45
|
+
constructor(filePath) {
|
|
46
|
+
this.lockPath = filePath + ".lock";
|
|
47
|
+
this.lockId = generateLockId();
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Acquire lock with retry and timeout
|
|
51
|
+
*/
|
|
52
|
+
async acquire(options) {
|
|
53
|
+
const opts = { ...DEFAULT_OPTIONS, ...options };
|
|
54
|
+
const startTime = Date.now();
|
|
55
|
+
while (Date.now() - startTime < opts.timeout) {
|
|
56
|
+
try {
|
|
57
|
+
// Check if stale lock exists
|
|
58
|
+
if (fs.existsSync(this.lockPath)) {
|
|
59
|
+
try {
|
|
60
|
+
const content = fs.readFileSync(this.lockPath, "utf-8");
|
|
61
|
+
const existing = JSON.parse(content);
|
|
62
|
+
const age = Date.now() - existing.timestamp;
|
|
63
|
+
if (age > opts.staleThreshold) {
|
|
64
|
+
// Lock is stale, remove it
|
|
65
|
+
log.warning(`🔓 Removing stale lock (age: ${Math.round(age / 1000)}s, pid: ${existing.pid})`);
|
|
66
|
+
try {
|
|
67
|
+
fs.unlinkSync(this.lockPath);
|
|
68
|
+
}
|
|
69
|
+
catch {
|
|
70
|
+
// Ignore if another process already removed it
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
catch {
|
|
75
|
+
// Corrupted lock file, try to remove it
|
|
76
|
+
try {
|
|
77
|
+
fs.unlinkSync(this.lockPath);
|
|
78
|
+
}
|
|
79
|
+
catch {
|
|
80
|
+
// Ignore
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
// Try to create lock file exclusively
|
|
85
|
+
const lockContent = {
|
|
86
|
+
pid: process.pid,
|
|
87
|
+
lockId: this.lockId,
|
|
88
|
+
timestamp: Date.now(),
|
|
89
|
+
hostname: process.env.HOSTNAME || process.env.COMPUTERNAME,
|
|
90
|
+
};
|
|
91
|
+
// Ensure directory exists
|
|
92
|
+
const lockDir = path.dirname(this.lockPath);
|
|
93
|
+
if (!fs.existsSync(lockDir)) {
|
|
94
|
+
fs.mkdirSync(lockDir, { recursive: true, mode: 0o700 });
|
|
95
|
+
}
|
|
96
|
+
// Try exclusive create (will fail if file exists)
|
|
97
|
+
fs.writeFileSync(this.lockPath, JSON.stringify(lockContent), {
|
|
98
|
+
flag: "wx", // Exclusive create - fails if file exists
|
|
99
|
+
mode: 0o600,
|
|
100
|
+
});
|
|
101
|
+
this.acquired = true;
|
|
102
|
+
return true;
|
|
103
|
+
}
|
|
104
|
+
catch (error) {
|
|
105
|
+
const err = error;
|
|
106
|
+
if (err.code !== "EEXIST") {
|
|
107
|
+
// Unexpected error
|
|
108
|
+
log.error(`❌ Lock acquisition error: ${err.message}`);
|
|
109
|
+
throw error;
|
|
110
|
+
}
|
|
111
|
+
// Lock exists, wait and retry
|
|
112
|
+
await new Promise((resolve) => setTimeout(resolve, opts.retryInterval));
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
// Timeout reached
|
|
116
|
+
log.warning(`⚠️ Lock acquisition timeout for ${this.lockPath}`);
|
|
117
|
+
return false;
|
|
118
|
+
}
|
|
119
|
+
/**
|
|
120
|
+
* Release lock
|
|
121
|
+
*/
|
|
122
|
+
release() {
|
|
123
|
+
if (!this.acquired)
|
|
124
|
+
return;
|
|
125
|
+
try {
|
|
126
|
+
// Verify we own the lock before releasing
|
|
127
|
+
if (fs.existsSync(this.lockPath)) {
|
|
128
|
+
try {
|
|
129
|
+
const content = fs.readFileSync(this.lockPath, "utf-8");
|
|
130
|
+
const existing = JSON.parse(content);
|
|
131
|
+
if (existing.lockId === this.lockId) {
|
|
132
|
+
fs.unlinkSync(this.lockPath);
|
|
133
|
+
}
|
|
134
|
+
else {
|
|
135
|
+
log.warning(`⚠️ Lock owned by different process, not releasing`);
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
catch {
|
|
139
|
+
// Ignore errors during release
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
catch {
|
|
144
|
+
// Ignore errors during release
|
|
145
|
+
}
|
|
146
|
+
this.acquired = false;
|
|
147
|
+
}
|
|
148
|
+
/**
|
|
149
|
+
* Check if lock is acquired
|
|
150
|
+
*/
|
|
151
|
+
isAcquired() {
|
|
152
|
+
return this.acquired;
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
/**
|
|
156
|
+
* Execute operation with file lock
|
|
157
|
+
*
|
|
158
|
+
* Acquires lock, executes operation, releases lock.
|
|
159
|
+
* Ensures lock is always released even if operation throws.
|
|
160
|
+
*
|
|
161
|
+
* @param filePath - Path to the file to lock (lock file will be filePath + ".lock")
|
|
162
|
+
* @param operation - Async operation to execute while holding lock
|
|
163
|
+
* @param options - Lock options
|
|
164
|
+
* @returns Result of the operation
|
|
165
|
+
* @throws Error if lock cannot be acquired within timeout
|
|
166
|
+
*/
|
|
167
|
+
export async function withLock(filePath, operation, options) {
|
|
168
|
+
const lock = new FileLock(filePath);
|
|
169
|
+
if (!(await lock.acquire(options))) {
|
|
170
|
+
throw new Error(`Could not acquire lock for ${filePath} within timeout`);
|
|
171
|
+
}
|
|
172
|
+
try {
|
|
173
|
+
return await operation();
|
|
174
|
+
}
|
|
175
|
+
finally {
|
|
176
|
+
lock.release();
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
/**
|
|
180
|
+
* Check if a file is currently locked
|
|
181
|
+
*
|
|
182
|
+
* Note: This is a point-in-time check and may be stale immediately after.
|
|
183
|
+
* Only use for informational purposes.
|
|
184
|
+
*/
|
|
185
|
+
export function isLocked(filePath, staleThreshold) {
|
|
186
|
+
const lockPath = filePath + ".lock";
|
|
187
|
+
const threshold = staleThreshold ?? DEFAULT_OPTIONS.staleThreshold;
|
|
188
|
+
if (!fs.existsSync(lockPath)) {
|
|
189
|
+
return false;
|
|
190
|
+
}
|
|
191
|
+
try {
|
|
192
|
+
const content = fs.readFileSync(lockPath, "utf-8");
|
|
193
|
+
const existing = JSON.parse(content);
|
|
194
|
+
const age = Date.now() - existing.timestamp;
|
|
195
|
+
// Consider stale locks as not locked
|
|
196
|
+
return age <= threshold;
|
|
197
|
+
}
|
|
198
|
+
catch {
|
|
199
|
+
return false;
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
/**
|
|
203
|
+
* Force remove a lock file (use with caution)
|
|
204
|
+
*
|
|
205
|
+
* Only use when you're certain the lock is orphaned.
|
|
206
|
+
*/
|
|
207
|
+
export function forceUnlock(filePath) {
|
|
208
|
+
const lockPath = filePath + ".lock";
|
|
209
|
+
try {
|
|
210
|
+
if (fs.existsSync(lockPath)) {
|
|
211
|
+
fs.unlinkSync(lockPath);
|
|
212
|
+
log.info(`🔓 Force removed lock: ${lockPath}`);
|
|
213
|
+
return true;
|
|
214
|
+
}
|
|
215
|
+
return false;
|
|
216
|
+
}
|
|
217
|
+
catch (error) {
|
|
218
|
+
log.error(`❌ Failed to force remove lock: ${error}`);
|
|
219
|
+
return false;
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
//# sourceMappingURL=file-lock.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"file-lock.js","sourceRoot":"","sources":["../../src/utils/file-lock.ts"],"names":[],"mappings":"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"}
|