From ca4c99f0746d0be96079d9452476709806799118 Mon Sep 17 00:00:00 2001 From: Neko Ayaka Date: Wed, 22 Apr 2026 14:23:45 +0800 Subject: [PATCH] fix(stage-pages,stage-ui): plugin host update --- apps/ui-server-auth/tsconfig.json | 1 + .../src/pages/devtools/plugin-host.vue | 64 ++++++++++++++++++- .../src/stores/devtools/plugin-host-debug.ts | 40 ++++++++++++ .../src/stores/mods/api/context-bridge.ts | 6 ++ 4 files changed, 110 insertions(+), 1 deletion(-) diff --git a/apps/ui-server-auth/tsconfig.json b/apps/ui-server-auth/tsconfig.json index 9f7359641..06fe74adc 100644 --- a/apps/ui-server-auth/tsconfig.json +++ b/apps/ui-server-auth/tsconfig.json @@ -8,6 +8,7 @@ "DOM.Iterable", "DOM.AsyncIterable" ], + "useDefineForClassFields": true, "paths": { "@proj-airi/stage-ui/*": [ "../../packages/stage-ui/src/*" diff --git a/packages/stage-pages/src/pages/devtools/plugin-host.vue b/packages/stage-pages/src/pages/devtools/plugin-host.vue index 7e8d4fe4e..ac5f00d0c 100644 --- a/packages/stage-pages/src/pages/devtools/plugin-host.vue +++ b/packages/stage-pages/src/pages/devtools/plugin-host.vue @@ -106,6 +106,18 @@ async function loadEnabled() { } } +async function setAutoReload(plugin: PluginManifestSummary, enabled: boolean) { + try { + await store.setAutoReload({ + name: plugin.name, + enabled, + }) + } + catch (error) { + toast.error(error instanceof Error ? error.message : `Failed to update auto-reload state for ${plugin.name}.`) + } +} + async function setEnabled(plugin: PluginManifestSummary, enabled: boolean) { try { await store.setEnabled({ @@ -173,7 +185,7 @@ onMounted(async () => { :description="store.error" /> -
+
Discovered @@ -206,6 +218,14 @@ onMounted(async () => { {{ readyCapabilitiesCount }} / {{ store.capabilities.length }}
+
+
+ Kits +
+
+ {{ store.kits.length }} +
+
@@ -272,6 +292,9 @@ onMounted(async () => { {{ plugin.enabled ? 'enabled' : 'disabled' }} + + {{ plugin.autoReload ? 'auto reload on' : 'auto reload off' }} + {{ plugin.loaded ? 'loaded' : 'not loaded' }} @@ -280,6 +303,14 @@ onMounted(async () => {
+
+
+
+ No kits registered. +
+
+
+
+ {{ kit.kitId }} + + v{{ kit.version }} + +
+
+ runtimes: {{ kit.runtimes.join(', ') || '-' }} +
+
{{ JSON.stringify(kit.capabilities, null, 2) }}
+
+
+
+
path: string enabled: boolean + autoReload: boolean loaded: boolean isNew: boolean } @@ -32,9 +33,36 @@ export interface PluginHostSessionSummary { moduleId: string } +export interface PluginHostKitCapabilitySummary { + key: string + actions: string[] +} + +export interface PluginHostKitSummary { + kitId: string + version: string + capabilities: PluginHostKitCapabilitySummary[] + runtimes: Array<'electron' | 'node' | 'web'> +} + +export interface PluginHostModuleSummary { + moduleId: string + ownerSessionId: string + ownerPluginId: string + kitId: string + kitModuleType: string + state: 'announced' | 'active' | 'degraded' | 'withdrawn' + runtime: 'electron' | 'node' | 'web' + revision: number + updatedAt: number + config: Record +} + export interface PluginHostDebugSnapshot { registry: PluginRegistrySnapshot sessions: PluginHostSessionSummary[] + kits: PluginHostKitSummary[] + modules: PluginHostModuleSummary[] capabilities: PluginCapabilityState[] refreshedAt: number } @@ -42,6 +70,7 @@ export interface PluginHostDebugSnapshot { interface PluginHostDebugBridge { list: () => Promise setEnabled: (payload: { name: string, enabled: boolean, path?: string }) => Promise + setAutoReload: (payload: { name: string, enabled: boolean }) => Promise loadEnabled: () => Promise load: (payload: { name: string }) => Promise unload: (payload: { name: string }) => Promise @@ -60,6 +89,7 @@ export const usePluginHostInspectorStore = defineStore('devtools:plugin-host-deb const bridge = ref() const registry = ref() const sessions = ref([]) + const kits = ref([]) const capabilities = ref([]) const refreshedAt = ref() const error = ref() @@ -87,6 +117,7 @@ export const usePluginHostInspectorStore = defineStore('devtools:plugin-host-deb function assignInspection(snapshot: PluginHostDebugSnapshot) { assignRegistry(snapshot.registry) sessions.value = snapshot.sessions + kits.value = snapshot.kits capabilities.value = snapshot.capabilities refreshedAt.value = snapshot.refreshedAt } @@ -146,6 +177,13 @@ export const usePluginHostInspectorStore = defineStore('devtools:plugin-host-deb return nextRegistry } + async function setAutoReload(payload: { name: string, enabled: boolean }) { + const nextRegistry = await withBridge(activeBridge => activeBridge.setAutoReload(payload)) + assignRegistry(nextRegistry) + await refreshInspection() + return nextRegistry + } + async function loadEnabled() { const nextRegistry = await withBridge(activeBridge => activeBridge.loadEnabled()) assignRegistry(nextRegistry) @@ -170,6 +208,7 @@ export const usePluginHostInspectorStore = defineStore('devtools:plugin-host-deb return { registry, sessions, + kits, capabilities, refreshedAt, loading, @@ -185,6 +224,7 @@ export const usePluginHostInspectorStore = defineStore('devtools:plugin-host-deb refreshInspection, refreshAll, setEnabled, + setAutoReload, loadEnabled, load, unload, diff --git a/packages/stage-ui/src/stores/mods/api/context-bridge.ts b/packages/stage-ui/src/stores/mods/api/context-bridge.ts index 264c6ec54..e318bd43f 100644 --- a/packages/stage-ui/src/stores/mods/api/context-bridge.ts +++ b/packages/stage-ui/src/stores/mods/api/context-bridge.ts @@ -55,11 +55,16 @@ export const useContextBridgeStore = defineStore('mods:api:context-bridge', () = const { post: broadcastContext, data: incomingContext } = useBroadcastChannel({ name: CONTEXT_CHANNEL_NAME }) const { post: broadcastStreamEvent, data: incomingStreamEvent } = useBroadcastChannel({ name: CHAT_STREAM_CHANNEL_NAME }) + const sparkNotifyHostRole = ref<'main' | 'client'>('client') const disposeHookFns = ref void>>([]) let remoteStreamGuard: { sessionId: string, generation: number } | null = null let initialized = false + function setSparkNotifyHostRole(role: 'main' | 'client') { + sparkNotifyHostRole.value = role + } + async function initialize() { await mutex.acquire() @@ -525,5 +530,6 @@ export const useContextBridgeStore = defineStore('mods:api:context-bridge', () = return { initialize, dispose, + setSparkNotifyHostRole, } })