E501 Line too long (109 > 100)
   --> adapters/mcp_server.py:364:101
    |
362 |         "focus": focus, "response_format": response_format, "recovery": recovery,
363 |         "ocr_language": ocr_language,
364 |         "page_start": page_start, "page_end": page_end, "ocr_mode": ocr_mode, "document_mode": document_mode,
    |                                                                                                     ^^^^^^^^^
365 |         "row_start": row_start, "row_end": row_end, "sheet": sheet,
366 |         "max_cell_chars": max_cell_chars,
    |

E501 Line too long (107 > 100)
   --> adapters/mcp_server.py:415:101
    |
413 |         "rank": rank,
414 |         "render": render,
415 |         "fresh": fresh, "ocr_mode": ocr_mode, "document_mode": document_mode, "ocr_language": ocr_language,
    |                                                                                                     ^^^^^^^
416 |         "profile": profile, "engines": engines, "ranking": ranking,
417 |         "prefer_domains": prefer_domains or [], "cache_mode": cache_mode, "max_age": max_age,
    |

E501 Line too long (105 > 100)
   --> adapters/mcp_server.py:455:101
    |
453 |     action: Literal["goto", "click", "fill", "type", "press", "select", "check", "uncheck",
454 |                     "hover", "wait", "wait_for", "text", "html", "attr", "count", "snapshot",
455 |                     "url", "title", "download", "network", "checkpoint", "tabs", "switch_tab", "history"]
    |                                                                                                     ^^^^^
456 |     frame: str = Field(default="", max_length=1000, description="CSS selector for an allowed iframe")
457 |     selector: str = Field(default="", max_length=1000)
    |

E501 Line too long (101 > 100)
   --> adapters/mcp_server.py:456:101
    |
454 |                     "hover", "wait", "wait_for", "text", "html", "attr", "count", "snapshot",
455 |                     "url", "title", "download", "network", "checkpoint", "tabs", "switch_tab", "history"]
456 |     frame: str = Field(default="", max_length=1000, description="CSS selector for an allowed iframe")
    |                                                                                                     ^
457 |     selector: str = Field(default="", max_length=1000)
458 |     value: str = Field(default="", max_length=4000)
    |

E501 Line too long (109 > 100)
   --> adapters/mcp_server.py:592:101
    |
590 |         "response_format": response_format, "reparse": reparse, "row_start": row_start,
591 |         "row_end": row_end, "sheet": sheet, "max_cell_chars": max_cell_chars,
592 |         "page_start": page_start, "page_end": page_end, "ocr_mode": ocr_mode, "document_mode": document_mode,
    |                                                                                                     ^^^^^^^^^
593 |         "ocr_language": ocr_language})
    |

E501 Line too long (101 > 100)
   --> browser-search/service.py:307:101
    |
306 |     action: str = Field(min_length=1, max_length=20)
307 |     frame: str = Field(default="", max_length=1000, description="CSS selector for an allowed iframe")
    |                                                                                                     ^
308 |     selector: str = Field(default="", max_length=1000)
309 |     value: str = Field(default="", max_length=4000)
    |

E501 Line too long (108 > 100)
   --> browser-search/service.py:433:101
    |
431 |           const saved = %s;
432 |           const values = saved[location.origin];
433 |           if (values) for (const [key, value] of Object.entries(values)) sessionStorage.setItem(key, value);
    |                                                                                                     ^^^^^^^^
434 |         })();""" % json.dumps(session_storage))
435 |     if public_only or allowed_hosts:
    |

B023 Function definition does not bind loop variable `s`
   --> browser-search/service.py:928:46
    |
926 |         if s.frame:
927 |             async def resolve_frame():
928 |                 element = await page.locator(s.frame).element_handle(timeout=s.ms or 8000)
    |                                              ^
929 |                 frame = await element.content_frame() if element else None
930 |                 if not frame or not _host_allowed(frame.url, state["allowed_hosts"]):
    |

B023 Function definition does not bind loop variable `s`
   --> browser-search/service.py:928:78
    |
926 |         if s.frame:
927 |             async def resolve_frame():
928 |                 element = await page.locator(s.frame).element_handle(timeout=s.ms or 8000)
    |                                                                              ^
929 |                 frame = await element.content_frame() if element else None
930 |                 if not frame or not _host_allowed(frame.url, state["allowed_hosts"]):
    |

B023 Function definition does not bind loop variable `scope`
   --> browser-search/service.py:967:56
    |
965 |         elif action == "press":
966 |             async def call(s=s):
967 |                 target = locator(s) if s.selector else scope.locator("body")
    |                                                        ^^^^^
968 |                 await target.press(s.value or "Enter", timeout=s.ms or 8000)
969 |                 return True
    |

B023 Function definition does not bind loop variable `scope`
   --> browser-search/service.py:996:23
    |
994 |                         "wait_for value must be attached, detached, visible, or hidden"
995 |                     )
996 |                 await scope.wait_for_selector(s.selector, state=state_name,
    |                       ^^^^^
997 |                                              timeout=s.ms or 8000)
998 |                 return True
    |

B023 Function definition does not bind loop variable `scope`
    --> browser-search/service.py:1001:56
     |
 999 |         elif action == "text":
1000 |             async def call(s=s, read_metadata=read_metadata):
1001 |                 target = locator(s) if s.selector else scope.locator("body")
     |                                                        ^^^^^
1002 |                 text = await target.inner_text(timeout=s.ms or 8000)
1003 |                 cap = s.max_chars or 16000
     |

B023 Function definition does not bind loop variable `scope`
    --> browser-search/service.py:1008:56
     |
1006 |         elif action == "html":
1007 |             async def call(s=s, read_metadata=read_metadata):
1008 |                 target = locator(s) if s.selector else scope.locator("html")
     |                                                        ^^^^^
1009 |                 try:
1010 |                     text = await target.evaluate("el => el.outerHTML")
     |

B023 Function definition does not bind loop variable `scope`
    --> browser-search/service.py:1023:30
     |
1021 |         elif action == "count":
1022 |             async def call(s=s):
1023 |                 return await scope.locator(s.selector).count()
     |                              ^^^^^
1024 |         elif action == "snapshot":
1025 |             async def call(s=s):
     |

B023 Function definition does not bind loop variable `scope`
    --> browser-search/service.py:1027:44
     |
1025 |             async def call(s=s):
1026 |                 try:
1027 |                     return await _snapshot(scope, s.selector, s.limit)
     |                                            ^^^^^
1028 |                 except Exception as exc:
1029 |                     target = (
     |

B023 Function definition does not bind loop variable `scope`
    --> browser-search/service.py:1031:44
     |
1029 |                     target = (
1030 |                         page.locator(s.selector).first
1031 |                         if s.selector else scope.locator("body")
     |                                            ^^^^^
1032 |                     )
1033 |                     await diagnosed_failure("snapshot", target, exc, "dom_snapshot")
     |

E501 Line too long (102 > 100)
    --> browser-search/service.py:1044:101
     |
1042 |                     "session_storage": {await frame.evaluate("location.origin"):
1043 |                         await frame.evaluate("Object.fromEntries(Object.entries(sessionStorage))")
1044 |                         for frame in page.frames if _host_allowed(frame.url, state["allowed_hosts"])},
     |                                                                                                     ^^
1045 |                     "expires": time.time() + 86400})
1046 |                 return {"saved": True, "retention_seconds": 86400,
     |

E501 Line too long (104 > 100)
    --> browser-search/service.py:1089:101
     |
1087 |                 nonlocal page, scope
1088 |                 tabs = state["context"].pages
1089 |                 if s.index >= len(tabs) or not _host_allowed(tabs[s.index].url, state["allowed_hosts"]):
     |                                                                                                     ^^^^
1090 |                     raise ValueError("tab_missing_or_outside_allowed_hosts")
1091 |                 page = tabs[s.index]
     |

E501 Line too long (110 > 100)
    --> src/dethrottled/fetch.py:1038:101
     |
1036 |         compatible = compatible and acquisition.get("ocr_mode", "auto") == (
1037 |             _READ_OPTIONS.get().get("ocr_mode", "auto"))
1038 |         for option, default in (("document_mode", "auto"), ("row_start", 1), ("row_end", None), ("sheet", ""),
     |                                                                                                     ^^^^^^^^^^
1039 |                                 ("max_cell_chars", None)):
1040 |             compatible = compatible and acquisition.get(option, default) == (
     |

E501 Line too long (112 > 100)
    --> src/dethrottled/fetch.py:1339:101
     |
1337 |                       page_start: int = 1, page_end: int | None = None,
1338 |                       row_start: int = 1, row_end: int | None = None, sheet: str = "",
1339 |                       max_cell_chars: int | None = None, document_mode: str = "auto", source_sink=None) -> dict:
     |                                                                                                     ^^^^^^^^^^^^
1340 |     """Read a URL with request-local rendering/target policy and bounded output."""
1341 |     options = dict(format=format, wait_for=wait_for, render_delay=render_delay,
     |

E501 Line too long (101 > 100)
  --> src/dethrottled/layout.py:47:101
   |
45 |         if end < len(metadata.get("pages", [])) or metadata.get("next_page"):
46 |             metadata["partial"] = True
47 |         metadata["warnings"].append("layout_is_model_inferred; verify_critical_cells_against_source")
   |                                                                                                     ^
48 |         return candidate[:limit], metadata
49 |     except (requests.RequestException, ValueError, KeyError, TypeError):
   |

E501 Line too long (106 > 100)
  --> src/dethrottled/research.py:90:101
   |
88 |         if not evidence:
89 |             actions.append({"tool": "search", "arguments": {"query": query, "profile": "thorough"},
90 |                             "reason": "No readable evidence for this facet; refine the query if needed."})
   |                                                                                                     ^^^^^^
91 |         facets.append({"query": query, "state": state, "candidates": len(candidates),
92 |                        "evidence": evidence, "unread": unread, "failed_or_duplicate": failures,
   |

E501 Line too long (120 > 100)
  --> src/dethrottled/research.py:95:101
   |
93 |                        "next_actions": actions, "answer_verified": False})
94 |     return {"method": "retrieval_and_lexical_accounting", "answer_verified": False,
95 |             "warning": "Readable text and matched terms do not establish an answer, truth, agreement, or completeness.",
   |                                                                                                     ^^^^^^^^^^^^^^^^^^^^
96 |             "facets": facets}
   |

E501 Line too long (112 > 100)
   --> src/dethrottled/server.py:187:101
    |
185 |     @classmethod
186 |     def validate_sources(cls, value):
187 |         allowed = {"auto", "web", "news", "mwmbl", "crossref", "openalex", "arxiv", "exa", "tavily", "parallel"}
    |                                                                                                     ^^^^^^^^^^^^
188 |         if any(x.strip() not in allowed for x in value.split(",") if x.strip()):
189 |             raise ValueError("supported sources: " + ", ".join(sorted(allowed)))
    |

E501 Line too long (101 > 100)
   --> src/dethrottled/server.py:442:101
    |
440 |     # text      read the text of `selector` (or the whole body)
441 |     action: str = Field(min_length=1, max_length=20)
442 |     frame: str = Field(default="", max_length=1000, description="CSS selector for an allowed iframe")
    |                                                                                                     ^
443 |     selector: str = Field(default="", max_length=1000)
444 |     value: str = Field(default="", max_length=4000)
    |

E501 Line too long (111 > 100)
   --> src/dethrottled/server.py:620:101
    |
618 |                                        page_start=page_start,
619 |                                        page_end=page_end, row_start=row_start, row_end=row_end,
620 |                                        sheet=sheet, max_cell_chars=max_cell_chars, document_mode=document_mode)
    |                                                                                                     ^^^^^^^^^^^
621 |     # Record what happened, per domain. A cache hit is not evidence about the
622 |     # site -- it says the cache worked, which is a different fact -- so only
    |

E501 Line too long (111 > 100)
   --> src/dethrottled/server.py:821:101
    |
819 |     return {
820 |         "service": "dethrottled",
821 |         "optional_search_providers": __import__("dethrottled.providers", fromlist=["configured"]).configured(),
    |                                                                                                     ^^^^^^^^^^^
822 |         "version": VERSION,
823 |         "client_contract": {
    |

E501 Line too long (120 > 100)
    --> src/dethrottled/server.py:1085:101
     |
1083 | …                     public_only=body.public_only, focus=body.focus,
1084 | …                     evidence_namespace=body.evidence_namespace,
1085 | …                     ocr_language=body.ocr_language, ocr_mode=body.ocr_mode, document_mode=body.document_mode,
     |                                                                                            ^^^^^^^^^^^^^^^^^^^^
1086 | …                     page_start=body.page_start,
1087 | …                     page_end=body.page_end, row_start=body.row_start,
     |

E501 Line too long (122 > 100)
    --> src/dethrottled/server.py:1451:101
     |
1449 |         extracted = _extract_row(row.get("url", ""), body.max_chars,
1450 |                                  allow_ocr=body.ocr_mode != "never",
1451 |                                  ocr_mode=body.ocr_mode, document_mode=body.document_mode, ocr_language=body.ocr_language,
     |                                                                                                     ^^^^^^^^^^^^^^^^^^^^^^
1452 |                                  page_budget=fetcher.PAGE_BUDGET_BULK,
1453 |                                  allow_render=sf_mode != "never",
     |

E501 Line too long (103 > 100)
  --> src/dethrottled/structure.py:71:101
   |
69 |                       "use source page points and are not an OCR alignment.",
70 |             "page_layout": record.get("metadata", {}).get("extraction", {}).get("pages", [])[:5],
71 |             "layout_tables": record.get("metadata", {}).get("extraction", {}).get("layout_tables", []),
   |                                                                                                     ^^^
72 |             "answer_verified": False}
   |

Found 30 errors.
