@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
@@ -83,6 +83,17 @@ export class NotebookCreator {
83
83
  }
84
84
  await randomDelay(1000, 2000);
85
85
  }
86
+ // Fail-safe: if sources were requested but NONE actually succeeded, the
87
+ // notebook is empty and useless. Discard it (best-effort delete to avoid
88
+ // burning quota) and throw so the caller never persists a library entry
89
+ // or counts a successful creation for it. An empty `sources` array (e.g.
90
+ // an overflow shell notebook) is a legitimate zero-success case and is
91
+ // left untouched.
92
+ if (sources.length > 0 && successCount === 0) {
93
+ log.error(`❌ Notebook creation failed: no sources could be added (${notebookId})`);
94
+ await this.deleteEmptyNotebook();
95
+ throw new Error("Notebook creation failed: no sources could be added; empty notebook was discarded");
96
+ }
86
97
  currentStep++;
87
98
  await sendProgress?.("Finalizing notebook...", currentStep, totalSteps);
88
99
  const notebookUrl = await this.navigation.finalizeAndGetUrl();
@@ -103,9 +114,47 @@ export class NotebookCreator {
103
114
  await this.navigation.cleanup();
104
115
  }
105
116
  }
117
+ /**
118
+ * Best-effort deletion of a freshly-created but empty notebook (no sources
119
+ * added). Opens the notebook's overflow/options menu and confirms delete.
120
+ *
121
+ * Failure to delete is logged but not rethrown: the caller is already
122
+ * reporting the creation as failed, so we must not mask that with a
123
+ * secondary error.
124
+ */
125
+ async deleteEmptyNotebook() {
126
+ const page = this.navigation.getCurrentPage();
127
+ if (!page) {
128
+ log.debug("notebook creator: no page available to delete empty notebook");
129
+ return;
130
+ }
131
+ try {
132
+ const menuButton = page
133
+ .locator('button[aria-label*="more" i], button[aria-label*="options" i], button[aria-label*="settings" i]')
134
+ .first();
135
+ await menuButton.click({ timeout: 5000 });
136
+ await randomDelay(500, 1000);
137
+ const deleteOption = page
138
+ .locator('button:has-text("Delete"), [role="menuitem"]:has-text("Delete")')
139
+ .first();
140
+ await deleteOption.click({ timeout: 5000 });
141
+ await randomDelay(500, 1000);
142
+ // Confirm in any follow-up dialog.
143
+ const confirmButton = page
144
+ .locator('button:has-text("Delete"), button:has-text("Confirm")')
145
+ .last();
146
+ if ((await confirmButton.count()) > 0) {
147
+ await confirmButton.click({ timeout: 5000 });
148
+ await randomDelay(500, 1000);
149
+ }
150
+ log.info("🗑️ Discarded empty notebook (no sources added)");
151
+ }
152
+ catch (error) {
153
+ log.warning(`⚠️ Could not delete empty notebook: ${error instanceof Error ? error.message : String(error)}`);
154
+ }
155
+ }
106
156
  }
107
157
  export async function createNotebook(authManager, contextManager, options) {
108
158
  const creator = new NotebookCreator(authManager, contextManager);
109
159
  return creator.createNotebook(options);
110
160
  }
111
- //# sourceMappingURL=notebook-creator.js.map
@@ -16,4 +16,3 @@ export declare class NotebookNavigation {
16
16
  safePageUrl(page: Page): string;
17
17
  cleanup(): Promise<void>;
18
18
  }
19
- //# sourceMappingURL=notebook-nav.d.ts.map
@@ -29,7 +29,16 @@ export class NotebookNavigation {
29
29
  }
30
30
  async initialize(headless) {
31
31
  log.info("🌐 Initializing browser for notebook creation...");
32
- const context = await this.contextManager.getOrCreateContext(headless === false ? true : undefined);
32
+ // Map the caller's headless intent to getOrCreateContext's explicit
33
+ // "show browser" contract (its argument is true = show/visible,
34
+ // false = headless, undefined = defer to CONFIG.headless).
35
+ // - headless === false -> the caller explicitly wants a VISIBLE browser
36
+ // -> showBrowser = true
37
+ // - headless === true / undefined -> no explicit visible request; defer
38
+ // to the configured default
39
+ // -> showBrowser = undefined
40
+ const showBrowser = headless === false ? true : undefined;
41
+ const context = await this.contextManager.getOrCreateContext(showBrowser);
33
42
  const isAuthenticated = await this.authManager.validateWithRetry(context);
34
43
  if (!isAuthenticated) {
35
44
  throw new Error("Not authenticated to NotebookLM. Please run setup_auth first.");
@@ -89,16 +98,23 @@ export class NotebookNavigation {
89
98
  log.debug(`notebook-nav: clicking 'New notebook' button selector: ${err instanceof Error ? err.message : String(err)}`);
90
99
  }
91
100
  }
92
- const textPatterns = ["New notebook", "Create notebook", "Create new", "New"];
101
+ // Specific, multi-word labels only. The previous last-ditch pattern was the
102
+ // bare word "New", which an includes()-match happily found inside unrelated
103
+ // controls like "New chat" or "New label" — clicking the wrong button. Match
104
+ // only full, unambiguous create-notebook labels.
105
+ const textPatterns = ["New notebook", "Create notebook", "Create new notebook"];
93
106
  for (const pattern of textPatterns) {
94
107
  try {
95
108
  const clicked = await this.page.evaluate((searchText) => {
96
109
  const browser = globalThis;
110
+ const needle = searchText.toLowerCase();
97
111
  const elements = browser.document.querySelectorAll('button, a, [role="button"]');
98
112
  for (const el of elements) {
99
- const elText = el.textContent?.toLowerCase() || "";
100
- const ariaLabel = el.getAttribute("aria-label")?.toLowerCase() || "";
101
- if (elText.includes(searchText.toLowerCase()) || ariaLabel.includes(searchText.toLowerCase())) {
113
+ const elText = (el.textContent || "").trim().toLowerCase();
114
+ const ariaLabel = (el.getAttribute("aria-label") || "").trim().toLowerCase();
115
+ // Exact label match only — never a loose substring — so we cannot
116
+ // latch onto "New chat" / "New label" etc.
117
+ if (elText === needle || ariaLabel === needle) {
102
118
  el.click();
103
119
  return true;
104
120
  }
@@ -237,4 +253,3 @@ export class NotebookNavigation {
237
253
  }
238
254
  }
239
255
  }
240
- //# sourceMappingURL=notebook-nav.js.map
@@ -26,6 +26,13 @@ export interface SyncResult {
26
26
  libraryName: string;
27
27
  libraryUrl: string;
28
28
  reason: string;
29
+ /**
30
+ * Whether this entry is SAFE to auto-remove. Only true when we have an
31
+ * exact, UUID-based confirmation that the notebook no longer exists. Entries
32
+ * that merely failed a fuzzy title match are reported as stale (for the
33
+ * human to review) but are NOT eligible for destructive auto-fix.
34
+ */
35
+ autoFixSafe: boolean;
29
36
  }>;
30
37
  missingNotebooks: ActualNotebook[];
31
38
  suggestions: string[];
@@ -84,7 +91,13 @@ export declare class NotebookSync {
84
91
  */
85
92
  private titlesMatch;
86
93
  /**
87
- * Extract notebook ID from URL
94
+ * Extract a STABLE notebook UUID from a URL, or null if none can be derived.
95
+ *
96
+ * Returns null for "pending-*" placeholders and for any URL that does not
97
+ * carry a real /notebook/UUID segment. A null id must NEVER be treated as a
98
+ * match key (two unknowns are not "equal") and must NEVER feed a destructive
99
+ * auto-fix decision — doing so previously let placeholder/garbage ids collide
100
+ * or let a missing id be (mis)matched and removed.
88
101
  */
89
102
  private extractNotebookId;
90
103
  /**
@@ -115,4 +128,3 @@ export declare function syncLibrary(authManager: AuthManager, contextManager: Sh
115
128
  autoFix?: boolean;
116
129
  showBrowser?: boolean;
117
130
  }): Promise<SyncResult>;
118
- //# sourceMappingURL=notebook-sync.d.ts.map
@@ -289,10 +289,26 @@ export class NotebookSync {
289
289
  return [];
290
290
  // Click each row to capture the URL via navigation
291
291
  const notebooks = [];
292
- const startUrl = this.page.url();
292
+ // Capture the library root URL ONCE, before any navigation. If the page is
293
+ // already sitting on a /notebook/ URL (left over from a prior step), the
294
+ // per-row waitForURL(/\/notebook\//) would resolve immediately against the
295
+ // pre-existing URL and mislabel every row with the wrong UUID. In that case
296
+ // navigate back to the library root first so clicks produce real
297
+ // navigations from a known-good base.
298
+ let startUrl = this.page.url();
299
+ if (/\/notebook\//.test(startUrl)) {
300
+ log.warning(" ⚠️ Not on library root before row scrape — returning to library");
301
+ await this.page.goto(NOTEBOOKLM_URL, { waitUntil: "domcontentloaded", timeout: CONFIG.browserTimeout });
302
+ await this.page.waitForLoadState("networkidle").catch(() => { });
303
+ await randomDelay(1500, 2000);
304
+ startUrl = this.page.url();
305
+ }
293
306
  for (let i = 0; i < rowData.length; i++) {
294
307
  const row = rowData[i];
295
308
  try {
309
+ // Record the URL immediately before the click so we can confirm that a
310
+ // REAL navigation occurred (and not accept a pre-existing notebook URL).
311
+ const urlBeforeClick = this.page.url();
296
312
  // Click the data row by index (skip non-data rows in evaluate)
297
313
  await this.page.evaluate((clickIdx) => {
298
314
  const browser = globalThis;
@@ -305,22 +321,32 @@ export class NotebookSync {
305
321
  }
306
322
  dataRows[clickIdx]?.click();
307
323
  }, i);
308
- // Wait for navigation to complete
309
- await this.page.waitForURL(/\/notebook\//, { timeout: 10000 }).catch(() => { });
324
+ // Wait for the URL to actually CHANGE to a new /notebook/ page. Using a
325
+ // predicate (rather than a bare /\/notebook\// regex) prevents resolving
326
+ // immediately against a pre-existing notebook URL and capturing a stale
327
+ // UUID for this row.
328
+ await this.page
329
+ .waitForURL((u) => /\/notebook\//.test(u.toString()) && u.toString() !== urlBeforeClick, { timeout: 10000 })
330
+ .catch(() => { });
310
331
  await randomDelay(500, 1000);
311
- // Capture the URL
332
+ // Capture the URL — only trust a UUID when a real navigation to a NEW
333
+ // notebook actually happened.
312
334
  const currentUrl = this.page.url();
313
335
  const notebookMatch = currentUrl.match(/\/notebook\/([a-f0-9-]+)/i);
314
- const url = notebookMatch
336
+ const navigated = currentUrl !== urlBeforeClick && notebookMatch !== null;
337
+ const url = navigated
315
338
  ? `https://notebooklm.google.com/notebook/${notebookMatch[1]}`
316
339
  : `pending-nav-${notebooks.length}`;
340
+ if (!navigated) {
341
+ log.warning(` ⚠️ Row click did not navigate to a new notebook: ${row.title}`);
342
+ }
317
343
  notebooks.push({
318
344
  title: row.title,
319
345
  url,
320
346
  sourceCount: row.sourceCount,
321
347
  createdDate: row.createdDate,
322
348
  });
323
- // Navigate back
349
+ // Navigate back to the library root
324
350
  await this.page.goto(startUrl, { waitUntil: "domcontentloaded", timeout: CONFIG.browserTimeout });
325
351
  await this.page.waitForLoadState("networkidle").catch(() => { });
326
352
  await randomDelay(1500, 2000);
@@ -404,65 +430,108 @@ export class NotebookSync {
404
430
  const matched = [];
405
431
  const staleEntries = [];
406
432
  const suggestions = [];
433
+ // Is the extraction trustworthy enough to treat "UUID absent from this list"
434
+ // as positive proof of deletion? Only if we actually saw notebooks AND every
435
+ // one of them yielded a real UUID. An empty list usually means extraction
436
+ // failed (page didn't load / strategy missed) — NOT that the account is
437
+ // empty — and a "pending-*" entry could BE the very notebook we're checking,
438
+ // so "absent" is not a confirmation. Without this guard a failed scrape would
439
+ // mark every valid library entry as "confirmed deleted" and autoFix would
440
+ // wipe the whole library. This is the core data-loss M33 must prevent.
441
+ const extractionIsAuthoritative = actualNotebooks.length > 0 &&
442
+ actualNotebooks.every((n) => this.extractNotebookId(n.url) !== null);
407
443
  // Track which actual notebooks are matched
408
444
  const matchedActualIndices = new Set();
445
+ // Actual notebooks tied to a library entry by a FUZZY (unconfirmed) title
446
+ // match. They are not authoritative matches, but we must not auto-ADD them
447
+ // as "missing" either — that would create a duplicate library entry for a
448
+ // notebook the human still needs to reconcile. Excluded from auto-add only.
449
+ const fuzzyReservedIndices = new Set();
409
450
  // Check each library entry
410
451
  for (const entry of libraryEntries) {
411
- // Extract notebook ID from URL
452
+ // Extract notebook ID from URL (null = pending/garbage, never a match key)
412
453
  const libraryNotebookId = this.extractNotebookId(entry.url);
413
- // Try to find matching actual notebook
414
- let matchingActualIndex = -1;
415
- // First try: match by URL/ID
416
- for (let i = 0; i < actualNotebooks.length; i++) {
417
- const actual = actualNotebooks[i];
418
- const actualNotebookId = this.extractNotebookId(actual.url);
419
- if (actualNotebookId === libraryNotebookId && !actual.url.startsWith("pending-")) {
420
- matchingActualIndex = i;
421
- break;
454
+ // First try: EXACT UUID match. This is the only authoritative identity —
455
+ // and the only signal allowed to drive a destructive auto-fix.
456
+ let exactMatchIndex = -1;
457
+ if (libraryNotebookId !== null) {
458
+ for (let i = 0; i < actualNotebooks.length; i++) {
459
+ const actualNotebookId = this.extractNotebookId(actualNotebooks[i].url);
460
+ if (actualNotebookId !== null && actualNotebookId === libraryNotebookId) {
461
+ exactMatchIndex = i;
462
+ break;
463
+ }
422
464
  }
423
465
  }
424
- // Second try: match by title similarity (fuzzy match)
425
- if (matchingActualIndex < 0) {
466
+ // Second try: fuzzy title match. This is a SUGGESTION ONLY. A 60% word
467
+ // overlap can match the wrong notebook ("Security Notes 2025" vs "...2026"),
468
+ // so a fuzzy hit must never be fed into removal/relabel — it only avoids
469
+ // proposing deletion of an entry we can plausibly still see.
470
+ let fuzzyMatchIndex = -1;
471
+ if (exactMatchIndex < 0) {
426
472
  const normalizedEntryName = this.normalizeTitle(entry.name);
427
473
  for (let i = 0; i < actualNotebooks.length; i++) {
428
474
  if (matchedActualIndices.has(i))
429
475
  continue; // Already matched
430
- const actual = actualNotebooks[i];
431
- const normalizedActualTitle = this.normalizeTitle(actual.title);
432
- // Check for significant overlap
476
+ const normalizedActualTitle = this.normalizeTitle(actualNotebooks[i].title);
433
477
  if (this.titlesMatch(normalizedEntryName, normalizedActualTitle)) {
434
- matchingActualIndex = i;
478
+ fuzzyMatchIndex = i;
435
479
  break;
436
480
  }
437
481
  }
438
482
  }
439
- if (matchingActualIndex >= 0) {
440
- const matchingActual = actualNotebooks[matchingActualIndex];
483
+ if (exactMatchIndex >= 0) {
484
+ const matchingActual = actualNotebooks[exactMatchIndex];
441
485
  matched.push({
442
486
  libraryId: entry.id,
443
487
  libraryName: entry.name,
444
488
  actualTitle: matchingActual.title,
445
489
  actualUrl: matchingActual.url,
446
490
  });
447
- matchedActualIndices.add(matchingActualIndex);
448
- // Check if name differs significantly
491
+ matchedActualIndices.add(exactMatchIndex);
492
+ // Title drift on a UUID-confirmed match is safe to suggest relabelling.
449
493
  const cleanActualTitle = this.normalizeTitle(matchingActual.title);
450
494
  const cleanEntryName = this.normalizeTitle(entry.name);
451
495
  if (cleanEntryName !== cleanActualTitle) {
452
496
  suggestions.push(`📝 "${entry.name}" matches "${matchingActual.title}" (consider updating library entry)`);
453
497
  }
454
498
  }
499
+ else if (fuzzyMatchIndex >= 0) {
500
+ // Fuzzy hit: report as a SUGGESTION only. Do not consume the actual
501
+ // notebook (leave it as "missing" so the human sees both sides) and do
502
+ // NOT mark the library entry as auto-removable.
503
+ const fuzzyActual = actualNotebooks[fuzzyMatchIndex];
504
+ fuzzyReservedIndices.add(fuzzyMatchIndex);
505
+ suggestions.push(`❓ "${entry.name}" may correspond to "${fuzzyActual.title}" (fuzzy title match — verify manually; not auto-applied)`);
506
+ staleEntries.push({
507
+ libraryId: entry.id,
508
+ libraryName: entry.name,
509
+ libraryUrl: entry.url,
510
+ reason: "No exact UUID match; only a fuzzy title match was found (review manually)",
511
+ autoFixSafe: false,
512
+ });
513
+ }
455
514
  else {
515
+ // No exact and no fuzzy match. Only safe to auto-remove when we could
516
+ // actually derive a real UUID for this entry AND positively confirmed it
517
+ // is absent. If the entry's own URL has no parseable UUID (pending/
518
+ // garbage), we cannot prove the notebook is gone — never auto-delete it.
456
519
  staleEntries.push({
457
520
  libraryId: entry.id,
458
521
  libraryName: entry.name,
459
522
  libraryUrl: entry.url,
460
- reason: "Notebook not found in NotebookLM (may be deleted or URL changed)",
523
+ reason: libraryNotebookId === null
524
+ ? "Entry has no resolvable notebook UUID (cannot confirm deletion — review manually)"
525
+ : !extractionIsAuthoritative
526
+ ? "Notebook not found, but extraction was incomplete (empty or pending results) — cannot confirm deletion; review manually"
527
+ : "Notebook UUID not present in NotebookLM (confirmed deleted or moved)",
528
+ autoFixSafe: libraryNotebookId !== null && extractionIsAuthoritative,
461
529
  });
462
530
  }
463
531
  }
464
- // Find notebooks not in library
465
- const missingNotebooks = actualNotebooks.filter((_, index) => !matchedActualIndices.has(index));
532
+ // Find notebooks not in library. Exclude fuzzy-reserved actuals so we don't
533
+ // auto-add a duplicate of a notebook a stale entry probably already denotes.
534
+ const missingNotebooks = actualNotebooks.filter((_, index) => !matchedActualIndices.has(index) && !fuzzyReservedIndices.has(index));
466
535
  // Generate suggestions
467
536
  if (staleEntries.length > 0) {
468
537
  suggestions.unshift(`🗑️ ${staleEntries.length} stale library entries should be removed`);
@@ -484,8 +553,13 @@ export class NotebookSync {
484
553
  normalizeTitle(title) {
485
554
  return title
486
555
  .toLowerCase()
487
- .replace(/[🔓🔒📁📄🔐⚛️🧠🛡️💻📋]/g, "") // Remove emojis
488
- .replace(/[\u{1F300}-\u{1F9FF}]/gu, "") // Remove other emojis
556
+ // Remove emoji across all Unicode ranges (flags, symbols, supplemental
557
+ // pictographs, etc.) plus the zero-width-joiner and variation selectors
558
+ // used to compose emoji sequences. A hardcoded set / narrow range missed
559
+ // common emoji and made otherwise-equal titles normalize differently,
560
+ // producing false "stale" mismatches.
561
+ .replace(/\p{Extended_Pictographic}/gu, "")
562
+ .replace(/[\u{200D}\u{FE0E}\u{FE0F}\u{1F3FB}-\u{1F3FF}]/gu, "") // ZWJ, variation selectors, skin-tone modifiers
489
563
  .replace(/[^\w\s]/g, " ") // Remove punctuation
490
564
  .replace(/\s+/g, " ") // Normalize whitespace
491
565
  .trim();
@@ -511,12 +585,21 @@ export class NotebookSync {
511
585
  return overlapRatio >= 0.6;
512
586
  }
513
587
  /**
514
- * Extract notebook ID from URL
588
+ * Extract a STABLE notebook UUID from a URL, or null if none can be derived.
589
+ *
590
+ * Returns null for "pending-*" placeholders and for any URL that does not
591
+ * carry a real /notebook/UUID segment. A null id must NEVER be treated as a
592
+ * match key (two unknowns are not "equal") and must NEVER feed a destructive
593
+ * auto-fix decision — doing so previously let placeholder/garbage ids collide
594
+ * or let a missing id be (mis)matched and removed.
515
595
  */
516
596
  extractNotebookId(url) {
597
+ if (!url || url.startsWith("pending-"))
598
+ return null;
517
599
  // URL format: https://notebooklm.google.com/notebook/UUID?authuser=X
518
- const match = url.match(/\/notebook\/([a-f0-9-]+)/i);
519
- return match ? match[1] : url;
600
+ // Require a canonical UUID so a partial/garbage id can't be matched.
601
+ const match = url.match(/\/notebook\/([a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12})/i);
602
+ return match ? match[1].toLowerCase() : null;
520
603
  }
521
604
  /**
522
605
  * Auto-fix stale entries by removing them
@@ -524,6 +607,13 @@ export class NotebookSync {
524
607
  async autoFixStaleEntries(staleEntries) {
525
608
  log.info("🔧 Auto-fixing stale entries...");
526
609
  for (const entry of staleEntries) {
610
+ // DESTRUCTIVE GUARD: only remove entries we could confirm as deleted via
611
+ // an exact UUID. Fuzzy/unresolvable entries are left for manual review so
612
+ // a valid library entry is never destroyed on a 60%-title-overlap guess.
613
+ if (!entry.autoFixSafe) {
614
+ log.warning(`⏭️ Skipping auto-remove of "${entry.libraryName}" — ${entry.reason}`);
615
+ continue;
616
+ }
527
617
  try {
528
618
  this.library.removeNotebook(entry.libraryId);
529
619
  log.success(`✅ Removed stale entry: ${entry.libraryName}`);
@@ -623,4 +713,3 @@ export async function syncLibrary(authManager, contextManager, library, options)
623
713
  const sync = new NotebookSync(authManager, contextManager, library);
624
714
  return await sync.syncLibrary(options);
625
715
  }
626
- //# sourceMappingURL=notebook-sync.js.map
@@ -138,4 +138,3 @@ export type SelectorKey = keyof typeof NOTEBOOKLM_SELECTORS;
138
138
  * Get all selectors for a key (primary + fallbacks)
139
139
  */
140
140
  export declare function getSelectors(key: SelectorKey): string[];
141
- //# sourceMappingURL=selectors.d.ts.map
@@ -227,13 +227,15 @@ export function getSelectors(key) {
227
227
  const info = NOTEBOOKLM_SELECTORS[key];
228
228
  return [info.primary, ...info.fallbacks].filter(Boolean);
229
229
  }
230
- // I146: warn once at module load for unconfirmed selectors so UI drift is visible
231
- {
230
+ // I146 / L32: surface unconfirmed selectors so UI drift is visible, but as a
231
+ // debug-only message gated behind NLMCP_DEBUG. Previously this ran at import
232
+ // time as a log.warning side effect, producing constant unsuppressable startup
233
+ // noise on every server boot.
234
+ if (process.env.NLMCP_DEBUG) {
232
235
  const unconfirmed = Object.entries(NOTEBOOKLM_SELECTORS)
233
236
  .filter(([, v]) => !v.confirmed)
234
237
  .map(([k]) => k);
235
238
  if (unconfirmed.length > 0) {
236
- log.warning(`⚠️ Unconfirmed selectors in use (run discovery to validate): ${unconfirmed.join(", ")}`);
239
+ log.debug(`Unconfirmed selectors in use (run discovery to validate): ${unconfirmed.join(", ")}`);
237
240
  }
238
241
  }
239
- //# sourceMappingURL=selectors.js.map
@@ -32,7 +32,22 @@ export declare class SourceManager {
32
32
  private authManager;
33
33
  private contextManager;
34
34
  private page;
35
+ private opChain;
35
36
  constructor(authManager: AuthManager, contextManager: SharedContextManager);
37
+ /**
38
+ * Serialize a public operation onto the op chain so concurrent invocations do
39
+ * not race on the shared this.page field. Failures of one operation must not
40
+ * poison the chain for the next, so the chain link always resolves.
41
+ */
42
+ private runExclusive;
43
+ /**
44
+ * Derive a STABLE source id from a DOM identity attribute when available,
45
+ * otherwise from a hash of the (title, occurrence) pair. Hashing the title
46
+ * gives an id that denotes the same source across sessions far better than a
47
+ * raw enumeration index, while staying opaque/stable for the removeSource
48
+ * contract. Occurrence disambiguates equal-titled rows within one listing.
49
+ */
50
+ private deriveSourceId;
36
51
  /**
37
52
  * Navigate to a notebook and ensure we're on the right page
38
53
  */
@@ -41,14 +56,17 @@ export declare class SourceManager {
41
56
  * List all sources in a notebook
42
57
  */
43
58
  listSources(notebookUrl: string): Promise<ListSourcesResult>;
59
+ private listSourcesInternal;
44
60
  /**
45
61
  * Add a source to an existing notebook
46
62
  */
47
63
  addSource(notebookUrl: string, source: NotebookSource): Promise<AddSourceResult>;
64
+ private addSourceInternal;
48
65
  /**
49
66
  * Remove a source from a notebook
50
67
  */
51
68
  removeSource(notebookUrl: string, sourceId: string): Promise<RemoveSourceResult>;
69
+ private removeSourceInternal;
52
70
  /**
53
71
  * Internal: Add URL source
54
72
  */
@@ -65,9 +83,19 @@ export declare class SourceManager {
65
83
  */
66
84
  private addFileSourceInternal;
67
85
  /**
68
- * Wait for source processing to complete
86
+ * Wait for source processing to complete.
87
+ *
88
+ * Returns an honest status:
89
+ * - "failed" — an error alert/toast appeared
90
+ * - "ready" — the processing indicator cleared (positive completion)
91
+ * - "processing" — we timed out before any conclusion (do NOT report "ready")
69
92
  */
70
93
  private waitForSourceProcessing;
94
+ /**
95
+ * Detect an error alert/toast for a source. Returns the error text if found,
96
+ * otherwise null. Mirrors NotebookCreationSourceManager.throwIfSourceErrorAlert.
97
+ */
98
+ private detectSourceErrorAlert;
71
99
  /**
72
100
  * Close the page if open
73
101
  */
@@ -96,4 +124,3 @@ export declare class NotebookCreationSourceManager {
96
124
  private waitForSourceProcessing;
97
125
  private throwIfSourceErrorAlert;
98
126
  }
99
- //# sourceMappingURL=source-manager.d.ts.map
@@ -174,4 +174,3 @@ export interface DiscoveryResult {
174
174
  /** Any errors encountered */
175
175
  errors: string[];
176
176
  }
177
- //# sourceMappingURL=types.d.ts.map
@@ -2,4 +2,3 @@
2
2
  * Types for notebook creation functionality
3
3
  */
4
4
  export {};
5
- //# sourceMappingURL=types.js.map
@@ -98,4 +98,3 @@ export declare class VideoManager {
98
98
  */
99
99
  private closePage;
100
100
  }
101
- //# sourceMappingURL=video-manager.d.ts.map