oka library

Oka: a declarative, no-Gradle build system for Flutter Android.

This package is the oka CLI and agent surface. It composes the platform packages into one build path that never invokes Gradle:

Package Role
oka_core Contracts: typed build context, BuildStep/Artifact pipeline, the declarative Oka composition root
oka_android Android pipelines, build steps, direct Android SDK toolchain (aapt2, d8, apksigner)
oka (this package) The oka CLI (bin/), doctor/get commands, version contract

Most users only need the CLI — oka reads a typed Dart entrypoint (or the legacy oka.yaml) from the project and runs the no-Gradle pipeline:

$ oka init                       # scaffold tool/oka_pipeline.dart
$ oka build apk --release        # no-Gradle release APK
$ oka build aab                  # no-Gradle Android App Bundle
$ oka explain                    # print the validated build plan (no tools)

Composing a pipeline in Dart

Projects that want full control declare their pipeline in Dart (ADR-0006) and point oka build at it via pipeline.dart_entrypoint:

import 'package:oka_android/oka_android.dart';
import 'package:oka_core/oka_core.dart';

Future<void> main(List<String> args) => okaRun(
      args,
      oka: const Oka(
        pipelines: [
          AndroidPipeline(
            config: AndroidBuild(packageName: 'dev.example.app'),
          ),
        ],
      ),
    );

Hook authors should depend on oka_android (which transitively provides oka_core), not this CLI package, to keep the host-app dependency surface minimal.

See also:

  • okaRun, the runtime that powers project entrypoints.
  • AndroidPipeline, the default no-Gradle Android pipeline.
  • Oka, the declarative composition root.

Classes

AabContentValidation
Detailed checks on the contents of an AAB, beyond its expected file names.
AabLayoutSpec
Describes files that must appear in a complete Flutter AAB base/ module.
AabLayoutValidation
Result of validating an AAB layout.
AdbDevice
One entry of adb devices [-l] output.
AdbFailure
Classified adb failure with an oka-style next step.
AdbTool
Thin adb executor. All argv goes through the pure constructors above; every failure is classified via classifyAdbFailure. Injectable adb path + process runner for scripted-fake tests.
AndroidAvdHandle
An Android Virtual Device identity restored from a durable state lease.
AndroidAvdHomeResolution
Result of resolving the directory Android uses to inventory AVDs.
AndroidAvdPlanner
Pure planner for persistent, host-scoped AVD inventory records.
AndroidAvdSource
Restores an AVD identity from the durable inventory lease.
AndroidAvdUseInspector
Reports positive observations of an AVD currently visible through adb.
AndroidBuild
Typed, const-constructible Android base config (ADR-0010).
AndroidBuilder
Android APK builder that orchestrates the build pipeline
AndroidCacheDiagnosticProvider
Describes Android virtual devices from recorded AVD metadata and the locations already discovered by the cache workspace.
AndroidDeliveryVerifier
Android implementation of the shared delivery verification contract.
AndroidDeviceProvisioner
Platform-scoped tool provider for Android device tooling (ADR-0013, T2).
AndroidPermission
Common permission name constants for typed composition.
AndroidPipeline
Declarative Android platform pipeline (ADR-0006).
AndroidSdkDoctorReport
Result of the Android SDK section of oka doctor.
AndroidSdkInstaller
Installs / cleans a minimal packaging Android SDK under an oka-owned root.
AndroidSdkInstallResult
Result of an install or cleanup operation.
AndroidToolchain
Android tool-resolution policy as data (ADR-0013, T1).
AndroidToolCheck
Outcome of one Android toolchain doctor check.
AndroidToolPolicy
Pure ordered source and remediation policy for Android host tools.
AndroidxJarProvisioner
Provisions the fixed AndroidX bootstrap artifacts used by host compilation. Legacy cache reads remain supported; new artifacts use ArtifactStore.
ApkLayoutSpec
Describes files that must appear in a complete Flutter APK layout.
ApkLayoutValidation
Result of validating an APK (zip) or a staging directory layout.
AppleCacheDiagnosticProvider
Stored Apple device metadata. This never invokes simctl or boots a device. Kept in the CLI adapter until an Apple platform package owns this provider.
Artifact<T>
A typed artifact key exchanged between pipeline steps (ADR-0006).
ArtifactCheck
One artifact validation. Implementations must be deterministic and offline; a check that cannot decide (missing inputs) returns ArtifactCheckVerdict.ok only when the absence is legitimate for the mode (e.g. no AOT in debug) and says so in ArtifactCheckVerdict.detail.
ArtifactCheckContext
Context handed to checks: the build and its staged state. Deliberately narrow — checks read; they never mutate.
ArtifactCheckVerdict
Outcome of one ArtifactCheck.
ArtifactComparison
Full comparison result for two APK/AAB artifacts.
ArtifactProvenanceRungStep
Rung: the artifact carries a provenance record and the staged binaries match its hashes. Old artifacts (no record) fail loudly — the ladder must not bless an unattested APK.
ArtifactStore
The one primitive for shared inputs across projects (ADR-0013): SDK components, Maven jars, Kotlin compilers, emulator images. Per-project outputs (staged APKs, dex) stay in buildDir/ under step-cache fingerprints — outputs are where nondeterminism lives; inputs are what a store can safely share (OKA_CACHE may point at a team/network path).
ArtifactStoreEntry
One materialized artifact in a store: its ContentKey, where it lives on disk, how big it is, when it was created, and which component registered it (source, e.g. maven-resolver).
AsdfVersionManager
asdf version manager implementation for Linux/macOS
AwaitVmServiceStep
Waits (bounded) for the Dart VM Service listening on … announcement in the device log after a debug launch, and provides vmServiceUri (ADR-0011 H2). Requires logcat -c to have run before the launch so a stale announcement from a previous run cannot match.
BadgingInfo
Parsed subset of aapt2 dump badging output.
BootEmulatorStep
Boots the emulator (idempotent: reuses an already-running instance for the same AVD) and waits for sys.boot_completed. Provides emulatorSerial.
BoundedRunResult
Outcome of a bounded run with bounded output capture.
BuildContext
Typed build context passed to every BuildStep (ADR-0006).
BuildLease
A machine-level lease around flutter/dart builds.
BuildStep
A composable unit of the build pipeline (ADR-0006).
BuildWarning
A warning that does not fail the build but demands attention.
BundletoolCommandResult
Process result used by the delivery verifier. Kept independent of ProcessResult so offline callers can inject bundletool responses.
BundletoolValidationResult
Result of bundletool's structural validate command.
BundletoolVerifyResult
Result of a bundletool verification run.
BytecodeCommandPolicy
BytecodeTools
CacheCleanupPlanRecord
CacheCleanupPlanRepository
CacheCleanupRequest
CacheDiagnosticAction
A suggestion only; callers explicitly choose whether to execute it.
CacheDiagnosticContext
Explicit inputs: inspection never discovers or executes project code. Supply canonical absolute project paths so all providers share relation IDs.
CacheDiagnosticContribution
CacheDiagnosticIds
Stable IDs: projects disambiguate otherwise identical lease IDs.
CacheDiagnosticIssue
CacheDiagnosticObservation
CacheDiagnosticProvider
Open extension point for platform packages; implementations must be read-only.
CacheDiagnosticRecord
Common navigable envelope, with provider-owned JSON-compatible metadata. Sizes in metadata are explanatory; they never augment storage totals.
CacheDiagnosticReport
CacheDiagnostics
Composes independent providers; one broken source cannot hide valid siblings.
CacheEvent
A step was served from the incremental cache.
CacheInspectRequest
CacheInspectResult
CacheProjectRegistry
Remembers project locations without placing user metadata in a prunable store.
CacheProjectRegistryIssue
CacheProjectRegistrySnapshot
CacheProjectSource
CacheTransactions
Headless cache application API used by the CLI and Dart callers.
CacheWorkspace
Resolved project coverage and one deduplicated storage inventory.
CacheWorkspaceRepository
Separates read-only inspection from explicit discovery and registration.
CacheWorkspaceRequest
ChangeClassification
Pure classification result: action plus human-readable reasons (path → why), so an agent can see exactly why a rebuild was routed.
CmakeNativeBuildService
CompileAndDexStep
aapt2 compile/link + kotlinc/javac + d8 → dex files.
CompileDexOutcome
CompileProtoAndDexStep
aapt2 compile + proto-format link + javac/kotlinc + d8 (AAB, ADR-0004).
ContentKey
Content-addressed identity of a stored artifact (ADR-0013).
CoreCacheDiagnosticProvider
First-party, read-only diagnostics for project and process metadata owned by oka_core. Platform packages add richer records through their own providers.
CredentialRef
A typed path reference to a build-host credential file (ADR-0014).
CredentialResolution
Result of credential-path resolution: the resolved path plus every candidate tried in order (the remediation law — failures name what was tried and the fix).
CredentialResolver
Credential-path resolution policy as data (ADR-0014).
CredentialSource
One ordered candidate source inside the credential-path policy.
DaemonEvent
One daemon event ([{"event": name, "params": {...}}]).
DaemonResponse
A response to a sent command ([{"id": N, "result"| "error": ...}]).
DaemonTransport
Narrow process seam for the adapter: everything FlutterDaemonAdapter needs from the spawned flutter attach --machine process. Injectable so tests feed a scripted fake instead of a real process.
DartMainBeaconRungStep
Rung: the generated startup beacon proves Dart main() entered (and ideally returned) in a release build — no app surgery (ADR-0029 D7).
DeeplinkConfig
Generates Android deeplink intent-filter XML fragments from config.
DeliveryVerificationOptions
Typed, platform-neutral options for post-build delivery verification.
DeliveryVerificationReport
Shared contracts for verifying a built artifact through a delivery target.
DeliveryVerificationStep
The shared pre-upload delivery gate (ADR-0023 §3): every store target that publishes with a DeliveryVerifier runs this step between artifact staging and the upload tail. A failed gate (including an unavailable verifier-reported check) is a hard failure — a target must never upload an artifact its verifier did not accept.
DeliveryVerifier
A delivery implementation supplied by a platform package.
DependencyCache
Disk-cache facade delegating resolution to MavenResolver.
DependencyPlanEntry
One source of declared dependencies: a plugin, pipeline.extra_deps, or the flutter-embedding AndroidX set.
DependencyPlanFinding
One resolution finding.
DependencyPlanReport
Composed + resolved dependency plan.
DependencyResolveStep
Resolves the AndroidX runtime dependency set (extensible via pipeline.extra_deps in oka.yaml and PipelineState.extraRuntimeJars).
DependencySuggestion
A suggested Maven coordinate for a missing class.
DevControlServer
The loopback JSON-lines control server (see the library doc). Bind is localhost-only by construction (InternetAddress.loopbackIPv4); there is no auth — this is a localhost-only dev tool, documented as such.
DevControlSessionInfo
Session metadata the status method answers from (no daemon round-trip): what the session attached to, not what the app is doing.
DevDeviceSelection
Result of selectDevDevice: exactly one ready device, or a refusal.
DevDiscoveryStore
DevDoctorReport
Result of devLoopDoctorChecks: overall readiness + printable lines.
DevEvent
DevEventRenderer
DevFlow
The outer oka dev flow: run one DevSession; when it ends with DevSessionOutcome.rebuildRequested, run the injected build (the exact parity flags the session was validated against), then re-attach. Quit/detach/daemon-exit end the flow.
DeviceHealthRungStep
Rung: is the host+device trustworthy at all? Fails-soft with RungStatus.inconclusiveDevice so downstream rungs are reported as unverified instead of silently passing/failing on poisoned evidence.
DeviceTarget
The device smoke-test target, shipped by oka_android (ADR-0015).
DevLaunchPrepared
Result of prepareDevLaunch: the device-side launch is done and the VM service is reachable (H2 artifacts consumed as-is).
DevSession
One flutter attach --machine session (ADR-0011 H3).
DevSessionCheck
Result of the oka dev preflight (checkDevSession): printable status lines, or the refusal reason. The CLI layer stays parse-and-delegate — every bit of session logic lives here.
DevSessionDiscovery
Typed view of .flutter_mcp/runner-session.json (see readRunnerSessionFile).
DevSessionDiscoveryRecord
DevSessionPreflight
Typed preflight transaction composed from persistence and SDK capabilities.
DexProbeOutcome
Outcome of checkDexSymbols.
DirectoryProcessLock
Directory mutex: create directory exclusively; steal when the recorded holder pid is dead. Caller releases on exit.
DiscoveredPlugin
A discovered Flutter plugin with optional Android metadata.
EmulatorTarget
Boots an Android emulator, idempotently (ADR-0013 T2 scope: provisioning
EngineArtifacts
Locates and extracts Flutter engine artifacts from a Flutter SDK tree.
EngineExtractionStep
Extracts libflutter.so per ABI from the Flutter engine artifacts.
EngineVariantMatchesModeCheck
The engine variant packaged into the artifact must match the build mode (debug → debug engine, profile → profile engine, release → release engine). Uses the provenance fact recorded by engine-extraction; when the fact is absent (build predating ADR-0029 D1) the check skips — the completeness check is the one that demands the fact.
EnsureAndroidSdkStep
Ensures Android SDK packaging tools exist; fails loudly otherwise.
EnsureAvdStep
Ensures the AVD exists (creates it when createIfMissing; a missing system image fails closed, naming the exact non-interactive sdkmanager command).
ExtraAssetsStep
Extra asset sources merged into flutter_assets/ at staging time.
ExtraDepsStep
Resolves user-declared extra Maven coordinates — including their POM transitive closure and AAR payloads — into PipelineState.extraRuntimeJars, aarNativeLibsByAbi, and aarResDirs before compile/package.
FailureSignature
One known launch-failure signature: the logcat needle, what it means, and the fix. evidence points at the incident write-up that recorded it.
FileCacheCleanupPlanRepository
FileDevDiscoveryStore
FileMaterialization
Result of a materializeFile call.
FileMavenArtifactRepository
FilePluginInputInspector
FileRunManifestRepository
FirstFrameRungStep
Rung: at least one frame rendered within budgetSeconds.
FixturePublishTarget
A conformance fixture: the minimal PublishTarget target packages extend, with a pure staging step standing in for real build steps.
FixtureStageAabStep
Pure staging step: provides the fixture artifact id, no I/O.
FixtureUploadStep
The real-mode upload tail (never executed under conformance — the audit only compiles/validates non-dry-run targets; it must never run this).
FlutterApkBuilder
Default no-Gradle Flutter APK builder.
FlutterAssembler
Runs flutter assemble for the Android application target.
FlutterAssembleResult
Result of a Flutter assemble invocation.
FlutterAssembleStep
Runs flutter assemble to produce flutter_assets.
FlutterAssetBundler
Flutter asset bundler that prepares flutter_assets/ directory
FlutterBuild
Typed, const-constructible Flutter build settings (ADR-0010) — the writable counterpart of the flutter: oka.yaml section.
FlutterDaemonAdapter
The daemon protocol adapter: parses stdout into typed DaemonEvents/DaemonResponses, gates commands behind app.start, and exposes reload / restart / stop / shutdown.
FlutterSdkProbe
FlutterSdkSnapshot
ForwardVmServiceStep
Forwards a local TCP port to the VM service port (adb forward tcp:0 tcp:DEVICE_PORT — adb picks a free local port) and provides vmServiceLocalPort (ADR-0011 H2). Requires vmServiceUri.
GmsDependencyProviderStep
A step that provides GMS-dependency artifacts for a composition that includes GMS (e.g. a Play distribution target).
HostCodegenStep
Generates MainActivity, GeneratedPluginRegistrant, manifest and minimal res.
HostFlutterSdkProbe
HostProcessLiveness
Default ProcessLiveness: ps / kill -0 on macOS, /proc/<pid> on Linux, and Windows PowerShell/CIM with machine and boot identity on Windows.
HostProcessTreeProbe
Default probe: ps -eo pid=,ppid= on macOS/Linux, Windows PowerShell/CIM on Windows.
HttpMavenTransport
HumanDevEventRenderer
IconConfig
Launcher icon configuration (ADR-0002 fast-settings).
IconResources
Result of staging launcher icon resources.
InstallApkStep
adb install -r the resolved APK, with the classic failure classification (signing-key mismatch, no device).
JavaEnvironment
Resolves and manages Java runtime environments for Kotlin compilation
JsonDevEventRenderer
LaunchAppStep
Resolves package + launchable activity (typed target config first, then aapt2 dump badging on the APK), clears the device log buffer, and starts the activity.
LeasedProcessProvider
Spawns a command as a leased, composition-managed component.
LeaseInventoryEntry
One entry of the lease inventory (inventoryLeases): the record plus its reconcile verdict against the live host.
LeaseReconcileSummary
Summary of the L2 reconcile sweep (reconcileLeases) — the crash- recovery pass that runs at doctor/CLI-inspection time.
LeaseStopHint
The graceful stop path for a leased process (ADR-0018 §1 stop_hint).
LeaseStopOutcome
Result of stopLease.
LintFinding
Result of one lint rule.
LocalAarsStep
Processes local AAR files declared in pipeline.local_aars.
LocalArtifactStore
Default ArtifactStore: a plain directory tree with one small JSON index per entry — no sqlite, no opaque blobs. A human can ls, du, and find -delete it, and every artifact is where ContentKey.toString says it is:
LogcatScanStep
Waits waitSeconds, checks the process is alive (pidof), then scans the full device log buffer for deviceFailureSignatures and reports.
LogcatSignaturesRungStep
Failure-signature scan over the device log, with cause/fix/evidence from the table (ADR-0029 D5) plus project extras.
ManifestSpec
Typed Android manifest specification rendered by host-codegen (ADR-0006).
MavenArtifactRepository
MavenCoordinate
A Maven coordinate — the single canonical typed value (ADR-0006/0007).
MavenMetadataParser
MavenRepoRegistry
Declarative Maven repository routing (ADR-0007): one authoritative group-prefix → host map instead of scattered hardcoded prefix checks.
MavenRepositoryRouter
MavenResolver
Resolves Maven coordinates to local jars (ADR-0007): repo routing, download with packaging fallback, AAR payload extraction, POM-graph transitive resolution (parents, BOMs, properties), memoization and parallel BFS.
MavenTransport
MetaDataSpec
A <meta-data android:name="…"> entry: either android:value or android:resource.
MissingDependencyResolver
Maps a missing class to dependency suggestions.
NativeBuildService
Oka
The declarative composition root for an oka build (ADR-0006).
PackageAndSignAabStep
Stages the AAB base/ module, zips and signs with jarsigner (v1).
PackageAndSignStep
Stages the APK layout, zips, zipaligns and signs.
PackagedPlugin
Result of packaging one Flutter Android plugin for no-Gradle APK builds.
ParsedGradleDep
A parsed dependency declaration.
Pipeline
Runs a list of steps in order, stopping at the first failure.
PipelineEvent
Base class — all events carry a wall-clock timestamp.
PipelineLog
Free-form progress message.
PipelineOverrides
Packaging fast-settings for the Android pipeline.
PipelineState
Mutable state shared across pipeline steps.
PlatformPipeline
A platform-specific pipeline (e.g. AndroidPipeline from oka_android).
PluginDeclaredDeps
Declared Maven inputs for one plugin (ADR-0008).
PluginDiscovery
Discover plugins for a Flutter project directory.
PluginDiscoveryResult
Result of scanning a Flutter project for plugins.
PluginInputInspector
PluginInputs
PluginPackager
Collects sources, Maven deps, resources, and native libs for Flutter plugins.
PluginPackagingResult
Aggregate packaging result for all plugins in a project.
PluginPackagingStep
Discovers plugins and packages them (sources, jars, natives).
PluginRegistration
Plugin registration entry used by generatePluginRegistrantJava.
PluginSupportDecision
Soft-mode gate: either hard-fail or return skip warnings.
PostBuildLintStep
Post-build lint (ADR-0007): runs after packaging, checks the artifact is actually releasable. Errors fail the build.
ProcessAliveRungStep
Rung: the app process is alive waitSeconds after launch.
ProcessCommand
The command a LeasedProcessProvider spawns — argv, never shell concatenation (ADR-0026 decision 11).
ProcessDaemonTransport
Real-process transport over Process.start(...).
ProcessLease
A durable record of one process oka spawned (or adopted), per ADR-0018 §1. Immutable value; JSON at the registry boundary only.
ProcessLeaseIssue
ProcessLeaseRegistry
Durable, advisory registry of ProcessLease records under directory (<project>/.oka_cache/processes/).
ProcessLeaseRegistrySnapshot
ProcessLiveness
Platform liveness / identity / kill seam (ADR-0018 §1): the three members every kind-specific lifecycle logic needs, abstracted from the host OS.
ProcessRunner
Injectable process runner (ADR-0007): every tool invocation flows through this interface so steps are testable without real SDKs and timeouts are enforced uniformly.
ProcessStopDecision
ProcessStopPolicy
Shared identity, ownership, verification and lease-retention policy. Platform adapters provide only the graceful operation and, for pid-less leases, a semantic verification probe.
ProcessTree
Snapshot of a process subtree rooted at rootPid.
ProcessTreeNode
One discovered process: pid, parent pid, and an optional command fragment kept for diagnostics only.
ProcessTreeProbe
Platform seam for subtree discovery, injectable for tests.
ProcOutcome
Result of an external process invocation.
ProjectDiscovery
Results from a bounded scan of explicitly selected project roots.
ProvenanceCompletenessCheck
The record must carry the facts the builtin pipeline promises. A missing fact means an unattested artifact — the exact gap that turned the 2026-09-27 incident into archaeology.
ProvenanceContributor
Extension point for developers composing on top of oka (ADR-0029 D1): anything that can name facts about this build. Steps may implement this too, but appending to state.addProvenanceFact(...) inside run() is usually simpler and composes with caching (facts are recorded per actual execution).
ProvenanceFact
A single provenance fact: namespaced key + JSON-primitive value.
ProvenanceRecord
The provenance record stamped into the artifact (flutter_assets/oka-provenance.json).
ProvenanceStampStep
Stamps the aggregated provenance record into flutter_assets/oka-provenance.json inside the build's staged assets — the artifact then carries its own birth certificate (ADR-0029 D1).
PublishPlan
The dry-run publish plan: exactly what a real run would do — the ADR-0008 plan law applied to publishing (ADR-0014).
PublishPlanStep
The plan-producing tail step oka_core substitutes for the upload step in dry-run mode (ADR-0014 dry-run law, as code).
PublishTarget
A Target with publishing conformance laws as code (ADR-0014).
PurgeResult
Outcome of a ArtifactStore.purge run.
RecordAndroidAvdInventoryStep
RecordRunSessionStep
Records run_session.json next to the packaged artifact (APK/AAB) at the end of the no-Gradle pipelines (ADR-0011 H1).
RegistryCacheProjectSource
ReleaseAotStep
Assembles release AOT (libapp.so) per ABI. No-op in debug/profile.
RepoHygieneReport
Outcome of the credential repo-hygiene check (ADR-0014).
ResolveAbisStep
Resolves target ABIs from config + CLI into PipelineState.abis.
ResolvedTool
A tool the policy actually resolved: where it lives and where it came from.
ResolvedToolchain
The resolved Android toolchain as an injectable artifact (ADR-0013, T1).
ResolveNewestApkStep
Resolves the APK the device flow operates on: explicitApk when given, otherwise the newest APK under .oka_cache/build/. Provides apkPath.
ResourceCompilationOutcome
RungStep
Shared plumbing for rung steps: resolve adb, invoke, record verdict.
RungVerdict
Typed verdict of one rung, JSON-encodable for the report artifact.
RunManifestRepository
Persistence boundary for run_session.json.
RunSession
The typed session manifest (ADR-0011 H1).
RunSessionRequest
The requested session — what oka dev was asked to run. Only fields a user can express on the CLI are compared; unset fields (null) are "no request" and match anything.
SdkLocator
Deprecated: thin wrapper over ResolvedToolchain (ADR-0013, T1).
SDKMANVersionManager
SDKMAN! version manager implementation for Linux/macOS
SecretAuditFinding
One audit finding: a dart-define key that looks like a secret.
SessionFieldMismatch
One differing field between the recorded manifest and the request.
SessionStateCleanupStep<H>
Cleanup preparation phase. Filesystem deletion remains core-owned.
SessionStateContext<H>
Typed input shared by workflow phases.
SessionStateFinding
One human- and machine-readable safety observation.
SessionStateHostIdentity
Stable Oka host identity plus identity of the current boot.
SessionStateInspector<H>
Read-only activity and ownership evidence.
SessionStateLease
A versioned durable pointer to one state resource.
SessionStateManager
Executes a workflow's typed provision stages after a durable reservation.
SessionStatePlan<H>
Typed planning value. handle is kept in memory and never serialized.
SessionStatePlanner<H>
Produces a plan without creating or mutating a resource.
SessionStateProvisionStep<H>
One idempotent provisioning phase.
SessionStateReconcileEntry
Explainable result for one lease.
SessionStateReconciler
Reconciles only when an explicit workflow with the exact recorded version is composed. Unknown providers and any inconclusive evidence are retained.
SessionStateReconcileReport
Full reconcile report, including registry parse issues.
SessionStateRegistry
Durable state records stored outside a project's .oka_cache.
SessionStateRegistryIssue
One session-state registry parse or filesystem issue.
SessionStateRegistrySnapshot
A non-mutating registry snapshot. Invalid records remain visible as issues.
SessionStateRequest
Inputs to a pure planner.
SessionStateSource<H>
A read-only source for reconstructing a typed handle from a durable lease.
SessionStateWorkflow<H>
Immutable composition of plan, typed source, provision, inspection and cleanup components. id is a stable, globally unique provider identifier; packages and projects must not reuse another workflow's ID because out-of-project CLI fallback can only compose first-party workflows.
SessionStateWorkflowContributor
Optional contract for targets that compose session-state workflows.
SessionStateWorkflowSession
A typed workflow restored from a durable lease for inspection, provisioning and cleanup preparation.
SessionValidation
Validation result: ok or mismatches (oka-branded rendering via formatSessionMismatches).
SignatureMatch
A matched signature in a log dump.
SigningConfig
Typed release-signing configuration (ADR-0006; closes the G2 gap).
SnapshotEnginePairingCheck
Verifies the staged AOT snapshot was built for the staged engine: the Dart snapshot version candidates in libapp.so and libflutter.so must intersect on exactly one hash (the 2026-09-27 incident shipped a snapshot the engine rejected — "VM snapshot invalid" — despite a matching-looking build).
SnapshotPairingRungStep
Rung: snapshot ↔ engine pairing on the built artifact (delegates to the same pure logic packaging validates with — see SnapshotEnginePairingCheck).
StageAabStep
Stages the Android App Bundle publish artifact (Artifact<String>('aab-path') — the shared publish contract, ADR-0014).
StepCache
Fingerprint-based step cache (ADR-0006: incremental builds).
StepFinished
A step finished.
StepResult
The outcome of a single pipeline step.
StepStarted
A step began executing.
StopEmulatorStep
Stops a booted emulator (adb -s <serial> emu kill) — compose into teardown targets; requires emulatorSerial (or an explicit serial).
StorageCleanupPlan
A reviewed selection, never a source of deletion authority. Applying it requires matching the selection against a newly discovered inventory.
StorageInventory
StorageLocation
A discoverable storage unit. Ownership is descriptive; pruning requires explicit eligibility and a matching scope.
StorageMeasurement
StoragePruneResult
StorageReport
StorageSelectionCriteria
Closed cleanup criteria evaluated against one measured snapshot.
SystemProcessRunner
Default runner: dart:io invocation with a deadline stop request.
Target
A project-declared, platform-owned build target (ADR-0015).
TargetChainDescription
The compiled, validated step chain of a Target — described, never executed (ADR-0015). This is the value behind oka explain --targets: the same validated-plan surface as builds (Pipeline.validate), with no tool invocation anywhere in the path.
TargetExecutionScope
Owns one target's forward execution, signal subscriptions and teardown.
TargetStepDescription
One step of a described target chain (ADR-0015): its name plus the artifact ids it requires and provides — the same summary oka explain prints for platform pipelines.
TeardownOutcome
Aggregate outcome of one teardown pass (runTeardownSteps).
Toolchain
Ordered, printable tool-resolution policy (ADR-0013, decision 1).
ToolchainEnv
Injectable environment for toolchain resolution (ADR-0013).
ToolQuery
Name of a tool to resolve, e.g. aapt2, d8, javac, kotlinc, adb.
ToolResolution
Outcome of evaluating a Toolchain policy for one ToolQuery.
ToolSource
One ordered candidate source inside a resolution policy.
TreeStopResult
Result of a tree stop. survivors lists pids still alive after the ladder or whose liveness is unverified. Only stopped establishes verified teardown; an empty list can accompany unknown discovery.
ValidateAabLayoutStep
Validates the produced AAB layout (proto manifest + dex + assets + libs).
ValidateArtifactStep
Runs checks over the staged artifact and fails the build on the first failing verdict. Composition-time wiring keeps this before packaging in the default pipelines; a check failure is a red build, not a shipped APK.
ValidateLayoutStep
Validates the produced APK layout (dex + flutter_assets + lib/<abi>).
VerificationReportStep
Renders the ladder report and turns it into the run's exit: any failed rung fails the run; an inconclusive device fails with distinct guidance (never a silent pass); all-pass prints the ladder summary.
VerifyTarget
The release verification ladder as a project-declared target (ADR-0015 + ADR-0029 D3). Run with oka run verify.
VersionManager
Abstract interface for Java version managers
VmServiceInfo
Parsed VM service announcement.
WindowsProcessLiveness
Windows process probe backed by inbox Windows PowerShell 5.1 and CIM.
WindowsProcessSnapshot
A validated Windows process observation.
WingetVersionManager
winget version manager implementation for Windows
ZipEntryDiff
Zip-level comparison result for the entry lists of two artifacts.

Enums

AndroidResourceFormat
BoundedRunCause
Why a bounded run ended — the meaning of the death, not just the fact.
BuildMode
Build mode enumeration.
CacheObservationSource
ChangeAction
What to do with a set of changed paths.
CredentialSourceKind
Where a credential path may come from, in descending order of preference (mirrors ToolSourceKind from the T1 tool policy).
DevControlCommand
Session control commands. Sources: the human TTY keyboard loop (r/R/q/d — see devCommandFromKey), the --json stdin line protocol (reload/restart/stop/detach/quit — see devCommandFromLine), and the --watch dispatcher (Dart change → DevControlCommand.reload; native change → DevControlCommand .rebuildRouting).
DevSessionOutcome
How a DevSession ended.
KillIdentity
Verdict of the identity-over-pid kill gate (verifyKillIdentity).
LeaseLiveness
Liveness verdict for a lease record (ProcessLeaseRegistry.checkLiveness).
LeaseOwnership
Ownership of a leased process (ADR-0018 §3): owned = this run spawned it; borrowed = idempotent reuse found it running. Teardown stops only owned leases — killing a borrowed session would break the reuse contract and whatever other terminal owns it.
LeaseScope
Lifecycle scope of a leased process (ADR-0018 §3): declared on the spawn target — a parameter, not a type hierarchy.
LeaseStopAction
How stopLease resolved (the action field of stop.result).
MaterializationStrategy
How a file was materialized — surfaced for verbose logs and tests.
MavenHost
ProcessStopDisposition
RungStatus
Outcome of one ladder rung.
SessionStateAcquisitionMode
How this acquisition relates to the resource.
SessionStateDisposition
Classification for a session-state lease.
SessionStateNamespace
Whether a resource is project-local or shared by the host.
SessionStateOwnership
Who owns the state resource itself, not the process using it.
SessionStatePhase
Durable lifecycle phase.
SessionStateResourceKind
A filesystem tree Oka can manage, or a resource that needs its own API.
SessionStateRetention
How long state is retained independently of its owning process.
SessionStateUse
Structured result from one state inspector. Only unused is affirmative; busy and unknown both block cleanup.
Severity
ToolSourceKind
Where a tool may come from, in descending order of preference.

Extension Types

AndroidConfig
Extension type that represents Android build configuration.
BuildArtifact
Extension type for build artifacts.
Dependency
Extension type that represents a dependency declaration.
FlutterConfig
Extension type that represents Flutter-specific configuration.
OkaConfig
Extension type that represents the main Oka configuration.
PluginMetadata
Extension type that represents Flutter plugin metadata.

Extensions

AndroidPipelineState on PipelineState
The store keys match the ids of the artifact constants in android_artifacts.dart.

Constants

aarNativeLibsByAbi → const Artifact<Object>
Native libs from processed AARs: abi → .so paths.
aarResDirs → const Artifact<List<String>>
Resource dirs extracted from AARs (values XML trees for aapt2).
abis → const Artifact<List<String>>
Resolved ABIs for the build (provided by resolve-abis).
androidAvdStateWorkflow → const SessionStateWorkflow<AndroidAvdHandle>
Default Android AVD workflow: durable inventory only, with no state creation, userdata reset, automatic cleanup, or inactive-state assertion.
androidxJars → const Artifact<Object>
Resolved AndroidX / runtime jars (provided by dependency-resolve and merged by extra-deps).
apkPath → const Artifact<String>
Final APK path (provided by package-and-sign / package-and-sign-aab).
apkStagingDir → const Artifact<Directory>
Staged APK layout directory (pre-zip).
builtinArtifactChecks → const List<ArtifactCheck>
Default checks the builtin pipeline ships (ADR-0029 D2). Third parties add their own by composing ValidateArtifactStep with their lists.
builtinFailureSignatures → const List<FailureSignature>
Signatures oka ships, most specific first (scanning reports every match; order only affects display).
defaultR8KeepRules → const String
Default keep rules oka feeds R8 for every release build (merged with the project's android.proguard_files). Validated against R8 9.4.24.
deviceFailureSignatures → const Map<String, String>
Device-log failure signatures scanned after launch (name → needle).
dexFiles → const Artifact<List<String>>
Produced dex files (provided by compile-and-dex / compile-proto-and-dex).
embeddingJar → const Artifact<String>
Flutter embedding classes jar (provided by engine-extraction).
emulatorSerial → const Artifact<String>
Artifact: the booted emulator's adb serial (emulator-5554).
engineVariants → const List<String>
Canonical engine variant suffixes (debug, profile, release).
extraRuntimeJars → const Artifact<List<String>>
Extra runtime jars injected by user config / hooks.
factAotBuildId → const String
factAotSnapshotSha256 → const String
factAssembleFingerprint → const String
factEngineJarSha256 → const String
factEngineLibflutterSha256 → const String
factEngineVariant → const String
Well-known fact keys (dot-namespaced; third parties use their own prefix — collide-proof by convention, e.g. my_plugin.variant).
factResolutionPackageConfigSha256 → const String
factResolutionPubspecLockSha256 → const String
flutterAssetsDir → const Artifact<String>
flutter_assets directory from flutter assemble.
gmsDependencyArtifactPrefix → const String
Artifact-id prefix marking a GMS-provided dependency.
gmsGroupPrefixes → const List<String>
Maven group prefixes whose artifacts are provided by Google Play Services (GMS) and therefore excluded from a GMS-free build variant.
hostDir → const Artifact<String>
Generated host sources dir — MainActivity, registrant, manifest (provided by host-codegen).
kBundletoolDownloadUrl → const String
Latest bundletool release download URL (GitHub releases).
kBundletoolVersion → const String
bundletool version served by kBundletoolDownloadUrl.
kDefaultSoftSkipPluginNames → const Set<String>
Plugin names that previously required soft-mode skip.
kKnownClassArtifacts → const Map<String, List<({String artifact, double confidence, String group, String version})>>
Offline knowledge base mapping well-known runtime-missing classes to their Maven artifacts. Keys are class prefixes matched against NoClassDefFoundError: Lcom/foo/Bar; descriptors.
kOkaSdkMarkerName → const String
Marker file written into oka-managed SDK roots so cleanup is safe.
kR8Version → const String
R8 version provisioned by oka (stable Google Maven release).
kSupportedAbis → const List<String>
Expected native ABI directory names inside an Android APK.
libappByAbi → const Artifact<Map<String, String>>
ABI → libapp.so paths, release AOT (provided by release-aot).
libflutterByAbi → const Artifact<Map<String, String>>
ABI → libflutter.so paths (provided by engine-extraction).
noAutoInstallEnv → const String
Set when automatic tool installation should be suppressed.
nonCredentialOkaEnvVars → const Set<String>
OKA_* env vars that are oka mechanics (cache root, SDK override, verbosity, …), not credential path references — excluded from the doctor's credential discovery. Tested constant.
okaGetUsageText → const String
Usage text for oka get (provisioning nouns + examples). Owned here so the verb stays free of Android packaging specifics (ADR-0015).
okaProvisionedToolGuidance → const List<ProvisionedToolGuidance>
Tools oka provisions into ~/.oka/tools (ADR-0007 self-heal + oka get). ProvisionedToolGuidance.match is a basename prefix; children without a match fall back to the discovery layer's generic note.
packagedPlugins → const Artifact<Object>
Packaged plugin outputs — sources, jars, natives (provided by plugin-packaging).
pipelineOverridesKey → const String
Typed accessors for Android build artifacts shared across steps (ADR-0006).
pluginDiscovery → const Artifact<Object>
Plugin discovery result (provided by plugin-packaging).
processLeasePidTokenKey → const String
Reserved ProcessLease.identity key carrying the platform process start-time token — the identity-over-pid anchor (ADR-0018 §1).
provenancePath → const Artifact<String>
Provenance record stamped into the artifact (provided by provenance-stamp, ADR-0029 D1).
provenanceSchemaVersion → const int
Schema version of the provenance record. Bump on breaking key changes.
registrations → const Artifact<List<PluginRegistration>>
Plugin registrations feeding GeneratedPluginRegistrant.
reservedCliVerbs → const Set<String>
Core CLI verbs, reserved across all projects (ADR-0015).
resolvedToolchainKey → const String
Key under which AndroidPipeline.run seeds the resolved toolchain (ADR-0013 T1): one shared, printable resolution policy for all steps.
runSessionFileName → const String
File name of the session manifest, written next to the APK.
runSessionPath → const Artifact<String>
Session manifest path recorded by record-run-session (ADR-0011 H1).
runSessionSchemaVersion → const int
Manifest schema version. Bump on any breaking field change; readers refuse unknown-schema manifests with an actionable error.
secretAuditTierRule → const String
The ADR-0014 tier-rule remediation message.
secretishKeyPatterns → const List<String>
Secret-ish dart-define key patterns (ADR-0014).
startupBeaconEnteredNeedle → const String
Logcat needle the dart-main verification rung waits for.
startupBeaconReturnedNeedle → const String
verificationVerdicts → const Artifact<List<String>>
Verification rung verdicts, JSON lines (ADR-0029 D3). Appended by each *-rung step; rendered by verification-report.
version → const String
Oka version
vmServiceLocalPort → const Artifact<int>
Local host port from adb forward tcp:0 (provided by forward-vm-service).
vmServiceUri → const Artifact<String>
VM service URI scraped from device log (provided by await-vm-service).
windowsProcessTableScript → const String
PowerShell table probe: one pid|ppid row per process. Fails loudly on an unavailable CIM so callers read "unknown", not "empty".

Properties

androidProvisioners → Map<String, Future<void> Function()>
Android provisioning nouns for the generic oka get verb, resolved via oka_android (ADR-0013/T1 tool-provider shape: the verb looks its noun up here — no Android dispatch literals in the CLI, ADR-0015).
final
autoInstallEnabled → bool
no setter
stdinUsagePattern → RegExp
Marker regexes for the no-stdin law (ADR-0013, inherited by ADR-0014).
final

Functions

adbDevicesArgs() → List<String>
adb devices -l (long listing: id, state, model).
adbForwardArgs({required int devicePort, int hostPort = 0, String? serial}) → List<String>
adb [-s <serial>] forward tcp:<hostPort> tcp:<devicePort>; hostPort 0 = adb picks a free local port (printed on stdout).
adbInstallArgs(String apk, {String? serial}) → List<String>
adb [-s <serial>] install -r <apk> (reinstall, keep data).
adbInstallMultipleArgs(List<String> apks, {String? serial}) → List<String>
adb [-s <serial>] install-multiple -r <apk>... for split APK sets.
adbLaunchArgs(String packageName, String activity, {String? serial}) → List<String>
adb [-s <serial>] shell am start -n <package>/<activity>.
adbLogcatClearArgs({String? serial}) → List<String>
adb [-s <serial>] logcat -c (clear buffer before launch, per LaunchAppStep).
adbLogcatDumpArgs({String? serial}) → List<String>
adb [-s <serial>] logcat -d (dump the current buffer — bounded scrape, no stream).
adbSerialArgs(String? serial) → List<String>
Serial prefix so adb targets one attached device. Multi-device hosts (phone + emulator) fail with "more than one device" without it.
androidAotBundleTarget(String abi) → String
AOT bundle target for a given ABI (produces app.so / libapp.so layouts).
androidApplicationTarget(BuildMode mode) → String
Flutter assemble target name for Android application assets (debug/profile).
androidSdkDoctorChecks({ResolvedToolchain? toolchain}) → Future<AndroidSdkDoctorReport>
Runs the Android SDK doctor checks (ADR-0013 toolchain policy semantics: same resolution, same order, results as data).
anyDexContainsClass(Iterable<List<int>> dexBlobs, String fullyQualifiedClass) → bool
True if any of the given DEX blobs contains fullyQualifiedClass.
assembleBuildMode(BuildMode mode) → String
Build mode string for flutter assemble defines.
auditDartDefines({Map<String, String> inlineDefines = const {}, Map<String, String> fileDefines = const {}}) → List<SecretAuditFinding>
Audits dart-define keys (inline --dart-define + --dart-define-from-file keys) against secretishKeyPatterns. Pure: takes keys only — values are never read, never stored, never logged (ADR-0014).
auditPublishConformance(PublishTarget target, BuildContext ctx, {List<String> sourcePaths = const []}) → Future<List<String>>
Audits a PublishTarget against the three publishing conformance laws (ADR-0014) and returns human-readable violations (empty = conforming).
avdManagerCreateArgs({required String name, required String image, String? deviceProfile}) → List<String>
avmmanager create avd -n <name> -k "<image>" [-d <device>] — echo no | is the caller's job (stdin must never be attached; avdmanager's custom hardware profile prompt defaults to no).
avdManagerListArgs() → List<String>
avdmanager list avd (the AVD inventory — emulator -list-avds is an emulator-binary flag, NOT an avdmanager one; passing it there is the bug this helper naming exists to prevent).
buildAapt2CompileDirArgs({required String resDir, required String compiledResourcesZip}) → List<String>
Args after the aapt2 executable for directory resource compilation.
buildAapt2LinkArgs({required String androidJar, required String manifestPath, required String outputAp, required String compiledResourcesZip, List<String> overlayZips = const [], String? javaOutDir, String? assetsDir, bool autoAddOverlay = true, List<String> resourceConfigs = const [], String? versionCode, String? versionName}) → List<String>
Args after the aapt2 executable for linking compiled-resources zips.
buildAapt2LinkProtoFormatArgs({required String androidJar, required String manifestPath, required String outputAp, required String compiledResourcesZip, List<String> overlayZips = const [], String? javaOutDir, bool autoAddOverlay = true, List<String> resourceConfigs = const [], String? versionCode, String? versionName}) → List<String>
Args after aapt2 for linking in proto format (App Bundle inputs).
buildDependencyPlan({required List<DiscoveredPlugin> plugins, required PluginPackager packager, required DependencyCache cache, required bool allowNetwork, List<String> extraDeps = const []}) → Future<DependencyPlanReport>
Compose the dependency plan from plugins + extraDeps and resolve it.
buildFlutterAotAssembleArgs({required String outputDir, required String targetFile, required String abi, List<String> extraArgs = const [], Map<String, String> dartDefines = const {}}) → List<String>
Pure command construction for release AOT bundle assemble.
buildFlutterAssembleArgs({required String outputDir, required String targetFile, required BuildMode mode, required String targetPlatform, List<String> extraArgs = const [], bool trackWidgetCreation = true, Map<String, String> dartDefines = const {}}) → List<String>
Pure command construction for flutter assemble (asset/kernel pipeline).
buildRelative(String projectPath, String path) → String
Relative-path helper re-exported for step diagnostics.
bundletoolAvailableInOkaTools({Directory? toolsDir}) → Future<bool>
True when a bundletool jar/wrapper sits under the oka tools dir (~/.oka/tools) — the doctor's presence signal for the AAB verification dependency (ADR-0004). toolsDir is injectable for tests.
bundletoolHealthLines({Directory? toolsDir}) → Future<List<String>>
Build-Health lines for the bundletool verification dependency, formatted exactly as oka doctor prints them (ADR-0015: the strings live with the mechanism they describe). toolsDir is injectable for tests.
bundletoolStoreKey({String version = kBundletoolVersion, String downloadUrl = kBundletoolDownloadUrl}) → ContentKey
Store key for the bundletool jar (ADR-0013/0028) so oka cache list/gc sees it and OKA_CACHE can share it.
checkCredentialRepoHygiene({required String credentialPath, required String projectPath, GitignoreChecker? isIgnored}) → RepoHygieneReport
Repo-hygiene check (ADR-0014): a credential file resolved inside the project must be gitignored — oka checks and warns.
checkDevSession({required String projectPath, String? targetFile, List<String> dartDefinePairs = const [], String? dartDefineFromFile, String requestedBuildMode = 'debug', RunManifestRepository manifestRepository = const FileRunManifestRepository(), FlutterSdkProbe sdkProbe = const HostFlutterSdkProbe(), Future<String?> discoverApk(String projectPath)?}) → Future<DevSessionCheck>
oka dev preflight (ADR-0011 H1): validate the newest built APK's session manifest against the requested session and resolve the flutter binary from the recorded SDK path (never ambient PATH).
checkDexSymbols({required String apk, required List<String> queries, void emit(String message)?}) → Future<DexProbeOutcome>
Runs the DEX symbol probe and prints the per-class report (same output the oka debug dex verb has always shown — the verb only parses args).
classifyAdbFailure(String rawOutput) → AdbFailure
Maps raw adb output to a typed failure + oka-style remediation. Best-effort: unknown outputs degrade to AdbFailure.kind = unknown with the raw text — never a silent pass.
classifyChanges(Iterable<String> paths) → ChangeClassification
Classifies changed paths (relative to the project root; absolute paths are normalized). The strongest action wins: any rebuild-class path routes the whole batch to a full rebuild.
clearRunnerSessionFile(String projectPath, {DevDiscoveryStore store = const FileDevDiscoveryStore()}) → Future<void>
Removes the runner-session discovery file (session over → no live channel). Only the file is deleted — never the .flutter_mcp/ directory or any sibling file (e.g. the toolkit's state.json).
clearVmUriFile(String projectPath, {DevDiscoveryStore store = const FileDevDiscoveryStore()}) → Future<void>
Removes the discovery file (session over → no live endpoint).
collectProvenance(List<ProvenanceFact> stateFacts, List<ProvenanceContributor> contributors, {BuildContext? ctx, PipelineState? state}) → ProvenanceRecord
Collects facts from the state list and contributors (declarative extras), last-writer-wins per key, preserving first-seen order. Pure.
commandLineToolsDownloadUrl({String? osOverride, String version = '11076708'}) → String
Command-line tools zip URL for the current host OS/arch.
compareArtifacts(String pathA, String pathB, {String? aapt2Path, bool skipBadgingSection = false, Future<String> dumpBadging(String aapt2, String artifact)?}) → Future<ArtifactComparison>
Compare two APK/AAB artifacts (badging + zip entries).
compareMavenVersions(String left, String right) → int
Compares dotted Maven version strings numerically segment by segment (1.15.0 > 1.9.0), ignoring non-digit separators (rc/beta suffixes).
compareZipEntries(String pathA, String pathB) → ZipEntryDiff
Compare the zip entry lists of two APK/AAB files.
compileAndDex({required BuildContext ctx, required ResolvedToolchain toolchain, required String hostDir, required String embeddingJar, required List<String> androidxJarPaths, List<String> pluginJavaSources = const [], List<String> pluginKotlinSources = const [], List<String> kotlinCompilerArgs = const [], List<String> pluginJarDeps = const [], List<String> pluginResDirs = const [], List<String> resourceConfigs = const [], String? versionCode, String? versionName, int? javaVersionOverride, AndroidProcessRunner processRunner = runAndroidProcess}) → Future<CompileDexOutcome>
compileAndDexProto({required BuildContext ctx, required ResolvedToolchain toolchain, required String hostDir, required String embeddingJar, required List<String> androidxJarPaths, List<String> pluginJavaSources = const [], List<String> pluginKotlinSources = const [], List<String> kotlinCompilerArgs = const [], List<String> pluginJarDeps = const [], List<String> pluginResDirs = const [], List<String> resourceConfigs = const [], String? versionCode, String? versionName, int? javaVersionOverride, AndroidProcessRunner processRunner = runAndroidProcess}) → Future<CompileDexOutcome>
compileAndroidBytecode({required BuildContext ctx, required BytecodeTools tools, required String hostDir, required String generatedSourcesDir, required String androidJar, required String embeddingJar, required List<String> dependencyJars, List<String> pluginJavaSources = const [], List<String> pluginKotlinSources = const [], List<String> kotlinCompilerArgs = const [], int? javaVersionOverride, AndroidProcessRunner processRunner = runAndroidProcess, BytecodeCommandPolicy? commandPolicy, Future<String?> ensureR8Tool({bool verbose}) = ensureR8, Future<Map<String, String>> environmentLoader({bool verbose}) = kotlinJavaEnvironment}) → Future<CompileDexOutcome>
compileAndroidResources({required BuildContext ctx, required ResolvedToolchain toolchain, required AndroidResourceFormat format, List<String> pluginResDirs = const [], List<String> resourceConfigs = const [], String? versionCode, String? versionName, AndroidProcessRunner processRunner = runAndroidProcess}) → Future<ResourceCompilationOutcome>
composeR8Rules({String base = defaultR8KeepRules, List<String> extraRules = const []}) → String
Composes the app-level R8 rule text from the oka defaults and the project's inline extraRules (AndroidBuild.r8Rules) — pure, so the merge order is golden-testable: defaults first, app rules last (later rules override earlier ones in R8).
computeDevWatchPaths({required String projectPath, String? targetFile}) → List<String>
The watched surface for a dev session (absolute paths): lib/, the target file, android/, assets/, oka.yaml, pubspec.yaml. Missing paths are skipped (a pure-Dart project may have no android/).
copyDirectory(Directory source, Directory destination) → Future<void>
Copies a res tree into destination (used by host codegen to stage user resDirs into the primary build res dir; later copies override earlier files, which is the intended user-over-generated precedence).
copyDirectoryTree(Directory source, Directory dest) → Future<void>
createToolTempDirectory(String prefix) → Future<Directory>
debounceStream<T>(Stream<T> source, Duration interval) → Stream<List<T>>
Quiet-period debounce: emits a batched list of values only after interval passed with no new value. Values arriving during the quiet window accumulate (a save storm is one dispatch).
debugKeystore({AndroidProcessRunner processRunner = runAndroidProcess}) → Future<String>
decidePluginSupport(PluginDiscoveryResult result, {bool strict = true}) → PluginSupportDecision
Decide whether build may proceed given unsupported plugins.
dedupeConditionalDeps(List<ParsedGradleDep> deps, {String pluginName = '', void onNotice(String notice)?}) → List<ParsedGradleDep>
Keep only the first variant of each if/else conditional group.
defaultAabPipeline(ResolvedToolchain toolchain, {bool verbose = false, bool strictPlugins = true, bool allowNetwork = true, DependencyCache? dependencyCache, PipelineOverrides overrides = const PipelineOverrides()}) → Future<Pipeline>
Builds the default no-Gradle AAB pipeline (ADR-0004).
defaultAbi() → String
Host-ABI default: arm64-v8a on ARM hosts, x86_64 otherwise.
defaultApkPipeline(ResolvedToolchain toolchain, {bool verbose = false, bool layoutOnly = false, bool strictPlugins = true, bool allowNetwork = true, DependencyCache? dependencyCache, PipelineOverrides overrides = const PipelineOverrides()}) → Future<Pipeline>
Builds the default no-Gradle APK pipeline (ADR-0002).
defaultBundletoolJarPath() → String
bundletool helpers for AAB verification (ADR-0004).
defaultCacheDiagnosticProviders() → List<CacheDiagnosticProvider>
First-party composition. Package developers may use, replace or extend it.
defaultCacheLocationSource({required String projectPath, required Map<String, String> environment, required bool includeShared, required bool includeProject, required ProcessLiveness liveness, List<({String guidance, String match})> toolGuidance = const []}) → Future<List<StorageLocation>>
defaultForegroundVector() → String
Default oka glyph: rounded "O" ring centered in the adaptive-icon safe zone (108dp viewport, content within inner ~66dp).
defaultLinkAttempts() → List<_LinkAttempt>
Default chain: clonefile (macOS) → reflink (Linux) → hardlink (POSIX). Platform-guarded; unsupported strategies report null immediately.
defaultOkaAndroidSdkRoot() → String
Default root for oka-managed Android SDK installs: ~/.oka/android-sdk.
defaultOkaToolsDir() → Directory
Default oka tools dir (~/.oka/tools).
defaultR8JarPath({String version = kR8Version}) → String
Default jar path for version under the oka tools directory.
definesToLine(Map<String, String> defines) → String
describeArtifacts(Iterable<Artifact<Object>> artifacts) → String
Shared helper for diagnostics.
describeSecretAuditLines({Map<String, String> inlineDefines = const {}, Map<String, String> fileDefines = const {}}) → List<String>
Doctor lines for the secret audit: ✅ when clean, one ❌ line per finding with the tier-rule fix.
describeTarget(Target target, BuildContext ctx) → TargetChainDescription
Describes target's compiled step chain without running it (ADR-0015).
detectMainShape(String entrypointSource) → ({bool isAsync, bool takesArgs})
Detects the real main declaration shape in entrypointSource.
detectRequiredJavaLevel(Iterable<String> gradleFiles) → int?
sourceCompatibility "NN") declared in any of gradleFiles; null when nothing declares one.
devCommandFromKey(String key) → DevControlCommand?
Maps the human TTY keyboard loop to commands (r reload, R hot restart, q quit, d detach). Returns null for unrecognized keys.
devCommandFromLine(String line) → DevControlCommand?
Maps a --json stdin control line to a command. Returns null for blank/unknown lines (unknown lines are answered with the key list).
devDependencyNames(String projectPath) → Set<String>
Names declared under dev_dependencies in projectPath/pubspec.yaml.
devLoopDoctorChecks({required String projectPath, ResolvedToolchain? toolchain, String? adbPath, bool checkDevice = true}) → Future<DevDoctorReport>
Runs the dev-loop readiness checks. checkDevice can be disabled for environments without a device expectation (CI) — the device check is the only one that needs adb to exist.
dexBytesContainString(List<int> dexBytes, String needle) → bool
Search raw DEX bytes for a UTF-8 needle (class descriptors often appear as plain strings, e.g. Lio/flutter/plugins/GeneratedPluginRegistrant;).
discoverStorageLocations({required String projectPath, Map<String, String>? environment, String? hostPlatform, bool includeShared = true, bool includeProject = true, ProcessLiveness liveness = const HostProcessLiveness(), List<({String guidance, String match})> toolGuidance = const []}) → Future<List<StorageLocation>>
Discovers directory storage without invoking platform package managers. External caches and device data are always informational.
doctorCredentialPolicyLines({Map<String, String>? environment, String? home, String? projectPath, List<CredentialRef> refs = const []}) → List<String>
Doctor credential-policy section (ADR-0014): the ordered policy as lines, resolution status for known refs, OKA_* env discovery, the well-known location, and the repo-hygiene verdict for every resolved credential inside projectPath.
doctorSecretAuditLines({List<String> inlineDefineArgs = const [], List<String> defineFilePaths = const []}) → List<String>
Parse-and-delegate entry for oka doctor: parses raw --dart-define=K=V flag values and --dart-define-from-file paths (the CLI passes raw strings only — no mechanics), audits the keys, and returns doctor lines. Unreadable files become ❌ lines, never throws.
downloadBundletool({String? destPath, bool verbose = false}) → Future<String>
Download bundletool into the shared artifact store (ADR-0028 §1).
effectiveJavaLevel({required int configVersion, Iterable<String> pluginGradleFiles = const [], void onBump(String message)?}) → int
Effective javac source/target: config version raised to the detected plugin maximum, with a printed notice when bumped.
emulatorLaunchArgs({required String name, bool headless = true, bool noSnapshotSave = true}) → List<String>
emulator -avd <name> [flags].
encodeVerdictLine(Map<String, Object?> verdict) → String
JSON encoding helper shared with verify rungs.
engineArtifactDirForVariant(String abi, {required String variant}) → String
Flutter engine cache dir for a build-mode variant: debug → android-<abi>, profile → android-<abi>-profile, release → android-<abi>-release (produce variant via engineVariantForMode).
engineArtifacts(BuildContext ctx, ResolvedToolchain toolchain) → Future<EngineArtifacts>
Engine artifacts helper shared by engine-related steps.
engineVariantForMode(BuildMode mode) → String
Engine cache-dir suffix for a build mode: debug → '', profile → '-profile', release → '-release'.
engineVariantOrThrow(String variant) → String
enrichPluginFromPubspec(DiscoveredPlugin plugin) → Future<DiscoveredPlugin>
Reads plugin Android class from plugin's pubspec.yaml flutter.plugin section.
ensureKotlinc({bool verbose = false}) → Future<bool>
Ensures the Kotlin compiler is available, downloading it into ~/.oka/tools when missing. Returns true when kotlinc is usable.
ensureR8({bool verbose = false}) → Future<String?>
Ensures the R8 shrinker jar is available, downloading the Google Maven release into ~/.oka/tools/r8 when missing (ADR-0007 self-heal, shared with oka get r8). Returns the jar path, or null when unavailable and auto-install is disabled/failed.
evaluateDeviceHealth({required String bootCompleted, required double loadAvg1, required bool anrInFocus, double maxLoad = 16}) → RungVerdict
Decides device health from raw probes. Pure.
expectPublishConformance(PublishTarget target, BuildContext ctx, {List<String> sourcePaths = const []}) → Future<void>
Asserts the three ADR-0014 publishing conformance laws for target — the shared suite any publish target must pass (the exportable seam target packages call from their tests).
extractAarPayload(List<int> aarBytes, String destDir, {bool verbose = false}) → Future<({String? manifestPath, Map<String, List<String>> nativeLibsByAbi, List<String> resDirs})>
Extracts AAR payload beyond classes.jar: jni/<abi>/*.so natives, res/, and the AAR's own AndroidManifest.xml (for per-package R).
extractClassesJarFromAar(List<int> aarBytes) → Uint8List
Extracts classes.jar bytes from an AAR (zip) archive.
extractClassesJarToFile(List<int> aarBytes, String destJarPath) → Future<String>
Writes extracted classes.jar to destJarPath; returns path.
extractDartSnapshotVersionCandidates(List<int> bytes) → List<String>
The Dart snapshot version hash is a 32-hex string embedded in both the AOT snapshot (libapp.so) and the engine that must run it (libflutter.so). In libapp.so it is immediately followed by the feature string (e.g. product no-asan …); in the engine it appears as a standalone string. Both may sit near ELF note build-ids, so candidates are intersected rather than trusted on sight.
extractMissingClass(String logText) → String?
Extracts the first missing-class descriptor from an ART crash log / NoClassDefFoundError message.
extractUniversalApk(String apksPath, String destApkPath) → Future<String>
Extract the universal APK from a .apks archive (it is a zip with splits/universal.apk).
fileSha256(String path) → Future<String?>
SHA-256 of a file (hex), or null when the file does not exist.
filesUnder(String dir, {String? extension}) → List<String>
Collects all files under dir (recursively), or returns empty when the dir does not exist.
filterCompileOnlyJars(List<String> jars) → List<String>
filterRuntimeJars(List<String> jars) → List<String>
findBundletool({String? explicitPath}) → Future<String?>
Locate a usable bundletool jar: explicit path, OKA env var, artifact store, oka tools dir, then PATH lookup for a bundletool wrapper.
findCmake(String androidSdk, {AndroidProcessRunner processRunner = runAndroidProcess}) → Future<String?>
findFlutterAssetsDir(String assembleOutput) → Future<String?>
Locates flutter_assets under an assemble output directory.
findJarsigner(ResolvedToolchain toolchain, {AndroidProcessRunner processRunner = runAndroidProcess}) → Future<String?>
findLibappSo(String aotOutput) → Future<String?>
Locates app.so / libapp.so under an AOT assemble output.
findNdkHome(String androidSdk, {Map<String, String>? environment}) → Future<String?>
findNewestBuiltApk(String projectPath) → Future<String?>
Newest APK across .oka_cache/build/*/app-*.apk (including the *-aab sibling layout), or null when none exists.
findPipelineEntrypoint(String projectPath) → Future<String?>
Resolves the project's Dart pipeline entrypoint (ADR-0006/0010):
findR8Jar({String? explicitPath, Map<String, String>? environment, String? home}) → Future<String?>
Locate an R8 jar: explicit path → OKA_R8_JAR → the shared artifact store → the legacy ~/.oka/tools copies. Returns the path or null.
findTarget(Oka oka, String name) → Target
Resolves name against Oka.targets (ADR-0015).
fingerprintInputs(Iterable<String> paths, {Iterable<String> extras = const []}) → Future<String>
Stable hash over a list of input files (path + size + mtime) plus scalar extras (mode, defines, tool versions, …). Missing files hash as misses — never silently reuse.
fingerprintInputsDetailed(Iterable<String> paths, {Iterable<String> extras = const []}) → Future<({String digest, Map<String, String> fileDigests})>
fingerprintInputs plus the per-file digest map, for oka why (D4).
flutterAttachMachineArgs({required String deviceId}) → List<String>
Pure argv builder for the attach spawn (unit-tested; the executor is spawnAttachDaemon).
flutterBinaryForSdk(String flutterSdkPath) → ({bool exists, String path})
The flutter binary of the SDK recorded in the manifest — the session must use the SDK that produced the APK's flutter_assets, never ambient PATH. Returns the platform-appropriate binary path; exists reports whether it is actually present.
flutterEmbeddingAndroidXDeps() → List<MavenCoordinate>
A Maven coordinate for Android dependencies. Minimal fixed set required for Flutter embedding hosts (no plugins).
formatSessionMismatches(List<SessionFieldMismatch> mismatches) → String
Oka-branded mismatch error: names every differing field + the fix.
formatSuggestions(String missingClass, List<DependencySuggestion> suggestions) → String
Formats suggestions into user-facing guidance with copy-pasteable fixes.
forwardedVmServiceUri(VmServiceInfo info, int localPort) → String
Rebuilds the host-reachable VM service endpoint after ForwardVmServiceStep: same scheme/auth path, host loopback, forwarded local port. Pure, exported for tests.
fullRebuildMessage() → String
The honest full-rebuild message (ADR-0011 §5: hot reload is Dart-only; never suggest reload for native/res/manifest changes).
generateAndroidManifestFromSpec({required String packageName, required String label, required String minSdk, required String targetSdk, String activityName = '.MainActivity', ManifestSpec spec = const ManifestSpec(), String extraIntentFilters = '', String iconRef = ''}) → String
Renders the host AndroidManifest from a typed ManifestSpec (ADR-0006).
generateAndroidManifestXml({required String packageName, required String label, required String minSdk, required String targetSdk, String activityName = '.MainActivity', List<String> permissions = const ['android.permission.INTERNET'], bool debuggable = true, String extraIntentFilters = '', String iconRef = ''}) → String
Generates a minimal AndroidManifest for Flutter embedding v2.
generateLauncherIconXml() → String
Minimal values/strings and adaptive-friendly placeholder: we rely on @android:style and a generated solid-color mipmap via aapt is complex; generate a tiny res tree description for callers.
generateMainActivityJava(String packageName) → String
Generates a minimal FlutterActivity host.
generatePluginRegistrantJava(List<PluginRegistration> plugins) → String
Generates io.flutter.plugins.GeneratedPluginRegistrant.
generateStartupBeaconEntrypoint({required String projectPath, required String entrypoint, required String buildDir}) → String
Generates the beacon wrapper entrypoint and returns its path.
getOkaVersion() → String
Gets the Oka version
gmsDependencyArtifact(String coordinate) → Artifact<String>
A typed artifact handle on a resolved GMS-provided dependency.
gmsDependencyArtifactId(String coordinate) → String
The artifact id for a GMS-provided coordinate (no version).
googleMavenUrl(MavenCoordinate coord) → String
Builds a Maven URL for coord via the default MavenRepoRegistry.
installKotlinCompiler({bool verbose = false}) → Future<void>
Installs the Kotlin compiler under ~/.oka/tools (ADR-0007 shared installer used by both the build self-heal and oka get kotlin).
installR8({String version = kR8Version, bool verbose = false}) → Future<String>
Download R8 version into the shared artifact store (ADR-0013: oka cache list/gc sees it; OKA_CACHE shares it). Returns the stored jar path — no tools-dir copy is made (ADR-0028 §1).
inventoryLeases(String projectPath, {ProcessLiveness? liveness}) → Future<List<LeaseInventoryEntry>>
The reconcile + listing of every lease in projectPath's registry. Corrupt records are skipped by the registry; dead/recycled ones stay listed (marked stale) — deletion is stopLease's or the L2 sweep's decision, never a surprise during inspection.
isCompiledResourcesZipPath(String path) → bool
Returns true if path looks like a compiled-resources archive file path (not a directory intended to hold loose .flat files).
isGmsCoordinate(String coordinate) → bool
Whether a Maven coordinate (group:artifact:version) is provided by GMS — i.e. must be excluded from a GMS-free variant.
isGmsDependencyArtifactId(String id) → bool
Whether id is a GMS-dependency artifact id.
isIgnoredByGitignore(String absolutePath, {required String projectPath}) → bool
Default GitignoreChecker: parses <projectPath>/.gitignore (plus .git/info/exclude when present) and matches absolutePath.
isKnownUnsupportedPluginName(String name, {Set<String> softSkipNames = const {}}) → bool
True when a plugin should be treated as unsupported native for oka.
isSecretishKey(String key) → bool
Whether a dart-define key is secret-ish (case-insensitive match against secretishKeyPatterns).
isValidAndroidPackageName(String packageName) → bool
Android package name validation (simple).
javaClassToDexDescriptor(String fullyQualifiedClass) → String
Convert Java FQCN to a DEX type descriptor used in string tables.
kotlinJavaEnvironment({bool verbose = false}) → Future<Map<String, String>>
linuxProcessIdentityToken({required String bootId, required String stat}) → String?
Combines Linux PID start ticks with the kernel boot UUID.
listAabEntries(String aabPath) → Future<List<String>>
Read entry names from an .aab zip.
listApkEntries(String apkPath) → Future<List<String>>
Read entry names from an APK/zip file.
listDexOutputs(String dexDir) → Future<List<String>>
Collect all multi-dex outputs from a d8 directory (classes.dex, classes2.dex, …). Sorted so classes.dex comes first.
listRelativePaths(Directory root) → Future<Set<String>>
Collect relative paths under root (posix-style).
loadCacheWorkspace({String? projectPath, List<String> scanRoots = const [], List<String>? savedProjects, Map<String, String>? environment, String? currentDirectory, bool inspection = false, List<({String guidance, String match})> toolGuidance = const [], CacheSessionStateReader? sessionStates}) → Future<CacheWorkspace>
loadOkaYaml(String projectPath) → Future<OkaConfig>
Loads and parses oka.yaml from projectPath. Missing file → OkaConfig.empty.
locateAapt2ForCompare() → Future<String?>
Convenience: locate aapt2 for compareArtifacts (null when unavailable).
mainActivityRelativePath(String packageName) → String
Path for MainActivity relative to a java source root.
mapEqualsStr(Map<String, String> a, Map<String, String> b) → bool
matchesGitignorePattern(String pattern, String rel) → bool
Matches one gitignore pattern against a project-relative path rel.
materializeFile({required String source, required String destination, bool keepSourcePermissions = false, List<_LinkAttempt>? linkAttempts}) → Future<FileMaterialization>
Materializes source at destination, replacing any existing file.
mergeConfigMaps(Map<String, dynamic> base, Map<String, dynamic> override) → Map<String, dynamic>
Deep-merges override over base (one nested level for the android:/flutter:/pipeline: sections). Keys present only in base are preserved; keys in override win. Pure — used for the ADR-0010 typed-Dart-config-over-yaml precedence.
mergeDartDefines({List<String> pairs = const [], Map<String, String> fileEntries = const {}}) → Map<String, String>
Merges --dart-define pairs with --dart-define-from-file contents and normalizes the result. Pure (file contents are passed in by the caller).
mergeStreams<T>(Iterable<Stream<T>> streams) → Stream<T>
Merges many single-value streams into one (tiny StreamGroup — no extra dependency).
minimalAarBytes() → List<int>
Builds a minimal AAR containing classes.jar for tests.
minimalBundleConfigPb() → List<int>
App Bundle layout helpers (ADR-0004).
minimalJarBytes({String entryName = 'META-INF/MANIFEST.MF'}) → List<int>
Builds a minimal valid JAR (zip with empty META-INF) for tests.
multiDexEntries(Iterable<String> apkPaths) → List<String>
Extract multi-dex entry names from an APK listing (classes.dex, classes2.dex, …).
ndkAbiTriple(String abi) → String
normalizeAbi(String abi) → String
Maps oka / Flutter ABI names to APK lib/<abi>/ directory names.
normalizeBundleAbi(String abi) → String
ABI normalization shared with the APK path (delegates to the same rules).
normalizeDartDefines(Map<String, String> defines) → Map<String, String>
Normalizes dart-defines for recording/comparison: stringified values, whitespace-trimmed keys/values, sorted by key. --dart-define=STORE= googlePlay and --dart-define-from-file contents must normalize to the same map for flag parity.
okaR8ToolsDir() → String
oka-managed R8 install directory: ~/.oka/tools/r8.
okaRun(List<String> args, {required Oka oka, String? projectPath, ArgParser? extraArgs, Future<void> registerCacheProject(String projectPath)?}) → Future<void>
Runs a declarative Oka composition from a project hook entrypoint (ADR-0006: oka build delegates to dart run <entrypoint> which calls this).
packageAndSign({required BuildContext ctx, required ResolvedToolchain toolchain, required List<String> dexFiles, required String flutterAssetsDir, required Map<String, String> libflutterByAbi, required Map<String, String> libappByAbi, Map<String, List<String>> extraNativeByAbi = const {}, SigningConfig? signing, AndroidProcessRunner processRunner = runAndroidProcess}) → Future<String>
packageAndSignAab({required BuildContext ctx, required ResolvedToolchain toolchain, required List<String> dexFiles, required String flutterAssetsDir, required Map<String, String> libflutterByAbi, required Map<String, String> libappByAbi, Map<String, List<String>> extraNativeByAbi = const {}, SigningConfig? signing, AndroidProcessRunner processRunner = runAndroidProcess}) → Future<String>
packageConfigFor(String projectPath) → File?
Locates the active package_config.json for projectPath.
packagingSdkPackages({String buildTools = '35.0.0', String platformApi = '34', List<String> extraPlatformApis = const ['35', '36']}) → List<String>
Packages required for no-Gradle APK packaging (adb optional).
packagingToolsPresent(String sdkRoot) → Future<bool>
True when aapt2, d8, zipalign, apksigner exist under sdkRoot.
parseAapt2Badging(String output) → Map<String, String>
Parses aapt2 dump badging output into {package, launchable-activity}.
parseAdbDevices(String output) → List<AdbDevice>
Parses adb devices -l output into AdbDevices. Tolerates the header line, daemon-startup noise (* daemon started successfully), and empty lines; returns an empty list when nothing is attached.
parseAvdManagerNames(String output) → List<String>
Parses avdmanager list avd output for the AVD names (Name: <x> blocks, ignoring blanks and INFO noise).
parseBadging(String output) → BadgingInfo
Parse aapt2 dump badging output into a BadgingInfo.
parseBootCompleted(String output) → bool
True when output (from adb shell getprop sys.boot_completed) means "booted".
parseDartDefineFile(String? path) → Map<String, String>
Expands --dart-define-from-file (JSON object of string values).
parseEmuAvdName(String output) → String?
Extracts an AVD name from adb -s <serial> emu avd name output (<name>\nOK).
parseFlutterPluginsDependenciesJson(String jsonContent, {String projectRoot = ''}) → PluginDiscoveryResult
Parses Flutter's .flutter-plugins-dependencies JSON (Flutter 2+).
parseFlutterPluginsFile(String content) → List<DiscoveredPlugin>
Parses legacy .flutter-plugins (name=path per line).
parseForwardPort(String output) → int?
Parses the local port chosen by adb forward tcp:0 tcp:<port> (adb prints the picked host port on stdout).
parseGradleDependencies(String gradleSource) → List<ParsedGradleDep>
Parse Maven coordinates from a Gradle or Gradle.kts file body.
parseLinuxProcStatStarttime(String stat) → String?
Extracts the process start time (field 22, starttime in clock ticks since boot) from a Linux /proc/<pid>/stat record.
parseMavenRepositoryUrls(String gradleSource) → List<String>
Extract custom maven repository URLs from gradle text.
parseModuleRuntimeDependencies(String jsonText) → List<MavenCoordinate>
Parses runtime dependencies from Gradle module metadata JSON (<artifact>-<version>.module).
parsePomDependencies(String pomXml) → List<MavenCoordinate>
Extract compile/runtime dependencies from a Maven POM (minimal).
parsePomImports(String pomXml) → List<MavenCoordinate>
Extracts BOM imports (<type>pom</type><scope>import</scope>) from a POM's dependencyManagement — their managed versions merge transitively.
parsePomManagedVersions(String pomXml) → Map<String, String>
Extracts <dependencyManagement><dependencies> versions from a POM: map of groupId:artifactId → version.
parsePomParent(String pomXml) → MavenCoordinate?
Extracts <parent> coordinates from a POM, when present.
parsePomProperties(String pomXml) → Map<String, String>
Extracts <properties> from a POM: map of property name → value.
parsePosixProcessParentMap(String output) → Map<int, int>
Parses ps -eo pid=,ppid= output into a pid → parent-pid map.
parseRenderedFrames(String gfxinfoOutput) → int
Parses Total frames rendered: N out of dumpsys gfxinfo output.
parseVmServiceUri(String log) → VmServiceInfo?
Scrapes the newest Dart VM Service listening on <uri> announcement from a logcat dump. The last match wins (older runs may still be in the buffer; logcat -c before launch is the primary guard).
parseWindowsProcessParentMap(String output) → Map<int, int>
Parses the pid|ppid rows emitted by windowsProcessTableScript.
parseWindowsProcessProbeOutput(String output) → WindowsProcessSnapshot?
Parses the one-line output from windowsProcessProbeScript.
pathDependencyInputs(String projectPath) → List<String>
Input files a kernel/AOT fingerprint must cover beyond the project's own sources: every path dependency's pubspec.yaml + lib/**.dart.
pathDependencyRoots(String packageConfigJson, {String? configDir}) → List<String>
Root directories of path (sibling-checkout / workspace) dependencies from a package_config.json. Hosted (.pub-cache) and SDK-bundled (bin/cache/pkg) packages are excluded — their contents are pinned by the config itself.
pidOf() → int
This process's pid (dart:io ), behind a function so tests can stub the identity when simulating live/stale holders.
prepareDevLaunch({required String projectPath, ResolvedToolchain? toolchain, String? deviceId, String? adbPath, int waitSeconds = 3, bool verbose = false, DevDiscoveryStore discoveryStore = const FileDevDiscoveryStore()}) → Future<DevLaunchPrepared>
Runs the device half of oka dev through the same validated Pipeline as every other flow (ADR-0002): the DeviceTarget steps (resolve newest APK → install → launch → logcat failure scan) followed by the H2 session steps (await VM service announcement → adb forward), consuming the vm_service_uri / vm_service_local_port artifacts as-is.
provenanceAbi(String abi) → String
Normalizes an ABI for provenance storage.
provisionAllMissingTools() → Future<void>
Install all missing build tools (build-tools, Kotlin, R8 as needed).
provisionBuildTools() → Future<void>
Install build-tools via the Android SDK Manager.
provisionBundletool() → Future<void>
Install bundletool.jar for AAB verification (ADR-0004).
provisionKotlinCompiler() → Future<void>
Install the Kotlin compiler into the oka tools dir (via the shared artifact store, ADR-0013).
provisionR8() → Future<void>
Install the R8 optimizer (Google Maven jar via the artifact store).
r8Command(String r8Path, List<String> args) → List<String>
Java command launching the R8 CLI from r8Path.
r8MavenDownloadUrl({String version = kR8Version}) → String
Google Maven download URL for the standalone R8 jar.
r8StoreKey({String version = kR8Version}) → ContentKey
Store key for the standalone R8 jar (ADR-0013/0028): identity is the download URL, so re-published artifacts change keys. The jar lives only in the store — no second copy under ~/.oka/tools (ADR-0028 §1).
readApkDexBlobs(String apkPath) → Future<Map<String, List<int>>>
Read all multi-dex blobs from an APK zip.
readAppleDiagnosticPlist(String path) → Future<Map<String, Object?>>
Apple's parser supports both binary and XML plists. Bounded, read-only file conversion; this is not a simulator runtime probe.
readEngineRevisionFromSdk(String flutterSdkPath) → Future<String>
Reads the engine revision for a Flutter SDK without running flutter: <sdk>/bin/internal/engine.version is authoritative and stable. Falls back to flutter --version --machine via the SDK's own binary (never PATH) when the file is absent (older SDK layouts).
readFlutterEngineRevision({Future<ProcessResult> runProcess(String, List<String>)?}) → Future<String?>
Reads Flutter engine revision from flutter --version --machine.
readProvenanceFromArtifact(String artifactPath) → Future<ProvenanceRecord?>
Reads the provenance record out of a built APK/AAB without unzipping to disk: unzip -p <artifact> assets/flutter_assets/oka-provenance.json. Null when the artifact predates ADR-0029 (no record inside).
readRunnerSessionFile(String projectPath, {DevDiscoveryStore store = const FileDevDiscoveryStore()}) → DevSessionDiscovery?
Reads the session discovery file: null when absent (no live session); FormatException when the file exists but is unreadable or carries an unknown schema (readers reject unknown schema values).
reconcileLeases(String projectPath, {ProcessLiveness? liveness, bool stopOrphans = false, Duration stopVerifyGrace = const Duration(seconds: 5), Future<ProcessResult> runProcess(String, List<String>)?}) → Future<LeaseReconcileSummary>
The L2 reconcile sweep (ADR-0018 §5): reconcile every lease in projectPath against the live host.
registerCacheProjectBestEffort(String projectPath, {Future<void> register(String projectPath)?, void warning(String message)?}) → Future<void>
Remembers executed projects for global cache management (ADR-0020). Registration is advisory: failures never prevent a build and diagnostics go to stderr so machine-readable stdout stays intact. The callback permits embedders to use their own registry without changing the build contract.
renderDeeplinkIntentFilters(List<DeeplinkConfig> deeplinks) → String
Renders deeplink intent-filters for a typed ManifestSpec.
resolveAbis({required List<String> configAbis, String targetAbi = ''}) → List<String>
Resolves the list of ABIs to package from config lists + optional target.
resolveAdbForSteps(PipelineState state, {String? adbPath, ResolvedToolchain? toolchain}) → Future<String>
Resolves adb (injectable path → toolchain policy) for the VM-service steps. Shared failure shape: missing adb is a failure naming the fix.
resolveAndroidAvdHome({required String avdName, String? explicit, Map<String, String>? environment}) → Future<AndroidAvdHomeResolution>
Resolves the AVD inventory directory using Android's documented search locations. An explicit path is authoritative; it is never replaced by a guessed fallback. A directory is accepted only when it contains the selected AVD's .ini inventory entry.
resolveAndroidJar(String androidSdk, String compileSdk) → Future<String>
resolveAndroidVersion(String projectPath, {required int configVersionCode, required String configVersionName}) → ({int versionCode, String versionName})
Resolves Android (versionCode, versionName): explicit oka.yaml version_code/version_name wins, otherwise the app pubspec.yaml version: x.y.z+nn.
resolveBytecodeTools(ResolvedToolchain toolchain, {required bool needsKotlin, bool needsR8 = false}) → Future<BytecodeTools>
resolveClassConflicts({required List<String> jars, required String buildDir}) → Future<List<String>>
Resolves cross-artifact duplicate classes before dexing.
resolveDelegationDart() → Future<String>
The Dart executable the delegated pipeline (dart run tool/oka_pipeline.dart) runs under.
resolveDevToolPath(ResolvedToolchain? toolchain) → Future<({String? path, String? refusal})>
Resolves the session tool path via the toolchain policy; returns a typed refusal (oka-branded fix) instead of throwing — the CLI prints it verbatim (parse-and-delegate, ADR-0015).
resolvedSigning(BuildContext ctx) → Future<SigningConfig?>
Resolved signing info for lint rules: whether a real keystore backs the build and the keystore path when known.
runAndroidProcess(String executable, List<String> arguments, {Map<String, String>? environment}) → Future<ProcessResult>
runBoundedProcess(String executable, List<String> arguments, {required Duration timeout, String? workingDirectory, Map<String, String>? environment, bool runInShell = false, Duration grace = const Duration(seconds: 3), Duration settle = const Duration(milliseconds: 250), int maxCapturedBytes = 256 * 1024, ProcessTreeProbe processTreeProbe = const HostProcessTreeProbe(), ProcessLiveness liveness = const HostProcessLiveness(), Duration observationBudget = const Duration(seconds: 2)}) → Future<BoundedRunResult>
Runs executable with arguments and a timeout stop-request deadline.
runnerSessionFilePath(String projectPath) → String
Path of the live dev-session discovery file (spec v2 — the toolkit-neutral Dart dev session contract): <project>/.flutter_mcp/runner-session.json — the sibling of the toolkit's own .flutter_mcp/state.json (overridable on the toolkit side via its --runner-session-file flag). Written by the RUNNER (oka is the first conforming runner) at each session.ready and deleted on session exit. Readers reject unknown schema values; absent file = no live delegable session. The runner field is display metadata only.
runTeardownSteps(List<BuildStep> steps, {required BuildContext ctx, PipelineState? state, Duration perStepTimeout = const Duration(seconds: 30), void write(String line)?}) → Future<TeardownOutcome>
Runs steps best-effort in order, each under perStepTimeout.
runToolProcess(String executable, List<String> arguments, {Map<String, String>? environment, Encoding? stdoutEncoding = systemEncoding, Encoding? stderrEncoding = systemEncoding}) → Future<ProcessResult>
scanFailureSignatures(String log, {List<FailureSignature> signatures = builtinFailureSignatures}) → List<SignatureMatch>
Scans log (case-insensitive) for signatures. Pure — unit-tested without a device.
scanLogForFailureSignatures(String log) → Map<String, String>
Scans a device log dump for deviceFailureSignatures (case-insensitive). Returns the subset of signatures found.
selectDevDevice({String? deviceId, String? adbPath, ResolvedToolchain? toolchain, AdbTool? tool}) → Future<DevDeviceSelection>
Selects the device for the session (ADR-0011 H3):
selectStorageCleanup({required Iterable<StorageMeasurement> measurements, required StorageSelectionCriteria criteria, required DateTime measuredAt}) → List<StorageMeasurement>
Selects cleanup entries without filesystem or clock access.
sessionStateOwnershipMarkerPath(String resourcePath) → String
Marker stored inside an Oka-created directory resource.
shellQuote(String s) → String
signAab({required String unsignedAabPath, required String keystorePath, required String keyAlias, required String storePass, required String signedAabPath, String? jarsignerPath}) → Future<String>
Sign an .aab with v1 JAR signing via jarsigner.
signApk({required BuildContext ctx, required String apksigner, required String alignedApk, required String signedApk, SigningConfig? signing, AndroidProcessRunner processRunner = runAndroidProcess}) → Future<void>
signBundle({required BuildContext ctx, required ResolvedToolchain toolchain, required String unsignedBundle, required String signedBundle, SigningConfig? signing, AndroidProcessRunner processRunner = runAndroidProcess}) → Future<void>
spawnAttachDaemon({required String flutterBinary, required String deviceId, String? adbPath}) → Future<DaemonTransport>
Spawns <flutterBinary> attach --machine -d <deviceId> and returns the transport. flutterBinary must be the session manifest's recorded-SDK binary (never PATH) — the caller enforces that via checkDevSession.
splitGmsDependencies(Iterable<String> coordinates) → ({List<String> gms, List<String> other})
Splits coordinates into the GMS-provided ones and the rest — the classification a GMS-exclusion variant applies to extraDeps.
stageAabBaseModule({required String baseDir, required String protoResourcesAp, List<String> dexFiles = const [], String? flutterAssetsDir, Map<String, String> libflutterByAbi = const {}, Map<String, String> libappByAbi = const {}, Map<String, List<String>> extraNativeByAbi = const {}}) → Future<void>
Stage an AAB base/ module directory.
stageApkLayout({required String stagingDir, String? dexFile, List<String> dexFiles = const [], String? flutterAssetsDir, Map<String, String> libflutterByAbi = const {}, Map<String, String> libappByAbi = const {}, String? resourcesApk}) → Future<void>
Stage files into an APK-shaped directory tree (before zip/aapt packaging).
stagedAotBuildId(PipelineState state) → Future<String?>
Extracts the Dart snapshot build id recorded by the AOT step (a thin helper so verify rungs and checks agree on extraction).
stageLauncherIcons(String resDir, IconConfig config, {required String projectPath}) → Future<IconResources>
Generates adaptive launcher icon resources (vector-first, no binary deps).
stopLease(String projectPath, String id, {ProcessLiveness? liveness, bool force = false, Duration stopVerifyGrace = const Duration(seconds: 5), Duration pollInterval = const Duration(milliseconds: 200), Future<ProcessResult> runProcess(String, List<String>)?, VerifySemanticStop? verifySemanticStop}) → Future<LeaseStopOutcome>
Stops the lease id in projectPath's registry, identity-verified and graceful-first (ADR-0018 §1):
stopProcessTree({required ProcessTreeProbe probe, required ProcessLiveness liveness, required int rootPid, String? rootIdentityToken, Duration grace = const Duration(seconds: 3), Duration settle = const Duration(milliseconds: 250), int forceRounds = 2, Duration observationBudget = const Duration(seconds: 2)}) → Future<TreeStopResult>
Stops rootPid and its live descendants with the graceful→force ladder.
storeBundletoolJarPath({Map<String, String>? environment}) → String
Absolute path of the bundletool jar inside the shared artifact store.
storeR8JarPath({String version = kR8Version, Map<String, String>? environment}) → String
Absolute path of version's R8 jar inside the shared artifact store.
targetPlatformForAbi(String abi) → String
Target platform define value for Flutter tools.
tryExtractClassesJarFromAar(List<int> aarBytes) → Uint8List?
Extracts classes.jar bytes from an AAR (zip) archive.
validateAabFile(String aabPath, {AabLayoutSpec spec = const AabLayoutSpec()}) → Future<AabContentValidation>
Validate an AAB archive, including manifest, DEX, native ABI, resource, duplicate-entry, and (optionally) v1 signature invariants.
validateAabPathSet(Iterable<String> paths, {AabLayoutSpec spec = const AabLayoutSpec()}) → AabLayoutValidation
Validate paths already listed from an .aab zip (module-relative).
validateAabWithBundletool({required String aabPath, String? bundletoolPath, bool verbose = false}) → Future<BundletoolValidationResult>
Run bundletool's inexpensive structural validator when available.
validatePathSet(Iterable<String> paths, {ApkLayoutSpec spec = const ApkLayoutSpec()}) → ApkLayoutValidation
Validates paths already listed (e.g. from unzip -l).
validateRunSession(RunSession session, RunSessionRequest request) → SessionValidation
Validates a request against a recorded session. Never warn-and-continue: mismatches come back typed so the caller can refuse loudly.
validateStagingLayout(String stagingDir, {ApkLayoutSpec spec = const ApkLayoutSpec()}) → Future<ApkLayoutValidation>
Validates a staging directory that mirrors APK internal paths.
validateTargetName(String name, {Set<String> reserved = reservedCliVerbs}) → String?
Validates a target name (ADR-0015).
validateTargets(Oka oka) → void
Validates every declared target name: lowercase identifier, unique, and never shadowing a reserved core verb (ADR-0015). Throws TargetResolutionException naming the first violation.
verifyAabPostBuild(String aabPath, {required bool verbose, BundletoolVerifier? verify, Future<String> keystore()?}) → Future<bool>
Post-build AAB verification loop (ADR-0004): run build-apks in universal mode against the debug keystore, then extract the universal APK. Prints progress; returns true when the bundle verifies.
verifyAabWithBundletool({required String aabPath, required String outputApksPath, required String keystorePath, required String keyAlias, required String keyPass, String? bundletoolPath, bool verbose = false}) → Future<BundletoolVerifyResult>
Verify an .aab by building universal APKs with bundletool.
verifyAndroidDelivery({required String aabPath, required String outputDirectory, String? deviceSpecPath, String? bundletoolPath, String? serial, bool install = false, bool launch = false, String? packageName, String? activity, String? adbPath, String? keystorePath, bool verbose = false, String? reportPath, Future<String> keystore()?, Future<BundletoolCommandResult> runBundletool(List<String> args)?, Future<void> installApks(List<String> apks)?, Future<void> launchApp()?}) → Future<DeliveryVerificationReport>
Runs the offline/online portions of release verification. The callback seams make the report testable without Java, bundletool, adb, or a device.
verifyAndroidDeliveryFromCli({required String aabPath, required String outputDirectory, required DeliveryVerificationOptions options, bool verbose = false}) → Future<DeliveryVerificationReport>
CLI-facing adapter owned by the Android delivery implementation.
verifyKillIdentity(ProcessLiveness liveness, int pid, String? recordedToken) → Future<KillIdentity>
Identity-over-pid gate (ADR-0018 §1): decides whether it is safe to signal pid given the start-time token recordedToken captured when the process was spawned (stored in the lease under processLeasePidTokenKey).
vmUriFilePath(String projectPath) → String
Path of the live dev-session discovery file: <project>/.oka_cache/dev/vm.uri — one line, the forwarded ws://127.0.0.1:<port>/<auth>/ws endpoint. Verification/inspection tools (e.g. flutter_mcp_cli --vm-service-uri) read this instead of scraping the oka dev --json stream. Absent = no live session.
watchCommandStream({required Stream<List<String>> changes, void onEvent(ChangeClassification)?}) → Stream<DevControlCommand>
Classification → session commands: Dart-only batches dispatch one reload; rebuild-class batches dispatch DevControlCommand .rebuildRouting (the session prints the exact command, or — with --rebuild-on-native — ends the session so the flow can rebuild). Ignore-class batches emit nothing. onEvent observes every batch (--json visibility and tests).
watchDevPaths({required String projectPath, String? targetFile, Duration debounce = const Duration(milliseconds: 300)}) → Stream<List<String>>
Watches the dev surface and yields debounced batches of changed paths, relative to projectPath when inside it.
windowsProcessProbeScript(int pid) → String
PowerShell probe invoked with a validated numeric PID.
withBuildLease<T>(String command, Future<T> body(), {String? projectDir, bool wait = true}) → Future<T>
Runs body under the build lease — the one-call guard for build entry points.
writeRunnerSessionFile(String projectPath, {required String vmServiceUri, required int controlPort, required String deviceId, int? processPid, DateTime? startedAt, DevDiscoveryStore store = const FileDevDiscoveryStore()}) → Future<void>
Writes the runner-session discovery file per spec v2 (best-effort, same law as the vm.uri file: a failed write must never break the dev session). vmServiceUri is the FORWARDED host-reachable endpoint (same value the vm.uri file carries); controlPort is the loopback delegation server's chosen port (ephemeral by default — only discoverable here). Creating .flutter_mcp/ never touches an existing sibling state.json.
writeVmUriFile(String projectPath, String vmServiceUri, {DevDiscoveryStore store = const FileDevDiscoveryStore()}) → Future<void>
Writes the discovery file (best-effort: a failed write must never break the dev session).
zipBundle(String bundleRoot, String aabPath) → Future<void>
Zip a bundle root (bundleRoot containing base/) into aabPath.
zipStagingToApk(String stagingDir, String apkPath) → Future<void>
Build an unsigned APK zip from a staging directory (no aapt2 required).

Typedefs

AdbInvoker = Future<ProcessResult> Function(String adb, List<String> args)
Signature of the adb invocation a rung makes — injectable so ladder rungs are unit-testable without a device.
AndroidAvdDeviceLister = Future<List<AdbDevice>> Function()
AndroidAvdNameReader = Future<String?> Function(String serial)
AndroidManifest = ManifestSpec
Convenience: typed manifest spec override for Dart composition.
AndroidProcessRunner = Future<ProcessResult> Function(String executable, List<String> arguments, {Map<String, String>? environment})
BundletoolVerifier = Future<BundletoolVerifyResult> Function({required String aabPath, String? bundletoolPath, required String keyAlias, required String keyPass, required String keystorePath, required String outputApksPath, bool verbose})
Signature of verifyAabWithBundletool, injectable for tests.
CacheClock = DateTime Function()
CacheLocationSource = Future<List<StorageLocation>> Function({required Map<String, String> environment, required bool includeProject, required bool includeShared, required ProcessLiveness liveness, required String projectPath, List<({String guidance, String match})> toolGuidance})
CacheSessionStateReader = Future<SessionStateRegistrySnapshot> Function()
DeviceToolRunner = Future<ProcessResult> Function(String executable, List<String> arguments, {Map<String, String>? environment, String? workingDirectory})
Injectable process runner signature (tests fake curl, sdkmanager, chmod — no network, no real SDK). Named distinctly from oka_core's ProcessRunner interface (same idea, raw ProcessResult for zip producing commands).
GitignoreChecker = bool Function(String absolutePath)
Injectable gitignore-checker seam (ADR-0014 repo hygiene).
GracefulLeaseStop = Future<bool> Function(ProcessLease lease)
JavaEnvironmentResolver = Future<Map<String, String>?> Function(String? requiredVersion)
LintRule = Future<List<LintFinding>> Function(PostBuildLintStep step, BuildContext ctx, PipelineState state)
Individual lint rules — composable, each a pure function over the packaged artifact. Add rules by appending to defaultRules or by supplying a custom list.
ProcessCommandRunner = Future<ProcessResult> Function(String executable, List<String> arguments)
Injectable command seam used by WindowsProcessLiveness and its tests.
ProcessExit = void Function(int code)
ProvisionedToolGuidance = ({String guidance, String match})
Cache-discovery guidance for one oka-provisioned tool under ~/.oka/tools (ADR-0019/0022). A structural record so the CLI's storage discovery stays platform-agnostic: it splits the tools directory per child and applies whatever guidance the composition root supplies — the knowledge of which tools oka provisions stays here, in oka_android (ADR-0022 capability boundaries).
ReleaseVerificationOptions = DeliveryVerificationOptions
Backwards-compatible name for clients which used the pre-delivery terminology. New APIs should use DeliveryVerificationOptions.
ResolvedJar = ResolvedJar
Result of resolving one coordinate to a local JAR path.
SignalStream = Stream<ProcessSignal> Function(ProcessSignal signal)
TempDirectoryFactory = Future<Directory> Function(String prefix)
ToolProcessRunner = Future<ProcessResult> Function(String executable, List<String> arguments, {Map<String, String>? environment, Encoding? stderrEncoding, Encoding? stdoutEncoding})
VerifySemanticStop = Future<bool?> Function(ProcessLease lease)

Exceptions / Errors

AdbToolException
Thrown by AdbTool on any classified failure.
AndroidSdkMissingException
Error thrown when required Android SDK build-tools are missing.
BuildLeaseHeldException
acquire(wait: false) refused — a live holder owns the lease.
CredentialResolutionException
Thrown when a required credential path fails to resolve. Names every candidate tried and the fix — same remediation law as ToolchainException.
DaemonException
Thrown on protocol-level failures (timeout, dead daemon, error response when the caller asked FlutterDaemonAdapter.send to enforce ok).
DevLaunchException
Thrown when the device half of oka dev fails; the message is oka-branded and actionable (step failures already are).
PublishConformanceException
Thrown by expectPublishConformance when a publish target violates an ADR-0014 conformance law. Escaping a test, this fails it with the full violation list — no test-framework dependency needed in oka_core.
RunSessionException
Thrown for missing/corrupt/unknown-schema manifests (fail closed).
SessionStateProvisionException
A provisioning failure that leaves its durable lease available for repair.
SessionStateRegistryException
Error from a state registry operation. Messages are safe to show in CLI.
TargetResolutionException
Thrown when target resolution fails (unknown name, name shadowing a reserved verb, invalid or duplicate name). Carries an actionable, user-facing message — catch it to print the message without a trace.
ToolchainException
Thrown when a required tool cannot be resolved: names every candidate tried, in order, plus the remediation (ADR-0007: errors name the fix).