|
1 | | -// Vocabulary for the platform-plugin provider facet. |
| 1 | +// Vocabulary for the platform-plugin provider facet and the request-scoped provider seam. |
2 | 2 | // |
3 | | -// `core/platform-plugin/plugin.ts` declares which daemon provider resolvers a platform |
4 | | -// family gates. The daemon owns the resolvers themselves and asserts at compile time, in |
5 | | -// `daemon/request-platform-providers.ts`, that every key named here is a real resolver — |
6 | | -// so the facet can never name a resolver the daemon does not compose. |
| 3 | +// `core/platform-plugin/plugin.ts` declares which provider resolvers a platform family gates. |
| 4 | +// The concrete resolver table and wrapper composition live in the root composition module; the |
| 5 | +// daemon only supplies this neutral request context and consumes the one capability it currently |
| 6 | +// needs from the resulting scope. |
| 7 | + |
| 8 | +import type { DeviceInfo } from '@agent-device/kernel/device'; |
| 9 | +import type { SessionSurface } from './session-surface.ts'; |
| 10 | + |
| 11 | +export type PlatformProviderRequestSession = Readonly<{ |
| 12 | + name: string; |
| 13 | + device: DeviceInfo; |
| 14 | + appBundleId?: string; |
| 15 | + appName?: string; |
| 16 | + surface?: SessionSurface; |
| 17 | +}>; |
| 18 | + |
| 19 | +/** Request data shared with a root-composed platform provider resolver. */ |
| 20 | +export type PlatformProviderRequestContext = Readonly<{ |
| 21 | + device: DeviceInfo; |
| 22 | + session?: PlatformProviderRequestSession; |
| 23 | + requestedSession?: string; |
| 24 | + requestId?: string; |
| 25 | + /** Daemon policy says that the root may construct its managed Web provider for this request. */ |
| 26 | + useDefaultWebProvider?: boolean; |
| 27 | +}>; |
| 28 | + |
| 29 | +/** The only request-scoped platform value currently consumed by daemon handlers. |
| 30 | + * |
| 31 | + * Its concrete Android executor type remains owned by the Android package. The daemon handlers |
| 32 | + * already pass this value through as an opaque capability, so duplicating that package type here |
| 33 | + * would make the seam another declaration site rather than a neutral contract. |
| 34 | + */ |
| 35 | +export type RequestPlatformProviderScope = Readonly<{ |
| 36 | + androidAdbExecutor?: unknown; |
| 37 | +}>; |
| 38 | + |
| 39 | +/** Root-composed provider wrappers; device selection remains a daemon policy. */ |
| 40 | +export type RequestPlatformProviders = Readonly<{ |
| 41 | + /** Avoid resolving a daemon device when no resolver or default Web provider is configured. */ |
| 42 | + hasConfiguredResolvers: boolean; |
| 43 | + run<T>( |
| 44 | + context: PlatformProviderRequestContext, |
| 45 | + task: (scope: RequestPlatformProviderScope) => Promise<T>, |
| 46 | + ): Promise<T>; |
| 47 | +}>; |
7 | 48 |
|
8 | 49 | /** |
9 | 50 | * The request provider resolvers whose application is PLATFORM-GATED — each ran behind |
10 | 51 | * a hand `device.platform === …` predicate inside its descriptor's `resolve`. The |
11 | 52 | * PlatformPlugin `providers` facet (issue #974) declares, per family, which of these |
12 | 53 | * apply to that family's devices (data-only: a plain string list, type-only in the |
13 | | - * plugin), and `platformGatedResolverApplies` routes the gate through it. The daemon |
14 | | - * still OWNS the resolver invocation, wrapper composition, and request-scope |
15 | | - * concurrency isolation — only the platform GATE moved to data. |
| 54 | + * plugin), and the root composition routes the gate through it. Resolver invocation, |
| 55 | + * wrapper composition, and request-scope concurrency isolation live with the concrete |
| 56 | + * provider composition, not in daemon request code. |
16 | 57 | * |
17 | 58 | * App-log and screen-recording transports are deliberately ABSENT: they carry no |
18 | 59 | * platform gate (they apply on every platform), so they stay ungated in the daemon and |
|
0 commit comments