Swift
Add a floating desktop companion to your macOS 14+ app. The SDK runs inside your app and displays the mascot in a separate window above other windows. Your app owns its lifecycle; it does not use the CLI’s shared host. The SDK currently has no view for placing a mascot inside your app’s interface.
Add the package
Add https://github.com/masko-ai/masko as a Swift package dependency and select the Masko library product. Use a pinned repository revision for reproducible builds. Access to the developer repository is currently required.
Show and control a character
Call the SDK on the main actor from a running macOS app. Retain the returned mascot for as long as you need it.
import Masko
@MainActor
func startMascot() async throws -> Mascot {
let ko = try await Masko.mascot("ko")
try await ko.show()
try await ko.state("working")
try await ko.play("celebrate")
return ko
}show(), state(), play() and prepare() return a request UUID as soon as they accept the command. Media loads and playback continue in the background. You can send state and play requests while show is loading. state() holds an activity until replaced; a performance returns to the latest state.
Wait explicitly when your next step depends on completion:
let shown = try await ko.show()
try await ko.waitForRequest(shown) // First visible frame.
let play = try await ko.play("celebrate", instant: true)
try await ko.waitForPlay(play) // Complete performance and return.waitForRequest also waits for state preparation/application or full graph preparation. State application does not wait for a visual transition to finish. Inspect ko.status() for request progress/errors, or set onError for background failures. Wait timeouts use seconds.
Public Ko needs no API key. The first load downloads hosted media. Use prepare() to download the full graph in advance.
Lifecycle and layout
| Call | Result |
|---|---|
try await ko.show() | Show or resume. |
ko.hide() | Hide and pause. |
try await ko.clearState() | Release the held state; an active play finishes before returning to default. |
try ko.resize(to: 180) | Set size in screen points, between 64 and 720. |
try ko.position(x: 400, y: 100) | Move using bottom-left screen coordinates. |
try await ko.prepare() | Cache the graph’s media. |
try ko.cancel() | Request the current performance’s return path. |
ko.dispose() | Close and release the mascot. |
A second simultaneous performance fails with busy. startPlay() is an alias for play(). Use waitForPlay() for completion. Call dispose() when the feature or app closes. Use onDispose to react to the user closing the native mascot window.
Studio authoring
With the matching local client source, use the Studio REST bridge through your saved workspace login:
let client = Masko.client()
let mascots = try await client.studio("GET", path: "mascots")
let job = try await client.studio("GET", path: "jobs/JOB_ID?api_version=2026-09-26")The Studio bridge is not yet published in the installer. Named namespace/name character creation, generation runs and automatic character runtime preparation belong to older backends and do not work against the migrated Studio backend.
Use mascot generation, independent canvas operations and explicit releases described in Studio migration. Generation returns job IDs; poll /v1/jobs/JOB_ID?api_version=2026-09-26 without resubmitting paid work. Keep REST credentials in trusted tooling or your backend.
For customer playback, your backend retrieves authorized signed release delivery. The payload is not a drop-in replacement for the retired character-access URL accepted by older SDKs. See application access and verify the installed client's delivery interface before integration. Public Ko playback above remains separate.