From 9b444a9a879b75a6af3d3c7ba8b9a4294574c3ec Mon Sep 17 00:00:00 2001 From: nsfisis Date: Wed, 5 Aug 2026 03:58:03 +0900 Subject: feat(plugin): run plugin-provided commands in a worker-side application A same-FQCN Composer\Console\Application, hand-written under the new php/runtime/ tree, hosts CommandProvider commands inside the PHP worker: PhpCommandProxy overrides run() and forwards the stringified input, so the real Symfony machinery binds, validates and executes against the live command object, while help/list render Rust-side from a definition read back at construction. Reverse \Shirabe\RustCommandStub rows let a plugin command invoke built-in commands back in the Rust process, keeping every command on the side whose helper set it was written for. Composer\EventDispatcher\Event moves from a generated stub to a dual-mode runtime class: the real BaseCommand::initialize constructs a PreCommandRunEvent natively in the worker, which a proxy-only constructor guard rejected. Its PRE_COMMAND_RUN dispatch reaches a new EventDispatcher stub whose dispatch supports the observably-no-op no-listener case and fails explicitly otherwise. The stub generator now accepts runtime-provided classes as stub bases (never as targets) and cross-checks the Application handoff property table against the real class. Co-Authored-By: Claude Fable 5 --- .../php/runtime/Composer/EventDispatcher/Event.php | 120 +++++++++++++++++++++ 1 file changed, 120 insertions(+) create mode 100644 crates/shirabe-php-rpc/php/runtime/Composer/EventDispatcher/Event.php (limited to 'crates/shirabe-php-rpc/php/runtime/Composer/EventDispatcher/Event.php') diff --git a/crates/shirabe-php-rpc/php/runtime/Composer/EventDispatcher/Event.php b/crates/shirabe-php-rpc/php/runtime/Composer/EventDispatcher/Event.php new file mode 100644 index 00000000..0d35ac55 --- /dev/null +++ b/crates/shirabe-php-rpc/php/runtime/Composer/EventDispatcher/Event.php @@ -0,0 +1,120 @@ +__rhandle = $name; + $this->__epoch = $args; + + return; + } + if (!is_string($name)) { + throw new \RuntimeException( + 'Shirabe does not support constructing ' . static::class . ' inside the plugin process without an event name' + ); + } + $this->__rhandle = null; + $this->name = $name; + $this->args = $args; + $this->flags = $flags; + } + + public function __destruct() + { + if ($this->__rhandle !== null) { + \ShirabeRustObjectRegistry::release($this->__rhandle); + } + } + + public function __shirabeRustHandleDescriptor(): ?array + { + if ($this->__rhandle === null) { + return null; + } + + return [ + '__rhandle' => $this->__rhandle, + '__class' => static::class, + '__epoch' => $this->__epoch, + ]; + } + + public function getName(): string + { + if ($this->__rhandle !== null) { + return \ShirabeRpcRuntime::callRust($this->__rhandle, 'getName', []); + } + + return $this->name; + } + + public function getArguments(): array + { + if ($this->__rhandle !== null) { + return \ShirabeRpcRuntime::callRust($this->__rhandle, 'getArguments', []); + } + + return $this->args; + } + + public function getFlags(): array + { + if ($this->__rhandle !== null) { + return \ShirabeRpcRuntime::callRust($this->__rhandle, 'getFlags', []); + } + + return $this->flags; + } + + public function isPropagationStopped(): bool + { + if ($this->__rhandle !== null) { + return \ShirabeRpcRuntime::callRust($this->__rhandle, 'isPropagationStopped', []); + } + + return $this->propagationStopped; + } + + public function stopPropagation(): void + { + if ($this->__rhandle !== null) { + \ShirabeRpcRuntime::callRust($this->__rhandle, 'stopPropagation', []); + + return; + } + $this->propagationStopped = true; + } +} -- cgit v1.3.1