chore(release): bump version to 2.1.6 (build 131)

Version: CURRENT_PROJECT_VERSION 130 -> 131 (project.yml, AGENTS.md, READMEs,
docs/llms.txt).

fix(flow): host-app identification now compiles in every build configuration
(Debug, TestFlight, Release). The arbiter probe and HostAppIdentity were
DEBUG-only, so TestFlight/App Store builds never knew the host bundle id and
could not auto-return after a startflow handoff. Debug-only logging and the
Home test card are unchanged.

Also includes the pending work in the tree:
- Home: single account/setup card surface (HomeAccountSurfacePolicy/Views)
- Wide screens: voice key row and centred mic placement, iPhone Duo layout
- Keyboard: clipboard skill ranking and AI skill layout updates
- Debug: account session handoff to the Simulator (+ import script)
- Docs: portfolio assets, privacy policy URL, site/README refresh
This commit is contained in:
Rocky
2026-10-29 11:54:13 +08:00
parent 055a40976f
commit 4dce67df84
65 changed files with 3682 additions and 787 deletions
@@ -716,6 +716,36 @@ public actor AccountAPIClient {
}
}
#if DEBUG
/// Debug-only device → Simulator session handoff. The Simulator cannot produce
/// DeviceCheck / App Attest evidence, so it cannot sign in, but refresh and
/// gateway grants only need the session itself.
extension AccountAPIClient {
/// Returns the session and forgets it on this device within one call, so
/// this client can never rotate the refresh token the Simulator now owns
/// (the server would treat a second rotation as reuse and revoke both).
/// Throws while a refresh is in flight: the token may already be spent.
public func debugRelinquishSession() async throws -> AccountTokenSession {
guard refreshOperation == nil,
let session = try await reloadSessionFromVault() else {
throw AccountAPIError.sessionUnavailable
}
try await clearSession()
guard refreshOperation == nil else {
throw AccountAPIError.sessionUnavailable
}
return session
}
/// Installs a session relinquished by another device, replacing any
/// cached one so the next request uses it.
public func debugAdoptSession(_ session: AccountTokenSession) async throws {
try await replaceSession(with: session)
try? await sessionVault.clearRefreshTransaction()
}
}
#endif
extension Data {
func base64URLEncodedString() -> String {
base64EncodedString()