Adds the one thing the extension could not answer before: roughly where
the user actually is, rather than which zone their clock is set to.
- `lib/geo.ts` resolves a place from ipapi.co. Chosen because it is HTTPS
and needs no API key; ip-api.com, the other obvious free option, is
HTTP-only on its free tier, which is not a place to send an IP address.
- Off by default, and skipped entirely when the user has set Location: the
better answer is already there, so spending their privacy on a worse one
would be indefensible. `ipPlace` is only wired into ToolContext when the
preference is on, so an off setting cannot reach the network at all.
- Cached for 6 hours. A city does not change between questions, and every
lookup hands the provider another copy of the address. Set Up Lam Agent
clears it on re-test, alongside the vision cache.
- Failures are returned, not swallowed: a rate limit or an offline machine
says so in the tool output while the region answer stays available. The
provider signals some failures with error: true and HTTP 200, so the body
is checked as well as the status.
- The tool output always names the provider and calls the result city-level
rather than exact. It also flags an IP timezone that disagrees with the
device clock, which usually means a VPN.
- The README claimed no geolocation service ever saw the user's address.
That is now conditional, so the section was rewritten rather than left to
quietly become untrue.
Deliberately not done: GPS. CoreLocation has no CLI on macOS and GeoClue's
usual provider resolves nearby Wi-Fi through a Mozilla service anyway.
Verified: 341 tests (25 new), tsc, eslint, prettier, and vici build. I did
not make a live API call, because doing so would send this machine's IP to
the provider as the exact flow being opted into.