Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .fallowrc.json
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@
"exports": ["*"]
},
{
// A published provider package's default export is its plugin contract; src/plugins/load.ts imports the package by name at runtime and reads `default`.
// A published provider package's default export is its plugin contract; packages/plugins/src/load.ts imports the package by name at runtime and reads `default`.
"file": "packages/provider-*/src/index.ts",
"exports": ["default"]
},
Expand Down
1 change: 1 addition & 0 deletions examples/sdk/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@
{ "path": "../../packages/platform-linux" },
{ "path": "../../packages/platform-vega" },
{ "path": "../../packages/platform-web" },
{ "path": "../../packages/plugins" },
{ "path": "../../packages/provider-limrun" },
{ "path": "../../packages/provider-testmu" },
{ "path": "../../packages/provider-webdriver" },
Expand Down
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -305,6 +305,7 @@
"@agent-device/platform-linux": "workspace:*",
"@agent-device/platform-vega": "workspace:*",
"@agent-device/platform-web": "workspace:*",
"@agent-device/plugins": "workspace:*",
"@agent-device/provider-limrun": "workspace:*",
"@agent-device/provider-webdriver": "workspace:*",
"@agent-device/provision-kit": "workspace:*",
Expand Down
1 change: 1 addition & 0 deletions packages/contracts/src/facades/remote.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,5 +26,6 @@ export type {
ProviderDeviceOrientation,
ProviderDeviceType,
RemoteConfigMetroOptions,
RemoteConfigProfile,
RemoteConnectionProfileFields,
} from '../remote-config-fields.ts';
15 changes: 15 additions & 0 deletions packages/contracts/src/remote-config-fields.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import type { DeviceTarget, PlatformSelector } from '@agent-device/kernel/device';
import type {
DaemonServerMode,
DaemonTransportPreference,
Expand Down Expand Up @@ -129,3 +130,17 @@ export type RemoteConnectionProfileFields = {
deviceKey?: string;
clientId?: string;
};

/** A resolved remote-config profile: the field groups above plus the device-selection fields. */
export type RemoteConfigProfile = RemoteConfigMetroOptions &
CloudProviderProfileFields &
RemoteConnectionProfileFields & {
platform?: PlatformSelector;
target?: DeviceTarget;
device?: string;
udid?: string;
serial?: string;
iosSimulatorDeviceSet?: string;
androidDeviceAllowlist?: string;
session?: string;
};
2 changes: 1 addition & 1 deletion packages/host-kit/src/internal/path-resolution.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ export function resolveUserPath(inputPath: string, options: PathResolutionOption
* same question those two answer — a location named by the environment becomes an absolute path —
* and it answers it with nothing but `env`: no option schema, no flag grammar, no command facet.
* Plugin discovery needs the answer at daemon start and must not acquire the CLI's schema layer to
* get it (`src/plugins/store.ts`), which is a 153-file zone rather than a path helper.
* get it (`packages/plugins/src/store.ts`), which is a 153-file zone rather than a path helper.
*/
export function resolveUserConfigPath(env: EnvMap): string {
const home = env.AGENT_DEVICE_HOME
Expand Down
38 changes: 38 additions & 0 deletions packages/plugins/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
{
"name": "@agent-device/plugins",
"version": "0.0.0",
"private": true,
"type": "module",
"description": "Provider plugin manifest, installation store, host and loader for agent-device. Internal workspace package bundled into the published artifact.",
"dependencies": {
"@agent-device/contracts": "workspace:*",
"@agent-device/host-kit": "workspace:*",
"@agent-device/kernel": "workspace:*",
"@agent-device/provider-webdriver": "workspace:*"
},
"exports": {
"./connection": {
"types": "./src/connection.ts",
"default": "./src/connection.ts"
},
"./host": {
"types": "./src/host.ts",
"default": "./src/host.ts"
},
"./load": {
"types": "./src/load.ts",
"default": "./src/load.ts"
},
"./manifest": {
"types": "./src/manifest.ts",
"default": "./src/manifest.ts"
},
"./store": {
"types": "./src/store.ts",
"default": "./src/store.ts"
}
},
"devDependencies": {
"@agent-device/test-kit": "workspace:*"
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@ import type { CliFlags } from '@agent-device/contracts/command';
import type {
ConnectionProviderCapabilities,
ProviderConnectionVerification,
RemoteConfigProfile,
} from '@agent-device/contracts/remote';
import type { EnvMap } from '@agent-device/kernel/source-value';
import type { RemoteConfigProfile } from '../remote/remote-config-schema.ts';
import { installedPlugins } from './store.ts';

export type PluginConnection = Readonly<{
Expand Down
10 changes: 8 additions & 2 deletions src/plugins/host.ts → packages/plugins/src/host.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,12 @@
import { AppError } from '@agent-device/kernel/errors';
import { AppError, type AppErrorCode, type AppErrorDetails } from '@agent-device/kernel/errors';
import { readVersion } from '@agent-device/host-kit/version';
import type { ProviderPluginHost } from '../sdk/plugins.ts';

export type ProviderPluginHost = Readonly<{
env: Readonly<Record<string, string | undefined>>;
options: Readonly<Record<string, unknown>>;
clientVersion: string;
createError(code: AppErrorCode, message: string, details?: AppErrorDetails): AppError;
}>;

export function createPluginHost(
env: NodeJS.ProcessEnv,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import {
webDriverPluginSource,
} from '@agent-device/test-kit';
import { AppError } from '@agent-device/kernel/errors';
import type { ProviderPluginHost } from '../sdk/plugins.ts';
import type { ProviderPluginHost } from './host.ts';
import type { DeviceLease, ProviderDeviceRuntime } from '@agent-device/contracts/device';

const realFetch = globalThis.fetch;
Expand Down
11 changes: 5 additions & 6 deletions src/plugins/load.ts → packages/plugins/src/load.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,15 @@ import { pathToFileURL } from 'node:url';
import { AppError } from '@agent-device/kernel/errors';
import type { ProviderDeviceRuntime } from '@agent-device/contracts/device';
import type { PlatformRuntimeProviderModule } from '@agent-device/contracts/platform-runtime-operations';
import type { ProviderPluginHost } from '../sdk/plugins.ts';
import { installedPlugins } from './store.ts';
import {
resolvePluginEntry,
assertUniquePluginProviders,
RESERVED_PLUGIN_PROVIDERS,
} from './manifest.ts';
import { createPluginHost } from './host.ts';
import { createPluginHost, type ProviderPluginHost } from './host.ts';
import type { PluginConnection } from './connection.ts';
import type { WebDriverPluginOptions } from '../sdk/plugin-webdriver.ts';
import type { CloudWebDriverProviderOptions } from '@agent-device/provider-webdriver/plugin';

type ProviderPluginRegistration = Readonly<{
runtime: ProviderDeviceRuntime;
Expand Down Expand Up @@ -75,10 +74,10 @@ async function instantiateProviderPlugin(
host: ProviderPluginHost,
) =>
| ProviderPluginRegistration
| { webDriver: WebDriverPluginOptions; connection?: PluginConnection }
| { webDriver: CloudWebDriverProviderOptions; connection?: PluginConnection }
| Promise<
| ProviderPluginRegistration
| { webDriver: WebDriverPluginOptions; connection?: PluginConnection }
| { webDriver: CloudWebDriverProviderOptions; connection?: PluginConnection }
>
)(host);
let registration: ProviderPluginRegistration;
Expand Down Expand Up @@ -108,7 +107,7 @@ async function instantiateProviderPlugin(

function isWebDriverPluginResult(
result: unknown,
): result is { webDriver: WebDriverPluginOptions; connection?: PluginConnection } {
): result is { webDriver: CloudWebDriverProviderOptions; connection?: PluginConnection } {
return typeof result === 'object' && result !== null && 'webDriver' in result;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,7 @@ import assert from 'node:assert/strict';
import fs from 'node:fs';
import path from 'node:path';
import { test } from 'vitest';
import { readPluginManifest, RESERVED_PLUGIN_PROVIDERS } from './manifest.ts';
import { DEFAULT_PROVIDER_RUNTIME_REQUIRED_IDS } from '../provider-device-runtimes.ts';
import { readPluginManifest } from './manifest.ts';
import { pluginHome, writePlugin } from '@agent-device/test-kit';

test('manifest compatibility is checked without evaluating plugin code', () => {
Expand Down Expand Up @@ -85,8 +84,3 @@ test('credential variables are optional environment variable names', () => {
for (const invalid of [null, 'EXAMPLE_USER', {}, [''], ['example_user'], ['2KEY'], ['A-B'], [1]])
assert.throws(() => read(invalid), { code: 'INVALID_ARGS' }, JSON.stringify(invalid));
});

test('every bundled provider runtime is reserved from plugins', () => {
for (const provider of DEFAULT_PROVIDER_RUNTIME_REQUIRED_IDS)
assert.ok((RESERVED_PLUGIN_PROVIDERS as readonly string[]).includes(provider), provider);
});
File renamed without changes.
File renamed without changes.
File renamed without changes.
20 changes: 20 additions & 0 deletions packages/plugins/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
{
"extends": "../../tsconfig.json",
"compilerOptions": {
"composite": true,
"noEmit": false,
"emitDeclarationOnly": true,
"declaration": true,
"declarationDir": "./dist-types",
"rootDir": "./src",
"tsBuildInfoFile": "./dist-types/index.tsbuildinfo"
},
"include": ["src"],
"references": [
{ "path": "../contracts" },
{ "path": "../host-kit" },
{ "path": "../kernel" },
{ "path": "../provider-webdriver" },
{ "path": "../test-kit" }
]
}
Loading
Loading