docs: native Swift SDK API design proposal - #165
Open
kitakkun wants to merge 2 commits into
Open
Conversation
Design for a pure-Swift SDK: an export-clean commonMain facade (config builder, a SwiftPluginBridge interface, a raw string/JSON messenger) with an idiomatic Swift wrapper (Codable messages tagged by a stable messageType, a JetWhalePlugin protocol instead of subclassing, async request). Only strings and plain values cross the boundary, so Kotlin generics and kotlinx.serialization never need to bridge. Covers XCFramework + SPM binaryTarget distribution, the wire-format compatibility risk, the URLSession network adapter, and phasing.
Contributor
There was a problem hiding this comment.
Pull request overview
Adds an architecture/design proposal document for a native Swift SDK wrapper around JetWhale’s agent runtime, focusing on an export-clean Kotlin façade and an idiomatic Swift Codable-first API that avoids exporting Kotlin-idiomatic surfaces.
Changes:
- Introduces a Swift consumer-facing API sketch (
JetWhale.start,JetWhalePlugin,JetWhaleMessenger, typed events/requests). - Proposes a Kotlin
commonMainfaçade (JetWhaleSwiftConfig,SwiftPluginBridge,RawMessenger) suitable for Obj-C interop now and Swift Export later. - Documents key risks and rollout phases, especially wire-format/discriminator compatibility and a conformance-test gate.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Comment on lines
+31
to
+36
| This is already possible: `JetWhaleMessenger` exposes a monomorphic boundary today — | ||
| `sendRaw(messageType: String, payload: String): Boolean` and | ||
| `suspend requestRaw(messageType, payload, timeout): String` | ||
| (`jetwhale-protocol/core/.../JetWhaleMessenger.kt:32,40`). The typed `trySend`/`request` are just | ||
| reified extensions over these. The Swift SDK builds directly on the raw pair and does its own | ||
| `Codable` encode/decode, so generics and serialization never need to bridge. |
Comment on lines
+177
to
+179
| The Network Inspector core is transport-agnostic — `JetWhaleNetworkAgentPlugin` exposes | ||
| `recordRequest`/`recordResponse`/`recordFailure`/`findMock`/`newTransactionId` | ||
| (`network/agent/.../JetWhaleNetworkAgentPlugin.kt:79-94`), and its docstring invites new adapters. |
Comment on lines
+153
to
+155
| - **`messageType`** must equal the discriminator the Kotlin side registers for that message | ||
| (today derived from the `@Serializable` class). The Swift `static let messageType` is the explicit | ||
| contract; the shared-message module on the Kotlin side must register the same string. |
Expand the shortened path references to full repo paths (JetWhaleMessenger.kt, JetWhaleNetworkAgentPlugin.kt), and correct the wire-format note: the message discriminator is the serializer descriptor serialName (FQ class name by default, overridable with `@SerialName`), not simply "derived from the class".
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
A design proposal (not implementation) for a native Swift SDK, following the Swift-Export feasibility study.
Core idea: do not export the Kotlin authoring surface (receiver-lambda DSLs, reified generics,
@Serializable, sealed markers, abstract-class plugins all fail to bridge). Instead add a thin export-clean facade incommonMainand design an idiomatic Swift wrapper on top.sendRaw/requestRawpair (JetWhaleMessenger.kt:32,40); the Swift SDK builds on it and does its ownCodable, so generics/serialization never bridge.JetWhale.start(host:port:) { config in … }value builder;Codablemessages tagged by a stablemessageType; aJetWhalePluginprotocol (Swift conforms, no subclassing);asyncrequest.JetWhaleSwiftConfig, aSwiftPluginBridgeinterface (→ Obj-C protocol), aRawMessengerexport; aSwiftBackedAgentPluginadapts the bridge to a realJetWhaleAgentPlugin.binaryTarget(KMMBridge), Obj-C interop today, Swift Export later without changing the Swift API.Codableand the host kotlinx.serialization — proposes a shared neutral schema + round-trip conformance test.URLProtocoladapter feeding the existing transport-agnostic capture API (Phase 2).Doc lives at
docs/architecture/swift-sdk-design.md(not in the published VitePress nav).