Commit Graph
4 Commits
Author SHA1 Message Date
coderdailyoneandClaude Fable 5 abb7eef863 fix: import tomllib's tomli fallback on Python 3.10
requires-python declares >=3.10 and the README says "Python 3.10+", but
coworker/config.py imports tomllib at module top and tomllib only landed in
the 3.11 stdlib — on 3.10 the package cannot even be imported (every test
module fails collection through the coworker.config import chain), so the
advertised floor is broken in practice.

Fall back to the tomli package (the pre-stdlib implementation of the same API)
and declare it as a dependency only for python_version < '3.11', so 3.11+
installs are unchanged.

Verified on 3.10: importing coworker.config and load_config() parsing a
workspace config.toml both work through the fallback; the config suite still
passes on 3.12.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-31 10:28:28 +01:00
coderdailyoneandClaude Fable 5 17e27ce98a ci: typecheck the GUI in the gui-unit job
The GUI README tells contributors to run `npx tsc --noEmit` and `npm run build`
starts with `tsc`, but CI never runs either — a type error ships green today
and only surfaces when someone next builds a bundle locally. Add the check as
one step inside the existing gui-unit job so it reuses that job's npm ci and
costs no extra runner.

Verified locally: `npx tsc --noEmit` exits 0 on current main, and the vitest
suite (82 tests) still passes.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-31 10:22:48 +01:00
coderdailyoneandClaude Fable 5 6356aa6cd0 docs: fix stale platform/ paths in the GUI README
The GUI README still described the pre-split monorepo layout: every command
cd'd into a platform/ directory that does not exist in this repository, so a
fresh contributor following it verbatim fails at the first step. The venv,
packaging scripts, and surfaces/gui all live at the repo root now — align the
commands and the server_bin() dev-fallback comment with the layout the root
README already documents.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-31 10:17:19 +01:00
coderdailyoneandClaude Fable 5 18ac388162 security: pin fetched connections to the vetted address (close DNS rebinding)
guard.get_checked previously resolved a name for the address check and then let
the client resolve it again to connect, so a ~0-TTL record could flip to
127.0.0.1 (or the metadata endpoint) between the two — the exact gap the module
docstring called out as "not covered".

Every hop now connects to the address that passed its check: the request URL
carries the vetted IP, Host keeps the original name (and explicit port) for
virtual hosting, and the sni_hostname extension keeps the TLS handshake — and
certificate verification — against the name. Literal-IP URLs are unchanged.
Redirect Locations are resolved against the logical URL, and the final logical
URL rides resp.extensions["logical_url"] so web_fetch reports the name, not the
pinned address.

Verified against a local TLS server whose cert carries only DNS:pinned.test:
the pinned request (URL=127.0.0.1, sni_hostname=pinned.test) verifies and the
server sees Host: pinned.test; the same request without the extension fails
with "IP address mismatch" — httpcore does verify certificates against
sni_hostname, not the URL host.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-31 10:16:09 +01:00