commits
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Stitches metadata discovery, PAR, browser consent, token exchange, and
token storage into a single signIn(handle:) flow; ensureScope(_:for:) is
a no-op when granted scopes already satisfy the request, triggering a
fresh browser flow only on actual scope gaps.
Also fixes AuthorizationURL.build to percent-encode colons in query
values (request_uri urn: prefix), required by RFC 9126 §2.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Implements DPoP-bound auth headers, per-origin nonce capture on responses,
and best-effort token refresh on 401 via refresh_token grant.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Replace the shared global handler with a UUID-keyed registry. Each `install()`
call gets its own slot (identified via `httpAdditionalHeaders["X-URLProtocolStub-ID"]`),
and `reset(session:)` clears only the calling test's handler — so concurrently
running suites can never clobber each other's state.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
EEXIST ("file already exists") misleads users during edit conflicts.
ESTALE (even though Finder renders it as "Stale NFS file handle")
semantically matches "the cached view is stale, refresh and retry"
which is exactly what swapRecord conflicts mean. Raw 409s (rkey
collision on createRecord) keep EEXIST, which is accurate.
Also updates the implementation plan to reflect this split.
Stitches metadata discovery, PAR, browser consent, token exchange, and
token storage into a single signIn(handle:) flow; ensureScope(_:for:) is
a no-op when granted scopes already satisfy the request, triggering a
fresh browser flow only on actual scope gaps.
Also fixes AuthorizationURL.build to percent-encode colons in query
values (request_uri urn: prefix), required by RFC 9126 §2.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Replace the shared global handler with a UUID-keyed registry. Each `install()`
call gets its own slot (identified via `httpAdditionalHeaders["X-URLProtocolStub-ID"]`),
and `reset(session:)` clears only the calling test's handler — so concurrently
running suites can never clobber each other's state.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
EEXIST ("file already exists") misleads users during edit conflicts.
ESTALE (even though Finder renders it as "Stale NFS file handle")
semantically matches "the cached view is stale, refresh and retry"
which is exactly what swapRecord conflicts mean. Raw 409s (rkey
collision on createRecord) keep EEXIST, which is accurate.
Also updates the implementation plan to reflect this split.