@pan-sec/notebooklm-mcp 2026.3.2 → 2026.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 (466) hide show
  1. package/dist/auth/auth-manager.d.ts +0 -1
  2. package/dist/auth/auth-manager.js +0 -1
  3. package/dist/auth/mcp-auth.d.ts +0 -1
  4. package/dist/auth/mcp-auth.js +0 -1
  5. package/dist/compliance/alert-manager.d.ts +6 -2
  6. package/dist/compliance/alert-manager.js +40 -10
  7. package/dist/compliance/breach-detection.d.ts +0 -1
  8. package/dist/compliance/breach-detection.js +0 -1
  9. package/dist/compliance/change-log.d.ts +13 -1
  10. package/dist/compliance/change-log.js +82 -16
  11. package/dist/compliance/compliance-logger.d.ts +29 -3
  12. package/dist/compliance/compliance-logger.js +90 -27
  13. package/dist/compliance/compliance-tools.d.ts +0 -1
  14. package/dist/compliance/compliance-tools.js +0 -1
  15. package/dist/compliance/consent-manager.d.ts +0 -1
  16. package/dist/compliance/consent-manager.js +0 -1
  17. package/dist/compliance/dashboard.d.ts +4 -3
  18. package/dist/compliance/dashboard.js +11 -8
  19. package/dist/compliance/data-classification.d.ts +0 -1
  20. package/dist/compliance/data-classification.js +0 -1
  21. package/dist/compliance/data-erasure.d.ts +0 -1
  22. package/dist/compliance/data-erasure.js +0 -1
  23. package/dist/compliance/data-export.d.ts +0 -1
  24. package/dist/compliance/data-export.js +0 -1
  25. package/dist/compliance/data-inventory.d.ts +0 -1
  26. package/dist/compliance/data-inventory.js +0 -1
  27. package/dist/compliance/dsar-handler.d.ts +0 -1
  28. package/dist/compliance/dsar-handler.js +0 -1
  29. package/dist/compliance/evidence-collector.d.ts +0 -1
  30. package/dist/compliance/evidence-collector.js +4 -2
  31. package/dist/compliance/health-monitor.d.ts +0 -1
  32. package/dist/compliance/health-monitor.js +0 -1
  33. package/dist/compliance/incident-manager.d.ts +0 -1
  34. package/dist/compliance/incident-manager.js +0 -1
  35. package/dist/compliance/index.d.ts +0 -1
  36. package/dist/compliance/index.js +0 -1
  37. package/dist/compliance/policy-docs.d.ts +0 -1
  38. package/dist/compliance/policy-docs.js +0 -1
  39. package/dist/compliance/privacy-notice-text.d.ts +0 -1
  40. package/dist/compliance/privacy-notice-text.js +0 -1
  41. package/dist/compliance/privacy-notice.d.ts +0 -1
  42. package/dist/compliance/privacy-notice.js +0 -1
  43. package/dist/compliance/report-generator.d.ts +7 -1
  44. package/dist/compliance/report-generator.js +116 -34
  45. package/dist/compliance/retention-engine.d.ts +0 -1
  46. package/dist/compliance/retention-engine.js +0 -1
  47. package/dist/compliance/siem-exporter.d.ts +26 -2
  48. package/dist/compliance/siem-exporter.js +89 -24
  49. package/dist/compliance/types.d.ts +0 -1
  50. package/dist/compliance/types.js +0 -1
  51. package/dist/config.d.ts +0 -1
  52. package/dist/config.js +2 -3
  53. package/dist/errors.d.ts +0 -1
  54. package/dist/errors.js +0 -1
  55. package/dist/events/event-emitter.d.ts +9 -1
  56. package/dist/events/event-emitter.js +47 -8
  57. package/dist/events/event-types.d.ts +0 -1
  58. package/dist/events/event-types.js +8 -2
  59. package/dist/gemini/gemini-client.d.ts +0 -1
  60. package/dist/gemini/gemini-client.js +237 -45
  61. package/dist/gemini/index.d.ts +0 -1
  62. package/dist/gemini/index.js +0 -1
  63. package/dist/gemini/pdf-chunker.d.ts +0 -1
  64. package/dist/gemini/pdf-chunker.js +60 -35
  65. package/dist/gemini/types.d.ts +0 -1
  66. package/dist/gemini/types.js +0 -1
  67. package/dist/index.d.ts +0 -1
  68. package/dist/index.js +74 -10
  69. package/dist/library/notebook-library.d.ts +30 -2
  70. package/dist/library/notebook-library.js +345 -85
  71. package/dist/library/types.d.ts +0 -1
  72. package/dist/library/types.js +0 -1
  73. package/dist/logging/index.d.ts +0 -1
  74. package/dist/logging/index.js +0 -1
  75. package/dist/logging/query-logger.d.ts +20 -1
  76. package/dist/logging/query-logger.js +104 -21
  77. package/dist/notebook-creation/audio-manager.d.ts +0 -1
  78. package/dist/notebook-creation/audio-manager.js +111 -20
  79. package/dist/notebook-creation/browser-options.d.ts +0 -1
  80. package/dist/notebook-creation/browser-options.js +0 -1
  81. package/dist/notebook-creation/data-table-manager.d.ts +7 -1
  82. package/dist/notebook-creation/data-table-manager.js +59 -3
  83. package/dist/notebook-creation/dom-scripts.d.ts +0 -1
  84. package/dist/notebook-creation/dom-scripts.js +0 -1
  85. package/dist/notebook-creation/errors.d.ts +0 -1
  86. package/dist/notebook-creation/errors.js +0 -1
  87. package/dist/notebook-creation/index.d.ts +0 -1
  88. package/dist/notebook-creation/index.js +0 -1
  89. package/dist/notebook-creation/notebook-creator.d.ts +9 -1
  90. package/dist/notebook-creation/notebook-creator.js +50 -1
  91. package/dist/notebook-creation/notebook-nav.d.ts +0 -1
  92. package/dist/notebook-creation/notebook-nav.js +21 -6
  93. package/dist/notebook-creation/notebook-sync.d.ts +14 -2
  94. package/dist/notebook-creation/notebook-sync.js +124 -35
  95. package/dist/notebook-creation/selectors.d.ts +0 -1
  96. package/dist/notebook-creation/selectors.js +6 -4
  97. package/dist/notebook-creation/source-manager.d.ts +29 -2
  98. package/dist/notebook-creation/source-manager.js +0 -0
  99. package/dist/notebook-creation/types.d.ts +0 -1
  100. package/dist/notebook-creation/types.js +0 -1
  101. package/dist/notebook-creation/video-manager.d.ts +0 -1
  102. package/dist/notebook-creation/video-manager.js +91 -15
  103. package/dist/observability/metrics.d.ts +0 -1
  104. package/dist/observability/metrics.js +0 -1
  105. package/dist/quota/index.d.ts +0 -1
  106. package/dist/quota/index.js +0 -1
  107. package/dist/quota/quota-manager.d.ts +59 -4
  108. package/dist/quota/quota-manager.js +195 -46
  109. package/dist/resources/resource-handlers.d.ts +0 -1
  110. package/dist/resources/resource-handlers.js +33 -3
  111. package/dist/session/browser-session.d.ts +0 -1
  112. package/dist/session/browser-session.js +0 -1
  113. package/dist/session/session-manager.d.ts +0 -1
  114. package/dist/session/session-manager.js +0 -1
  115. package/dist/session/session-timeout.d.ts +0 -1
  116. package/dist/session/session-timeout.js +0 -1
  117. package/dist/session/shared-context-manager.d.ts +0 -1
  118. package/dist/session/shared-context-manager.js +0 -1
  119. package/dist/tools/annotations.d.ts +0 -1
  120. package/dist/tools/annotations.js +0 -1
  121. package/dist/tools/definitions/ask-question.d.ts +6 -3
  122. package/dist/tools/definitions/ask-question.js +12 -8
  123. package/dist/tools/definitions/chat-history.d.ts +0 -1
  124. package/dist/tools/definitions/chat-history.js +1 -1
  125. package/dist/tools/definitions/data-tables.d.ts +0 -1
  126. package/dist/tools/definitions/data-tables.js +4 -1
  127. package/dist/tools/definitions/gemini.d.ts +0 -1
  128. package/dist/tools/definitions/gemini.js +14 -7
  129. package/dist/tools/definitions/notebook-management.d.ts +0 -1
  130. package/dist/tools/definitions/notebook-management.js +7 -2
  131. package/dist/tools/definitions/query-history.d.ts +0 -1
  132. package/dist/tools/definitions/query-history.js +0 -1
  133. package/dist/tools/definitions/session-management.d.ts +0 -1
  134. package/dist/tools/definitions/session-management.js +0 -1
  135. package/dist/tools/definitions/system.d.ts +0 -1
  136. package/dist/tools/definitions/system.js +32 -12
  137. package/dist/tools/definitions/video.d.ts +0 -1
  138. package/dist/tools/definitions/video.js +6 -3
  139. package/dist/tools/definitions.d.ts +0 -1
  140. package/dist/tools/definitions.js +0 -1
  141. package/dist/tools/handlers/ask-question.d.ts +0 -1
  142. package/dist/tools/handlers/ask-question.js +47 -18
  143. package/dist/tools/handlers/audio-video.d.ts +0 -1
  144. package/dist/tools/handlers/audio-video.js +0 -1
  145. package/dist/tools/handlers/auth.d.ts +0 -1
  146. package/dist/tools/handlers/auth.js +0 -1
  147. package/dist/tools/handlers/error-utils.d.ts +0 -1
  148. package/dist/tools/handlers/error-utils.js +0 -1
  149. package/dist/tools/handlers/gemini.d.ts +0 -1
  150. package/dist/tools/handlers/gemini.js +0 -1
  151. package/dist/tools/handlers/index.d.ts +0 -1
  152. package/dist/tools/handlers/index.js +0 -1
  153. package/dist/tools/handlers/notebook-creation.d.ts +0 -1
  154. package/dist/tools/handlers/notebook-creation.js +16 -1
  155. package/dist/tools/handlers/notebook-management.d.ts +0 -1
  156. package/dist/tools/handlers/notebook-management.js +7 -2
  157. package/dist/tools/handlers/session-management.d.ts +0 -1
  158. package/dist/tools/handlers/session-management.js +0 -1
  159. package/dist/tools/handlers/system.d.ts +0 -1
  160. package/dist/tools/handlers/system.js +0 -1
  161. package/dist/tools/handlers/types.d.ts +0 -1
  162. package/dist/tools/handlers/types.js +0 -1
  163. package/dist/tools/handlers/webhooks.d.ts +0 -1
  164. package/dist/tools/handlers/webhooks.js +0 -1
  165. package/dist/tools/icons.d.ts +0 -1
  166. package/dist/tools/icons.js +0 -1
  167. package/dist/tools/index.d.ts +0 -1
  168. package/dist/tools/index.js +0 -1
  169. package/dist/types.d.ts +0 -1
  170. package/dist/types.js +0 -1
  171. package/dist/utils/audit-logger.d.ts +11 -1
  172. package/dist/utils/audit-logger.js +189 -21
  173. package/dist/utils/cleanup-manager.d.ts +0 -1
  174. package/dist/utils/cleanup-manager.js +0 -1
  175. package/dist/utils/cli-handler.d.ts +0 -1
  176. package/dist/utils/cli-handler.js +0 -1
  177. package/dist/utils/crypto.d.ts +18 -9
  178. package/dist/utils/crypto.js +93 -28
  179. package/dist/utils/file-lock.d.ts +15 -1
  180. package/dist/utils/file-lock.js +67 -59
  181. package/dist/utils/file-permissions.d.ts +0 -1
  182. package/dist/utils/file-permissions.js +35 -7
  183. package/dist/utils/logger.d.ts +0 -1
  184. package/dist/utils/logger.js +0 -1
  185. package/dist/utils/page-utils.d.ts +0 -1
  186. package/dist/utils/page-utils.js +32 -28
  187. package/dist/utils/response-validator.d.ts +0 -1
  188. package/dist/utils/response-validator.js +18 -15
  189. package/dist/utils/secrets-scanner.d.ts +0 -1
  190. package/dist/utils/secrets-scanner.js +32 -7
  191. package/dist/utils/secure-memory.d.ts +34 -16
  192. package/dist/utils/secure-memory.js +40 -25
  193. package/dist/utils/security.d.ts +0 -1
  194. package/dist/utils/security.js +66 -39
  195. package/dist/utils/settings-manager.d.ts +9 -1
  196. package/dist/utils/settings-manager.js +45 -2
  197. package/dist/utils/stealth-utils.d.ts +0 -1
  198. package/dist/utils/stealth-utils.js +11 -9
  199. package/dist/webhooks/index.d.ts +0 -1
  200. package/dist/webhooks/index.js +0 -1
  201. package/dist/webhooks/types.d.ts +0 -1
  202. package/dist/webhooks/types.js +0 -1
  203. package/dist/webhooks/webhook-dispatcher.d.ts +0 -1
  204. package/dist/webhooks/webhook-dispatcher.js +0 -1
  205. package/package.json +5 -4
  206. package/dist/auth/auth-manager.d.ts.map +0 -1
  207. package/dist/auth/auth-manager.js.map +0 -1
  208. package/dist/auth/mcp-auth.d.ts.map +0 -1
  209. package/dist/auth/mcp-auth.js.map +0 -1
  210. package/dist/compliance/alert-manager.d.ts.map +0 -1
  211. package/dist/compliance/alert-manager.js.map +0 -1
  212. package/dist/compliance/breach-detection.d.ts.map +0 -1
  213. package/dist/compliance/breach-detection.js.map +0 -1
  214. package/dist/compliance/change-log.d.ts.map +0 -1
  215. package/dist/compliance/change-log.js.map +0 -1
  216. package/dist/compliance/compliance-logger.d.ts.map +0 -1
  217. package/dist/compliance/compliance-logger.js.map +0 -1
  218. package/dist/compliance/compliance-tools.d.ts.map +0 -1
  219. package/dist/compliance/compliance-tools.js.map +0 -1
  220. package/dist/compliance/consent-manager.d.ts.map +0 -1
  221. package/dist/compliance/consent-manager.js.map +0 -1
  222. package/dist/compliance/dashboard.d.ts.map +0 -1
  223. package/dist/compliance/dashboard.js.map +0 -1
  224. package/dist/compliance/data-classification.d.ts.map +0 -1
  225. package/dist/compliance/data-classification.js.map +0 -1
  226. package/dist/compliance/data-erasure.d.ts.map +0 -1
  227. package/dist/compliance/data-erasure.js.map +0 -1
  228. package/dist/compliance/data-export.d.ts.map +0 -1
  229. package/dist/compliance/data-export.js.map +0 -1
  230. package/dist/compliance/data-inventory.d.ts.map +0 -1
  231. package/dist/compliance/data-inventory.js.map +0 -1
  232. package/dist/compliance/dsar-handler.d.ts.map +0 -1
  233. package/dist/compliance/dsar-handler.js.map +0 -1
  234. package/dist/compliance/evidence-collector.d.ts.map +0 -1
  235. package/dist/compliance/evidence-collector.js.map +0 -1
  236. package/dist/compliance/health-monitor.d.ts.map +0 -1
  237. package/dist/compliance/health-monitor.js.map +0 -1
  238. package/dist/compliance/incident-manager.d.ts.map +0 -1
  239. package/dist/compliance/incident-manager.js.map +0 -1
  240. package/dist/compliance/index.d.ts.map +0 -1
  241. package/dist/compliance/index.js.map +0 -1
  242. package/dist/compliance/policy-docs.d.ts.map +0 -1
  243. package/dist/compliance/policy-docs.js.map +0 -1
  244. package/dist/compliance/privacy-notice-text.d.ts.map +0 -1
  245. package/dist/compliance/privacy-notice-text.js.map +0 -1
  246. package/dist/compliance/privacy-notice.d.ts.map +0 -1
  247. package/dist/compliance/privacy-notice.js.map +0 -1
  248. package/dist/compliance/report-generator.d.ts.map +0 -1
  249. package/dist/compliance/report-generator.js.map +0 -1
  250. package/dist/compliance/retention-engine.d.ts.map +0 -1
  251. package/dist/compliance/retention-engine.js.map +0 -1
  252. package/dist/compliance/siem-exporter.d.ts.map +0 -1
  253. package/dist/compliance/siem-exporter.js.map +0 -1
  254. package/dist/compliance/types.d.ts.map +0 -1
  255. package/dist/compliance/types.js.map +0 -1
  256. package/dist/config.d.ts.map +0 -1
  257. package/dist/config.js.map +0 -1
  258. package/dist/errors.d.ts.map +0 -1
  259. package/dist/errors.js.map +0 -1
  260. package/dist/events/event-emitter.d.ts.map +0 -1
  261. package/dist/events/event-emitter.js.map +0 -1
  262. package/dist/events/event-types.d.ts.map +0 -1
  263. package/dist/events/event-types.js.map +0 -1
  264. package/dist/gemini/gemini-client.d.ts.map +0 -1
  265. package/dist/gemini/gemini-client.js.map +0 -1
  266. package/dist/gemini/index.d.ts.map +0 -1
  267. package/dist/gemini/index.js.map +0 -1
  268. package/dist/gemini/pdf-chunker.d.ts.map +0 -1
  269. package/dist/gemini/pdf-chunker.js.map +0 -1
  270. package/dist/gemini/types.d.ts.map +0 -1
  271. package/dist/gemini/types.js.map +0 -1
  272. package/dist/index.d.ts.map +0 -1
  273. package/dist/index.js.map +0 -1
  274. package/dist/library/notebook-library.d.ts.map +0 -1
  275. package/dist/library/notebook-library.js.map +0 -1
  276. package/dist/library/types.d.ts.map +0 -1
  277. package/dist/library/types.js.map +0 -1
  278. package/dist/logging/index.d.ts.map +0 -1
  279. package/dist/logging/index.js.map +0 -1
  280. package/dist/logging/query-logger.d.ts.map +0 -1
  281. package/dist/logging/query-logger.js.map +0 -1
  282. package/dist/notebook-creation/audio-manager.d.ts.map +0 -1
  283. package/dist/notebook-creation/audio-manager.js.map +0 -1
  284. package/dist/notebook-creation/browser-options.d.ts.map +0 -1
  285. package/dist/notebook-creation/browser-options.js.map +0 -1
  286. package/dist/notebook-creation/data-table-manager.d.ts.map +0 -1
  287. package/dist/notebook-creation/data-table-manager.js.map +0 -1
  288. package/dist/notebook-creation/discover-creation-flow.d.ts +0 -2
  289. package/dist/notebook-creation/discover-creation-flow.d.ts.map +0 -1
  290. package/dist/notebook-creation/discover-creation-flow.js +0 -177
  291. package/dist/notebook-creation/discover-creation-flow.js.map +0 -1
  292. package/dist/notebook-creation/discover-quota.d.ts +0 -2
  293. package/dist/notebook-creation/discover-quota.d.ts.map +0 -1
  294. package/dist/notebook-creation/discover-quota.js +0 -194
  295. package/dist/notebook-creation/discover-quota.js.map +0 -1
  296. package/dist/notebook-creation/discover-source-dialog.d.ts +0 -8
  297. package/dist/notebook-creation/discover-source-dialog.d.ts.map +0 -1
  298. package/dist/notebook-creation/discover-source-dialog.js +0 -134
  299. package/dist/notebook-creation/discover-source-dialog.js.map +0 -1
  300. package/dist/notebook-creation/discover-sources.d.ts +0 -8
  301. package/dist/notebook-creation/discover-sources.d.ts.map +0 -1
  302. package/dist/notebook-creation/discover-sources.js +0 -272
  303. package/dist/notebook-creation/discover-sources.js.map +0 -1
  304. package/dist/notebook-creation/discover-text-input.d.ts +0 -7
  305. package/dist/notebook-creation/discover-text-input.d.ts.map +0 -1
  306. package/dist/notebook-creation/discover-text-input.js +0 -135
  307. package/dist/notebook-creation/discover-text-input.js.map +0 -1
  308. package/dist/notebook-creation/dom-scripts.d.ts.map +0 -1
  309. package/dist/notebook-creation/dom-scripts.js.map +0 -1
  310. package/dist/notebook-creation/errors.d.ts.map +0 -1
  311. package/dist/notebook-creation/errors.js.map +0 -1
  312. package/dist/notebook-creation/index.d.ts.map +0 -1
  313. package/dist/notebook-creation/index.js.map +0 -1
  314. package/dist/notebook-creation/notebook-creator.d.ts.map +0 -1
  315. package/dist/notebook-creation/notebook-creator.js.map +0 -1
  316. package/dist/notebook-creation/notebook-nav.d.ts.map +0 -1
  317. package/dist/notebook-creation/notebook-nav.js.map +0 -1
  318. package/dist/notebook-creation/notebook-sync.d.ts.map +0 -1
  319. package/dist/notebook-creation/notebook-sync.js.map +0 -1
  320. package/dist/notebook-creation/run-discovery.d.ts +0 -11
  321. package/dist/notebook-creation/run-discovery.d.ts.map +0 -1
  322. package/dist/notebook-creation/run-discovery.js +0 -151
  323. package/dist/notebook-creation/run-discovery.js.map +0 -1
  324. package/dist/notebook-creation/selector-discovery.d.ts +0 -65
  325. package/dist/notebook-creation/selector-discovery.d.ts.map +0 -1
  326. package/dist/notebook-creation/selector-discovery.js +0 -414
  327. package/dist/notebook-creation/selector-discovery.js.map +0 -1
  328. package/dist/notebook-creation/selectors.d.ts.map +0 -1
  329. package/dist/notebook-creation/selectors.js.map +0 -1
  330. package/dist/notebook-creation/selectors.ts +0 -112
  331. package/dist/notebook-creation/source-manager.d.ts.map +0 -1
  332. package/dist/notebook-creation/source-manager.js.map +0 -1
  333. package/dist/notebook-creation/test-create.d.ts +0 -8
  334. package/dist/notebook-creation/test-create.d.ts.map +0 -1
  335. package/dist/notebook-creation/test-create.js +0 -72
  336. package/dist/notebook-creation/test-create.js.map +0 -1
  337. package/dist/notebook-creation/types.d.ts.map +0 -1
  338. package/dist/notebook-creation/types.js.map +0 -1
  339. package/dist/notebook-creation/video-manager.d.ts.map +0 -1
  340. package/dist/notebook-creation/video-manager.js.map +0 -1
  341. package/dist/observability/metrics.d.ts.map +0 -1
  342. package/dist/observability/metrics.js.map +0 -1
  343. package/dist/quota/index.d.ts.map +0 -1
  344. package/dist/quota/index.js.map +0 -1
  345. package/dist/quota/quota-manager.d.ts.map +0 -1
  346. package/dist/quota/quota-manager.js.map +0 -1
  347. package/dist/resources/resource-handlers.d.ts.map +0 -1
  348. package/dist/resources/resource-handlers.js.map +0 -1
  349. package/dist/session/browser-session.d.ts.map +0 -1
  350. package/dist/session/browser-session.js.map +0 -1
  351. package/dist/session/session-manager.d.ts.map +0 -1
  352. package/dist/session/session-manager.js.map +0 -1
  353. package/dist/session/session-timeout.d.ts.map +0 -1
  354. package/dist/session/session-timeout.js.map +0 -1
  355. package/dist/session/shared-context-manager.d.ts.map +0 -1
  356. package/dist/session/shared-context-manager.js.map +0 -1
  357. package/dist/tools/annotations.d.ts.map +0 -1
  358. package/dist/tools/annotations.js.map +0 -1
  359. package/dist/tools/definitions/ask-question.d.ts.map +0 -1
  360. package/dist/tools/definitions/ask-question.js.map +0 -1
  361. package/dist/tools/definitions/chat-history.d.ts.map +0 -1
  362. package/dist/tools/definitions/chat-history.js.map +0 -1
  363. package/dist/tools/definitions/data-tables.d.ts.map +0 -1
  364. package/dist/tools/definitions/data-tables.js.map +0 -1
  365. package/dist/tools/definitions/gemini.d.ts.map +0 -1
  366. package/dist/tools/definitions/gemini.js.map +0 -1
  367. package/dist/tools/definitions/notebook-management.d.ts.map +0 -1
  368. package/dist/tools/definitions/notebook-management.js.map +0 -1
  369. package/dist/tools/definitions/query-history.d.ts.map +0 -1
  370. package/dist/tools/definitions/query-history.js.map +0 -1
  371. package/dist/tools/definitions/session-management.d.ts.map +0 -1
  372. package/dist/tools/definitions/session-management.js.map +0 -1
  373. package/dist/tools/definitions/system.d.ts.map +0 -1
  374. package/dist/tools/definitions/system.js.map +0 -1
  375. package/dist/tools/definitions/video.d.ts.map +0 -1
  376. package/dist/tools/definitions/video.js.map +0 -1
  377. package/dist/tools/definitions.d.ts.map +0 -1
  378. package/dist/tools/definitions.js.map +0 -1
  379. package/dist/tools/handlers/ask-question.d.ts.map +0 -1
  380. package/dist/tools/handlers/ask-question.js.map +0 -1
  381. package/dist/tools/handlers/audio-video.d.ts.map +0 -1
  382. package/dist/tools/handlers/audio-video.js.map +0 -1
  383. package/dist/tools/handlers/auth.d.ts.map +0 -1
  384. package/dist/tools/handlers/auth.js.map +0 -1
  385. package/dist/tools/handlers/error-utils.d.ts.map +0 -1
  386. package/dist/tools/handlers/error-utils.js.map +0 -1
  387. package/dist/tools/handlers/gemini.d.ts.map +0 -1
  388. package/dist/tools/handlers/gemini.js.map +0 -1
  389. package/dist/tools/handlers/index.d.ts.map +0 -1
  390. package/dist/tools/handlers/index.js.map +0 -1
  391. package/dist/tools/handlers/notebook-creation.d.ts.map +0 -1
  392. package/dist/tools/handlers/notebook-creation.js.map +0 -1
  393. package/dist/tools/handlers/notebook-management.d.ts.map +0 -1
  394. package/dist/tools/handlers/notebook-management.js.map +0 -1
  395. package/dist/tools/handlers/session-management.d.ts.map +0 -1
  396. package/dist/tools/handlers/session-management.js.map +0 -1
  397. package/dist/tools/handlers/system.d.ts.map +0 -1
  398. package/dist/tools/handlers/system.js.map +0 -1
  399. package/dist/tools/handlers/types.d.ts.map +0 -1
  400. package/dist/tools/handlers/types.js.map +0 -1
  401. package/dist/tools/handlers/webhooks.d.ts.map +0 -1
  402. package/dist/tools/handlers/webhooks.js.map +0 -1
  403. package/dist/tools/handlers.d.ts +0 -666
  404. package/dist/tools/handlers.d.ts.map +0 -1
  405. package/dist/tools/handlers.js +0 -2929
  406. package/dist/tools/handlers.js.map +0 -1
  407. package/dist/tools/icons.d.ts.map +0 -1
  408. package/dist/tools/icons.js.map +0 -1
  409. package/dist/tools/index.d.ts.map +0 -1
  410. package/dist/tools/index.js.map +0 -1
  411. package/dist/types.d.ts.map +0 -1
  412. package/dist/types.js.map +0 -1
  413. package/dist/utils/audit-logger.d.ts.map +0 -1
  414. package/dist/utils/audit-logger.js.map +0 -1
  415. package/dist/utils/cert-pinning.d.ts +0 -97
  416. package/dist/utils/cert-pinning.d.ts.map +0 -1
  417. package/dist/utils/cert-pinning.js +0 -328
  418. package/dist/utils/cert-pinning.js.map +0 -1
  419. package/dist/utils/cleanup-manager.d.ts.map +0 -1
  420. package/dist/utils/cleanup-manager.js.map +0 -1
  421. package/dist/utils/cli-handler.d.ts.map +0 -1
  422. package/dist/utils/cli-handler.js.map +0 -1
  423. package/dist/utils/crypto.d.ts.map +0 -1
  424. package/dist/utils/crypto.js.map +0 -1
  425. package/dist/utils/file-lock.d.ts.map +0 -1
  426. package/dist/utils/file-lock.js.map +0 -1
  427. package/dist/utils/file-permissions.d.ts.map +0 -1
  428. package/dist/utils/file-permissions.js.map +0 -1
  429. package/dist/utils/logger.d.ts.map +0 -1
  430. package/dist/utils/logger.js.map +0 -1
  431. package/dist/utils/page-utils.d.ts.map +0 -1
  432. package/dist/utils/page-utils.js.map +0 -1
  433. package/dist/utils/response-validator.d.ts.map +0 -1
  434. package/dist/utils/response-validator.js.map +0 -1
  435. package/dist/utils/secrets-scanner.d.ts.map +0 -1
  436. package/dist/utils/secrets-scanner.js.map +0 -1
  437. package/dist/utils/secure-memory.d.ts.map +0 -1
  438. package/dist/utils/secure-memory.js.map +0 -1
  439. package/dist/utils/security.d.ts.map +0 -1
  440. package/dist/utils/security.js.map +0 -1
  441. package/dist/utils/settings-manager.d.ts.map +0 -1
  442. package/dist/utils/settings-manager.js.map +0 -1
  443. package/dist/utils/stealth-utils.d.ts.map +0 -1
  444. package/dist/utils/stealth-utils.js.map +0 -1
  445. package/dist/utils/tool-validation.d.ts +0 -93
  446. package/dist/utils/tool-validation.d.ts.map +0 -1
  447. package/dist/utils/tool-validation.js +0 -277
  448. package/dist/utils/tool-validation.js.map +0 -1
  449. package/dist/webhooks/index.d.ts.map +0 -1
  450. package/dist/webhooks/index.js.map +0 -1
  451. package/dist/webhooks/types.d.ts.map +0 -1
  452. package/dist/webhooks/types.js.map +0 -1
  453. package/dist/webhooks/webhook-dispatcher.d.ts.map +0 -1
  454. package/dist/webhooks/webhook-dispatcher.js.map +0 -1
  455. package/docs/COMPLIANCE-SPEC.md +0 -1452
  456. package/docs/MCP-DIRECTORY-LISTINGS.md +0 -91
  457. package/docs/SECURITY-FORK-OPPORTUNITIES.md +0 -79
  458. package/docs/SECURITY_IMPLEMENTATION_PLAN.md +0 -437
  459. package/docs/archive/ISSUES-legacy-2026-04-24.md +0 -644
  460. package/docs/configuration.md +0 -94
  461. package/docs/dependency-risk.md +0 -25
  462. package/docs/improvement-sprint-2026.2.10.md +0 -210
  463. package/docs/testing-runbook.md +0 -166
  464. package/docs/tools.md +0 -34
  465. package/docs/troubleshooting.md +0 -59
  466. package/docs/usage-guide.md +0 -246
@@ -37,8 +37,6 @@ function generateQueryId() {
37
37
  return crypto.randomBytes(8).toString("hex");
38
38
  }
39
39
  const MAX_LOG_FILE_BYTES = 100 * 1024 * 1024; // 100 MB per daily file (I232)
40
- const TRUNCATED_FIELD_LENGTH = 500;
41
- const TRUNCATED_SUFFIX = "...[truncated]";
42
40
  /**
43
41
  * Query Logger Class
44
42
  *
@@ -56,6 +54,19 @@ export class QueryLogger {
56
54
  * severity so we don't redact legitimate base64 payloads (images, PDFs,
57
55
  * JWT payloads) that frequently appear in NotebookLM answers. Real
58
56
  * credentials live at critical/high/medium severity.
57
+ *
58
+ * ACCEPTED RISK (L11): the only `severity: "low"` rule in the scanner is the
59
+ * "High Entropy String" pattern (/\b[A-Za-z0-9+/]{32,}={0,2}\b/, see
60
+ * secrets-scanner.ts). It is DELIBERATELY NOT redacted at rest because
61
+ * NotebookLM answers routinely contain long, high-entropy base64 that is NOT
62
+ * a secret — inline image/PDF data-URIs, JWT payload segments, GCS object
63
+ * names, CSRF tokens, document hashes. Redacting at "low" would shred this
64
+ * legitimate research content (high false-positive rate) for marginal gain:
65
+ * genuine credentials (API keys, bearer tokens, private keys, connection
66
+ * strings) already match dedicated critical/high/medium rules and are
67
+ * redacted regardless. The base64 false-positive cost outweighs the residual
68
+ * risk of an unstructured low-confidence entropy hit slipping through, so the
69
+ * threshold stays at "medium" by design.
59
70
  */
60
71
  scanner = new SecretsScanner({ minSeverity: "medium" });
61
72
  stats = {
@@ -91,14 +102,25 @@ export class QueryLogger {
91
102
  cleanOldLogs() {
92
103
  try {
93
104
  const files = fs.readdirSync(this.config.logDir);
105
+ // Filenames are UTC dates (toISOString) and new Date("YYYY-MM-DD") parses as
106
+ // UTC midnight, so compute the cutoff at UTC midnight too — using local
107
+ // setDate/getDate would skew the comparison by up to a day near TZ boundaries (L13).
94
108
  const cutoffDate = new Date();
95
- cutoffDate.setDate(cutoffDate.getDate() - this.config.retentionDays);
109
+ cutoffDate.setUTCHours(0, 0, 0, 0);
110
+ cutoffDate.setUTCDate(cutoffDate.getUTCDate() - this.config.retentionDays);
96
111
  let deletedCount = 0;
97
112
  for (const file of files) {
98
113
  if (!file.startsWith("query-log-") || !file.endsWith(".jsonl"))
99
114
  continue;
100
- // Extract date from filename (query-log-YYYY-MM-DD.jsonl)
115
+ // Extract date from filename (query-log-YYYY-MM-DD.jsonl). The fixed-width
116
+ // slice(10,20) yields "YYYY-MM-DD" for both base and rotated
117
+ // (query-log-DATE.NNN.jsonl) names, so this guard does NOT exclude rotated files
118
+ // from retention — it only rejects genuinely malformed names before feeding
119
+ // new Date, which would otherwise parse to Invalid Date or a misread cutoff (L13).
120
+ // Matches audit-logger's guard.
101
121
  const dateStr = file.slice(10, 20);
122
+ if (!/^\d{4}-\d{2}-\d{2}$/.test(dateStr))
123
+ continue;
102
124
  const fileDate = new Date(dateStr);
103
125
  if (fileDate < cutoffDate) {
104
126
  fs.unlinkSync(path.join(this.config.logDir, file));
@@ -131,7 +153,13 @@ export class QueryLogger {
131
153
  if (this.currentLogFile !== expectedFile) {
132
154
  this.currentLogFile = expectedFile;
133
155
  }
134
- // Enforce per-file size cap (I232) truncate fields if approaching limit
156
+ // Enforce per-file size cap (I232). When the cap would be exceeded we ROTATE to
157
+ // a sequence-suffixed file (query-log-DATE.NNN.jsonl) instead of silently
158
+ // truncating Q&A content (M9) — the old behaviour permanently lost research
159
+ // data with no record. Each rotation emits a mandatory log.warning so the event
160
+ // is visible. The current file size is re-read after each rotation; the next
161
+ // suffix is determined by scanning the directory so the cap holds across writers
162
+ // and process restarts (per-process counters did not).
135
163
  let currentFileSize = (() => {
136
164
  try {
137
165
  return fs.statSync(this.currentLogFile).size;
@@ -140,29 +168,65 @@ export class QueryLogger {
140
168
  return 0;
141
169
  }
142
170
  })();
143
- const lines = batch.map((e) => {
171
+ const linesToWrite = [];
172
+ for (const e of batch) {
144
173
  const serialized = JSON.stringify(e);
145
174
  const entryBytes = Buffer.byteLength(serialized + "\n");
146
- if (currentFileSize + entryBytes > MAX_LOG_FILE_BYTES) {
147
- const truncated = {
148
- ...e,
149
- question: e.question.slice(0, TRUNCATED_FIELD_LENGTH) + TRUNCATED_SUFFIX,
150
- answer: e.answer.slice(0, TRUNCATED_FIELD_LENGTH) + TRUNCATED_SUFFIX,
151
- };
152
- const ts = JSON.stringify(truncated);
153
- currentFileSize += Buffer.byteLength(ts + "\n");
154
- return ts;
175
+ if (currentFileSize > 0 && currentFileSize + entryBytes > MAX_LOG_FILE_BYTES) {
176
+ // Flush what we have to the current file before rotating.
177
+ if (linesToWrite.length > 0) {
178
+ appendFileSecure(this.currentLogFile, linesToWrite.join("\n") + "\n", PERMISSION_MODES.OWNER_READ_WRITE);
179
+ linesToWrite.length = 0;
180
+ }
181
+ const rotatedFile = this.nextRotatedFile(today);
182
+ log.warning(`⚠️ Query log ${path.basename(this.currentLogFile)} reached ${MAX_LOG_FILE_BYTES} byte cap — rotating to ${path.basename(rotatedFile)} (no content truncated)`);
183
+ this.currentLogFile = rotatedFile;
184
+ currentFileSize = (() => {
185
+ try {
186
+ return fs.statSync(this.currentLogFile).size;
187
+ }
188
+ catch {
189
+ return 0;
190
+ }
191
+ })();
155
192
  }
193
+ linesToWrite.push(serialized);
156
194
  currentFileSize += entryBytes;
157
- return serialized;
158
- }).join("\n") + "\n";
159
- appendFileSecure(this.currentLogFile, lines, PERMISSION_MODES.OWNER_READ_WRITE);
195
+ }
196
+ if (linesToWrite.length > 0) {
197
+ appendFileSecure(this.currentLogFile, linesToWrite.join("\n") + "\n", PERMISSION_MODES.OWNER_READ_WRITE);
198
+ }
160
199
  }
161
200
  }
162
201
  finally {
163
202
  this.isWriting = false;
164
203
  }
165
204
  }
205
+ /**
206
+ * Determine the next sequence-suffixed log file for `date` when the base file (or a
207
+ * prior rotation) has hit the size cap (M9). Scans the directory for the highest
208
+ * existing query-log-DATE.NNN.jsonl suffix and returns the next one, so rotation is
209
+ * correct across writers and restarts rather than relying on a per-process counter.
210
+ */
211
+ nextRotatedFile(date) {
212
+ let maxSeq = 0;
213
+ try {
214
+ const re = new RegExp(`^query-log-${date}\\.(\\d{3})\\.jsonl$`);
215
+ for (const f of fs.readdirSync(this.config.logDir)) {
216
+ const m = f.match(re);
217
+ if (m) {
218
+ const seq = parseInt(m[1], 10);
219
+ if (seq > maxSeq)
220
+ maxSeq = seq;
221
+ }
222
+ }
223
+ }
224
+ catch (err) {
225
+ log.debug(`query-logger: scanning for rotated files: ${err instanceof Error ? err.message : String(err)}`);
226
+ }
227
+ const nextSeq = String(maxSeq + 1).padStart(3, "0");
228
+ return path.join(this.config.logDir, `query-log-${date}.${nextSeq}.jsonl`);
229
+ }
166
230
  /**
167
231
  * Log a query (Q&A pair).
168
232
  *
@@ -216,8 +280,23 @@ export class QueryLogger {
216
280
  * Get all queries for a specific date (YYYY-MM-DD)
217
281
  */
218
282
  async getQueriesForDate(date) {
219
- const logFile = path.join(this.config.logDir, `query-log-${date}.jsonl`);
220
- return this.readLogFile(logFile);
283
+ // Include any size-cap rotations for the day (query-log-DATE.NNN.jsonl), not just
284
+ // the base file, so rotated entries are not missed (M9).
285
+ const baseFile = path.join(this.config.logDir, `query-log-${date}.jsonl`);
286
+ const entries = this.readLogFile(baseFile);
287
+ const rotatedRe = new RegExp(`^query-log-${date}\\.\\d{3}\\.jsonl$`);
288
+ try {
289
+ const rotated = fs.readdirSync(this.config.logDir)
290
+ .filter(f => rotatedRe.test(f))
291
+ .sort();
292
+ for (const f of rotated) {
293
+ entries.push(...this.readLogFile(path.join(this.config.logDir, f)));
294
+ }
295
+ }
296
+ catch (err) {
297
+ log.debug(`query-logger: reading rotated files for date ${date}: ${err instanceof Error ? err.message : String(err)}`);
298
+ }
299
+ return entries;
221
300
  }
222
301
  /**
223
302
  * Get recent queries
@@ -279,6 +358,11 @@ export class QueryLogger {
279
358
  return;
280
359
  process.on("beforeExit", () => QueryLogger.flushAllSync());
281
360
  process.on("SIGTERM", () => QueryLogger.flushAllSync());
361
+ // Mirror SIGTERM for SIGINT (Ctrl-C) and SIGHUP so buffered Q&A is flushed
362
+ // synchronously on those signals too (M5). Additive flush-only safety nets — the
363
+ // process entry point owns termination, so these do not suppress exit or hang.
364
+ process.on("SIGINT", () => QueryLogger.flushAllSync());
365
+ process.on("SIGHUP", () => QueryLogger.flushAllSync());
282
366
  QueryLogger.processHandlersRegistered = true;
283
367
  }
284
368
  static flushAllSync() {
@@ -361,4 +445,3 @@ export function getQueryLogger() {
361
445
  export async function logQuery(entry) {
362
446
  return getQueryLogger().logQuery(entry);
363
447
  }
364
- //# sourceMappingURL=query-logger.js.map
@@ -53,4 +53,3 @@ export declare class AudioManager {
53
53
  */
54
54
  private closePage;
55
55
  }
56
- //# sourceMappingURL=audio-manager.d.ts.map
@@ -8,6 +8,68 @@ import { log } from "../utils/logger.js";
8
8
  import { randomDelay } from "../utils/stealth-utils.js";
9
9
  import fs from "fs";
10
10
  import path from "path";
11
+ import os from "os";
12
+ /**
13
+ * Maximum size for a downloaded audio file. Caps unbounded in-memory buffering
14
+ * (response.body() reads the whole response) and arbitrary disk writes (H14).
15
+ */
16
+ const MAX_AUDIO_BYTES = 200 * 1024 * 1024; // 200 MiB
17
+ /**
18
+ * Allowed origins for audio download URLs scraped from the page DOM.
19
+ * Prevents SSRF: the download URL (downloadBtn.href / data-url / audio.src) is
20
+ * attacker-influenceable content, so it must be confined to Google/NotebookLM
21
+ * hosts before page.goto() (C3). Mirrors the host-matching used by
22
+ * validateNotebookUrl in utils/security.ts.
23
+ */
24
+ const ALLOWED_AUDIO_DOWNLOAD_DOMAINS = [
25
+ "google.com",
26
+ "googleusercontent.com",
27
+ ];
28
+ /**
29
+ * Resolve and validate the audio output path, confining it to an allowed base
30
+ * directory (C2). Mirrors resolveExportPath in tools/handlers/system.ts:
31
+ * 1. NLMCP_EXPORT_DIR env override
32
+ * 2. user home directory
33
+ * Rejects absolute paths and '..' traversal that escape the base dir.
34
+ */
35
+ function resolveAudioOutputPath(userPath, defaultName) {
36
+ const envDir = process.env.NLMCP_EXPORT_DIR?.trim();
37
+ const baseDirRaw = envDir && envDir.length > 0 ? envDir : os.homedir();
38
+ const baseDir = path.resolve(baseDirRaw);
39
+ const candidate = userPath && userPath.trim().length > 0
40
+ ? path.resolve(baseDir, userPath)
41
+ : path.resolve(baseDir, defaultName);
42
+ // Defence in depth: ensure resolved path is still inside the base dir.
43
+ const rel = path.relative(baseDir, candidate);
44
+ if (rel.startsWith("..") || path.isAbsolute(rel)) {
45
+ throw new Error(`output_path must resolve inside ${baseDir} (got '${candidate}'). ` +
46
+ `Set NLMCP_EXPORT_DIR to allow another base directory.`);
47
+ }
48
+ return candidate;
49
+ }
50
+ /**
51
+ * Validate a DOM-sourced audio download URL before navigating to it (C3, SSRF).
52
+ * Enforces https and an allowed Google/NotebookLM host. Returns the normalized
53
+ * URL or throws.
54
+ */
55
+ function validateAudioDownloadUrl(url) {
56
+ let parsed;
57
+ try {
58
+ parsed = new URL(url);
59
+ }
60
+ catch {
61
+ throw new Error("Audio download URL is not a valid absolute URL");
62
+ }
63
+ if (parsed.protocol !== "https:") {
64
+ throw new Error(`Audio download URL must be https (got '${parsed.protocol}')`);
65
+ }
66
+ const hostname = parsed.hostname.toLowerCase();
67
+ const allowed = ALLOWED_AUDIO_DOWNLOAD_DOMAINS.some((d) => hostname === d || hostname.endsWith("." + d));
68
+ if (!allowed) {
69
+ throw new Error(`Audio download host not allowed: ${hostname}`);
70
+ }
71
+ return parsed.href;
72
+ }
11
73
  // Selectors for audio controls (may need refinement based on actual UI)
12
74
  const AUDIO_SELECTORS = {
13
75
  // Generate button
@@ -65,20 +127,20 @@ export class AudioManager {
65
127
  * Generate an audio overview for a notebook
66
128
  */
67
129
  async generateAudioOverview(notebookUrl) {
68
- log.info(`🎙️ Generating audio overview for: ${notebookUrl}`);
130
+ log.info(`Generating audio overview for: ${notebookUrl}`);
69
131
  const page = await this.navigateToNotebook(notebookUrl);
70
132
  try {
71
133
  // First, check current status
72
134
  const currentStatus = await this.checkAudioStatusInternal(page);
73
135
  if (currentStatus.status === "generating") {
74
- log.info(" Audio generation already in progress");
136
+ log.info(" Audio generation already in progress");
75
137
  return {
76
138
  success: true,
77
139
  status: currentStatus,
78
140
  };
79
141
  }
80
142
  if (currentStatus.status === "ready") {
81
- log.info(" Audio already generated");
143
+ log.info(" Audio already generated");
82
144
  return {
83
145
  success: true,
84
146
  status: currentStatus,
@@ -127,7 +189,7 @@ export class AudioManager {
127
189
  });
128
190
  }
129
191
  if (!generateClicked) {
130
- log.warning(" ⚠️ Could not find audio generation button");
192
+ log.warning(" Could not find audio generation button");
131
193
  return {
132
194
  success: false,
133
195
  status: { status: "unknown" },
@@ -138,7 +200,7 @@ export class AudioManager {
138
200
  // Check if generation started
139
201
  const newStatus = await this.checkAudioStatusInternal(page);
140
202
  if (newStatus.status === "generating" || newStatus.status === "ready") {
141
- log.success(` Audio generation ${newStatus.status === "ready" ? "completed" : "started"}`);
203
+ log.success(` Audio generation ${newStatus.status === "ready" ? "completed" : "started"}`);
142
204
  return {
143
205
  success: true,
144
206
  status: newStatus,
@@ -158,7 +220,7 @@ export class AudioManager {
158
220
  * Check the current audio status for a notebook
159
221
  */
160
222
  async getAudioStatus(notebookUrl) {
161
- log.info(`🔍 Checking audio status for: ${notebookUrl}`);
223
+ log.info(`Checking audio status for: ${notebookUrl}`);
162
224
  const page = await this.navigateToNotebook(notebookUrl);
163
225
  try {
164
226
  const status = await this.checkAudioStatusInternal(page);
@@ -222,7 +284,7 @@ export class AudioManager {
222
284
  * Download the generated audio file
223
285
  */
224
286
  async downloadAudio(notebookUrl, outputPath) {
225
- log.info(`⬇️ Downloading audio from: ${notebookUrl}`);
287
+ log.info(`Downloading audio from: ${notebookUrl}`);
226
288
  const page = await this.navigateToNotebook(notebookUrl);
227
289
  try {
228
290
  // First check if audio is ready
@@ -266,12 +328,12 @@ export class AudioManager {
266
328
  return false;
267
329
  });
268
330
  if (clicked) {
269
- // Wait for download to start
331
+ // The button was clicked but we cannot capture the file via this code
332
+ // path, so no file is written. Do not report success (M27).
270
333
  await randomDelay(2000, 3000);
271
- // Note: Actual file download handling would require more complex logic
272
334
  return {
273
- success: true,
274
- error: "Download initiated. Check your downloads folder.",
335
+ success: false,
336
+ error: "Download could not be completed automatically; no file was saved. Try downloading the audio manually from the notebook.",
275
337
  };
276
338
  }
277
339
  return {
@@ -279,29 +341,59 @@ export class AudioManager {
279
341
  error: "Could not find download button or audio source",
280
342
  };
281
343
  }
282
- // Generate output path if not provided
283
- const finalPath = outputPath || path.join(process.env.HOME || process.env.USERPROFILE || ".", `notebooklm-audio-${Date.now()}.mp3`);
344
+ // Confine output to an allowed base directory (C2). When no output_path
345
+ // is supplied, the generated default also lands inside the base dir.
346
+ const defaultName = `notebooklm-audio-${Date.now()}.mp3`;
347
+ const finalPath = resolveAudioOutputPath(outputPath, defaultName);
348
+ // Validate the DOM-sourced download URL before navigating (C3, SSRF).
349
+ const safeDownloadUrl = validateAudioDownloadUrl(downloadInfo.url);
284
350
  // Download the file using the page context
285
- const response = await page.goto(downloadInfo.url);
351
+ const response = await page.goto(safeDownloadUrl);
286
352
  if (!response) {
287
353
  return {
288
354
  success: false,
289
355
  error: "Failed to fetch audio file",
290
356
  };
291
357
  }
358
+ // Enforce size cap early via Content-Length if present (H14).
359
+ const contentLengthHeader = response.headers()["content-length"];
360
+ if (contentLengthHeader) {
361
+ const declared = parseInt(contentLengthHeader, 10);
362
+ if (Number.isFinite(declared) && declared > MAX_AUDIO_BYTES) {
363
+ return {
364
+ success: false,
365
+ error: `Audio file too large: ${declared} bytes exceeds limit of ${MAX_AUDIO_BYTES} bytes`,
366
+ };
367
+ }
368
+ }
369
+ // Warn (do not hard-fail) if content-type is not audio/* — NotebookLM may
370
+ // serve application/octet-stream.
371
+ const contentType = response.headers()["content-type"];
372
+ if (contentType && !contentType.startsWith("audio/") && !contentType.startsWith("application/octet-stream")) {
373
+ log.warning(` Unexpected audio content-type: ${contentType}`);
374
+ }
375
+ // patchright's response.body() has no streaming cap, so buffer then
376
+ // enforce the cap before writing (H14). Content-Length can be absent or
377
+ // inaccurate, so this check is authoritative.
292
378
  const buffer = await response.body();
293
- fs.writeFileSync(finalPath, buffer);
294
- const stats = fs.statSync(finalPath);
295
- log.success(` ✅ Audio downloaded: ${finalPath} (${stats.size} bytes)`);
379
+ if (buffer.length > MAX_AUDIO_BYTES) {
380
+ return {
381
+ success: false,
382
+ error: `Audio file too large: ${buffer.length} bytes exceeds limit of ${MAX_AUDIO_BYTES} bytes`,
383
+ };
384
+ }
385
+ // Async write to avoid blocking the event loop (H14).
386
+ await fs.promises.writeFile(finalPath, buffer);
387
+ log.success(` Audio downloaded: ${finalPath} (${buffer.length} bytes)`);
296
388
  return {
297
389
  success: true,
298
390
  filePath: finalPath,
299
- size: stats.size,
391
+ size: buffer.length,
300
392
  };
301
393
  }
302
394
  catch (error) {
303
395
  const msg = error instanceof Error ? error.message : String(error);
304
- log.error(` Failed to download audio: ${msg}`);
396
+ log.error(` Failed to download audio: ${msg}`);
305
397
  return {
306
398
  success: false,
307
399
  error: msg,
@@ -327,4 +419,3 @@ export class AudioManager {
327
419
  }
328
420
  }
329
421
  }
330
- //# sourceMappingURL=audio-manager.js.map
@@ -25,4 +25,3 @@ export interface BrowserOptions {
25
25
  * Apply browser options to CONFIG (returns modified copy, doesn't mutate global CONFIG).
26
26
  */
27
27
  export declare function applyBrowserOptions(options?: BrowserOptions, legacyShowBrowser?: boolean): Config;
28
- //# sourceMappingURL=browser-options.d.ts.map
@@ -72,4 +72,3 @@ export function applyBrowserOptions(options, legacyShowBrowser) {
72
72
  }
73
73
  return config;
74
74
  }
75
- //# sourceMappingURL=browser-options.js.map
@@ -87,9 +87,15 @@ export declare class DataTableManager {
87
87
  * Returns the largest table found.
88
88
  */
89
89
  private extractTableData;
90
+ /**
91
+ * Sanitize extracted table content through the shared response validator.
92
+ * Each cell originates from untrusted document sources, so any prompt
93
+ * injection / malicious content is redacted before the table is returned
94
+ * to the calling model.
95
+ */
96
+ private sanitizeTable;
90
97
  /**
91
98
  * Close the page if open
92
99
  */
93
100
  private closePage;
94
101
  }
95
- //# sourceMappingURL=data-table-manager.d.ts.map
@@ -16,6 +16,7 @@
16
16
  */
17
17
  import { log } from "../utils/logger.js";
18
18
  import { randomDelay } from "../utils/stealth-utils.js";
19
+ import { validateResponse } from "../utils/response-validator.js";
19
20
  export class DataTableManager {
20
21
  authManager;
21
22
  contextManager;
@@ -105,6 +106,18 @@ export class DataTableManager {
105
106
  if (item.classList.contains("shimmer-blue") || titleText.toLowerCase().includes("generating")) {
106
107
  return { status: "generating", progress: 0 };
107
108
  }
109
+ // Detect an explicit failure state on THIS artifact before assuming ready.
110
+ // A failed generation leaves a non-shimmer artifact, which would otherwise be
111
+ // misreported as "ready". Scope the check to the matched item only — a page-global
112
+ // alert query could match unrelated UI. Class names are best-effort (unconfirmed
113
+ // by live inspection); [role="alert"]/error child is the locale-independent signal.
114
+ const hasErrorChild = !!item.querySelector('[role="alert"], .error-state, .artifact-error');
115
+ if (hasErrorChild ||
116
+ item.classList.contains("error-state") ||
117
+ item.classList.contains("artifact-error") ||
118
+ item.classList.contains("failed")) {
119
+ return { status: "failed" };
120
+ }
108
121
  // Otherwise it's ready
109
122
  return { status: "ready" };
110
123
  }
@@ -214,6 +227,14 @@ export class DataTableManager {
214
227
  await randomDelay(500, 800);
215
228
  // Check if generation started
216
229
  const newStatus = await this.checkDataTableStatusInternal(page);
230
+ if (newStatus.status === "failed") {
231
+ log.warning(" Data table generation reported a failed state");
232
+ return {
233
+ success: false,
234
+ status: newStatus,
235
+ error: "Data table generation failed.",
236
+ };
237
+ }
217
238
  if (newStatus.status === "generating" || newStatus.status === "ready") {
218
239
  log.success(` Data table generation ${newStatus.status === "ready" ? "completed" : "started"}`);
219
240
  return { success: true, status: newStatus };
@@ -253,6 +274,12 @@ export class DataTableManager {
253
274
  error: "No data table found. Use generate_data_table first.",
254
275
  };
255
276
  }
277
+ if (status.status === "failed") {
278
+ return {
279
+ success: false,
280
+ error: "Data table generation failed. Use generate_data_table to retry.",
281
+ };
282
+ }
256
283
  // Click the data table artifact to open it
257
284
  const artifactClicked = await this.clickDataTableArtifact(page);
258
285
  if (!artifactClicked) {
@@ -270,10 +297,14 @@ export class DataTableManager {
270
297
  error: "Could not extract table data. The table may not be visible yet.",
271
298
  };
272
299
  }
273
- log.success(` Extracted data table: ${table.totalColumns} columns x ${table.totalRows} rows`);
300
+ // Notebook sources are arbitrary documents, so table cell text is untrusted
301
+ // and a prompt-injection conduit. Sanitize every cell before returning it
302
+ // to the calling model (mirrors ask_question response validation).
303
+ const safeTable = await this.sanitizeTable(table);
304
+ log.success(` Extracted data table: ${safeTable.totalColumns} columns x ${safeTable.totalRows} rows`);
274
305
  return {
275
306
  success: true,
276
- table,
307
+ table: safeTable,
277
308
  };
278
309
  }
279
310
  finally {
@@ -335,6 +366,32 @@ export class DataTableManager {
335
366
  return bestTable;
336
367
  });
337
368
  }
369
+ /**
370
+ * Sanitize extracted table content through the shared response validator.
371
+ * Each cell originates from untrusted document sources, so any prompt
372
+ * injection / malicious content is redacted before the table is returned
373
+ * to the calling model.
374
+ */
375
+ async sanitizeTable(table) {
376
+ let flagged = false;
377
+ const sanitizeCell = async (value) => {
378
+ const validation = await validateResponse(value);
379
+ if (!validation.safe)
380
+ flagged = true;
381
+ return validation.sanitized;
382
+ };
383
+ const headers = await Promise.all(table.headers.map(sanitizeCell));
384
+ const rows = await Promise.all(table.rows.map((row) => Promise.all(row.map(sanitizeCell))));
385
+ if (flagged) {
386
+ log.warning("🛡️ Suspicious content detected in extracted data table — sanitized");
387
+ }
388
+ return {
389
+ headers,
390
+ rows,
391
+ totalRows: table.totalRows,
392
+ totalColumns: table.totalColumns,
393
+ };
394
+ }
338
395
  /**
339
396
  * Close the page if open
340
397
  */
@@ -351,4 +408,3 @@ export class DataTableManager {
351
408
  }
352
409
  }
353
410
  }
354
- //# sourceMappingURL=data-table-manager.js.map
@@ -7,4 +7,3 @@
7
7
  export declare function clickCopiedTextSourceOption(): {
8
8
  clicked: boolean;
9
9
  };
10
- //# sourceMappingURL=dom-scripts.d.ts.map
@@ -55,4 +55,3 @@ export function clickCopiedTextSourceOption() {
55
55
  }
56
56
  return { clicked: false };
57
57
  }
58
- //# sourceMappingURL=dom-scripts.js.map
@@ -15,4 +15,3 @@ export declare class NotebookCreationError extends Error {
15
15
  readonly cause?: unknown;
16
16
  constructor(message: string, options: NotebookCreationErrorOptions);
17
17
  }
18
- //# sourceMappingURL=errors.d.ts.map
@@ -17,4 +17,3 @@ export class NotebookCreationError extends Error {
17
17
  this.cause = options.cause;
18
18
  }
19
19
  }
20
- //# sourceMappingURL=errors.js.map
@@ -12,4 +12,3 @@ export * from "./notebook-creator.js";
12
12
  export * from "./notebook-sync.js";
13
13
  export * from "./video-manager.js";
14
14
  export * from "./data-table-manager.js";
15
- //# sourceMappingURL=index.d.ts.map
@@ -12,4 +12,3 @@ export * from "./notebook-creator.js";
12
12
  export * from "./notebook-sync.js";
13
13
  export * from "./video-manager.js";
14
14
  export * from "./data-table-manager.js";
15
- //# sourceMappingURL=index.js.map
@@ -17,6 +17,14 @@ export declare class NotebookCreator {
17
17
  private withOperationLock;
18
18
  createNotebook(options: CreateNotebookOptions): Promise<CreatedNotebook>;
19
19
  private runCreateNotebook;
20
+ /**
21
+ * Best-effort deletion of a freshly-created but empty notebook (no sources
22
+ * added). Opens the notebook's overflow/options menu and confirms delete.
23
+ *
24
+ * Failure to delete is logged but not rethrown: the caller is already
25
+ * reporting the creation as failed, so we must not mask that with a
26
+ * secondary error.
27
+ */
28
+ private deleteEmptyNotebook;
20
29
  }
21
30
  export declare function createNotebook(authManager: AuthManager, contextManager: SharedContextManager, options: CreateNotebookOptions): Promise<CreatedNotebook>;
22
- //# sourceMappingURL=notebook-creator.d.ts.map