@pan-sec/notebooklm-mcp 2026.3.3 → 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 +60 -7
  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
@@ -10,9 +10,22 @@
10
10
  import fs from "fs";
11
11
  import path from "path";
12
12
  import crypto from "crypto";
13
+ import os from "os";
13
14
  import { CONFIG } from "../config.js";
14
15
  import { log } from "../utils/logger.js";
15
16
  import { writeFileSecure, PERMISSION_MODES } from "../utils/file-permissions.js";
17
+ /**
18
+ * Maximum number of parent directories to walk when detecting a project.
19
+ * An attacker who controls the launch directory could otherwise force a very
20
+ * deep walk; bound it to fail safe to the global library. (M26)
21
+ */
22
+ const MAX_PROJECT_WALK_DEPTH = 10;
23
+ /**
24
+ * Maximum package.json size we are willing to read+parse during project
25
+ * detection. An attacker controlling the launch dir could drop a huge file to
26
+ * cause a memory spike; cap it and fail safe. (M26)
27
+ */
28
+ const MAX_PACKAGE_JSON_BYTES = 1024 * 1024; // 1 MB
16
29
  /**
17
30
  * Detect project from current working directory
18
31
  */
@@ -33,10 +46,26 @@ function detectProject() {
33
46
  if (pkgRoot) {
34
47
  try {
35
48
  const pkgPath = path.join(pkgRoot, "package.json");
49
+ // Cap the file size before reading to avoid a memory spike from an
50
+ // attacker-controlled launch directory. (M26)
51
+ const stat = fs.statSync(pkgPath);
52
+ if (stat.size > MAX_PACKAGE_JSON_BYTES) {
53
+ log.debug(`notebook-library: package.json too large (${stat.size} bytes) — falling back to directory name`);
54
+ return {
55
+ id: hashPath(pkgRoot),
56
+ name: path.basename(pkgRoot),
57
+ path: pkgRoot,
58
+ type: "npm",
59
+ };
60
+ }
36
61
  const pkg = JSON.parse(fs.readFileSync(pkgPath, "utf-8"));
62
+ // Only trust pkg.name when it is actually a string. (M26)
63
+ const name = typeof pkg.name === "string" && pkg.name.length > 0
64
+ ? pkg.name
65
+ : path.basename(pkgRoot);
37
66
  return {
38
67
  id: hashPath(pkgRoot),
39
- name: pkg.name || path.basename(pkgRoot),
68
+ name,
40
69
  path: pkgRoot,
41
70
  type: "npm",
42
71
  };
@@ -61,7 +90,9 @@ function detectProject() {
61
90
  function findGitRoot(startPath) {
62
91
  let currentPath = startPath;
63
92
  const root = path.parse(currentPath).root;
64
- while (currentPath !== root) {
93
+ // Bound the upward walk so an attacker-controlled launch dir can't force a
94
+ // deep traversal. (M26)
95
+ for (let depth = 0; depth < MAX_PROJECT_WALK_DEPTH && currentPath !== root; depth++) {
65
96
  const gitPath = path.join(currentPath, ".git");
66
97
  if (fs.existsSync(gitPath)) {
67
98
  return currentPath;
@@ -76,7 +107,9 @@ function findGitRoot(startPath) {
76
107
  function findPackageJson(startPath) {
77
108
  let currentPath = startPath;
78
109
  const root = path.parse(currentPath).root;
79
- while (currentPath !== root) {
110
+ // Bound the upward walk so an attacker-controlled launch dir can't force a
111
+ // deep traversal. (M26)
112
+ for (let depth = 0; depth < MAX_PROJECT_WALK_DEPTH && currentPath !== root; depth++) {
80
113
  const pkgPath = path.join(currentPath, "package.json");
81
114
  if (fs.existsSync(pkgPath)) {
82
115
  return currentPath;
@@ -95,12 +128,152 @@ function hashPath(filePath) {
95
128
  .digest("hex")
96
129
  .substring(0, 12);
97
130
  }
131
+ /**
132
+ * Synchronous advisory file lock.
133
+ *
134
+ * The library save path is fully synchronous (callers consume the returned
135
+ * NotebookEntry immediately), so the async withLock() in utils/file-lock.ts
136
+ * cannot be used here. This helper mirrors that utility's on-disk convention
137
+ * (a "<file>.lock" sentinel created with the exclusive "wx" flag, JSON body
138
+ * with pid/timestamp, stale-lock reclamation) so the two interoperate safely,
139
+ * but acquires the lock with a blocking spin instead of awaiting. (M25)
140
+ */
141
+ const SYNC_LOCK_TIMEOUT_MS = 10000;
142
+ const SYNC_LOCK_RETRY_MS = 25;
143
+ const SYNC_LOCK_STALE_MS = 900000;
144
+ function withLockSync(filePath, operation) {
145
+ const lockPath = filePath + ".lock";
146
+ const lockDir = path.dirname(lockPath);
147
+ if (!fs.existsSync(lockDir)) {
148
+ fs.mkdirSync(lockDir, { recursive: true, mode: 0o700 });
149
+ }
150
+ const lockBody = JSON.stringify({
151
+ pid: process.pid,
152
+ timestamp: Date.now(),
153
+ hostname: os.hostname(),
154
+ });
155
+ const start = Date.now();
156
+ let acquired = false;
157
+ while (Date.now() - start < SYNC_LOCK_TIMEOUT_MS) {
158
+ try {
159
+ // Reclaim a stale lock left behind by a crashed process.
160
+ if (fs.existsSync(lockPath)) {
161
+ try {
162
+ const existing = JSON.parse(fs.readFileSync(lockPath, "utf-8"));
163
+ const age = Date.now() - (existing.timestamp ?? 0);
164
+ if (age > SYNC_LOCK_STALE_MS) {
165
+ log.warning(`🔓 Removing stale library lock (age: ${Math.round(age / 1000)}s)`);
166
+ fs.unlinkSync(lockPath);
167
+ }
168
+ }
169
+ catch {
170
+ // Corrupt lock file — remove it so we can make progress.
171
+ try {
172
+ fs.unlinkSync(lockPath);
173
+ }
174
+ catch { /* ignore */ }
175
+ }
176
+ }
177
+ fs.writeFileSync(lockPath, lockBody, { flag: "wx", mode: 0o600 });
178
+ acquired = true;
179
+ break;
180
+ }
181
+ catch (error) {
182
+ const err = error;
183
+ if (err.code !== "EEXIST") {
184
+ throw error;
185
+ }
186
+ // Lock held by another process; sleep briefly (no CPU spin) and retry.
187
+ sleepSync(SYNC_LOCK_RETRY_MS);
188
+ }
189
+ }
190
+ if (!acquired) {
191
+ throw new Error(`Could not acquire library lock for ${filePath} within timeout`);
192
+ }
193
+ try {
194
+ return operation();
195
+ }
196
+ finally {
197
+ try {
198
+ if (fs.existsSync(lockPath)) {
199
+ const owner = JSON.parse(fs.readFileSync(lockPath, "utf-8"));
200
+ if (owner.pid === process.pid) {
201
+ fs.unlinkSync(lockPath);
202
+ }
203
+ }
204
+ }
205
+ catch (err) {
206
+ log.debug(`notebook-library: releasing library lock: ${err instanceof Error ? err.message : String(err)}`);
207
+ }
208
+ }
209
+ }
210
+ /**
211
+ * Deep-clone a Library so that mutations to the copy never alias the original
212
+ * (the previous {...library} shallow copy shared the notebooks array, so a
213
+ * failed write could leave this.library mutated-but-unpersisted). (M25)
214
+ */
215
+ function cloneLibrary(library) {
216
+ return {
217
+ ...library,
218
+ notebooks: library.notebooks.map((n) => ({
219
+ ...n,
220
+ topics: [...n.topics],
221
+ content_types: [...n.content_types],
222
+ use_cases: [...n.use_cases],
223
+ tags: n.tags ? [...n.tags] : n.tags,
224
+ })),
225
+ };
226
+ }
227
+ /**
228
+ * Block the current thread for `ms` without busy-spinning a CPU core.
229
+ * Uses Atomics.wait on a throwaway SharedArrayBuffer; the wait always times out
230
+ * (no one ever notifies index 0). Only hit on the contended retry path. (M25)
231
+ */
232
+ function sleepSync(ms) {
233
+ Atomics.wait(SLEEP_BUFFER, 0, 0, ms);
234
+ }
235
+ const SLEEP_BUFFER = new Int32Array(new SharedArrayBuffer(4));
236
+ /**
237
+ * Module-level shutdown registry. (M25)
238
+ *
239
+ * Each NotebookLibrary instance registers itself here; a single set of
240
+ * process listeners (one per signal) flushes every live instance on shutdown.
241
+ * This avoids 3×N process listeners (and the MaxListeners warning) and shrinks
242
+ * the surface that overrides Node's default signal handling. The flush is
243
+ * flush-only — src/index.ts owns the actual SIGINT/SIGTERM exit. (M25)
244
+ */
245
+ const LIVE_LIBRARIES = new Set();
246
+ let shutdownHooksInstalled = false;
247
+ function flushAllLibraries() {
248
+ for (const lib of LIVE_LIBRARIES) {
249
+ try {
250
+ lib.flushSave();
251
+ }
252
+ catch (err) {
253
+ log.debug(`notebook-library: shutdown flush failed: ${err instanceof Error ? err.message : String(err)}`);
254
+ }
255
+ }
256
+ }
257
+ function registerForShutdownFlush(lib) {
258
+ LIVE_LIBRARIES.add(lib);
259
+ if (!shutdownHooksInstalled) {
260
+ shutdownHooksInstalled = true;
261
+ process.once("SIGTERM", flushAllLibraries);
262
+ process.once("SIGINT", flushAllLibraries);
263
+ process.once("beforeExit", flushAllLibraries);
264
+ }
265
+ }
266
+ function unregisterFromShutdownFlush(lib) {
267
+ LIVE_LIBRARIES.delete(lib);
268
+ }
98
269
  export class NotebookLibrary {
99
270
  libraryPath;
100
271
  library;
101
272
  projectInfo;
102
273
  useProjectLibrary;
103
274
  saveTimer = null;
275
+ /** Pending use-count deltas keyed by notebook id, flushed by the debounced save. (M25) */
276
+ pendingUseCounts = new Map();
104
277
  constructor(options) {
105
278
  // Determine if we should use per-project libraries
106
279
  this.useProjectLibrary = options?.useProjectLibrary ?? false;
@@ -131,6 +304,9 @@ export class NotebookLibrary {
131
304
  fs.mkdirSync(libraryDir, { recursive: true, mode: 0o700 });
132
305
  }
133
306
  this.library = this.loadLibrary();
307
+ // Flush any pending (debounced) use-count updates synchronously on shutdown
308
+ // so they aren't lost when the process exits within the debounce window. (M25)
309
+ registerForShutdownFlush(this);
134
310
  log.info("📚 NotebookLibrary initialized");
135
311
  log.info(` Library path: ${this.libraryPath}`);
136
312
  log.info(` Notebooks: ${this.library.notebooks.length}`);
@@ -236,9 +412,45 @@ export class NotebookLibrary {
236
412
  }
237
413
  }
238
414
  /**
239
- * Generate a unique ID from a string (slug format)
415
+ * Read the library file from disk without mutating in-memory state.
416
+ * Used inside the lock to pick up changes made by concurrent sessions. (M25)
240
417
  */
241
- generateId(name) {
418
+ readLibraryFromDisk() {
419
+ try {
420
+ if (fs.existsSync(this.libraryPath)) {
421
+ const data = fs.readFileSync(this.libraryPath, "utf-8");
422
+ return JSON.parse(data);
423
+ }
424
+ }
425
+ catch (error) {
426
+ log.warning(` ⚠️ Failed to reload library from disk: ${error}`);
427
+ }
428
+ // Fall back to a deep copy of the in-memory library if the file is gone.
429
+ return cloneLibrary(this.library);
430
+ }
431
+ /**
432
+ * Atomically apply a read-modify-write to the library file.
433
+ *
434
+ * Holds a cross-process lock, reloads the latest library from disk (so a
435
+ * concurrent session's notebooks aren't clobbered), applies `mutate` to a
436
+ * deep copy, persists it, and only then commits it to this.library. If the
437
+ * write throws, this.library is left untouched. (M25)
438
+ */
439
+ mutateLibrary(mutate) {
440
+ return withLockSync(this.libraryPath, () => {
441
+ const working = cloneLibrary(this.readLibraryFromDisk());
442
+ const result = mutate(working);
443
+ this.saveLibrary(working);
444
+ return result;
445
+ });
446
+ }
447
+ /**
448
+ * Generate a unique ID from a string (slug format).
449
+ * Uniqueness is checked against the supplied library (defaults to the
450
+ * in-memory one) so callers inside mutateLibrary can de-dupe against the
451
+ * freshly-reloaded disk state. (M25)
452
+ */
453
+ generateId(name, library = this.library) {
242
454
  const base = name
243
455
  .toLowerCase()
244
456
  .replace(/[^a-z0-9]+/g, "-")
@@ -247,7 +459,7 @@ export class NotebookLibrary {
247
459
  // Ensure uniqueness
248
460
  let id = base;
249
461
  let counter = 1;
250
- while (this.library.notebooks.some((n) => n.id === id)) {
462
+ while (library.notebooks.some((n) => n.id === id)) {
251
463
  id = `${base}-${counter}`;
252
464
  counter++;
253
465
  }
@@ -258,35 +470,36 @@ export class NotebookLibrary {
258
470
  */
259
471
  addNotebook(input) {
260
472
  log.info(`📝 Adding notebook: ${input.name}`);
261
- // Generate ID
262
- const id = this.generateId(input.name);
263
- // Create entry
264
- const notebook = {
265
- id,
266
- url: input.url,
267
- name: input.name,
268
- description: input.description,
269
- topics: input.topics,
270
- content_types: input.content_types || ["documentation", "examples"],
271
- use_cases: input.use_cases || [
272
- `Learning about ${input.name}`,
273
- `Implementing features with ${input.name}`,
274
- ],
275
- added_at: new Date().toISOString(),
276
- last_used: new Date().toISOString(),
277
- use_count: 0,
278
- tags: input.tags || [],
279
- };
280
- // Add to library
281
- const updated = { ...this.library };
282
- updated.notebooks.push(notebook);
283
- // Set as active if it's the first notebook
284
- if (updated.notebooks.length === 1) {
285
- updated.active_notebook_id = id;
286
- }
287
- this.saveLibrary(updated);
288
- log.success(`✅ Notebook added: ${id}`);
289
- return notebook;
473
+ // Locked read-modify-write against the latest on-disk library so a
474
+ // concurrent session's notebooks are preserved. (M25)
475
+ return this.mutateLibrary((library) => {
476
+ // Generate ID unique within the freshly-reloaded library.
477
+ const id = this.generateId(input.name, library);
478
+ // Create entry
479
+ const notebook = {
480
+ id,
481
+ url: input.url,
482
+ name: input.name,
483
+ description: input.description,
484
+ topics: input.topics,
485
+ content_types: input.content_types || ["documentation", "examples"],
486
+ use_cases: input.use_cases || [
487
+ `Learning about ${input.name}`,
488
+ `Implementing features with ${input.name}`,
489
+ ],
490
+ added_at: new Date().toISOString(),
491
+ last_used: new Date().toISOString(),
492
+ use_count: 0,
493
+ tags: input.tags || [],
494
+ };
495
+ library.notebooks.push(notebook);
496
+ // Set as active if it's the first notebook
497
+ if (library.notebooks.length === 1) {
498
+ library.active_notebook_id = id;
499
+ }
500
+ log.success(`✅ Notebook added: ${id}`);
501
+ return notebook;
502
+ });
290
503
  }
291
504
  /**
292
505
  * List all notebooks in library
@@ -313,67 +526,67 @@ export class NotebookLibrary {
313
526
  * Select a notebook as active
314
527
  */
315
528
  selectNotebook(id) {
316
- const notebook = this.getNotebook(id);
317
- if (!notebook) {
318
- throw new Error(`Notebook not found: ${id}`);
319
- }
320
529
  log.info(`🎯 Selecting notebook: ${id}`);
321
- const updated = { ...this.library };
322
- updated.active_notebook_id = id;
323
- // Update last_used
324
- const notebookIndex = updated.notebooks.findIndex((n) => n.id === id);
325
- updated.notebooks[notebookIndex] = {
326
- ...notebook,
327
- last_used: new Date().toISOString(),
328
- };
329
- this.saveLibrary(updated);
330
- log.success(`✅ Active notebook: ${id}`);
331
- return updated.notebooks[notebookIndex];
530
+ // Locked read-modify-write against the latest on-disk library. (M25)
531
+ return this.mutateLibrary((library) => {
532
+ const notebookIndex = library.notebooks.findIndex((n) => n.id === id);
533
+ if (notebookIndex === -1) {
534
+ throw new Error(`Notebook not found: ${id}`);
535
+ }
536
+ library.active_notebook_id = id;
537
+ library.notebooks[notebookIndex] = {
538
+ ...library.notebooks[notebookIndex],
539
+ last_used: new Date().toISOString(),
540
+ };
541
+ log.success(`✅ Active notebook: ${id}`);
542
+ return library.notebooks[notebookIndex];
543
+ });
332
544
  }
333
545
  /**
334
546
  * Update notebook metadata
335
547
  */
336
548
  updateNotebook(input) {
337
- const notebook = this.getNotebook(input.id);
338
- if (!notebook) {
339
- throw new Error(`Notebook not found: ${input.id}`);
340
- }
341
549
  log.info(`📝 Updating notebook: ${input.id}`);
342
- const updated = { ...this.library };
343
- const index = updated.notebooks.findIndex((n) => n.id === input.id);
344
- updated.notebooks[index] = {
345
- ...notebook,
346
- ...(input.name && { name: input.name }),
347
- ...(input.description && { description: input.description }),
348
- ...(input.topics && { topics: input.topics }),
349
- ...(input.content_types && { content_types: input.content_types }),
350
- ...(input.use_cases && { use_cases: input.use_cases }),
351
- ...(input.tags && { tags: input.tags }),
352
- ...(input.url && { url: input.url }),
353
- };
354
- this.saveLibrary(updated);
355
- log.success(`✅ Notebook updated: ${input.id}`);
356
- return updated.notebooks[index];
550
+ // Locked read-modify-write against the latest on-disk library. (M25)
551
+ return this.mutateLibrary((library) => {
552
+ const index = library.notebooks.findIndex((n) => n.id === input.id);
553
+ if (index === -1) {
554
+ throw new Error(`Notebook not found: ${input.id}`);
555
+ }
556
+ library.notebooks[index] = {
557
+ ...library.notebooks[index],
558
+ ...(input.name && { name: input.name }),
559
+ ...(input.description && { description: input.description }),
560
+ ...(input.topics && { topics: input.topics }),
561
+ ...(input.content_types && { content_types: input.content_types }),
562
+ ...(input.use_cases && { use_cases: input.use_cases }),
563
+ ...(input.tags && { tags: input.tags }),
564
+ ...(input.url && { url: input.url }),
565
+ };
566
+ log.success(`✅ Notebook updated: ${input.id}`);
567
+ return library.notebooks[index];
568
+ });
357
569
  }
358
570
  /**
359
571
  * Remove notebook from library
360
572
  */
361
573
  removeNotebook(id) {
362
- const notebook = this.getNotebook(id);
363
- if (!notebook) {
364
- return false;
365
- }
366
574
  log.info(`🗑️ Removing notebook: ${id}`);
367
- const updated = { ...this.library };
368
- updated.notebooks = updated.notebooks.filter((n) => n.id !== id);
369
- // If we removed the active notebook, select another one
370
- if (updated.active_notebook_id === id) {
371
- updated.active_notebook_id =
372
- updated.notebooks.length > 0 ? updated.notebooks[0].id : null;
373
- }
374
- this.saveLibrary(updated);
375
- log.success(`✅ Notebook removed: ${id}`);
376
- return true;
575
+ // Locked read-modify-write against the latest on-disk library. (M25)
576
+ return this.mutateLibrary((library) => {
577
+ const exists = library.notebooks.some((n) => n.id === id);
578
+ if (!exists) {
579
+ return false;
580
+ }
581
+ library.notebooks = library.notebooks.filter((n) => n.id !== id);
582
+ // If we removed the active notebook, select another one
583
+ if (library.active_notebook_id === id) {
584
+ library.active_notebook_id =
585
+ library.notebooks.length > 0 ? library.notebooks[0].id : null;
586
+ }
587
+ log.success(`✅ Notebook removed: ${id}`);
588
+ return true;
589
+ });
377
590
  }
378
591
  /**
379
592
  * Increment use count for a notebook
@@ -390,6 +603,9 @@ export class NotebookLibrary {
390
603
  last_used: new Date().toISOString(),
391
604
  };
392
605
  this.library.notebooks[notebookIndex] = updatedNotebook;
606
+ // Track the delta so the debounced flush can re-apply it additively to the
607
+ // latest on-disk state instead of clobbering concurrent sessions. (M25)
608
+ this.pendingUseCounts.set(id, (this.pendingUseCounts.get(id) ?? 0) + 1);
393
609
  this.debouncedSave();
394
610
  return updatedNotebook;
395
611
  }
@@ -401,10 +617,55 @@ export class NotebookLibrary {
401
617
  return;
402
618
  this.saveTimer = setTimeout(() => {
403
619
  this.saveTimer = null;
404
- this.saveLibrary(this.library);
620
+ this.flushSave();
405
621
  }, 5000);
406
622
  this.saveTimer.unref();
407
623
  }
624
+ /**
625
+ * Synchronously flush any pending debounced use-count updates to disk under
626
+ * the cross-process lock, re-applying the accumulated deltas to the latest
627
+ * on-disk library so concurrent sessions' notebooks and counts survive. (M25)
628
+ */
629
+ flushSave() {
630
+ if (this.saveTimer) {
631
+ clearTimeout(this.saveTimer);
632
+ this.saveTimer = null;
633
+ }
634
+ if (this.pendingUseCounts.size === 0) {
635
+ return;
636
+ }
637
+ const deltas = new Map(this.pendingUseCounts);
638
+ this.pendingUseCounts.clear();
639
+ try {
640
+ this.mutateLibrary((library) => {
641
+ const now = new Date().toISOString();
642
+ for (const [id, delta] of deltas) {
643
+ const idx = library.notebooks.findIndex((n) => n.id === id);
644
+ if (idx === -1)
645
+ continue;
646
+ library.notebooks[idx] = {
647
+ ...library.notebooks[idx],
648
+ use_count: library.notebooks[idx].use_count + delta,
649
+ last_used: now,
650
+ };
651
+ }
652
+ });
653
+ }
654
+ catch (error) {
655
+ // Restore the deltas so a later flush can retry rather than lose them. (M25)
656
+ for (const [id, delta] of deltas) {
657
+ this.pendingUseCounts.set(id, (this.pendingUseCounts.get(id) ?? 0) + delta);
658
+ }
659
+ log.error(` ❌ Failed to flush library use-count updates: ${error}`);
660
+ }
661
+ }
662
+ /**
663
+ * Release resources: flush pending writes and detach shutdown handlers. (M25)
664
+ */
665
+ close() {
666
+ this.flushSave();
667
+ unregisterFromShutdownFlush(this);
668
+ }
408
669
  /**
409
670
  * Get library statistics
410
671
  */
@@ -430,4 +691,3 @@ export class NotebookLibrary {
430
691
  n.tags?.some((t) => t.toLowerCase().includes(lowerQuery)));
431
692
  }
432
693
  }
433
- //# sourceMappingURL=notebook-library.js.map
@@ -79,4 +79,3 @@ export interface ProjectInfo {
79
79
  export interface ProjectLibrary extends Library {
80
80
  project?: ProjectInfo;
81
81
  }
82
- //# sourceMappingURL=types.d.ts.map
@@ -5,4 +5,3 @@
5
5
  * in a persistent library that Claude can manage autonomously.
6
6
  */
7
7
  export {};
8
- //# sourceMappingURL=types.js.map
@@ -4,4 +4,3 @@
4
4
  * Query logging for NotebookLM MCP Server
5
5
  */
6
6
  export { QueryLogger, getQueryLogger, logQuery, type QueryLogEntry, type QueryLoggerConfig, type QuerySearchOptions, } from "./query-logger.js";
7
- //# sourceMappingURL=index.d.ts.map
@@ -4,4 +4,3 @@
4
4
  * Query logging for NotebookLM MCP Server
5
5
  */
6
6
  export { QueryLogger, getQueryLogger, logQuery, } from "./query-logger.js";
7
- //# sourceMappingURL=index.js.map
@@ -69,6 +69,19 @@ export declare class QueryLogger {
69
69
  * severity so we don't redact legitimate base64 payloads (images, PDFs,
70
70
  * JWT payloads) that frequently appear in NotebookLM answers. Real
71
71
  * credentials live at critical/high/medium severity.
72
+ *
73
+ * ACCEPTED RISK (L11): the only `severity: "low"` rule in the scanner is the
74
+ * "High Entropy String" pattern (/\b[A-Za-z0-9+/]{32,}={0,2}\b/, see
75
+ * secrets-scanner.ts). It is DELIBERATELY NOT redacted at rest because
76
+ * NotebookLM answers routinely contain long, high-entropy base64 that is NOT
77
+ * a secret — inline image/PDF data-URIs, JWT payload segments, GCS object
78
+ * names, CSRF tokens, document hashes. Redacting at "low" would shred this
79
+ * legitimate research content (high false-positive rate) for marginal gain:
80
+ * genuine credentials (API keys, bearer tokens, private keys, connection
81
+ * strings) already match dedicated critical/high/medium rules and are
82
+ * redacted regardless. The base64 false-positive cost outweighs the residual
83
+ * risk of an unstructured low-confidence entropy hit slipping through, so the
84
+ * threshold stays at "medium" by design.
72
85
  */
73
86
  private scanner;
74
87
  private stats;
@@ -89,6 +102,13 @@ export declare class QueryLogger {
89
102
  * Write entry to log file
90
103
  */
91
104
  private writeEntry;
105
+ /**
106
+ * Determine the next sequence-suffixed log file for `date` when the base file (or a
107
+ * prior rotation) has hit the size cap (M9). Scans the directory for the highest
108
+ * existing query-log-DATE.NNN.jsonl suffix and returns the next one, so rotation is
109
+ * correct across writers and restarts rather than relying on a per-process counter.
110
+ */
111
+ private nextRotatedFile;
92
112
  /**
93
113
  * Log a query (Q&A pair).
94
114
  *
@@ -158,4 +178,3 @@ export declare function getQueryLogger(): QueryLogger;
158
178
  * Convenience function for quick query logging
159
179
  */
160
180
  export declare function logQuery(entry: Omit<QueryLogEntry, "timestamp" | "queryId">): Promise<string>;
161
- //# sourceMappingURL=query-logger.d.ts.map