Oko/Docs

Clients

iOS companion

Architecture, trust boundaries, requirements, and local setup for the Oko mobile client.

Oko iOS#

Oko iOS is the mobile companion to Oko Desktop on macOS. It gives the founder a read and chat client for company strategy, team velocity and goals, and conversations with Oko.

Architecture#

The macOS application depends on terminals, PTYs, Git processes, network listeners, and agent spawning that are not portable to iOS. The mobile application instead reuses only portable logic and talks to the same backends:

  • `Sources/Core` (`OkoIOSCore`) — pure Foundation models for the company_* and auto_goals_snapshot Supabase tables, a SupabaseClient for email-code sign-in and RLS-scoped reads, and a ChatClient.
  • `Sources/Features` (`OkoIOSUI`) — SwiftUI views for Strategy, Goals and Velocity, Chat, authentication, and the root tab view.
  • `Sources/App` — the @main application shell and only Xcode-only source.

Both library targets also build on the host, so their logic and SwiftUI can be type-checked outside the application target.

Existing-source setup#

The first-use cover opens with Transcript source before the companion walkthrough. The same screen remains under Team > Oko settings > Transcript source, and replaying onboarding reopens it. Enter the canonical Stado host, discover its existing sources, choose one returned Claude Code, Codex, OMP, Factory Droid, or Kimi root, and adopt it. Skip leaves Oko empty and usable.

The portable TranscriptSourceClient calls two authenticated structured Stado operations:

text
POST /api/integration/oko/transcript-sources
POST /api/integration/oko/transcript-sources-adopt

Both use Authorization: Bearer <Stado integration client token> and JSON bodies. The installation supplies STADO_INTEGRATION_API_URL, OKO_IOS_STADO_INTEGRATION_TOKEN, and optionally OKO_IOS_STADO_HOST_ID; the bearer is neither compiled into nor persisted by this client. Stado authorizes the exact oko/transcript-sources or oko/transcript-sources-adopt grant, selects the named host, re-discovers the root, and invokes fixed oko transcripts argv. iOS never injects a terminal command and never reads a raw transcript.

Adoption closes the source step only after Transcript Lake has accepted and persisted the selected source and Oko has indexed the Lake projection. The screen reports imported, unchanged, conflicting, rejected, pending-final-line, and catalogue counts. Invalid/malformed inputs, roots not returned by discovery, host failures, nonzero owner commands, and malformed receipts leave the step open. The host id is retained in device preferences; canonical source and catalogue state remain on the host.

Automation on a selected host#

Team > Oko settings > Automation provides context reads, Slack readiness, autonomy mode changes and recurring context/autonomy work on a named Stado host. The phone never executes host commands or stores provider credentials. It shares the source-setup transport and the same installation configuration.

Each POST /api/integration/oko/<action> needs its own exact Stado grant: context-snapshot, slack-status, autonomy-status, autonomy-set, routines-list, routines-create, routines-show, routines-pause, routines-resume, routines-remove, routines-run and routines-inspect. Transcript-source grants do not grant automation. Missing installation configuration, an unavailable host or refused action remains visible.

Stado returns the host, operation, actual owner exit status, bounded diagnostic and structured owner data. Nonzero status is not success even when diagnostic data is present. The screen preserves useful source/Slack failure reports. The host requires the matching Oko CLI; an older command cannot produce a successful automation receipt.

Creation and manual-run identities are persisted before requests. Inspect uncertain creation uses the same schedule ID; Run now / retry reuses the pending token after a lost response. A confirmed submission is not completion. Inspect result reads the real job state and canonical Oko receipt. Removal stops future occurrences without cancelling already submitted jobs. Monthly cron examples use the selected IANA timezone. Oko has no payment executor.

Security boundary#

Only the Supabase anon key, a publishable client key protected by Row Level Security, ships in the application. The service-role key and model-router HMAC secret never reach the device.

Chat requests go through the oko-chat Supabase Edge Function owned by wisent-supabase-oko. That function signs the model-router request server-side. Do not move either server credential into the client or add it to generated Xcode configuration.

Requirements#

  • iOS 17 or newer
  • Swift 6 and Xcode 16 or newer
  • XcodeGen to regenerate the application project

Build and run#

sh
swift build
swift test
xcodegen generate
open Oko.xcodeproj

The first two commands exercise the portable Core and UI targets on the host. Generate the project before opening it, then select an iOS Simulator or connected device in Xcode.

Source#

The mobile client is maintained in wisent-ai/oko-ios. Product, desktop, CLI, relay, and transcript-intelligence documentation remain under the owning Oko site.

Migrated from src/content/docs/ios.md