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
Original file line number Diff line number Diff line change
Expand Up @@ -501,7 +501,29 @@ private static function browser_component_plugins( array $input, array $declared
private static function browser_runtime_component_slugs( array $declared_components, bool $include_required ): array {
$slugs = array();
if ( $include_required ) {
$slugs = array( 'agents-api', 'data-machine', 'data-machine-code' );
/**
* Filters the set of component slugs the browser runtime always installs.
*
* The generic runtime has no built-in required components; consumer
* integrations (e.g. an agent runtime) register the plugin slugs their
* sandbox depends on. Slugs must have a matching entry in the component
* registry (see the wp_codebox_browser_runtime_component_registry filter)
* to resolve to an installable source.
*
* @param array<int,string> $slugs Required component slugs. Default empty.
*/
$required = function_exists( 'apply_filters' )
? apply_filters( 'wp_codebox_browser_runtime_required_components', array() )
: array();

if ( is_array( $required ) ) {
foreach ( $required as $required_slug ) {
$normalized = self::safe_key( (string) $required_slug );
if ( '' !== $normalized ) {
$slugs[] = $normalized;
}
}
}
}

foreach ( $declared_components as $component ) {
Expand All @@ -520,33 +542,22 @@ private static function browser_runtime_component_key( string $slug ): string {

/** @return array<string,array<string,mixed>> */
private static function browser_runtime_component_registry(): array {
$registry = array(
'agents-api' => array(
'resource' => 'url',
'url' => 'https://github.com/Automattic/agents-api/releases/latest/download/agents-api.zip',
'targetFolderName' => 'agents-api',
'activate' => true,
'provenance' => array( 'source' => 'runtime-component-registry' ),
),
'data-machine' => array(
'resource' => 'url',
'url' => 'https://github.com/Extra-Chill/data-machine/releases/latest/download/data-machine.zip',
'targetFolderName' => 'data-machine',
'activate' => true,
'provenance' => array( 'source' => 'runtime-component-registry' ),
),
'data-machine-code' => array(
'resource' => 'url',
'url' => 'https://github.com/Extra-Chill/data-machine-code/releases/latest/download/data-machine-code.zip',
'targetFolderName' => 'data-machine-code',
'activate' => true,
'provenance' => array( 'source' => 'runtime-component-registry' ),
),
);

if ( function_exists( 'apply_filters' ) ) {
$registry = apply_filters( 'wp_codebox_browser_runtime_component_registry', $registry );
}
/**
* Filters the browser runtime component registry: a map of component slug
* to an installable source descriptor (resource, url, targetFolderName,
* activate, provenance).
*
* The generic runtime ships no built-in components — it must not know which
* downstream plugins or vendor release URLs exist. Consumer integrations
* register their own components (and pair them with the
* wp_codebox_browser_runtime_required_components filter when a component
* should always be installed).
*
* @param array<string,array<string,mixed>> $registry Component registry. Default empty.
*/
$registry = function_exists( 'apply_filters' )
? apply_filters( 'wp_codebox_browser_runtime_component_registry', array() )
: array();

return is_array( $registry ) ? $registry : array();
}
Expand Down
47 changes: 47 additions & 0 deletions tests/smoke-wordpress-plugin.php
Original file line number Diff line number Diff line change
Expand Up @@ -544,6 +544,37 @@ function get_users( array $args ): array { return array( new WP_User( 11, 'Priva
'data_machine_code' => $root . '/data-machine-code',
'provider_plugins' => array( $root . '/ai-provider-test' ),
);
// The generic runtime ships no built-in components. A consumer integration
// registers the agent-stack components + their release sources via these
// filters (mirrors how extrachill-roadie wires the Extra Chill platform in).
$GLOBALS['wp_codebox_filters']['wp_codebox_browser_runtime_required_components'] = static function ( array $slugs ): array {
foreach ( array( 'agents-api', 'data-machine', 'data-machine-code' ) as $required ) {
if ( ! in_array( $required, $slugs, true ) ) {
$slugs[] = $required;
}
}
return $slugs;
};
$GLOBALS['wp_codebox_filters']['wp_codebox_browser_runtime_component_registry'] = static function ( array $registry ): array {
$defaults = array(
'agents-api' => 'https://github.com/Automattic/agents-api/releases/latest/download/agents-api.zip',
'data-machine' => 'https://github.com/Extra-Chill/data-machine/releases/latest/download/data-machine.zip',
'data-machine-code' => 'https://github.com/Extra-Chill/data-machine-code/releases/latest/download/data-machine-code.zip',
);
foreach ( $defaults as $slug => $url ) {
if ( isset( $registry[ $slug ] ) ) {
continue;
}
$registry[ $slug ] = array(
'resource' => 'url',
'url' => $url,
'targetFolderName' => $slug,
'activate' => true,
'provenance' => array( 'source' => 'runtime-component-registry' ),
);
}
return $registry;
};
$GLOBALS['wp_codebox_filters']['wp_codebox_bin'] = $root . '/wp-codebox.js';
$GLOBALS['wp_codebox_filters']['wp_codebox_default_agent'] = 'site-coder';
$GLOBALS['wp_codebox_filters']['wp_codebox_default_provider'] = 'openai';
Expand Down Expand Up @@ -1533,7 +1564,23 @@ static function ( $result, array $input, array $payload ) use ( $runner_report_p
$component_paths = $GLOBALS['wp_codebox_filters']['wp_codebox_component_paths'];
$GLOBALS['wp_codebox_filters']['wp_codebox_component_paths'] = array_merge( $component_paths, array( 'data_machine' => '' ) );
$registry_filter = $GLOBALS['wp_codebox_filters']['wp_codebox_browser_runtime_component_registry'] ?? null;
// Register only agents-api + data-machine-code (omit data-machine) so the
// missing-Data-Machine prerequisite path is exercised. The generic default is
// empty, so the consumer-style registration here is the full source of truth.
$GLOBALS['wp_codebox_filters']['wp_codebox_browser_runtime_component_registry'] = static function ( array $registry ): array {
$defaults = array(
'agents-api' => 'https://github.com/Automattic/agents-api/releases/latest/download/agents-api.zip',
'data-machine-code' => 'https://github.com/Extra-Chill/data-machine-code/releases/latest/download/data-machine-code.zip',
);
foreach ( $defaults as $slug => $url ) {
$registry[ $slug ] = array(
'resource' => 'url',
'url' => $url,
'targetFolderName' => $slug,
'activate' => true,
'provenance' => array( 'source' => 'runtime-component-registry' ),
);
}
unset( $registry['data-machine'] );
return $registry;
};
Expand Down