Tags: mvanhorn/agentcookie
Tags
fix(cmux): restore Domain on host-only cookies so WebKit sends them (… …GitHub login regression) (#105) PR #103 changed cmuxCookieParam to scope host-only cookies by url alone with NO Domain. WebKit STORES such a cookie (cookies.get sees it) but does not SEND it on a real navigation, so GitHub's user_session / _gh_sess were delivered yet never authenticated -- the cmux pane silently stayed logged out. #103 fixed the __Host- rejection but regressed every other host-only auth cookie. Restore Domain = host_key for all non-__Host- cookies (the pre-#103 behavior that worked); keep the url-only/no-Domain shaping ONLY for __Host- (which WebKit rejects when it carries a Domain). Verified end to end: GitHub logs in as the user in cmux's WebKit browser after a normal sync. This also corrects the v0.17.0 framing: GitHub is NOT "browser-bound" and the session is NOT unrecoverable by cookie copy -- that conclusion was wrong. The same cookies authenticate in both Chromium (agent-sync) and cmux once shaped to be sent. Updated the bound-session doc, the doctor WARN, and the verify guidance to state the fact (delivered != authenticated) without the false cause. Also fixes a false negative in the --verify probe: it navigated at surface-creation (racing cookie propagation) and gated "ready" on readyState alone, so a poll on about:blank reported logged-out. Now it opens about:blank, navigates explicitly, and gates ready on being on the target host. Claude-Session: https://claude.ai/code/session_01EnSMwviMaV3mgjACiBoBdU Co-authored-by: Matt Van Horn <455140+mvanhorn@users.noreply.github.com> Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
fix(cmux): honest auth status for browser-bound sessions (GitHub) (#104) * fix(cmux): report honest auth status for browser-bound sessions (GitHub) Delivering cookies is not the same as authenticating. GitHub binds its web session to the origin browser (a SameSite/site-context-gated session, the __Host-user_session_same_site cookie plus `vary: Sec-Fetch-Site`), so the cookies copy into cmux's WebKit store and are even sent on requests, yet the server still serves the logged-out page. cmux-sync reported a healthy "injected N cookies" push regardless, which read as success. cmux-sync now verifies empirically: after a --once push it opens a hidden browser surface, navigates each browser-bound-session host, and checks a logged-in marker, printing delivery-vs-authentication truth plus the real fix (native login in cmux, or gh CLI for git work). doctor surfaces the same as a per-host "cmux session health" check. Verification is non-fatal: any probe error or load timeout reports "unknown", never failing the push or doctor. Also hardens the PR #103 known residual: __Host- cookies now defensively drop any Domain and always carry a url, so cmux's handler never falls back to a navigated surface's host (which would re-add a Domain and get the cookie dropped by WebKit). - internal/chrome/boundsession.go: bound-session host model, distinct from DBSC - internal/sinkpush/verify.go: empirical post-injection auth probe - cmux-sync --verify (default on for --once, off for --watch) - doctor: cmux session health check (injectable for tests) - shared hostMatchesSuffix; reuse matchLike for spec filtering Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01EnSMwviMaV3mgjACiBoBdU * fix(cmux): address Greptile P2s on the auth verifier - Quote the CSS attribute value in the metaPresent predicate (meta[name="user-login"], JSON-encoded), instead of an unquoted meta[name=user-login] which is only valid for identifier-shaped names. - Clear a transient eval-error detail on a successful-but-not-ready poll so a later load timeout reports the timeout, not a stale "eval error". Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01EnSMwviMaV3mgjACiBoBdU * style(cmux): modernize verify poll loop to range-over-int (go-lint) Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01EnSMwviMaV3mgjACiBoBdU --------- Co-authored-by: Matt Van Horn <455140+mvanhorn@users.noreply.github.com> Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
fix(cmux): scope __Host-/host-only cookies by url, not Domain (#103) WebKit hard-rejects a __Host- cookie that carries any Domain attribute, which silently dropped GitHub's __Host-user_session_same_site on the cmux lane and left the agent browser logged out despite a healthy push. cmuxCookieParam now mirrors internal/livecdp.buildParam: __Host- and host-only cookies are scoped via a synthesized url with no Domain (and __Host- forces Secure + Path /), while domain cookies keep their leading-dot Domain. Adds cmuxCookieURL and regression tests. Co-authored-by: Matt Van Horn <455140+mvanhorn@users.noreply.github.com>
fix(release): archive examples/blocklist.yaml (renamed from allowlist… ….yaml) The example config was renamed allowlist.yaml -> blocklist.yaml in the v0.2->v0.3 transition, but the goreleaser archive list was never updated. Goreleaser fails to find examples/allowlist.yaml, breaking CI releases the moment RELEASE_CI_ENABLED is flipped on.
v0.14.0-beta.1: secrets bus adoption standard A standard projects adopt to opt into agentcookie sync. Layered on the v0.13 wire format; no envelope changes. Highlights: - docs/spec-agentcookie-secrets-bus-v2-adoption.md - agentcookie.toml manifest, well-known discovery paths - agentcookie discover + secret revoke subcommands - pkg/agentcookieadoption author helper library - PP CLI auto-detect adapter (free adoption for all 30+ PP CLIs) - Hand-off guides for printing-press team + last30days team - 70 new tests; full suite at 449 passing See CHANGELOG.md and docs/handoff-guides/.
v0.13.0-beta.1: secrets bus A standardized, runtime-agnostic format for per-CLI secrets/auth-tokens that ride alongside cookies in the existing source-to-sink push. Highlights: - ~/.agentcookie/secrets/<cli>/secrets.env (mode 0600) - Optional sealed twin under the v0.12 master key - agentcookie secret subcommand (list/get/set/rm/import-from/env) - pkg/agentcookiesecret Go reader library - Doctor check (11 categories now) - gh shim worked example proving non-PP CLI consumability See CHANGELOG.md and docs/spec-agentcookie-secrets-bus-v1.md.
feat(v0.12.0-beta.6): skip keychain strategy loop on headless + the c… …ompetitor audit doc (#57) Two small items grouped. Friction #19 fix: on a headless wizard install (no TTY, skip_chrome_sqlite resolved true), the v0.10 set-keychain-access strategy loop still fired even though the sink daemon never reads Chrome Safe Storage in that mode. The loop's 60s timeout + alarming WARNING block was pure noise. Gate the strategy loop AND the prompt step on `!skipChromeSQLite`. Explicit --skip-keychain-access and --write-chrome-sqlite preserve the pre-beta.6 paths. Hoist resolveSinkHeadlessMode() once at the top of wizardInstallSink so upgrade-in-place installs get the same gating as fresh ones (the pre-beta.6 resolve fired only inside the write-fresh-sink.yaml branch). the competitor audit: Matt asked whether anything in github.com/the competitor/skills/blob/main/skills/cookie-sync/SKILL.md was worth being inspired by. Document at docs/audits/2026-05-21-the competitor-cookie-sync.md walks the feature surface, argues both sides for the three real candidates (domain allowlist, CDP-based source-side read, two-way sync), and recommends adopting none right now -- they solve problems agentcookie doesn't have. Reference doc only; no implementation work. New test: TestKeychainStrategyGatedOnHeadless models the 4-cell gating decision (explicit --skip-keychain-access / headless mode / both off / both on) and asserts the right branch fires. go test ./... 335/335 pass. Co-authored-by: Matt Van Horn <455140+mvanhorn@users.noreply.github.com> Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
fix(cdp): drop double-strip, normalize Domain, correct PP CLI install… … paths Three corrections from the 2026-05-21 dry-run validation against beta.4 that the initial commit missed: 1. Double-strip removal: internal/chrome/read.go already strips the Chrome 127+ App-Bound prefix on the source side via the defensive SHA256(host_key)-match strip. CDP injection was running a second unconditional strip, lopping 32 bytes off every cookie value longer than the prefix. Chrome silently rejected the mangled values, contributing to the 64% drop rate. Removed the duplicate strip. Deleted prefix_test.go since the function is gone. 2. Domain normalization: Chrome SQLite stores host_key as ".instacart.com" to mark parent-domain scope. The modern CDP Network.setCookies API silently rejects Domain values starting with ".". Strip the leading dot when present; Chrome derives the subdomain-wildcard scope from the explicit Domain attribute the same way it would from a server-issued Set-Cookie. 3. PP CLI install paths: beta.4 shipped `go install github.com/mvanhorn/printing-press-library/<name>@latest` but those subpackages don't exist. Each PP CLI is its own repo (github.com/mvanhorn/instacart-pp-cli, github.com/mvanhorn/airbnb-vrbo-pp-cli). The remaining three (eBay, Pagliacci, table-reservation-goat) ship via the printing-press meta tool; install-beta.sh + quickstart now link there instead of trying to publish a wrong path. Drop-rate measurement after these fixes (from the dry-run on the live Mac mini, 8258 cookies synced): - Global: 55% drop (down from 64%) - stripe: 6/17 -> 15/17 (88% retention) - github: 11/24 -> 18/24 (75%) - airbnb: 20/26 -> 20/26 (77%) - instacart: 2/33 -> 2/33 (unchanged; further investigation needed) The PP CLI path is unaffected by the CDP drop rate. Adapter session files cover the five built-in adapters fully; sidecar covers everything else. `ssh second-mac 'instacart-pp-cli carts'` returns the friend's actual cart, verified. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
fix(cdp): synthesize URL + map SameSite; install-beta.sh hints PP CLI… … install (beta.4) (#56) Two findings from the 2026-05-21 dry-run that the verdict missed: **CDP injection coverage.** Chrome rejected 64% of cookies overall and 90%+ on instacart.com when cdp.InjectCookies passed Domain+Path without URL. Cause: Chrome's Network.setCookies applies stricter validation when no URL is provided -- SameSite defaults to Lax (so originally cross-site cookies get rejected), SameSite=None requires Secure, host-only/subdomain semantics flake. Fix: synthesize a URL per cookie from host_key + path + scheme, pass alongside Domain+Path so CDP uses URL for origin checks and Domain for the cookie's Domain attribute. Map Chrome's numeric SameSite encoding to CookieSameSite explicitly. 16 new tests cover the URL synthesis edge cases and SameSite mapping. Drop rate expected to fall below 5% in the beta.4 dry-run. **PP CLI install gap.** install-beta.sh shipped a working agentcookie sink but never told the friend that the sites-actually-loaded value comes from PP CLIs that need separate installation. Friend SSHs in, types `instacart-pp-cli carts`, gets command-not-found, thinks agentcookie is broken. Fix: install-beta.sh prints a clear post-install block with the go install commands for the five built-in adapters and an SSH-test verification line. quickstart-beta.md gains a new "Install at least one PP CLI on the sink" section. Closes the gap between the dry-run verdict ("ship it") and reality. Co-authored-by: Matt Van Horn <455140+mvanhorn@users.noreply.github.com> Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
PreviousNext