The SQL IDE for Your Terminal. Now with hsql, your agent's favorite sql client.
This report summarizes scanner evidence for tconbeer/harlequin, a Python project with 6,454 GitHub stars. SynthScan examined 72,219 lines of code across 242 source files, recording 1758 pattern matches distributed across 13 syntactic categories. The legacy adjusted pattern signal is 24.6 (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? 1407 finding(s).
Are imports declared and package/API names verified? 281 finding(s).
Are wrappers, guards, and repeated structures necessary? 1442 finding(s).
Which changes need focused human review? 1758 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 1758 distinct pattern matches across 13 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 | 263 | def app_all_adapters_small_db( | CODE |
| LOW | tests/conftest.py | 284 | def _create_sqlite_db_from_data_dir(data_dir: Path, db_path: Path) -> None: | CODE |
| LOW | tests/unit_tests/test_completers.py | 27 | def test_completer_fixed_first(iris_completer: WordCompleter) -> None: | CODE |
| LOW | tests/unit_tests/test_completers.py | 32 | def test_completer_fuzzy_match(iris_completer: WordCompleter) -> None: | CODE |
| LOW | tests/unit_tests/test_completers.py | 59 | def test_extend_catalog_merges_by_default(parent_item: CatalogItem) -> None: | CODE |
| LOW | tests/unit_tests/test_completers.py | 65 | def test_extend_catalog_defer_merge(parent_item: CatalogItem) -> None: | CODE |
| LOW⚡ | tests/unit_tests/test_completers.py | 115 | def test_buffer_symbol_is_offered(word_completer: WordCompleter) -> None: | CODE |
| LOW⚡ | tests/unit_tests/test_completers.py | 121 | def test_buffer_symbol_does_not_complete_to_itself( | CODE |
| LOW⚡ | tests/unit_tests/test_completers.py | 130 | def test_buffer_symbol_is_not_duplicated(word_completer: WordCompleter) -> None: | CODE |
| LOW⚡ | tests/unit_tests/test_completers.py | 135 | def test_catalog_item_in_buffer_ranks_first(word_completer: WordCompleter) -> None: | CODE |
| LOW⚡ | tests/unit_tests/test_completers.py | 141 | def test_completion_whose_context_is_in_buffer_ranks_higher( | CODE |
| LOW | tests/unit_tests/test_completers.py | 152 | def test_member_completions_come_from_the_buffer( | CODE |
| LOW | tests/unit_tests/test_completers.py | 162 | def test_member_completions_from_the_buffer_are_not_duplicated( | CODE |
| LOW⚡ | tests/unit_tests/test_completers.py | 173 | def test_buffer_symbols_survive_a_catalog_update( | CODE |
| LOW⚡ | tests/unit_tests/test_completers.py | 181 | def test_numbers_do_not_complete(word_completer: WordCompleter) -> None: | CODE |
| LOW⚡ | tests/unit_tests/test_completers.py | 188 | def test_unquoted_numeric_members_do_not_complete( | CODE |
| LOW | tests/unit_tests/test_completers.py | 200 | def test_fuzzy_matches_start_at_a_word_boundary( | CODE |
| LOW | tests/unit_tests/test_completers.py | 207 | def test_one_character_does_not_fuzzy_match(word_completer: WordCompleter) -> None: | CODE |
| LOW⚡ | tests/unit_tests/test_editor_cache.py | 48 | def test_write_cache_round_trips(mock_user_cache_dir: Path, cache: Cache) -> None: | CODE |
| LOW⚡ | tests/unit_tests/test_editor_cache.py | 53 | def test_write_cache_leaves_no_temp_file( | CODE |
| LOW⚡ | tests/unit_tests/test_editor_cache.py | 63 | def test_a_failed_write_leaves_the_last_cache_alone( | CODE |
| LOW | tests/unit_tests/test_editor_cache.py | 78 | def test_write_cache_returns_false_when_the_cache_dir_is_unwritable( | CODE |
| LOW | tests/unit_tests/test_editor_cache.py | 86 | def test_write_recovery_does_not_touch_the_shared_cache( | CODE |
| LOW⚡ | tests/unit_tests/test_editor_cache.py | 103 | def test_clear_recovery_when_there_is_nothing_to_clear( | CODE |
| LOW⚡ | tests/unit_tests/test_editor_cache.py | 109 | def test_adopt_recovery_finds_nothing(mock_user_cache_dir: Path, cache: Cache) -> None: | CODE |
| LOW⚡ | tests/unit_tests/test_editor_cache.py | 114 | def test_adopt_recovery_replays_a_crash_handlers_file( | CODE |
| LOW | tests/unit_tests/test_editor_cache.py | 126 | def test_adopt_recovery_replays_each_file_once( | CODE |
| LOW | tests/unit_tests/test_editor_cache.py | 136 | def test_adopt_recovery_consumes_a_file_it_cannot_unpickle( | CODE |
| LOW | tests/unit_tests/test_editor_cache.py | 150 | def test_adopt_recovery_leaves_a_live_sessions_file_alone( | CODE |
| LOW | tests/unit_tests/test_editor_cache.py | 160 | def test_adopt_recovery_takes_over_a_stale_file( | CODE |
| LOW | tests/unit_tests/test_editor_cache.py | 176 | def test_adopt_recovery_prefers_the_newest_crash( | CODE |
| LOW⚡ | tests/unit_tests/test_config_wizard.py | 352 | def test_a_fresh_profile_is_not_given_a_limit( | CODE |
| LOW⚡ | tests/unit_tests/test_config_wizard.py | 362 | def test_an_existing_limit_is_offered_and_kept( | CODE |
| LOW⚡ | tests/unit_tests/test_config_wizard.py | 372 | def test_blank_removes_an_existing_limit( | CODE |
| LOW | tests/unit_tests/test_config_wizard.py | 89 | def test_choosing_no_default_removes_it_from_the_file( | CODE |
| LOW | tests/unit_tests/test_config_wizard.py | 110 | def test_setting_a_default_writes_it( | CODE |
| LOW | tests/unit_tests/test_config_wizard.py | 138 | def test_a_secret_is_written_to_the_file_and_not_to_the_screen( | CODE |
| LOW | tests/unit_tests/test_config_wizard.py | 165 | def test_a_variable_the_file_reads_a_secret_from_is_written_back_unresolved( | CODE |
| LOW | tests/unit_tests/test_config_wizard.py | 206 | def test_saying_yes_writes_the_key( | CODE |
| LOW | tests/unit_tests/test_config_wizard.py | 222 | def test_a_profile_that_is_not_read_only_says_nothing( | CODE |
| LOW | tests/unit_tests/test_config_wizard.py | 239 | def test_saying_no_turns_off_a_profile_that_was_read_only( | CODE |
| LOW | tests/unit_tests/test_config_wizard.py | 256 | def test_the_question_is_not_put_to_an_adapter_that_cannot_answer_it( | CODE |
| LOW | tests/unit_tests/test_config_wizard.py | 295 | def test_the_prompt_offers_what_the_profile_already_says( | CODE |
| LOW | tests/unit_tests/test_config_wizard.py | 309 | def test_the_wizard_keeps_the_comments_in_a_profile_it_did_not_touch( | CODE |
| LOW | tests/unit_tests/test_config_wizard.py | 388 | def test_a_typed_limit_is_written( | CODE |
| LOW | tests/unit_tests/test_config_wizard.py | 404 | def test_minus_one_is_accepted_and_omitted( | CODE |
| LOW | tests/unit_tests/test_config_wizard.py | 421 | def test_the_limit_prompt_offers_blank_and_says_so( | CODE |
| LOW | tests/unit_tests/test_config_wizard.py | 447 | def test_a_blank_secret_option_is_not_written( | CODE |
| LOW | tests/unit_tests/test_config_wizard.py | 465 | def test_a_blank_text_option_is_not_written( | CODE |
| LOW | tests/unit_tests/test_config_wizard.py | 484 | def test_a_blank_list_option_is_not_written( | CODE |
| LOW | tests/unit_tests/test_config_wizard.py | 502 | def test_blank_clears_an_existing_adapter_option( | CODE |
| LOW | tests/unit_tests/test_config_wizard.py | 519 | def test_an_explicit_false_on_a_flag_is_written( | CODE |
| LOW | tests/unit_tests/test_config_wizard.py | 562 | def test_saying_no_writes_no_ssh_keys( | CODE |
| LOW | tests/unit_tests/test_config_wizard.py | 579 | def test_the_question_defaults_to_no( | CODE |
| LOW | tests/unit_tests/test_config_wizard.py | 596 | def test_saying_yes_writes_the_tunnel( | CODE |
| LOW | tests/unit_tests/test_config_wizard.py | 620 | def test_a_forward_the_ssh_config_supplies_is_left_out( | CODE |
| LOW | tests/unit_tests/test_config_wizard.py | 645 | def test_several_forwards_are_written_as_a_list( | CODE |
| LOW | tests/unit_tests/test_config_wizard.py | 666 | def test_an_existing_tunnel_is_offered_back( | CODE |
| LOW | tests/unit_tests/test_config_wizard.py | 693 | def test_the_wizard_never_writes_the_key_a_config_file_may_not_answer( | CODE |
| LOW | tests/unit_tests/test_config_wizard.py | 714 | def test_the_tunnel_is_asked_about_before_the_adapter_options( | CODE |
| 1304 more matches not shown… | ||||
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW | tests/tunnels.py | 3 | CODE | |
| LOW | tests/conftest.py | 1 | CODE | |
| LOW | tests/hsql_sessions.py | 7 | CODE | |
| LOW | tests/waiting.py | 8 | CODE | |
| LOW | tests/unit_tests/test_editor_cache.py | 1 | CODE | |
| LOW | tests/unit_tests/test_config_wizard.py | 1 | CODE | |
| LOW | tests/unit_tests/test_statements.py | 8 | CODE | |
| LOW | tests/unit_tests/conftest.py | 1 | CODE | |
| LOW | tests/unit_tests/test_redact.py | 9 | CODE | |
| LOW | tests/unit_tests/test_packaging.py | 14 | CODE | |
| LOW | tests/unit_tests/test_plugins.py | 1 | CODE | |
| LOW | tests/unit_tests/test_navigate.py | 13 | CODE | |
| LOW | tests/unit_tests/test_options.py | 9 | CODE | |
| LOW | tests/unit_tests/test_plugin.py | 15 | CODE | |
| LOW | tests/unit_tests/test_hsql_session.py | 10 | CODE | |
| LOW | tests/unit_tests/test_config_schema.py | 10 | CODE | |
| LOW | tests/unit_tests/test_import_hygiene.py | 9 | CODE | |
| LOW | tests/unit_tests/test_skill.py | 13 | CODE | |
| LOW | tests/unit_tests/test_cli_reference.py | 13 | CODE | |
| LOW | tests/unit_tests/test_ssh.py | 8 | CODE | |
| LOW | tests/unit_tests/test_external.py | 1 | CODE | |
| LOW | tests/unit_tests/test_s3_tree.py | 1 | CODE | |
| LOW | tests/unit_tests/test_crash.py | 1 | CODE | |
| LOW | tests/unit_tests/test_core_options.py | 4 | CODE | |
| LOW | tests/unit_tests/test_exception.py | 1 | CODE | |
| LOW | tests/unit_tests/test_config.py | 1 | CODE | |
| LOW | tests/unit_tests/test_publish_artifacts.py | 14 | CODE | |
| LOW | tests/unit_tests/test_hsql_serve.py | 13 | CODE | |
| LOW | tests/unit_tests/test_golden_formats.py | 17 | CODE | |
| LOW | tests/unit_tests/test_symbols.py | 1 | CODE | |
| LOW | tests/unit_tests/test_query.py | 1 | CODE | |
| LOW | tests/unit_tests/test_query_log.py | 8 | CODE | |
| LOW | tests/unit_tests/test_documented_flags.py | 17 | CODE | |
| LOW | tests/unit_tests/test_layout.py | 1 | CODE | |
| LOW | tests/unit_tests/test_history.py | 9 | CODE | |
| LOW | tests/unit_tests/test_hsql.py | 9 | CODE | |
| LOW | tests/unit_tests/test_hsql_equivalence.py | 16 | CODE | |
| LOW | tests/unit_tests/test_export.py | 1 | CODE | |
| LOW | tests/unit_tests/test_environment.py | 1 | CODE | |
| LOW | tests/unit_tests/test_windows_timezone.py | 1 | CODE | |
| LOW | tests/unit_tests/test_bindings.py | 9 | CODE | |
| LOW | tests/functional_tests/test_ssh_recovery.py | 8 | CODE | |
| LOW | tests/functional_tests/test_keys_app.py | 1 | CODE | |
| LOW | tests/functional_tests/test_results_viewer.py | 1 | CODE | |
| LOW | tests/functional_tests/test_keymap_vscode.py | 1 | CODE | |
| LOW | tests/functional_tests/test_run_query_bar.py | 1 | CODE | |
| LOW | tests/functional_tests/test_query_editor.py | 1 | CODE | |
| LOW | tests/functional_tests/test_crash.py | 9 | CODE | |
| LOW | tests/functional_tests/test_command_palette.py | 1 | CODE | |
| LOW | tests/functional_tests/test_history_screen.py | 1 | CODE | |
| LOW | tests/functional_tests/helpers.py | 3 | CODE | |
| LOW | tests/functional_tests/test_app.py | 1 | CODE | |
| LOW | tests/functional_tests/test_windows_timezone.py | 1 | CODE | |
| LOW | tests/functional_tests/test_keymap_from_config.py | 1 | CODE | |
| LOW | tests/adapter_tests/test_duckdb.py | 1 | CODE | |
| LOW | tests/adapter_tests/test_sqlite.py | 1 | CODE | |
| LOW | scripts/catalog_lag.py | 14 | CODE | |
| LOW | scripts/write_legacy_cache.py | 14 | CODE | |
| LOW | scripts/write_config_schema.py | 16 | CODE | |
| LOW | scripts/publish_artifacts.py | 23 | CODE | |
| 192 more matches not shown… | ||||
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| HIGH⚡ | tests/unit_tests/test_options.py | 73 | """A key that does not apply is null, not a key that is missing. | STRING |
| HIGH | tests/unit_tests/test_golden_formats.py | 52 | 2, 'a value considerably wider than its column name', null, null, false, | CODE |
| HIGH | tests/unit_tests/test_golden_formats.py | 53 | null, null, null, null, null, null, null, null | CODE |
| HIGH⚡ | tests/unit_tests/test_layout.py | 470 | "select * from (values (1, null), (22, 'a value')) t(id, note)" | CODE |
| HIGH | tests/unit_tests/test_hsql.py | 1128 | """A key nothing defines is null, not a key that is missing. | STRING |
| HIGH⚡ | tests/unit_tests/test_export.py | 100 | b'[\n\t{"a":1,"b":"x,y"},\n\t{"a":2,"b":null}\n]\n' | CODE |
| HIGH⚡ | tests/unit_tests/test_export.py | 104 | assert to_bytes(data, "jsonl") == b'{"a":1,"b":"x,y"}\n{"a":2,"b":null}\n' | CODE |
| HIGH | src/harlequin_sqlite/adapter.py | 53 | select m.name, m.type, null, null | CODE |
| HIGH⚡ | src/harlequin/query_log.py | 55 | run_at text not null, | STRING |
| HIGH⚡ | src/harlequin/query_log.py | 56 | program text not null, | STRING |
| HIGH⚡ | src/harlequin/query_log.py | 60 | sql text not null, | STRING |
| HIGH⚡ | src/harlequin/query_log.py | 61 | status text not null, | STRING |
| HIGH | src/harlequin/query_log.py | 74 | migrated_at text not null, | STRING |
| HIGH | src/harlequin/query.py | 11 | null, how a nested struct comes out) in two places, and the disagreement would | STRING |
| HIGH | src/harlequin/layout.py | 167 | """A value, rendered, styled if it is a null, and padded to `width`. | STRING |
| HIGH | src/harlequin/layout.py | 232 | widths = _column_widths(headers, rows, self.null) | CODE |
| HIGH | src/harlequin/layout.py | 309 | self.null = _escape(self.null) | CODE |
| HIGH | src/harlequin/layout.py | 319 | for width in _column_widths(headers, rows, self.null) | CODE |
| HIGH | src/harlequin/layout.py | 365 | rule_width = name_width + len(separator) + _widest(rows, self.null) | CODE |
| HIGH | src/harlequin/config_schema.py | 309 | null, which TOML cannot write: the schema says the same thing by leaving the | STRING |
| HIGH | src/harlequin/hsql/modes/config.py | 212 | # TOML has no null, so a key with no value is a key the file cannot | COMMENT |
| HIGH⚡ | src/harlequin_duckdb/adapter.py | 58 | select d.database_name, null, null, null, null, null | CODE |
| HIGH⚡ | src/harlequin_duckdb/adapter.py | 64 | select s.catalog_name, s.schema_name, null, null, null, null | CODE |
| HIGH⚡ | src/harlequin_duckdb/adapter.py | 72 | select t.table_catalog, t.table_schema, t.table_name, t.table_type, null, null | CODE |
| HIGH | src/harlequin_duckdb/adapter.py | 101 | null, so `all` is every level of the catalog rather than the two at the bottom. | CODE |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| HIGH | src/harlequin/config.py | 248 | except OSError: | CODE |
| HIGH | src/harlequin/crash.py | 197 | except OSError: | CODE |
| HIGH | src/harlequin/cli.py | 333 | except HarlequinConfigError: | CODE |
| HIGH | src/harlequin/app_base.py | 121 | except BaseException: | CODE |
| HIGH | src/harlequin/app_base.py | 129 | except BaseException: | CODE |
| HIGH | src/harlequin/app.py | 1355 | except Exception: | CODE |
| HIGH | src/harlequin/app.py | 1347 | except OSError: | CODE |
| HIGH | src/harlequin/editor_cache.py | 132 | except OSError: | CODE |
| HIGH | src/harlequin/editor_cache.py | 105 | except OSError: | CODE |
| HIGH | src/harlequin/hsql/client.py | 293 | except (KeyboardInterrupt, UnsafeRuntimeDir, protocol.ProtocolError, OSError): | CODE |
| HIGH | src/harlequin/hsql/__init__.py | 89 | except BaseException: | CODE |
| HIGH | src/harlequin/components/text_modal.py | 97 | except pyperclip.PyperclipException: | CODE |
| HIGH | src/harlequin_duckdb/adapter.py | 141 | except duckdb.Error: | CODE |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| HIGH | src/harlequin/hsql/protocol.py | 0 | every annotation here is a string (pep 563), so `typing` stays off this path. | STRING |
| HIGH | src/harlequin/hsql/client.py | 0 | every annotation here is a string (pep 563), so `typing` stays off this path. | STRING |
| HIGH | src/harlequin/hsql/session.py | 0 | every annotation here is a string (pep 563), so `typing` stays off this path. | STRING |
| HIGH | src/harlequin/hsql/modes/config.py | 0 | the one `--format` a document mode answers to. `none` writes nothing. | STRING |
| HIGH | src/harlequin/hsql/modes/spec.py | 0 | the one `--format` a document mode answers to. `none` writes nothing. | STRING |
| HIGH | src/harlequin/hsql/modes/info.py | 0 | the one `--format` a document mode answers to. `none` writes nothing. | STRING |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW | tests/conftest.py | 77 | def set_locale_to_enUS() -> None: | CODE |
| LOW | tests/functional_tests/conftest.py | 177 | def set_paste(x: str) -> None: | CODE |
| LOW | src/harlequin/keys_app.py | 396 | def update_binding(new_binding: HarlequinKeyBinding | None) -> None: | CODE |
| LOW | src/harlequin/keys_app.py | 427 | def update_keymap_name(self, message: ActiveKeymapFound) -> None: | CODE |
| LOW | src/harlequin/locale_manager.py | 6 | def set_locale(locale_config: str) -> None: | CODE |
| LOW | src/harlequin/catalog_cache.py | 24 | __all__ = [ | CODE |
| LOW | src/harlequin/cache.py | 9 | __all__ = ["BufferState", "Cache"] | CODE |
| LOW | src/harlequin/__init__.py | 38 | __all__ = [ | CODE |
| LOW⚡ | src/harlequin/app.py | 1080 | def update_transaction_button_label(self, message: TransactionModeChanged) -> None: | CODE |
| LOW | src/harlequin/app.py | 724 | def update_limit_tooltip(self, message: Input.Changed) -> None: | CODE |
| LOW | src/harlequin/app.py | 1102 | def update_editor_completers(self, message: CompletersReady) -> None: | CODE |
| LOW | src/harlequin/app.py | 1916 | def update_completers(self, catalog: Catalog) -> None: | CODE |
| LOW | src/harlequin/app.py | 1957 | def update_schema_data(self) -> None: | CODE |
| LOW | src/harlequin/autocomplete/__init__.py | 9 | __all__ = [ | CODE |
| LOW | src/harlequin/autocomplete/completers.py | 76 | def update_catalog(self, catalog: Catalog) -> None: | CODE |
| LOW | src/harlequin/autocomplete/completers.py | 93 | def update_buffer_symbols(self, symbols: BufferSymbols) -> None: | CODE |
| LOW | src/harlequin/hsql/__init__.py | 22 | __all__ = ["main"] | CODE |
| LOW | src/harlequin/components/__init__.py | 12 | __all__ = [ | CODE |
| LOW | src/harlequin/components/code_editor.py | 401 | def update_completer_symbols(self, message: CodeEditor.SymbolsFound) -> None: | CODE |
| LOW | src/harlequin/components/run_query_bar.py | 106 | def set_not_responsive(self) -> None: | CODE |
| LOW | src/harlequin/components/run_query_bar.py | 113 | def set_responsive(self) -> None: | CODE |
| LOW⚡ | src/harlequin/components/data_catalog/__init__.py | 235 | def update_database_tree(self, catalog: Catalog) -> None: | CODE |
| LOW⚡ | src/harlequin/components/data_catalog/__init__.py | 238 | def update_file_tree(self) -> None: | CODE |
| LOW⚡ | src/harlequin/components/data_catalog/__init__.py | 242 | def update_s3_tree(self) -> None: | CODE |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW | tests/functional_tests/test_crash.py | 51 | except Exception as caught: | CODE |
| LOW | src/harlequin/options.py | 252 | except Exception as e: | CODE |
| LOW | src/harlequin/query.py | 167 | except Exception as e: # noqa: BLE001 | CODE |
| LOW | src/harlequin/query.py | 253 | except Exception as e: | CODE |
| LOW | src/harlequin/windows_timezone.py | 133 | except Exception as e: | CODE |
| LOW | src/harlequin/copy_widgets.py | 36 | except Exception as e: | CODE |
| LOW | src/harlequin/bindings.py | 70 | except Exception as e: | CODE |
| LOW | src/harlequin/app.py | 1341 | except Exception: | CODE |
| LOW | src/harlequin/app.py | 1355 | except Exception: | CODE |
| LOW | src/harlequin/app.py | 1388 | except Exception: | CODE |
| LOW | src/harlequin/app.py | 1714 | except Exception as e: | CODE |
| LOW | src/harlequin/app.py | 1939 | except Exception: | CODE |
| LOW | src/harlequin/app.py | 2011 | except Exception as e: | CODE |
| LOW | src/harlequin/app.py | 2037 | except Exception as e: | CODE |
| LOW | src/harlequin/app.py | 2063 | except Exception as e: | CODE |
| LOW | src/harlequin/app.py | 2085 | except Exception as e: | CODE |
| LOW | src/harlequin/editor_cache.py | 155 | except Exception: | CODE |
| LOW | src/harlequin/hsql/server.py | 863 | except Exception as e: # noqa: BLE001 -- the server outlives a request | CODE |
| LOW | src/harlequin/hsql/server.py | 886 | except Exception: # noqa: BLE001 -- the server outlives a request | CODE |
| LOW | src/harlequin/hsql/server.py | 941 | except Exception as e: # noqa: BLE001 -- the server outlives a request | CODE |
| LOW | src/harlequin/hsql/server.py | 1066 | except Exception: | CODE |
| LOW | src/harlequin/hsql/__init__.py | 109 | except Exception: | CODE |
| LOW | src/harlequin/hsql/cli.py | 1724 | except Exception as e: # noqa: BLE001 -- adapters are third-party code | CODE |
| LOW | src/harlequin/hsql/cli.py | 1775 | except Exception as e: # noqa: BLE001 -- adapters are third-party code | CODE |
| LOW | src/harlequin/hsql/cli.py | 2363 | except Exception as e: # noqa: BLE001 -- adapters are third-party code | CODE |
| LOW | src/harlequin/components/debug_info.py | 81 | except Exception: | CODE |
| LOW | src/harlequin/components/debug_info.py | 85 | except Exception: | CODE |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW | tests/conftest.py | 284 | CODE | |
| LOW | tests/waiting.py | 184 | CODE | |
| LOW | tests/unit_tests/test_hsql_session.py | 386 | CODE | |
| LOW | tests/unit_tests/test_hsql_serve.py | 1062 | CODE | |
| LOW | tests/functional_tests/test_crash.py | 263 | CODE | |
| LOW | scripts/export_screenshots.py | 34 | CODE | |
| LOW | src/harlequin_sqlite/adapter.py | 361 | CODE | |
| LOW | src/harlequin_sqlite/adapter.py | 482 | CODE | |
| LOW | src/harlequin/layout.py | 260 | CODE | |
| LOW | src/harlequin/redact.py | 65 | CODE | |
| LOW | src/harlequin/app.py | 768 | CODE | |
| LOW | src/harlequin/app.py | 955 | CODE | |
| LOW | src/harlequin/app.py | 1112 | CODE | |
| LOW | src/harlequin/ssh.py | 371 | CODE | |
| LOW | src/harlequin/ssh.py | 843 | CODE | |
| LOW | src/harlequin/editor_cache.py | 161 | CODE | |
| LOW | src/harlequin/hsql/client.py | 265 | CODE | |
| LOW | src/harlequin/hsql/client.py | 312 | CODE | |
| LOW | src/harlequin/hsql/client.py | 338 | CODE | |
| LOW | src/harlequin/components/help_screen.py | 68 | CODE | |
| LOW | src/harlequin/components/debug_info.py | 262 | CODE | |
| LOW | src/harlequin/components/debug_info.py | 272 | CODE | |
| LOW | src/harlequin/components/data_catalog/s3_tree.py | 96 | CODE | |
| LOW | src/harlequin_duckdb/adapter.py | 481 | CODE |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| HIGH | src/harlequin/adapter.py | 84 | Executes query and returns a cursor (for a select stmt) or None. Raises HarlequinQueryError if the data | STRING |
| HIGH | src/harlequin/adapter.py | 119 | Returns every catalog item whose label contains term, matched case-insensitively, without walking the c | STRING |
| HIGH | src/harlequin/adapter.py | 157 | Exports data returned by query to a file or directory at path, using options. Args: | STRING |
| HIGH | src/harlequin/adapter.py | 175 | Parses text as one or more queries; returns text if parsing does not result in an error; otherwise retu | STRING |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| MEDIUM | pyproject.toml | 110 | # parses the skill's frontmatter the way a harness loading it would. Not a | COMMENT |
| LOW | src/harlequin/query_log.py | 542 | # Never raise a TypeError, just use the repr | COMMENT |
| MEDIUM | src/harlequin/hsql/diagnostics.py | 493 | # sys.stderr is resolved on each call, not bound at import: a test harness | COMMENT |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW | src/harlequin_sqlite/adapter.py | 422 | CODE | |
| LOW | src/harlequin/options.py | 393 | CODE | |
| LOW | src/harlequin/export.py | 236 | CODE | |
| LOW | src/harlequin/cli.py | 252 | CODE | |
| LOW | src/harlequin/app.py | 310 | CODE | |
| LOW | src/harlequin/hsql/server.py | 297 | CODE | |
| LOW | src/harlequin/components/results_viewer.py | 37 | CODE | |
| LOW | src/harlequin_duckdb/adapter.py | 436 | CODE |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW⚡ | tests/functional_tests/test_history_screen.py | 562 | one_liner = "select '" + "lorem ipsum dolor sit amet " * 200 + "';" | CODE |
| LOW⚡ | tests/functional_tests/test_history_screen.py | 562 | one_liner = "select '" + "lorem ipsum dolor sit amet " * 200 + "';" | CODE |
| LOW | src/harlequin/options.py | 212 | placeholder = self.placeholder or getattr(other, "placeholder", None) | CODE |
| LOW | src/harlequin/options.py | 450 | placeholder = self.placeholder or getattr(other, "placeholder", None) | CODE |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW | src/harlequin/hsql/diagnostics.py | 481 | if message is not None: | COMMENT |
| LOW | src/harlequin/hsql/cli.py | 241 | # `profile`, `config_path` and the mode flags are named rather than left | COMMENT |
| LOW | src/harlequin/hsql/cli.py | 541 | # a typed -P, -a or CONN_STR names one database and narrows the | COMMENT |
| LOW | src/harlequin/components/data_catalog/database_tree.py | 541 | # scrolled or collapsed out of view before we got to it, so | COMMENT |