feat: implement AirAppRuntimeBridge for managing runtime lifecycle and add corresponding unit tests for launcher window and runtime orchestration

This commit is contained in:
lincube
2026-07-14 01:41:01 +09:00
parent a858860b3f
commit 611d03b828
14 changed files with 852 additions and 382 deletions

View File

@@ -2,7 +2,12 @@
- [x] `LanMountainDesktop.AirAppRuntime` is included in `LanMountainDesktop.slnx`.
- [x] Launcher no longer hosts `IAirAppLifecycleService`.
- [x] Launcher performs a bounded Host attach after startup, records the outcome, and exits without waiting for the Host process lifetime.
- [x] Built-in world-clock, whiteboard, and RSS-reader entry components execute in Host and call Host-side `AirAppLauncherService`.
- [x] AirApp Runtime starts AirAppHost, and AirAppHost renders only the compiled-in built-in Air APP views.
- [x] Host fallback starts `LanMountainDesktop.AirAppRuntime`, not `LanMountainDesktop.Launcher air-app-broker`.
- [x] Production Host/Runtime/AirAppHost/Launcher do not reference AirAppSdk, AirAppTemplate, or AirAppDevServer and do not scan third-party `airapp.json` packages.
- [x] Documentation does not present the prototype `.laapp`/`airapp.json` output as compatible with the production `plugin.json` package installer.
- [x] AirApp Runtime is explicitly non-AOT and framework-dependent.
- [x] `dotnet build LanMountainDesktop.slnx -c Debug` passes.
- [x] Related AirApp Runtime tests pass.

View File

@@ -2,20 +2,29 @@
## Goal
Move built-in Air APP lifecycle management out of Launcher into a dedicated framework-dependent JIT process named `LanMountainDesktop.AirAppRuntime`.
Move built-in Air APP lifecycle management out of Launcher into a dedicated framework-dependent JIT process named `LanMountainDesktop.AirAppRuntime`, while keeping the built-in desktop entry components in the main Host and the visible Air APP windows in separate `LanMountainDesktop.AirAppHost` processes.
## Behavior
- Launcher remains the user-facing entry point and pre-starts AirApp Runtime during normal `launch`.
- The built-in world-clock, whiteboard, and RSS-reader desktop entry components run in the main `LanMountainDesktop` Host. Their click handlers call the Host-side `AirAppLauncherService`; they do not run inside Launcher.
- `AirAppLauncherService` sends an `AirAppOpenRequest` to `IAirAppLifecycleService` through the `LanMountainDesktop.AirAppRuntime.v1` IPC pipe.
- AirApp Runtime resolves the built-in instance key and starts or activates a separate `LanMountainDesktop.AirAppHost` process. `AirAppHost` owns and renders the visible built-in Air APP window.
- Launcher is a short-lived startup coordinator. During normal `launch` it pre-starts AirApp Runtime, starts Host, performs a bounded live-Host-PID handoff through `IAirAppRuntimeControlService`, then shuts down instead of remaining alive for the Host lifetime. A failed handoff is diagnosed and left to Host's on-demand Runtime fallback.
- AirApp Runtime exposes `IAirAppLifecycleService` and `IAirAppRuntimeControlService` on `LanMountainDesktop.AirAppRuntime.v1`.
- Desktop host requests Air APP operations through AirApp Runtime IPC.
- If the runtime pipe is unavailable, the desktop host starts `LanMountainDesktop.AirAppRuntime` directly and retries.
- AirApp Runtime keeps one AirAppHost process per `{appId}:{sourceComponentId}:{sourcePlacementId}` key, with `world-clock` sharing `world-clock:clock-suite:global`.
- AirApp Runtime remains alive while Launcher, Host, requester, or any AirAppHost process is alive.
- AirApp Runtime keeps one AirAppHost process per resolved instance key. `world-clock` shares `world-clock:clock-suite:global`, `rss-reader` shares `rss-reader:global`, and other built-ins use `{appId}:{sourceComponentId}:{sourcePlacementId}`.
- AirApp Runtime remains alive while the startup Launcher, attached Host, requester, or any AirAppHost process is alive. After a confirmed Host attachment, Host becomes the normal runtime owner; Launcher exits after its bounded handoff work rather than extending Host lifetime.
- AirApp Runtime exits after Launcher/Host/requester are gone and no Air APP windows remain.
## Production Boundary
- `LanMountainDesktop.AirAppSdk`, `LanMountainDesktop.AirAppTemplate`, and `LanMountainDesktop.AirAppDevServer` are preview/prototype projects. The production Host, Runtime, AirAppHost, and Launcher do not reference them or load third-party `airapp.json` assemblies.
- The production AirAppHost currently selects compiled-in views for `world-clock`, `whiteboard`, and `rss-reader`; it is not a general SDK package loader.
- `.laapp` is currently routed through the plugin packaging/install path, which requires `plugin.json`. The DevServer prototype's `.laapp` output based on `airapp.json` is therefore not a production-installable Air APP package.
## Out of Scope
- Moving Air APP windows into the runtime process.
- Third-party plugin-declared Air APP metadata.
- Integrating the AirAppSdk/Template/DevServer prototype or implementing a third-party Air APP manifest/package loader.
- Persisting the Air APP instance table across OS reboot.

View File

@@ -4,8 +4,11 @@
- [x] Add shared AirApp Runtime path resolver and process starter.
- [x] Add `LanMountainDesktop.AirAppRuntime` as a framework-dependent JIT process.
- [x] Move Air APP lifecycle service out of Launcher.
- [x] Make Launcher pre-start AirApp Runtime and attach Host PID after launch.
- [x] Keep built-in Air APP entry components in Host and route their clicks to AirApp Runtime over IPC.
- [x] Make Launcher pre-start AirApp Runtime, perform a bounded Host PID handoff after launch, and exit instead of tracking Host lifetime.
- [x] Keep visible built-in Air APP windows in separate AirAppHost processes managed by AirApp Runtime.
- [x] Make Host fallback start AirApp Runtime instead of Launcher broker.
- [x] Remove Launcher `air-app-broker` command handling.
- [x] Update packaging scripts and release workflow to include AirApp Runtime.
- [x] Document that AirAppSdk, AirAppTemplate, and AirAppDevServer are not yet connected to the production loading path.
- [x] Update unit tests and architecture/package assertions.