Unofficial Python API and agentic skill for Google Gemini Notebook. Full programmatic access to NotebookLM's features—including capabilities the web UI doesn't expose—via Python, CLI, and AI agents like Claude Code, Codex, and OpenClaw.
This report summarizes scanner evidence for teng-lin/notebooklm-py, a Python project with 19,683 GitHub stars. SynthScan examined 1,559,628 lines of code across 1984 source files, recording 23460 pattern matches distributed across 23 syntactic categories. The legacy adjusted pattern signal is 19.9 (Elevated pattern signal); it is not an authorship estimate.
Use the findings to ask whether maintainers can explain intent, verify dependencies, simplify unnecessary scaffolding, and focus review effort. Risk Payload v1 adds ownership, supply-chain, over-engineering, and review-effort vectors when available. These are prompts for human verification, not probabilities, security findings, or measured maintenance costs.
Use each vector to guide manual verification of the underlying findings.
Can maintainers explain intent, assumptions, and trade-offs? 17227 finding(s).
Are imports declared and package/API names verified? 2554 finding(s).
Are wrappers, guards, and repeated structures necessary? 19833 finding(s).
Which changes need focused human review? 23460 finding(s).
This chart tracks the legacy adjusted pattern score across scan runs. Changes can reflect source changes, scan coverage, or detector/scoring versions; they do not measure AI adoption or prove that a team refactored code. Compare runs only when their scoring versions are compatible. The dashed line tracks the raw pattern-hit count.
Groups findings by configured severity weight. Severity is not a confidence estimate, security rating, or proof that a package is missing. Verify imports against the project's manifests and inspect each finding in its local design context.
This horizontal bar chart shows where configured pattern scores accumulate across directories. Treat the bars as locations to inspect, not as evidence of authorship or code quality. Use the file-level findings to decide whether a directory needs a focused ownership, dependency, complexity, or review check.
The scanner identified 23460 distinct pattern matches across 23 syntactic categories. Each entry below represents a discrete location in the source code where the engine recorded a detector match to inspect in context. Expand any category row to inspect the individual file paths, line numbers, code snippets, and the lexical context (CODE, COMMENT, or STRING) in which each match was detected.
Reading the findings table: The Severity column indicates the configured finding weight (CRITICAL / HIGH / MEDIUM / LOW). The Context column identifies whether the match occurred inside executable code, an inline comment, or a string literal — legacy comment-context matches receive a ×1.5 score weight. The ⚡ bolt icon marks clustered matches: three or more patterns within a 10-line window, each receiving an additional ×1.5 density multiplier under the legacy scoring model.
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW | tests/conftest.py | 128 | def _isolate_backend_preference( | CODE |
| LOW | tests/conftest.py | 442 | def pytest_collection_modifyitems(config, items): | CODE |
| LOW | tests/conftest.py | 631 | def mock_list_notebooks_response(): | STRING |
| LOW | tests/conftest.py | 751 | def legacy_vcr_follow_up_probe(monkeypatch): | STRING |
| LOW | tests/conftest.py | 762 | async def _count_prior_server_turns( | STRING |
| LOW | tests/conftest.py | 774 | def legacy_vcr_add_url_baseline(): | CODE |
| LOW | tests/cassette_patterns.py | 1674 | def synthetic_error_cassette_name(mode: str, slug: str) -> str: | CODE |
| LOW | tests/cassette_patterns.py | 1691 | def build_synthetic_error_response( | CODE |
| LOW | tests/vcr_config.py | 181 | def _substitute_synthetic_error(response: dict[str, Any]) -> dict[str, Any]: | CODE |
| LOW | tests/vcr_config.py | 564 | def _is_create_artifact_client_options(node: Any) -> bool: | CODE |
| LOW | tests/vcr_config.py | 580 | def _normalize_create_artifact_options(decoded_outer: Any) -> Any: | CODE |
| LOW | tests/_helpers/android_grpc_harness.py | 148 | def _inject_correlation_names(monkeypatch: pytest.MonkeyPatch, names: tuple[str, ...]) -> None: | CODE |
| LOW | tests/_helpers/downloads.py | 15 | def configure_complete_artifact_listing(mock_client: MagicMock) -> None: | CODE |
| LOW | tests/_helpers/downloads.py | 30 | def configure_prepared_artifact_downloads(mock_client: MagicMock) -> None: | CODE |
| LOW | tests/_helpers/android_phenotype_http_cassette.py | 55 | def _validate_phenotype_request(message: Any) -> None: | CODE |
| LOW | tests/_helpers/android_phenotype_http_cassette.py | 94 | def _scrub_phenotype_response(response: dict[str, Any]) -> dict[str, Any]: | CODE |
| LOW | tests/_helpers/android_phenotype_http_cassette.py | 160 | def build_phenotype_http_post(cassette_path: Path) -> PhenotypeHttpPost: | CODE |
| LOW | tests/_helpers/android_grpc_cassette.py | 137 | def _application_metadata_keys(metadata: Any) -> tuple[str, ...] | None: | CODE |
| LOW | tests/_helpers/android_grpc_cassette.py | 155 | def _check_placeholder_budget(count: int) -> None: | CODE |
| LOW | tests/_helpers/android_grpc_cassette.py | 266 | def _trust_string_placeholder(self, value: str) -> bool: | CODE |
| LOW | tests/_helpers/client_factory.py | 32 | def build_client_shell_for_tests( | CODE |
| LOW⚡ | tests/unit/test_artifacts_helpers.py | 30 | def test_extract_data_table_rows_happy_path() -> None: | CODE |
| LOW⚡ | tests/unit/test_artifacts_helpers.py | 51 | def test_extract_data_table_rows_missing_inner_list() -> None: | CODE |
| LOW⚡ | tests/unit/test_artifacts_helpers.py | 61 | def test_extract_data_table_rows_wrong_type_at_one_level() -> None: | CODE |
| LOW⚡ | tests/unit/test_artifacts_helpers.py | 70 | def test_extract_data_table_rows_truncated_structure() -> None: | CODE |
| LOW⚡ | tests/unit/test_artifacts_helpers.py | 83 | def test_extract_data_table_rows_non_list_inner_value( | CODE |
| LOW⚡ | tests/unit/test_artifacts_helpers.py | 105 | def test_parse_data_table_raises_artifact_parse_error_on_drift() -> None: | CODE |
| LOW | tests/unit/test_artifacts_helpers.py | 118 | def test_parse_data_table_raises_on_empty_rows() -> None: | CODE |
| LOW | tests/unit/test_artifacts_helpers.py | 126 | def test_parse_data_table_happy_path() -> None: | CODE |
| LOW | tests/unit/test_artifacts_helpers.py | 154 | def test_parse_data_table_skips_malformed_row_sections() -> None: | CODE |
| LOW⚡ | tests/unit/test_json_stdout_purity.py | 340 | def _customize_suggest_prompts(client: MagicMock) -> None: | CODE |
| LOW⚡ | tests/unit/test_json_stdout_purity.py | 349 | def _customize_suggest_next_steps(client: MagicMock) -> None: | CODE |
| LOW⚡ | tests/unit/test_json_stdout_purity.py | 355 | def _customize_artifact_choices(client: MagicMock) -> None: | CODE |
| LOW⚡ | tests/unit/test_json_stdout_purity.py | 1474 | def test_matched_partial_id_goes_to_stderr_in_json_mode(runner: CliRunner, mock_auth_env) -> None: | CODE |
| LOW | tests/unit/test_json_stdout_purity.py | 242 | async def wait_for_research_completion( | CODE |
| LOW | tests/unit/test_json_stdout_purity.py | 380 | def _customize_source_transfers(client: MagicMock) -> None: | CODE |
| LOW | tests/unit/test_json_stdout_purity.py | 398 | def _customize_share_view_level(client: MagicMock) -> None: | CODE |
| LOW | tests/unit/test_json_stdout_purity.py | 402 | def _customize_source_fulltext(client: MagicMock) -> None: | CODE |
| LOW | tests/unit/test_json_stdout_purity.py | 456 | def _customize_source_add_book(client: MagicMock) -> None: | CODE |
| LOW | tests/unit/test_json_stdout_purity.py | 462 | def _customize_source_add_research(client: MagicMock) -> None: | CODE |
| LOW | tests/unit/test_json_stdout_purity.py | 474 | def _customize_research_discover(client: MagicMock) -> None: | CODE |
| LOW | tests/unit/test_json_stdout_purity.py | 512 | def _customize_research_import(client: MagicMock) -> None: | CODE |
| LOW | tests/unit/test_json_stdout_purity.py | 538 | def _customize_research_cancel(client: MagicMock) -> None: | CODE |
| LOW | tests/unit/test_json_stdout_purity.py | 544 | def _customize_notebook_create(client: MagicMock) -> None: | CODE |
| LOW | tests/unit/test_json_stdout_purity.py | 968 | def test_json_mode_stdout_is_parseable( | CODE |
| LOW | tests/unit/test_json_stdout_purity.py | 1374 | def test_all_json_commands_have_sweep_entry() -> None: | CODE |
| LOW | tests/unit/test_json_stdout_purity.py | 1493 | def test_matched_partial_id_still_goes_to_stdout_in_human_mode( | CODE |
| LOW | tests/unit/test_client_keepalive.py | 69 | async def _read_storage_text_when_available(storage_path): | CODE |
| LOW | tests/unit/test_client_keepalive.py | 79 | async def _wait_until_storage_contains(storage_path, needle: str, failure_message: str) -> None: | CODE |
| LOW | tests/unit/test_client_keepalive.py | 101 | async def test_storage_wait_retries_extended_sharing_violations(monkeypatch): | CODE |
| LOW | tests/unit/test_client_keepalive.py | 123 | async def _wait_for_rotate_requests( | CODE |
| LOW | tests/unit/test_client_keepalive.py | 144 | async def test_keepalive_off_by_default(self, mock_auth, httpx_mock: HTTPXMock): | CODE |
| LOW | tests/unit/test_client_keepalive.py | 160 | async def test_spawns_task_on_enter_cancels_on_exit(self, mock_auth, httpx_mock: HTTPXMock): | CODE |
| LOW | tests/unit/test_client_keepalive.py | 188 | async def test_floor_clamps_low_interval(self, mock_auth): | CODE |
| LOW | tests/unit/test_client_keepalive.py | 198 | async def test_floor_does_not_lower_higher_interval(self, mock_auth): | CODE |
| LOW | tests/unit/test_client_keepalive.py | 220 | def test_rejects_non_positive_or_non_finite_keepalive(self, mock_auth, bad): | CODE |
| LOW | tests/unit/test_client_keepalive.py | 226 | def test_rejects_non_positive_or_non_finite_floor(self, mock_auth, bad): | CODE |
| LOW | tests/unit/test_client_keepalive.py | 259 | async def test_failure_does_not_crash_loop(self, mock_auth): | CODE |
| LOW | tests/unit/test_client_keepalive.py | 290 | async def test_persistence_failure_logs_warning_and_continues( | CODE |
| LOW | tests/unit/test_client_keepalive.py | 338 | async def test_explicit_storage_path_used_when_auth_lacks_one( | CODE |
| 16053 more matches not shown… | ||||
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| MEDIUM⚡ | tests/cassette_patterns.py | 747 | # ============================================================================= | COMMENT |
| MEDIUM⚡ | tests/cassette_patterns.py | 749 | # ============================================================================= | COMMENT |
| MEDIUM⚡ | tests/cassette_patterns.py | 756 | # ------------------------------------------------------------------------- | COMMENT |
| MEDIUM⚡ | tests/cassette_patterns.py | 758 | # ------------------------------------------------------------------------- | COMMENT |
| MEDIUM⚡ | tests/cassette_patterns.py | 783 | # ------------------------------------------------------------------------- | COMMENT |
| MEDIUM⚡ | tests/cassette_patterns.py | 785 | # ------------------------------------------------------------------------- | COMMENT |
| MEDIUM⚡ | tests/cassette_patterns.py | 792 | # ------------------------------------------------------------------------- | COMMENT |
| MEDIUM⚡ | tests/cassette_patterns.py | 794 | # ------------------------------------------------------------------------- | COMMENT |
| MEDIUM⚡ | tests/cassette_patterns.py | 802 | # ------------------------------------------------------------------------- | COMMENT |
| MEDIUM⚡ | tests/cassette_patterns.py | 804 | # ------------------------------------------------------------------------- | COMMENT |
| MEDIUM⚡ | tests/cassette_patterns.py | 811 | # ------------------------------------------------------------------------- | COMMENT |
| MEDIUM⚡ | tests/cassette_patterns.py | 813 | # ------------------------------------------------------------------------- | COMMENT |
| MEDIUM⚡ | tests/cassette_patterns.py | 913 | # ------------------------------------------------------------------------- | COMMENT |
| MEDIUM⚡ | tests/cassette_patterns.py | 915 | # ------------------------------------------------------------------------- | COMMENT |
| MEDIUM⚡ | tests/cassette_patterns.py | 925 | # ------------------------------------------------------------------------- | COMMENT |
| MEDIUM⚡ | tests/cassette_patterns.py | 927 | # ------------------------------------------------------------------------- | COMMENT |
| MEDIUM⚡ | tests/cassette_patterns.py | 945 | # ------------------------------------------------------------------------- | COMMENT |
| MEDIUM⚡ | tests/cassette_patterns.py | 947 | # ------------------------------------------------------------------------- | COMMENT |
| MEDIUM⚡ | tests/cassette_patterns.py | 952 | # ------------------------------------------------------------------------- | COMMENT |
| MEDIUM⚡ | tests/cassette_patterns.py | 954 | # ------------------------------------------------------------------------- | COMMENT |
| MEDIUM⚡ | tests/cassette_patterns.py | 1307 | # ============================================================================= | COMMENT |
| MEDIUM⚡ | tests/cassette_patterns.py | 1309 | # ============================================================================= | COMMENT |
| MEDIUM⚡ | tests/cassette_patterns.py | 1312 | # --------------------------------------------------------------------------- | COMMENT |
| MEDIUM | tests/cassette_patterns.py | 137 | # ============================================================================= | COMMENT |
| MEDIUM | tests/cassette_patterns.py | 139 | # ============================================================================= | COMMENT |
| MEDIUM | tests/cassette_patterns.py | 255 | # ============================================================================= | COMMENT |
| MEDIUM | tests/cassette_patterns.py | 257 | # ============================================================================= | COMMENT |
| MEDIUM | tests/cassette_patterns.py | 308 | # ============================================================================= | COMMENT |
| MEDIUM | tests/cassette_patterns.py | 310 | # ============================================================================= | COMMENT |
| MEDIUM | tests/cassette_patterns.py | 324 | # ============================================================================= | COMMENT |
| MEDIUM | tests/cassette_patterns.py | 326 | # ============================================================================= | COMMENT |
| MEDIUM | tests/cassette_patterns.py | 369 | # ============================================================================= | COMMENT |
| MEDIUM | tests/cassette_patterns.py | 371 | # ============================================================================= | COMMENT |
| MEDIUM | tests/cassette_patterns.py | 417 | # ============================================================================= | COMMENT |
| MEDIUM | tests/cassette_patterns.py | 419 | # ============================================================================= | COMMENT |
| MEDIUM | tests/cassette_patterns.py | 544 | # ============================================================================= | COMMENT |
| MEDIUM | tests/cassette_patterns.py | 546 | # ============================================================================= | COMMENT |
| MEDIUM | tests/cassette_patterns.py | 827 | # ------------------------------------------------------------------------- | COMMENT |
| MEDIUM | tests/cassette_patterns.py | 829 | # ------------------------------------------------------------------------- | COMMENT |
| MEDIUM | tests/cassette_patterns.py | 854 | # ------------------------------------------------------------------------- | COMMENT |
| MEDIUM | tests/cassette_patterns.py | 856 | # ------------------------------------------------------------------------- | COMMENT |
| MEDIUM | tests/cassette_patterns.py | 894 | # ------------------------------------------------------------------------- | COMMENT |
| MEDIUM | tests/cassette_patterns.py | 896 | # ------------------------------------------------------------------------- | COMMENT |
| MEDIUM | tests/cassette_patterns.py | 967 | # ------------------------------------------------------------------------- | COMMENT |
| MEDIUM | tests/cassette_patterns.py | 969 | # ------------------------------------------------------------------------- | COMMENT |
| MEDIUM | tests/cassette_patterns.py | 991 | # ------------------------------------------------------------------------- | COMMENT |
| MEDIUM | tests/cassette_patterns.py | 993 | # ------------------------------------------------------------------------- | COMMENT |
| MEDIUM | tests/cassette_patterns.py | 1006 | # ============================================================================= | COMMENT |
| MEDIUM | tests/cassette_patterns.py | 1008 | # ============================================================================= | COMMENT |
| MEDIUM | tests/cassette_patterns.py | 1641 | # ============================================================================= | COMMENT |
| MEDIUM | tests/cassette_patterns.py | 1643 | # ============================================================================= | COMMENT |
| MEDIUM | tests/vcr_config.py | 319 | # ============================================================================= | COMMENT |
| MEDIUM | tests/vcr_config.py | 321 | # ============================================================================= | COMMENT |
| MEDIUM | tests/vcr_config.py | 823 | # ============================================================================= | COMMENT |
| MEDIUM | tests/vcr_config.py | 825 | # ============================================================================= | COMMENT |
| MEDIUM⚡ | tests/unit/test_artifacts_helpers.py | 25 | # --------------------------------------------------------------------------- | COMMENT |
| MEDIUM⚡ | tests/unit/test_artifacts_helpers.py | 27 | # --------------------------------------------------------------------------- | COMMENT |
| MEDIUM⚡ | tests/unit/test_artifacts_helpers.py | 46 | # --------------------------------------------------------------------------- | COMMENT |
| MEDIUM⚡ | tests/unit/test_artifacts_helpers.py | 48 | # --------------------------------------------------------------------------- | COMMENT |
| MEDIUM⚡ | tests/unit/test_artifacts_helpers.py | 78 | # --------------------------------------------------------------------------- | COMMENT |
| 2736 more matches not shown… | ||||
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW | hatch_build.py | 21 | CODE | |
| LOW | desktop-extension/run_server.py | 24 | CODE | |
| LOW | tests/cassette_patterns.py | 131 | CODE | |
| LOW | tests/_helpers/android_grpc_harness.py | 20 | CODE | |
| LOW | tests/_helpers/android_grpc_normalizers.py | 11 | CODE | |
| LOW | tests/_helpers/android_notes.py | 3 | CODE | |
| LOW | tests/_helpers/android_supervisor.py | 3 | CODE | |
| LOW | tests/_helpers/play_book_http_cassette.py | 3 | CODE | |
| LOW | tests/_helpers/_v080_history.py | 7 | CODE | |
| LOW | tests/_helpers/android_phenotype_http_cassette.py | 10 | CODE | |
| LOW | tests/_helpers/android_grpc_cassette.py | 17 | CODE | |
| LOW | tests/_helpers/client_factory.py | 3 | CODE | |
| LOW | tests/_helpers/source_delete.py | 3 | CODE | |
| LOW | tests/unit/test_artifacts_helpers.py | 12 | CODE | |
| LOW | tests/unit/test_json_stdout_purity.py | 19 | CODE | |
| LOW | tests/unit/test_refresh_lock_registry.py | 20 | CODE | |
| LOW | tests/unit/test_from_storage_dual_protocol.py | 18 | CODE | |
| LOW | tests/unit/test_curl_cffi_transport_poc.py | 14 | CODE | |
| LOW | tests/unit/test_firefox_containers.py | 12 | CODE | |
| LOW | tests/unit/test_auth_patch_survivor_policy.py | 1 | CODE | |
| LOW | tests/unit/test_storage_writer.py | 12 | CODE | |
| LOW | tests/unit/test_vcr_scrubbing.py | 31 | CODE | |
| LOW | tests/unit/test_auth_refresh_profile_store.py | 3 | CODE | |
| LOW | tests/unit/test_chat_session_control.py | 3 | CODE | |
| LOW | tests/unit/test_play_books.py | 9 | CODE | |
| LOW | tests/unit/test_play_book_http_cassette.py | 3 | CODE | |
| LOW | tests/unit/test_auth_coverage_allowance_policy.py | 1 | CODE | |
| LOW | tests/unit/test_collection_exceptions.py | 3 | CODE | |
| LOW | tests/unit/test_auth_instance_invariant.py | 3 | CODE | |
| LOW | tests/unit/test_collections_api.py | 3 | CODE | |
| LOW | tests/unit/test_android_fault_cleanup.py | 3 | CODE | |
| LOW | tests/unit/test_auth_session_master_token.py | 3 | CODE | |
| LOW | tests/unit/test_vcr_config.py | 20 | CODE | |
| LOW | tests/unit/test_source_upload_coverage.py | 10 | CODE | |
| LOW | tests/unit/test_operation_context.py | 3 | CODE | |
| LOW | tests/unit/test_auth_master_token.py | 7 | CODE | |
| LOW | tests/unit/test_ci_account_pool_workflows.py | 3 | CODE | |
| LOW | tests/unit/test_tier_enforcement_hook.py | 41 | CODE | |
| LOW | tests/unit/test_auth_refresh_retry.py | 12 | CODE | |
| LOW | tests/unit/test_android_fault_scenarios.py | 3 | CODE | |
| LOW | tests/unit/test_deploy_compose_default.py | 10 | CODE | |
| LOW | tests/unit/test_auth_lock_path_derivation.py | 28 | CODE | |
| LOW | tests/unit/test_live_auth_matrix.py | 15 | CODE | |
| LOW | tests/unit/test_serving.py | 9 | CODE | |
| LOW | tests/unit/test_streaming_chat_wire.py | 3 | CODE | |
| LOW | tests/unit/test_streaming_chat_wire.py | 1033 | CODE | |
| LOW | tests/unit/test_get_or_none.py | 15 | CODE | |
| LOW | tests/unit/test_audit_auth_import_graph.py | 3 | CODE | |
| LOW | tests/unit/test_browser_capture_cdp_arm.py | 25 | CODE | |
| LOW | tests/unit/test_concurrency_refresh_race.py | 60 | CODE | |
| LOW | tests/unit/test_fault_cohort_cleanup.py | 3 | CODE | |
| LOW | tests/unit/test_middleware_chain_host.py | 28 | CODE | |
| LOW | tests/unit/test_auth_cold_start_recovery.py | 3 | CODE | |
| LOW | tests/unit/test_artifact_completeness.py | 3 | CODE | |
| LOW | tests/unit/test_capture_rpc_registry.py | 8 | CODE | |
| LOW | tests/unit/test_generation_state.py | 15 | CODE | |
| LOW | tests/unit/test_research_row_adapter.py | 15 | CODE | |
| LOW | tests/unit/test_auth_credential_io.py | 3 | CODE | |
| LOW | tests/unit/test_with_client_handle_errors.py | 20 | CODE | |
| LOW | tests/unit/test_curl_fault_cleanup.py | 3 | CODE | |
| 2257 more matches not shown… | ||||
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| HIGH | tests/cassette_patterns.py | 874 | r'("SCRUBBED_EMAIL@example\.com","","(?:[^"\\]|\\.)*",0,0,null,"",1,")' | CODE |
| HIGH | tests/vcr_config.py | 709 | # Streaming-chat envelope: [null, "<inner_json>"]. | COMMENT |
| HIGH | tests/vcr_config.py | 634 | 1. **Streaming-chat envelope** ``[null, "<inner_json>"]`` where the inner | STRING |
| HIGH | tests/vcr_config.py | 640 | 2. **Batchexecute envelope** ``[[[rpc_id, args_json, null, "generic"]]]`` | STRING |
| HIGH | tests/unit/test_vcr_config.py | 98 | JSON envelope is ``[null, "<inner_json>"]`` and ``<inner_json>`` is itself a | STRING |
| HIGH⚡ | tests/unit/test_check_rpc_health.py | 1063 | return ")]}'\n\n" + f'[["wrb.fr","{_CHOICES_ID}",{inner},null,null,null,"generic"]]' | CODE |
| HIGH⚡ | tests/unit/test_check_rpc_health.py | 1221 | body = ")]}'\n\n" + f'[["wrb.fr","{_CHOICES_ID}",null,null,null,[3],"generic"]]' | CODE |
| HIGH⚡ | tests/unit/test_check_rpc_health.py | 1235 | body = ")]}'\n\n" + '[["wrb.fr","zzzzzz","[[]]",null,null,null,"generic"]]' | CODE |
| HIGH⚡ | tests/unit/test_decoder.py | 1286 | payload = f'[["wrb.fr","{self.RPC_ID}",null,null,null,{deep}]]' | CODE |
| HIGH⚡ | tests/unit/test_decoder.py | 1294 | payload = f'[["wrb.fr","{self.RPC_ID}",null,null,null,{deep}]]' | CODE |
| HIGH | tests/unit/test_decoder.py | 893 | """``[5, null, 'x']`` is the same google.rpc.Status at a longer arity. | STRING |
| HIGH⚡ | tests/unit/test_sources_row_adapter.py | 862 | # 402x [null, 2] — no Drive-status slot | COMMENT |
| HIGH⚡ | tests/unit/test_sources_row_adapter.py | 863 | # 4x [null, 2, null, 3] — Drive-backed, ACTIVE | COMMENT |
| HIGH⚡ | tests/unit/test_sources_row_adapter.py | 864 | # 3x [null, 2, [null,null,null,[]]] — a populated settings[2], no [3] | COMMENT |
| HIGH⚡ | tests/unit/test_sources_row_adapter.py | 692 | """A live-shaped web-page row (``metadata[0]`` null, URL at ``[7]``) yields None. | STRING |
| HIGH⚡ | tests/unit/test_sources_row_adapter.py | 879 | """settings ``[null, 2, null, 3]`` — the only populated shape seen live.""" | STRING |
| HIGH⚡ | tests/unit/test_sources_row_adapter.py | 887 | """settings ``[null, 2]`` — 402 of 409 live rows. No Drive claim at all.""" | STRING |
| HIGH⚡ | tests/unit/test_sources_row_adapter.py | 894 | """settings ``[null, 2, [null,null,null,[]]]`` — 3 of 409 live rows. | STRING |
| HIGH⚡ | tests/unit/test_collection_params.py | 93 | # Owner capture: [ [null,null,null,[[nbid]]], [] ] with the type-3 tail. | COMMENT |
| HIGH | tests/unit/test_api_coverage.py | 151 | # Real API returns 3 levels of nesting: [[[null, [summary], [[keywords]], []]]] | COMMENT |
| HIGH | tests/unit/test_api_coverage.py | 188 | # Response format: [[[title, description, null, null, prompt, audience_level], ...]] | COMMENT |
| HIGH⚡ | tests/unit/test_api_coverage.py | 317 | # Verify reference payload: [null, ["source_id"], [2]] | COMMENT |
| HIGH⚡ | tests/unit/test_api_coverage.py | 333 | # Verify reference payload: [null, ["source_id"], [2]] | COMMENT |
| HIGH | tests/unit/test_authed_post_pipeline.py | 1717 | decoded_payload = b')]}\'\n\n[["wrb.fr",null,"[1]",null,null,null,"generic"]]' | CODE |
| HIGH | tests/unit/test_select_artifact.py | 276 | ever emits ``[null, ...]`` at index 15 the sort must coerce that | STRING |
| HIGH | tests/unit/test_auth_cookie_save_race.py | 1067 | f"None-valued cookie must never be persisted as value:null, got: {stored}" | CODE |
| HIGH | tests/unit/test_save_chat_as_note_encoder.py | 136 | # passage[3] = [[null, start, end]]; passage[5] = [[[passage_id], source_id]]; | COMMENT |
| HIGH | tests/unit/test_save_chat_as_note_encoder.py | 232 | assert "[0,0,0,null,null,null,null,0,0]" in actual_json | CODE |
| HIGH | tests/unit/test_browser_oauth_token.py | 495 | page.evaluate("url => history.replaceState(null, '', url)", consent_url) | CODE |
| HIGH⚡ | tests/unit/test_user_settings_api.py | 145 | # GET_USER_SETTINGS inner: [[null,[..limits..],[true,null,null,true,["fr"]], | COMMENT |
| HIGH⚡ | tests/unit/test_user_settings_api.py | 147 | # SET_USER_SETTINGS inner: [null,[..limits..],[true,null,null,true,["en"]], | COMMENT |
| HIGH | tests/unit/test_rate_limit_retry.py | 48 | resp.text = ")]}'\n[null,[" + str(payload).replace("'", '"') + "]]" | CODE |
| HIGH | tests/unit/test_rescrub_cassettes_script.py | 87 | '0,0,null,"",1,"SCRUBBED_NAME","SCRUBBED_AVATAR_URL"]]' | CODE |
| HIGH | tests/unit/test_rescrub_cassettes_script.py | 96 | f'[["wrb.fr","JFMDGd","[[null,[\\"{avatar_url}\\"]]]",null,null,null,"generic"]]' | CODE |
| HIGH | tests/unit/test_research_api.py | 919 | # Live shape for the Drive corpus: ``[null, null, null, null, 1]`` plus | COMMENT |
| HIGH | tests/unit/test_scrub_rpc_har.py | 59 | freq = json.dumps([[["CCqFvf", '["t",null,null,[2],[1]]', None, "generic"]]]) | CODE |
| HIGH | tests/unit/test_scrub_rpc_har.py | 146 | freq = json.dumps([[["CCqFvf", '["t",null,null,[2],[1]]', None, "generic"]]]) | CODE |
| HIGH | tests/unit/test_mutation_null_status.py | 418 | null), ``SHARE_NOTEBOOK`` / ``SHARE_ARTIFACT`` / | STRING |
| HIGH⚡ | tests/unit/test_rpc_overrides.py | 246 | '{"LIST_NOTEBOOKS": null, "CREATE_NOTEBOOK": "valid"}', | CODE |
| HIGH | tests/unit/test_cassette_patterns.py | 983 | '[["SCRUBBED_EMAIL@example.com","","opaque",0,0,null,"",1,' | CODE |
| HIGH | tests/unit/test_cassette_patterns.py | 1002 | '0,0,null,"",1,"SCRUBBED_NAME","SCRUBBED_AVATAR_URL"]]' | CODE |
| HIGH | tests/unit/test_ci_test_matrix.py | 406 | assert checkout["with"]["ref"] == "${{ inputs.custom_branch || github.ref }}" | CODE |
| HIGH | tests/unit/test_ci_test_matrix.py | 625 | "ref": "${{ inputs.custom_branch || github.sha }}", | CODE |
| HIGH⚡ | tests/unit/test_vcr_body_matcher.py | 117 | """Build a streaming-chat ``f.req`` form body (`[null, "<inner_json>"]`).""" | STRING |
| HIGH⚡ | tests/unit/test_vcr_body_matcher.py | 208 | fixtures: the cassette has a trailing ``[null, null]`` while the live | STRING |
| HIGH | tests/unit/test_vcr_body_matcher.py | 106 | is ``[[[rpc_id, "<args_json>", null, "generic"]]]`` and ``<args_json>`` | STRING |
| HIGH | tests/unit/test_vcr_body_matcher.py | 394 | The outer ``[[[rpc, "...", null, "generic"]]]`` shape parses cleanly, | STRING |
| HIGH⚡ | tests/unit/test_chat_row_adapter.py | 402 | # ``[None]`` (leading slot present but null) yields ``None`` — the | COMMENT |
| HIGH | tests/unit/test_source_selection.py | 1060 | # Response format: [[[title, description, null, null, prompt, audience_level], ...]] | COMMENT |
| HIGH | tests/unit/mcp/test_profile_files.py | 114 | if (message.method === 'tools/call') calls.push(message.params); | CODE |
| HIGH | tests/unit/mcp/test_profile_files.py | 119 | callTool: async (name, args) => calls.push({name, arguments: args}) | CODE |
| HIGH⚡ | tests/unit/mcp/test_sources.py | 314 | # ``status: Literal[...] | None`` serializes as an ``anyOf`` of {enum} + {null}. | COMMENT |
| HIGH⚡ | tests/unit/mcp/test_sources.py | 2240 | {"source": null} as success — it projects NOT_FOUND.""" | STRING |
| HIGH⚡ | tests/unit/mcp/test_uploadwidget.py | 80 | assert "uploadUrls[i]=null;confirmUpload(tok)" in _WIDGET_HTML | CODE |
| HIGH⚡ | tests/unit/mcp/test_uploadwidget.py | 106 | callTool: async (name, args) => { confirms.push({name, args}); } | CODE |
| HIGH⚡ | tests/unit/mcp/test_uploadwidget.py | 113 | headers: {get: () => null}, text: async () => "transient or recovered"}; | CODE |
| HIGH⚡ | tests/unit/mcp/test_uploadwidget.py | 117 | headers: {get: name => name === 'X-NotebookLM-Upload-Status' ? 'unconfirmed' : null}, | CODE |
| HIGH | tests/unit/cli/test_usage.py | 84 | """JSON keeps precision, zero versus null, enum names, and reset offsets.""" | STRING |
| HIGH | tests/unit/cli/test_note.py | 578 | CLI emitted ``{"id": null, "created": false, "error": "Creation may | STRING |
| HIGH | tests/unit/cli/test_playwright_login_render_contract.py | 760 | " 2. Or run: notebooklm auth logout && notebooklm login\n" | CODE |
| 79 more matches not shown… | ||||
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| HIGH | tests/vcr_config.py | 173 | except UnicodeDecodeError: | CODE |
| HIGH | tests/vcr_config.py | 275 | except UnicodeDecodeError: | CODE |
| HIGH | tests/vcr_config.py | 440 | except UnicodeDecodeError: | CODE |
| HIGH | tests/vcr_config.py | 425 | except UnicodeDecodeError: | CODE |
| HIGH | tests/_helpers/android_grpc_cassette.py | 659 | except FileNotFoundError: | CODE |
| HIGH | tests/unit/test_client_keepalive.py | 88 | except PermissionError: | CODE |
| HIGH | tests/unit/test_refresh_lock_registry.py | 379 | except threading.BrokenBarrierError: | CODE |
| HIGH | tests/unit/test_curl_cffi_transport_poc.py | 59 | except (BrokenPipeError, ConnectionResetError): | CODE |
| HIGH | tests/unit/test_operation_context.py | 186 | except asyncio.CancelledError: | CODE |
| HIGH | tests/unit/test_operation_context.py | 208 | except asyncio.CancelledError: | CODE |
| HIGH | tests/unit/test_web_asset_lifecycle.py | 331 | except asyncio.CancelledError: | CODE |
| HIGH | tests/unit/test_web_asset_lifecycle.py | 384 | except asyncio.CancelledError: | CODE |
| HIGH | tests/unit/test_web_asset_lifecycle.py | 372 | except asyncio.CancelledError: | CODE |
| HIGH | tests/unit/test_polling_registry.py | 52 | except asyncio.CancelledError: | CODE |
| HIGH | tests/unit/test_session_close.py | 59 | except asyncio.CancelledError: | CODE |
| HIGH | tests/unit/test_auth_cold_recovery_coordinator.py | 446 | except RuntimeError: | CODE |
| HIGH | tests/unit/app/test_source_fetch.py | 248 | except (BrokenPipeError, ConnectionResetError): | CODE |
| HIGH | tests/unit/concurrency/test_close_cancellation_leak.py | 370 | except Exception: | CODE |
| HIGH | tests/integration/conftest.py | 395 | except ImportError: | CODE |
| HIGH | tests/integration/conftest.py | 401 | except ImportError: | CODE |
| HIGH | tests/integration/test_chat_oversized_rejection_vcr.py | 144 | except Exception: # noqa: BLE001 — best-effort scratch cleanup | CODE |
| HIGH | tests/integration/cli_vcr/conftest.py | 172 | except json.JSONDecodeError: | CODE |
| HIGH | tests/integration/cli_vcr/conftest.py | 184 | except json.JSONDecodeError: | CODE |
| HIGH | tests/integration/cli_vcr/test_auth.py | 103 | except (OSError, NotImplementedError): | CODE |
| HIGH | tests/integration/cli_vcr/test_doctor.py | 63 | except (OSError, NotImplementedError): | CODE |
| HIGH | …ntegration/concurrency/test_aexit_exception_masking.py | 155 | except asyncio.CancelledError: | CODE |
| HIGH | tests/integration/concurrency/test_helpers.py | 227 | except asyncio.CancelledError: | CODE |
| HIGH | tests/integration/concurrency/helpers.py | 265 | except BaseException: # noqa: BLE001 — cleanup must not propagate | CODE |
| HIGH | tests/e2e/conftest.py | 30 | except ImportError: | CODE |
| HIGH | tests/e2e/conftest.py | 1186 | except Exception: | CODE |
| HIGH | tests/e2e/conftest.py | 1199 | except Exception: | CODE |
| HIGH | tests/e2e/conftest.py | 1442 | except Exception: | CODE |
| HIGH | tests/e2e/conftest.py | 887 | except OSError: | CODE |
| HIGH | tests/e2e/conftest.py | 1219 | except Exception: | CODE |
| HIGH | tests/e2e/conftest.py | 1350 | except Exception: | CODE |
| HIGH | tests/e2e/conftest.py | 1184 | except Exception: | CODE |
| HIGH | tests/e2e/conftest.py | 1440 | except Exception: | CODE |
| HIGH | tests/e2e/conftest.py | 1197 | except Exception: | CODE |
| HIGH | tests/e2e/_collection_candidate.py | 123 | except Exception: | CODE |
| HIGH | tests/e2e/_generation_journal.py | 175 | except OSError: | CODE |
| HIGH | examples/notes.py | 141 | except json.JSONDecodeError: | CODE |
| HIGH | scripts/_ci_progress.py | 30 | except OSError: | CODE |
| HIGH | scripts/decode_mobile_grpc.py | 94 | except ValueError: | CODE |
| HIGH | scripts/_ci_e2e_notebooks.py | 526 | except FileNotFoundError: | CODE |
| HIGH | scripts/_ci_e2e_notebooks.py | 439 | except FileNotFoundError: | CODE |
| HIGH | scripts/materialize_ci_auth.py | 133 | except FileNotFoundError: | CODE |
| HIGH | scripts/materialize_ci_auth.py | 106 | except FileNotFoundError: | CODE |
| HIGH | scripts/audit_public_api_compat.py | 593 | except json.JSONDecodeError: | CODE |
| HIGH | scripts/manage_ci_e2e_notebooks.py | 1301 | except Exception: | CODE |
| HIGH | scripts/audit_backend_coupling.py | 163 | except TypeError: | CODE |
| HIGH | scripts/audit_backend_coupling.py | 174 | except AttributeError: | CODE |
| HIGH | scripts/live_auth_matrix.py | 225 | except (OSError, subprocess.TimeoutExpired): | CODE |
| HIGH | scripts/live_auth_matrix.py | 230 | except ProcessLookupError: | CODE |
| HIGH | scripts/live_auth_matrix.py | 892 | except ProcessLookupError: | CODE |
| HIGH | scripts/stress_fault_server.py | 460 | except (OSError, TypeError, ValueError): | CODE |
| HIGH | src/notebooklm/_curl_cffi_transport.py | 210 | except Exception: # noqa: BLE001 — cleanup must not mask the original error | CODE |
| HIGH | src/notebooklm/notebooklm_cli.py | 68 | except (AttributeError, OSError, TypeError, ValueError): | CODE |
| HIGH | src/notebooklm/migration.py | 206 | except FileNotFoundError: | CODE |
| HIGH | src/notebooklm/_android/auth.py | 159 | except BaseException: | CODE |
| HIGH | src/notebooklm/_android/upload.py | 526 | except BaseException: | CODE |
| 41 more matches not shown… | ||||
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW | tests/_helpers/android_grpc_harness.py | 385 | __all__ = [ | CODE |
| LOW | tests/_helpers/android_grpc_normalizers.py | 40 | __all__ = ["REQUEST_NONCE_FIELDS", "normalize_request"] | CODE |
| LOW | tests/_helpers/android_notes.py | 90 | __all__ = ["StatefulAndroidNotesTransport"] | CODE |
| LOW | tests/_helpers/android_supervisor.py | 80 | __all__ = ["SupervisedAndroidTransport"] | CODE |
| LOW | tests/_helpers/play_book_http_cassette.py | 65 | def _set_content_length(headers: Any, length: int) -> None: | CODE |
| LOW | tests/_helpers/play_book_http_cassette.py | 161 | __all__ = ["PlayBookHttpCassetteScrubber", "SYNTHETIC_BOOK_ROWS"] | CODE |
| LOW | tests/_helpers/android_phenotype_http_cassette.py | 35 | def _set_content_length(headers: Any, length: int) -> None: | CODE |
| LOW | tests/_helpers/android_phenotype_http_cassette.py | 189 | __all__ = ["PhenotypeHttpPost", "build_phenotype_http_post"] | CODE |
| LOW | tests/_helpers/android_grpc_cassette.py | 1054 | __all__ = [ | CODE |
| LOW⚡ | tests/unit/test_json_stdout_purity.py | 581 | def _setup_fs_doctor(tmp_path: Path, monkeypatch: pytest.MonkeyPatch) -> None: | CODE |
| LOW | tests/unit/test_json_stdout_purity.py | 623 | def _setup_fs_profile_list(tmp_path: Path, monkeypatch: pytest.MonkeyPatch) -> None: | CODE |
| LOW | tests/unit/test_auth_refresh_profile_store.py | 99 | def _set_live(live: httpx.Cookies, name: str, value: str) -> None: | CODE |
| LOW | tests/unit/test_auth_cookie_save_race.py | 108 | def _set_cookie_value(jar: httpx.Cookies, name: str, value) -> None: | CODE |
| LOW | tests/unit/test_client_lifecycle_waves.py | 43 | def set_bound_loop(self, loop: asyncio.AbstractEventLoop) -> None: | CODE |
| LOW | tests/unit/test_client_lifecycle_waves.py | 94 | def set_bound_loop(self, loop: asyncio.AbstractEventLoop) -> None: | CODE |
| LOW | tests/unit/test_runtime_lifecycle.py | 35 | def set_bound_loop(self, loop: asyncio.AbstractEventLoop) -> None: | CODE |
| LOW | tests/unit/test_runtime_lifecycle.py | 68 | def set_bound_loop(self, loop: asyncio.AbstractEventLoop) -> None: | CODE |
| LOW | tests/unit/test_lazy_web_sidecar.py | 42 | def set_bound_loop(self, loop: asyncio.AbstractEventLoop) -> None: | CODE |
| LOW | tests/unit/mcp/conftest.py | 156 | __all__ = ["AsyncMock"] # re-exported for convenience in tool tests | CODE |
| LOW | tests/unit/mcp/test_entrypoint.py | 59 | def _set_oauth_env(monkeypatch: pytest.MonkeyPatch) -> None: | CODE |
| LOW | tests/unit/cli/test_cli_mcp_parity.py | 220 | def _setup(c: Any) -> None: | CODE |
| LOW | tests/unit/cli/test_cli_mcp_parity.py | 235 | def _setup(c: Any) -> None: | CODE |
| LOW | tests/_baselines/registry.py | 522 | __all__ = [ | CODE |
| LOW | tests/_baselines/storage_transaction_policy.py | 72 | __all__ = [ | CODE |
| LOW | tests/_baselines/__init__.py | 20 | __all__ = ["BASELINES", "Baseline"] | CODE |
| LOW | tests/_baselines/module_size.py | 152 | __all__ = [ | CODE |
| LOW | tests/_baselines/guardrail_literals.py | 79 | __all__ = [ | CODE |
| LOW | tests/_guardrails/_v100_breaks.py | 210 | __all__ = [ | CODE |
| LOW⚡ | tests/_guardrails/test_cookie_persistence_boundary.py | 574 | def _set_local_client(self, name: str, value: bool) -> None: | CODE |
| LOW⚡ | tests/integration/test_android_grpc_cassette.py | 321 | async def _settle(seconds: float) -> None: | CODE |
| LOW | tests/integration/test_transfer_rpcs_vcr.py | 56 | async def _settle(seconds: float) -> None: | CODE |
| LOW | tests/integration/cli_vcr/_cassette_expectations.py | 304 | __all__ = [ | CODE |
| LOW | tests/integration/cli_vcr/conftest.py | 59 | __all__ = [ | CODE |
| LOW | tests/integration/cli_vcr/_fixtures.py | 87 | __all__ = [ | CODE |
| LOW⚡ | tests/integration/concurrency/conftest.py | 58 | logger = logging.getLogger(__name__) | CODE |
| LOW | tests/integration/concurrency/conftest.py | 210 | def set_delay(self, seconds: float) -> None: | CODE |
| LOW | tests/integration/concurrency/test_chat_history_race.py | 170 | def set_answer(self, question: str, answer: str) -> None: | CODE |
| LOW | tests/integration/concurrency/helpers.py | 47 | logger = logging.getLogger(__name__) | CODE |
| LOW | tests/integration/mcp_vcr/conftest.py | 42 | __all__ = ["build_mcp_client", "build_zero_retry_mcp_client"] | CODE |
| LOW | tests/server/fakes.py | 344 | async def set_mode(self, notebook_id: str, mode: Any) -> None: | CODE |
| LOW | tests/server/fakes.py | 830 | def set_research_failed(self, notebook_id: str, poll_id: str, *, query: str = "q") -> None: | CODE |
| LOW | tests/_fixtures/rpc_error_frames.py | 18 | __all__ = [ | CODE |
| LOW | tests/_fixtures/chain.py | 122 | __all__ = [ | CODE |
| LOW | tests/_fixtures/__init__.py | 23 | __all__ = [ | CODE |
| LOW | tests/_fault_server/grpc.py | 470 | __all__ = [ | CODE |
| LOW | tests/_fault_server/web.py | 157 | __all__ = [ | CODE |
| LOW | tests/_fault_server/android_scenarios.py | 756 | __all__ = ["SCENARIOS", "run_scenario"] | CODE |
| LOW | tests/_fault_server/web_workflows.py | 589 | __all__ = ["SCENARIOS", "run_scenario"] | CODE |
| LOW | tests/_fault_server/adapter_scenarios.py | 643 | __all__ = ["SCENARIOS", "run_scenario"] | CODE |
| LOW | tests/_fault_server/web_resilience_scenarios.py | 858 | __all__ = ["BUDGETS", "IMPLEMENTATIONS", "PLANS", "REQUIRED_CHECKS", "SCENARIOS"] | CODE |
| LOW | tests/_fault_server/android.py | 168 | __all__ = [ | CODE |
| LOW | tests/_fault_server/http.py | 712 | __all__ = [ | CODE |
| LOW | tests/_fault_server/web_concurrency.py | 438 | __all__ = ["BUDGETS", "IMPLEMENTATIONS", "PLANS", "REQUIRED_CHECKS"] | CODE |
| LOW | tests/_fault_server/web_generation_faults.py | 345 | __all__ = ["BUDGETS", "IMPLEMENTATIONS", "REQUIRED_CHECKS", "SCENARIOS"] | CODE |
| LOW | tests/_fault_server/android_resilience_scenarios.py | 173 | __all__ = ["IMPLEMENTATIONS", "PLANS", "SCENARIOS"] | CODE |
| LOW | tests/_fault_server/web_scenarios.py | 808 | __all__ = ["SCENARIOS", "run_scenario"] | CODE |
| LOW | tests/e2e/_collection_candidate.py | 243 | __all__ = ["created_collection_candidate"] | CODE |
| LOW | scripts/_tracked_files.py | 29 | __all__ = ["tracked_files"] | CODE |
| LOW | scripts/_live_auth_scenarios/__init__.py | 48 | __all__ = [ | CODE |
| LOW | src/notebooklm/_sharing.py | 11 | logger = logging.getLogger(__name__) | CODE |
| 376 more matches not shown… | ||||
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| HIGH | tests/cassette_patterns.py | 155 | Re-derive ``<count>`` prefixes in a chunked response body. Google's batchexecute responses are framed as alternatin | STRING |
| HIGH | tests/cassette_patterns.py | 1694 | Return a ``(status_code, body, headers)`` triple for a synthetic error. The shape is intentionally minimal; the cli | STRING |
| HIGH | src/notebooklm/_sharing.py | 48 | Share notebook with a user. Intent wrapper over :meth:`set_users`. The underlying operation is an upser | STRING |
| HIGH | src/notebooklm/_notes.py | 65 | Get a specific note by ID. Args: notebook_id: The notebook ID. note_id: The note ID. | STRING |
| HIGH | src/notebooklm/paths.py | 225 | Get directory for a specific profile. Args: profile: Profile name. If None, resolves via resolve_profile(). | STRING |
| HIGH | src/notebooklm/client.py | 710 | Create a client from Playwright storage state file. This is the recommended way to create a client for programm | STRING |
| HIGH | src/notebooklm/client.py | 904 | Refresh the selected backend's authentication state. Web refreshes the NotebookLM homepage to obtain a fresh CS | STRING |
| HIGH | src/notebooklm/_chat.py | 309 | Ask the notebook a question. Args: notebook_id: The notebook ID. question: The question | STRING |
| HIGH | src/notebooklm/_chat.py | 667 | Save a chat answer as a citation-rich note (issue #660). Unlike :meth:`NotesAPI.create`, this preserves the ``[ | STRING |
| HIGH | src/notebooklm/_chat.py | 794 | Read the notebook's current chat configuration. Decodes the chat-settings block from ``GET_NOTEBOOK`` so a *par | STRING |
| HIGH | src/notebooklm/_sources.py | 186 | Get details of a specific source. Args: notebook_id: The notebook ID. source_id: The so | STRING |
| HIGH | src/notebooklm/_sources.py | 241 | Wait for a source to become ready. Polls until READY, terminal ERROR, or timeout. Configured transient | STRING |
| HIGH | src/notebooklm/_sources.py | 331 | Wait for a source to be registered server-side (status >= PROCESSING). Polls until the source is visible in the | STRING |
| HIGH | src/notebooklm/_sources.py | 382 | Wait for multiple sources to become ready in parallel. Args: notebook_id: The notebook ID. | STRING |
| HIGH | src/notebooklm/_sources.py | 516 | Add a file source using the backend's resumable upload pipeline. Registers the source, opens an upload session, | STRING |
| HIGH | src/notebooklm/utils.py | 159 | Return the surrounding source-text passage for a chat citation. A :class:`~notebooklm.types.ChatReference` carries | STRING |
| HIGH | src/notebooklm/_lookup.py | 28 | Return ``obj`` unchanged, or raise ``exc`` when ``obj`` is ``None``. The narrow contract is deliberate: callers pas | STRING |
| HIGH | src/notebooklm/artifacts.py | 84 | Run an artifact-generation callable with rate-limit retry. The callable is always invoked at least once. A retry is | STRING |
| HIGH | src/notebooklm/_mind_maps_api.py | 243 | Rename a mind map (dispatches by kind: ``UPDATE_NOTE`` / ``RENAME_ARTIFACT``). Omitting ``kind`` triggers an ex | STRING |
| HIGH | src/notebooklm/_types/documents.py | 817 | A readable flat rendering of the document, or of one range of it. The third of this library's three renderings | STRING |
| HIGH | src/notebooklm/_auth/cookies.py | 182 | Extract Google cookies from Playwright storage state for NotebookLM auth. Filters through the canonical auth-domain | STRING |
| HIGH | src/notebooklm/_auth/cookies.py | 375 | Load cookies as an httpx.Cookies object for authenticated downloads. Unlike load_auth_from_storage() which returns | STRING |
| HIGH | src/notebooklm/_auth/cookies.py | 415 | Extract Google cookies from storage state preserving original identity. Returns a path-aware ``(name, domain, path) | STRING |
| HIGH | src/notebooklm/_auth/cookies.py | 507 | Build an httpx.Cookies jar with original domains preserved. This function loads cookies from storage and creates a | STRING |
| HIGH | src/notebooklm/_auth/tokens.py | 290 | Return the ``Cookie:`` header this session would send to ``url``. .. deprecated:: 0.8.1 Scheduled fo | STRING |
| HIGH | src/notebooklm/_auth/tokens.py | 462 | Create AuthTokens from Playwright storage state file. Compatibility loader for callers that still need a standa | STRING |
| HIGH | src/notebooklm/_auth/tokens.py | 866 | Load Google cookies from storage as a flat name→value dict. Loads authentication cookies with the following precede | STRING |
| HIGH | src/notebooklm/_auth/extraction.py | 87 | Extract a ``WIZ_global_data[key]`` value from a NotebookLM HTML response. NotebookLM (and other Google products) em | STRING |
| HIGH | src/notebooklm/_auth/extraction.py | 447 | Extract CSRF token (SNlM0e) from NotebookLM page HTML. The CSRF token is embedded in the page's WIZ_global_dat | STRING |
| HIGH | src/notebooklm/_auth/extraction.py | 490 | Extract session ID (FdrFJe) from NotebookLM page HTML. The session ID is embedded in the page's WIZ_global_dat | STRING |
| HIGH | src/notebooklm/_auth/refresh.py | 971 | Internal: fetch CSRF and session tokens using a pre-built cookie jar. This is the single implementation for all tok | STRING |
| HIGH | src/notebooklm/_auth/refresh.py | 1077 | Fetch tokens from a cookie mapping. For backward compatibility. Prefer NotebookLMClient.from_storage(), which prese | STRING |
| HIGH | src/notebooklm/_auth/refresh.py | 1184 | Validate the auth cookies on disk without any side effects. Performs the same token-fetch round-trip (a homepage GE | STRING |
| HIGH | src/notebooklm/_auth/account.py | 112 | Enumerate Google accounts visible to the given cookie jar. Probes ``<configured base URL>/?authuser=N`` (see :f | STRING |
| HIGH | src/notebooklm/mcp/_resolve.py | 280 | Resolve a notebook reference (full/partial id, exact title, or unique title prefix) to its id. Args: client | STRING |
| HIGH | src/notebooklm/mcp/_resolve.py | 308 | Resolve a source reference within a notebook to its id. Args: client: The lifespan-bound client. no | STRING |
| HIGH | src/notebooklm/mcp/_resolve.py | 339 | Resolve many source references within a notebook, listing sources at most once. The per-tool callers ``chat_ask`` / | STRING |
| HIGH | src/notebooklm/mcp/_resolve.py | 439 | Resolve a note reference within a notebook to its id. Same matching rules as :func:`resolve_source`, over the noteb | STRING |
| HIGH | src/notebooklm/mcp/_resolve.py | 470 | Resolve a studio-artifact reference within a notebook to its id. Same matching rules as :func:`resolve_source`, ove | STRING |
| HIGH | src/notebooklm/cli/resolve.py | 44 | Validate and normalize an entity ID. Args: entity_id: The ID to validate. entity_name: Name for err | STRING |
| HIGH | src/notebooklm/cli/resolve.py | 127 | Get notebook ID from argument, env var, or active context. Resolution order (env-var precedence): 1. ``noteboo | STRING |
| HIGH | src/notebooklm/cli/resolve.py | 214 | Resolve a partial ID against a **pre-fetched** item list. Sync core of the partial-ID matching logic. Encapsulates | STRING |
| HIGH | src/notebooklm/cli/resolve.py | 346 | Resolve a case-insensitive partial ID prefix to a full entity ID. Allows users to type partial IDs like ``abc`` ins | STRING |
| HIGH | src/notebooklm/cli/_firefox_containers.py | 231 | Resolve a ``--browser-cookies 'firefox::<spec>'`` to a selector. Args: profile_path: Firefox profile direct | STRING |
| HIGH | src/notebooklm/cli/_firefox_containers.py | 420 | Read ``cookies.sqlite`` filtered to a single container. Args: profile_path: Firefox profile directory conta | STRING |
| HIGH | src/notebooklm/cli/_chromium_profiles.py | 316 | Read and decrypt cookies from a single Chromium user-data profile. Uses ``rookie_cookies.any_browser(db_path, domai | STRING |
| HIGH | src/notebooklm/cli/download_helpers.py | 34 | Resolve a partial artifact ID to a full ID. UUID-shaped IDs (canonical 8-4-4-4-12 hex layout, case-insensitive - | STRING |
| HIGH | src/notebooklm/cli/auth_runtime.py | 84 | Get auth components from context. Args: ctx: Click context with optional storage_path in obj Returns: | STRING |
| HIGH | src/notebooklm/cli/input.py | 11 | Read all of stdin as UTF-8 text and strip surrounding whitespace. Centralizes the Unix ``-`` stdin convention used | STRING |
| HIGH | src/notebooklm/cli/input.py | 44 | Resolve prompt text from a positional argument or ``--prompt-file``. Exactly one source may be provided. The file/s | STRING |
| HIGH | src/notebooklm/cli/services/login/cookie_jar.py | 81 | Probe ``?authuser=N`` against one cookie set and return tagged Accounts. Shared by both the legacy single-jar path | STRING |
| HIGH | src/notebooklm/cli/services/login/profile_targets.py | 46 | Derive a valid profile name from an email address. Profile names are restricted to ``[a-zA-Z0-9_-]`` (see :data | STRING |
| HIGH | src/notebooklm/_web/sharing.py | 318 | Set several users' permissions on a notebook in one request. This is an **upsert**, not an add: an email that i | STRING |
| HIGH | src/notebooklm/_web/research.py | 211 | Start a research session. Args: notebook_id: The notebook ID. query: The research query | STRING |
| HIGH | src/notebooklm/_web/research.py | 321 | Discover web sources synchronously (the "Discover sources" dialog call). One blocking ``DISCOVER_SOURCES`` roun | STRING |
| HIGH | src/notebooklm/_web/notes.py | 628 | Get a specific note by ID. Args: notebook_id: The notebook ID. note_id: The note ID. | STRING |
| HIGH | src/notebooklm/_web/notebooks.py | 432 | Get AI-suggested prompts for a notebook. Backed by ``GeneratePromptSuggestions`` (``otmP3b``): a *general* | STRING |
| HIGH | src/notebooklm/_web/notebooks.py | 732 | Get notebook details. Args: notebook_id: The notebook ID. Returns: Notebook ob | STRING |
| HIGH | src/notebooklm/_web/transport/reqid_counter.py | 173 | Atomically increment the counter and return the new value. Args: step: Increment applied to the cou | STRING |
| HIGH | src/notebooklm/_web/wire/decoder.py | 295 | Parse chunked response format (rt=c mode). Format is alternating lines of: - byte_count (integer) - js | STRING |
| 15 more matches not shown… | ||||
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW | tests/cassette_patterns.py | 596 | CODE | |
| LOW | tests/vcr_config.py | 627 | CODE | |
| LOW | tests/vcr_config.py | 679 | CODE | |
| LOW | tests/_helpers/play_book_http_cassette.py | 94 | CODE | |
| LOW | tests/_helpers/android_grpc_cassette.py | 334 | CODE | |
| LOW | tests/unit/test_live_auth_matrix.py | 1043 | CODE | |
| LOW | tests/unit/test_streaming_chat_wire.py | 1006 | CODE | |
| LOW | tests/unit/test_concurrency_refresh_race.py | 501 | CODE | |
| LOW | tests/unit/test_auth_cold_start_recovery.py | 620 | CODE | |
| LOW | tests/unit/test_auth_profile_store_minted.py | 723 | CODE | |
| LOW | tests/unit/test_auth_psidts_recovery.py | 433 | CODE | |
| LOW | tests/unit/test_app_master_token.py | 573 | CODE | |
| LOW | tests/unit/test_sources_row_adapter.py | 80 | CODE | |
| LOW | tests/unit/test_browser_oauth_token.py | 460 | CODE | |
| LOW | tests/unit/test_auth_mint_service.py | 146 | CODE | |
| LOW | tests/unit/test_init_order.py | 171 | CODE | |
| LOW | tests/unit/test_browser_capture_session_candidate.py | 566 | CODE | |
| LOW | tests/unit/test_browser_capture_session_candidate.py | 582 | CODE | |
| LOW | tests/unit/test_rpc_types.py | 67 | CODE | |
| LOW | tests/unit/test_historical_split.py | 38 | CODE | |
| LOW | tests/unit/test_rpc_overrides.py | 72 | CODE | |
| LOW | tests/unit/test_auth_remaining_branches.py | 521 | CODE | |
| LOW | tests/unit/test_auth_expired_errors.py | 61 | CODE | |
| LOW | tests/unit/test_ci_test_matrix.py | 85 | CODE | |
| LOW | tests/unit/test_ci_test_matrix.py | 272 | CODE | |
| LOW | tests/unit/test_ci_selection_contracts.py | 48 | CODE | |
| LOW | tests/unit/test_ci_selection_contracts.py | 136 | CODE | |
| LOW | tests/unit/app/test_source_fallback.py | 162 | CODE | |
| LOW | tests/unit/app/test_source_fallback.py | 275 | CODE | |
| LOW | tests/unit/app/test_app_login_cookie.py | 371 | CODE | |
| LOW | tests/unit/cli/test_quiet_enforcement.py | 99 | CODE | |
| LOW | tests/unit/android/test_organization_adapters.py | 170 | CODE | |
| LOW | tests/_baselines/storage_transaction_policy.py | 17 | CODE | |
| LOW | tests/_baselines/module_size.py | 108 | CODE | |
| LOW | tests/_baselines/guardrail_literals.py | 54 | CODE | |
| LOW | tests/_guardrails/test_middleware_context_contract.py | 99 | CODE | |
| LOW | …drails/test_auth_web_bootstrap_compatibility_island.py | 110 | CODE | |
| LOW | …drails/test_auth_web_bootstrap_compatibility_island.py | 193 | CODE | |
| LOW | tests/_guardrails/test_auth_phase12c_boundaries.py | 253 | CODE | |
| LOW | tests/_guardrails/test_auth_storage_lock_boundary.py | 116 | CODE | |
| LOW | tests/_guardrails/test_auth_cookie_filter_boundary.py | 91 | CODE | |
| LOW | tests/_guardrails/test_auth_cookie_filter_boundary.py | 139 | CODE | |
| LOW | tests/_guardrails/test_no_session.py | 60 | CODE | |
| LOW | tests/_guardrails/test_auth_credential_io_boundary.py | 114 | CODE | |
| LOW | tests/_guardrails/test_cli_boundary.py | 199 | CODE | |
| LOW | tests/_guardrails/test_cli_boundary.py | 230 | CODE | |
| LOW | tests/_guardrails/test_cli_boundary.py | 263 | CODE | |
| LOW | tests/_guardrails/test_cli_boundary.py | 364 | CODE | |
| LOW | tests/_guardrails/test_cli_boundary.py | 470 | CODE | |
| LOW | tests/_guardrails/test_cli_boundary.py | 586 | CODE | |
| LOW | tests/_guardrails/test_auth_profile_store_boundary.py | 482 | CODE | |
| LOW | tests/_guardrails/test_auth_profile_store_boundary.py | 942 | CODE | |
| LOW | tests/_guardrails/test_auth_profile_store_boundary.py | 992 | CODE | |
| LOW | tests/_guardrails/test_auth_profile_store_boundary.py | 2295 | CODE | |
| LOW | tests/_guardrails/test_auth_profile_store_boundary.py | 294 | CODE | |
| LOW | tests/_guardrails/test_auth_profile_store_boundary.py | 1067 | CODE | |
| LOW | tests/_guardrails/test_auth_profile_store_boundary.py | 1418 | CODE | |
| LOW | tests/_guardrails/test_auth_profile_store_boundary.py | 1455 | CODE | |
| LOW | tests/_guardrails/test_auth_storage_compatibility.py | 77 | CODE | |
| LOW | tests/_guardrails/test_auth_storage_compatibility.py | 1253 | CODE | |
| 348 more matches not shown… | ||||
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW | .pre-commit-config.yaml | 21 | # | COMMENT |
| LOW | pyproject.toml | 41 | Issues = "https://github.com/teng-lin/notebooklm-py/issues" | COMMENT |
| LOW | README.md | 221 | COMMENT | |
| LOW | deploy/README.md | 21 | # 1. One-time, on a machine with a browser — bootstrap the Google credential: | COMMENT |
| LOW | deploy/docker-compose.build.yml | 1 | # Override: build the notebooklm-mcp image from THIS checkout instead of pulling | COMMENT |
| LOW | deploy/docker-compose.yml | 1 | # Remote notebooklm-mcp behind a tunnel. Pick ONE tunnel via a Compose profile: | COMMENT |
| LOW | deploy/docker-compose.yml | 21 | # out of the box once a stable release exists. Pin a specific release with | COMMENT |
| LOW | deploy/docker-compose.yml | 41 | # Optional self-hosted OAuth (for claude.ai). Unset → bearer-only; set both | COMMENT |
| LOW | deploy/docker-compose.yml | 61 | # `${FASTMCP_STATELESS_HTTP:-}` injects an EMPTY string when unset, and FastMCP's pydantic | COMMENT |
| LOW | deploy/docker-compose.yml | 101 | # `:-` not `:?` — Compose interpolates the WHOLE file before profile filtering, | COMMENT |
| LOW | tests/cassette_patterns.py | 221 | remainder = body | COMMENT |
| LOW | tests/cassette_patterns.py | 361 | # The display-name escaped-literal scrubber reuses the existing | COMMENT |
| LOW | tests/cassette_patterns.py | 421 | _EMAIL_PATTERN_BASE = ( | COMMENT |
| LOW | tests/cassette_patterns.py | 461 | # Each entry is regex-escaped because some legitimate UI titles could in | COMMENT |
| LOW | tests/cassette_patterns.py | 481 | # Anchoring strategy per shape: | COMMENT |
| LOW | tests/cassette_patterns.py | 501 | r"aas_et/[A-Za-z0-9_\-]+", | COMMENT |
| LOW | tests/cassette_patterns.py | 541 | ) | COMMENT |
| LOW | tests/cassette_patterns.py | 561 | # | COMMENT |
| LOW | tests/cassette_patterns.py | 741 | # scrubber and detector both registry-derived closes that drift. | COMMENT |
| LOW | tests/cassette_patterns.py | 761 | # on the allowlist (the ``LSID`` leak class), inside a response/request | COMMENT |
| LOW | tests/cassette_patterns.py | 781 | # which does not itself re-match (idempotent). | COMMENT |
| LOW | tests/cassette_patterns.py | 821 | # was missing from this list, so its value round-tripped unscrubbed into the | COMMENT |
| LOW | tests/cassette_patterns.py | 841 | # Double-encoded ``authuser%3D<email>`` form (issue #1368). When the | COMMENT |
| LOW | tests/cassette_patterns.py | 941 | ), | COMMENT |
| LOW | tests/cassette_patterns.py | 961 | r"\1SCRUBBED_DRIVE_FILE_ID\2", | COMMENT |
| LOW | tests/cassette_patterns.py | 981 | # The pattern requires the LITERAL escaped quotes (``\\"`` in regex, | COMMENT |
| LOW | tests/cassette_patterns.py | 1041 | # RUN inside arbitrary text. A cookie header is a ``;``-delimited run of | COMMENT |
| LOW | tests/cassette_patterns.py | 1161 | # Standalone upload_id query parameter: value must be SCRUBBED_UPLOAD_ID. | COMMENT |
| LOW | tests/cassette_patterns.py | 1181 | ) | COMMENT |
| LOW | tests/cassette_patterns.py | 1221 | # avatar URL detector (/ogw/ group). The pattern matches | COMMENT |
| LOW | tests/cassette_patterns.py | 1241 | # closes the ``JrWMbf`` gap. | COMMENT |
| LOW | tests/cassette_patterns.py | 1261 | # ``authuser%3D<email>`` redirect-param shape (issue #1368). Unlike the | COMMENT |
| LOW | tests/cassette_patterns.py | 1301 | ("Google API key", _DETECT_GOOGLE_API_KEY), | COMMENT |
| LOW | tests/cassette_patterns.py | 1321 | # field whose API key the name-anchored scrubbers skipped), and #1372 fixed a | COMMENT |
| LOW | tests/cassette_patterns.py | 1341 | # quoted high-entropy scalar (a credential split across structural punctuation, | COMMENT |
| LOW | tests/cassette_patterns.py | 1361 | # * the canonical UUID shape (``8-4-4-4-12`` hex-with-dashes) — these are | COMMENT |
| LOW | tests/cassette_patterns.py | 1601 | COMMENT | |
| LOW | tests/cassette_patterns.py | 1621 | # --- 9. Google API-key shape (field-name-agnostic) --------------------- | COMMENT |
| LOW | tests/cassette_patterns.py | 1641 | # ============================================================================= | COMMENT |
| LOW | tests/vcr_config.py | 361 | # matcher's intent is to catch **structural** drift (different RPC id, different | COMMENT |
| LOW | tests/vcr_config.py | 781 | COMMENT | |
| LOW | tests/vcr_config.py | 801 | if len(c1) >= 5: | COMMENT |
| LOW | tests/vcr_config.py | 821 | COMMENT | |
| LOW | tests/vcr_config.py | 861 | # Register custom matcher for rpcids-based request differentiation | COMMENT |
| LOW | tests/unit/test_vcr_config.py | 381 | # | COMMENT |
| LOW | tests/unit/conftest.py | 41 | """ | COMMENT |
| LOW | tests/unit/conftest.py | 61 | # wrapper's ``aiter_bytes`` + rebuild path works on it. Returning a | COMMENT |
| LOW | tests/unit/test_check_rpc_health.py | 861 | # stringifies to "" and must surface as the class name, not be swallowed. | COMMENT |
| LOW | tests/unit/test_check_rpc_health.py | 1281 | assert rc == 0 | COMMENT |
| LOW | tests/unit/test_public_api_behavior.py | 81 | # --------------------------------------------------------------------------- | COMMENT |
| LOW | tests/unit/test_cassette_sanitizer.py | 721 | if line.strip() and not line.strip().startswith("#") | COMMENT |
| LOW | tests/unit/test_cassette_sanitizer.py | 741 | # With all cassette repairs landed, this loop has nothing to assert; | COMMENT |
| LOW | tests/unit/test_exceptions.py | 341 | with pytest.raises(SourceError): | COMMENT |
| LOW | tests/unit/test_artifact_downloads_coverage.py | 561 | # out to the temp-file cleanup, keeping the assertion on the original | COMMENT |
| LOW | tests/unit/test_auth_cookie_save_race.py | 1761 | # rather than monkeypatching ``notebooklm._core.save_cookies_to_storage``. | COMMENT |
| LOW | tests/unit/test_auth_cookie_save_race.py | 1781 | if len(submitted) == 2: | COMMENT |
| LOW | tests/unit/test_user_settings_api.py | 141 | # --------------------------------------------------------------------------- | COMMENT |
| LOW | tests/unit/test_scripts_auth_cookie_domains.py | 401 | # Everything above pins the *auth* path. The three probe request paths -- two | COMMENT |
| LOW | tests/unit/test_atomic_update_json.py | 421 | COMMENT | |
| LOW | tests/unit/test_rpc_health_coverage.py | 61 | # --------------------------------------------------------------------------- | COMMENT |
| 357 more matches not shown… | ||||
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| HIGH | tests/unit/test_auth_cookie_policy.py | 0 | tests for auth token refresh and fetch_tokens (split in d1 pr-2). this file owns one concern from the auth subpackage. t | STRING |
| HIGH | tests/unit/test_auth_storage.py | 0 | tests for auth token refresh and fetch_tokens (split in d1 pr-2). this file owns one concern from the auth subpackage. t | STRING |
| HIGH | tests/unit/test_auth_refresh.py | 0 | tests for auth token refresh and fetch_tokens (split in d1 pr-2). this file owns one concern from the auth subpackage. t | STRING |
| HIGH | tests/unit/cli/test_artifact.py | 0 | path a: uuid-shaped id skips partial-resolve; backend none → exit 1. | STRING |
| HIGH | tests/unit/cli/test_source.py | 0 | path a: uuid-shaped id skips partial-resolve; backend none → exit 1. | STRING |
| HIGH | tests/unit/cli/test_note.py | 0 | path a: uuid-shaped id skips partial-resolve; backend none → exit 1. | STRING |
| HIGH | tests/unit/cli/test_artifact.py | 0 | path a under ``--json``: typed json error doc + exit 1. | STRING |
| HIGH | tests/unit/cli/test_source.py | 0 | path a under ``--json``: typed json error doc + exit 1. | STRING |
| HIGH | tests/unit/cli/test_note.py | 0 | path a under ``--json``: typed json error doc + exit 1. | STRING |
| HIGH | tests/unit/cli/test_artifact.py | 0 | path b: partial-resolve succeeds, backend get() returns none → exit 1. | STRING |
| HIGH | tests/unit/cli/test_source.py | 0 | path b: partial-resolve succeeds, backend get() returns none → exit 1. | STRING |
| HIGH | tests/unit/cli/test_note.py | 0 | path b: partial-resolve succeeds, backend get() returns none → exit 1. | STRING |
| HIGH | tests/unit/android/test_source_writes.py | 0 | declare unowned child scheduling for direct transport tests. | STRING |
| HIGH | tests/unit/android/test_source_search.py | 0 | declare unowned child scheduling for direct transport tests. | STRING |
| HIGH | tests/unit/android/test_notebook_mutations.py | 0 | declare unowned child scheduling for direct transport tests. | STRING |
| HIGH | tests/unit/android/test_source_commit_paths.py | 0 | declare unowned child scheduling for direct transport tests. | STRING |
| HIGH | tests/_guardrails/test_server_classify_consistency.py | 0 | exactly one exemplar per category, so the parametrization is exhaustive. | STRING |
| HIGH | tests/_guardrails/test_mcp_classify_consistency.py | 0 | exactly one exemplar per category, so the parametrization is exhaustive. | STRING |
| HIGH | …_guardrails/test_classify_error_handler_consistency.py | 0 | exactly one exemplar per category, so the parametrization is exhaustive. | STRING |
| HIGH | …ts/integration/test_artifact_generation_idempotency.py | 0 | open a real lifecycle generation, then install the mock transport. | STRING |
| HIGH | tests/integration/test_research_idempotency.py | 0 | open a real lifecycle generation, then install the mock transport. | STRING |
| HIGH | tests/integration/test_side_effects_idempotency.py | 0 | open a real lifecycle generation, then install the mock transport. | STRING |
| HIGH | tests/integration/test_notes_idempotency.py | 0 | open a real lifecycle generation, then install the mock transport. | STRING |
| HIGH | …ts/integration/test_artifact_generation_idempotency.py | 0 | extract the ``rpcids=`` query param from a batchexecute request url. | STRING |
| HIGH | tests/integration/test_research_idempotency.py | 0 | extract the ``rpcids=`` query param from a batchexecute request url. | STRING |
| HIGH | tests/integration/test_side_effects_idempotency.py | 0 | extract the ``rpcids=`` query param from a batchexecute request url. | STRING |
| HIGH | tests/integration/test_notes_idempotency.py | 0 | extract the ``rpcids=`` query param from a batchexecute request url. | STRING |
| HIGH | …sts/integration/concurrency/test_note_create_cancel.py | 0 | extract the ``rpcids=`` query param from a batchexecute request url. | STRING |
| HIGH | tests/integration/test_settings_integration.py | 0 | integration tests for sharingapi. moved from ``tests/unit/`` to ``tests/integration/``. mock-backed (``pytest_httpx``); | STRING |
| HIGH | tests/integration/test_notes_integration.py | 0 | integration tests for sharingapi. moved from ``tests/unit/`` to ``tests/integration/``. mock-backed (``pytest_httpx``); | STRING |
| HIGH | tests/integration/test_notebooks_integration.py | 0 | integration tests for sharingapi. moved from ``tests/unit/`` to ``tests/integration/``. mock-backed (``pytest_httpx``); | STRING |
| HIGH | tests/integration/test_sharing_integration.py | 0 | integration tests for sharingapi. moved from ``tests/unit/`` to ``tests/integration/``. mock-backed (``pytest_httpx``); | STRING |
| HIGH | tests/integration/test_chat_delete_conversation_vcr.py | 0 | decode the form-encoded ``f.req`` body into its param list. | STRING |
| HIGH | tests/integration/test_notebooks_suggest_prompts_vcr.py | 0 | decode the form-encoded ``f.req`` body into its param list. | STRING |
| HIGH | tests/integration/test_research_discover_vcr.py | 0 | decode the form-encoded ``f.req`` body into its param list. | STRING |
| HIGH | tests/integration/test_research_cancel_vcr.py | 0 | decode the form-encoded ``f.req`` body into its param list. | STRING |
| HIGH | tests/integration/test_chat_delete_conversation_vcr.py | 0 | delete the scratch notebook. best-effort — failures are logged, not raised. | STRING |
| HIGH | tests/integration/test_research_discover_vcr.py | 0 | delete the scratch notebook. best-effort — failures are logged, not raised. | STRING |
| HIGH | tests/integration/test_research_cancel_vcr.py | 0 | delete the scratch notebook. best-effort — failures are logged, not raised. | STRING |
| HIGH | tests/integration/cli_vcr/test_generate.py | 0 | cli integration tests for note commands. these tests exercise the full cli → client → rpc path using vcr cassettes. | STRING |
| HIGH | tests/integration/cli_vcr/test_downloads.py | 0 | cli integration tests for note commands. these tests exercise the full cli → client → rpc path using vcr cassettes. | STRING |
| HIGH | tests/integration/cli_vcr/test_notes.py | 0 | cli integration tests for note commands. these tests exercise the full cli → client → rpc path using vcr cassettes. | STRING |
| HIGH | …ipts/_live_auth_scenarios/sibling_concurrent_reload.py | 0 | entry point for ``python -m`` execution by the live-auth matrix. | STRING |
| HIGH | scripts/_live_auth_scenarios/rest_recovery.py | 0 | entry point for ``python -m`` execution by the live-auth matrix. | STRING |
| HIGH | scripts/_live_auth_scenarios/mcp_recovery.py | 0 | entry point for ``python -m`` execution by the live-auth matrix. | STRING |
| HIGH | scripts/_live_auth_scenarios/browser_refresh.py | 0 | entry point for ``python -m`` execution by the live-auth matrix. | STRING |
| HIGH | scripts/_live_auth_scenarios/master_token_recovery.py | 0 | entry point for ``python -m`` execution by the live-auth matrix. | STRING |
| HIGH | src/notebooklm/_sharing.py | 0 | return the backend's scope for one multi-call workflow. | STRING |
| HIGH | src/notebooklm/_research.py | 0 | return the backend's scope for one multi-call workflow. | STRING |
| HIGH | src/notebooklm/_notes.py | 0 | return the backend's scope for one multi-call workflow. | STRING |
| HIGH | src/notebooklm/_chat.py | 0 | return the backend's scope for one multi-call workflow. | STRING |
| HIGH | src/notebooklm/_sources.py | 0 | return the backend's scope for one multi-call workflow. | STRING |
| HIGH | src/notebooklm/_settings.py | 0 | return the backend's scope for one multi-call workflow. | STRING |
| HIGH | src/notebooklm/_notebooks.py | 0 | return the backend's scope for one multi-call workflow. | STRING |
| HIGH | src/notebooklm/_collections.py | 0 | return the backend's scope for one multi-call workflow. | STRING |
| HIGH | src/notebooklm/_artifacts.py | 0 | return the backend's scope for one multi-call workflow. | STRING |
| HIGH | src/notebooklm/_mind_maps_api.py | 0 | return the backend's scope for one multi-call workflow. | STRING |
| HIGH | src/notebooklm/_labels.py | 0 | return the backend's scope for one multi-call workflow. | STRING |
| HIGH | src/notebooklm/_web/artifacts.py | 0 | return the backend's scope for one multi-call workflow. | STRING |
| HIGH | src/notebooklm/_artifacts.py | 0 | revise an individual slide in a completed slide deck using a prompt. | STRING |
| 8 more matches not shown… | ||||
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW | tests/conftest.py | 417 | except Exception: | CODE |
| LOW | tests/conftest.py | 515 | except Exception: | CODE |
| LOW | tests/_helpers/android_grpc_harness.py | 186 | except Exception as cleanup_error: # noqa: BLE001 - reported, not hidden | CODE |
| LOW | tests/_helpers/android_grpc_cassette.py | 924 | except Exception as error: # noqa: BLE001 - diagnostics must never mask the mismatch | CODE |
| LOW | tests/unit/test_windows_compatibility.py | 312 | except Exception as e: | CODE |
| LOW | tests/unit/mcp/conftest.py | 96 | except Exception as exc: # noqa: BLE001 - scripted per-item outcome | CODE |
| LOW | tests/unit/cli/test_cli_mcp_parity.py | 182 | except Exception as exc: # noqa: BLE001 - caller classifies (see _mcp_capture) | CODE |
| LOW | tests/unit/concurrency/test_close_cancellation_leak.py | 370 | except Exception: | CODE |
| LOW | …sts/_guardrails/test_mcp_lazy_client_error_boundary.py | 221 | except Exception: | CODE |
| LOW | …sts/_guardrails/test_mcp_lazy_client_error_boundary.py | 233 | except Exception: | CODE |
| LOW | …sts/_guardrails/test_mcp_lazy_client_error_boundary.py | 245 | except Exception: | CODE |
| LOW | …sts/_guardrails/test_mcp_lazy_client_error_boundary.py | 257 | except Exception: | CODE |
| LOW | …sts/_guardrails/test_mcp_lazy_client_error_boundary.py | 268 | except Exception: | CODE |
| MEDIUM | …sts/_guardrails/test_mcp_lazy_client_error_boundary.py | 207 | def route(request): | CODE |
| MEDIUM | …sts/_guardrails/test_mcp_lazy_client_error_boundary.py | 230 | def route(request): | CODE |
| MEDIUM | …sts/_guardrails/test_mcp_lazy_client_error_boundary.py | 242 | def route(request): | CODE |
| MEDIUM | …sts/_guardrails/test_mcp_lazy_client_error_boundary.py | 254 | def route(request): | CODE |
| MEDIUM | …sts/_guardrails/test_mcp_lazy_client_error_boundary.py | 265 | def tool(ctx): | CODE |
| LOW | tests/_guardrails/test_storage_transaction_ratchet.py | 227 | except Exception: | STRING |
| LOW | tests/integration/test_android_grpc_cassette.py | 712 | except Exception as cleanup_error: # noqa: BLE001 - reported, not hidden | CODE |
| LOW | tests/integration/test_chat_delete_conversation_vcr.py | 139 | except Exception as exc: # noqa: BLE001 | CODE |
| LOW⚡ | tests/integration/test_chat_session_control_vcr.py | 94 | except Exception as exc: # noqa: BLE001 - best-effort live-record cleanup | CODE |
| LOW⚡ | tests/integration/test_chat_multi_source_vcr.py | 272 | except Exception as exc: # noqa: BLE001 — best-effort cleanup | CODE |
| LOW | tests/integration/test_chat_oversized_rejection_vcr.py | 144 | except Exception: # noqa: BLE001 — best-effort scratch cleanup | CODE |
| LOW | tests/integration/test_research_discover_vcr.py | 113 | except Exception as exc: # noqa: BLE001 | CODE |
| LOW | …sts/integration/test_curl_cffi_cassette_conformance.py | 66 | except Exception: | CODE |
| LOW | tests/integration/test_research_cancel_vcr.py | 152 | except Exception as exc: # noqa: BLE001 | CODE |
| LOW | tests/integration/concurrency/test_add_file_toctou.py | 235 | except Exception: # noqa: BLE001 — defensive | CODE |
| LOW | tests/server/fakes.py | 167 | except Exception as exc: # noqa: BLE001 - scripted per-item outcome | CODE |
| LOW | tests/scripts/setup-generation-notebook.py | 74 | except Exception as exc: # noqa: BLE001 — top-level CLI surface | CODE |
| LOW | tests/scripts/check_cassettes_clean.py | 254 | except Exception: # noqa: BLE001 - degrade to line-scan on any parse/read error | CODE |
| LOW | tests/_fault_server/web_protocol.py | 165 | except Exception as exc: | CODE |
| LOW | tests/_fault_server/web_workflows.py | 183 | except Exception as exc: # exact public class asserted below | CODE |
| LOW | tests/_fault_server/web_workflows.py | 270 | except Exception as exc: # exact contract asserted after cleanup | CODE |
| LOW | tests/_fault_server/web_workflows.py | 315 | except Exception as exc: # first operation remains settled after the later failure | CODE |
| LOW | tests/_fault_server/web_workflows.py | 356 | except Exception as exc: | CODE |
| LOW | tests/_fault_server/web_workflows.py | 416 | except Exception as exc: | CODE |
| LOW | tests/_fault_server/android_protocol.py | 86 | except Exception as exc: | CODE |
| LOW | tests/_fault_server/adapter_scenarios.py | 123 | except Exception: | CODE |
| LOW | tests/_fault_server/web_slow_responses.py | 151 | except Exception as exc: | CODE |
| LOW | tests/_fault_server/mcp_auth_startup_worker.py | 91 | except Exception as error: | CODE |
| MEDIUM | tests/_fault_server/mcp_auth_startup_worker.py | 38 | def observe() -> None: | CODE |
| LOW | tests/_fault_server/web_saturation.py | 161 | except Exception as exc: | CODE |
| LOW | tests/_fault_server/http.py | 559 | except Exception as exc: | CODE |
| LOW | tests/_fault_server/web_scenarios.py | 333 | except Exception as exc: | CODE |
| LOW | tests/_fault_server/web_scenarios.py | 362 | except Exception as exc: | CODE |
| LOW | tests/_fault_server/web_scenarios.py | 377 | except Exception as exc: | CODE |
| LOW | tests/_fault_server/web_scenarios.py | 392 | except Exception as exc: | CODE |
| LOW | tests/_fault_server/web_scenarios.py | 409 | except Exception as exc: | CODE |
| LOW | tests/_fault_server/web_scenarios.py | 519 | except Exception as exc: | CODE |
| LOW | tests/_fault_server/web_scenarios.py | 539 | except Exception as exc: | CODE |
| MEDIUM | tests/e2e/conftest.py | 153 | def _ask_with_skip(*args, **kwargs): | CODE |
| LOW⚡ | tests/e2e/conftest.py | 1043 | except Exception as e: | CODE |
| LOW⚡ | tests/e2e/conftest.py | 1104 | except Exception: | CODE |
| LOW⚡ | tests/e2e/conftest.py | 1219 | except Exception: | CODE |
| LOW⚡ | tests/e2e/conftest.py | 1228 | except Exception: | CODE |
| LOW⚡ | tests/e2e/conftest.py | 1306 | except Exception as e: | CODE |
| LOW⚡ | tests/e2e/conftest.py | 1332 | except Exception: | CODE |
| LOW⚡ | tests/e2e/conftest.py | 1350 | except Exception: | CODE |
| LOW⚡ | tests/e2e/conftest.py | 1509 | except Exception as e: | CODE |
| 203 more matches not shown… | ||||
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| CRITICAL | tests/unit/test_browser_capture_session_candidate.py | 1265 | browser.context.request.get.return_value.dispose.assert_called_once_with() | CODE |
| CRITICAL⚡ | tests/unit/mcp/test_studio.py | 1494 | assert mock_client.artifacts.download_quiz.await_args.kwargs.get("output_format") == "markdown" | CODE |
| CRITICAL | tests/unit/cli/test_generate.py | 865 | mock_client.mind_maps.generate.await_args.kwargs.get("instructions") | CODE |
| CRITICAL | tests/unit/cli/test_resolver_characterization.py | 400 | passed_conv_id = mock_client.chat.ask.await_args.kwargs.get("conversation_id") | CODE |
| CRITICAL⚡ | tests/unit/android/test_artifact_outputs.py | 377 | table = projection.table.document.body.content.add().table | CODE |
| CRITICAL⚡ | tests/unit/android/test_artifact_outputs.py | 408 | projection.table.document.body.content.add().table.table_rows.add() | CODE |
| CRITICAL⚡ | tests/unit/android/test_artifact_outputs.py | 428 | table = projection.table.document.body.content.add().table | CODE |
| CRITICAL | tests/unit/android/test_artifact_outputs.py | 441 | table = projection.table.document.body.content.add().table | CODE |
| CRITICAL | tests/unit/android/test_artifact_outputs.py | 455 | table = projection.table.document.body.content.add().table | CODE |
| CRITICAL⚡ | tests/unit/android/test_artifacts.py | 1587 | structural = raw.tailored_report.report_doc.body.content.add(start_index=0, end_index=12) | CODE |
| CRITICAL⚡ | tests/unit/android/test_artifacts.py | 1591 | bullet = raw.tailored_report.report_doc.body.content.add() | CODE |
| CRITICAL⚡ | tests/unit/android/test_artifacts.py | 1595 | rule = raw.tailored_report.report_doc.body.content.add() | CODE |
| CRITICAL⚡ | tests/unit/android/test_artifacts.py | 1597 | table = raw.tailored_report.report_doc.body.content.add().table | CODE |
| CRITICAL | tests/unit/android/test_artifacts.py | 1386 | table = projection.table.document.body.content.add().table | CODE |
| CRITICAL | tests/unit/android/test_artifacts.py | 1412 | table = projection.table.document.body.content.add().table | CODE |
| CRITICAL | tests/unit/android/test_artifacts.py | 1431 | table = projection.table.document.body.content.add().table | CODE |
| CRITICAL | tests/unit/android/test_artifacts.py | 1447 | table = projection.table.document.body.content.add().table | CODE |
| CRITICAL | tests/integration/test_vcr_example.py | 82 | # Simulate the request format from notebooklm._web.transport.executor.RpcExecutor.rpc_call() | COMMENT |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| MEDIUM | tests/unit/test_concurrency_refresh_race.py | 82 | # Test-side deadline for any single asyncio.Event in the race scaffolding. | COMMENT |
| MEDIUM | tests/unit/test_concurrency_refresh_race.py | 542 | # Build the same auth scaffold the unit conftest's ``make_core`` produces | COMMENT |
| MEDIUM⚡ | tests/unit/test_check_rpc_health.py | 710 | # The streamed-chat orchestration RPC has no obfuscated method ID to echo back | COMMENT |
| MEDIUM⚡ | tests/unit/test_drive_import.py | 458 | # DriveImportService — orchestration, cleanup, second defense | COMMENT |
| MEDIUM | tests/unit/test_audit_auth_patch_sites.py | 63 | # string-target patch — and it correctly trips both ADR-0007 guardrails | COMMENT |
| MEDIUM | tests/unit/test_rpc_health_coverage.py | 134 | # without re-introducing the whole skip-list scaffolding. | COMMENT |
| MEDIUM⚡ | tests/unit/test_chat_transport.py | 45 | # Test scaffolding | COMMENT |
| MEDIUM⚡ | tests/unit/app/test_app_source_clean.py | 249 | # prepare / skip / execute orchestration | COMMENT |
| MEDIUM | tests/_guardrails/test_cli_boundary.py | 378 | # facade or app orchestration, never ``_browser``. | COMMENT |
| MEDIUM | tests/_guardrails/_wire_contract.py | 52 | #: which lives in its own package rather than the ``orchestration.v1`` wire section. | COMMENT |
| MEDIUM | tests/_guardrails/_wire_contract.py | 69 | #: orchestration account envelope. | COMMENT |
| MEDIUM | tests/cassettes/web/cli_notebook_create.yaml | 2158 | SEO 2026:The Ultimate Roadmap to AI Agent Visibility - Karan Powar\\\",[null,3905,[1773505574,851569000],[\\\"0f | CODE |
| MEDIUM | tests/cassettes/web/cli_notebook_create.yaml | 2159 | SEO 2026:The Ultimate Roadmap to AI Agent Visibility - Karan Powar\\\",[null,3905,[1773505614,213638000],[\\\"10 | CODE |
| MEDIUM | tests/cassettes/web/sources_transfer_lifecycle.yaml | 2364 | Authorization (ID-JAG) - Descope Documentation\\\",[null,692,[1784352296,728922000],[\\\"00000000-0000-4000-8000 | CODE |
| MEDIUM | tests/cassettes/web/workflow_tracer_bullet.yaml | 2086 | SEO 2026:The Ultimate Roadmap to AI Agent Visibility - Karan Powar\\\",[null,3905,[1773505574,851569000],[\\\"0f | CODE |
| MEDIUM | tests/cassettes/web/workflow_tracer_bullet.yaml | 2087 | SEO 2026:The Ultimate Roadmap to AI Agent Visibility - Karan Powar\\\",[null,3905,[1773505614,213638000],[\\\"10 | CODE |
| MEDIUM | tests/cassettes/web/cli_notebook_list.yaml | 2158 | SEO 2026:The Ultimate Roadmap to AI Agent Visibility - Karan Powar\\\",[null,3905,[1773505574,851569000],[\\\"0f | CODE |
| MEDIUM | tests/cassettes/web/cli_notebook_list.yaml | 2159 | SEO 2026:The Ultimate Roadmap to AI Agent Visibility - Karan Powar\\\",[null,3905,[1773505614,213638000],[\\\"10 | CODE |
| MEDIUM | docs/architecture.md | 766 | #### Evidence and guardrails | COMMENT |
| MEDIUM | docs/architecture.md | 786 | [guardrail map](https://teng-lin.github.io/notebooklm-py/diagrams/22-testing-and-guardrails.html) | CODE |
| MEDIUM | docs/architecture.md | 1605 | The [testing and guardrails view](https://teng-lin.github.io/notebooklm-py/diagrams/22-testing-and-guardrails.html) maps | CODE |
| MEDIUM | docs/architecture.md | 2163 | │ ├── login_browser.py # Markup-free browser-login plan/orchestration: conflict validation, path preparation, | CODE |
| MEDIUM | docs/architecture.md | 2164 | │ ├── login_cookie.py # Click-free login/cookie-import operations: request validation, browser-jar probing, a | CODE |
| MEDIUM | docs/architecture.md | 2182 | │ ├── source_clean.py # Click-free `source clean` core: junk-source classification + batched-deletion orchest | CODE |
| MEDIUM | docs/architecture.md | 2372 | │ └── lifecycle.py # Root lifecycle waves + phased transport orchestration | CODE |
| MEDIUM | docs/architecture.md | 2415 | ├── _chat.py # Abstract ChatAPI + shared ask/configure/settings/turn-count orchestration over typed | CODE |
| MEDIUM | docs/development.md | 31 | the [testing/guardrails map](https://teng-lin.github.io/notebooklm-py/diagrams/22-testing-and-guardrails.html) | CODE |
| MEDIUM | docs/development.md | 67 | ├── _chat.py # Backend-neutral ChatAPI orchestration | CODE |
| MEDIUM | docs/adr/0013-composable-session-capabilities.md | 263 | - **C-Z. AST-based delegate-surface regression guard** *(historical)* — introduced by PR [#885](https://github.com/teng- | CODE |
| MEDIUM | docs/adr/0013-composable-session-capabilities.md | 263 | - **C-Z. AST-based delegate-surface regression guard** *(historical)* — introduced by PR [#885](https://github.com/teng- | CODE |
| MEDIUM | docs/adr/0014-feature-local-runtime-adapters.md | 231 | ### Rule 4 — `Session` retains only orchestration plus the documented middleware-chain seams | COMMENT |
| MEDIUM | docs/adr/0036-browser-acquisition-package.md | 1 | # ADR-0036: Browser acquisition package and neutral login orchestration | COMMENT |
| MEDIUM | docs/diagrams/README.md | 82 | | 22 | Test infrastructure | How do unit tests, guardrails, replay, real-loopback faults, and live tests fit into CI? | | CODE |
| MEDIUM⚡ | docs/diagrams/22-testing-and-guardrails.html | 4963 | <script id="archify-source-evidence-data" type="application/json">{"schemaVersion":1,"verified":true,"repository":{" | CODE |
| MEDIUM⚡ | docs/diagrams/22-testing-and-guardrails.html | 4963 | <script id="archify-source-evidence-data" type="application/json">{"schemaVersion":1,"verified":true,"repository":{" | CODE |
| MEDIUM | docs/android/proto-evidence-ledger.md | 351 | `#7`. The cumulative orchestration service admits all four Notes signatures. The generated | CODE |
| MEDIUM | docs/android/proto-evidence-ledger.md | 886 | | `orchestration.v1.UploadFileRequest` | `project_id #3`, `request_context #4`, `source_id #5`, `provenance #6` | exact | CODE |
| MEDIUM | scripts/check_rpc_health.py | 2298 | # Probe the streamed-chat orchestration RPC. It is not an | COMMENT |
| MEDIUM | src/notebooklm/_artifacts.py | 662 | # is used by first-party orchestration; routing legacy calls through | COMMENT |
| MEDIUM | src/notebooklm/_android/sharing.py | 28 | # through the orchestration service's generic project mutator -- see | COMMENT |
| MEDIUM | src/notebooklm/_web/params/notebooks.py | 85 | # what the backend RETURNS for each mode. ``5`` critique / ``6`` debate scaffolding / | COMMENT |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| MEDIUM | tests/cassette_patterns.py | 214 | # fixed number of characters) is robust to alternate-length prefixes if | COMMENT |
| MEDIUM | tests/vcr_config.py | 366 | # matcher robust across recording sessions while still failing on meaningful | COMMENT |
| MEDIUM | tests/vcr_config.py | 810 | # or extra non-volatile dict keys — while staying robust against leaf | COMMENT |
| MEDIUM⚡ | tests/unit/test_json_stdout_purity.py | 571 | # so the mock-client harness can't drive them. The parametrized sweep | COMMENT |
| MEDIUM | tests/unit/test_json_stdout_purity.py | 950 | # the mock-client harness. `notebook_create` goes through the standard | COMMENT |
| MEDIUM | tests/unit/test_json_stdout_purity.py | 980 | # harness — they read NOTEBOOKLM_HOME directly. Stage a clean layout | COMMENT |
| MEDIUM | tests/unit/test_auth_cookie_save_race.py | 1806 | # order) to stay robust across schedulers. | COMMENT |
| MEDIUM⚡ | tests/unit/test_row_adapters.py | 1367 | # TZ-robust: compare the round-tripped epoch, not a wall-time string. | COMMENT |
| MEDIUM⚡ | tests/unit/test_json_error_exit.py | 810 | # then invoke without the mock-client harness (these commands don't | COMMENT |
| MEDIUM | tests/unit/test_json_error_exit.py | 785 | # Filesystem-driven failure cases bypass the mock-client harness — they | COMMENT |
| MEDIUM | tests/unit/test_sources_upload_delegation.py | 55 | # parse bytecode. ``casefold()`` makes the suffix check robust on | COMMENT |
| MEDIUM | tests/unit/test_rpc_golden_payloads.py | 1359 | # Wiring those would require contorting the harness or adding production code | COMMENT |
| MEDIUM⚡ | tests/unit/test_vcr_body_matcher.py | 293 | # Volatile-key stripping — keep matching robust across recording timestamps | COMMENT |
| MEDIUM | tests/unit/cli/test_login.py | 373 | # rebuilding this harness. | COMMENT |
| MEDIUM | tests/_guardrails/test_no_pinned_cassette_values.py | 170 | # allow-listing the comparison methods) keeps the gate robust as new | COMMENT |
| MEDIUM | tests/integration/concurrency/test_harness_smoke.py | 50 | # concurrency-harness smoke tests against a mock transport; no | COMMENT |
| MEDIUM | tests/integration/concurrency/test_harness_smoke.py | 139 | # Peak in-flight was high — the harness is genuinely fanning out. | COMMENT |
| MEDIUM | …ts/integration/concurrency/test_max_concurrent_rpcs.py | 71 | # concurrency-harness tests against a mock transport; no HTTP, | COMMENT |
| MEDIUM | …ts/integration/concurrency/test_max_concurrent_rpcs.py | 156 | # Anything <= 8 would mean the gate isn't kicking in (the harness | COMMENT |
| MEDIUM | tests/integration/mcp_vcr/test_research.py | 61 | # recorded poll (the "Python programming best practices" task). Pinning it makes | COMMENT |
| MEDIUM | tests/scripts/generate_relevance_ledger.py | 417 | """Inspect all guardrail and historical files and build comprehensive relevance ledger.""" | STRING |
| MEDIUM | tests/e2e/test_cli_live.py | 64 | # or an enveloped object so the test is robust to the exact shape. | COMMENT |
| MEDIUM⚡ | tests/e2e/test_research_import_verification.py | 93 | # makes this path robust for fast-mode imports too. | COMMENT |
| MEDIUM | tests/e2e/_collection_candidate.py | 109 | # The exact full name is the test-harness ownership boundary. The | COMMENT |
| MEDIUM⚡ | docs/diagrams/22-testing-and-guardrails.html | 4963 | <script id="archify-source-evidence-data" type="application/json">{"schemaVersion":1,"verified":true,"repository":{" | CODE |
| MEDIUM | src/notebooklm/_atomic_io.py | 413 | # and re-introduce the divergent-lock race. ``casefold`` is the robust | COMMENT |
| LOW | src/notebooklm/_web/sharing.py | 261 | # Fetch current status and override view_level with what we just set | COMMENT |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW | tests/unit/test_storage_writer.py | 538 | (storage_mod.AccountRecord(7, "user@example.com"), "set", 7, "user@example.com"), | CODE |
| LOW⚡ | tests/unit/test_auth_credential_io.py | 104 | "email": "user@example.com", | CODE |
| LOW⚡ | tests/unit/test_auth_credential_io.py | 112 | '{\n "version": 1,\n "email": "user@example.com",\n' | CODE |
| LOW | tests/unit/test_app_master_token.py | 69 | app.MasterTokenLoginPlan("user@example.com", storage, None, False), | CODE |
| LOW | tests/unit/test_app_master_token.py | 118 | plan = app.MasterTokenLoginPlan("user@example.com", storage, "android", False) | CODE |
| LOW | tests/unit/test_app_master_token.py | 134 | assert calls[0][1] == {"email": "user@example.com", "storage_path": storage, "force": False} | CODE |
| LOW | tests/unit/test_app_master_token.py | 138 | "email": "user@example.com", | CODE |
| LOW | tests/unit/test_app_master_token.py | 157 | app.MasterTokenLoginPlan("user@example.com", storage, None, True), | CODE |
| LOW | tests/unit/test_app_master_token.py | 185 | app.MasterTokenLoginPlan("user@example.com", storage, None, False), | CODE |
| LOW | tests/unit/test_app_master_token.py | 212 | app.MasterTokenLoginPlan("user@example.com", storage, None, False), | CODE |
| LOW | tests/unit/test_app_master_token.py | 250 | app.MasterTokenLoginPlan("user@example.com", storage, None, False), | CODE |
| LOW | tests/unit/test_app_master_token.py | 549 | account_email="user@example.com", | CODE |
| LOW | tests/unit/test_auth_profile_store_account.py | 55 | ({"authuser": 3, "email": " user@example.com "}, ProfileAccount(3, "user@example.com")), | CODE |
| LOW⚡ | tests/unit/test_cassette_sanitizer.py | 565 | fake_key = "AIza" + "Z" * 35 | CODE |
| LOW⚡ | tests/unit/test_cassette_sanitizer.py | 568 | (examples / "leak.json").write_text(f'{{"JrWMbf":"{fake_key}"}}\n', encoding="utf-8") | CODE |
| LOW⚡ | tests/unit/test_chat_ask_invariants.py | 180 | account_email="user@example.com", | CODE |
| LOW | tests/unit/test_chat_ask_invariants.py | 201 | assert _extract_query_param(str(request.url), "authuser") == "user@example.com" | CODE |
| LOW | tests/unit/test_public_decoder_deprecations.py | 55 | lambda: SharedUser.from_api_response(["user@example.com", 1]), | CODE |
| LOW | tests/unit/test_public_decoder_deprecations.py | 56 | lambda: decode_shared_user(SharedUser, ["user@example.com", 1]), | CODE |
| LOW⚡ | tests/unit/test_artifact_generation_prompt.py | 102 | raw = _row_with_prompt(ArtifactTypeCode.AUDIO.value, 6, (1, 0), prompt="placeholder") | CODE |
| LOW⚡ | tests/unit/test_token_regex.py | 47 | assert value == "user@example.com" | CODE |
| LOW⚡ | tests/unit/test_cassette_patterns.py | 285 | @pytest.mark.parametrize("placeholder", sorted(SCRUB_PLACEHOLDERS)) | CODE |
| LOW⚡ | tests/unit/test_sharing_types.py | 283 | data = ["user@example.com", 3, [], ["Test User", "https://avatar.url"]] | CODE |
| LOW⚡ | tests/unit/test_sharing_types.py | 286 | assert user.email == "user@example.com" | CODE |
| LOW⚡ | tests/unit/test_sharing_types.py | 310 | data = ["user@example.com", 2, []] | CODE |
| LOW⚡ | tests/unit/test_sharing_types.py | 313 | assert user.email == "user@example.com" | CODE |
| LOW⚡ | tests/unit/test_sharing_types.py | 320 | data = ["user@example.com", 99, []] | CODE |
| LOW⚡ | tests/unit/test_sharing_types.py | 327 | data = ["user@example.com", {"permission": 3}, []] | CODE |
| LOW⚡ | tests/unit/test_sharing_types.py | 373 | data = ["user@example.com", 3, [], ["Just Name"]] | CODE |
| LOW⚡ | tests/unit/test_sharing_types.py | 510 | ["user@example.com", 3, [], ["Name", "https://avatar"]], # full | CODE |
| LOW⚡ | tests/unit/test_sharing_types.py | 511 | ["user@example.com", 2, []], # minimal (no user_info slot) | CODE |
| LOW⚡ | tests/unit/test_sharing_types.py | 512 | ["user@example.com", 3, [], ["Just Name"]], # partial user_info (no avatar) | CODE |
| LOW⚡ | tests/unit/test_sharing_types.py | 513 | ["user@example.com", 99, []], # unknown permission | CODE |
| LOW⚡ | tests/unit/test_sharing_types.py | 514 | ["user@example.com", {"k": 1}, []], # malformed (unhashable) permission | CODE |
| LOW⚡ | tests/unit/app/test_app_sharing.py | 129 | "user@example.com", | CODE |
| LOW⚡ | tests/unit/app/test_app_sharing.py | 139 | "user@example.com", | CODE |
| LOW⚡ | tests/unit/app/test_app_sharing.py | 159 | "user@example.com", | CODE |
| LOW⚡ | tests/unit/app/test_app_sharing.py | 166 | "full_nb_part", "user@example.com", SharePermission.VIEWER | CODE |
| LOW⚡ | tests/unit/app/test_app_sharing.py | 181 | await execute_share_remove_user(client, "nb_1", "user@example.com") | CODE |
| LOW⚡ | tests/unit/app/test_app_sharing.py | 183 | client.sharing.remove_user.assert_awaited_once_with("nb_1", "user@example.com") | CODE |
| LOW⚡ | tests/unit/cli/test_share.py | 176 | ["share", "add", "user@example.com", "-n", "nb_123"], | CODE |
| LOW⚡ | tests/unit/cli/test_share.py | 185 | "user@example.com", | CODE |
| LOW⚡ | tests/unit/cli/test_share.py | 206 | ["share", "add", "user@example.com", "-n", "nb_123", "-p", "editor"], | CODE |
| LOW⚡ | tests/unit/cli/test_share.py | 214 | "user@example.com", | CODE |
| LOW⚡ | tests/unit/cli/test_share.py | 242 | ["share", "remove", "user@example.com", "-n", "nb_123", "-y"], | CODE |
| LOW⚡ | tests/unit/cli/test_share.py | 248 | mock_client.sharing.remove_user.assert_called_once_with("nb_123", "user@example.com") | CODE |
| LOW⚡ | tests/unit/cli/test_share.py | 289 | ["share", "remove", "user@example.com", "-n", "nb_123", "--json"], | CODE |
| LOW⚡ | tests/unit/cli/test_share.py | 294 | assert '"removed_user": "user@example.com"' in result.output | CODE |
| LOW⚡ | tests/unit/cli/test_share.py | 314 | ["share", "remove", "user@example.com", "-n", "nb_123", "--json"], | CODE |
| LOW⚡ | tests/unit/cli/test_share.py | 319 | assert '"removed_user": "user@example.com"' in result.output | CODE |
| LOW⚡ | tests/unit/cli/test_share.py | 321 | mock_client.sharing.remove_user.assert_called_once_with("nb_123", "user@example.com") | CODE |
| LOW⚡ | tests/unit/cli/test_share.py | 487 | assert '"updated_user": "user@example.com"' in result.output | CODE |
| LOW⚡ | tests/unit/cli/test_share.py | 663 | ["share", "add", "user@example.com", "-n", "nb_123", "--json"], | CODE |
| LOW⚡ | tests/unit/cli/test_share.py | 668 | assert '"added_user": "user@example.com"' in result.output | CODE |
| LOW | tests/unit/cli/test_share.py | 265 | ["share", "remove", "user@example.com", "-n", "nb_123"], | CODE |
| LOW | tests/unit/cli/test_share.py | 447 | ["share", "update", "user@example.com", "-n", "nb_123", "-p", "editor"], | CODE |
| LOW | tests/unit/cli/test_share.py | 455 | "nb_123", "user@example.com", SharePermission.EDITOR | CODE |
| LOW | tests/unit/cli/test_share.py | 476 | "user@example.com", | CODE |
| LOW⚡ | tests/unit/cli/test_session_characterization.py | 196 | result = char_runner.invoke(cli, ["login", "--account", "user@example.com"]) | CODE |
| LOW | tests/unit/cli/test_auth_refresh_cold_start.py | 62 | "account": {"authuser": 0, "email": "user@example.com"}, | CODE |
| 20 more matches not shown… | ||||
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW⚡ | tests/unit/test_cookie_domain_split.py | 612 | # Step 2: storage_state → DomainCookieMap (used by AuthTokens). | COMMENT |
| LOW⚡ | tests/unit/test_cookie_domain_split.py | 618 | # Step 3: storage_state → httpx jar (used by downloads + refresh). | COMMENT |
| LOW⚡ | tests/unit/test_cookie_domain_split.py | 626 | # Step 4: the runtime gate itself accepts every YouTube variant. | COMMENT |
| LOW | tests/unit/test_cookie_domain_split.py | 601 | # Step 1: rookiepy → storage_state conversion must keep the YouTube | COMMENT |
| LOW⚡ | tests/integration/test_sources_integration.py | 800 | # Step 1: Mock RPC registration response (o4cbdc) | COMMENT |
| LOW⚡ | tests/integration/test_sources_integration.py | 809 | # Step 2: Mock upload session start response | COMMENT |
| LOW⚡ | tests/integration/test_sources_integration.py | 819 | # Step 3: Mock upload finalize response | COMMENT |
| LOW⚡ | tests/integration/test_sources_integration.py | 997 | # Step 1: Mock RPC registration | COMMENT |
| LOW⚡ | tests/integration/test_sources_integration.py | 1006 | # Step 2: Mock upload session start | COMMENT |
| LOW⚡ | tests/integration/test_sources_integration.py | 1016 | # Step 3: Mock upload finalize | COMMENT |
| LOW⚡ | tests/integration/test_sources_integration.py | 2765 | # Step 1: Successful RPC registration | COMMENT |
| LOW⚡ | tests/integration/test_sources_integration.py | 2775 | # Step 2: Upload session response WITHOUT the required upload URL header | COMMENT |
| LOW⚡ | tests/e2e/test_research_import_verification.py | 43 | # Step 1: Start fast web research | COMMENT |
| LOW | tests/e2e/test_research_import_verification.py | 57 | # Step 2: Poll until complete | COMMENT |
| LOW | tests/e2e/test_research_import_verification.py | 75 | # Step 3: Get sources to import | COMMENT |
| LOW⚡ | tests/e2e/test_research_import_verification.py | 89 | # Step 4: Import sources. Use the verification-aware variant so an | COMMENT |
| LOW | tests/e2e/test_research_import_verification.py | 105 | # Step 5: Poll for imported sources to appear | COMMENT |
| LOW | tests/e2e/test_research_import_verification.py | 117 | # Step 6: Verify source count | COMMENT |
| LOW⚡ | tests/e2e/test_research.py | 200 | # Step 1: Start research | COMMENT |
| LOW | tests/e2e/test_research.py | 211 | # Step 2: Poll until complete | COMMENT |
| LOW | tests/e2e/test_research.py | 233 | # Step 3: Import sources (if any found) | COMMENT |
| LOW⚡ | docs/troubleshooting.md | 596 | # Step 1: Install bird (macOS/Linux) | COMMENT |
| LOW⚡ | docs/troubleshooting.md | 599 | # Step 2: Fetch X.com content as markdown | COMMENT |
| LOW⚡ | docs/troubleshooting.md | 602 | # Step 3: Add the local markdown file to NotebookLM | COMMENT |
| LOW | docs/rpc-development.md | 269 | ### Step 1: Capture | COMMENT |
| LOW | docs/rpc-development.md | 278 | ### Step 2: Decode | COMMENT |
| LOW | docs/rpc-development.md | 296 | ### Step 3: Implement | COMMENT |
| LOW | docs/rpc-development.md | 345 | ### Step 4: Test | COMMENT |
| LOW | docs/rpc-development.md | 379 | ### Step 5: Document | COMMENT |
| LOW | examples/video.py | 26 | # Step 1: Create a notebook with content | COMMENT |
| LOW⚡ | examples/video.py | 45 | # Step 2: Generate the video overview | COMMENT |
| LOW | examples/video.py | 80 | # Step 3: Wait for completion with status updates | COMMENT |
| LOW | examples/video.py | 95 | # Step 4: Download the video | COMMENT |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW⚡ | tests/unit/test_cookie_domain_split.py | 612 | # Step 2: storage_state → DomainCookieMap (used by AuthTokens). | COMMENT |
| LOW⚡ | tests/unit/test_cookie_domain_split.py | 618 | # Step 3: storage_state → httpx jar (used by downloads + refresh). | COMMENT |
| LOW⚡ | tests/unit/test_cookie_domain_split.py | 626 | # Step 4: the runtime gate itself accepts every YouTube variant. | COMMENT |
| LOW | tests/unit/test_cookie_domain_split.py | 601 | # Step 1: rookiepy → storage_state conversion must keep the YouTube | COMMENT |
| LOW⚡ | tests/integration/test_sources_integration.py | 800 | # Step 1: Mock RPC registration response (o4cbdc) | COMMENT |
| LOW⚡ | tests/integration/test_sources_integration.py | 809 | # Step 2: Mock upload session start response | COMMENT |
| LOW⚡ | tests/integration/test_sources_integration.py | 819 | # Step 3: Mock upload finalize response | COMMENT |
| LOW⚡ | tests/integration/test_sources_integration.py | 997 | # Step 1: Mock RPC registration | COMMENT |
| LOW⚡ | tests/integration/test_sources_integration.py | 1006 | # Step 2: Mock upload session start | COMMENT |
| LOW⚡ | tests/integration/test_sources_integration.py | 1016 | # Step 3: Mock upload finalize | COMMENT |
| LOW⚡ | tests/integration/test_sources_integration.py | 2765 | # Step 1: Successful RPC registration | COMMENT |
| LOW⚡ | tests/integration/test_sources_integration.py | 2775 | # Step 2: Upload session response WITHOUT the required upload URL header | COMMENT |
| LOW⚡ | tests/e2e/test_research_import_verification.py | 43 | # Step 1: Start fast web research | COMMENT |
| LOW | tests/e2e/test_research_import_verification.py | 57 | # Step 2: Poll until complete | COMMENT |
| LOW | tests/e2e/test_research_import_verification.py | 75 | # Step 3: Get sources to import | COMMENT |
| LOW⚡ | tests/e2e/test_research_import_verification.py | 89 | # Step 4: Import sources. Use the verification-aware variant so an | COMMENT |
| LOW | tests/e2e/test_research_import_verification.py | 105 | # Step 5: Poll for imported sources to appear | COMMENT |
| LOW | tests/e2e/test_research_import_verification.py | 117 | # Step 6: Verify source count | COMMENT |
| LOW⚡ | tests/e2e/test_research.py | 200 | # Step 1: Start research | COMMENT |
| LOW | tests/e2e/test_research.py | 211 | # Step 2: Poll until complete | COMMENT |
| LOW | tests/e2e/test_research.py | 233 | # Step 3: Import sources (if any found) | COMMENT |
| LOW | examples/video.py | 26 | # Step 1: Create a notebook with content | COMMENT |
| LOW⚡ | examples/video.py | 45 | # Step 2: Generate the video overview | COMMENT |
| LOW | examples/video.py | 80 | # Step 3: Wait for completion with status updates | COMMENT |
| LOW | examples/video.py | 95 | # Step 4: Download the video | COMMENT |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| MEDIUM | tests/unit/test_artifact_downloads.py | 892 | # Create the complex nested structure for data table. | COMMENT |
| MEDIUM⚡ | tests/unit/test_sources_upload.py | 973 | # Create a temp file | COMMENT |
| MEDIUM⚡ | tests/unit/cli/test_resolve.py | 345 | # Create a notebook with a short ID that we'll match exactly | COMMENT |
| MEDIUM | tests/unit/cli/test_source.py | 719 | # Create a temp file | COMMENT |
| MEDIUM | tests/integration/test_vcr_comprehensive.py | 811 | # Create a test file | COMMENT |
| MEDIUM | tests/integration/test_vcr_comprehensive.py | 901 | # Create a source to delete | COMMENT |
| MEDIUM | tests/integration/test_vcr_comprehensive.py | 939 | # Create a notebook to delete | COMMENT |
| MEDIUM | tests/integration/test_vcr_comprehensive.py | 971 | # Create a note to delete | COMMENT |
| MEDIUM | tests/integration/test_android_grpc_cassette.py | 286 | # Create the conversation inside the family so it re-records on its own. | COMMENT |
| MEDIUM | tests/e2e/test_artifacts.py | 246 | # Create a quiz artifact for deletion (different type than flashcards) | COMMENT |
| MEDIUM | tests/e2e/test_sources.py | 123 | # Create a source to delete | COMMENT |
| MEDIUM⚡ | examples/notes.py | 49 | # Create a new note with title and content | COMMENT |
| MEDIUM | examples/notes.py | 27 | # Create a notebook for our examples | COMMENT |
| MEDIUM | examples/chat.py | 23 | # Create a notebook with some content | COMMENT |
| MEDIUM | src/notebooklm/notebooklm_cli.py | 179 | notebooklm create "My Notes" # Create a notebook | STRING |
| MEDIUM | src/notebooklm/_browser/browser_capture.py | 1360 | # Create a TEMPORARY page we own for the navigation, and close ONLY | COMMENT |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW | tests/_helpers/client_factory.py | 32 | CODE | |
| LOW | tests/unit/test_logging_correlation.py | 244 | CODE | |
| LOW | tests/unit/test_auth_profile_store_minted.py | 37 | CODE | |
| LOW | tests/unit/test_e2e_collection_candidate.py | 23 | CODE | |
| LOW | tests/unit/test_rpc_executor.py | 91 | CODE | |
| LOW | tests/unit/test_rpc_executor.py | 276 | CODE | |
| LOW | tests/unit/test_rpc_executor.py | 924 | CODE | |
| LOW | tests/unit/test_idempotency_registry.py | 534 | CODE | |
| LOW | tests/unit/test_runtime_lifecycle.py | 115 | CODE | |
| LOW | tests/unit/test_rpc_golden_payloads.py | 1581 | CODE | |
| LOW | tests/unit/app/test_app_research.py | 41 | CODE | |
| LOW | tests/unit/cli/test_playwright_login_render_contract.py | 179 | CODE | |
| LOW | tests/unit/android/test_session.py | 229 | CODE | |
| LOW | tests/_guardrails/test_auth_storage_compatibility.py | 1814 | CODE | |
| LOW | tests/_fault_server/web.py | 90 | CODE | |
| LOW | tests/_fault_server/android.py | 76 | CODE | |
| LOW | tests/_fault_server/web_scenarios.py | 142 | CODE | |
| LOW | src/notebooklm/_client_assembly.py | 132 | CODE | |
| LOW | src/notebooklm/client.py | 263 | CODE | |
| LOW | src/notebooklm/client.py | 688 | CODE | |
| LOW | src/notebooklm/_curl_cffi_transport.py | 234 | CODE | |
| LOW | src/notebooklm/_client_options.py | 283 | CODE | |
| LOW | src/notebooklm/exceptions.py | 497 | CODE | |
| LOW | src/notebooklm/_android/upload.py | 419 | CODE | |
| LOW | src/notebooklm/_android/session.py | 264 | CODE | |
| LOW | src/notebooklm/_android/session.py | 644 | CODE | |
| LOW | src/notebooklm/_android/session.py | 861 | CODE | |
| LOW | src/notebooklm/_auth/refresh.py | 712 | CODE | |
| LOW | src/notebooklm/mcp/tools/studio.py | 223 | CODE | |
| LOW | src/notebooklm/mcp/tools/sources.py | 617 | CODE | |
| LOW | src/notebooklm/cli/resolve.py | 199 | CODE | |
| LOW | src/notebooklm/_web/transport/runtime.py | 283 | CODE | |
| LOW | src/notebooklm/_web/transport/runtime.py | 315 | CODE | |
| LOW | src/notebooklm/_web/transport/init.py | 266 | CODE | |
| LOW | src/notebooklm/_web/transport/executor.py | 139 | CODE | |
| LOW | src/notebooklm/_web/transport/executor.py | 204 | CODE | |
| LOW | src/notebooklm/_web/transport/executor.py | 329 | CODE | |
| LOW | src/notebooklm/_web/sources/upload.py | 185 | CODE | |
| LOW | src/notebooklm/_source/polling.py | 123 | CODE | |
| LOW | src/notebooklm/_source/polling.py | 192 | CODE | |
| LOW | src/notebooklm/_app/generation_requests.py | 657 | CODE |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| MEDIUM | tests/unit/test_auth_remaining_branches.py | 873 | CODE | |
| MEDIUM | tests/unit/mcp/test_web_profiles.py | 295 | CODE | |
| MEDIUM | tests/unit/mcp/test_fileroutes.py | 1076 | CODE | |
| MEDIUM | tests/unit/mcp/test_stdio_source_add_roots.py | 101 | CODE | |
| MEDIUM | tests/unit/mcp/test_sources.py | 2048 | CODE | |
| MEDIUM | tests/unit/mcp/test_meta.py | 385 | CODE | |
| MEDIUM | tests/unit/mcp/test_meta.py | 411 | CODE | |
| MEDIUM | tests/unit/android/test_session_fake_server.py | 357 | CODE | |
| MEDIUM | tests/server/conftest.py | 67 | CODE | |
| MEDIUM | tests/server/test_app_lifecycle.py | 171 | CODE | |
| MEDIUM | tests/server/test_app_lifecycle.py | 223 | CODE | |
| MEDIUM | tests/server/test_app_lifecycle.py | 250 | CODE | |
| MEDIUM | tests/server/test_app_lifecycle.py | 275 | CODE | |
| MEDIUM | tests/server/test_sources.py | 120 | CODE | |
| MEDIUM | tests/server/test_meta.py | 206 | CODE |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| HIGH | docs/python-api.md | 1310 | # Get AI-generated description (parsed with suggested topics) | COMMENT |
| HIGH | docs/python-api.md | 1447 | # Get AI-generated summary and keywords (returns a typed SourceGuide) | COMMENT |
| HIGH⚡ | examples/video.py | 51 | # - CINEMATIC: AI-generated documentary footage (Veo 3) | COMMENT |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW⚡ | tests/unit/test_check_deprecation_targets.py | 637 | "@decorate(_LAZY_EXPORTS)\ndef helper():\n pass", | STRING |
| LOW⚡ | tests/unit/test_check_deprecation_targets.py | 638 | "def helper(value=_LAZY_EXPORTS):\n pass", | STRING |
| LOW⚡ | tests/unit/test_check_deprecation_targets.py | 639 | "def helper() -> _LAZY_EXPORTS:\n pass", | STRING |
| LOW | tests/unit/test_check_deprecation_targets.py | 717 | function = ast.parse("def helper():\n pass\n").body[0] | STRING |
| LOW⚡ | tests/unit/test_audit_auth_patch_sites.py | 588 | "def helper(monkeypatch, ATTR):\n" | CODE |
| LOW⚡ | tests/unit/test_audit_auth_patch_sites.py | 599 | "def helper(monkeypatch):\n" | CODE |
| LOW⚡ | tests/unit/test_audit_auth_patch_sites.py | 609 | body = "def helper(target):\n target.SEAM = 1\ndef test_x():\n helper(object())\n" | CODE |
| LOW⚡ | tests/unit/test_audit_auth_patch_sites.py | 616 | "def helper(monkeypatch, targets):\n" | CODE |
| LOW⚡ | tests/unit/test_audit_auth_patch_sites.py | 627 | "def helper(monkeypatch, targets):\n" | CODE |
| LOW | tests/unit/test_audit_auth_patch_sites.py | 527 | "def helper(monkeypatch):\n" | CODE |
| LOW | tests/unit/test_audit_auth_patch_sites.py | 550 | "def helper(mp, target):\n" | CODE |
| LOW | tests/unit/test_audit_auth_patch_sites.py | 572 | "def helper(mp, target):\n" | CODE |
| LOW⚡ | tests/unit/test_audit_auth_shared_mutations.py | 272 | "def helper(monkeypatch, ATTR):\n" | CODE |
| LOW⚡ | tests/unit/test_audit_auth_shared_mutations.py | 282 | "def helper(target):\n" | CODE |
| LOW⚡ | tests/unit/test_audit_auth_shared_mutations.py | 293 | "def helper(monkeypatch, targets):\n" | CODE |
| LOW⚡ | tests/unit/test_audit_auth_shared_mutations.py | 304 | "def helper(targets):\n" | CODE |
| LOW | tests/unit/test_audit_auth_shared_mutations.py | 60 | "def helper(monkeypatch):\n" | CODE |
| LOW | tests/unit/test_audit_auth_shared_mutations.py | 242 | "def helper(mp, target):\n" | CODE |
| LOW | tests/unit/test_audit_auth_shared_mutations.py | 256 | "def helper(mp, target):\n" | CODE |
| LOW | tests/unit/test_auth_behavior_scenario_policy.py | 303 | "def helper(): pass\n" | CODE |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW | tests/unit/test_windows_compatibility.py | 261 | # Check if UTF-8 mode is active (either via flag or env var) | COMMENT |
| LOW | tests/unit/test_auth_storage.py | 147 | # Set NOTEBOOKLM_HOME to tmp_path and create a file there | COMMENT |
| LOW | tests/scripts/generate_relevance_ledger.py | 443 | # Check if specific node rule exists | COMMENT |
| LOW | tests/e2e/test_chat.py | 101 | # Check if any references have cited_text | COMMENT |
| LOW | scripts/check_rpc_health.py | 948 | # Check if error response still contains our expected ID | COMMENT |
| LOW | scripts/check_rpc_health.py | 965 | # Check if expected ID is in response | COMMENT |
| LOW | src/notebooklm/_auth/cookie_policy.py | 903 | # Check if it's a valid canonical Google domain (base or regional). | COMMENT |
| LOW | src/notebooklm/_app/chat.py | 198 | # Check if the user switched notebooks via the --notebook flag. Only read | COMMENT |