v0.2.0

feder-cr/AIHawkv0.2.0Sep 3, 2026by feder-cr

AI Summary

This release improves the user experience by relocating the model selection to the top of the README and fixes a critical security vulnerability regarding OpenRouter key leakage. It also updates dependencies and corrects documentation and packaging errors.

Key Highlights

  • Moved the model source choice to the top of the README for better visibility.
  • Fixed a security leak where OpenRouter keys were inadvertently exposed to the browser process.
  • Updated dependency to invisible-playwright-mcp 0.10.0 to enable proper dropdown handling via browser_select_option.
  • Corrected documentation errors regarding uvx commands, socks5 examples, and command-line history visibility.
  • Fixed PyPI packaging issues, including absolute links and missing license/platform declarations.

New Features

  • Moved model source choice to the top of the README.
  • Enhanced dropdown handling using browser_select_option from invisible-playwright-mcp.

Full Release Notes

**The choice is at the top now.** What a reader has to decide is where the model
comes from: an assistant they already use, or an OpenRouter key. That choice sat
at line 111 of 159, under "Already have an MCP client? Then you may not need this
at all" - the right answer for many readers, phrased as an aside and placed where
they would not reach it. Meanwhile "Two ways to run it" sat near the top meaning
something else, `ui` against `do`.

**Fixed, and this closes a gap rather than softening a sentence.** The README
claimed the OpenRouter key never reaches the browser process. `child_env` popped
one exact name, so the same secret under a second name reached the browser
verbatim, and `OPENAI_API_KEY` holding an OpenRouter key is ordinary here because
the client is OpenAI-compatible. A lowercase variable survived on any
case-sensitive platform. The leak reached Firefox itself, not just the MCP
server. Two strict xfails in the suite already called both REAL GAP and each
named what would close it. Both are closed, by name and by value, with the
resolved key threaded from both callers because a key passed on the command line
is in no environment to be found by reading.

**Requires invisible-playwright-mcp 0.10.0**, for `browser_select_option`.
Without it a model with no way to set a dropdown clicks it, presses arrow keys,
and ends up setting the value through `browser_evaluate` - script, no keystroke,
an untrusted event.

**Fixed, from a cold read of the page by someone who had never seen it.** Both
routes start with `uvx` and uv was installed 35 lines lower, so the chooser was
inert on a machine without it. Column 1 named three clients and gave a command
only one can run. A bare `socks5://` raises when parsed and was offered as an
example. `--binary` is refused unless it matches the packaged seal. "Both take
the same ones" was contradicted four rows later by `--host` and `--port`.
Passing the key on the command line puts it in shell history and in the process
list, which was not mentioned. The browser downloads on the first request that
needs a page, not at install, and the page implied the opposite.

**Packaging.** The README is the PyPI long description, so the logo and every
relative link are now absolute; they resolved to nothing on the package page.
pyproject declares the MIT licence the README claims and LICENSE grants, and the
supported platforms, neither of which it did before.