NewsBlur is a personal news reader that brings people together to talk about the world. A new sound of an old instrument.
This report presents the forensic synthetic code analysis of samuelclay/NewsBlur, a Python project with 7,565 GitHub stars. SynthScan v2.0 examined 633,194 lines of code across 2903 source files, recording 2866 pattern matches distributed across 21 syntactic categories. The overall adjusted score of 5.5 places this repository in the Low AI signal band.
The scanner applied 160+ deterministic lexical heuristics, multi-line block detectors, abstract syntax tree depth profilers, and a cross-file Jaccard similarity matrix to construct a statistically normalised synthetic code estimate. All matches are individually weighted by severity coefficient and contextual multiplier before summation, and the resulting headline score is temporally discounted to account for the repository's development history relative to the commercial emergence of large language model coding tooling (November 2022 onward).
Longitudinal tracking requires multiple scan runs. Once this repository is re-scanned after new commits land, this chart will visualise how the synthetic code signal evolves over time — enabling you to detect whether AI authorship is growing, stabilising, or being actively corrected by human engineers.
Classifies detected patterns by their diagnostic confidence and structural impact. CRITICAL patterns (coefficient 10) represent definitive synthetic signatures — hallucinated imports, explicit LLM attribution metadata — virtually never produced by human authors. HIGH (5) indicates strong structural tells such as cross-file repetition or cross-linguistic idioms. MEDIUM (2) covers recognisable conversational padding and AI-specific vocabulary. LOW (1) captures subtle indicators like tautological comments and generic boilerplate that require density to carry independent signal.
This horizontal bar chart decomposes the repository's raw synthetic code score by top-level directory, allowing you to pinpoint precisely which modules or components carry the highest AI authorship density. Directories with disproportionately high scores relative to their size warrant targeted manual review: concentrated AI signatures often trace back to mass-generated configuration layers, auto-ported test suites, LLM-scaffolded boilerplate classes, or entire subsystems authored under heavy copilot assistance. Use this view to prioritise your human code-review effort.
The scanner identified 2866 distinct pattern matches across 21 syntactic categories. Each entry below represents a discrete location in the source code where the engine recorded a statistically significant AI authorship indicator. 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 diagnostic confidence level (CRITICAL / HIGH / MEDIUM / LOW). The Context column identifies whether the match occurred inside executable code, an inline comment, or a string literal — comment-context matches receive a ×1.5 weight because LLMs systematically over-annotate. The ⚡ bolt icon marks clustered matches: three or more patterns within a 10-line window, each receiving an additional ×1.5 density multiplier as dense clusters constitute far stronger evidence of synthetic authorship than isolated hits.
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW | clients/browser-extension/src/options/options.js | 505 | async function handleRemoveBlockedDomain(domain) { | CODE |
| LOW | clients/browser-extension/src/popup/popup.js | 139 | async function syncPendingArchivesFromPopup() { | CODE |
| LOW | clients/ios/static/mark.js | 644 | value: function callNoMatchOnInvalidRanges(range, last) { | CODE |
| LOW | clients/ios/static/mark.js | 744 | value: function wrapRangeInMappedTextNode(dict, start, end, filterCb, eachCb) { | CODE |
| LOW | clients/ios/static/mark.js | 808 | value: function wrapMatchesAcrossElements(regex, ignoreGroups, filterCb, eachCb, endCb) { | CODE |
| LOW | clients/ios/static/storyDetailView.js | 256 | function applyClassifierHighlights(classifiers) { | CODE |
| LOW | archive/jammit.py | 98 | def javascript_tag_compressed(self, asset_package, asset_type_ext): | CODE |
| LOW | archive/jammit.py | 107 | def stylesheet_tag_compressed(self, asset_package, asset_type_ext): | CODE |
| LOW⚡ | archive/fabfile.py | 150 | def assign_digitalocean_roledefs(split=False): | CODE |
| LOW | archive/fabfile.py | 534 | def setup_repo_local_settings(): | CODE |
| LOW | archive/fabfile.py | 788 | def switch_forked_mongoengine(): | CODE |
| LOW | archive/fabfile.py | 1676 | def setup_original_page_server(): | CODE |
| LOW | archive/fabfile.py | 1761 | def setup_feeds_fetched_monitor(): | CODE |
| LOW | archive/ansible/do_inventory.py | 509 | def load_droplet_variables_for_host(self): | CODE |
| LOW | archive/api/newsblur.py | 169 | def mark_story_hashes_as_read(self, story_hashes): | CODE |
| LOW | utils/prometheus_worker_slots.py | 46 | def discard_corrupt_slot_files(prom_dir, slot): | CODE |
| LOW | utils/feed_fetcher.py | 180 | def fetch_url_with_scrapingbee(url): | CODE |
| LOW | utils/feed_fetcher.py | 217 | def openrss_corrected_address(self, address): | CODE |
| LOW | utils/feed_fetcher.py | 977 | def migrate_openrss_feed_address(self): | CODE |
| LOW | utils/feed_fetcher.py | 1331 | def compare_feed_attribute_changes(self): | CODE |
| LOW | utils/feed_fetcher.py | 1464 | def reset_database_connections(self): | CODE |
| LOW | utils/feed_fetcher.py | 1811 | def fetch_and_process_archive_pages(self, feed_id): | CODE |
| LOW | utils/feed_fetcher.py | 1999 | def count_unreads_for_subscribers(self, feed, new_story_count=0): | CODE |
| LOW | utils/feed_fetcher.py | 2072 | def calculate_feed_scores_with_stories(self, user_subs, stories): | CODE |
| LOW | utils/feed_fetcher.py | 2078 | def classify_stories_for_subscribers(self, feed, stories, new_story_count): | CODE |
| LOW | utils/feed_functions.py | 449 | def strip_underscore_from_feed_address(feed_address): | CODE |
| LOW | utils/feed_functions.py | 496 | def rewrite_openrss_to_feed_address(url): | CODE |
| LOW | utils/fields.py | 52 | def contribute_to_related_class(self, cls, related): | CODE |
| LOW | utils/user_functions.py | 123 | def invalidate_template_cache(fragment_name, *variables): | CODE |
| LOW | utils/ai_functions.py | 210 | def classify_stories_with_vision(prompt_classifier, stories, model="claude-haiku-4-5", user_id=None): | CODE |
| LOW | utils/reddit_fetcher.py | 111 | def normalized_listing_segments(self): | CODE |
| LOW | utils/reddit_fetcher.py | 131 | def should_fetch_original_rss(self): | CODE |
| LOW | utils/reddit_fetcher.py | 163 | def extract_listing_path_and_sort(self): | CODE |
| LOW | utils/youtube_fetcher.py | 37 | def strip_xml_control_characters(value): | CODE |
| LOW | utils/youtube_fetcher.py | 193 | def _thumbnail_url_from_snippet(self, payload): | CODE |
| LOW | utils/story_functions.py | 43 | def _normalize_image_url_for_dedup(url): | CODE |
| LOW | utils/story_functions.py | 84 | def _image_url_matches_content(media_url, story_content): | CODE |
| LOW | utils/story_functions.py | 118 | def format_story_link_date__short(date, now=None): | CODE |
| LOW | utils/story_functions.py | 131 | def format_story_link_date__long(date, now=None): | CODE |
| LOW | utils/story_functions.py | 214 | def strip_non_embeddable_iframes(content): | CODE |
| LOW | utils/story_functions.py | 399 | def restore_instagram_data_attributes(content): | CODE |
| LOW | utils/story_functions.py | 447 | def strip_tags_preserve_blockquote(html): | CODE |
| LOW | utils/story_functions.py | 610 | def create_imageproxy_signed_url(base_url, hmac_key, url, options=None): | CODE |
| LOW⚡ | utils/prometheus_middleware.py | 14 | def ensure_prometheus_directory(): | CODE |
| LOW | utils/mongo_raw_log_middleware.py | 93 | def _mongodb_decode_wire_protocol(message): | CODE |
| LOW⚡ | utils/test_prometheus_worker_slots.py | 112 | def test_first_worker_takes_slot_zero(self): | CODE |
| LOW⚡ | utils/test_prometheus_worker_slots.py | 115 | def test_next_worker_takes_the_next_slot(self): | CODE |
| LOW⚡ | utils/test_prometheus_worker_slots.py | 118 | def test_a_reaped_workers_slot_is_reused(self): | CODE |
| LOW⚡ | utils/test_prometheus_worker_slots.py | 128 | def test_live_workers_never_share_a_slot(self): | CODE |
| LOW | utils/test_prometheus_worker_slots.py | 150 | def test_recycled_worker_resumes_the_dead_workers_counters(self): | CODE |
| LOW | utils/test_prometheus_worker_slots.py | 164 | def test_rolling_recycles_never_decrease_the_counter(self): | CODE |
| LOW | utils/test_prometheus_worker_slots.py | 185 | def test_file_count_stays_bounded_across_many_recycles(self): | CODE |
| LOW | utils/test_prometheus_worker_slots.py | 194 | def test_file_count_tracks_peak_concurrency(self): | CODE |
| LOW | utils/test_prometheus_worker_slots.py | 206 | def test_corrupt_slot_file_is_discarded_before_reuse(self): | CODE |
| LOW | utils/test_prometheus_worker_slots.py | 219 | def test_corrupt_file_from_a_dead_worker_does_not_break_the_next_worker(self): | CODE |
| LOW | utils/test_prometheus_middleware.py | 19 | def test_requests_preserve_dead_worker_counter_files( | CODE |
| LOW | utils/llm_costs.py | 250 | def _report_stripe_meter_event(cls, feature, user_id, profile=None): | CODE |
| LOW | utils/S3.py | 108 | def query_args_hash_to_string(query_args): | CODE |
| LOW | utils/db_functions.py | 13 | def mongo_max_replication_lag(connection): | CODE |
| LOW | utils/test_haproxy_batch_state.py | 26 | def test_parse_show_servers_state_keeps_first_server_after_version_preamble(self): | STRING |
| 1052 more matches not shown… | ||||
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| MEDIUM⚡ | archive/fabfile.py | 140 | # ================ | COMMENT |
| MEDIUM⚡ | archive/fabfile.py | 142 | # ================ | COMMENT |
| MEDIUM⚡ | archive/fabfile.py | 1959 | # =============== | COMMENT |
| MEDIUM⚡ | archive/fabfile.py | 1961 | # =============== | COMMENT |
| MEDIUM | archive/fabfile.py | 47 | # ============ | COMMENT |
| MEDIUM | archive/fabfile.py | 49 | # ============ | COMMENT |
| MEDIUM | archive/fabfile.py | 227 | # ============= | COMMENT |
| MEDIUM | archive/fabfile.py | 229 | # ============= | COMMENT |
| MEDIUM | archive/fabfile.py | 385 | # ================== | COMMENT |
| MEDIUM | archive/fabfile.py | 387 | # ================== | COMMENT |
| MEDIUM | archive/fabfile.py | 406 | # ================== | COMMENT |
| MEDIUM | archive/fabfile.py | 408 | # ================== | COMMENT |
| MEDIUM | archive/fabfile.py | 882 | # =============== | COMMENT |
| MEDIUM | archive/fabfile.py | 884 | # =============== | COMMENT |
| MEDIUM | archive/fabfile.py | 1283 | # ============== | COMMENT |
| MEDIUM | archive/fabfile.py | 1285 | # ============== | COMMENT |
| MEDIUM | archive/fabfile.py | 1789 | # ================ | COMMENT |
| MEDIUM | archive/fabfile.py | 1791 | # ================ | COMMENT |
| MEDIUM | archive/fabfile.py | 1850 | # ========================= | COMMENT |
| MEDIUM | archive/fabfile.py | 1852 | # ========================= | COMMENT |
| MEDIUM | archive/fabfile.py | 1994 | # ========== | COMMENT |
| MEDIUM | archive/fabfile.py | 1996 | # ========== | COMMENT |
| MEDIUM | archive/fabfile.py | 2211 | # =========== | COMMENT |
| MEDIUM | archive/fabfile.py | 2213 | # =========== | COMMENT |
| MEDIUM | archive/fabfile.py | 2259 | # =============== | COMMENT |
| MEDIUM | archive/fabfile.py | 2261 | # =============== | COMMENT |
| MEDIUM | archive/fabfile.py | 2281 | # ============== | COMMENT |
| MEDIUM | archive/fabfile.py | 2283 | # ============== | COMMENT |
| MEDIUM | utils/check_health.sh | 59 | # ===================== | COMMENT |
| MEDIUM | utils/check_health.sh | 61 | # ===================== | COMMENT |
| MEDIUM | utils/check_health.sh | 145 | # ===================== | COMMENT |
| MEDIUM | utils/check_health.sh | 147 | # ===================== | COMMENT |
| MEDIUM | utils/check_health.sh | 364 | # ===================== | COMMENT |
| MEDIUM | utils/check_health.sh | 366 | # ===================== | COMMENT |
| MEDIUM⚡ | newsblur_web/docker_local_settings.py | 4 | # =================== | COMMENT |
| MEDIUM⚡ | newsblur_web/docker_local_settings.py | 6 | # =================== | COMMENT |
| MEDIUM⚡ | newsblur_web/docker_local_settings.py | 16 | # =================== | COMMENT |
| MEDIUM⚡ | newsblur_web/docker_local_settings.py | 18 | # =================== | COMMENT |
| MEDIUM⚡ | newsblur_web/docker_local_settings.py | 86 | # =============== | COMMENT |
| MEDIUM⚡ | newsblur_web/docker_local_settings.py | 88 | # =============== | COMMENT |
| MEDIUM⚡ | newsblur_web/docker_local_settings.py | 96 | # ============= | COMMENT |
| MEDIUM⚡ | newsblur_web/docker_local_settings.py | 98 | # ============= | COMMENT |
| MEDIUM | newsblur_web/docker_local_settings.py | 156 | # =========== | COMMENT |
| MEDIUM | newsblur_web/docker_local_settings.py | 158 | # =========== | COMMENT |
| MEDIUM⚡ | newsblur_web/settings.py | 351 | # ============== | COMMENT |
| MEDIUM⚡ | newsblur_web/settings.py | 353 | # ============== | COMMENT |
| MEDIUM⚡ | newsblur_web/settings.py | 362 | # =========== | COMMENT |
| MEDIUM⚡ | newsblur_web/settings.py | 364 | # =========== | COMMENT |
| MEDIUM⚡ | newsblur_web/settings.py | 369 | # =============== | COMMENT |
| MEDIUM⚡ | newsblur_web/settings.py | 371 | # =============== | COMMENT |
| MEDIUM⚡ | newsblur_web/settings.py | 699 | # ================= | COMMENT |
| MEDIUM⚡ | newsblur_web/settings.py | 701 | # ================= | COMMENT |
| MEDIUM⚡ | newsblur_web/settings.py | 707 | # ==================== | COMMENT |
| MEDIUM⚡ | newsblur_web/settings.py | 709 | # ==================== | COMMENT |
| MEDIUM⚡ | newsblur_web/settings.py | 1043 | # ================== | COMMENT |
| MEDIUM⚡ | newsblur_web/settings.py | 1045 | # ================== | COMMENT |
| MEDIUM⚡ | newsblur_web/settings.py | 1054 | # ========== | COMMENT |
| MEDIUM⚡ | newsblur_web/settings.py | 1056 | # ========== | COMMENT |
| MEDIUM⚡ | newsblur_web/settings.py | 1061 | # ========== | COMMENT |
| MEDIUM⚡ | newsblur_web/settings.py | 1063 | # ========== | COMMENT |
| 177 more matches not shown… | ||||
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW | ansible.cfg | 21 | # Retry establishing the SSH connection this many times before marking a host | COMMENT |
| LOW | clients/ios/Classes/OfflineCleanImages.h | 1 | // | COMMENT |
| LOW | clients/ios/Classes/HorizontalPageDelegate.swift | 1 | // | COMMENT |
| LOW | clients/ios/Classes/HorizontalPageDelegate.swift | 21 | // | COMMENT |
| LOW | clients/ios/Classes/HorizontalPageDelegate.swift | 41 | // let pageIndex = (currentViewController.pageIndex ?? -1) - 1 | COMMENT |
| LOW | clients/ios/Classes/HorizontalPageDelegate.swift | 61 | // | COMMENT |
| LOW | clients/ios/Classes/SmallActivityCell.m | 1 | // | COMMENT |
| LOW | clients/ios/Classes/DividerView.swift | 1 | // | COMMENT |
| LOW | clients/ios/Classes/SiteCell.m | 1 | // | COMMENT |
| LOW | clients/ios/Classes/ActivitiesNavigationBar.m | 1 | // | COMMENT |
| LOW | clients/ios/Classes/ActivitiesNavigationBar.m | 21 | // subViewFrame.size.height = 64; | COMMENT |
| LOW | clients/ios/Classes/FeedDetailTableCell.m | 1 | // | COMMENT |
| LOW | clients/ios/Classes/FontSettingsViewController.m | 1 | // | COMMENT |
| LOW | clients/ios/Classes/ThemeManager.m | 1 | // | COMMENT |
| LOW | clients/ios/Classes/SmallInteractionCell.m | 1 | // | COMMENT |
| LOW | clients/ios/Classes/CustomIconRenderer.swift | 1 | // | COMMENT |
| LOW | clients/ios/Classes/InteractionCell.m | 1 | // | COMMENT |
| LOW | clients/ios/Classes/FriendsListViewController.m | 1 | // | COMMENT |
| LOW | clients/ios/Classes/AddSiteViewController.m | 1 | // | COMMENT |
| LOW | clients/ios/Classes/FeedTableCell.m | 1 | // | COMMENT |
| LOW | clients/ios/Classes/FeedChooserViewController.m | 1 | // | COMMENT |
| LOW | clients/ios/Classes/StoryDetailObjCViewController.m | 1 | // | COMMENT |
| LOW | clients/ios/Classes/StoryPagesObjCViewController.h | 1 | // | COMMENT |
| LOW | clients/ios/Classes/AuxSceneDelegate.swift | 61 | //TODO: 🚧 perhaps make a toolbar for this window | COMMENT |
| LOW | clients/ios/Classes/LoginViewController.m | 1 | // | COMMENT |
| LOW | clients/ios/Classes/DetailViewController.swift | 1 | // | COMMENT |
| LOW | clients/ios/Classes/DashList.swift | 161 | } | COMMENT |
| LOW | clients/ios/Classes/NewsBlurAppDelegate.m | 1 | // NewsBlurAppDelegate.m | COMMENT |
| LOW | clients/ios/Classes/NewsBlurAppDelegate.m | 21 | #import "FeedChooserViewController.h" | COMMENT |
| LOW | clients/ios/Classes/NewsBlurAppDelegate.m | 41 | #import "SBJson4.h" | COMMENT |
| LOW | clients/ios/Classes/NewsBlurAppDelegate.m | 401 | // NSTimeInterval daysInterval = 60 * 60; | COMMENT |
| LOW | clients/ios/Classes/NewsBlurAppDelegate.m | 2241 | [self reloadFeedsView:NO]; | COMMENT |
| LOW | clients/ios/Classes/FirstTimeUserViewController.m | 1 | // | COMMENT |
| LOW | clients/ios/Classes/ProfileBadge.m | 1 | // | COMMENT |
| LOW | clients/ios/Classes/FeedDetailObjCViewController.h | 1 | // | COMMENT |
| LOW | clients/ios/Classes/AddSiteTableCell.m | 1 | // | COMMENT |
| LOW | clients/ios/Classes/ShareViewController.m | 1 | // | COMMENT |
| LOW | clients/ios/Classes/ActivityCell.m | 1 | // | COMMENT |
| LOW | clients/ios/Classes/FeedsObjCViewController.m | 1 | // | COMMENT |
| LOW | clients/ios/Classes/FeedsObjCViewController.m | 21 | #import "Utilities.h" | COMMENT |
| LOW | clients/ios/Classes/FeedsObjCViewController.m | 721 | } | COMMENT |
| LOW | clients/ios/Classes/FeedsObjCViewController.m | 1021 | [userPreferences synchronize]; | COMMENT |
| LOW | clients/ios/Classes/FeedsObjCViewController.m | 1041 | // [settingsButton setImage:[[ThemeManager themeManager] themedImage:settingsImage] forState:UIControlStateNormal]; | COMMENT |
| LOW | clients/ios/Classes/StoriesCollection.m | 1 | // | COMMENT |
| LOW | clients/ios/Classes/SmallInteractionCell.h | 1 | // | COMMENT |
| LOW | clients/ios/Classes/ThemeManager.h | 1 | // | COMMENT |
| LOW | clients/ios/Classes/StoryDetailViewController.swift | 1 | // | COMMENT |
| LOW | clients/ios/Classes/NBCopyLinkActivity.h | 1 | // | COMMENT |
| LOW | clients/ios/Classes/ActivitiesNavigationBar.h | 1 | // | COMMENT |
| LOW | clients/ios/Classes/SiteCell.h | 1 | // | COMMENT |
| LOW | clients/ios/Classes/Storyboards.swift | 1 | // | COMMENT |
| LOW | clients/ios/Classes/ActivityModule.m | 1 | // | COMMENT |
| LOW | clients/ios/Classes/OfflineCleanImages.m | 1 | // | COMMENT |
| LOW | clients/ios/Classes/FontListViewController.m | 1 | // | COMMENT |
| LOW | clients/ios/Classes/SmallActivityCell.h | 1 | // | COMMENT |
| LOW | …ts/ios/Classes/FirstTimeUserAddFriendsViewController.m | 41 | COMMENT | |
| LOW | clients/ios/Classes/UserTagsViewController.m | 1 | // | COMMENT |
| LOW | clients/ios/Classes/FeedTableCell.h | 1 | // | COMMENT |
| LOW | clients/ios/Classes/NewsBlurApplication.h | 1 | // | COMMENT |
| LOW | clients/ios/Classes/MarkReadMenuViewController.m | 1 | // | COMMENT |
| 303 more matches not shown… | ||||
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| MEDIUM | clients/ios/run_ios.py | 214 | print("Error: No simulator UDID specified.\n") | CODE |
| MEDIUM | clients/ios/Classes/AuxSceneDelegate.swift | 31 | print("Error activating scene: \(error)") | CODE |
| MEDIUM | clients/ios/Classes/AuxSceneDelegate.swift | 35 | print("Error activating scene: \(error)") | CODE |
| MEDIUM | clients/ios/scripts/convert_icons_to_pdf.py | 23 | print("Error: cairosvg is required. Install with: pip install cairosvg") | CODE |
| LOW | clients/ios/scripts/convert_icons_to_pdf.py | 47 | except Exception as e: | CODE |
| MEDIUM | clients/android/run_android.py | 898 | print(f"Error: {exc}", file=sys.stderr) | CODE |
| MEDIUM | …NewsBlur Archive/NewsBlur Archive/ViewController.swift | 62 | print("Error opening Safari preferences: \(error)") | STRING |
| LOW | archive/fabfile.py | 2190 | except Exception as e: | CODE |
| LOW | archive/munin/munin/__init__.py | 57 | except Exception as exc: | CODE |
| LOW | config/gunicorn_conf.py | 64 | except Exception as e: | CODE |
| LOW | utils/analytics_degradation.py | 90 | except Exception as e: | CODE |
| LOW | utils/prometheus_worker_slots.py | 68 | except Exception as e: | CODE |
| LOW | utils/json_functions.py | 156 | except Exception as e: | CODE |
| LOW | utils/feed_fetcher.py | 205 | except Exception as e: | CODE |
| LOW | utils/feed_fetcher.py | 633 | except Exception as e: | CODE |
| LOW | utils/feed_fetcher.py | 831 | except Exception as e: | CODE |
| LOW | utils/feed_fetcher.py | 919 | except Exception as e: | CODE |
| LOW | utils/feed_fetcher.py | 945 | except Exception: | CODE |
| LOW | utils/feed_fetcher.py | 1356 | except Exception as e: | CODE |
| LOW | utils/feed_fetcher.py | 1640 | except Exception as e: | CODE |
| LOW | utils/feed_fetcher.py | 1709 | except Exception as e: | CODE |
| LOW | utils/feed_fetcher.py | 1745 | except Exception as e: | CODE |
| LOW | utils/ai_functions.py | 153 | except Exception as e: | CODE |
| LOW | utils/ai_functions.py | 205 | except Exception as e: | CODE |
| LOW | utils/ai_functions.py | 401 | except Exception as e: | CODE |
| LOW | utils/reddit_fetcher.py | 484 | except Exception: | CODE |
| LOW | utils/youtube_fetcher.py | 230 | except Exception: | CODE |
| LOW | utils/youtube_fetcher.py | 244 | except Exception: | CODE |
| LOW | utils/youtube_fetcher.py | 283 | except Exception: | CODE |
| LOW | utils/tornado_escape.py | 38 | except Exception: | CODE |
| LOW | utils/story_functions.py | 49 | except Exception: | CODE |
| LOW | utils/story_functions.py | 232 | except Exception: | CODE |
| LOW | utils/ip_rate_tracker.py | 333 | except Exception: | CODE |
| LOW | utils/ip_rate_tracker.py | 658 | except Exception: | CODE |
| LOW | utils/ip_rate_tracker.py | 745 | except Exception: | CODE |
| LOW⚡ | utils/prometheus_middleware.py | 21 | except Exception as e: | CODE |
| LOW | utils/prometheus_middleware.py | 43 | except Exception as retry_error: | CODE |
| LOW | utils/prometheus_middleware.py | 56 | except Exception as e: | CODE |
| MEDIUM | utils/prometheus_middleware.py | 33 | def __call__(self, request): | CODE |
| LOW | utils/feedfinder_forman.py | 45 | except Exception as e: | CODE |
| MEDIUM | utils/feedfinder_forman.py | 40 | def get_feed(self, url, skip_user_agent=False): | CODE |
| LOW⚡ | utils/webfeed_fetcher.py | 177 | except Exception: | CODE |
| LOW⚡ | utils/webfeed_fetcher.py | 184 | except Exception: | CODE |
| LOW⚡ | utils/webfeed_fetcher.py | 194 | except Exception: | CODE |
| LOW⚡ | utils/webfeed_fetcher.py | 204 | except Exception: | CODE |
| LOW⚡ | utils/webfeed_fetcher.py | 212 | except Exception: | CODE |
| LOW⚡ | utils/webfeed_fetcher.py | 226 | except Exception: | CODE |
| LOW⚡ | utils/webfeed_fetcher.py | 236 | except Exception: | CODE |
| LOW⚡ | utils/webfeed_fetcher.py | 246 | except Exception: | CODE |
| LOW | utils/llm_costs.py | 199 | except Exception: | CODE |
| LOW | utils/llm_costs.py | 214 | except Exception as e: | CODE |
| LOW | utils/llm_costs.py | 245 | except Exception as e: | CODE |
| LOW | utils/llm_costs.py | 279 | except Exception as e: | CODE |
| LOW | utils/llm_costs.py | 291 | except Exception: | CODE |
| LOW | utils/monitor_task_fetches.py | 32 | except Exception as e: | CODE |
| LOW | utils/monitor_work_queue.py | 30 | except Exception as e: | CODE |
| LOW | utils/bluesky_fetcher.py | 37 | except Exception as e: | CODE |
| LOW | utils/view_functions.py | 99 | except Exception as e: | CODE |
| LOW | utils/archive/bootstrap_story_hash.py | 30 | except Exception as e: | CODE |
| LOW | utils/backups/offsite_pull.sh | 183 | except Exception: | CODE |
| 195 more matches not shown… | ||||
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW | clients/ios/run_ios.py | 156 | CODE | |
| LOW | clients/android/run_android.py | 623 | CODE | |
| LOW | archive/jammit.py | 34 | CODE | |
| LOW | archive/fabfile.py | 322 | CODE | |
| LOW | archive/fabfile.py | 577 | CODE | |
| LOW | archive/fabfile.py | 594 | CODE | |
| LOW | archive/fabfile.py | 1115 | CODE | |
| LOW | archive/fabfile.py | 1196 | CODE | |
| LOW | archive/fabfile.py | 2053 | CODE | |
| LOW | archive/fabfile.py | 2375 | CODE | |
| LOW | archive/munin/munin/cassandra.py | 26 | CODE | |
| LOW | archive/munin/munin/cassandra.py | 52 | CODE | |
| LOW | archive/munin/munin/__init__.py | 27 | CODE | |
| LOW | archive/munin/munin/__init__.py | 47 | CODE | |
| LOW | archive/munin/munin/mysql.py | 13 | CODE | |
| LOW | archive/ansible/do_inventory.py | 162 | CODE | |
| LOW | archive/ansible/do_inventory.py | 227 | CODE | |
| LOW | utils/zgrep.py | 117 | CODE | |
| LOW | utils/json_fetcher.py | 86 | CODE | |
| LOW | utils/json_functions.py | 43 | CODE | |
| LOW | utils/json_functions.py | 50 | CODE | |
| LOW | utils/feed_fetcher.py | 238 | CODE | |
| LOW | utils/feed_fetcher.py | 1004 | CODE | |
| LOW | utils/feed_fetcher.py | 1211 | CODE | |
| LOW | utils/feed_fetcher.py | 1486 | CODE | |
| LOW | utils/feed_fetcher.py | 1811 | CODE | |
| LOW | utils/rtail.py | 17 | CODE | |
| LOW | utils/feed_functions.py | 174 | CODE | |
| LOW | utils/feed_functions.py | 196 | CODE | |
| LOW | utils/feed_functions.py | 315 | CODE | |
| LOW | utils/log.py | 29 | CODE | |
| LOW | utils/redis_raw_log_middleware.py | 89 | CODE | |
| LOW | utils/redis_raw_log_middleware.py | 112 | CODE | |
| LOW | utils/feedfinder_pilgrim.py | 407 | CODE | |
| LOW | utils/tlnb.py | 34 | CODE | |
| LOW | utils/tlnb.py | 110 | CODE | |
| LOW | utils/tlnb.py | 160 | CODE | |
| LOW | utils/user_functions.py | 135 | CODE | |
| LOW | utils/ai_functions.py | 33 | CODE | |
| LOW | utils/ai_functions.py | 158 | CODE | |
| LOW | utils/ai_functions.py | 210 | CODE | |
| LOW | utils/reddit_fetcher.py | 179 | CODE | |
| LOW | utils/youtube_fetcher.py | 174 | CODE | |
| LOW | utils/youtube_fetcher.py | 287 | CODE | |
| LOW | utils/youtube_fetcher.py | 513 | CODE | |
| LOW | utils/tornado_escape.py | 212 | CODE | |
| LOW | utils/story_functions.py | 148 | CODE | |
| LOW | utils/story_functions.py | 241 | CODE | |
| LOW | utils/image_functions.py | 52 | CODE | |
| LOW | utils/ip_rate_tracker.py | 698 | CODE | |
| LOW | utils/twitter_fetcher.py | 121 | CODE | |
| LOW | utils/twitter_fetcher.py | 174 | CODE | |
| LOW | utils/twitter_fetcher.py | 239 | CODE | |
| LOW | utils/twitter_fetcher.py | 284 | CODE | |
| LOW | utils/twitter_fetcher.py | 346 | CODE | |
| LOW | utils/twitter_fetcher.py | 406 | CODE | |
| LOW | utils/webfeed_fetcher.py | 111 | CODE | |
| LOW | utils/webfeed_fetcher.py | 173 | CODE | |
| LOW | utils/mongo_command_monitor.py | 18 | CODE | |
| LOW | utils/facebook_fetcher.py | 20 | CODE | |
| 271 more matches not shown… | ||||
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW | clients/ios/scripts/convert_icons_to_pdf.py | 16 | CODE | |
| LOW | clients/android/run_android.py | 56 | CODE | |
| LOW | archive/munin/munin/cassandra.py | 4 | CODE | |
| LOW | archive/munin/munin/riak.py | 9 | CODE | |
| LOW | archive/munin/munin/ddwrt.py | 4 | CODE | |
| LOW | archive/ansible/do_inventory.py | 124 | CODE | |
| LOW | archive/ansible/do_inventory.py | 124 | CODE | |
| LOW | archive/ansible/do_inventory.py | 124 | CODE | |
| LOW | archive/perf/locust.py | 1 | CODE | |
| LOW | archive/perf/locust.py | 2 | CODE | |
| LOW | archive/perf/locust.py | 4 | CODE | |
| LOW | utils/zgrep.py | 6 | CODE | |
| LOW | utils/zgrep.py | 11 | CODE | |
| LOW | utils/feed_fetcher.py | 54 | CODE | |
| LOW | utils/feed_fetcher.py | 56 | CODE | |
| LOW | utils/feed_fetcher.py | 58 | CODE | |
| LOW | utils/feed_fetcher.py | 76 | CODE | |
| LOW | utils/feed_functions.py | 9 | CODE | |
| LOW | utils/redis_raw_log_middleware.py | 1 | CODE | |
| LOW | utils/redis_raw_log_middleware.py | 5 | CODE | |
| LOW | utils/tlnb.py | 6 | CODE | |
| LOW | utils/ai_functions.py | 10 | CODE | |
| LOW | utils/ai_functions.py | 11 | CODE | |
| LOW | utils/youtube_fetcher.py | 15 | CODE | |
| LOW | utils/youtube_fetcher.py | 16 | CODE | |
| LOW | utils/story_functions.py | 14 | CODE | |
| LOW | utils/hostname_ssh.py | 7 | CODE | |
| LOW | utils/mongo_raw_log_middleware.py | 5 | CODE | |
| LOW | utils/mongo_raw_log_middleware.py | 6 | CODE | |
| LOW | utils/mongo_raw_log_middleware.py | 8 | CODE | |
| LOW | utils/mongo_raw_log_middleware.py | 13 | CODE | |
| LOW | utils/webfeed_fetcher.py | 1 | CODE | |
| LOW | utils/webfeed_fetcher.py | 10 | CODE | |
| LOW | utils/exception_middleware.py | 7 | CODE | |
| LOW | utils/exception_middleware.py | 10 | CODE | |
| LOW | utils/monitor_work_queue.py | 9 | CODE | |
| LOW | utils/S3.py | 15 | CODE | |
| LOW | utils/S3.py | 16 | CODE | |
| LOW | utils/templatetags/utils_tags.py | 4 | CODE | |
| LOW | utils/templatetags/utils_tags.py | 11 | CODE | |
| LOW | utils/templatetags/utils_tags.py | 12 | CODE | |
| LOW | utils/templatetags/utils_tags.py | 12 | CODE | |
| LOW | utils/templatetags/utils_tags.py | 24 | CODE | |
| LOW | utils/archive/memcached_status.py | 2 | CODE | |
| LOW | utils/backups/offsite_status.py | 13 | CODE | |
| LOW | ansible/utils/generate_hetzner_inventory.py | 3 | CODE | |
| LOW | ansible/utils/generate_hetzner_inventory.py | 4 | CODE | |
| LOW | ansible/utils/generate_hetzner_inventory.py | 5 | CODE | |
| LOW | ansible/utils/generate_hetzner_inventory.py | 6 | CODE | |
| LOW | ansible/utils/generate_hetzner_inventory.py | 12 | CODE | |
| LOW | flask_monitor/flask_settings.py | 8 | CODE | |
| LOW | flask_monitor/db_monitor.py | 1 | CODE | |
| LOW | newsblur_web/__init__.py | 1 | CODE | |
| LOW | newsblur_web/__init__.py | 1 | CODE | |
| LOW | newsblur_web/__init__.py | 5 | CODE | |
| LOW | newsblur_web/settings.py | 769 | CODE | |
| LOW | newsblur_web/settings.py | 772 | CODE | |
| LOW | newsblur_web/settings.py | 778 | CODE | |
| LOW | newsblur_web/settings.py | 785 | CODE | |
| LOW | newsblur_web/celeryapp.py | 1 | CODE | |
| 199 more matches not shown… | ||||
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW | worktree-dev.sh | 93 | # Check if setup has been run | COMMENT |
| LOW | worktree-dev.sh | 177 | # Check if we can copy from parent repo (handle both regular repo and worktree) | COMMENT |
| LOW | worktree-dev.sh | 206 | # Check if shared services are already running (using original container names) | COMMENT |
| LOW | worktree-dev.sh | 396 | # Check if this worktree already has chrome-devtools configured with --isolated | COMMENT |
| LOW | worktree-dev.sh | 413 | # Check if shared services are already running | COMMENT |
| LOW | worktree-dev.sh | 522 | # Check if any container is in Exited state (potential broken network) | COMMENT |
| LOW | clients/ios/scripts/fix_alpha_target.rb | 32 | # Check if already added to Alpha target | COMMENT |
| LOW | clients/ios/scripts/add_files_to_xcode.rb | 36 | # Check if files already exist in project | COMMENT |
| LOW | clients/ios/scripts/add_files_to_xcode.rb | 65 | # Check if Icons group/reference already exists | COMMENT |
| LOW | clients/safari-extension/build.sh | 20 | # Check if browser extension exists | COMMENT |
| LOW | archive/netdata_docker/vars/main.yml | 10 | # Set whether to run the Agent web server/dashboard/API, or disable them. | COMMENT |
| LOW | utils/test_haproxy_toggle.sh | 119 | # Display results | COMMENT |
| LOW⚡ | utils/feed_fetcher.py | 130 | # Check if any of the indicators are present | COMMENT |
| LOW | utils/feed_fetcher.py | 1051 | # Check if caller requested a specific max_stories limit (e.g. bootstrap_popular_feeds) | COMMENT |
| LOW | utils/feed_fetcher.py | 1056 | # Check if this is a high-volume feed that can handle more stories | COMMENT |
| LOW | utils/retry_unlinked_loop.sh | 33 | # Check if there are no more unlinked feeds | COMMENT |
| LOW | utils/story_functions.py | 362 | # Check if wrapper has height:0 and padding-bottom (responsive embed pattern) | COMMENT |
| LOW | utils/feedfinder_forman.py | 112 | # Check if it is already a feed. | COMMENT |
| LOW | utils/search_openrss_24h.py | 63 | # Check if within last 24 hours | COMMENT |
| LOW | utils/bootstrap_loop.sh | 65 | # Check if we've processed all entries | COMMENT |
| LOW | utils/load_test_deploy.sh | 113 | # Display results | COMMENT |
| LOW | utils/view_functions.py | 80 | # Check if in_progress cleared but no result (request failed) | COMMENT |
| LOW | utils/view_functions.py | 173 | # Check if parameter is included | COMMENT |
| LOW | utils/view_functions.py | 179 | # Check if parameter is correct type | COMMENT |
| LOW | utils/ssh_hz.sh | 33 | # Check if an alias is provided | COMMENT |
| LOW | utils/ssh_hz.sh | 57 | # Check if a host was found | COMMENT |
| LOW | ansible/roles/consul/tasks/get_consul_manager_ip.py | 34 | # Check if the group exists | COMMENT |
| LOW | newsblur_web/docker_local_settings.py | 66 | # Set this to the username that is shown on the homepage to unauthenticated users. | COMMENT |
| LOW | newsblur_web/settings.py | 808 | # Set traces_sample_rate to 1.0 to capture 100% | COMMENT |
| LOW | newsblur_mcp/newsblur_mcp/cli/auth.py | 338 | # Check if expired | COMMENT |
| LOW | flask_metrics/flask_metrics_postgres.py | 51 | # Check if this is a primary by looking for connected replicas | COMMENT |
| LOW | flask_metrics/flask_metrics_postgres.py | 182 | # Check if we're in recovery (i.e., a replica) | COMMENT |
| LOW | apps/reader/models.py | 1614 | # Check if user is archive and story is outside unread cutoff | COMMENT |
| LOW | apps/reader/models.py | 3408 | # Check if user already has a custom icon for the original feed | COMMENT |
| LOW | apps/reader/views.py | 1322 | # Check if user wants YouTube captions enabled | COMMENT |
| LOW | apps/reader/views.py | 2768 | # Check if user wants YouTube captions enabled | COMMENT |
| LOW | apps/reader/views.py | 3019 | # Check if path can be encoded as ASCII | COMMENT |
| LOW | apps/reader/views.py | 3797 | # Check if Twitter API is active for user | COMMENT |
| LOW | apps/reader/views.py | 5812 | # Check if user is archive tier (required for this feature) | COMMENT |
| LOW | apps/reader/views.py | 5877 | # Check if user is archive tier (required for this feature) | COMMENT |
| LOW | apps/rss_feeds/models.py | 4826 | # Check if new_tag (case-insensitive) is already present | COMMENT |
| LOW | apps/rss_feeds/text_importer.py | 135 | # Check if we should try UTF-8 first. | COMMENT |
| LOW | apps/rss_feeds/page_importer.py | 128 | # Check if the HTML declares UTF-8 charset and use that instead. | COMMENT |
| LOW | apps/rss_feeds/page_importer.py | 286 | # Check if the HTML declares UTF-8 charset and use that instead. | COMMENT |
| LOW | apps/rss_feeds/test_rss_feeds.py | 365 | # Check if we're getting the right format | COMMENT |
| LOW | apps/discover/views.py | 1488 | # Check if a Feed with this address already exists | COMMENT |
| LOW⚡ | …/management/commands/index_popular_feeds_for_search.py | 114 | # Check if already indexed (unless reindexing) | COMMENT |
| LOW | apps/oauth/views.py | 928 | # Check if this is a browser extension redirect | COMMENT |
| LOW | apps/newsletters/views.py | 149 | # Check if it looks like ImprovMX format | COMMENT |
| LOW | apps/ask_ai/views.py | 176 | # Read the file content from Django's InMemoryUploadedFile | COMMENT |
| LOW | apps/webfeed/views.py | 147 | # Check if feed already exists | COMMENT |
| LOW | apps/clustering/models.py | 791 | # Check if any member already belongs to an existing cluster | COMMENT |
| LOW | apps/search/models.py | 755 | # Check if index exists | COMMENT |
| LOW | apps/search/models.py | 881 | # Check if already indexed to avoid expensive vector generation | COMMENT |
| LOW | apps/search/models.py | 1099 | # Check if index exists | COMMENT |
| LOW | apps/search/models.py | 1636 | # Check if index exists | COMMENT |
| LOW | apps/profile/models.py | 2390 | # Check if there's already an active subscription | COMMENT |
| LOW | apps/profile/middleware.py | 868 | # Check if rate limit would be exceeded | COMMENT |
| LOW | …ps/profile/management/commands/generate_dev_session.py | 28 | # Check if we're in development | COMMENT |
| LOW | …ps/profile/management/commands/generate_dev_session.py | 35 | # Check if session file exists and is not being forced to regenerate | COMMENT |
| 7 more matches not shown… | ||||
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW | clients/ios/CLAUDE.md | 154 | # Step 1: Find available simulators and their UDIDs | COMMENT |
| LOW | clients/ios/CLAUDE.md | 157 | # Step 2: Use --udid with any action | COMMENT |
| LOW | clients/ios/Classes/NewsBlurAppDelegate.m | 5613 | // Step 1: Remove classifier at old scope | COMMENT |
| LOW | clients/ios/Classes/NewsBlurAppDelegate.m | 5626 | // Step 2: Add classifier at new scope after remove succeeds | COMMENT |
| LOW | …ients/ios/Other Sources/OnePasswordExtension/README.md | 37 | ### Step 1: Download the Source Code and Sample Apps | COMMENT |
| LOW | …ients/ios/Other Sources/OnePasswordExtension/README.md | 47 | ### Step 2: Install the Latest versions of 1Password & Xcode | COMMENT |
| LOW | …ients/ios/Other Sources/OnePasswordExtension/README.md | 60 | ### Step 3: Run the Apps | COMMENT |
| LOW | .claude/commands/commit-all.md | 19 | ### Step 1: Analyze and group changes | COMMENT |
| LOW | .claude/commands/commit-all.md | 30 | ### Step 2: Commit each group | COMMENT |
| LOW | .claude/commands/commit-all.md | 42 | ### Step 3: Confirm | COMMENT |
| LOW⚡ | .claude/commands/commit.md | 19 | ### Step 1: Determine which files to stage | COMMENT |
| LOW⚡ | .claude/commands/commit.md | 29 | ### Step 2: Stage the relevant files | COMMENT |
| LOW⚡ | .claude/commands/commit.md | 35 | ### Step 3: Verify staged changes | COMMENT |
| LOW⚡ | .claude/commands/commit.md | 39 | ### Step 4: Commit | COMMENT |
| LOW | .claude/commands/commit.md | 57 | ### Step 5: Confirm | COMMENT |
| LOW⚡ | .claude/commands/commit-push.md | 10 | ### Step 1: Commit | COMMENT |
| LOW⚡ | .claude/commands/commit-push.md | 14 | ### Step 2: Push | COMMENT |
| LOW⚡ | .claude/commands/commit-push.md | 24 | ### Step 3: Confirm | COMMENT |
| LOW | .claude/commands/feature.md | 23 | ### Step 1: Find the matching blog post | COMMENT |
| LOW⚡ | .claude/commands/feature.md | 34 | ### Step 2: Study existing feature style | COMMENT |
| LOW⚡ | .claude/commands/feature.md | 43 | ### Step 3: Write 4-5 feature options | COMMENT |
| LOW⚡ | .claude/commands/feature.md | 52 | ### Step 4: Ask the user to choose a feature | COMMENT |
| LOW⚡ | .claude/commands/feature.md | 56 | ### Step 5: Post to production | COMMENT |
| LOW | .claude/commands/feature.md | 75 | ### Step 6: Confirm feature | COMMENT |
| LOW | .claude/commands/feature.md | 79 | ### Step 7: Write tweet sets | COMMENT |
| LOW⚡ | .claude/skills/find-skills/SKILL.md | 36 | ### Step 1: Understand What They Need | COMMENT |
| LOW⚡ | .claude/skills/find-skills/SKILL.md | 44 | ### Step 2: Check the Leaderboard First | COMMENT |
| LOW⚡ | .claude/skills/find-skills/SKILL.md | 52 | ### Step 3: Search for Skills | COMMENT |
| LOW | .claude/skills/find-skills/SKILL.md | 66 | ### Step 4: Verify Quality Before Recommending | COMMENT |
| LOW | .claude/skills/find-skills/SKILL.md | 74 | ### Step 5: Present Options to the User | COMMENT |
| LOW | .claude/skills/find-skills/SKILL.md | 96 | ### Step 6: Offer to Install | COMMENT |
| LOW⚡ | utils/feed_fetcher.py | 135 | # Step 1: HTML Unescaping - convert HTML entities to their literal characters | COMMENT |
| LOW⚡ | utils/feed_fetcher.py | 139 | # Step 2: Encoding Reinterpretation | COMMENT |
| LOW⚡ | apps/rss_feeds/models.py | 4282 | # Step 1: Fetch the Google News article page to get signature and timestamp | COMMENT |
| LOW⚡ | apps/rss_feeds/models.py | 4302 | # Step 2: Call batchexecute API to decode the URL | COMMENT |
| LOW | …s/discover/management/commands/discover_newsletters.py | 1360 | # Step 1: Always fetch sitemap to get publication slugs (fast, idempotent) | COMMENT |
| LOW | …s/discover/management/commands/discover_newsletters.py | 1394 | # Step 2: Fetch each publication page for metadata | COMMENT |
| LOW | …r/management/commands/backfill_underpopulated_feeds.py | 148 | # Step 1: Load fixture and identify gaps | COMMENT |
| LOW | …r/management/commands/backfill_underpopulated_feeds.py | 205 | # Step 3: Categorize discovered feeds with Claude | COMMENT |
| LOW | …r/management/commands/backfill_underpopulated_feeds.py | 216 | # Step 4: Merge into fixture | COMMENT |
| LOW⚡ | apps/webfeed/tasks.py | 545 | # Step 4: Variants already carry preview stories and are ranked best-first. | COMMENT |
| LOW | apps/webfeed/tasks.py | 409 | # Step 1: Fetch page HTML | COMMENT |
| LOW | apps/webfeed/tasks.py | 440 | # Step 2: Call Claude for XPath analysis. The model is non-deterministic | COMMENT |
| LOW | apps/webfeed/tasks.py | 492 | # Step 3: First analysis pass, plus a single retry when nothing matched. | COMMENT |
| LOW⚡ | apps/profile/models.py | 1663 | # Step 1: Get the order to retrieve purchaseToken | COMMENT |
| LOW⚡ | apps/profile/models.py | 1682 | # Step 2: Store GooglePlayIds for RTDN mapping | COMMENT |
| LOW⚡ | apps/profile/models.py | 1710 | # Step 4: Determine renewals from latestOrderId | COMMENT |
| LOW | apps/profile/models.py | 1695 | # Step 3: Get full subscription state via purchaseToken | COMMENT |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| HIGH⚡ | archive/fabfile.py | 1950 | run("mkdir -p ~%s/.ssh && chmod 700 ~%s/.ssh" % (repo_user, repo_user)) | CODE |
| HIGH | archive/fabfile.py | 498 | run("mkdir -p ~/.ssh && chmod 700 ~/.ssh") | CODE |
| HIGH | archive/fabfile.py | 567 | run("./configure && make && sudo make install") | CODE |
| HIGH | archive/fabfile.py | 570 | run("./configure && make && sudo make install") | CODE |
| HIGH | utils/management_functions.py | 26 | os.dup2(null, i) | CODE |
| HIGH | utils/management_functions.py | 30 | os.close(null) | CODE |
| HIGH⚡ | apps/rss_feeds/models.py | 4305 | '["garturlreq",[["X","X",["X","X"],null,null,1,1,"US:en"' | CODE |
| HIGH⚡ | apps/rss_feeds/models.py | 4306 | ',null,1,null,null,null,null,null,0,1],"X","X",1,[1,1,1]' | CODE |
| HIGH⚡ | apps/rss_feeds/models.py | 4307 | f',1,1,null,0,0,null,0],"{base64_str}",{timestamp}' | CODE |
| HIGH | apps/rss_feeds/management/commands/calculate_scores.py | 79 | os.dup2(null, i) | CODE |
| HIGH | apps/rss_feeds/management/commands/calculate_scores.py | 83 | os.close(null) | CODE |
| HIGH | apps/oauth/views.py | 1164 | body: formData.toString() | CODE |
| HIGH | apps/notifications/models.py | 469 | apns.push(notification=notification, device_token=token) | CODE |
| HIGH | apps/archive_extension/views.py | 98 | matched_story_hash: str or null, | STRING |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| HIGH | apps/discover/management/commands/discover_podcasts.py | 0 | use claude to categorize feeds that don't have categories. | STRING |
| HIGH | …s/discover/management/commands/discover_newsletters.py | 0 | use claude to categorize feeds that don't have categories. | STRING |
| HIGH | …ps/discover/management/commands/discover_subreddits.py | 0 | use claude to categorize feeds that don't have categories. | STRING |
| HIGH | …ps/discover/management/commands/discover_real_feeds.py | 0 | make a get request to feedly, optionally through scrapingbee proxy. | STRING |
| HIGH | …s/discover/management/commands/discover_newsletters.py | 0 | make a get request to feedly, optionally through scrapingbee proxy. | STRING |
| HIGH | …r/management/commands/backfill_underpopulated_feeds.py | 0 | make a get request to feedly, optionally through scrapingbee proxy. | STRING |
| HIGH | apps/recommendations/tests.py | 0 | this file demonstrates two different styles of tests (one doctest and one unittest). these will both pass when you run " | STRING |
| HIGH | apps/mobile/tests.py | 0 | this file demonstrates two different styles of tests (one doctest and one unittest). these will both pass when you run " | STRING |
| HIGH | apps/static/tests.py | 0 | this file demonstrates two different styles of tests (one doctest and one unittest). these will both pass when you run " | STRING |
| HIGH | apps/api/tests.py | 0 | this file demonstrates two different styles of tests (one doctest and one unittest). these will both pass when you run " | STRING |
| HIGH | apps/recommendations/tests.py | 0 | another way to test that 1 + 1 is equal to 2. >>> 1 + 1 == 2 true | STRING |
| HIGH | apps/mobile/tests.py | 0 | another way to test that 1 + 1 is equal to 2. >>> 1 + 1 == 2 true | STRING |
| HIGH | apps/static/tests.py | 0 | another way to test that 1 + 1 is equal to 2. >>> 1 + 1 == 2 true | STRING |
| HIGH | apps/api/tests.py | 0 | another way to test that 1 + 1 is equal to 2. >>> 1 + 1 == 2 true | STRING |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW | clients/ios/Widget Extension/WidgetStory.swift | 85 | content = "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Curabitur nec ornare dolor. Vivamus porta mi | CODE |
| LOW | clients/ios/Widget Extension/WidgetStory.swift | 85 | content = "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Curabitur nec ornare dolor. Vivamus porta mi | CODE |
| LOW | …er Sources/OnePasswordExtension/OnePasswordExtension.m | 596 | 'label-tag',m(a));e(c,'label-data',g(a,'data-label'));e(c,'label-aria',g(a,'aria-label'));e(c,'label-top',n(a));b=[];for | CODE |
| LOW | …roid/NewsBlur/app/src/test/resources/shortContent.json | 242 | "about": "Minim tempor commodo tempor enim duis voluptate pariatur consequat sit. Eiusmod eiusmod reprehenderit ipsu | CODE |
| LOW | apps/reader/forms.py | 29 | attrs={"tabindex": 1, "class": "NB-input", "placeholder": "Username or email"} | CODE |
| LOW | apps/reader/forms.py | 35 | widget=forms.PasswordInput(attrs={"tabindex": 2, "class": "NB-input", "placeholder": "Password"}), | CODE |
| LOW⚡ | apps/reader/forms.py | 103 | widget=forms.TextInput(attrs={"class": "NB-input", "placeholder": "Username"}), | CODE |
| LOW⚡ | apps/reader/forms.py | 111 | widget=forms.TextInput(attrs={"maxlength": 75, "class": "NB-input", "placeholder": "Email address"}), | CODE |
| LOW⚡ | apps/reader/forms.py | 118 | attrs={"class": "NB-input", "placeholder": "Password (optional)"}, | CODE |
| LOW | apps/reader/tests.py | 55 | self.user = User.objects.create_user(username="testuser", password="testpass", email="test@test.com") | CODE |
| LOW⚡ | apps/analyzer/tests.py | 88 | author="John Doe", | CODE |
| LOW⚡ | apps/analyzer/tests.py | 92 | self.assertEqual(classifier.author, "John Doe") | CODE |
| LOW⚡ | apps/analyzer/tests.py | 369 | author="John Doe", | CODE |
| LOW⚡ | apps/analyzer/tests.py | 374 | story = {"story_feed_id": self.feed.pk, "story_authors": "John Doe"} | CODE |
| LOW⚡ | apps/analyzer/tests.py | 1550 | author="John Doe", | CODE |
| LOW | apps/analyzer/tests.py | 41 | self.user = User.objects.create_user(username="testuser", password="testpass", email="test@test.com") | CODE |
| LOW | apps/analyzer/tests.py | 1519 | "story_authors": "John Doe", | CODE |
| LOW | apps/analyzer/tests.py | 1585 | author="John Doe", | CODE |
| LOW | apps/archive_extension/tests.py | 61 | email="test@test.com", | CODE |
| LOW | media/js/mobile/jquery.mobile-1.0b1.js | 4090 | if( !this.getAttribute('value') || text.length == 0 || $this.jqmData('placeholder') ){ | CODE |
| LOW | media/js/newsblur/reader/reader_add_feed.js | 503 | this.$('.NB-add-folder-input').attr('placeholder', 'New folder under ' + parent_folder + '...'); | CODE |
| LOW⚡ | media/js/newsblur/reader/reader_classifier.js | 3429 | $input.attr('placeholder', 'e.g., \\bcat\\b or dog|bird'); | CODE |
| LOW⚡ | media/js/newsblur/reader/reader_classifier.js | 3431 | $input.attr('placeholder', 'e.g., \\bbreaking\\b or urgent|alert'); | CODE |
| LOW⚡ | media/js/newsblur/reader/reader_classifier.js | 3433 | $input.attr('placeholder', 'e.g., /news/\\d+ or /category/'); | CODE |
| LOW⚡ | media/js/newsblur/reader/reader_classifier.js | 3435 | $input.attr('placeholder', 'e.g., ^Sam or smith|jones'); | CODE |
| LOW⚡ | media/js/newsblur/reader/reader_classifier.js | 3458 | $input.attr('placeholder', 'Enter text to match...'); | CODE |
| LOW⚡ | media/js/newsblur/reader/reader_classifier.js | 3460 | $input.attr('placeholder', 'Enter URL pattern to match...'); | CODE |
| LOW⚡ | media/js/newsblur/reader/reader_classifier.js | 3462 | $input.attr('placeholder', 'Enter author pattern...'); | CODE |
| LOW⚡ | media/js/newsblur/reader/reader_classifier.js | 3464 | $input.attr('placeholder', ''); | CODE |
| LOW⚡ | media/js/newsblur/views/story_ask_ai_view.js | 703 | $input.attr('placeholder', 'Recording...'); | CODE |
| LOW⚡ | media/js/newsblur/views/story_ask_ai_view.js | 713 | $input.attr('placeholder', 'Transcribing...'); | CODE |
| LOW⚡ | media/js/newsblur/views/story_ask_ai_view.js | 721 | $input.attr('placeholder', 'Follow up...'); | CODE |
| LOW | media/js/newsblur/views/story_ask_ai_view.js | 738 | $input.attr('placeholder', 'Follow up...'); | CODE |
| LOW | media/js/newsblur/views/story_ask_ai_view.js | 759 | $input.attr('placeholder', 'Quota exceeded'); | CODE |
| LOW | media/js/newsblur/views/story_ask_ai_view.js | 762 | $input.attr('placeholder', 'Follow up...'); | CODE |
| LOW⚡ | media/js/newsblur/views/story_detail_view.js | 2385 | $input.attr('placeholder', 'Recording...'); | CODE |
| LOW⚡ | media/js/newsblur/views/story_detail_view.js | 2391 | $input.attr('placeholder', 'Transcribing...'); | CODE |
| LOW⚡ | media/js/newsblur/views/story_detail_view.js | 2400 | $input.attr('placeholder', 'Ask a question...'); | CODE |
| LOW | media/js/newsblur/views/story_detail_view.js | 2421 | $input.attr('placeholder', 'Quota exceeded'); | CODE |
| LOW | media/js/newsblur/views/story_detail_view.js | 2428 | $input.attr('placeholder', error || 'Error - please try again'); | CODE |
| LOW⚡ | media/js/newsblur/views/archive_view.js | 1749 | $input.attr('placeholder', 'Recording...'); | CODE |
| LOW⚡ | media/js/newsblur/views/archive_view.js | 1756 | $input.attr('placeholder', 'Transcribing...'); | CODE |
| LOW⚡ | media/js/newsblur/views/archive_view.js | 1763 | $input.attr('placeholder', 'Ask about your browsing history...'); | CODE |
| LOW⚡ | media/js/newsblur/views/archive_view.js | 1772 | $input.attr('placeholder', 'Ask about your browsing history...'); | CODE |
| LOW⚡ | media/js/newsblur/views/archive_view.js | 1793 | $input.attr('placeholder', 'Ask about your browsing history...'); | CODE |
| LOW⚡ | media/js/newsblur/views/archive_view.js | 1798 | $input.attr('placeholder', 'Enable microphone in browser settings to use voice input'); | CODE |
| LOW⚡ | media/js/newsblur/views/archive_view.js | 1802 | $input.attr('placeholder', error || 'Voice recording failed. Please try again.'); | CODE |
| LOW⚡ | media/js/newsblur/views/archive_view.js | 1805 | $input.attr('placeholder', 'Ask about your browsing history...'); | CODE |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| CRITICAL | …/main/java/com/newsblur/compose/DailyBriefingScreen.kt | 863 | colorFilter = androidx.compose.ui.graphics.ColorFilter.tint(archivePurple), | CODE |
| CRITICAL | …/main/java/com/newsblur/compose/DailyBriefingScreen.kt | 880 | androidx.compose.ui.graphics.Brush.linearGradient( | CODE |
| CRITICAL | media/js/newsblur/views/folder_view.js | 662 | NEWSBLUR.Views.FeedTitleView.prototype.expand_mark_read.call(this); | CODE |
| CRITICAL | media/js/newsblur/views/dashboard_river_view.js | 224 | NEWSBLUR.app.dashboard_rivers.left.rivers.forEach(function (river) { | CODE |
| CRITICAL | media/js/newsblur/views/story_titles_header_view.js | 384 | NEWSBLUR.Views.FeedTitleView.prototype.expand_mark_read.call(this); | CODE |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| MEDIUM | docker/postgres/entrypoint.sh | 4 | # Create a user with the specified UID/GID | COMMENT |
| MEDIUM | utils/ai_functions.py | 66 | # Define the tool for classification | COMMENT |
| MEDIUM | utils/ratelimit.py | 18 | # This class is designed to be sub-classed | COMMENT |
| MEDIUM | blog/_plugins/paginated_feed.rb | 28 | # Create the feed page | COMMENT |
| MEDIUM | apps/reader/test_reader.py | 456 | # Create a folder-scoped classifier for "YouTube (no shorts)" (top-level path) | COMMENT |
| MEDIUM | apps/reader/test_reader.py | 543 | # Create a folder-scoped classifier with the full nested path | COMMENT |
| MEDIUM | apps/reader/tests.py | 142 | # Create a story with the new tag already | COMMENT |
| MEDIUM | apps/monitor/views/newsblur_llm_costs.py | 35 | # Define the dimensions we track (use centralized lists from RLLMCosts) | COMMENT |
| MEDIUM | apps/discover/views.py | 1498 | # Create a bare Feed record directly — no feed discovery, no HTTP requests | COMMENT |
| MEDIUM | apps/newsletters/models.py | 93 | # Create a new feed if it doesn't exist by stable newsletter identity. | COMMENT |
| MEDIUM | apps/search/models.py | 199 | # Create the finish callbacks | COMMENT |
| MEDIUM | apps/push/test_push.py | 3 | # This file is part of djpubsubhubbub. | COMMENT |
| MEDIUM | apps/push/test_push.py | 372 | # Create a feed first since PushSubscription requires it | STRING |
| MEDIUM | apps/profile/models.py | 439 | # Create the archived record | COMMENT |
| MEDIUM | apps/profile/views.py | 736 | # Create the instance. | COMMENT |
| MEDIUM | …ps/profile/management/commands/generate_dev_session.py | 56 | # Create a new session | COMMENT |
| MEDIUM | apps/analyzer/tests.py | 1343 | # Create a UserSubscriptionFolders entry so the endpoint can organize by folder | COMMENT |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| HIGH | node/ask_ai.js | 1 | // Ask AI streaming handler -- relays AI-generated story summaries and Q&A | COMMENT |
| HIGH | node/briefing.js | 1 | // Briefing streaming handler -- relays AI-generated news briefing progress | COMMENT |
| HIGH | apps/briefing/views.py | 227 | # views.py: Add display names for AI-generated sections not in BRIEFING_SECTION_DEFINITIONS. | COMMENT |
| HIGH | apps/archive_extension/models.py | 49 | # AI-generated categorization | COMMENT |
| HIGH | media/js/newsblur/models/briefing_sections.js | 26 | // the section order from the AI-generated summary HTML. | COMMENT |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW | clients/ios/Classes/NewsBlurAppDelegate.m | 5613 | // Step 1: Remove classifier at old scope | COMMENT |
| LOW | clients/ios/Classes/NewsBlurAppDelegate.m | 5626 | // Step 2: Add classifier at new scope after remove succeeds | COMMENT |
| LOW⚡ | utils/feed_fetcher.py | 135 | # Step 1: HTML Unescaping - convert HTML entities to their literal characters | COMMENT |
| LOW⚡ | utils/feed_fetcher.py | 139 | # Step 2: Encoding Reinterpretation | COMMENT |
| LOW⚡ | apps/rss_feeds/models.py | 4282 | # Step 1: Fetch the Google News article page to get signature and timestamp | COMMENT |
| LOW⚡ | apps/rss_feeds/models.py | 4302 | # Step 2: Call batchexecute API to decode the URL | COMMENT |
| LOW | …s/discover/management/commands/discover_newsletters.py | 1360 | # Step 1: Always fetch sitemap to get publication slugs (fast, idempotent) | COMMENT |
| LOW | …s/discover/management/commands/discover_newsletters.py | 1394 | # Step 2: Fetch each publication page for metadata | COMMENT |
| LOW | …r/management/commands/backfill_underpopulated_feeds.py | 148 | # Step 1: Load fixture and identify gaps | COMMENT |
| LOW | …r/management/commands/backfill_underpopulated_feeds.py | 205 | # Step 3: Categorize discovered feeds with Claude | COMMENT |
| LOW | …r/management/commands/backfill_underpopulated_feeds.py | 216 | # Step 4: Merge into fixture | COMMENT |
| LOW⚡ | apps/webfeed/tasks.py | 545 | # Step 4: Variants already carry preview stories and are ranked best-first. | COMMENT |
| LOW | apps/webfeed/tasks.py | 409 | # Step 1: Fetch page HTML | COMMENT |
| LOW | apps/webfeed/tasks.py | 440 | # Step 2: Call Claude for XPath analysis. The model is non-deterministic | COMMENT |
| LOW | apps/webfeed/tasks.py | 492 | # Step 3: First analysis pass, plus a single retry when nothing matched. | COMMENT |
| LOW⚡ | apps/profile/models.py | 1663 | # Step 1: Get the order to retrieve purchaseToken | COMMENT |
| LOW⚡ | apps/profile/models.py | 1682 | # Step 2: Store GooglePlayIds for RTDN mapping | COMMENT |
| LOW⚡ | apps/profile/models.py | 1710 | # Step 4: Determine renewals from latestOrderId | COMMENT |
| LOW | apps/profile/models.py | 1695 | # Step 3: Get full subscription state via purchaseToken | COMMENT |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| MEDIUM | clients/ios/Classes/StoryPagesObjCViewController.m | 932 | // Update content inset on all pages' web views so swiping between them is seamless | COMMENT |
| MEDIUM | utils/feedfinder_pilgrim.py | 404 | ##### test harness ###### | COMMENT |
| MEDIUM | utils/scrubber/__init__.py | 281 | # TODO: This probably needs to be more robust | COMMENT |
| MEDIUM | ansible/roles/consul/files/consul.hcl | 47 | # This cannot be used in conjunction with the legacy -bootstrap flag. This flag requires | COMMENT |
| LOW | apps/rss_feeds/models.py | 1918 | # Don't mangle stories with code, just use new | COMMENT |
| MEDIUM | apps/ask_ai/prompts.py | 48 | full_prompt="""Please provide a comprehensive paragraph summary of the following article. | CODE |
| MEDIUM | apps/webfeed/prompts.py | 78 | # On retry, the first pass matched nothing; nudge hard toward robust selectors. | COMMENT |
| LOW | apps/clustering/models.py | 801 | # existing zCL: — just add new members and update sCL: pointers. | COMMENT |
| MEDIUM | apps/profile/views.py | 401 | # Log comprehensive debugging info to diagnose the encoding issue | COMMENT |
| LOW | apps/notifications/models.py | 414 | # - export "Apple Push Service: com.newsblur.NewsBlur" as aps.p12 (or just use aps.cer in #5) | COMMENT |
| MEDIUM | media/js/mobile/jquery.mobile-1.0b1.js | 1283 | // robust, there are a few unfortunate browser bugs surrounding expected | COMMENT |
| MEDIUM | media/js/newsblur/welcome/welcome.js | 33 | // Clone all cards and append them for seamless infinite loop. | COMMENT |
| MEDIUM | media/js/newsblur/welcome/welcome.js | 89 | // Never wrap — use the duplicate content for seamless transitions. | COMMENT |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW | archive/munin/munin/cassandra.py | 24 | CODE | |
| LOW | utils/mongo_raw_log_middleware.py | 90 | CODE | |
| LOW | utils/PyRSS2Gen.py | 314 | CODE | |
| LOW | utils/PyRSS2Gen.py | 433 | CODE | |
| LOW | utils/exception_middleware.py | 31 | CODE | |
| LOW | newsblur_mcp/newsblur_mcp/tools/stories.py | 9 | CODE | |
| LOW | newsblur_mcp/newsblur_mcp/tools/stories.py | 57 | CODE | |
| LOW | newsblur_mcp/newsblur_mcp/tools/stories.py | 151 | CODE | |
| LOW | newsblur_mcp/newsblur_mcp/tools/stories.py | 190 | CODE | |
| LOW | newsblur_mcp/newsblur_mcp/tools/classifiers.py | 7 | CODE | |
| LOW | newsblur_mcp/newsblur_mcp/tools/classifiers.py | 64 | CODE | |
| LOW | apps/reader/models.py | 176 | CODE | |
| LOW | apps/reader/models.py | 473 | CODE | |
| LOW | apps/reader/models.py | 739 | CODE | |
| LOW | apps/reader/models.py | 1521 | CODE | |
| LOW | apps/reader/models.py | 1637 | CODE | |
| LOW | apps/reader/views.py | 667 | CODE | |
| LOW | apps/reader/views.py | 843 | CODE | |
| LOW | apps/social/models.py | 1090 | CODE | |
| LOW | apps/social/models.py | 1195 | CODE | |
| LOW | apps/social/models.py | 1298 | CODE | |
| LOW | apps/social/models.py | 1410 | CODE | |
| LOW | apps/briefing/scoring.py | 32 | CODE | |
| LOW | apps/profile/models.py | 5216 | CODE | |
| LOW | apps/profile/views.py | 143 | CODE | |
| LOW | apps/profile/views.py | 165 | CODE | |
| LOW | apps/profile/views.py | 335 | CODE | |
| LOW | apps/profile/views.py | 367 | CODE | |
| LOW | apps/profile/views.py | 378 | CODE | |
| LOW | apps/profile/views.py | 393 | CODE | |
| LOW | apps/analyzer/models.py | 1212 | CODE | |
| LOW | apps/analyzer/models.py | 1402 | CODE | |
| LOW | apps/analyzer/views.py | 299 | CODE | |
| LOW | apps/analyzer/views.py | 514 | CODE | |
| LOW | apps/analyzer/views.py | 807 | CODE | |
| LOW | apps/archive_extension/models.py | 171 | CODE | |
| LOW | apps/archive_extension/search.py | 230 | CODE | |
| LOW | apps/archive_extension/search.py | 320 | CODE |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| MEDIUM | clients/ios/Other Sources/fmdb/fmdb.m | 875 | // just mix things up a bit for demonstration purposes. | COMMENT |
| MEDIUM | clients/ios/Other Sources/fmdb/fmdb.m | 1262 | // just mix things up a bit for demonstration purposes. | COMMENT |
| MEDIUM | clients/ios/Other Sources/fmdb/fmdb.m | 1297 | // just mix things up a bit for demonstration purposes. | COMMENT |
| LOW | archive/fabfile.py | 1420 | # Don't forget to add 'setup_postgres_backups' to new | COMMENT |
| MEDIUM | config/pystartup.py | 3 | # bound to the Esc key by default (you can change it - see readline docs). | COMMENT |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| MEDIUM | utils/feed_fetcher.py | 1497 | # If fetching archive pages, come back once the archive scaffolding is built | COMMENT |
| MEDIUM | apps/webfeed/prompts.py | 70 | # Truncate HTML to ~100KB for LLM context window | COMMENT |
| MEDIUM | apps/clustering/models.py | 561 | # Two guardrails must pass: | COMMENT |
| MEDIUM | apps/clustering/models.py | 679 | # guardrails from find_semantic_clusters apply here for any remaining | COMMENT |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW | utils/prometheus_worker_slots.py | 34 | logger = logging.getLogger(__name__) | CODE |
| LOW⚡ | utils/prometheus_middleware.py | 11 | logger = logging.getLogger(__name__) | CODE |
| LOW | utils/pipeline_utils.py | 22 | logger = logging.getLogger(__name__) | CODE |
| LOW | utils/scrubber/__init__.py | 12 | __all__ = ["Scrubber", "SelectiveScriptScrubber", "ScrubberWarning", "UnapprovedJavascript", "urlize"] | CODE |
| LOW | newsblur_web/__init__.py | 7 | __all__ = ["celery_app"] | CODE |
| LOW | newsblur_mcp/newsblur_mcp/auth.py | 20 | logger = logging.getLogger(__name__) | CODE |
| LOW | newsblur_mcp/newsblur_mcp/server.py | 22 | logger = logging.getLogger(__name__) | CODE |
| LOW | newsblur_mcp/newsblur_mcp/cli/auth.py | 73 | def set_server_url(server: str) -> None: | CODE |
| LOW | newsblur_mcp/newsblur_mcp/cli/auth.py | 280 | def set_readonly(enabled: bool) -> None: | CODE |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW | utils/retry_unlinked_loop.sh | 8 | # Usage: | COMMENT |
| LOW | utils/bootstrap_loop.sh | 8 | # Usage: | COMMENT |
| LOW | utils/check_health.sh | 5 | # Usage: | COMMENT |