AppPlayerCoreService class

Top-level entrypoint assembling Connection / Runtime / Session / Dashboard / Tenant layers (MOD-CORE-001, FR-CORE-001~008).

Hosts receive AppSession / DashboardSession from the open* methods and never touch MCPUIRuntime directly.

Available extensions

Constructors

AppPlayerCoreService()
AppPlayerCoreService.forTesting({required ClientConnector connector})
Test-only constructor that injects a mock ClientConnector. Kept out of the public initialize signature to prevent leaking a transport seam into production APIs (NFR-API-005).

Properties

bundleInstallRoot → String
Absolute path where installed bundles are stored.
no setter
connectionManagerForInternals → ConnectionManager
no setter
connections → Map<String, ConnectionInfo>
no setter
Per-app capability consent (FR-CAP). Null unless the shell injected a ConsentPrompt in initialize — pure-Dart hosts without a consent UI have no enforcement point.
no setter
credentialVault → CredentialVault
Exposed for transport configs that need to read secrets when building connection options. Callers must not cache returned values.
no setter
currentTenant → TenantContext?
no setter
debugCaptureKey → GlobalKey<State<StatefulWidget>>?
Global key of the debug capture RepaintBoundary, or null when the Debug MCP host is not active. Hosts wrap their root with debugCaptureWrap; the key is exposed for advanced integrations.
no setter
debugOpenBundle ↔ Future<bool> Function(String bundleId)?
How this tier puts an installed bundle on screen, for the debug host's app.open. Left null by a tier that has no shell — the tool then reports that it cannot open rather than pretending it did. Answers whether it actually put the bundle on screen. A door that reports success without opening is worse than no door: the harness that calls it then measures the screen it was already on.
getter/setter pair
definitionResolver → Future<Map<String, dynamic>> Function(String ref, Map<String, dynamic> origin)?
The registered composition resolver, or null when this host does not claim the Composition Profile. Exposed so a host (or its tests) can verify its own claim and drive the exact production resolution path rather than a parallel one.
no setter
hashCode → int
The hash code for this object.
no setterinherited
healthMonitorForInternals → ConnectionHealthMonitor
Test-only — the health monitor, so the reconnect-pacing wiring (isEngaged) can be asserted against a really-open app rather than assumed. An unwired seam here is invisible: every reconnect still works, just slower and slower on the one screen the user is watching.
no setter
hostBrightness → ValueListenable<Brightness>?
no setter
inProcessToolNames → List<String>
Test-only — in-process tool names registered onto the dispatcher. bk.fact.write ... bk.knowledge.query should appear once KernelApp.boot + standardTools(app) register succeeds.
no setter
isBridgeBooted → bool
Test-only — whether the bundle session bridge is booted. Pairs with isKernelBooted for the wiring regression suite.
no setter
isKernelBooted → bool
Test-only — whether brain_kernel boot succeeded. Production code goes through the public surface (open* / setActiveSession / dispose); only regression suites inspect this directly.
no setter
kernelConnectionsForInternals → Iterable<KernelClientConnection>
The kernel's outbound connections — what is adopted or opened through it.
no setter
lifecycleListenable → Listenable
Notifier that fires whenever connection or runtime lifecycle state changes — launcher UI listens to this to refresh per-app badges ("connected" dot on the app icon) without polling.
no setter
notifications → AppNotificationPort
Notification port (FR-NOTIF) apps post through and the shell renders.
no setter
openSessionCount → int
Test-only — open session count (per-bundle map size). Increments on activate, decrements on close.
no setter
permissions → PlatformPermissionPort
OS permission port (FR-PERM) for shell-driven, lazy permission requests.
no setter
resourceSubscriberForInternals → ResourceSubscriber
no setter
runtimeManagerForInternals → RuntimeManager
no setter
runtimeType → Type
A representation of the runtime type of the object.
no setterinherited
scheduler → JobScheduler
Periodic / scheduled background jobs (FR-SCHED). Hosts register jobs (health sweeps, data pulls) that run on a foreground timer and delegate to the platform background task while suspended.
no setter
servedResources → List<String>
MCP Serving 1.0 — URIs currently served over the bridge, e.g. bundle://manifest.json for an open bundle. Host/test introspection.
no setter
serverReGrant ← ServerReGrant?
Wire the durable-reconnect token re-grant (see ServerReGrant). Call once after initialize, when the marketplace session exists (capabilities are built after composition). A stale marketplace connectionToken is then silently refreshed on connect / reconnect / health-monitor auto-reconnect instead of requiring a manual reinstall. Pass null to clear it. Hosts without a marketplace (Standard / hand-typed / discovered) never call this, so their connect behaviour is unchanged.
no getter
settings → SettingsStore
Persists user values declared by the bundle's settings.sections[].fields[] schema. Hosts inject their own implementation (SharedPreferences, SecureStorage, files, ...) via initialize(settingsStore: ...). When not provided the core falls back to the in-memory default, which clears on process restart.
no setter
stalledServers → Set<String>
Servers an open app is stalled on — the connection failed AND an app is open on it (FR-HEALTH-009). Changes are announced through lifecycleListenable, since both inputs live behind it.
no setter
toolDispatcherForInternals → ToolDispatcher
no setter

Methods

adoptConnectionAsOrigin({required String id, required Client client}) → Future<KernelClientConnection>
Make a connection this host ALREADY holds usable as a composition origin, under id — one device, one connection.
applyTenant(String appCode) → Future<TenantContext>
FR-CORE-005
bindOnlineChanges(Stream<bool> online) → void
Bind the host's "is there a network" stream so the core dials the moment one returns (FR-HEALTH-010).
clearTenant() → Future<void>
closeApp(AppHandle handle) → Future<void>
FR-CORE-008 — terminate a session by handle.
closeDashboard() → Future<void>
connectExtensionTransport({required String id, required ClientTransport transport}) → Future<KernelClientConnection>
Connect to an external MCP server (e.g. an embedded board) over a host-supplied extension transport (serial / usb / ble / tcp / ws), injected through the kernel seam (McpClientKernelHost.connectWith).
debugCaptureWrap(Widget child) → Widget
Wrap child in the debug capture RepaintBoundary when the Debug MCP host is active; otherwise return child unchanged. Hosts call this from their root MaterialApp builder so the capture / tap / tree primitives have a stable render boundary.
deleteServer(String id) → Future<void>
dispose() → Future<void>
fetchBundleMetadata(BundleRef bundleRef) → Future<AppMetadata>
FR-META-007 — load a bundle's manifest and publish its metadata (name / icon / publisher) WITHOUT adapting the definition or building a runtime. The bundle twin of fetchServerMetadata: "installing a bundle" only writes it to disk (installBundleFromFile), so call this right after to populate the launcher card — otherwise the tile shows the raw bundle id until the user first opens it. The UI is rendered later, on open (openAppFromBundle).
fetchServerMetadata(String serverId) → Future<AppMetadata?>
FR-META-006 — connect and read ui://app/info ONLY, without loading the UI or initialising a runtime. This is the "install / register a server" step: it populates the launcher tile (name / icon / publisher) so the user sees the app before ever opening it — the UI is rendered later, on tap, via openAppFromServer. Mirrors how a local server is added (metadata first, render on open), instead of rendering the app the moment it is installed.
getServer(String id) → Future<ServerConfig?>
Fetches a single ServerConfig by id (FR-STOR passthrough). Returns null when no entry matches.
handleFor(HasAppHandle app) → AppHandle

Available on AppPlayerCoreService, provided by the AppPlayerCoreServiceActivity extension

Returns the AppHandle used by core for the given launcher entry. Useful for closeApp(handle) calls from a context-menu close action.
hintReachable([String? serverId]) → void
Tell the core a server may be reachable again (FR-HEALTH-008): the network returned, the device was sighted on the discovery axis, the user pressed retry. A connection waiting out its retry interval dials immediately.
initialize({RuntimeLogHandler? onRuntimeLog, required ServerStorage storage, required String bundleInstallRoot, BundleInstallStore? bundleInstallStore, String workspaceId = 'appplayer', TenantSource? tenantSource, Logger? logger, MetricsPort? metrics, BundleFetcher? bundleFetcher, AppMetadataSink? appMetadataSink, CredentialVault? credentialVault, HealthMonitorConfig? healthConfig, ValueListenable<Brightness>? hostBrightness, ServingAuthorization? servingAuthorization, ServingHeaders? servingHeaders, String? requestLanguage()?, ServerClientLayer? serverClientLayer, RuntimeCapabilities runtimeCapabilities = RuntimeCapabilities.none, McpLogMessageHandler? onMcpLogMessage, SettingsStore? settingsStore, BackgroundPolicy backgroundPolicy = BackgroundPolicy.pauseResume, BackgroundExecutionPort? backgroundPort, PlatformPermissionPort? permissionPort, AppNotificationPort? notificationPort, ConsentPrompt? consentPrompt, ConsentStore? consentStore, MemoryReclaimer? memoryReclaimer, KvStoragePort? kvStorage, String? appIdOf(String bundleId)?, KbAccountRecords? kbAccountRecords()?, String? kbWriteUnit()?, WorkspaceMemberPort? memberPortOf(String appId)?, bool enableDebugMcp = false, int debugMcpPort = 7930}) → Future<void>
FR-CORE-001
installBundleFromBytes(Uint8List bytes) → Future<InstalledAppBundle>
Install a bundle from .mcpb bytes (FR-INSTALL-001).
installBundleFromDirectory(String mbdPath) → Future<InstalledAppBundle>
installBundleFromFile(String filePath) → Future<InstalledAppBundle>
installBundleFromUrl(Uri url) → Future<InstalledAppBundle>
isAppActive(HasAppHandle app) → bool

Available on AppPlayerCoreService, provided by the AppPlayerCoreServiceActivity extension

isBundleLoaded(String bundleId) → bool
True when a bundle's runtime is currently loaded in the runtime cache. Bundle apps don't maintain a network connection, so the cached runtime is the equivalent "is this app active?" signal.
isServerConnected(String serverId) → bool
True when a stdio / HTTP connection for serverId is live (ConnectionState.connected). Used by the launcher to paint the "connected" dot on server-type and dashboard-type tiles.
listInstalledBundles() → Future<List<InstalledAppBundle>>
listServers() → Future<List<ServerConfig>>
loadBundle(BundleRef ref) → Future<McpBundle>
noSuchMethod(Invocation invocation) → dynamic
Invoked when a nonexistent method or property is accessed.
inherited
onLifecyclePhase(AppLifecyclePhase phase) → Future<void>
Forward an OS lifecycle transition (FR-LIFE-001). The shell's WidgetsBindingObserver maps AppLifecycleState to AppLifecyclePhase and calls this; the coordinator applies the configured BackgroundPolicy — pausing/reconnecting connections and the health monitor, and pausing/resuming scheduled jobs.
openAppFromBundle(BundleRef bundleRef, {TrustLevel trustLevel = TrustLevel.basic, EntryContext? entry, IdentityContext? identity, String? launchRoute}) → Future<AppSession>
FR-CORE-003 — Local Bundle path (McpBundle file / inline JSON).
openAppFromServer(String serverId, {TrustLevel trustLevel = TrustLevel.basic, EntryContext? entry, IdentityContext? identity, String? launchRoute, Duration? connectWithin}) → Future<AppSession>
FR-CORE-002 — Online path (MCP server serves ui:// application).
openDashboard(DashboardBundleRef bundle, List<String> deviceIds) → Future<DashboardSession>
FR-CORE-004
openSavedDeviceAsOrigin(String id) → Future<KernelClientConnection>
Open the saved device id as a composition origin — one device, one connection.
readServedResource(String uri) → Future<Object?>
MCP Serving 1.0 — read a served resource by URI, delegating to the bridge. Returns the bundle document for bundle://manifest.json, or null when no bundle is open / the URI is unknown.
registerCapabilityTools(Map<String, Future<Object?> Function(Map<String, dynamic>)> tools) → void
Register additional in-process capability tools after boot — e.g. a desktop io / device tool-pack (io.*). Host-injected and opt-in: the core depends on no capability package, so platform-specific adapters (e.g. dart:io process execution) stay in the host layer. The tools share the same in-process dispatcher as the standard bk.* / mcp.* surface, so agents call them identically. Additive — safe to call more than once.
registerDefinitionResolver(Future<Map<String, dynamic>> resolve(String ref, Map<String, dynamic> origin)) → void
Register the resolver that backs multi-origin composition — one bundle rendering definitions served by several MCP servers (spec v1.4 §6.11).
registerStreamSource(String scheme, Stream open(String uri, Map<String, dynamic> params)) → void
Register a client.mcpStream source — e.g. a BLE scan hub for ble://. Applied to every app/bundle runtime after it initializes, so DSL bundles can bind live server-pushed data. Host-injected and opt-in: the core carries no radio/transport dep, mirroring registerCapabilityTools. Additive — safe to call more than once (per-scheme, last wins in the host runtime resolver). Registrations made before boot apply to every runtime; calling after a runtime exists applies to runtimes created afterwards.
releaseConnection(String serverId, String holder) → Future<void>
holder is done with serverId's connection.
releaseServerApp(String serverId) → Future<bool>
The app for server serverId is gone — its card was removed, here or on another device of the account — so this device stops holding what the app held.
resolveBundleEntry(McpBundle bundle) → BundleEntryPoint
retainConnection(String serverId, String holder) → void
holder uses the connection of serverId — a lent session, say. Pair with releaseConnection; the connection closes when its last holder lets go (23 §6.1.4).
saveServer(ServerConfig server) → Future<void>
setActiveSession(AppHandle? handle) → void
Called by host shells (Standard chrome, Pro launcher, ...) when the visible bundle (the active tab/window) changes. Keeps the brain_kernel dispatch wrapper context — the auto-composed <bundleId>.* prefix — in sync. Passing null means the host itself is in front (home or launcher view), which is interpreted as the master context. Idempotent — repeating the same handle is a no-op.
setMcpLoggingLevel(String serverId, McpLogLevel level) → Future<bool>
MCP logging spec — request the server identified by serverId to emit only messages at or above level via notifications/message. Returns false when there is no active connection for serverId.
toString() → String
A string representation of this object.
inherited
uninstallBundle(String bundleId) → Future<void>
useKernelDefinitionResolver({Future<Map<String, dynamic>> readOwn(String uri)?, Future<void> openOrigin(String connectionId)?}) → void
Claim the Composition Profile using the kernel's own mcp.* tools.

Operators

operator ==(Object other) → bool
The equality operator.
inherited