LCEssentials installs standalone; each sub target-depends on it so linking a
sub's product always pulls LCEssentials in too, without the consumer having to
declare it separately.
- LCECryptoKit: internalized from the remote LCECryptoKitBinary git dependency
(embedded token URL removed) into a local binaryTarget vendoring
Frameworks/LCECryptoKit.xcframework. LCECryptoKitManager moved out of
LCEssentials core into its own LCECryptoKitManager target/product; the
no-op fallback for when the binary wasn't linked is gone (breaking change
for existing consumers, see decisions/2026-09-15-sub-spm-optional-products.md).
- LCFeatureControl: new product wrapping Atomenta's Feature Control API
(flag evaluation with TTL cache + safe-degrade fallback to defaults,
notifications inbox, batched exposure telemetry). 45 new tests.
Dummy mirrored button used to balance title centering rendered as a
visible empty glass pill under iOS 26's automatic button chrome. Side
buttons now only render when actually configured, title centers via
ZStack independent of button widths, and title padding is derived from
measured button width so long titles truncate instead of overlapping.
Glass button style is opt-in via setGlassButtonsEnabled(_:), off by
default.
- Package.swift: .iOS(.v13) -> .iOS(.v15), .watchOS(.v6) -> .v8
(README already stated iOS 15; watchOS 8 needed for URLSession.upload(for:fromFile:))
- drop the iOS-13 uploadTask continuation bridge; both upload overloads now
share one runUpload using session.upload(for:fromFile:delegate:)
- remove now-redundant @available(iOS 15) from the progress overload and test
- Documentation/API.md: drop iOS-version caveats
- upload<T>(url:method:form:pathParams:headers:debug:timeoutInterval:networkServiceType:)
serialises MultipartForm to a temp file, streams it via uploadTask(with:fromFile:)
bridged to async (works on iOS 13+, unlike URLSession.upload(for:fromFile:))
- temp body file always removed via defer (success and throw)
- move requestLOG/responseLOG to LCEssentials+API+Logging.swift; extract
logResponseError helper; keeps API file at 473 lines
- APIUploadTests: 4 cases
- progress-reporting overload deferred (no stub seam for didSendBodyData)