| 文件 | 最后提交记录 | 最后更新时间 |
|---|---|---|
Give every wiki page a view counter of its own (#1265) * Give every wiki page a view counter of its own A GitHub wiki serves no per-page analytics. The traffic API reports the ten most visited paths over fourteen days and nothing below that, so a corpus of 61 pages is invisible by construction: measured today, not one individual wiki page reaches that top ten on either property. We know which pages rank and not which ones get read. Each page now embeds a 68-byte transparent 1x1 PNG held as an asset of an article-views release, the way the browser launch counter has worked since May: the asset's download count is how many times the page was loaded. The release is created with make_latest=false, so it never becomes the repository's Latest. What that number is not, measured rather than assumed: four deliberate loads produced six counts, so it carries fetches we did not make and cannot separate, download_count being a bare integer with no provenance. It counts fetches and not visitors, crawlers like readers, and nothing at all for a reader who blocks images. It is for comparing pages and days. The pixel goes into the wiki only, never back into docs/: the wiki is the surface that ranks, while the .md in the repository is served as a JSON payload React mounts, so a counter there would measure almost nothing and put markup in the source tree. build_wiki.py writes no pixel unless it is told which repository it builds for, which is right for a local preview and silent otherwise - a wiki published that way looks entirely normal and counts nothing. So the workflow passes the flag and then gates on it: the checker refuses a page with no pixel, with two, or with one addressed elsewhere, and its own eleven known-bad cases run first. * Pace the first upload run, and say it in English The first run on an existing corpus uploads one asset per page and GitHub throttles bursts of content-creating requests with a 403 or 429 carrying Retry-After. That burst happens before the wiki push, so a throttle would have blocked the publish itself on the one run nobody gets to rehearse. Honour the header, retry, and pace the loop at a tenth of a second. The backoff has its own three known-bad cases against a fake throttling server, because retry code that has never once retried is not retry code. A 404 stays unretried on purpose: reading one is how a missing release is found. And the file was carrying Italian identifiers and test names into a public repository. The language gate reads git ls-files, so running it before the file was tracked was running it against a world where the file did not exist. | 2 天前 | |
One command: aihawk is the server, aihawk ui the interface (0.11.0) (#1254) No command spells aihawk.mcp or invisible-playwright-mcp any more. `aihawk` with no subcommand is the MCP server over stdio: `uvx aihawk` is what a client registers, `python -m aihawk` is what the interface spawns, and a person at a terminal gets one line on stderr saying what is waiting. `aihawk ui` is the interface as before. The second console script this package carried since 0.10.0 is gone, and so is python -m aihawk.mcp; the PyPI name invisible-playwright-mcp stays a shim over aihawk, so a client that registered it before today keeps working unchanged. The README, the wiki page of the server and every config block say `uvx aihawk`. The content gate reads `aihawk` as the command, as a whole word, so `uvx aihawk` and `uvx aihawk ui` are both checked against the README's launcher, and its CLI-surface regex no longer crosses a line break, which `uvx aihawk` at the end of a line would otherwise have tripped. The README test measures the MCP way by the registration command a reader copies, since the server's own name now also starts the interface's. Measured with the built wheel: the default suite green, the 29 e2e tests green against a cached engine (the ones that spawn the server now spawn python -m aihawk), the clean-venv install carries one script, and python -m aihawk and uvx aihawk both answer the MCP handshake, list 18 tools and open a page, while uvx aihawk ui --help is the interface. | 3 天前 | |
Become the package, not a folder that contains one The repository held documentation and a `pkg-cli/` directory off to one side. It is the product now, so the package is at the root: pyproject.toml, src/aihawk, tests. The articles move to articles/ because they are prose, and src/ is for code. The README was describing the opposite of what this is. It told a reader to install an MCP server into Claude Desktop and drive it from there - true when this repository was documentation for somebody else's client, and backwards now that the interface and the model are here. It leads with `uvx aihawk ui` and an OpenRouter key, and keeps the MCP path further down for people who already have a client, because for them it is still the right answer. CONTRIBUTING said "there is no application to build or run here". That was written this morning and was true for about six hours. ONE LOOP, and this is the part worth reading. `do` ran agent.run_task and the interface had its own copy with narration added: two implementations of the same five decisions, while the README promised "same machinery". The narration is a parameter now - `do` passes a sink that drops it, the interface passes the thing that pushes events to the page - and there is exactly one call to the model in the whole package. Conversation holds the transcript so the follow-up box means something; `do` throws it away after one instruction and gets its old behaviour for free. Two failures a tool can produce stop ending the run, and both changes were requested by the tests that pinned the old behaviour: they said in their own docstrings that they recorded a defect and should be updated the day somebody fixed it. Malformed tool arguments are now reported back so the model can retry, and the tool is still not called with them. A tool that raises - a timeout, a closed page, a refused connection - is fed back as its result. On a page nobody controls those are the normal texture of a task, and a twenty-step run that dies on the first one is not a run. CI arrives: the English gate as its own copy, because running a sibling's copy scans the sibling and reports clean; tests on Linux and Windows across 3.11 to 3.13; and a job that builds the wheel and installs it into an empty environment, because an editable install passes every test while the built artifact is missing a module. Every run: block was executed locally before this was committed. | 7 天前 | |
Give every wiki page a view counter of its own (#1265) * Give every wiki page a view counter of its own A GitHub wiki serves no per-page analytics. The traffic API reports the ten most visited paths over fourteen days and nothing below that, so a corpus of 61 pages is invisible by construction: measured today, not one individual wiki page reaches that top ten on either property. We know which pages rank and not which ones get read. Each page now embeds a 68-byte transparent 1x1 PNG held as an asset of an article-views release, the way the browser launch counter has worked since May: the asset's download count is how many times the page was loaded. The release is created with make_latest=false, so it never becomes the repository's Latest. What that number is not, measured rather than assumed: four deliberate loads produced six counts, so it carries fetches we did not make and cannot separate, download_count being a bare integer with no provenance. It counts fetches and not visitors, crawlers like readers, and nothing at all for a reader who blocks images. It is for comparing pages and days. The pixel goes into the wiki only, never back into docs/: the wiki is the surface that ranks, while the .md in the repository is served as a JSON payload React mounts, so a counter there would measure almost nothing and put markup in the source tree. build_wiki.py writes no pixel unless it is told which repository it builds for, which is right for a local preview and silent otherwise - a wiki published that way looks entirely normal and counts nothing. So the workflow passes the flag and then gates on it: the checker refuses a page with no pixel, with two, or with one addressed elsewhere, and its own eleven known-bad cases run first. * Pace the first upload run, and say it in English The first run on an existing corpus uploads one asset per page and GitHub throttles bursts of content-creating requests with a 403 or 429 carrying Retry-After. That burst happens before the wiki push, so a throttle would have blocked the publish itself on the one run nobody gets to rehearse. Honour the header, retry, and pace the loop at a tenth of a second. The backoff has its own three known-bad cases against a fake throttling server, because retry code that has never once retried is not retry code. A 404 stays unretried on purpose: reading one is how a missing release is found. And the file was carrying Italian identifiers and test names into a public repository. The language gate reads git ls-files, so running it before the file was tracked was running it against a world where the file did not exist. | 2 天前 |
| 文件 | 最后提交记录 | 最后更新时间 |
|---|---|---|
| 2 天前 | ||
| 3 天前 | ||
| 7 天前 | ||
| 2 天前 |