Skip to content

Advanced windows and commands

The immutable API remains the precise, stable layer beneath convention-first applications. Use it for generators, reusable plugins, infrastructure, dynamic manifests, or cases where every protocol-facing object should be visible.

$app = Application::make(
id: 'com.example.my-app',
name: 'My desktop app',
version: '1.0.0',
window: Window::create('My desktop app')
->load('resources/index.html')
->size(1120, 720)
->minimumSize(720, 520)
->theme(WindowTheme::Dark),
)
->description('A PHP-first desktop application.')
->publisher('My team')
->category(ApplicationCategory::Development);
$app->command('greet', static function (CommandContext $command): CommandResult {
$name = $command->string('name', 'world');
return CommandResult::success(['message' => "Hello, {$name}!"])
->effect(WindowEffect::title("Hello, {$name}", $command->windowId))
->event(new ClientEvent('greeting.completed', compact('name')));
});

The worker accepts ordinary PHP values too; only use CommandResult when the handler needs to attach effects or events manually.

const result = await window.pam.invoke(
"greet",
{ name: "Ada" },
{ timeout: 5_000 },
);

Every request carries its exact source window, gateway origin, and ephemeral bridge token. AbortSignal cancellation and hard deadlines are supported.

Commands, frontend events, and background jobs run through supervised PHP workers. On timeout, cancellation, crash, invalid output, or message overflow, PAM kills and reaps the generation before accepting new work. Interrupted commands are never retried automatically because their side effects may have completed immediately before failure.