@vincenthanxiaodu/pi-web 1.202608.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +185 -0
- package/dist/cli.js +1149 -0
- package/dist/cli.js.map +1 -0
- package/dist/client/apple-touch-icon.png +0 -0
- package/dist/client/assets/CodeViewer-D_Q6ljLV.js +4 -0
- package/dist/client/assets/TerminalPanel-CTGixJIz.js +187 -0
- package/dist/client/assets/index-C2phil_t.js +5637 -0
- package/dist/client/assets/vendor-editor-core-CXO8gGab.js +12 -0
- package/dist/client/assets/vendor-editor-languages-CpW4sJsX.js +46 -0
- package/dist/client/assets/vendor-editor-legacy-CYBnW6ZU.js +1 -0
- package/dist/client/assets/vendor-terminal-BrP-ENHg.css +1 -0
- package/dist/client/assets/vendor-terminal-D8k4UKM2.js +35 -0
- package/dist/client/favicon.svg +11 -0
- package/dist/client/index.html +124 -0
- package/dist/client/manifest.webmanifest +24 -0
- package/dist/client/pwa-icon-192.png +0 -0
- package/dist/client/pwa-icon-512.png +0 -0
- package/dist/config.js +505 -0
- package/dist/config.js.map +1 -0
- package/dist/docker/piWebDockerCommandPlan.js +212 -0
- package/dist/docker/piWebDockerCommandPlan.js.map +1 -0
- package/dist/environment.js +4 -0
- package/dist/environment.js.map +1 -0
- package/dist/nativeServices/installedServiceDefinitions.js +602 -0
- package/dist/nativeServices/installedServiceDefinitions.js.map +1 -0
- package/dist/nativeServices/serviceAction.js +174 -0
- package/dist/nativeServices/serviceAction.js.map +1 -0
- package/dist/nativeServices/serviceDoctor.js +783 -0
- package/dist/nativeServices/serviceDoctor.js.map +1 -0
- package/dist/nativeServices/serviceInstall.js +35 -0
- package/dist/nativeServices/serviceInstall.js.map +1 -0
- package/dist/nativeServices/servicePlan.js +358 -0
- package/dist/nativeServices/servicePlan.js.map +1 -0
- package/dist/nativeServices/serviceProbe.js +447 -0
- package/dist/nativeServices/serviceProbe.js.map +1 -0
- package/dist/nativeServices/serviceRendering.js +132 -0
- package/dist/nativeServices/serviceRendering.js.map +1 -0
- package/dist/pi-web-plugins/git/browser/git-contract.js +108 -0
- package/dist/pi-web-plugins/git/browser/git-panel.js +609 -0
- package/dist/pi-web-plugins/git/browser/gitFileList.js +43 -0
- package/dist/pi-web-plugins/git/browser/gitFileShared.js +16 -0
- package/dist/pi-web-plugins/git/browser/gitFileTree.js +81 -0
- package/dist/pi-web-plugins/git/browser/gitFileViewPreference.js +35 -0
- package/dist/pi-web-plugins/git/browser/gitRoute.js +42 -0
- package/dist/pi-web-plugins/git/browser/pi-web-plugin.js +10 -0
- package/dist/pi-web-plugins/git/browser/unifiedDiff.js +301 -0
- package/dist/pi-web-plugins/git/git-backend.js +439 -0
- package/dist/pi-web-plugins/git/package.json +16 -0
- package/dist/pi-web-plugins/git/server-plugin.js +176 -0
- package/dist/pi-web-plugins/info/infoInternals.js +222 -0
- package/dist/pi-web-plugins/info/package.json +9 -0
- package/dist/pi-web-plugins/info/pi-web-plugin.js +48 -0
- package/dist/pi-web-plugins/relays/markdownDocument.js +81 -0
- package/dist/pi-web-plugins/relays/package.json +9 -0
- package/dist/pi-web-plugins/relays/pi-web-plugin.js +44 -0
- package/dist/pi-web-plugins/relays/relayDiscovery.js +228 -0
- package/dist/pi-web-plugins/relays/relaysPanelElement.js +550 -0
- package/dist/pi-web-plugins/relays/vendor/README.md +24 -0
- package/dist/pi-web-plugins/relays/vendor/marked.esm.js +76 -0
- package/dist/pi-web-plugins/updates/package.json +9 -0
- package/dist/pi-web-plugins/updates/pi-web-plugin.js +185 -0
- package/dist/pi-web-plugins/updates/updatesLogic.js +97 -0
- package/dist/pi-web-plugins/workspace-tasks/config.js +91 -0
- package/dist/pi-web-plugins/workspace-tasks/package.json +9 -0
- package/dist/pi-web-plugins/workspace-tasks/pi-web-plugin.js +48 -0
- package/dist/pi-web-plugins/workspace-tasks/taskRunner.js +12 -0
- package/dist/pi-web-plugins/workspace-tasks/tasksPanelElement.js +288 -0
- package/dist/pi-web-plugins/workspace-tasks/workspaceTasksClient.js +47 -0
- package/dist/piWebVersionReport.js +278 -0
- package/dist/piWebVersionReport.js.map +1 -0
- package/dist/plugin-api.d.ts +222 -0
- package/dist/pluginRecoveryCli.js +172 -0
- package/dist/pluginRecoveryCli.js.map +1 -0
- package/dist/server/activeAgentProfileProvider.js +25 -0
- package/dist/server/activeAgentProfileProvider.js.map +1 -0
- package/dist/server/activity/workspaceActivityService.js +106 -0
- package/dist/server/activity/workspaceActivityService.js.map +1 -0
- package/dist/server/app.js +218 -0
- package/dist/server/app.js.map +1 -0
- package/dist/server/browserMessageProjection.js +54 -0
- package/dist/server/browserMessageProjection.js.map +1 -0
- package/dist/server/configRoutes.js +293 -0
- package/dist/server/configRoutes.js.map +1 -0
- package/dist/server/diagnostics/nodePtyNativeModule.js +36 -0
- package/dist/server/diagnostics/nodePtyNativeModule.js.map +1 -0
- package/dist/server/diagnostics/nodePtySpawnHelper.js +135 -0
- package/dist/server/diagnostics/nodePtySpawnHelper.js.map +1 -0
- package/dist/server/git/gitEnv.js +15 -0
- package/dist/server/git/gitEnv.js.map +1 -0
- package/dist/server/goals/goalArchive.js +184 -0
- package/dist/server/goals/goalArchive.js.map +1 -0
- package/dist/server/goals/goalFile.js +200 -0
- package/dist/server/goals/goalFile.js.map +1 -0
- package/dist/server/goals/goalStore.js +65 -0
- package/dist/server/goals/goalStore.js.map +1 -0
- package/dist/server/index.js +7 -0
- package/dist/server/index.js.map +1 -0
- package/dist/server/machines/machineClient.js +191 -0
- package/dist/server/machines/machineClient.js.map +1 -0
- package/dist/server/machines/machinePluginProxyRoutes.js +247 -0
- package/dist/server/machines/machinePluginProxyRoutes.js.map +1 -0
- package/dist/server/machines/machineProxyRoutes.js +318 -0
- package/dist/server/machines/machineProxyRoutes.js.map +1 -0
- package/dist/server/machines/machineRoutes.js +56 -0
- package/dist/server/machines/machineRoutes.js.map +1 -0
- package/dist/server/machines/machineService.js +274 -0
- package/dist/server/machines/machineService.js.map +1 -0
- package/dist/server/machines/machineStore.js +143 -0
- package/dist/server/machines/machineStore.js.map +1 -0
- package/dist/server/piPackageRoutes.js +91 -0
- package/dist/server/piPackageRoutes.js.map +1 -0
- package/dist/server/piPackageService.js +101 -0
- package/dist/server/piPackageService.js.map +1 -0
- package/dist/server/piWebPluginCatalog.js +584 -0
- package/dist/server/piWebPluginCatalog.js.map +1 -0
- package/dist/server/piWebPluginLifecycle.js +162 -0
- package/dist/server/piWebPluginLifecycle.js.map +1 -0
- package/dist/server/piWebPluginService.js +224 -0
- package/dist/server/piWebPluginService.js.map +1 -0
- package/dist/server/piWebReleaseLookupCache.js +37 -0
- package/dist/server/piWebReleaseLookupCache.js.map +1 -0
- package/dist/server/piWebStatus.js +624 -0
- package/dist/server/piWebStatus.js.map +1 -0
- package/dist/server/piWebStatusCache.js +45 -0
- package/dist/server/piWebStatusCache.js.map +1 -0
- package/dist/server/plugins/pluginBackendProxyRoutes.js +69 -0
- package/dist/server/plugins/pluginBackendProxyRoutes.js.map +1 -0
- package/dist/server/plugins/serverPluginExec.js +184 -0
- package/dist/server/plugins/serverPluginExec.js.map +1 -0
- package/dist/server/plugins/serverPluginRuntime.js +480 -0
- package/dist/server/plugins/serverPluginRuntime.js.map +1 -0
- package/dist/server/projectTrustRoutes.js +80 -0
- package/dist/server/projectTrustRoutes.js.map +1 -0
- package/dist/server/projects/directorySuggestions.js +207 -0
- package/dist/server/projects/directorySuggestions.js.map +1 -0
- package/dist/server/projects/projectService.js +33 -0
- package/dist/server/projects/projectService.js.map +1 -0
- package/dist/server/realtime/sessionEventHub.js +93 -0
- package/dist/server/realtime/sessionEventHub.js.map +1 -0
- package/dist/server/requestCancellation.js +32 -0
- package/dist/server/requestCancellation.js.map +1 -0
- package/dist/server/sessiond/agentHttpDispatcher.js +108 -0
- package/dist/server/sessiond/agentHttpDispatcher.js.map +1 -0
- package/dist/server/sessiond/agentProcessEnvironment.js +61 -0
- package/dist/server/sessiond/agentProcessEnvironment.js.map +1 -0
- package/dist/server/sessiond/pluginBackendRoutes.js +64 -0
- package/dist/server/sessiond/pluginBackendRoutes.js.map +1 -0
- package/dist/server/sessiond/sessionDaemonShutdown.js +31 -0
- package/dist/server/sessiond/sessionDaemonShutdown.js.map +1 -0
- package/dist/server/sessiond/sessionProxyRoutes.js +61 -0
- package/dist/server/sessiond/sessionProxyRoutes.js.map +1 -0
- package/dist/server/sessiond/sessionServiceDependencies.js +34 -0
- package/dist/server/sessiond/sessionServiceDependencies.js.map +1 -0
- package/dist/server/sessiond/sessiondStateOwnership.js +235 -0
- package/dist/server/sessiond/sessiondStateOwnership.js.map +1 -0
- package/dist/server/sessiond/workspaceCatalogRoutes.js +31 -0
- package/dist/server/sessiond/workspaceCatalogRoutes.js.map +1 -0
- package/dist/server/sessiond/workspaceRemovalRoutes.js +41 -0
- package/dist/server/sessiond/workspaceRemovalRoutes.js.map +1 -0
- package/dist/server/sessiond.js +387 -0
- package/dist/server/sessiond.js.map +1 -0
- package/dist/server/sessions/askUserTool.js +102 -0
- package/dist/server/sessions/askUserTool.js.map +1 -0
- package/dist/server/sessions/attachmentService.js +119 -0
- package/dist/server/sessions/attachmentService.js.map +1 -0
- package/dist/server/sessions/authProviderOptions.js +50 -0
- package/dist/server/sessions/authProviderOptions.js.map +1 -0
- package/dist/server/sessions/authRoutes.js +59 -0
- package/dist/server/sessions/authRoutes.js.map +1 -0
- package/dist/server/sessions/authService.js +122 -0
- package/dist/server/sessions/authService.js.map +1 -0
- package/dist/server/sessions/builtinCommands.js +27 -0
- package/dist/server/sessions/builtinCommands.js.map +1 -0
- package/dist/server/sessions/dockerEnvironmentFacts.js +254 -0
- package/dist/server/sessions/dockerEnvironmentFacts.js.map +1 -0
- package/dist/server/sessions/editPreview.js +196 -0
- package/dist/server/sessions/editPreview.js.map +1 -0
- package/dist/server/sessions/extensionDialogWaiters.js +76 -0
- package/dist/server/sessions/extensionDialogWaiters.js.map +1 -0
- package/dist/server/sessions/globalProviderPolicy.js +167 -0
- package/dist/server/sessions/globalProviderPolicy.js.map +1 -0
- package/dist/server/sessions/interruptedRunStore.js +147 -0
- package/dist/server/sessions/interruptedRunStore.js.map +1 -0
- package/dist/server/sessions/messagePaging.js +43 -0
- package/dist/server/sessions/messagePaging.js.map +1 -0
- package/dist/server/sessions/modelCatalogRefresher.js +193 -0
- package/dist/server/sessions/modelCatalogRefresher.js.map +1 -0
- package/dist/server/sessions/oauthLoginFlowService.js +346 -0
- package/dist/server/sessions/oauthLoginFlowService.js.map +1 -0
- package/dist/server/sessions/pendingAskStore.js +275 -0
- package/dist/server/sessions/pendingAskStore.js.map +1 -0
- package/dist/server/sessions/pendingExtensionDialogStore.js +196 -0
- package/dist/server/sessions/pendingExtensionDialogStore.js.map +1 -0
- package/dist/server/sessions/piSessionManagerGateway.js +246 -0
- package/dist/server/sessions/piSessionManagerGateway.js.map +1 -0
- package/dist/server/sessions/piSessionService.js +4059 -0
- package/dist/server/sessions/piSessionService.js.map +1 -0
- package/dist/server/sessions/plainTextTheme.js +112 -0
- package/dist/server/sessions/plainTextTheme.js.map +1 -0
- package/dist/server/sessions/sessionArchiveStore.js +273 -0
- package/dist/server/sessions/sessionArchiveStore.js.map +1 -0
- package/dist/server/sessions/sessionArchiveTree.js +35 -0
- package/dist/server/sessions/sessionArchiveTree.js.map +1 -0
- package/dist/server/sessions/sessionCleanup.js +157 -0
- package/dist/server/sessions/sessionCleanup.js.map +1 -0
- package/dist/server/sessions/sessionCommandService.js +336 -0
- package/dist/server/sessions/sessionCommandService.js.map +1 -0
- package/dist/server/sessions/sessionEnvironmentFacts.js +48 -0
- package/dist/server/sessions/sessionEnvironmentFacts.js.map +1 -0
- package/dist/server/sessions/sessionFileFormat.js +27 -0
- package/dist/server/sessions/sessionFileFormat.js.map +1 -0
- package/dist/server/sessions/sessionFileHeader.js +104 -0
- package/dist/server/sessions/sessionFileHeader.js.map +1 -0
- package/dist/server/sessions/sessionModelScope.js +141 -0
- package/dist/server/sessions/sessionModelScope.js.map +1 -0
- package/dist/server/sessions/sessionNameGenerator.js +90 -0
- package/dist/server/sessions/sessionNameGenerator.js.map +1 -0
- package/dist/server/sessions/sessionNotificationStore.js +484 -0
- package/dist/server/sessions/sessionNotificationStore.js.map +1 -0
- package/dist/server/sessions/sessionRoutes.js +744 -0
- package/dist/server/sessions/sessionRoutes.js.map +1 -0
- package/dist/server/sessions/sessionRuntimeStore.js +2 -0
- package/dist/server/sessions/sessionRuntimeStore.js.map +1 -0
- package/dist/server/sessions/sessionService.js +2 -0
- package/dist/server/sessions/sessionService.js.map +1 -0
- package/dist/server/sessions/sessionSummaryScanner.js +491 -0
- package/dist/server/sessions/sessionSummaryScanner.js.map +1 -0
- package/dist/server/sessions/sessionTreeProjection.js +250 -0
- package/dist/server/sessions/sessionTreeProjection.js.map +1 -0
- package/dist/server/sessions/sessionUnreadStore.js +520 -0
- package/dist/server/sessions/sessionUnreadStore.js.map +1 -0
- package/dist/server/sessions/shutdownDrain.js +73 -0
- package/dist/server/sessions/shutdownDrain.js.map +1 -0
- package/dist/server/sessions/spawnSessionTool.js +48 -0
- package/dist/server/sessions/spawnSessionTool.js.map +1 -0
- package/dist/server/sessions/spawnSubsessionTool.js +216 -0
- package/dist/server/sessions/spawnSubsessionTool.js.map +1 -0
- package/dist/server/sessions/spawnTargetResolver.js +23 -0
- package/dist/server/sessions/spawnTargetResolver.js.map +1 -0
- package/dist/server/sessions/subsessionTranscript.js +235 -0
- package/dist/server/sessions/subsessionTranscript.js.map +1 -0
- package/dist/server/status/machineStatusRoutes.js +8 -0
- package/dist/server/status/machineStatusRoutes.js.map +1 -0
- package/dist/server/status/machineStatusService.js +181 -0
- package/dist/server/status/machineStatusService.js.map +1 -0
- package/dist/server/status/workspaceAttribution.js +87 -0
- package/dist/server/status/workspaceAttribution.js.map +1 -0
- package/dist/server/storage/projectStore.js +88 -0
- package/dist/server/storage/projectStore.js.map +1 -0
- package/dist/server/terminalProxyRoutes.js +141 -0
- package/dist/server/terminalProxyRoutes.js.map +1 -0
- package/dist/server/terminals/terminalRoutes.js +155 -0
- package/dist/server/terminals/terminalRoutes.js.map +1 -0
- package/dist/server/terminals/terminalService.js +305 -0
- package/dist/server/terminals/terminalService.js.map +1 -0
- package/dist/server/terminals/terminalSize.js +17 -0
- package/dist/server/terminals/terminalSize.js.map +1 -0
- package/dist/server/types.js +2 -0
- package/dist/server/types.js.map +1 -0
- package/dist/server/updates/fleetRoutes.js +111 -0
- package/dist/server/updates/fleetRoutes.js.map +1 -0
- package/dist/server/updates/restartRoutes.js +48 -0
- package/dist/server/updates/restartRoutes.js.map +1 -0
- package/dist/server/updates/selfUpdateRoutes.js +145 -0
- package/dist/server/updates/selfUpdateRoutes.js.map +1 -0
- package/dist/server/webSocketBridge.js +32 -0
- package/dist/server/webSocketBridge.js.map +1 -0
- package/dist/server/workingDirectory.js +44 -0
- package/dist/server/workingDirectory.js.map +1 -0
- package/dist/server/workspaceExplorerRoutes.js +147 -0
- package/dist/server/workspaceExplorerRoutes.js.map +1 -0
- package/dist/server/workspaces/effectivePathAccess.js +8 -0
- package/dist/server/workspaces/effectivePathAccess.js.map +1 -0
- package/dist/server/workspaces/fileContentService.js +190 -0
- package/dist/server/workspaces/fileContentService.js.map +1 -0
- package/dist/server/workspaces/filePreviewResponseHeaders.js +18 -0
- package/dist/server/workspaces/filePreviewResponseHeaders.js.map +1 -0
- package/dist/server/workspaces/filePreviewResponsePolicy.js +55 -0
- package/dist/server/workspaces/filePreviewResponsePolicy.js.map +1 -0
- package/dist/server/workspaces/filePreviewService.js +81 -0
- package/dist/server/workspaces/filePreviewService.js.map +1 -0
- package/dist/server/workspaces/fileSuggestions.js +520 -0
- package/dist/server/workspaces/fileSuggestions.js.map +1 -0
- package/dist/server/workspaces/fileTreeService.js +35 -0
- package/dist/server/workspaces/fileTreeService.js.map +1 -0
- package/dist/server/workspaces/pathAccessPolicy.js +90 -0
- package/dist/server/workspaces/pathAccessPolicy.js.map +1 -0
- package/dist/server/workspaces/pathSafety.js +45 -0
- package/dist/server/workspaces/pathSafety.js.map +1 -0
- package/dist/server/workspaces/projectPiWebConfig.js +61 -0
- package/dist/server/workspaces/projectPiWebConfig.js.map +1 -0
- package/dist/server/workspaces/projectWorkspaceCwds.js +17 -0
- package/dist/server/workspaces/projectWorkspaceCwds.js.map +1 -0
- package/dist/server/workspaces/sessionDaemonWorkspaceCatalog.js +402 -0
- package/dist/server/workspaces/sessionDaemonWorkspaceCatalog.js.map +1 -0
- package/dist/server/workspaces/workspaceCatalog.js +47 -0
- package/dist/server/workspaces/workspaceCatalog.js.map +1 -0
- package/dist/server/workspaces/workspaceContext.js +6 -0
- package/dist/server/workspaces/workspaceContext.js.map +1 -0
- package/dist/server/workspaces/workspaceDeletionRoutes.js +49 -0
- package/dist/server/workspaces/workspaceDeletionRoutes.js.map +1 -0
- package/dist/server/workspaces/workspaceProviderRegistry.js +651 -0
- package/dist/server/workspaces/workspaceProviderRegistry.js.map +1 -0
- package/dist/server/workspaces/workspaceRemovalService.js +256 -0
- package/dist/server/workspaces/workspaceRemovalService.js.map +1 -0
- package/dist/server/workspaces/workspaceRouteErrors.js +7 -0
- package/dist/server/workspaces/workspaceRouteErrors.js.map +1 -0
- package/dist/server/workspaces/worktreePreRemoveHook.js +39 -0
- package/dist/server/workspaces/worktreePreRemoveHook.js.map +1 -0
- package/dist/server-plugin-api.d.ts +140 -0
- package/dist/server-plugin-api.js +2 -0
- package/dist/server-plugin-api.js.map +1 -0
- package/dist/serverPluginRecovery.js +138 -0
- package/dist/serverPluginRecovery.js.map +1 -0
- package/dist/sessiond/activeAgentProfile.js +12 -0
- package/dist/sessiond/activeAgentProfile.js.map +1 -0
- package/dist/sessiond/config.js +20 -0
- package/dist/sessiond/config.js.map +1 -0
- package/dist/sessiond/sessionDaemonClient.js +105 -0
- package/dist/sessiond/sessionDaemonClient.js.map +1 -0
- package/dist/shared/activeAgentProfile.js +37 -0
- package/dist/shared/activeAgentProfile.js.map +1 -0
- package/dist/shared/activity.js +16 -0
- package/dist/shared/activity.js.map +1 -0
- package/dist/shared/apiTypes.js +41 -0
- package/dist/shared/apiTypes.js.map +1 -0
- package/dist/shared/capabilities.js +37 -0
- package/dist/shared/capabilities.js.map +1 -0
- package/dist/shared/federatedRoutes.js +127 -0
- package/dist/shared/federatedRoutes.js.map +1 -0
- package/dist/shared/machinePluginIds.js +43 -0
- package/dist/shared/machinePluginIds.js.map +1 -0
- package/dist/shared/machineStatus.js +94 -0
- package/dist/shared/machineStatus.js.map +1 -0
- package/dist/shared/piWebStatusParsing.js +141 -0
- package/dist/shared/piWebStatusParsing.js.map +1 -0
- package/dist/shared/pluginApiTypes.d.ts +150 -0
- package/dist/shared/pluginApiTypes.js +3 -0
- package/dist/shared/pluginApiTypes.js.map +1 -0
- package/dist/shared/pluginBackendProtocol.js +110 -0
- package/dist/shared/pluginBackendProtocol.js.map +1 -0
- package/dist/shared/pluginIds.js +10 -0
- package/dist/shared/pluginIds.js.map +1 -0
- package/dist/shared/pluginRecoveryCommands.js +14 -0
- package/dist/shared/pluginRecoveryCommands.js.map +1 -0
- package/dist/shared/promptAttachments.js +92 -0
- package/dist/shared/promptAttachments.js.map +1 -0
- package/dist/shared/selfUpdate.js +3 -0
- package/dist/shared/selfUpdate.js.map +1 -0
- package/dist/shared/thinkingLevels.js +31 -0
- package/dist/shared/thinkingLevels.js.map +1 -0
- package/dist/shared/workspaceDeletion.js +12 -0
- package/dist/shared/workspaceDeletion.js.map +1 -0
- package/dist/shared/workspaceFiles.js +42 -0
- package/dist/shared/workspaceFiles.js.map +1 -0
- package/dist/shared/workspaceRemovalProtocol.js +24 -0
- package/dist/shared/workspaceRemovalProtocol.js.map +1 -0
- package/docs/assets/favicon.svg +11 -0
- package/docs/assets/pi-web-banner.png +0 -0
- package/docs/assets/pi-web-desktop.png +0 -0
- package/docs/assets/pi-web-mobile.png +0 -0
- package/docs/assets/pi-web-tablet.png +0 -0
- package/docs/config.md +444 -0
- package/docs/plugins.md +1305 -0
- package/examples/workspace-provider-plugin/README.md +52 -0
- package/examples/workspace-provider-plugin/package.json +25 -0
- package/examples/workspace-provider-plugin/src/browser/index.ts +69 -0
- package/examples/workspace-provider-plugin/src/server.ts +64 -0
- package/examples/workspace-provider-plugin/tsconfig.json +21 -0
- package/extensions/README-pi-web-restart-migration.md +45 -0
- package/extensions/pi-web.ts +324 -0
- package/install.sh +5 -0
- package/package.json +173 -0
- package/plugin-api.d.ts +1 -0
- package/server-plugin-api.d.ts +1 -0
|
@@ -0,0 +1,288 @@
|
|
|
1
|
+
// Generated from pi-web-plugins/workspace-tasks/tasksPanelElement.ts. Do not edit directly.
|
|
2
|
+
import { TASKS_CONFIG_PATH } from "./config.js";
|
|
3
|
+
import { runWorkspaceTaskInTerminal } from "./taskRunner.js";
|
|
4
|
+
import { loadWorkspaceTasksConfig, tasksConfigRefreshHint, tasksConfigUnavailableMessage } from "./workspaceTasksClient.js";
|
|
5
|
+
export const tasksPanelTagName = "pi-web-workspace-tasks-panel";
|
|
6
|
+
const configChangedEvent = "pi-web-workspace-tasks-config-changed";
|
|
7
|
+
const configCache = new Map();
|
|
8
|
+
export function defineTasksPanelElement() {
|
|
9
|
+
if (!customElements.get(tasksPanelTagName))
|
|
10
|
+
customElements.define(tasksPanelTagName, PiWebTasksPanel);
|
|
11
|
+
}
|
|
12
|
+
export function tasksPanelBadge(context) {
|
|
13
|
+
const state = getCachedWorkspaceConfig(context);
|
|
14
|
+
return state?.kind === "unavailable" ? "!" : undefined;
|
|
15
|
+
}
|
|
16
|
+
class PiWebTasksPanel extends HTMLElement {
|
|
17
|
+
contextValue;
|
|
18
|
+
runningTaskId;
|
|
19
|
+
status;
|
|
20
|
+
root;
|
|
21
|
+
onConfigChanged = () => {
|
|
22
|
+
this.render();
|
|
23
|
+
};
|
|
24
|
+
constructor() {
|
|
25
|
+
super();
|
|
26
|
+
this.root = this.attachShadow({ mode: "open" });
|
|
27
|
+
}
|
|
28
|
+
set context(value) {
|
|
29
|
+
const previousKey = this.contextValue === undefined ? undefined : cacheKeyForContext(this.contextValue);
|
|
30
|
+
const nextKey = value === undefined ? undefined : cacheKeyForContext(value);
|
|
31
|
+
this.contextValue = value;
|
|
32
|
+
// Parent app updates should not rebuild this shadow DOM for the same workspace:
|
|
33
|
+
// doing so resets the mobile scroll position and can replace buttons mid-click.
|
|
34
|
+
if (previousKey === nextKey)
|
|
35
|
+
return;
|
|
36
|
+
this.runningTaskId = undefined;
|
|
37
|
+
this.status = undefined;
|
|
38
|
+
this.render();
|
|
39
|
+
}
|
|
40
|
+
connectedCallback() {
|
|
41
|
+
window.addEventListener(configChangedEvent, this.onConfigChanged);
|
|
42
|
+
this.render();
|
|
43
|
+
}
|
|
44
|
+
disconnectedCallback() {
|
|
45
|
+
window.removeEventListener(configChangedEvent, this.onConfigChanged);
|
|
46
|
+
}
|
|
47
|
+
render() {
|
|
48
|
+
const context = this.contextValue;
|
|
49
|
+
if (context === undefined) {
|
|
50
|
+
this.root.innerHTML = `${taskStyles()}<section class="empty">Select a workspace.</section>`;
|
|
51
|
+
return;
|
|
52
|
+
}
|
|
53
|
+
const state = getOrLoadWorkspaceConfig(context);
|
|
54
|
+
this.root.innerHTML = `
|
|
55
|
+
${taskStyles()}
|
|
56
|
+
<section class="toolbar">
|
|
57
|
+
<strong>Workspace Tasks</strong>
|
|
58
|
+
<span class="toolbar-tasks">
|
|
59
|
+
<button class="secondary" data-refresh-config ${state.kind === "loading" ? "disabled" : ""}>Refresh</button>
|
|
60
|
+
<button class="secondary" data-open-terminal>Open Terminal</button>
|
|
61
|
+
</span>
|
|
62
|
+
</section>
|
|
63
|
+
${this.renderStatus()}
|
|
64
|
+
<section class="viewer tasks-viewer">
|
|
65
|
+
${this.renderConfigState(state)}
|
|
66
|
+
</section>
|
|
67
|
+
`;
|
|
68
|
+
this.root.querySelector("button[data-refresh-config]")?.addEventListener("click", () => {
|
|
69
|
+
void this.refreshConfig(context);
|
|
70
|
+
});
|
|
71
|
+
for (const button of this.root.querySelectorAll("button[data-task-id]")) {
|
|
72
|
+
button.addEventListener("click", () => {
|
|
73
|
+
void this.dispatchTaskById(context, button.getAttribute("data-task-id"));
|
|
74
|
+
});
|
|
75
|
+
}
|
|
76
|
+
this.root.querySelector("button[data-open-terminal]")?.addEventListener("click", () => {
|
|
77
|
+
this.openWorkspaceTerminal();
|
|
78
|
+
});
|
|
79
|
+
}
|
|
80
|
+
dispatchTaskById(context, taskId) {
|
|
81
|
+
if (!this.isCurrentContext(context))
|
|
82
|
+
return Promise.resolve();
|
|
83
|
+
const task = taskFromConfigState(getCachedWorkspaceConfig(context), taskId);
|
|
84
|
+
if (task === undefined) {
|
|
85
|
+
this.status = { kind: "error", message: "That task is no longer available. Click Refresh, then try again." };
|
|
86
|
+
this.render();
|
|
87
|
+
return Promise.resolve();
|
|
88
|
+
}
|
|
89
|
+
return this.dispatchTask(context, task);
|
|
90
|
+
}
|
|
91
|
+
isCurrentContext(context) {
|
|
92
|
+
return this.contextValue !== undefined && cacheKeyForContext(this.contextValue) === cacheKeyForContext(context);
|
|
93
|
+
}
|
|
94
|
+
renderConfigState(state) {
|
|
95
|
+
if (state.kind === "loading")
|
|
96
|
+
return `<p class="muted">Loading ${escapeHtml(TASKS_CONFIG_PATH)}…</p>`;
|
|
97
|
+
if (state.kind === "missing")
|
|
98
|
+
return renderMissingState(state);
|
|
99
|
+
if (state.kind === "unavailable")
|
|
100
|
+
return renderUnavailableState(state);
|
|
101
|
+
if (state.config.tasks.length === 0)
|
|
102
|
+
return `<p class="muted">No tasks are defined in ${escapeHtml(state.path)}. Add tasks to the file, then click Refresh.</p>`;
|
|
103
|
+
return `
|
|
104
|
+
<p class="muted">Tasks run in a dedicated workspace terminal, then switch to that terminal. Edit ${escapeHtml(state.path)} and click Refresh to reload.</p>
|
|
105
|
+
${renderTaskGroups(state.config.tasks, this.runningTaskId)}
|
|
106
|
+
`;
|
|
107
|
+
}
|
|
108
|
+
renderStatus() {
|
|
109
|
+
if (this.status === undefined)
|
|
110
|
+
return "";
|
|
111
|
+
const detail = this.status.detail === undefined ? "" : `<pre>${escapeHtml(this.status.detail)}</pre>`;
|
|
112
|
+
return `<div class="status panel-status ${escapeAttr(this.status.kind)}">${escapeHtml(this.status.message)}${detail}</div>`;
|
|
113
|
+
}
|
|
114
|
+
async refreshConfig(context) {
|
|
115
|
+
this.status = { kind: "info", message: `Refreshing ${TASKS_CONFIG_PATH}…` };
|
|
116
|
+
configCache.set(cacheKeyForContext(context), { kind: "loading" });
|
|
117
|
+
this.render();
|
|
118
|
+
const state = await refreshWorkspaceConfig(context);
|
|
119
|
+
if (!this.isCurrentContext(context))
|
|
120
|
+
return;
|
|
121
|
+
this.status = state.kind === "loaded"
|
|
122
|
+
? { kind: "success", message: `Loaded ${String(state.config.tasks.length)} task${state.config.tasks.length === 1 ? "" : "s"}.` }
|
|
123
|
+
: undefined;
|
|
124
|
+
this.render();
|
|
125
|
+
}
|
|
126
|
+
async dispatchTask(context, task) {
|
|
127
|
+
if (this.runningTaskId !== undefined) {
|
|
128
|
+
this.status = { kind: "info", message: "Another task is already starting. Wait for it to finish dispatching, then try again." };
|
|
129
|
+
this.render();
|
|
130
|
+
return;
|
|
131
|
+
}
|
|
132
|
+
if (task.confirm && !window.confirm(`Run ${task.title}?\n\n${task.command}`)) {
|
|
133
|
+
this.status = { kind: "info", message: `Cancelled ${task.title}.` };
|
|
134
|
+
this.render();
|
|
135
|
+
return;
|
|
136
|
+
}
|
|
137
|
+
this.runningTaskId = task.id;
|
|
138
|
+
this.status = { kind: "info", message: `Starting ${task.title}…` };
|
|
139
|
+
this.render();
|
|
140
|
+
try {
|
|
141
|
+
const handle = await runWorkspaceTaskInTerminal(context.terminal, task);
|
|
142
|
+
if (!this.isCurrentContext(context))
|
|
143
|
+
return;
|
|
144
|
+
this.status = {
|
|
145
|
+
kind: "success",
|
|
146
|
+
message: `Started terminal command “${handle.run.title}”.`,
|
|
147
|
+
detail: task.command,
|
|
148
|
+
};
|
|
149
|
+
this.runningTaskId = undefined;
|
|
150
|
+
this.render();
|
|
151
|
+
}
|
|
152
|
+
catch (error) {
|
|
153
|
+
if (!this.isCurrentContext(context))
|
|
154
|
+
return;
|
|
155
|
+
this.runningTaskId = undefined;
|
|
156
|
+
this.status = { kind: "error", message: error instanceof Error ? error.message : String(error) };
|
|
157
|
+
this.render();
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
openWorkspaceTerminal(terminalId) {
|
|
161
|
+
const context = this.contextValue;
|
|
162
|
+
if (context === undefined) {
|
|
163
|
+
this.status = { kind: "error", message: "Select a workspace before opening a terminal." };
|
|
164
|
+
this.render();
|
|
165
|
+
return;
|
|
166
|
+
}
|
|
167
|
+
if (terminalId === undefined)
|
|
168
|
+
context.terminal.open();
|
|
169
|
+
else
|
|
170
|
+
context.terminal.open({ terminalId });
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
function getCachedWorkspaceConfig(context) {
|
|
174
|
+
return configCache.get(cacheKeyForContext(context));
|
|
175
|
+
}
|
|
176
|
+
function getOrLoadWorkspaceConfig(context) {
|
|
177
|
+
const cached = getCachedWorkspaceConfig(context);
|
|
178
|
+
if (cached !== undefined)
|
|
179
|
+
return cached;
|
|
180
|
+
const loading = { kind: "loading" };
|
|
181
|
+
configCache.set(cacheKeyForContext(context), loading);
|
|
182
|
+
void refreshWorkspaceConfig(context);
|
|
183
|
+
return loading;
|
|
184
|
+
}
|
|
185
|
+
async function refreshWorkspaceConfig(context) {
|
|
186
|
+
const key = cacheKeyForContext(context);
|
|
187
|
+
const state = await loadWorkspaceTasksConfig(context.files).catch((error) => ({
|
|
188
|
+
kind: "unavailable",
|
|
189
|
+
message: tasksConfigUnavailableMessage,
|
|
190
|
+
hint: tasksConfigRefreshHint,
|
|
191
|
+
detail: error instanceof Error ? error.message : String(error),
|
|
192
|
+
}));
|
|
193
|
+
configCache.set(key, state);
|
|
194
|
+
context.host.requestRender();
|
|
195
|
+
window.dispatchEvent(new Event(configChangedEvent));
|
|
196
|
+
return state;
|
|
197
|
+
}
|
|
198
|
+
function cacheKeyForContext(context) {
|
|
199
|
+
return `${context.machine.id}:${context.workspace.projectId}:${context.workspace.id}`;
|
|
200
|
+
}
|
|
201
|
+
function renderMissingState(state) {
|
|
202
|
+
return `<div class="empty-state"><strong>${escapeHtml(state.message)}</strong><p>${escapeHtml(state.hint)}</p></div>`;
|
|
203
|
+
}
|
|
204
|
+
function renderUnavailableState(state) {
|
|
205
|
+
const detail = state.detail === undefined ? "" : `<pre>${escapeHtml(state.detail)}</pre>`;
|
|
206
|
+
return `<div class="status error"><strong>${escapeHtml(state.message)}</strong><p>${escapeHtml(state.hint)}</p>${detail}</div>`;
|
|
207
|
+
}
|
|
208
|
+
function renderTaskGroups(tasks, runningTaskId) {
|
|
209
|
+
return `<div class="tasks">${groupTasks(tasks).map((group) => renderTaskGroup(group, runningTaskId)).join("")}</div>`;
|
|
210
|
+
}
|
|
211
|
+
function groupTasks(tasks) {
|
|
212
|
+
const groups = [];
|
|
213
|
+
for (const task of tasks) {
|
|
214
|
+
const title = task.group;
|
|
215
|
+
let group = groups.find((candidate) => candidate.title === title);
|
|
216
|
+
if (group === undefined) {
|
|
217
|
+
group = { title, tasks: [] };
|
|
218
|
+
groups.push(group);
|
|
219
|
+
}
|
|
220
|
+
group.tasks.push(task);
|
|
221
|
+
}
|
|
222
|
+
return groups;
|
|
223
|
+
}
|
|
224
|
+
function renderTaskGroup(group, runningTaskId) {
|
|
225
|
+
const title = group.title === undefined ? "" : `<h3>${escapeHtml(group.title)}</h3>`;
|
|
226
|
+
return `<section class="task-group">${title}${group.tasks.map((task) => renderTask(task, runningTaskId)).join("")}</section>`;
|
|
227
|
+
}
|
|
228
|
+
function renderTask(task, runningTaskId) {
|
|
229
|
+
const running = runningTaskId === task.id;
|
|
230
|
+
const disabled = runningTaskId !== undefined;
|
|
231
|
+
const description = task.description === undefined ? "" : `<span>${escapeHtml(task.description)}</span>`;
|
|
232
|
+
return `
|
|
233
|
+
<article class="task-card">
|
|
234
|
+
<div class="task-copy">
|
|
235
|
+
<strong>${escapeHtml(task.title)}</strong>
|
|
236
|
+
${description}
|
|
237
|
+
<code>${escapeHtml(task.command)}</code>
|
|
238
|
+
</div>
|
|
239
|
+
<button data-task-id="${escapeAttr(task.id)}" ${disabled ? "disabled" : ""}>${running ? "Dispatching…" : "Run"}</button>
|
|
240
|
+
</article>
|
|
241
|
+
`;
|
|
242
|
+
}
|
|
243
|
+
function taskFromConfigState(state, taskId) {
|
|
244
|
+
if (state?.kind !== "loaded" || taskId === null)
|
|
245
|
+
return undefined;
|
|
246
|
+
return state.config.tasks.find((task) => task.id === taskId);
|
|
247
|
+
}
|
|
248
|
+
function taskStyles() {
|
|
249
|
+
return `
|
|
250
|
+
<style>
|
|
251
|
+
:host { display: contents; }
|
|
252
|
+
.toolbar { display: flex; align-items: center; justify-content: space-between; gap: 8px; padding: 10px 12px; border-bottom: 1px solid var(--pi-border-muted); }
|
|
253
|
+
.toolbar-tasks { display: inline-flex; flex-wrap: wrap; justify-content: flex-end; gap: 8px; }
|
|
254
|
+
.viewer { box-sizing: border-box; min-height: 0; overflow: auto; padding: 12px; }
|
|
255
|
+
.tasks-viewer { display: grid; align-content: start; gap: 12px; }
|
|
256
|
+
.tasks { display: grid; gap: 14px; }
|
|
257
|
+
.task-group { display: grid; gap: 10px; }
|
|
258
|
+
.task-group h3 { margin: 4px 0 0; color: var(--pi-text-secondary); font-size: 13px; text-transform: uppercase; letter-spacing: 0.04em; }
|
|
259
|
+
.task-card { display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: 12px; align-items: center; border: 1px solid var(--pi-border); border-radius: 10px; background: var(--pi-surface); padding: 12px; }
|
|
260
|
+
.task-copy { display: grid; min-width: 0; gap: 5px; }
|
|
261
|
+
.task-copy span, .muted { color: var(--pi-muted); }
|
|
262
|
+
code, pre { border: 1px solid var(--pi-border-muted); border-radius: 6px; background: var(--pi-bg); color: var(--pi-text-secondary); font: 12px ui-monospace, SFMono-Regular, Menlo, Consolas, monospace; }
|
|
263
|
+
code { overflow: auto; padding: 5px 7px; white-space: nowrap; }
|
|
264
|
+
pre { margin: 8px 0 0; overflow: auto; padding: 8px; white-space: pre-wrap; }
|
|
265
|
+
button { border: 1px solid var(--pi-accent-border); border-radius: 7px; background: var(--pi-accent); color: var(--pi-bg); cursor: pointer; padding: 6px 10px; font: inherit; }
|
|
266
|
+
button.secondary { border-color: var(--pi-border); background: var(--pi-surface); color: var(--pi-text); }
|
|
267
|
+
button:disabled { cursor: wait; opacity: 0.65; }
|
|
268
|
+
.empty-state { border: 1px dashed var(--pi-border-muted); border-radius: 8px; color: var(--pi-muted); padding: 12px; }
|
|
269
|
+
.empty-state p { margin: 6px 0 0; }
|
|
270
|
+
.panel-status { margin: 12px 12px 0; }
|
|
271
|
+
.status { border: 1px solid var(--pi-border); border-radius: 8px; padding: 10px; }
|
|
272
|
+
.status.info { border-color: var(--pi-accent-border); background: var(--pi-bg-overlay-soft); }
|
|
273
|
+
.status.success { border-color: var(--pi-success-border); background: var(--pi-success-surface); color: var(--pi-success); }
|
|
274
|
+
.status.error { border-color: var(--pi-danger); color: var(--pi-danger); }
|
|
275
|
+
.empty { padding: 16px; color: var(--pi-muted); }
|
|
276
|
+
@media (max-width: 760px) {
|
|
277
|
+
.task-card { grid-template-columns: 1fr; }
|
|
278
|
+
.task-card button { justify-self: start; }
|
|
279
|
+
}
|
|
280
|
+
</style>
|
|
281
|
+
`;
|
|
282
|
+
}
|
|
283
|
+
function escapeHtml(value) {
|
|
284
|
+
return String(value).replaceAll("&", "&").replaceAll("<", "<").replaceAll(">", ">");
|
|
285
|
+
}
|
|
286
|
+
function escapeAttr(value) {
|
|
287
|
+
return escapeHtml(value).replaceAll('"', """);
|
|
288
|
+
}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
// Generated from pi-web-plugins/workspace-tasks/workspaceTasksClient.ts. Do not edit directly.
|
|
2
|
+
import { TASKS_CONFIG_PATH, parseTasksConfigText } from "./config.js";
|
|
3
|
+
export const tasksConfigMissingMessage = "No workspace tasks configured here.";
|
|
4
|
+
export const tasksConfigMissingHint = `${TASKS_CONFIG_PATH} is optional. Create it in this workspace if you want custom tasks.`;
|
|
5
|
+
export const tasksConfigUnavailableMessage = "Could not load workspace tasks.";
|
|
6
|
+
export const tasksConfigRefreshHint = `Fix ${TASKS_CONFIG_PATH}, then click Refresh.`;
|
|
7
|
+
const missingWorkspaceFileError = "Path does not exist";
|
|
8
|
+
export async function loadWorkspaceTasksConfig(files) {
|
|
9
|
+
let file;
|
|
10
|
+
try {
|
|
11
|
+
file = await files.readFile(TASKS_CONFIG_PATH);
|
|
12
|
+
}
|
|
13
|
+
catch (error) {
|
|
14
|
+
if (errorMessage(error) === missingWorkspaceFileError)
|
|
15
|
+
return missing();
|
|
16
|
+
return unavailable(`Unable to read ${TASKS_CONFIG_PATH}: ${formatUnknownError(error)}`);
|
|
17
|
+
}
|
|
18
|
+
if (file.binary)
|
|
19
|
+
return unavailable(`${TASKS_CONFIG_PATH} must be a text file`);
|
|
20
|
+
if (file.truncated)
|
|
21
|
+
return unavailable(`${TASKS_CONFIG_PATH} is too large and was truncated`);
|
|
22
|
+
const result = parseTasksConfigText(file.content);
|
|
23
|
+
if (!result.ok)
|
|
24
|
+
return unavailable(result.error);
|
|
25
|
+
return { kind: "loaded", config: result.config, path: TASKS_CONFIG_PATH };
|
|
26
|
+
}
|
|
27
|
+
function missing() {
|
|
28
|
+
return {
|
|
29
|
+
kind: "missing",
|
|
30
|
+
message: tasksConfigMissingMessage,
|
|
31
|
+
hint: tasksConfigMissingHint,
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
function unavailable(detail) {
|
|
35
|
+
return {
|
|
36
|
+
kind: "unavailable",
|
|
37
|
+
message: tasksConfigUnavailableMessage,
|
|
38
|
+
hint: tasksConfigRefreshHint,
|
|
39
|
+
detail,
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
function errorMessage(error) {
|
|
43
|
+
return error instanceof Error ? error.message : undefined;
|
|
44
|
+
}
|
|
45
|
+
function formatUnknownError(error) {
|
|
46
|
+
return error instanceof Error ? error.message : String(error);
|
|
47
|
+
}
|
|
@@ -0,0 +1,278 @@
|
|
|
1
|
+
import { readFileSync } from "node:fs";
|
|
2
|
+
import { dirname, join } from "node:path";
|
|
3
|
+
import { fileURLToPath } from "node:url";
|
|
4
|
+
import { effectivePiWebConfig } from "./config.js";
|
|
5
|
+
import { SessionDaemonClient } from "./sessiond/sessionDaemonClient.js";
|
|
6
|
+
import { parsePiWebComponentStatus, parsePiWebVersionResponse } from "./shared/piWebStatusParsing.js";
|
|
7
|
+
const PI_WEB_PACKAGE_NAME = "@vincenthanxiaodu/pi-web";
|
|
8
|
+
const PI_WEB_VERSION_TIMEOUT_MS = 2000;
|
|
9
|
+
const PI_WEB_VERSION_ENDPOINT_PATH = "/api/pi-web/version";
|
|
10
|
+
const PI_WEB_STATUS_ENDPOINT_PATH = "/api/pi-web/status";
|
|
11
|
+
const DEFAULT_PACKAGE_VERSION = "0.0.0-dev";
|
|
12
|
+
/**
|
|
13
|
+
* Readiness rule for `pi-web doctor`: an expected running component is ready
|
|
14
|
+
* only when the report carries its status and that status is available and not
|
|
15
|
+
* stale. A component missing from the report (an error-only entry) is not
|
|
16
|
+
* ready. Components that are not expected stay informational regardless of
|
|
17
|
+
* state.
|
|
18
|
+
*/
|
|
19
|
+
export function runningComponentsReady(info, expected) {
|
|
20
|
+
return expected.every((id) => {
|
|
21
|
+
const status = info[id];
|
|
22
|
+
return status !== undefined && status.available && !status.stale;
|
|
23
|
+
});
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Readiness probe for service lifecycle waits: the web component is ready when
|
|
27
|
+
* the web/API version endpoint (or its legacy status fallback) serves a
|
|
28
|
+
* parseable response; the session daemon is ready when its health endpoint
|
|
29
|
+
* serves version information. Shares the version report's endpoints and
|
|
30
|
+
* parsing so lifecycle readiness matches what `pi-web version` reports.
|
|
31
|
+
*/
|
|
32
|
+
export async function probeRunningComponentReady(component, options = {}) {
|
|
33
|
+
if (component === "sessiond") {
|
|
34
|
+
const sessiond = await collectRunningSessiondInfo();
|
|
35
|
+
return sessiond.component !== undefined;
|
|
36
|
+
}
|
|
37
|
+
const endpoint = webVersionEndpoint(options.configEnv);
|
|
38
|
+
if (endpoint.endpoint === undefined)
|
|
39
|
+
return false;
|
|
40
|
+
const fetchImplementation = options.fetch ?? globalThis.fetch;
|
|
41
|
+
try {
|
|
42
|
+
await fetchPiWebVersionResponse(endpoint.endpoint, fetchImplementation);
|
|
43
|
+
return true;
|
|
44
|
+
}
|
|
45
|
+
catch (error) {
|
|
46
|
+
const statusEndpoint = statusEndpointFor(endpoint.endpoint);
|
|
47
|
+
if (!isHttpNotFound(error) || statusEndpoint === endpoint.endpoint)
|
|
48
|
+
return false;
|
|
49
|
+
try {
|
|
50
|
+
await fetchPiWebVersionResponse(statusEndpoint, fetchImplementation);
|
|
51
|
+
return true;
|
|
52
|
+
}
|
|
53
|
+
catch {
|
|
54
|
+
return false;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
export function packageVersion() {
|
|
59
|
+
return readPackageInfo()?.version ?? DEFAULT_PACKAGE_VERSION;
|
|
60
|
+
}
|
|
61
|
+
export async function printPiWebVersionReport(options = {}) {
|
|
62
|
+
console.log("PI WEB version");
|
|
63
|
+
printInstalledPackageVersions();
|
|
64
|
+
const runningInfo = await collectRunningVersionInfo(options);
|
|
65
|
+
printRunningVersionInfo(runningInfo);
|
|
66
|
+
return runningInfo;
|
|
67
|
+
}
|
|
68
|
+
function packageRootPath() {
|
|
69
|
+
return dirname(dirname(fileURLToPath(import.meta.url)));
|
|
70
|
+
}
|
|
71
|
+
function packageJsonPath() {
|
|
72
|
+
return join(packageRootPath(), "package.json");
|
|
73
|
+
}
|
|
74
|
+
function readPackageInfo() {
|
|
75
|
+
const path = packageJsonPath();
|
|
76
|
+
try {
|
|
77
|
+
return parsePackageInfo(JSON.parse(readFileSync(path, "utf8")), path);
|
|
78
|
+
}
|
|
79
|
+
catch {
|
|
80
|
+
return undefined;
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
function parsePackageInfo(value, path) {
|
|
84
|
+
if (!isRecord(value))
|
|
85
|
+
return undefined;
|
|
86
|
+
const name = value["name"];
|
|
87
|
+
const version = value["version"];
|
|
88
|
+
if (typeof name !== "string" || name === "" || typeof version !== "string" || version === "")
|
|
89
|
+
return undefined;
|
|
90
|
+
return { name, version, path };
|
|
91
|
+
}
|
|
92
|
+
function webVersionEndpoint(configEnv) {
|
|
93
|
+
try {
|
|
94
|
+
const { config } = effectivePiWebConfig(configEnv === undefined ? {} : { env: configEnv });
|
|
95
|
+
const host = httpClientHost(config.host);
|
|
96
|
+
const port = config.port ?? 8504;
|
|
97
|
+
return { endpoint: `http://${urlHost(host)}:${String(port)}${PI_WEB_VERSION_ENDPOINT_PATH}` };
|
|
98
|
+
}
|
|
99
|
+
catch (error) {
|
|
100
|
+
return { error: `could not read PI WEB config: ${errorMessage(error)}` };
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
function httpClientHost(configuredHost) {
|
|
104
|
+
const host = configuredHost === undefined || configuredHost === "" ? "127.0.0.1" : configuredHost;
|
|
105
|
+
if (host === "0.0.0.0" || host === "::" || host === "[::]")
|
|
106
|
+
return "127.0.0.1";
|
|
107
|
+
return host;
|
|
108
|
+
}
|
|
109
|
+
function urlHost(host) {
|
|
110
|
+
if (host.startsWith("[") || !host.includes(":"))
|
|
111
|
+
return host;
|
|
112
|
+
return `[${host}]`;
|
|
113
|
+
}
|
|
114
|
+
function statusEndpointFor(versionEndpoint) {
|
|
115
|
+
if (!versionEndpoint.endsWith(PI_WEB_VERSION_ENDPOINT_PATH))
|
|
116
|
+
return versionEndpoint;
|
|
117
|
+
return `${versionEndpoint.slice(0, -PI_WEB_VERSION_ENDPOINT_PATH.length)}${PI_WEB_STATUS_ENDPOINT_PATH}`;
|
|
118
|
+
}
|
|
119
|
+
async function fetchPiWebVersionResponse(endpoint, fetchImplementation) {
|
|
120
|
+
const response = await fetchImplementation(endpoint, {
|
|
121
|
+
headers: { accept: "application/json" },
|
|
122
|
+
signal: AbortSignal.timeout(PI_WEB_VERSION_TIMEOUT_MS),
|
|
123
|
+
});
|
|
124
|
+
if (!response.ok)
|
|
125
|
+
throw new Error(`HTTP ${String(response.status)}`);
|
|
126
|
+
const parsed = await response.json();
|
|
127
|
+
const status = parsePiWebVersionResponse(parsed);
|
|
128
|
+
if (status === undefined)
|
|
129
|
+
throw new Error("response did not include PI WEB version information");
|
|
130
|
+
return status;
|
|
131
|
+
}
|
|
132
|
+
async function collectRunningVersionInfo(options) {
|
|
133
|
+
const endpoint = options.webEndpointError === undefined
|
|
134
|
+
? webVersionEndpoint(options.configEnv)
|
|
135
|
+
: { error: options.webEndpointError };
|
|
136
|
+
const fetchImplementation = options.fetch ?? globalThis.fetch;
|
|
137
|
+
if (endpoint.endpoint !== undefined) {
|
|
138
|
+
try {
|
|
139
|
+
const status = await fetchPiWebVersionResponse(endpoint.endpoint, fetchImplementation);
|
|
140
|
+
return { generatedAt: status.generatedAt, web: status.components.web, sessiond: status.components.sessiond };
|
|
141
|
+
}
|
|
142
|
+
catch (error) {
|
|
143
|
+
let webError = `${endpoint.endpoint}: ${errorMessage(error)}`;
|
|
144
|
+
const statusEndpoint = statusEndpointFor(endpoint.endpoint);
|
|
145
|
+
if (statusEndpoint !== endpoint.endpoint && isHttpNotFound(error)) {
|
|
146
|
+
try {
|
|
147
|
+
const status = await fetchPiWebVersionResponse(statusEndpoint, fetchImplementation);
|
|
148
|
+
return { generatedAt: status.generatedAt, web: status.components.web, sessiond: status.components.sessiond };
|
|
149
|
+
}
|
|
150
|
+
catch (statusError) {
|
|
151
|
+
webError = `${webError}; ${statusEndpoint}: ${errorMessage(statusError)}`;
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
return runningVersionInfoWithSessiondFallback({ webError });
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
return runningVersionInfoWithSessiondFallback({ webError: endpoint.error ?? "web/API status endpoint unavailable" });
|
|
158
|
+
}
|
|
159
|
+
async function runningVersionInfoWithSessiondFallback(base) {
|
|
160
|
+
const sessiond = await collectRunningSessiondInfo();
|
|
161
|
+
return {
|
|
162
|
+
webError: base.webError,
|
|
163
|
+
...(sessiond.component === undefined ? {} : { sessiond: sessiond.component }),
|
|
164
|
+
...(sessiond.error === undefined ? {} : { sessiondError: sessiond.error }),
|
|
165
|
+
};
|
|
166
|
+
}
|
|
167
|
+
async function collectRunningSessiondInfo() {
|
|
168
|
+
try {
|
|
169
|
+
const response = await withTimeout(new SessionDaemonClient().request("GET", "/health"), PI_WEB_VERSION_TIMEOUT_MS, "session daemon health check timed out");
|
|
170
|
+
if (response.statusCode < 200 || response.statusCode >= 300)
|
|
171
|
+
throw new Error(`HTTP ${String(response.statusCode)}`);
|
|
172
|
+
const parsed = response.body === "" ? undefined : JSON.parse(response.body);
|
|
173
|
+
const version = isRecord(parsed) ? parsed["version"] : undefined;
|
|
174
|
+
const component = parsePiWebComponentStatus(version);
|
|
175
|
+
if (component === undefined)
|
|
176
|
+
throw new Error("health response did not include version information");
|
|
177
|
+
return { component };
|
|
178
|
+
}
|
|
179
|
+
catch (error) {
|
|
180
|
+
return { error: errorMessage(error) };
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
async function withTimeout(promise, timeoutMs, timeoutMessage) {
|
|
184
|
+
let timeout;
|
|
185
|
+
try {
|
|
186
|
+
return await Promise.race([
|
|
187
|
+
promise,
|
|
188
|
+
new Promise((_, reject) => {
|
|
189
|
+
timeout = setTimeout(() => {
|
|
190
|
+
reject(new Error(timeoutMessage));
|
|
191
|
+
}, timeoutMs);
|
|
192
|
+
}),
|
|
193
|
+
]);
|
|
194
|
+
}
|
|
195
|
+
finally {
|
|
196
|
+
if (timeout !== undefined)
|
|
197
|
+
clearTimeout(timeout);
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
function isHttpNotFound(error) {
|
|
201
|
+
return error instanceof Error && error.message === "HTTP 404";
|
|
202
|
+
}
|
|
203
|
+
function printInstalledPackageVersions() {
|
|
204
|
+
const info = readPackageInfo();
|
|
205
|
+
console.log("Installed packages:");
|
|
206
|
+
if (info === undefined) {
|
|
207
|
+
console.log(`? ${PI_WEB_PACKAGE_NAME}: unknown`);
|
|
208
|
+
console.log(` missing package metadata: ${packageJsonPath()}`);
|
|
209
|
+
return;
|
|
210
|
+
}
|
|
211
|
+
console.log(`✓ ${info.name}: ${info.version}`);
|
|
212
|
+
console.log(` ${info.path}`);
|
|
213
|
+
}
|
|
214
|
+
function printRunningVersionInfo(info) {
|
|
215
|
+
console.log("Running services:");
|
|
216
|
+
if (info.web === undefined)
|
|
217
|
+
printUnavailableComponent("Web/UI", info.webError);
|
|
218
|
+
else
|
|
219
|
+
printComponentVersion(info.web);
|
|
220
|
+
if (info.sessiond === undefined)
|
|
221
|
+
printUnavailableComponent("Session daemon", info.sessiondError);
|
|
222
|
+
else
|
|
223
|
+
printComponentVersion(info.sessiond);
|
|
224
|
+
if (info.generatedAt !== undefined)
|
|
225
|
+
console.log(` reported by web/API at ${info.generatedAt}`);
|
|
226
|
+
}
|
|
227
|
+
function printComponentVersion(component) {
|
|
228
|
+
const icon = component.available ? component.stale ? "!" : "✓" : "?";
|
|
229
|
+
const status = !component.available ? "unavailable" : component.stale ? "restart needed" : "current";
|
|
230
|
+
console.log(`${icon} ${component.label}: ${status}`);
|
|
231
|
+
if (component.available || component.runtimeVersion !== undefined || component.installedVersion !== undefined) {
|
|
232
|
+
console.log(` running: ${formatVersion(component.runtimeVersion)}; installed: ${formatVersion(component.installedVersion)}`);
|
|
233
|
+
}
|
|
234
|
+
if (component.piVersion !== undefined)
|
|
235
|
+
console.log(` pi: ${component.piVersion}`);
|
|
236
|
+
const installation = installationLabel(component.installation);
|
|
237
|
+
if (installation !== undefined)
|
|
238
|
+
console.log(` installation: ${installation}`);
|
|
239
|
+
if (component.error !== undefined)
|
|
240
|
+
console.log(` ${component.error}`);
|
|
241
|
+
}
|
|
242
|
+
function printUnavailableComponent(label, error) {
|
|
243
|
+
console.log(`? ${label}: unavailable`);
|
|
244
|
+
if (error !== undefined && error !== "")
|
|
245
|
+
console.log(` ${error}`);
|
|
246
|
+
}
|
|
247
|
+
function installationLabel(installation) {
|
|
248
|
+
if (installation === undefined)
|
|
249
|
+
return undefined;
|
|
250
|
+
if (installation.kind === "pi-package") {
|
|
251
|
+
const source = installation.source ?? "Pi package";
|
|
252
|
+
const scope = installation.scope === undefined ? "" : ` · ${installation.scope}`;
|
|
253
|
+
const path = installation.path === undefined ? "" : ` · ${installation.path}`;
|
|
254
|
+
return `${source}${scope}${path}`;
|
|
255
|
+
}
|
|
256
|
+
if (installation.kind === "npm-global") {
|
|
257
|
+
const npmRoot = installation.npmRoot === undefined ? "" : ` · ${installation.npmRoot}`;
|
|
258
|
+
const path = installation.path === undefined ? "" : ` · ${installation.path}`;
|
|
259
|
+
return `global npm package${npmRoot}${path}`;
|
|
260
|
+
}
|
|
261
|
+
if (installation.kind === "local")
|
|
262
|
+
return installation.path === undefined ? "local checkout" : `local checkout · ${installation.path}`;
|
|
263
|
+
if (installation.kind === "docker") {
|
|
264
|
+
const mode = installation.dockerMode === "dev" ? "Docker development runtime" : "Docker runtime";
|
|
265
|
+
return installation.path === undefined ? mode : `${mode} · ${installation.path}`;
|
|
266
|
+
}
|
|
267
|
+
return installation.path === undefined ? "installation unknown" : `installation unknown · ${installation.path}`;
|
|
268
|
+
}
|
|
269
|
+
function formatVersion(version) {
|
|
270
|
+
return version === undefined || version === "" ? "unknown" : version;
|
|
271
|
+
}
|
|
272
|
+
function errorMessage(error) {
|
|
273
|
+
return error instanceof Error ? error.message : String(error);
|
|
274
|
+
}
|
|
275
|
+
function isRecord(value) {
|
|
276
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
277
|
+
}
|
|
278
|
+
//# sourceMappingURL=piWebVersionReport.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"piWebVersionReport.js","sourceRoot":"","sources":["../src/piWebVersionReport.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACvC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAC1C,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AACzC,OAAO,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAC;AACnD,OAAO,EAAE,mBAAmB,EAAE,MAAM,mCAAmC,CAAC;AAExE,OAAO,EAAE,yBAAyB,EAAE,yBAAyB,EAAE,MAAM,gCAAgC,CAAC;AAEtG,MAAM,mBAAmB,GAAG,0BAA0B,CAAC;AACvD,MAAM,yBAAyB,GAAG,IAAI,CAAC;AACvC,MAAM,4BAA4B,GAAG,qBAAqB,CAAC;AAC3D,MAAM,2BAA2B,GAAG,oBAAoB,CAAC;AACzD,MAAM,uBAAuB,GAAG,WAAW,CAAC;AA2B5C;;;;;;GAMG;AACH,MAAM,UAAU,sBAAsB,CAAC,IAAwB,EAAE,QAAuC;IACtG,OAAO,QAAQ,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,EAAE;QAC3B,MAAM,MAAM,GAAG,IAAI,CAAC,EAAE,CAAC,CAAC;QACxB,OAAO,MAAM,KAAK,SAAS,IAAI,MAAM,CAAC,SAAS,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC;IACnE,CAAC,CAAC,CAAC;AACL,CAAC;AAED;;;;;;GAMG;AACH,MAAM,CAAC,KAAK,UAAU,0BAA0B,CAC9C,SAA6B,EAC7B,UAAkE,EAAE;IAEpE,IAAI,SAAS,KAAK,UAAU,EAAE,CAAC;QAC7B,MAAM,QAAQ,GAAG,MAAM,0BAA0B,EAAE,CAAC;QACpD,OAAO,QAAQ,CAAC,SAAS,KAAK,SAAS,CAAC;IAC1C,CAAC;IACD,MAAM,QAAQ,GAAG,kBAAkB,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;IACvD,IAAI,QAAQ,CAAC,QAAQ,KAAK,SAAS;QAAE,OAAO,KAAK,CAAC;IAClD,MAAM,mBAAmB,GAAG,OAAO,CAAC,KAAK,IAAI,UAAU,CAAC,KAAK,CAAC;IAC9D,IAAI,CAAC;QACH,MAAM,yBAAyB,CAAC,QAAQ,CAAC,QAAQ,EAAE,mBAAmB,CAAC,CAAC;QACxE,OAAO,IAAI,CAAC;IACd,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,cAAc,GAAG,iBAAiB,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;QAC5D,IAAI,CAAC,cAAc,CAAC,KAAK,CAAC,IAAI,cAAc,KAAK,QAAQ,CAAC,QAAQ;YAAE,OAAO,KAAK,CAAC;QACjF,IAAI,CAAC;YACH,MAAM,yBAAyB,CAAC,cAAc,EAAE,mBAAmB,CAAC,CAAC;YACrE,OAAO,IAAI,CAAC;QACd,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,KAAK,CAAC;QACf,CAAC;IACH,CAAC;AACH,CAAC;AAED,MAAM,UAAU,cAAc;IAC5B,OAAO,eAAe,EAAE,EAAE,OAAO,IAAI,uBAAuB,CAAC;AAC/D,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,uBAAuB,CAAC,UAAqC,EAAE;IACnF,OAAO,CAAC,GAAG,CAAC,gBAAgB,CAAC,CAAC;IAC9B,6BAA6B,EAAE,CAAC;IAChC,MAAM,WAAW,GAAG,MAAM,yBAAyB,CAAC,OAAO,CAAC,CAAC;IAC7D,uBAAuB,CAAC,WAAW,CAAC,CAAC;IACrC,OAAO,WAAW,CAAC;AACrB,CAAC;AAED,SAAS,eAAe;IACtB,OAAO,OAAO,CAAC,OAAO,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;AAC1D,CAAC;AAED,SAAS,eAAe;IACtB,OAAO,IAAI,CAAC,eAAe,EAAE,EAAE,cAAc,CAAC,CAAC;AACjD,CAAC;AAED,SAAS,eAAe;IACtB,MAAM,IAAI,GAAG,eAAe,EAAE,CAAC;IAC/B,IAAI,CAAC;QACH,OAAO,gBAAgB,CAAC,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC;IACxE,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,SAAS,CAAC;IACnB,CAAC;AACH,CAAC;AAED,SAAS,gBAAgB,CAAC,KAAc,EAAE,IAAY;IACpD,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC;QAAE,OAAO,SAAS,CAAC;IACvC,MAAM,IAAI,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC;IAC3B,MAAM,OAAO,GAAG,KAAK,CAAC,SAAS,CAAC,CAAC;IACjC,IAAI,OAAO,IAAI,KAAK,QAAQ,IAAI,IAAI,KAAK,EAAE,IAAI,OAAO,OAAO,KAAK,QAAQ,IAAI,OAAO,KAAK,EAAE;QAAE,OAAO,SAAS,CAAC;IAC/G,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;AACjC,CAAC;AAED,SAAS,kBAAkB,CAAC,SAAwC;IAClE,IAAI,CAAC;QACH,MAAM,EAAE,MAAM,EAAE,GAAG,oBAAoB,CAAC,SAAS,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,GAAG,EAAE,SAAS,EAAE,CAAC,CAAC;QAC3F,MAAM,IAAI,GAAG,cAAc,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;QACzC,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,IAAI,IAAI,CAAC;QACjC,OAAO,EAAE,QAAQ,EAAE,UAAU,OAAO,CAAC,IAAI,CAAC,IAAI,MAAM,CAAC,IAAI,CAAC,GAAG,4BAA4B,EAAE,EAAE,CAAC;IAChG,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO,EAAE,KAAK,EAAE,iCAAiC,YAAY,CAAC,KAAK,CAAC,EAAE,EAAE,CAAC;IAC3E,CAAC;AACH,CAAC;AAED,SAAS,cAAc,CAAC,cAAkC;IACxD,MAAM,IAAI,GAAG,cAAc,KAAK,SAAS,IAAI,cAAc,KAAK,EAAE,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,cAAc,CAAC;IAClG,IAAI,IAAI,KAAK,SAAS,IAAI,IAAI,KAAK,IAAI,IAAI,IAAI,KAAK,MAAM;QAAE,OAAO,WAAW,CAAC;IAC/E,OAAO,IAAI,CAAC;AACd,CAAC;AAED,SAAS,OAAO,CAAC,IAAY;IAC3B,IAAI,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC;QAAE,OAAO,IAAI,CAAC;IAC7D,OAAO,IAAI,IAAI,GAAG,CAAC;AACrB,CAAC;AAED,SAAS,iBAAiB,CAAC,eAAuB;IAChD,IAAI,CAAC,eAAe,CAAC,QAAQ,CAAC,4BAA4B,CAAC;QAAE,OAAO,eAAe,CAAC;IACpF,OAAO,GAAG,eAAe,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,4BAA4B,CAAC,MAAM,CAAC,GAAG,2BAA2B,EAAE,CAAC;AAC3G,CAAC;AAED,KAAK,UAAU,yBAAyB,CACtC,QAAgB,EAChB,mBAA4C;IAE5C,MAAM,QAAQ,GAAG,MAAM,mBAAmB,CAAC,QAAQ,EAAE;QACnD,OAAO,EAAE,EAAE,MAAM,EAAE,kBAAkB,EAAE;QACvC,MAAM,EAAE,WAAW,CAAC,OAAO,CAAC,yBAAyB,CAAC;KACvD,CAAC,CAAC;IACH,IAAI,CAAC,QAAQ,CAAC,EAAE;QAAE,MAAM,IAAI,KAAK,CAAC,QAAQ,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;IACrE,MAAM,MAAM,GAAY,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC;IAC9C,MAAM,MAAM,GAAG,yBAAyB,CAAC,MAAM,CAAC,CAAC;IACjD,IAAI,MAAM,KAAK,SAAS;QAAE,MAAM,IAAI,KAAK,CAAC,qDAAqD,CAAC,CAAC;IACjG,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,KAAK,UAAU,yBAAyB,CAAC,OAAkC;IACzE,MAAM,QAAQ,GAAG,OAAO,CAAC,gBAAgB,KAAK,SAAS;QACrD,CAAC,CAAC,kBAAkB,CAAC,OAAO,CAAC,SAAS,CAAC;QACvC,CAAC,CAAC,EAAE,KAAK,EAAE,OAAO,CAAC,gBAAgB,EAAE,CAAC;IACxC,MAAM,mBAAmB,GAAG,OAAO,CAAC,KAAK,IAAI,UAAU,CAAC,KAAK,CAAC;IAC9D,IAAI,QAAQ,CAAC,QAAQ,KAAK,SAAS,EAAE,CAAC;QACpC,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,MAAM,yBAAyB,CAAC,QAAQ,CAAC,QAAQ,EAAE,mBAAmB,CAAC,CAAC;YACvF,OAAO,EAAE,WAAW,EAAE,MAAM,CAAC,WAAW,EAAE,GAAG,EAAE,MAAM,CAAC,UAAU,CAAC,GAAG,EAAE,QAAQ,EAAE,MAAM,CAAC,UAAU,CAAC,QAAQ,EAAE,CAAC;QAC/G,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,IAAI,QAAQ,GAAG,GAAG,QAAQ,CAAC,QAAQ,KAAK,YAAY,CAAC,KAAK,CAAC,EAAE,CAAC;YAC9D,MAAM,cAAc,GAAG,iBAAiB,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;YAC5D,IAAI,cAAc,KAAK,QAAQ,CAAC,QAAQ,IAAI,cAAc,CAAC,KAAK,CAAC,EAAE,CAAC;gBAClE,IAAI,CAAC;oBACH,MAAM,MAAM,GAAG,MAAM,yBAAyB,CAAC,cAAc,EAAE,mBAAmB,CAAC,CAAC;oBACpF,OAAO,EAAE,WAAW,EAAE,MAAM,CAAC,WAAW,EAAE,GAAG,EAAE,MAAM,CAAC,UAAU,CAAC,GAAG,EAAE,QAAQ,EAAE,MAAM,CAAC,UAAU,CAAC,QAAQ,EAAE,CAAC;gBAC/G,CAAC;gBAAC,OAAO,WAAW,EAAE,CAAC;oBACrB,QAAQ,GAAG,GAAG,QAAQ,KAAK,cAAc,KAAK,YAAY,CAAC,WAAW,CAAC,EAAE,CAAC;gBAC5E,CAAC;YACH,CAAC;YACD,OAAO,sCAAsC,CAAC,EAAE,QAAQ,EAAE,CAAC,CAAC;QAC9D,CAAC;IACH,CAAC;IAED,OAAO,sCAAsC,CAAC,EAAE,QAAQ,EAAE,QAAQ,CAAC,KAAK,IAAI,qCAAqC,EAAE,CAAC,CAAC;AACvH,CAAC;AAED,KAAK,UAAU,sCAAsC,CAAC,IAA0B;IAC9E,MAAM,QAAQ,GAAG,MAAM,0BAA0B,EAAE,CAAC;IACpD,OAAO;QACL,QAAQ,EAAE,IAAI,CAAC,QAAQ;QACvB,GAAG,CAAC,QAAQ,CAAC,SAAS,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,QAAQ,CAAC,SAAS,EAAE,CAAC;QAC7E,GAAG,CAAC,QAAQ,CAAC,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,aAAa,EAAE,QAAQ,CAAC,KAAK,EAAE,CAAC;KAC3E,CAAC;AACJ,CAAC;AAED,KAAK,UAAU,0BAA0B;IACvC,IAAI,CAAC;QACH,MAAM,QAAQ,GAAG,MAAM,WAAW,CAChC,IAAI,mBAAmB,EAAE,CAAC,OAAO,CAAC,KAAK,EAAE,SAAS,CAAC,EACnD,yBAAyB,EACzB,uCAAuC,CACxC,CAAC;QACF,IAAI,QAAQ,CAAC,UAAU,GAAG,GAAG,IAAI,QAAQ,CAAC,UAAU,IAAI,GAAG;YAAE,MAAM,IAAI,KAAK,CAAC,QAAQ,MAAM,CAAC,QAAQ,CAAC,UAAU,CAAC,EAAE,CAAC,CAAC;QACpH,MAAM,MAAM,GAAY,QAAQ,CAAC,IAAI,KAAK,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;QACrF,MAAM,OAAO,GAAG,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;QACjE,MAAM,SAAS,GAAG,yBAAyB,CAAC,OAAO,CAAC,CAAC;QACrD,IAAI,SAAS,KAAK,SAAS;YAAE,MAAM,IAAI,KAAK,CAAC,qDAAqD,CAAC,CAAC;QACpG,OAAO,EAAE,SAAS,EAAE,CAAC;IACvB,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO,EAAE,KAAK,EAAE,YAAY,CAAC,KAAK,CAAC,EAAE,CAAC;IACxC,CAAC;AACH,CAAC;AAED,KAAK,UAAU,WAAW,CAAI,OAAmB,EAAE,SAAiB,EAAE,cAAsB;IAC1F,IAAI,OAAkD,CAAC;IACvD,IAAI,CAAC;QACH,OAAO,MAAM,OAAO,CAAC,IAAI,CAAC;YACxB,OAAO;YACP,IAAI,OAAO,CAAI,CAAC,CAAC,EAAE,MAAM,EAAE,EAAE;gBAC3B,OAAO,GAAG,UAAU,CAAC,GAAG,EAAE;oBACxB,MAAM,CAAC,IAAI,KAAK,CAAC,cAAc,CAAC,CAAC,CAAC;gBACpC,CAAC,EAAE,SAAS,CAAC,CAAC;YAChB,CAAC,CAAC;SACH,CAAC,CAAC;IACL,CAAC;YAAS,CAAC;QACT,IAAI,OAAO,KAAK,SAAS;YAAE,YAAY,CAAC,OAAO,CAAC,CAAC;IACnD,CAAC;AACH,CAAC;AAED,SAAS,cAAc,CAAC,KAAc;IACpC,OAAO,KAAK,YAAY,KAAK,IAAI,KAAK,CAAC,OAAO,KAAK,UAAU,CAAC;AAChE,CAAC;AAED,SAAS,6BAA6B;IACpC,MAAM,IAAI,GAAG,eAAe,EAAE,CAAC;IAC/B,OAAO,CAAC,GAAG,CAAC,qBAAqB,CAAC,CAAC;IACnC,IAAI,IAAI,KAAK,SAAS,EAAE,CAAC;QACvB,OAAO,CAAC,GAAG,CAAC,KAAK,mBAAmB,WAAW,CAAC,CAAC;QACjD,OAAO,CAAC,GAAG,CAAC,+BAA+B,eAAe,EAAE,EAAE,CAAC,CAAC;QAChE,OAAO;IACT,CAAC;IACD,OAAO,CAAC,GAAG,CAAC,KAAK,IAAI,CAAC,IAAI,KAAK,IAAI,CAAC,OAAO,EAAE,CAAC,CAAC;IAC/C,OAAO,CAAC,GAAG,CAAC,KAAK,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC;AAChC,CAAC;AAED,SAAS,uBAAuB,CAAC,IAAwB;IACvD,OAAO,CAAC,GAAG,CAAC,mBAAmB,CAAC,CAAC;IACjC,IAAI,IAAI,CAAC,GAAG,KAAK,SAAS;QAAE,yBAAyB,CAAC,QAAQ,EAAE,IAAI,CAAC,QAAQ,CAAC,CAAC;;QAC1E,qBAAqB,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IACrC,IAAI,IAAI,CAAC,QAAQ,KAAK,SAAS;QAAE,yBAAyB,CAAC,gBAAgB,EAAE,IAAI,CAAC,aAAa,CAAC,CAAC;;QAC5F,qBAAqB,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;IAC1C,IAAI,IAAI,CAAC,WAAW,KAAK,SAAS;QAAE,OAAO,CAAC,GAAG,CAAC,4BAA4B,IAAI,CAAC,WAAW,EAAE,CAAC,CAAC;AAClG,CAAC;AAED,SAAS,qBAAqB,CAAC,SAA+B;IAC5D,MAAM,IAAI,GAAG,SAAS,CAAC,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC;IACrE,MAAM,MAAM,GAAG,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,CAAC,gBAAgB,CAAC,CAAC,CAAC,SAAS,CAAC;IACrG,OAAO,CAAC,GAAG,CAAC,GAAG,IAAI,IAAI,SAAS,CAAC,KAAK,KAAK,MAAM,EAAE,CAAC,CAAC;IACrD,IAAI,SAAS,CAAC,SAAS,IAAI,SAAS,CAAC,cAAc,KAAK,SAAS,IAAI,SAAS,CAAC,gBAAgB,KAAK,SAAS,EAAE,CAAC;QAC9G,OAAO,CAAC,GAAG,CAAC,cAAc,aAAa,CAAC,SAAS,CAAC,cAAc,CAAC,gBAAgB,aAAa,CAAC,SAAS,CAAC,gBAAgB,CAAC,EAAE,CAAC,CAAC;IAChI,CAAC;IACD,IAAI,SAAS,CAAC,SAAS,KAAK,SAAS;QAAE,OAAO,CAAC,GAAG,CAAC,SAAS,SAAS,CAAC,SAAS,EAAE,CAAC,CAAC;IACnF,MAAM,YAAY,GAAG,iBAAiB,CAAC,SAAS,CAAC,YAAY,CAAC,CAAC;IAC/D,IAAI,YAAY,KAAK,SAAS;QAAE,OAAO,CAAC,GAAG,CAAC,mBAAmB,YAAY,EAAE,CAAC,CAAC;IAC/E,IAAI,SAAS,CAAC,KAAK,KAAK,SAAS;QAAE,OAAO,CAAC,GAAG,CAAC,KAAK,SAAS,CAAC,KAAK,EAAE,CAAC,CAAC;AACzE,CAAC;AAED,SAAS,yBAAyB,CAAC,KAAa,EAAE,KAAyB;IACzE,OAAO,CAAC,GAAG,CAAC,KAAK,KAAK,eAAe,CAAC,CAAC;IACvC,IAAI,KAAK,KAAK,SAAS,IAAI,KAAK,KAAK,EAAE;QAAE,OAAO,CAAC,GAAG,CAAC,KAAK,KAAK,EAAE,CAAC,CAAC;AACrE,CAAC;AAED,SAAS,iBAAiB,CAAC,YAA+C;IACxE,IAAI,YAAY,KAAK,SAAS;QAAE,OAAO,SAAS,CAAC;IACjD,IAAI,YAAY,CAAC,IAAI,KAAK,YAAY,EAAE,CAAC;QACvC,MAAM,MAAM,GAAG,YAAY,CAAC,MAAM,IAAI,YAAY,CAAC;QACnD,MAAM,KAAK,GAAG,YAAY,CAAC,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,YAAY,CAAC,KAAK,EAAE,CAAC;QACjF,MAAM,IAAI,GAAG,YAAY,CAAC,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,YAAY,CAAC,IAAI,EAAE,CAAC;QAC9E,OAAO,GAAG,MAAM,GAAG,KAAK,GAAG,IAAI,EAAE,CAAC;IACpC,CAAC;IACD,IAAI,YAAY,CAAC,IAAI,KAAK,YAAY,EAAE,CAAC;QACvC,MAAM,OAAO,GAAG,YAAY,CAAC,OAAO,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,YAAY,CAAC,OAAO,EAAE,CAAC;QACvF,MAAM,IAAI,GAAG,YAAY,CAAC,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,YAAY,CAAC,IAAI,EAAE,CAAC;QAC9E,OAAO,qBAAqB,OAAO,GAAG,IAAI,EAAE,CAAC;IAC/C,CAAC;IACD,IAAI,YAAY,CAAC,IAAI,KAAK,OAAO;QAAE,OAAO,YAAY,CAAC,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,gBAAgB,CAAC,CAAC,CAAC,oBAAoB,YAAY,CAAC,IAAI,EAAE,CAAC;IACvI,IAAI,YAAY,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;QACnC,MAAM,IAAI,GAAG,YAAY,CAAC,UAAU,KAAK,KAAK,CAAC,CAAC,CAAC,4BAA4B,CAAC,CAAC,CAAC,gBAAgB,CAAC;QACjG,OAAO,YAAY,CAAC,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,IAAI,MAAM,YAAY,CAAC,IAAI,EAAE,CAAC;IACnF,CAAC;IACD,OAAO,YAAY,CAAC,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,sBAAsB,CAAC,CAAC,CAAC,0BAA0B,YAAY,CAAC,IAAI,EAAE,CAAC;AAClH,CAAC;AAED,SAAS,aAAa,CAAC,OAA2B;IAChD,OAAO,OAAO,KAAK,SAAS,IAAI,OAAO,KAAK,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,OAAO,CAAC;AACvE,CAAC;AAED,SAAS,YAAY,CAAC,KAAc;IAClC,OAAO,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;AAChE,CAAC;AAED,SAAS,QAAQ,CAAC,KAAc;IAC9B,OAAO,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;AAC9E,CAAC"}
|