@pan-sec/notebooklm-mcp 1.6.0 → 1.8.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 (134) hide show
  1. package/dist/config.d.ts +4 -0
  2. package/dist/config.d.ts.map +1 -1
  3. package/dist/config.js +10 -0
  4. package/dist/config.js.map +1 -1
  5. package/dist/events/event-emitter.d.ts +45 -0
  6. package/dist/events/event-emitter.d.ts.map +1 -0
  7. package/dist/events/event-emitter.js +100 -0
  8. package/dist/events/event-emitter.js.map +1 -0
  9. package/dist/events/event-types.d.ts +124 -0
  10. package/dist/events/event-types.d.ts.map +1 -0
  11. package/dist/events/event-types.js +18 -0
  12. package/dist/events/event-types.js.map +1 -0
  13. package/dist/gemini/gemini-client.d.ts +45 -0
  14. package/dist/gemini/gemini-client.d.ts.map +1 -0
  15. package/dist/gemini/gemini-client.js +211 -0
  16. package/dist/gemini/gemini-client.js.map +1 -0
  17. package/dist/gemini/index.d.ts +8 -0
  18. package/dist/gemini/index.d.ts.map +1 -0
  19. package/dist/gemini/index.js +8 -0
  20. package/dist/gemini/index.js.map +1 -0
  21. package/dist/gemini/types.d.ts +136 -0
  22. package/dist/gemini/types.d.ts.map +1 -0
  23. package/dist/gemini/types.js +10 -0
  24. package/dist/gemini/types.js.map +1 -0
  25. package/dist/index.js +76 -3
  26. package/dist/index.js.map +1 -1
  27. package/dist/library/notebook-library.d.ts +25 -2
  28. package/dist/library/notebook-library.d.ts.map +1 -1
  29. package/dist/library/notebook-library.js +142 -2
  30. package/dist/library/notebook-library.js.map +1 -1
  31. package/dist/library/types.d.ts +15 -0
  32. package/dist/library/types.d.ts.map +1 -1
  33. package/dist/notebook-creation/audio-manager.d.ts +56 -0
  34. package/dist/notebook-creation/audio-manager.d.ts.map +1 -0
  35. package/dist/notebook-creation/audio-manager.js +335 -0
  36. package/dist/notebook-creation/audio-manager.js.map +1 -0
  37. package/dist/notebook-creation/discover-creation-flow.d.ts +8 -0
  38. package/dist/notebook-creation/discover-creation-flow.d.ts.map +1 -0
  39. package/dist/notebook-creation/discover-creation-flow.js +177 -0
  40. package/dist/notebook-creation/discover-creation-flow.js.map +1 -0
  41. package/dist/notebook-creation/discover-quota.d.ts +8 -0
  42. package/dist/notebook-creation/discover-quota.d.ts.map +1 -0
  43. package/dist/notebook-creation/discover-quota.js +195 -0
  44. package/dist/notebook-creation/discover-quota.js.map +1 -0
  45. package/dist/notebook-creation/discover-source-dialog.d.ts +8 -0
  46. package/dist/notebook-creation/discover-source-dialog.d.ts.map +1 -0
  47. package/dist/notebook-creation/discover-source-dialog.js +134 -0
  48. package/dist/notebook-creation/discover-source-dialog.js.map +1 -0
  49. package/dist/notebook-creation/discover-sources.d.ts +8 -0
  50. package/dist/notebook-creation/discover-sources.d.ts.map +1 -0
  51. package/dist/notebook-creation/discover-sources.js +273 -0
  52. package/dist/notebook-creation/discover-sources.js.map +1 -0
  53. package/dist/notebook-creation/discover-text-input.d.ts +7 -0
  54. package/dist/notebook-creation/discover-text-input.d.ts.map +1 -0
  55. package/dist/notebook-creation/discover-text-input.js +135 -0
  56. package/dist/notebook-creation/discover-text-input.js.map +1 -0
  57. package/dist/notebook-creation/index.d.ts +12 -0
  58. package/dist/notebook-creation/index.d.ts.map +1 -0
  59. package/dist/notebook-creation/index.js +12 -0
  60. package/dist/notebook-creation/index.js.map +1 -0
  61. package/dist/notebook-creation/notebook-creator.d.ts +95 -0
  62. package/dist/notebook-creation/notebook-creator.d.ts.map +1 -0
  63. package/dist/notebook-creation/notebook-creator.js +689 -0
  64. package/dist/notebook-creation/notebook-creator.js.map +1 -0
  65. package/dist/notebook-creation/notebook-sync.d.ts +93 -0
  66. package/dist/notebook-creation/notebook-sync.d.ts.map +1 -0
  67. package/dist/notebook-creation/notebook-sync.js +370 -0
  68. package/dist/notebook-creation/notebook-sync.js.map +1 -0
  69. package/dist/notebook-creation/run-discovery.d.ts +11 -0
  70. package/dist/notebook-creation/run-discovery.d.ts.map +1 -0
  71. package/dist/notebook-creation/run-discovery.js +151 -0
  72. package/dist/notebook-creation/run-discovery.js.map +1 -0
  73. package/dist/notebook-creation/selector-discovery.d.ts +65 -0
  74. package/dist/notebook-creation/selector-discovery.d.ts.map +1 -0
  75. package/dist/notebook-creation/selector-discovery.js +421 -0
  76. package/dist/notebook-creation/selector-discovery.js.map +1 -0
  77. package/dist/notebook-creation/selectors.d.ts +150 -0
  78. package/dist/notebook-creation/selectors.d.ts.map +1 -0
  79. package/dist/notebook-creation/selectors.js +225 -0
  80. package/dist/notebook-creation/selectors.js.map +1 -0
  81. package/dist/notebook-creation/source-manager.d.ts +73 -0
  82. package/dist/notebook-creation/source-manager.d.ts.map +1 -0
  83. package/dist/notebook-creation/source-manager.js +486 -0
  84. package/dist/notebook-creation/source-manager.js.map +1 -0
  85. package/dist/notebook-creation/test-create.d.ts +8 -0
  86. package/dist/notebook-creation/test-create.d.ts.map +1 -0
  87. package/dist/notebook-creation/test-create.js +72 -0
  88. package/dist/notebook-creation/test-create.js.map +1 -0
  89. package/dist/notebook-creation/types.d.ts +173 -0
  90. package/dist/notebook-creation/types.d.ts.map +1 -0
  91. package/dist/notebook-creation/types.js +5 -0
  92. package/dist/notebook-creation/types.js.map +1 -0
  93. package/dist/quota/index.d.ts +8 -0
  94. package/dist/quota/index.d.ts.map +1 -0
  95. package/dist/quota/index.js +8 -0
  96. package/dist/quota/index.js.map +1 -0
  97. package/dist/quota/quota-manager.d.ts +125 -0
  98. package/dist/quota/quota-manager.d.ts.map +1 -0
  99. package/dist/quota/quota-manager.js +330 -0
  100. package/dist/quota/quota-manager.js.map +1 -0
  101. package/dist/session/session-manager.d.ts +5 -0
  102. package/dist/session/session-manager.d.ts.map +1 -1
  103. package/dist/session/session-manager.js +6 -0
  104. package/dist/session/session-manager.js.map +1 -1
  105. package/dist/tools/definitions/gemini.d.ts +12 -0
  106. package/dist/tools/definitions/gemini.d.ts.map +1 -0
  107. package/dist/tools/definitions/gemini.js +135 -0
  108. package/dist/tools/definitions/gemini.js.map +1 -0
  109. package/dist/tools/definitions/notebook-management.d.ts.map +1 -1
  110. package/dist/tools/definitions/notebook-management.js +525 -0
  111. package/dist/tools/definitions/notebook-management.js.map +1 -1
  112. package/dist/tools/definitions/system.d.ts.map +1 -1
  113. package/dist/tools/definitions/system.js +158 -0
  114. package/dist/tools/definitions/system.js.map +1 -1
  115. package/dist/tools/definitions.d.ts.map +1 -1
  116. package/dist/tools/definitions.js +2 -0
  117. package/dist/tools/definitions.js.map +1 -1
  118. package/dist/tools/handlers.d.ts +257 -0
  119. package/dist/tools/handlers.d.ts.map +1 -1
  120. package/dist/tools/handlers.js +1097 -0
  121. package/dist/tools/handlers.js.map +1 -1
  122. package/dist/webhooks/index.d.ts +8 -0
  123. package/dist/webhooks/index.d.ts.map +1 -0
  124. package/dist/webhooks/index.js +8 -0
  125. package/dist/webhooks/index.js.map +1 -0
  126. package/dist/webhooks/types.d.ts +57 -0
  127. package/dist/webhooks/types.d.ts.map +1 -0
  128. package/dist/webhooks/types.js +5 -0
  129. package/dist/webhooks/types.js.map +1 -0
  130. package/dist/webhooks/webhook-dispatcher.d.ts +120 -0
  131. package/dist/webhooks/webhook-dispatcher.d.ts.map +1 -0
  132. package/dist/webhooks/webhook-dispatcher.js +519 -0
  133. package/dist/webhooks/webhook-dispatcher.js.map +1 -0
  134. package/package.json +2 -1
@@ -0,0 +1,173 @@
1
+ /**
2
+ * Types for notebook creation functionality
3
+ */
4
+ import type { ProgressCallback } from "../types.js";
5
+ /**
6
+ * Source types supported for notebook creation
7
+ */
8
+ export type SourceType = "url" | "text" | "file";
9
+ /**
10
+ * A source to add to a notebook
11
+ */
12
+ export interface NotebookSource {
13
+ /** Type of source */
14
+ type: SourceType;
15
+ /** URL, text content, or file path depending on type */
16
+ value: string;
17
+ /** Optional title for text sources */
18
+ title?: string;
19
+ }
20
+ /**
21
+ * Options for creating a notebook
22
+ */
23
+ export interface CreateNotebookOptions {
24
+ /** Display name for the notebook */
25
+ name: string;
26
+ /** Sources to add to the notebook */
27
+ sources: NotebookSource[];
28
+ /** Progress callback for status updates */
29
+ sendProgress?: ProgressCallback;
30
+ /** Browser options override */
31
+ browserOptions?: {
32
+ headless?: boolean;
33
+ show?: boolean;
34
+ timeout_ms?: number;
35
+ };
36
+ }
37
+ /**
38
+ * Result of notebook creation
39
+ */
40
+ export interface CreatedNotebook {
41
+ /** URL of the created notebook */
42
+ url: string;
43
+ /** Name of the notebook */
44
+ name: string;
45
+ /** Number of sources successfully added */
46
+ sourceCount: number;
47
+ /** ISO timestamp of creation */
48
+ createdAt: string;
49
+ /** Any sources that failed to add */
50
+ failedSources?: FailedSource[];
51
+ }
52
+ /**
53
+ * Information about a failed source
54
+ */
55
+ export interface FailedSource {
56
+ /** The source that failed */
57
+ source: NotebookSource;
58
+ /** Error message */
59
+ error: string;
60
+ }
61
+ /**
62
+ * Input for create_notebook tool
63
+ */
64
+ export interface CreateNotebookInput {
65
+ /** Display name for the notebook */
66
+ name: string;
67
+ /** Sources to add */
68
+ sources: NotebookSource[];
69
+ /** Optional description for library */
70
+ description?: string;
71
+ /** Optional topics for library */
72
+ topics?: string[];
73
+ /** Whether to auto-add to library (default: true) */
74
+ auto_add_to_library?: boolean;
75
+ /** Browser options */
76
+ browser_options?: {
77
+ headless?: boolean;
78
+ show?: boolean;
79
+ timeout_ms?: number;
80
+ };
81
+ /** Show browser window (simple version) */
82
+ show_browser?: boolean;
83
+ }
84
+ /**
85
+ * Discovered UI element information
86
+ */
87
+ export interface ElementInfo {
88
+ /** HTML tag name */
89
+ tag: string;
90
+ /** Element ID if present */
91
+ id: string;
92
+ /** CSS classes */
93
+ classes: string;
94
+ /** aria-label attribute */
95
+ ariaLabel: string | null;
96
+ /** Text content (truncated) */
97
+ text: string | null;
98
+ /** data-* attributes */
99
+ dataAttrs: Record<string, string>;
100
+ /** Element's role attribute */
101
+ role: string | null;
102
+ /** Whether element is visible */
103
+ isVisible: boolean;
104
+ /** Bounding box if visible */
105
+ boundingBox?: {
106
+ x: number;
107
+ y: number;
108
+ width: number;
109
+ height: number;
110
+ };
111
+ }
112
+ /**
113
+ * Discovered selectors for NotebookLM UI
114
+ */
115
+ export interface DiscoveredSelectors {
116
+ /** Selector for "New notebook" button on homepage */
117
+ newNotebookButton: SelectorInfo;
118
+ /** Selector for notebook name input */
119
+ notebookNameInput: SelectorInfo;
120
+ /** Selector for "Add source" button */
121
+ addSourceButton: SelectorInfo;
122
+ /** Selector for URL source option */
123
+ urlSourceOption: SelectorInfo;
124
+ /** Selector for text source option */
125
+ textSourceOption: SelectorInfo;
126
+ /** Selector for file source option */
127
+ fileSourceOption: SelectorInfo;
128
+ /** Selector for URL input field */
129
+ urlInput: SelectorInfo;
130
+ /** Selector for text input area */
131
+ textInput: SelectorInfo;
132
+ /** Selector for file input element */
133
+ fileInput: SelectorInfo;
134
+ /** Selector for submit/add button */
135
+ submitButton: SelectorInfo;
136
+ /** Selector for processing indicator */
137
+ processingIndicator: SelectorInfo;
138
+ /** Selector for success indicator */
139
+ successIndicator: SelectorInfo;
140
+ /** Selector for error message */
141
+ errorMessage: SelectorInfo;
142
+ }
143
+ /**
144
+ * Information about a discovered selector
145
+ */
146
+ export interface SelectorInfo {
147
+ /** Primary CSS selector */
148
+ primary: string;
149
+ /** Fallback selectors in priority order */
150
+ fallbacks: string[];
151
+ /** Description of what this selector targets */
152
+ description: string;
153
+ /** Whether this selector was confirmed working */
154
+ confirmed: boolean;
155
+ }
156
+ /**
157
+ * Result of selector discovery
158
+ */
159
+ export interface DiscoveryResult {
160
+ /** Discovered selectors */
161
+ selectors: Partial<DiscoveredSelectors>;
162
+ /** Elements found on homepage */
163
+ homepageElements: ElementInfo[];
164
+ /** Elements found on creation page/modal */
165
+ creationElements: ElementInfo[];
166
+ /** Elements found on source addition UI */
167
+ sourceElements: ElementInfo[];
168
+ /** Discovery timestamp */
169
+ discoveredAt: string;
170
+ /** Any errors encountered */
171
+ errors: string[];
172
+ }
173
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/notebook-creation/types.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Types for notebook creation functionality
3
+ */
4
+ export {};
5
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/notebook-creation/types.ts"],"names":[],"mappings":"AAAA;;GAEG"}
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Quota Management Module
3
+ *
4
+ * Exports quota management functionality for license tier detection,
5
+ * usage tracking, and limit enforcement.
6
+ */
7
+ export { QuotaManager, getQuotaManager, type LicenseTier, type QuotaLimits, type QuotaUsage, type QuotaSettings, } from "./quota-manager.js";
8
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/quota/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EACL,YAAY,EACZ,eAAe,EACf,KAAK,WAAW,EAChB,KAAK,WAAW,EAChB,KAAK,UAAU,EACf,KAAK,aAAa,GACnB,MAAM,oBAAoB,CAAC"}
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Quota Management Module
3
+ *
4
+ * Exports quota management functionality for license tier detection,
5
+ * usage tracking, and limit enforcement.
6
+ */
7
+ export { QuotaManager, getQuotaManager, } from "./quota-manager.js";
8
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/quota/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EACL,YAAY,EACZ,eAAe,GAKhB,MAAM,oBAAoB,CAAC"}
@@ -0,0 +1,125 @@
1
+ /**
2
+ * NotebookLM Quota Manager
3
+ *
4
+ * Manages license tier detection, usage tracking, and limit enforcement.
5
+ */
6
+ import type { Page } from "patchright";
7
+ export type LicenseTier = "free" | "pro" | "ultra" | "unknown";
8
+ export interface QuotaLimits {
9
+ notebooks: number;
10
+ sourcesPerNotebook: number;
11
+ wordsPerSource: number;
12
+ queriesPerDay: number;
13
+ }
14
+ export interface QuotaUsage {
15
+ notebooks: number;
16
+ queriesUsedToday: number;
17
+ lastQueryDate: string;
18
+ lastUpdated: string;
19
+ }
20
+ export interface QuotaSettings {
21
+ tier: LicenseTier;
22
+ limits: QuotaLimits;
23
+ usage: QuotaUsage;
24
+ autoDetected: boolean;
25
+ }
26
+ export declare class QuotaManager {
27
+ private settings;
28
+ private settingsPath;
29
+ constructor();
30
+ /**
31
+ * Load settings from disk or create defaults
32
+ */
33
+ private loadSettings;
34
+ /**
35
+ * Get default settings
36
+ */
37
+ private getDefaultSettings;
38
+ /**
39
+ * Save settings to disk
40
+ */
41
+ private saveSettings;
42
+ /**
43
+ * Detect license tier from NotebookLM UI
44
+ * Tiers: free, pro, ultra (Google AI Ultra $249.99/month)
45
+ */
46
+ detectTierFromPage(page: Page): Promise<LicenseTier>;
47
+ /**
48
+ * Extract source limit from source dialog (e.g., "0/300")
49
+ */
50
+ extractSourceLimitFromDialog(page: Page): Promise<number | null>;
51
+ /**
52
+ * Count notebooks from homepage
53
+ */
54
+ countNotebooksFromPage(page: Page): Promise<number>;
55
+ /**
56
+ * Update quota from UI scraping
57
+ */
58
+ updateFromUI(page: Page): Promise<void>;
59
+ /**
60
+ * Manually set tier (for user override)
61
+ */
62
+ setTier(tier: LicenseTier): void;
63
+ /**
64
+ * Get current settings
65
+ */
66
+ getSettings(): QuotaSettings;
67
+ /**
68
+ * Get current limits
69
+ */
70
+ getLimits(): QuotaLimits;
71
+ /**
72
+ * Get current usage
73
+ */
74
+ getUsage(): QuotaUsage;
75
+ /**
76
+ * Increment notebook count
77
+ */
78
+ incrementNotebookCount(): void;
79
+ /**
80
+ * Increment query count
81
+ */
82
+ incrementQueryCount(): void;
83
+ /**
84
+ * Check if can create notebook
85
+ */
86
+ canCreateNotebook(): {
87
+ allowed: boolean;
88
+ reason?: string;
89
+ };
90
+ /**
91
+ * Check if can add source to notebook
92
+ */
93
+ canAddSource(currentSourceCount: number): {
94
+ allowed: boolean;
95
+ reason?: string;
96
+ };
97
+ /**
98
+ * Check if can make query
99
+ */
100
+ canMakeQuery(): {
101
+ allowed: boolean;
102
+ reason?: string;
103
+ };
104
+ /**
105
+ * Get quota status summary
106
+ */
107
+ getStatus(): {
108
+ tier: LicenseTier;
109
+ notebooks: {
110
+ used: number;
111
+ limit: number;
112
+ percent: number;
113
+ };
114
+ sources: {
115
+ limit: number;
116
+ };
117
+ queries: {
118
+ used: number;
119
+ limit: number;
120
+ percent: number;
121
+ };
122
+ };
123
+ }
124
+ export declare function getQuotaManager(): QuotaManager;
125
+ //# sourceMappingURL=quota-manager.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"quota-manager.d.ts","sourceRoot":"","sources":["../../src/quota/quota-manager.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,YAAY,CAAC;AAMvC,MAAM,MAAM,WAAW,GAAG,MAAM,GAAG,KAAK,GAAG,OAAO,GAAG,SAAS,CAAC;AAE/D,MAAM,WAAW,WAAW;IAC1B,SAAS,EAAE,MAAM,CAAC;IAClB,kBAAkB,EAAE,MAAM,CAAC;IAC3B,cAAc,EAAE,MAAM,CAAC;IACvB,aAAa,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,WAAW,UAAU;IACzB,SAAS,EAAE,MAAM,CAAC;IAClB,gBAAgB,EAAE,MAAM,CAAC;IACzB,aAAa,EAAE,MAAM,CAAC;IACtB,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,WAAW,CAAC;IAClB,MAAM,EAAE,WAAW,CAAC;IACpB,KAAK,EAAE,UAAU,CAAC;IAClB,YAAY,EAAE,OAAO,CAAC;CACvB;AAgCD,qBAAa,YAAY;IACvB,OAAO,CAAC,QAAQ,CAAgB;IAChC,OAAO,CAAC,YAAY,CAAS;;IAO7B;;OAEG;IACH,OAAO,CAAC,YAAY;IAgBpB;;OAEG;IACH,OAAO,CAAC,kBAAkB;IAc1B;;OAEG;IACH,OAAO,CAAC,YAAY;IAiBpB;;;OAGG;IACG,kBAAkB,CAAC,IAAI,EAAE,IAAI,GAAG,OAAO,CAAC,WAAW,CAAC;IA0C1D;;OAEG;IACG,4BAA4B,CAAC,IAAI,EAAE,IAAI,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC;IAetE;;OAEG;IACG,sBAAsB,CAAC,IAAI,EAAE,IAAI,GAAG,OAAO,CAAC,MAAM,CAAC;IAiBzD;;OAEG;IACG,YAAY,CAAC,IAAI,EAAE,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC;IA6B7C;;OAEG;IACH,OAAO,CAAC,IAAI,EAAE,WAAW,GAAG,IAAI;IAQhC;;OAEG;IACH,WAAW,IAAI,aAAa;IAI5B;;OAEG;IACH,SAAS,IAAI,WAAW;IAIxB;;OAEG;IACH,QAAQ,IAAI,UAAU;IAItB;;OAEG;IACH,sBAAsB,IAAI,IAAI;IAM9B;;OAEG;IACH,mBAAmB,IAAI,IAAI;IAc3B;;OAEG;IACH,iBAAiB,IAAI;QAAE,OAAO,EAAE,OAAO,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,CAAA;KAAE;IAmB1D;;OAEG;IACH,YAAY,CAAC,kBAAkB,EAAE,MAAM,GAAG;QAAE,OAAO,EAAE,OAAO,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,CAAA;KAAE;IAa/E;;OAEG;IACH,YAAY,IAAI;QAAE,OAAO,EAAE,OAAO,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,CAAA;KAAE;IA2BrD;;OAEG;IACH,SAAS,IAAI;QACX,IAAI,EAAE,WAAW,CAAC;QAClB,SAAS,EAAE;YAAE,IAAI,EAAE,MAAM,CAAC;YAAC,KAAK,EAAE,MAAM,CAAC;YAAC,OAAO,EAAE,MAAM,CAAA;SAAE,CAAC;QAC5D,OAAO,EAAE;YAAE,KAAK,EAAE,MAAM,CAAA;SAAE,CAAC;QAC3B,OAAO,EAAE;YAAE,IAAI,EAAE,MAAM,CAAC;YAAC,KAAK,EAAE,MAAM,CAAC;YAAC,OAAO,EAAE,MAAM,CAAA;SAAE,CAAC;KAC3D;CAoBF;AAKD,wBAAgB,eAAe,IAAI,YAAY,CAK9C"}
@@ -0,0 +1,330 @@
1
+ /**
2
+ * NotebookLM Quota Manager
3
+ *
4
+ * Manages license tier detection, usage tracking, and limit enforcement.
5
+ */
6
+ import { log } from "../utils/logger.js";
7
+ import { CONFIG } from "../config.js";
8
+ import fs from "fs";
9
+ import path from "path";
10
+ // Known limits by tier (based on NotebookLM documentation Dec 2025)
11
+ // https://support.google.com/notebooklm/answer/16213268
12
+ const TIER_LIMITS = {
13
+ free: {
14
+ notebooks: 100,
15
+ sourcesPerNotebook: 50,
16
+ wordsPerSource: 500000,
17
+ queriesPerDay: 50,
18
+ },
19
+ pro: {
20
+ notebooks: 500,
21
+ sourcesPerNotebook: 300,
22
+ wordsPerSource: 500000,
23
+ queriesPerDay: 500,
24
+ },
25
+ ultra: {
26
+ notebooks: 500,
27
+ sourcesPerNotebook: 600,
28
+ wordsPerSource: 500000,
29
+ queriesPerDay: 5000,
30
+ },
31
+ unknown: {
32
+ // Conservative defaults (use free tier limits)
33
+ notebooks: 100,
34
+ sourcesPerNotebook: 50,
35
+ wordsPerSource: 500000,
36
+ queriesPerDay: 50,
37
+ },
38
+ };
39
+ export class QuotaManager {
40
+ settings;
41
+ settingsPath;
42
+ constructor() {
43
+ this.settingsPath = path.join(CONFIG.configDir, "quota.json");
44
+ this.settings = this.loadSettings();
45
+ }
46
+ /**
47
+ * Load settings from disk or create defaults
48
+ */
49
+ loadSettings() {
50
+ try {
51
+ if (fs.existsSync(this.settingsPath)) {
52
+ const data = fs.readFileSync(this.settingsPath, "utf-8");
53
+ const loaded = JSON.parse(data);
54
+ log.info(`📊 Loaded quota settings (tier: ${loaded.tier})`);
55
+ return loaded;
56
+ }
57
+ }
58
+ catch (error) {
59
+ log.warning(`⚠️ Could not load quota settings: ${error}`);
60
+ }
61
+ // Return defaults
62
+ return this.getDefaultSettings();
63
+ }
64
+ /**
65
+ * Get default settings
66
+ */
67
+ getDefaultSettings() {
68
+ return {
69
+ tier: "unknown",
70
+ limits: TIER_LIMITS.unknown,
71
+ usage: {
72
+ notebooks: 0,
73
+ queriesUsedToday: 0,
74
+ lastQueryDate: new Date().toISOString().split("T")[0],
75
+ lastUpdated: new Date().toISOString(),
76
+ },
77
+ autoDetected: false,
78
+ };
79
+ }
80
+ /**
81
+ * Save settings to disk
82
+ */
83
+ saveSettings() {
84
+ try {
85
+ const dir = path.dirname(this.settingsPath);
86
+ if (!fs.existsSync(dir)) {
87
+ fs.mkdirSync(dir, { recursive: true, mode: 0o700 });
88
+ }
89
+ fs.writeFileSync(this.settingsPath, JSON.stringify(this.settings, null, 2), { mode: 0o600 });
90
+ log.info(`💾 Saved quota settings`);
91
+ }
92
+ catch (error) {
93
+ log.error(`❌ Could not save quota settings: ${error}`);
94
+ }
95
+ }
96
+ /**
97
+ * Detect license tier from NotebookLM UI
98
+ * Tiers: free, pro, ultra (Google AI Ultra $249.99/month)
99
+ */
100
+ async detectTierFromPage(page) {
101
+ log.info("🔍 Detecting license tier...");
102
+ const tierInfo = await page.evaluate(() => {
103
+ // @ts-expect-error - DOM types
104
+ const allText = document.body.innerText.toUpperCase();
105
+ // Check for ULTRA first (highest tier)
106
+ // @ts-expect-error - DOM types
107
+ const ultraBadge = document.querySelector(".ultra-badge, [class*='ultra']");
108
+ if (ultraBadge || allText.includes("ULTRA")) {
109
+ return "ultra";
110
+ }
111
+ // Look for PRO badge
112
+ // @ts-expect-error - DOM types
113
+ const proBadge = document.querySelector(".pro-badge");
114
+ if (proBadge) {
115
+ return "pro";
116
+ }
117
+ // Look for PRO text in specific elements
118
+ // @ts-expect-error - DOM types
119
+ const proLabels = document.querySelectorAll(".pro-label, [class*='pro']");
120
+ for (const el of proLabels) {
121
+ if (el.textContent?.toUpperCase().includes("PRO")) {
122
+ return "pro";
123
+ }
124
+ }
125
+ // Check for upgrade prompts (indicates free tier)
126
+ if (allText.includes("UPGRADE") && !allText.includes("PRO") && !allText.includes("ULTRA")) {
127
+ return "free";
128
+ }
129
+ return "unknown";
130
+ });
131
+ log.info(` Detected tier: ${tierInfo}`);
132
+ return tierInfo;
133
+ }
134
+ /**
135
+ * Extract source limit from source dialog (e.g., "0/300")
136
+ */
137
+ async extractSourceLimitFromDialog(page) {
138
+ const limitInfo = await page.evaluate(() => {
139
+ // Look for X/Y pattern
140
+ // @ts-expect-error - DOM types
141
+ const allText = document.body.innerText;
142
+ const match = allText.match(/(\d+)\s*\/\s*(\d+)/);
143
+ if (match) {
144
+ return parseInt(match[2], 10); // Return the limit (Y in X/Y)
145
+ }
146
+ return null;
147
+ });
148
+ return limitInfo;
149
+ }
150
+ /**
151
+ * Count notebooks from homepage
152
+ */
153
+ async countNotebooksFromPage(page) {
154
+ const count = await page.evaluate(() => {
155
+ // Count table rows that have "Source" in them (notebook rows)
156
+ // @ts-expect-error - DOM types
157
+ const rows = document.querySelectorAll("tr");
158
+ let count = 0;
159
+ for (const row of rows) {
160
+ if (row.textContent?.includes("Source")) {
161
+ count++;
162
+ }
163
+ }
164
+ return count;
165
+ });
166
+ return count;
167
+ }
168
+ /**
169
+ * Update quota from UI scraping
170
+ */
171
+ async updateFromUI(page) {
172
+ log.info("📊 Updating quota from UI...");
173
+ // Detect tier
174
+ const tier = await this.detectTierFromPage(page);
175
+ if (tier !== "unknown") {
176
+ this.settings.tier = tier;
177
+ this.settings.limits = TIER_LIMITS[tier];
178
+ this.settings.autoDetected = true;
179
+ }
180
+ // Count notebooks
181
+ const notebookCount = await this.countNotebooksFromPage(page);
182
+ if (notebookCount > 0) {
183
+ this.settings.usage.notebooks = notebookCount;
184
+ }
185
+ // Try to get source limit from dialog if visible
186
+ const sourceLimit = await this.extractSourceLimitFromDialog(page);
187
+ if (sourceLimit) {
188
+ this.settings.limits.sourcesPerNotebook = sourceLimit;
189
+ }
190
+ this.settings.usage.lastUpdated = new Date().toISOString();
191
+ this.saveSettings();
192
+ log.success(`✅ Quota updated: tier=${this.settings.tier}, notebooks=${this.settings.usage.notebooks}`);
193
+ }
194
+ /**
195
+ * Manually set tier (for user override)
196
+ */
197
+ setTier(tier) {
198
+ this.settings.tier = tier;
199
+ this.settings.limits = TIER_LIMITS[tier];
200
+ this.settings.autoDetected = false;
201
+ this.saveSettings();
202
+ log.info(`📊 Tier set to: ${tier}`);
203
+ }
204
+ /**
205
+ * Get current settings
206
+ */
207
+ getSettings() {
208
+ return { ...this.settings };
209
+ }
210
+ /**
211
+ * Get current limits
212
+ */
213
+ getLimits() {
214
+ return { ...this.settings.limits };
215
+ }
216
+ /**
217
+ * Get current usage
218
+ */
219
+ getUsage() {
220
+ return { ...this.settings.usage };
221
+ }
222
+ /**
223
+ * Increment notebook count
224
+ */
225
+ incrementNotebookCount() {
226
+ this.settings.usage.notebooks++;
227
+ this.settings.usage.lastUpdated = new Date().toISOString();
228
+ this.saveSettings();
229
+ }
230
+ /**
231
+ * Increment query count
232
+ */
233
+ incrementQueryCount() {
234
+ const today = new Date().toISOString().split("T")[0];
235
+ // Reset if new day
236
+ if (this.settings.usage.lastQueryDate !== today) {
237
+ this.settings.usage.queriesUsedToday = 0;
238
+ this.settings.usage.lastQueryDate = today;
239
+ }
240
+ this.settings.usage.queriesUsedToday++;
241
+ this.settings.usage.lastUpdated = new Date().toISOString();
242
+ this.saveSettings();
243
+ }
244
+ /**
245
+ * Check if can create notebook
246
+ */
247
+ canCreateNotebook() {
248
+ const { notebooks } = this.settings.usage;
249
+ const { notebooks: limit } = this.settings.limits;
250
+ if (notebooks >= limit) {
251
+ return {
252
+ allowed: false,
253
+ reason: `Notebook limit reached (${notebooks}/${limit}). Delete notebooks or upgrade your plan.`,
254
+ };
255
+ }
256
+ // Warn if approaching limit
257
+ if (notebooks >= limit * 0.9) {
258
+ log.warning(`⚠️ Approaching notebook limit: ${notebooks}/${limit}`);
259
+ }
260
+ return { allowed: true };
261
+ }
262
+ /**
263
+ * Check if can add source to notebook
264
+ */
265
+ canAddSource(currentSourceCount) {
266
+ const { sourcesPerNotebook: limit } = this.settings.limits;
267
+ if (currentSourceCount >= limit) {
268
+ return {
269
+ allowed: false,
270
+ reason: `Source limit reached for this notebook (${currentSourceCount}/${limit}).`,
271
+ };
272
+ }
273
+ return { allowed: true };
274
+ }
275
+ /**
276
+ * Check if can make query
277
+ */
278
+ canMakeQuery() {
279
+ const today = new Date().toISOString().split("T")[0];
280
+ // Reset if new day
281
+ if (this.settings.usage.lastQueryDate !== today) {
282
+ this.settings.usage.queriesUsedToday = 0;
283
+ this.settings.usage.lastQueryDate = today;
284
+ }
285
+ const { queriesUsedToday } = this.settings.usage;
286
+ const { queriesPerDay: limit } = this.settings.limits;
287
+ if (queriesUsedToday >= limit) {
288
+ return {
289
+ allowed: false,
290
+ reason: `Daily query limit reached (${queriesUsedToday}/${limit}). Try again tomorrow or upgrade your plan.`,
291
+ };
292
+ }
293
+ // Warn if approaching limit
294
+ if (queriesUsedToday >= limit * 0.8) {
295
+ log.warning(`⚠️ Approaching daily query limit: ${queriesUsedToday}/${limit}`);
296
+ }
297
+ return { allowed: true };
298
+ }
299
+ /**
300
+ * Get quota status summary
301
+ */
302
+ getStatus() {
303
+ const { tier, limits, usage } = this.settings;
304
+ return {
305
+ tier,
306
+ notebooks: {
307
+ used: usage.notebooks,
308
+ limit: limits.notebooks,
309
+ percent: Math.round((usage.notebooks / limits.notebooks) * 100),
310
+ },
311
+ sources: {
312
+ limit: limits.sourcesPerNotebook,
313
+ },
314
+ queries: {
315
+ used: usage.queriesUsedToday,
316
+ limit: limits.queriesPerDay,
317
+ percent: Math.round((usage.queriesUsedToday / limits.queriesPerDay) * 100),
318
+ },
319
+ };
320
+ }
321
+ }
322
+ // Singleton instance
323
+ let quotaManagerInstance = null;
324
+ export function getQuotaManager() {
325
+ if (!quotaManagerInstance) {
326
+ quotaManagerInstance = new QuotaManager();
327
+ }
328
+ return quotaManagerInstance;
329
+ }
330
+ //# sourceMappingURL=quota-manager.js.map