@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.
- package/dist/auth/auth-manager.d.ts +0 -1
- package/dist/auth/auth-manager.js +0 -1
- package/dist/auth/mcp-auth.d.ts +0 -1
- package/dist/auth/mcp-auth.js +0 -1
- package/dist/compliance/alert-manager.d.ts +6 -2
- package/dist/compliance/alert-manager.js +40 -10
- package/dist/compliance/breach-detection.d.ts +0 -1
- package/dist/compliance/breach-detection.js +0 -1
- package/dist/compliance/change-log.d.ts +13 -1
- package/dist/compliance/change-log.js +82 -16
- package/dist/compliance/compliance-logger.d.ts +29 -3
- package/dist/compliance/compliance-logger.js +90 -27
- package/dist/compliance/compliance-tools.d.ts +0 -1
- package/dist/compliance/compliance-tools.js +0 -1
- package/dist/compliance/consent-manager.d.ts +0 -1
- package/dist/compliance/consent-manager.js +0 -1
- package/dist/compliance/dashboard.d.ts +4 -3
- package/dist/compliance/dashboard.js +11 -8
- package/dist/compliance/data-classification.d.ts +0 -1
- package/dist/compliance/data-classification.js +0 -1
- package/dist/compliance/data-erasure.d.ts +0 -1
- package/dist/compliance/data-erasure.js +0 -1
- package/dist/compliance/data-export.d.ts +0 -1
- package/dist/compliance/data-export.js +0 -1
- package/dist/compliance/data-inventory.d.ts +0 -1
- package/dist/compliance/data-inventory.js +0 -1
- package/dist/compliance/dsar-handler.d.ts +0 -1
- package/dist/compliance/dsar-handler.js +0 -1
- package/dist/compliance/evidence-collector.d.ts +0 -1
- package/dist/compliance/evidence-collector.js +4 -2
- package/dist/compliance/health-monitor.d.ts +0 -1
- package/dist/compliance/health-monitor.js +0 -1
- package/dist/compliance/incident-manager.d.ts +0 -1
- package/dist/compliance/incident-manager.js +0 -1
- package/dist/compliance/index.d.ts +0 -1
- package/dist/compliance/index.js +0 -1
- package/dist/compliance/policy-docs.d.ts +0 -1
- package/dist/compliance/policy-docs.js +0 -1
- package/dist/compliance/privacy-notice-text.d.ts +0 -1
- package/dist/compliance/privacy-notice-text.js +0 -1
- package/dist/compliance/privacy-notice.d.ts +0 -1
- package/dist/compliance/privacy-notice.js +0 -1
- package/dist/compliance/report-generator.d.ts +7 -1
- package/dist/compliance/report-generator.js +116 -34
- package/dist/compliance/retention-engine.d.ts +0 -1
- package/dist/compliance/retention-engine.js +0 -1
- package/dist/compliance/siem-exporter.d.ts +26 -2
- package/dist/compliance/siem-exporter.js +89 -24
- package/dist/compliance/types.d.ts +0 -1
- package/dist/compliance/types.js +0 -1
- package/dist/config.d.ts +0 -1
- package/dist/config.js +2 -3
- package/dist/errors.d.ts +0 -1
- package/dist/errors.js +0 -1
- package/dist/events/event-emitter.d.ts +9 -1
- package/dist/events/event-emitter.js +47 -8
- package/dist/events/event-types.d.ts +0 -1
- package/dist/events/event-types.js +8 -2
- package/dist/gemini/gemini-client.d.ts +0 -1
- package/dist/gemini/gemini-client.js +237 -45
- package/dist/gemini/index.d.ts +0 -1
- package/dist/gemini/index.js +0 -1
- package/dist/gemini/pdf-chunker.d.ts +0 -1
- package/dist/gemini/pdf-chunker.js +60 -35
- package/dist/gemini/types.d.ts +0 -1
- package/dist/gemini/types.js +0 -1
- package/dist/index.d.ts +0 -1
- package/dist/index.js +60 -7
- package/dist/library/notebook-library.d.ts +30 -2
- package/dist/library/notebook-library.js +345 -85
- package/dist/library/types.d.ts +0 -1
- package/dist/library/types.js +0 -1
- package/dist/logging/index.d.ts +0 -1
- package/dist/logging/index.js +0 -1
- package/dist/logging/query-logger.d.ts +20 -1
- package/dist/logging/query-logger.js +104 -21
- package/dist/notebook-creation/audio-manager.d.ts +0 -1
- package/dist/notebook-creation/audio-manager.js +111 -20
- package/dist/notebook-creation/browser-options.d.ts +0 -1
- package/dist/notebook-creation/browser-options.js +0 -1
- package/dist/notebook-creation/data-table-manager.d.ts +7 -1
- package/dist/notebook-creation/data-table-manager.js +59 -3
- package/dist/notebook-creation/dom-scripts.d.ts +0 -1
- package/dist/notebook-creation/dom-scripts.js +0 -1
- package/dist/notebook-creation/errors.d.ts +0 -1
- package/dist/notebook-creation/errors.js +0 -1
- package/dist/notebook-creation/index.d.ts +0 -1
- package/dist/notebook-creation/index.js +0 -1
- package/dist/notebook-creation/notebook-creator.d.ts +9 -1
- package/dist/notebook-creation/notebook-creator.js +50 -1
- package/dist/notebook-creation/notebook-nav.d.ts +0 -1
- package/dist/notebook-creation/notebook-nav.js +21 -6
- package/dist/notebook-creation/notebook-sync.d.ts +14 -2
- package/dist/notebook-creation/notebook-sync.js +124 -35
- package/dist/notebook-creation/selectors.d.ts +0 -1
- package/dist/notebook-creation/selectors.js +6 -4
- package/dist/notebook-creation/source-manager.d.ts +29 -2
- package/dist/notebook-creation/source-manager.js +0 -0
- package/dist/notebook-creation/types.d.ts +0 -1
- package/dist/notebook-creation/types.js +0 -1
- package/dist/notebook-creation/video-manager.d.ts +0 -1
- package/dist/notebook-creation/video-manager.js +91 -15
- package/dist/observability/metrics.d.ts +0 -1
- package/dist/observability/metrics.js +0 -1
- package/dist/quota/index.d.ts +0 -1
- package/dist/quota/index.js +0 -1
- package/dist/quota/quota-manager.d.ts +59 -4
- package/dist/quota/quota-manager.js +195 -46
- package/dist/resources/resource-handlers.d.ts +0 -1
- package/dist/resources/resource-handlers.js +33 -3
- package/dist/session/browser-session.d.ts +0 -1
- package/dist/session/browser-session.js +0 -1
- package/dist/session/session-manager.d.ts +0 -1
- package/dist/session/session-manager.js +0 -1
- package/dist/session/session-timeout.d.ts +0 -1
- package/dist/session/session-timeout.js +0 -1
- package/dist/session/shared-context-manager.d.ts +0 -1
- package/dist/session/shared-context-manager.js +0 -1
- package/dist/tools/annotations.d.ts +0 -1
- package/dist/tools/annotations.js +0 -1
- package/dist/tools/definitions/ask-question.d.ts +6 -3
- package/dist/tools/definitions/ask-question.js +12 -8
- package/dist/tools/definitions/chat-history.d.ts +0 -1
- package/dist/tools/definitions/chat-history.js +1 -1
- package/dist/tools/definitions/data-tables.d.ts +0 -1
- package/dist/tools/definitions/data-tables.js +4 -1
- package/dist/tools/definitions/gemini.d.ts +0 -1
- package/dist/tools/definitions/gemini.js +14 -7
- package/dist/tools/definitions/notebook-management.d.ts +0 -1
- package/dist/tools/definitions/notebook-management.js +7 -2
- package/dist/tools/definitions/query-history.d.ts +0 -1
- package/dist/tools/definitions/query-history.js +0 -1
- package/dist/tools/definitions/session-management.d.ts +0 -1
- package/dist/tools/definitions/session-management.js +0 -1
- package/dist/tools/definitions/system.d.ts +0 -1
- package/dist/tools/definitions/system.js +32 -12
- package/dist/tools/definitions/video.d.ts +0 -1
- package/dist/tools/definitions/video.js +6 -3
- package/dist/tools/definitions.d.ts +0 -1
- package/dist/tools/definitions.js +0 -1
- package/dist/tools/handlers/ask-question.d.ts +0 -1
- package/dist/tools/handlers/ask-question.js +47 -18
- package/dist/tools/handlers/audio-video.d.ts +0 -1
- package/dist/tools/handlers/audio-video.js +0 -1
- package/dist/tools/handlers/auth.d.ts +0 -1
- package/dist/tools/handlers/auth.js +0 -1
- package/dist/tools/handlers/error-utils.d.ts +0 -1
- package/dist/tools/handlers/error-utils.js +0 -1
- package/dist/tools/handlers/gemini.d.ts +0 -1
- package/dist/tools/handlers/gemini.js +0 -1
- package/dist/tools/handlers/index.d.ts +0 -1
- package/dist/tools/handlers/index.js +0 -1
- package/dist/tools/handlers/notebook-creation.d.ts +0 -1
- package/dist/tools/handlers/notebook-creation.js +16 -1
- package/dist/tools/handlers/notebook-management.d.ts +0 -1
- package/dist/tools/handlers/notebook-management.js +7 -2
- package/dist/tools/handlers/session-management.d.ts +0 -1
- package/dist/tools/handlers/session-management.js +0 -1
- package/dist/tools/handlers/system.d.ts +0 -1
- package/dist/tools/handlers/system.js +0 -1
- package/dist/tools/handlers/types.d.ts +0 -1
- package/dist/tools/handlers/types.js +0 -1
- package/dist/tools/handlers/webhooks.d.ts +0 -1
- package/dist/tools/handlers/webhooks.js +0 -1
- package/dist/tools/icons.d.ts +0 -1
- package/dist/tools/icons.js +0 -1
- package/dist/tools/index.d.ts +0 -1
- package/dist/tools/index.js +0 -1
- package/dist/types.d.ts +0 -1
- package/dist/types.js +0 -1
- package/dist/utils/audit-logger.d.ts +11 -1
- package/dist/utils/audit-logger.js +189 -21
- package/dist/utils/cleanup-manager.d.ts +0 -1
- package/dist/utils/cleanup-manager.js +0 -1
- package/dist/utils/cli-handler.d.ts +0 -1
- package/dist/utils/cli-handler.js +0 -1
- package/dist/utils/crypto.d.ts +18 -9
- package/dist/utils/crypto.js +93 -28
- package/dist/utils/file-lock.d.ts +15 -1
- package/dist/utils/file-lock.js +67 -59
- package/dist/utils/file-permissions.d.ts +0 -1
- package/dist/utils/file-permissions.js +35 -7
- package/dist/utils/logger.d.ts +0 -1
- package/dist/utils/logger.js +0 -1
- package/dist/utils/page-utils.d.ts +0 -1
- package/dist/utils/page-utils.js +32 -28
- package/dist/utils/response-validator.d.ts +0 -1
- package/dist/utils/response-validator.js +18 -15
- package/dist/utils/secrets-scanner.d.ts +0 -1
- package/dist/utils/secrets-scanner.js +32 -7
- package/dist/utils/secure-memory.d.ts +34 -16
- package/dist/utils/secure-memory.js +40 -25
- package/dist/utils/security.d.ts +0 -1
- package/dist/utils/security.js +66 -39
- package/dist/utils/settings-manager.d.ts +9 -1
- package/dist/utils/settings-manager.js +45 -2
- package/dist/utils/stealth-utils.d.ts +0 -1
- package/dist/utils/stealth-utils.js +11 -9
- package/dist/webhooks/index.d.ts +0 -1
- package/dist/webhooks/index.js +0 -1
- package/dist/webhooks/types.d.ts +0 -1
- package/dist/webhooks/types.js +0 -1
- package/dist/webhooks/webhook-dispatcher.d.ts +0 -1
- package/dist/webhooks/webhook-dispatcher.js +0 -1
- package/package.json +5 -4
- package/dist/auth/auth-manager.d.ts.map +0 -1
- package/dist/auth/auth-manager.js.map +0 -1
- package/dist/auth/mcp-auth.d.ts.map +0 -1
- package/dist/auth/mcp-auth.js.map +0 -1
- package/dist/compliance/alert-manager.d.ts.map +0 -1
- package/dist/compliance/alert-manager.js.map +0 -1
- package/dist/compliance/breach-detection.d.ts.map +0 -1
- package/dist/compliance/breach-detection.js.map +0 -1
- package/dist/compliance/change-log.d.ts.map +0 -1
- package/dist/compliance/change-log.js.map +0 -1
- package/dist/compliance/compliance-logger.d.ts.map +0 -1
- package/dist/compliance/compliance-logger.js.map +0 -1
- package/dist/compliance/compliance-tools.d.ts.map +0 -1
- package/dist/compliance/compliance-tools.js.map +0 -1
- package/dist/compliance/consent-manager.d.ts.map +0 -1
- package/dist/compliance/consent-manager.js.map +0 -1
- package/dist/compliance/dashboard.d.ts.map +0 -1
- package/dist/compliance/dashboard.js.map +0 -1
- package/dist/compliance/data-classification.d.ts.map +0 -1
- package/dist/compliance/data-classification.js.map +0 -1
- package/dist/compliance/data-erasure.d.ts.map +0 -1
- package/dist/compliance/data-erasure.js.map +0 -1
- package/dist/compliance/data-export.d.ts.map +0 -1
- package/dist/compliance/data-export.js.map +0 -1
- package/dist/compliance/data-inventory.d.ts.map +0 -1
- package/dist/compliance/data-inventory.js.map +0 -1
- package/dist/compliance/dsar-handler.d.ts.map +0 -1
- package/dist/compliance/dsar-handler.js.map +0 -1
- package/dist/compliance/evidence-collector.d.ts.map +0 -1
- package/dist/compliance/evidence-collector.js.map +0 -1
- package/dist/compliance/health-monitor.d.ts.map +0 -1
- package/dist/compliance/health-monitor.js.map +0 -1
- package/dist/compliance/incident-manager.d.ts.map +0 -1
- package/dist/compliance/incident-manager.js.map +0 -1
- package/dist/compliance/index.d.ts.map +0 -1
- package/dist/compliance/index.js.map +0 -1
- package/dist/compliance/policy-docs.d.ts.map +0 -1
- package/dist/compliance/policy-docs.js.map +0 -1
- package/dist/compliance/privacy-notice-text.d.ts.map +0 -1
- package/dist/compliance/privacy-notice-text.js.map +0 -1
- package/dist/compliance/privacy-notice.d.ts.map +0 -1
- package/dist/compliance/privacy-notice.js.map +0 -1
- package/dist/compliance/report-generator.d.ts.map +0 -1
- package/dist/compliance/report-generator.js.map +0 -1
- package/dist/compliance/retention-engine.d.ts.map +0 -1
- package/dist/compliance/retention-engine.js.map +0 -1
- package/dist/compliance/siem-exporter.d.ts.map +0 -1
- package/dist/compliance/siem-exporter.js.map +0 -1
- package/dist/compliance/types.d.ts.map +0 -1
- package/dist/compliance/types.js.map +0 -1
- package/dist/config.d.ts.map +0 -1
- package/dist/config.js.map +0 -1
- package/dist/errors.d.ts.map +0 -1
- package/dist/errors.js.map +0 -1
- package/dist/events/event-emitter.d.ts.map +0 -1
- package/dist/events/event-emitter.js.map +0 -1
- package/dist/events/event-types.d.ts.map +0 -1
- package/dist/events/event-types.js.map +0 -1
- package/dist/gemini/gemini-client.d.ts.map +0 -1
- package/dist/gemini/gemini-client.js.map +0 -1
- package/dist/gemini/index.d.ts.map +0 -1
- package/dist/gemini/index.js.map +0 -1
- package/dist/gemini/pdf-chunker.d.ts.map +0 -1
- package/dist/gemini/pdf-chunker.js.map +0 -1
- package/dist/gemini/types.d.ts.map +0 -1
- package/dist/gemini/types.js.map +0 -1
- package/dist/index.d.ts.map +0 -1
- package/dist/index.js.map +0 -1
- package/dist/library/notebook-library.d.ts.map +0 -1
- package/dist/library/notebook-library.js.map +0 -1
- package/dist/library/types.d.ts.map +0 -1
- package/dist/library/types.js.map +0 -1
- package/dist/logging/index.d.ts.map +0 -1
- package/dist/logging/index.js.map +0 -1
- package/dist/logging/query-logger.d.ts.map +0 -1
- package/dist/logging/query-logger.js.map +0 -1
- package/dist/notebook-creation/audio-manager.d.ts.map +0 -1
- package/dist/notebook-creation/audio-manager.js.map +0 -1
- package/dist/notebook-creation/browser-options.d.ts.map +0 -1
- package/dist/notebook-creation/browser-options.js.map +0 -1
- package/dist/notebook-creation/data-table-manager.d.ts.map +0 -1
- package/dist/notebook-creation/data-table-manager.js.map +0 -1
- package/dist/notebook-creation/discover-creation-flow.d.ts +0 -2
- package/dist/notebook-creation/discover-creation-flow.d.ts.map +0 -1
- package/dist/notebook-creation/discover-creation-flow.js +0 -177
- package/dist/notebook-creation/discover-creation-flow.js.map +0 -1
- package/dist/notebook-creation/discover-quota.d.ts +0 -2
- package/dist/notebook-creation/discover-quota.d.ts.map +0 -1
- package/dist/notebook-creation/discover-quota.js +0 -194
- package/dist/notebook-creation/discover-quota.js.map +0 -1
- package/dist/notebook-creation/discover-source-dialog.d.ts +0 -8
- package/dist/notebook-creation/discover-source-dialog.d.ts.map +0 -1
- package/dist/notebook-creation/discover-source-dialog.js +0 -134
- package/dist/notebook-creation/discover-source-dialog.js.map +0 -1
- package/dist/notebook-creation/discover-sources.d.ts +0 -8
- package/dist/notebook-creation/discover-sources.d.ts.map +0 -1
- package/dist/notebook-creation/discover-sources.js +0 -272
- package/dist/notebook-creation/discover-sources.js.map +0 -1
- package/dist/notebook-creation/discover-text-input.d.ts +0 -7
- package/dist/notebook-creation/discover-text-input.d.ts.map +0 -1
- package/dist/notebook-creation/discover-text-input.js +0 -135
- package/dist/notebook-creation/discover-text-input.js.map +0 -1
- package/dist/notebook-creation/dom-scripts.d.ts.map +0 -1
- package/dist/notebook-creation/dom-scripts.js.map +0 -1
- package/dist/notebook-creation/errors.d.ts.map +0 -1
- package/dist/notebook-creation/errors.js.map +0 -1
- package/dist/notebook-creation/index.d.ts.map +0 -1
- package/dist/notebook-creation/index.js.map +0 -1
- package/dist/notebook-creation/notebook-creator.d.ts.map +0 -1
- package/dist/notebook-creation/notebook-creator.js.map +0 -1
- package/dist/notebook-creation/notebook-nav.d.ts.map +0 -1
- package/dist/notebook-creation/notebook-nav.js.map +0 -1
- package/dist/notebook-creation/notebook-sync.d.ts.map +0 -1
- package/dist/notebook-creation/notebook-sync.js.map +0 -1
- package/dist/notebook-creation/run-discovery.d.ts +0 -11
- package/dist/notebook-creation/run-discovery.d.ts.map +0 -1
- package/dist/notebook-creation/run-discovery.js +0 -151
- package/dist/notebook-creation/run-discovery.js.map +0 -1
- package/dist/notebook-creation/selector-discovery.d.ts +0 -65
- package/dist/notebook-creation/selector-discovery.d.ts.map +0 -1
- package/dist/notebook-creation/selector-discovery.js +0 -414
- package/dist/notebook-creation/selector-discovery.js.map +0 -1
- package/dist/notebook-creation/selectors.d.ts.map +0 -1
- package/dist/notebook-creation/selectors.js.map +0 -1
- package/dist/notebook-creation/selectors.ts +0 -112
- package/dist/notebook-creation/source-manager.d.ts.map +0 -1
- package/dist/notebook-creation/source-manager.js.map +0 -1
- package/dist/notebook-creation/test-create.d.ts +0 -8
- package/dist/notebook-creation/test-create.d.ts.map +0 -1
- package/dist/notebook-creation/test-create.js +0 -72
- package/dist/notebook-creation/test-create.js.map +0 -1
- package/dist/notebook-creation/types.d.ts.map +0 -1
- package/dist/notebook-creation/types.js.map +0 -1
- package/dist/notebook-creation/video-manager.d.ts.map +0 -1
- package/dist/notebook-creation/video-manager.js.map +0 -1
- package/dist/observability/metrics.d.ts.map +0 -1
- package/dist/observability/metrics.js.map +0 -1
- package/dist/quota/index.d.ts.map +0 -1
- package/dist/quota/index.js.map +0 -1
- package/dist/quota/quota-manager.d.ts.map +0 -1
- package/dist/quota/quota-manager.js.map +0 -1
- package/dist/resources/resource-handlers.d.ts.map +0 -1
- package/dist/resources/resource-handlers.js.map +0 -1
- package/dist/session/browser-session.d.ts.map +0 -1
- package/dist/session/browser-session.js.map +0 -1
- package/dist/session/session-manager.d.ts.map +0 -1
- package/dist/session/session-manager.js.map +0 -1
- package/dist/session/session-timeout.d.ts.map +0 -1
- package/dist/session/session-timeout.js.map +0 -1
- package/dist/session/shared-context-manager.d.ts.map +0 -1
- package/dist/session/shared-context-manager.js.map +0 -1
- package/dist/tools/annotations.d.ts.map +0 -1
- package/dist/tools/annotations.js.map +0 -1
- package/dist/tools/definitions/ask-question.d.ts.map +0 -1
- package/dist/tools/definitions/ask-question.js.map +0 -1
- package/dist/tools/definitions/chat-history.d.ts.map +0 -1
- package/dist/tools/definitions/chat-history.js.map +0 -1
- package/dist/tools/definitions/data-tables.d.ts.map +0 -1
- package/dist/tools/definitions/data-tables.js.map +0 -1
- package/dist/tools/definitions/gemini.d.ts.map +0 -1
- package/dist/tools/definitions/gemini.js.map +0 -1
- package/dist/tools/definitions/notebook-management.d.ts.map +0 -1
- package/dist/tools/definitions/notebook-management.js.map +0 -1
- package/dist/tools/definitions/query-history.d.ts.map +0 -1
- package/dist/tools/definitions/query-history.js.map +0 -1
- package/dist/tools/definitions/session-management.d.ts.map +0 -1
- package/dist/tools/definitions/session-management.js.map +0 -1
- package/dist/tools/definitions/system.d.ts.map +0 -1
- package/dist/tools/definitions/system.js.map +0 -1
- package/dist/tools/definitions/video.d.ts.map +0 -1
- package/dist/tools/definitions/video.js.map +0 -1
- package/dist/tools/definitions.d.ts.map +0 -1
- package/dist/tools/definitions.js.map +0 -1
- package/dist/tools/handlers/ask-question.d.ts.map +0 -1
- package/dist/tools/handlers/ask-question.js.map +0 -1
- package/dist/tools/handlers/audio-video.d.ts.map +0 -1
- package/dist/tools/handlers/audio-video.js.map +0 -1
- package/dist/tools/handlers/auth.d.ts.map +0 -1
- package/dist/tools/handlers/auth.js.map +0 -1
- package/dist/tools/handlers/error-utils.d.ts.map +0 -1
- package/dist/tools/handlers/error-utils.js.map +0 -1
- package/dist/tools/handlers/gemini.d.ts.map +0 -1
- package/dist/tools/handlers/gemini.js.map +0 -1
- package/dist/tools/handlers/index.d.ts.map +0 -1
- package/dist/tools/handlers/index.js.map +0 -1
- package/dist/tools/handlers/notebook-creation.d.ts.map +0 -1
- package/dist/tools/handlers/notebook-creation.js.map +0 -1
- package/dist/tools/handlers/notebook-management.d.ts.map +0 -1
- package/dist/tools/handlers/notebook-management.js.map +0 -1
- package/dist/tools/handlers/session-management.d.ts.map +0 -1
- package/dist/tools/handlers/session-management.js.map +0 -1
- package/dist/tools/handlers/system.d.ts.map +0 -1
- package/dist/tools/handlers/system.js.map +0 -1
- package/dist/tools/handlers/types.d.ts.map +0 -1
- package/dist/tools/handlers/types.js.map +0 -1
- package/dist/tools/handlers/webhooks.d.ts.map +0 -1
- package/dist/tools/handlers/webhooks.js.map +0 -1
- package/dist/tools/handlers.d.ts +0 -666
- package/dist/tools/handlers.d.ts.map +0 -1
- package/dist/tools/handlers.js +0 -2929
- package/dist/tools/handlers.js.map +0 -1
- package/dist/tools/icons.d.ts.map +0 -1
- package/dist/tools/icons.js.map +0 -1
- package/dist/tools/index.d.ts.map +0 -1
- package/dist/tools/index.js.map +0 -1
- package/dist/types.d.ts.map +0 -1
- package/dist/types.js.map +0 -1
- package/dist/utils/audit-logger.d.ts.map +0 -1
- package/dist/utils/audit-logger.js.map +0 -1
- package/dist/utils/cert-pinning.d.ts +0 -97
- package/dist/utils/cert-pinning.d.ts.map +0 -1
- package/dist/utils/cert-pinning.js +0 -328
- package/dist/utils/cert-pinning.js.map +0 -1
- package/dist/utils/cleanup-manager.d.ts.map +0 -1
- package/dist/utils/cleanup-manager.js.map +0 -1
- package/dist/utils/cli-handler.d.ts.map +0 -1
- package/dist/utils/cli-handler.js.map +0 -1
- package/dist/utils/crypto.d.ts.map +0 -1
- package/dist/utils/crypto.js.map +0 -1
- package/dist/utils/file-lock.d.ts.map +0 -1
- package/dist/utils/file-lock.js.map +0 -1
- package/dist/utils/file-permissions.d.ts.map +0 -1
- package/dist/utils/file-permissions.js.map +0 -1
- package/dist/utils/logger.d.ts.map +0 -1
- package/dist/utils/logger.js.map +0 -1
- package/dist/utils/page-utils.d.ts.map +0 -1
- package/dist/utils/page-utils.js.map +0 -1
- package/dist/utils/response-validator.d.ts.map +0 -1
- package/dist/utils/response-validator.js.map +0 -1
- package/dist/utils/secrets-scanner.d.ts.map +0 -1
- package/dist/utils/secrets-scanner.js.map +0 -1
- package/dist/utils/secure-memory.d.ts.map +0 -1
- package/dist/utils/secure-memory.js.map +0 -1
- package/dist/utils/security.d.ts.map +0 -1
- package/dist/utils/security.js.map +0 -1
- package/dist/utils/settings-manager.d.ts.map +0 -1
- package/dist/utils/settings-manager.js.map +0 -1
- package/dist/utils/stealth-utils.d.ts.map +0 -1
- package/dist/utils/stealth-utils.js.map +0 -1
- package/dist/utils/tool-validation.d.ts +0 -93
- package/dist/utils/tool-validation.d.ts.map +0 -1
- package/dist/utils/tool-validation.js +0 -277
- package/dist/utils/tool-validation.js.map +0 -1
- package/dist/webhooks/index.d.ts.map +0 -1
- package/dist/webhooks/index.js.map +0 -1
- package/dist/webhooks/types.d.ts.map +0 -1
- package/dist/webhooks/types.js.map +0 -1
- package/dist/webhooks/webhook-dispatcher.d.ts.map +0 -1
- package/dist/webhooks/webhook-dispatcher.js.map +0 -1
- package/docs/COMPLIANCE-SPEC.md +0 -1452
- package/docs/MCP-DIRECTORY-LISTINGS.md +0 -91
- package/docs/SECURITY-FORK-OPPORTUNITIES.md +0 -79
- package/docs/SECURITY_IMPLEMENTATION_PLAN.md +0 -437
- package/docs/archive/ISSUES-legacy-2026-04-24.md +0 -644
- package/docs/configuration.md +0 -94
- package/docs/dependency-risk.md +0 -25
- package/docs/improvement-sprint-2026.2.10.md +0 -210
- package/docs/testing-runbook.md +0 -166
- package/docs/tools.md +0 -34
- package/docs/troubleshooting.md +0 -59
- 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
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
*
|
|
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
|
-
|
|
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 (
|
|
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
|
-
//
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
id,
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
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
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
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
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
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
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
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.
|
|
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
|
package/dist/library/types.d.ts
CHANGED
package/dist/library/types.js
CHANGED
package/dist/logging/index.d.ts
CHANGED
package/dist/logging/index.js
CHANGED
|
@@ -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
|