@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,48 @@
|
|
|
1
|
+
import { spawn } from "node:child_process";
|
|
2
|
+
function systemdRunnerAvailable() {
|
|
3
|
+
// A Docker deployment has no systemd user session, and the container image
|
|
4
|
+
// does not always set CONTAINER. Reporting "restart started" there was worse
|
|
5
|
+
// than reporting nothing: the caller was told work had begun that could never
|
|
6
|
+
// happen, and a fleet report inherited the same false claim for that machine.
|
|
7
|
+
if (isTruthyEnv("PI_WEB_DOCKER_RUNTIME"))
|
|
8
|
+
return false;
|
|
9
|
+
return process.env["CONTAINER"] === undefined || process.env["CONTAINER"] === "";
|
|
10
|
+
}
|
|
11
|
+
function isTruthyEnv(key) {
|
|
12
|
+
const value = process.env[key];
|
|
13
|
+
return value !== undefined && value !== "" && value !== "0" && value.toLowerCase() !== "false";
|
|
14
|
+
}
|
|
15
|
+
export function createRestartService(logger) {
|
|
16
|
+
return {
|
|
17
|
+
restartSupported() {
|
|
18
|
+
return systemdRunnerAvailable();
|
|
19
|
+
},
|
|
20
|
+
async restart() {
|
|
21
|
+
if (!systemdRunnerAvailable())
|
|
22
|
+
throw new Error("Detached restart is unavailable on this host (no systemd user session)");
|
|
23
|
+
const runner = spawn("systemd-run", ["--user", "--collect", "--unit=pi-web-restart", "--", "systemctl", "--user", "restart", "pi-web-sessiond", "pi-web"], {
|
|
24
|
+
detached: true,
|
|
25
|
+
stdio: "ignore",
|
|
26
|
+
});
|
|
27
|
+
runner.unref();
|
|
28
|
+
// Surface an immediate fork failure (missing systemd-run) synchronously.
|
|
29
|
+
await new Promise((resolve) => {
|
|
30
|
+
runner.once("error", (error) => { logger?.warn({ err: error }, "systemd-run failed to start restart"); resolve(); });
|
|
31
|
+
runner.once("spawn", () => { resolve(); });
|
|
32
|
+
});
|
|
33
|
+
},
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
export function registerRestartRoutes(app, deps = {}) {
|
|
37
|
+
const service = deps.restart ?? createRestartService(app.log);
|
|
38
|
+
app.post("/api/pi-web/restart", async (_request, reply) => {
|
|
39
|
+
try {
|
|
40
|
+
await service.restart();
|
|
41
|
+
return await reply.code(202).send({ started: true });
|
|
42
|
+
}
|
|
43
|
+
catch (error) {
|
|
44
|
+
return reply.code(400).send({ started: false, error: error instanceof Error ? error.message : String(error) });
|
|
45
|
+
}
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
//# sourceMappingURL=restartRoutes.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"restartRoutes.js","sourceRoot":"","sources":["../../../src/server/updates/restartRoutes.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,EAAE,MAAM,oBAAoB,CAAC;AAmB3C,SAAS,sBAAsB;IAC7B,2EAA2E;IAC3E,6EAA6E;IAC7E,8EAA8E;IAC9E,8EAA8E;IAC9E,IAAI,WAAW,CAAC,uBAAuB,CAAC;QAAE,OAAO,KAAK,CAAC;IACvD,OAAO,OAAO,CAAC,GAAG,CAAC,WAAW,CAAC,KAAK,SAAS,IAAI,OAAO,CAAC,GAAG,CAAC,WAAW,CAAC,KAAK,EAAE,CAAC;AACnF,CAAC;AAED,SAAS,WAAW,CAAC,GAAW;IAC9B,MAAM,KAAK,GAAG,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IAC/B,OAAO,KAAK,KAAK,SAAS,IAAI,KAAK,KAAK,EAAE,IAAI,KAAK,KAAK,GAAG,IAAI,KAAK,CAAC,WAAW,EAAE,KAAK,OAAO,CAAC;AACjG,CAAC;AAED,MAAM,UAAU,oBAAoB,CAAC,MAAiE;IACpG,OAAO;QACL,gBAAgB;YACd,OAAO,sBAAsB,EAAE,CAAC;QAClC,CAAC;QACD,KAAK,CAAC,OAAO;YACX,IAAI,CAAC,sBAAsB,EAAE;gBAAE,MAAM,IAAI,KAAK,CAAC,wEAAwE,CAAC,CAAC;YACzH,MAAM,MAAM,GAAG,KAAK,CAAC,aAAa,EAAE,CAAC,QAAQ,EAAE,WAAW,EAAE,uBAAuB,EAAE,IAAI,EAAE,WAAW,EAAE,QAAQ,EAAE,SAAS,EAAE,iBAAiB,EAAE,QAAQ,CAAC,EAAE;gBACzJ,QAAQ,EAAE,IAAI;gBACd,KAAK,EAAE,QAAQ;aAChB,CAAC,CAAC;YACH,MAAM,CAAC,KAAK,EAAE,CAAC;YACf,yEAAyE;YACzE,MAAM,IAAI,OAAO,CAAO,CAAC,OAAO,EAAE,EAAE;gBAClC,MAAM,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC,KAAK,EAAE,EAAE,GAAG,MAAM,EAAE,IAAI,CAAC,EAAE,GAAG,EAAE,KAAK,EAAE,EAAE,qCAAqC,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;gBACrH,MAAM,CAAC,IAAI,CAAC,OAAO,EAAE,GAAG,EAAE,GAAG,OAAO,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;YAC7C,CAAC,CAAC,CAAC;QACL,CAAC;KACF,CAAC;AACJ,CAAC;AAMD,MAAM,UAAU,qBAAqB,CAAC,GAAoB,EAAE,OAAyB,EAAE;IACrF,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,IAAI,oBAAoB,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IAE9D,GAAG,CAAC,IAAI,CAAC,qBAAqB,EAAE,KAAK,EAAE,QAAQ,EAAE,KAAK,EAAE,EAAE;QACxD,IAAI,CAAC;YACH,MAAM,OAAO,CAAC,OAAO,EAAE,CAAC;YACxB,OAAO,MAAM,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC;QACvD,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;QACjH,CAAC;IACH,CAAC,CAAC,CAAC;AACL,CAAC"}
|
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
import { execFile, spawn } from "node:child_process";
|
|
2
|
+
import { existsSync } from "node:fs";
|
|
3
|
+
import { join } from "node:path";
|
|
4
|
+
import { promisify } from "node:util";
|
|
5
|
+
import { PI_WEB_UPDATE_REPO_ENV } from "../../shared/selfUpdate.js";
|
|
6
|
+
import { packageVersion } from "../../piWebVersionReport.js";
|
|
7
|
+
const execFileAsync = promisify(execFile);
|
|
8
|
+
const GIT_FETCH_INTERVAL_MS = 60_000;
|
|
9
|
+
/**
|
|
10
|
+
* Managed deployments (the nix flake, installer scripts) update through a
|
|
11
|
+
* command that owns version drift - for the flake that is the automated
|
|
12
|
+
* lock-and-switch pipeline, invoked via /pi-web update or the update UI.
|
|
13
|
+
* When this environment is set the git-checkout path is not offered, because
|
|
14
|
+
* a store build has no .git to compare against.
|
|
15
|
+
*/
|
|
16
|
+
export const PI_WEB_UPDATE_COMMAND_ENV = "PI_WEB_UPDATE_COMMAND";
|
|
17
|
+
function updateCommand() {
|
|
18
|
+
const fromEnv = process.env[PI_WEB_UPDATE_COMMAND_ENV];
|
|
19
|
+
return fromEnv !== undefined && fromEnv !== "" ? fromEnv : undefined;
|
|
20
|
+
}
|
|
21
|
+
function repoCandidate() {
|
|
22
|
+
const fromEnv = process.env[PI_WEB_UPDATE_REPO_ENV];
|
|
23
|
+
if (fromEnv !== undefined && fromEnv !== "")
|
|
24
|
+
return fromEnv;
|
|
25
|
+
// A checkout built by `npm run build` carries its own package.json; walking
|
|
26
|
+
// up from the server bundle finds the repo root in local development.
|
|
27
|
+
const cwd = process.cwd();
|
|
28
|
+
const candidate = join(cwd, "package.json");
|
|
29
|
+
return existsSync(candidate) ? cwd : undefined;
|
|
30
|
+
}
|
|
31
|
+
async function gitShort(ref, cwd) {
|
|
32
|
+
try {
|
|
33
|
+
const { stdout } = await execFileAsync("git", ["rev-parse", "--short", ref], { cwd, timeout: 5000 });
|
|
34
|
+
return stdout.trim() || undefined;
|
|
35
|
+
}
|
|
36
|
+
catch {
|
|
37
|
+
return undefined;
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
export function createSelfUpdateService(logger) {
|
|
41
|
+
let lastFetch = 0;
|
|
42
|
+
let fetchInFlight;
|
|
43
|
+
async function refreshRemote(repo) {
|
|
44
|
+
const now = Date.now();
|
|
45
|
+
if (now - lastFetch < GIT_FETCH_INTERVAL_MS)
|
|
46
|
+
return;
|
|
47
|
+
fetchInFlight ??= (async () => {
|
|
48
|
+
try {
|
|
49
|
+
await execFileAsync("git", ["fetch", "fork"], { cwd: repo, timeout: 10_000 });
|
|
50
|
+
}
|
|
51
|
+
catch (error) {
|
|
52
|
+
logger?.warn({ err: error, repo }, "failed to fetch fork remote for self-update check");
|
|
53
|
+
}
|
|
54
|
+
finally {
|
|
55
|
+
lastFetch = Date.now();
|
|
56
|
+
fetchInFlight = undefined;
|
|
57
|
+
}
|
|
58
|
+
})();
|
|
59
|
+
await fetchInFlight;
|
|
60
|
+
}
|
|
61
|
+
return {
|
|
62
|
+
async status() {
|
|
63
|
+
const command = updateCommand();
|
|
64
|
+
if (command !== undefined) {
|
|
65
|
+
return {
|
|
66
|
+
enabled: true,
|
|
67
|
+
current: packageVersion(),
|
|
68
|
+
latest: undefined,
|
|
69
|
+
available: false,
|
|
70
|
+
branch: undefined,
|
|
71
|
+
checkedAt: new Date().toISOString(),
|
|
72
|
+
};
|
|
73
|
+
}
|
|
74
|
+
const repo = repoCandidate();
|
|
75
|
+
if (repo === undefined) {
|
|
76
|
+
return { enabled: false, current: "", latest: undefined, available: false, branch: undefined, checkedAt: new Date().toISOString(), disabledReason: "no checkout (set PI_WEB_UPDATE_REPO)" };
|
|
77
|
+
}
|
|
78
|
+
await refreshRemote(repo);
|
|
79
|
+
const current = await gitShort("HEAD", repo);
|
|
80
|
+
const branch = await gitShort("--abbrev-ref", repo);
|
|
81
|
+
const latest = branch === undefined ? undefined : await gitShort(`fork/${branch}`, repo);
|
|
82
|
+
const available = current !== undefined && latest !== undefined && current !== latest;
|
|
83
|
+
return {
|
|
84
|
+
enabled: true,
|
|
85
|
+
current: current ?? "",
|
|
86
|
+
latest,
|
|
87
|
+
available,
|
|
88
|
+
branch,
|
|
89
|
+
checkedAt: new Date().toISOString(),
|
|
90
|
+
};
|
|
91
|
+
},
|
|
92
|
+
async apply() {
|
|
93
|
+
const command = updateCommand();
|
|
94
|
+
if (command !== undefined) {
|
|
95
|
+
// bash -lc so the command's own PATH expectations hold (home-manager
|
|
96
|
+
// switch needs the nix profile on PATH). Detached via systemd-run:
|
|
97
|
+
// the update restarts this very process.
|
|
98
|
+
const runner = spawn("systemd-run", ["--user", "--collect", "--unit=pi-web-self-update", "--", "/bin/bash", "-lc", command], {
|
|
99
|
+
detached: true,
|
|
100
|
+
stdio: "ignore",
|
|
101
|
+
});
|
|
102
|
+
runner.unref();
|
|
103
|
+
await new Promise((resolve) => {
|
|
104
|
+
runner.once("error", (error) => { logger?.warn({ err: error }, "systemd-run failed to start command self-update"); resolve(); });
|
|
105
|
+
runner.once("spawn", () => { resolve(); });
|
|
106
|
+
});
|
|
107
|
+
return;
|
|
108
|
+
}
|
|
109
|
+
const repo = repoCandidate();
|
|
110
|
+
if (repo === undefined)
|
|
111
|
+
throw new Error("no checkout to update (set PI_WEB_UPDATE_REPO)");
|
|
112
|
+
const script = join(repo, "scripts", "auto-update.sh");
|
|
113
|
+
if (!existsSync(script))
|
|
114
|
+
throw new Error(`no auto-update script at ${script}`);
|
|
115
|
+
// systemd-run detaches the apply from this process, so the restart of
|
|
116
|
+
// the web process mid-apply cannot kill it. Fall back to a plain fork
|
|
117
|
+
// when systemd is unavailable (containers), where the web process being
|
|
118
|
+
// recycled is less disruptive.
|
|
119
|
+
const runner = spawn("systemd-run", ["--user", "--collect", "--unit=pi-web-self-update", "--", "bash", script], {
|
|
120
|
+
detached: true,
|
|
121
|
+
stdio: "ignore",
|
|
122
|
+
});
|
|
123
|
+
runner.unref();
|
|
124
|
+
// Surface an immediate fork failure (missing systemd-run) synchronously.
|
|
125
|
+
await new Promise((resolve) => {
|
|
126
|
+
runner.once("error", (error) => { logger?.warn({ err: error }, "systemd-run failed to start self-update; falling back"); resolve(); });
|
|
127
|
+
runner.once("spawn", () => { resolve(); });
|
|
128
|
+
});
|
|
129
|
+
},
|
|
130
|
+
};
|
|
131
|
+
}
|
|
132
|
+
export function registerSelfUpdateRoutes(app, deps = {}) {
|
|
133
|
+
const service = deps.selfUpdate ?? createSelfUpdateService(app.log);
|
|
134
|
+
app.get("/api/pi-web/update/status", async () => service.status());
|
|
135
|
+
app.post("/api/pi-web/update/apply", async (_request, reply) => {
|
|
136
|
+
try {
|
|
137
|
+
await service.apply();
|
|
138
|
+
return await reply.code(202).send({ started: true });
|
|
139
|
+
}
|
|
140
|
+
catch (error) {
|
|
141
|
+
return reply.code(400).send({ started: false, error: error instanceof Error ? error.message : String(error) });
|
|
142
|
+
}
|
|
143
|
+
});
|
|
144
|
+
}
|
|
145
|
+
//# sourceMappingURL=selfUpdateRoutes.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"selfUpdateRoutes.js","sourceRoot":"","sources":["../../../src/server/updates/selfUpdateRoutes.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { WebSocket } from "ws";
|
|
2
|
+
export function bridgeSockets(client, upstream) {
|
|
3
|
+
const sendToClient = createBufferedSender(client);
|
|
4
|
+
const sendToUpstream = createBufferedSender(upstream);
|
|
5
|
+
client.on("message", (data) => { sendToUpstream(data); });
|
|
6
|
+
upstream.on("message", (data) => { sendToClient(data); });
|
|
7
|
+
client.on("close", () => { upstream.close(); });
|
|
8
|
+
upstream.on("close", () => { client.close(); });
|
|
9
|
+
upstream.on("error", () => { client.close(); });
|
|
10
|
+
client.on("error", () => { upstream.close(); });
|
|
11
|
+
}
|
|
12
|
+
export function createBufferedSender(socket) {
|
|
13
|
+
const queue = [];
|
|
14
|
+
const flush = () => {
|
|
15
|
+
while (socket.readyState === WebSocket.OPEN) {
|
|
16
|
+
const data = queue.shift();
|
|
17
|
+
if (data === undefined)
|
|
18
|
+
return;
|
|
19
|
+
socket.send(data);
|
|
20
|
+
}
|
|
21
|
+
};
|
|
22
|
+
socket.on("open", flush);
|
|
23
|
+
return (data) => {
|
|
24
|
+
if (socket.readyState === WebSocket.OPEN) {
|
|
25
|
+
socket.send(data);
|
|
26
|
+
return;
|
|
27
|
+
}
|
|
28
|
+
if (socket.readyState === WebSocket.CONNECTING)
|
|
29
|
+
queue.push(data);
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
//# sourceMappingURL=webSocketBridge.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"webSocketBridge.js","sourceRoot":"","sources":["../../src/server/webSocketBridge.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAa,MAAM,IAAI,CAAC;AAE1C,MAAM,UAAU,aAAa,CAAC,MAAiB,EAAE,QAAmB;IAClE,MAAM,YAAY,GAAG,oBAAoB,CAAC,MAAM,CAAC,CAAC;IAClD,MAAM,cAAc,GAAG,oBAAoB,CAAC,QAAQ,CAAC,CAAC;IACtD,MAAM,CAAC,EAAE,CAAC,SAAS,EAAE,CAAC,IAAI,EAAE,EAAE,GAAG,cAAc,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IAC1D,QAAQ,CAAC,EAAE,CAAC,SAAS,EAAE,CAAC,IAAI,EAAE,EAAE,GAAG,YAAY,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IAC1D,MAAM,CAAC,EAAE,CAAC,OAAO,EAAE,GAAG,EAAE,GAAG,QAAQ,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;IAChD,QAAQ,CAAC,EAAE,CAAC,OAAO,EAAE,GAAG,EAAE,GAAG,MAAM,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;IAChD,QAAQ,CAAC,EAAE,CAAC,OAAO,EAAE,GAAG,EAAE,GAAG,MAAM,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;IAChD,MAAM,CAAC,EAAE,CAAC,OAAO,EAAE,GAAG,EAAE,GAAG,QAAQ,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;AAClD,CAAC;AAED,MAAM,UAAU,oBAAoB,CAAC,MAAiB;IACpD,MAAM,KAAK,GAAW,EAAE,CAAC;IACzB,MAAM,KAAK,GAAG,GAAG,EAAE;QACjB,OAAO,MAAM,CAAC,UAAU,KAAK,SAAS,CAAC,IAAI,EAAE,CAAC;YAC5C,MAAM,IAAI,GAAG,KAAK,CAAC,KAAK,EAAE,CAAC;YAC3B,IAAI,IAAI,KAAK,SAAS;gBAAE,OAAO;YAC/B,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACpB,CAAC;IACH,CAAC,CAAC;IACF,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;IACzB,OAAO,CAAC,IAAI,EAAE,EAAE;QACd,IAAI,MAAM,CAAC,UAAU,KAAK,SAAS,CAAC,IAAI,EAAE,CAAC;YACzC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YAClB,OAAO;QACT,CAAC;QACD,IAAI,MAAM,CAAC,UAAU,KAAK,SAAS,CAAC,UAAU;YAAE,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACnE,CAAC,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { isAbsolute, resolve } from "node:path";
|
|
2
|
+
/**
|
|
3
|
+
* Working-directory normalization boundaries.
|
|
4
|
+
*
|
|
5
|
+
* Cwd strings reach the server from three kinds of sources with different trust:
|
|
6
|
+
*
|
|
7
|
+
* 1. HTTP requests (web UI, federation proxies): normalize strictly with
|
|
8
|
+
* `normalizeRequestCwd` at route parsing. Relative paths are rejected instead
|
|
9
|
+
* of being silently resolved against the daemon's own working directory.
|
|
10
|
+
* 2. Data pi-web writes itself (archive store records): canonicalized on write
|
|
11
|
+
* and on load with `canonicalizeStoredCwd`, so internal `===` comparisons are
|
|
12
|
+
* safe by construction.
|
|
13
|
+
* 3. Data other writers own (Pi session file headers via the SDK): canonicalized
|
|
14
|
+
* on read at the gateway, and compared tolerantly with `cwdPathsEqual` where a
|
|
15
|
+
* raw value can still appear (e.g. runtime cwd of sessions opened from files).
|
|
16
|
+
*
|
|
17
|
+
* Inside these boundaries, plain string equality on cwd values is safe.
|
|
18
|
+
*/
|
|
19
|
+
/**
|
|
20
|
+
* Strictly normalize a client-supplied working directory at an HTTP boundary.
|
|
21
|
+
* Throws for non-string, empty, or relative input; returns the resolved
|
|
22
|
+
* (separator- and trailing-slash-normalized) absolute path otherwise.
|
|
23
|
+
*/
|
|
24
|
+
export function normalizeRequestCwd(cwd) {
|
|
25
|
+
if (typeof cwd !== "string" || cwd === "")
|
|
26
|
+
throw new Error("cwd is required");
|
|
27
|
+
if (!isAbsolute(cwd))
|
|
28
|
+
throw new Error("cwd must be an absolute path");
|
|
29
|
+
return resolve(cwd);
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Leniently canonicalize a working directory loaded from stored data.
|
|
33
|
+
* Absolute paths are resolved to canonical form; anything else (legacy empty or
|
|
34
|
+
* relative values) is preserved as-is so a single bad record cannot fail a whole
|
|
35
|
+
* load, and never silently resolves against this process's working directory.
|
|
36
|
+
*/
|
|
37
|
+
export function canonicalizeStoredCwd(cwd) {
|
|
38
|
+
return isAbsolute(cwd) ? resolve(cwd) : cwd;
|
|
39
|
+
}
|
|
40
|
+
/** Compare two working-directory paths, tolerating separator and normalization differences (e.g. Windows backslash vs forward slash). */
|
|
41
|
+
export function cwdPathsEqual(a, b) {
|
|
42
|
+
return resolve(a) === resolve(b);
|
|
43
|
+
}
|
|
44
|
+
//# sourceMappingURL=workingDirectory.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"workingDirectory.js","sourceRoot":"","sources":["../../src/server/workingDirectory.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAEhD;;;;;;;;;;;;;;;;GAgBG;AAEH;;;;GAIG;AACH,MAAM,UAAU,mBAAmB,CAAC,GAAY;IAC9C,IAAI,OAAO,GAAG,KAAK,QAAQ,IAAI,GAAG,KAAK,EAAE;QAAE,MAAM,IAAI,KAAK,CAAC,iBAAiB,CAAC,CAAC;IAC9E,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC;QAAE,MAAM,IAAI,KAAK,CAAC,8BAA8B,CAAC,CAAC;IACtE,OAAO,OAAO,CAAC,GAAG,CAAC,CAAC;AACtB,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,qBAAqB,CAAC,GAAW;IAC/C,OAAO,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC;AAC9C,CAAC;AAED,yIAAyI;AACzI,MAAM,UAAU,aAAa,CAAC,CAAS,EAAE,CAAS;IAChD,OAAO,OAAO,CAAC,CAAC,CAAC,KAAK,OAAO,CAAC,CAAC,CAAC,CAAC;AACnC,CAAC"}
|
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
import { deleteWorkspaceFile, moveWorkspaceFile, readWorkspaceFile, writeWorkspaceFile } from "./workspaces/fileContentService.js";
|
|
2
|
+
import { isAbsoluteishFileSuggestionQuery, listFileSuggestions, listPathSuggestions } from "./workspaces/fileSuggestions.js";
|
|
3
|
+
import { listWorkspaceTree } from "./workspaces/fileTreeService.js";
|
|
4
|
+
import { readWorkspaceFilePreview } from "./workspaces/filePreviewService.js";
|
|
5
|
+
import { workspaceFilePreviewResponsePolicy } from "./workspaces/filePreviewResponsePolicy.js";
|
|
6
|
+
import { applyWorkspaceFilePreviewErrorResponsePolicy } from "./workspaces/filePreviewResponseHeaders.js";
|
|
7
|
+
import { readWorkspaceGoals } from "./goals/goalStore.js";
|
|
8
|
+
import { archiveWorkspaceGoal, GoalArchiveError } from "./goals/goalArchive.js";
|
|
9
|
+
import { resolveWorkspaceContext } from "./workspaces/workspaceContext.js";
|
|
10
|
+
import { pathAccessForWorkspaceContext } from "./workspaces/effectivePathAccess.js";
|
|
11
|
+
import { sendWorkspaceRequestError } from "./workspaces/workspaceRouteErrors.js";
|
|
12
|
+
export function registerWorkspaceExplorerRoutes(app, projects, workspaces, prefix = "/api", options = {}) {
|
|
13
|
+
registerWorkspaceFileContentParsers(app);
|
|
14
|
+
app.get(`${prefix}/projects/:projectId/workspaces/:workspaceId/tree`, async (request, reply) => {
|
|
15
|
+
try {
|
|
16
|
+
const context = await resolveWorkspaceContext(projects, workspaces, request.params.projectId, request.params.workspaceId);
|
|
17
|
+
return await listWorkspaceTree(context.root, request.query.path, await pathAccessForWorkspaceContext(context, options.config));
|
|
18
|
+
}
|
|
19
|
+
catch (error) {
|
|
20
|
+
return sendWorkspaceRequestError(reply, error, 400);
|
|
21
|
+
}
|
|
22
|
+
});
|
|
23
|
+
// Goals are read straight from the workspace's `.pi/goals/` directory rather
|
|
24
|
+
// than through a session: the records outlive any one session, and several
|
|
25
|
+
// sessions of the same workspace share the directory.
|
|
26
|
+
app.get(`${prefix}/projects/:projectId/workspaces/:workspaceId/goals`, async (request, reply) => {
|
|
27
|
+
try {
|
|
28
|
+
const context = await resolveWorkspaceContext(projects, workspaces, request.params.projectId, request.params.workspaceId);
|
|
29
|
+
return await readWorkspaceGoals(context.root);
|
|
30
|
+
}
|
|
31
|
+
catch (error) {
|
|
32
|
+
return sendWorkspaceRequestError(reply, error, 400);
|
|
33
|
+
}
|
|
34
|
+
});
|
|
35
|
+
/**
|
|
36
|
+
* Archiving is the one write pi-web makes to goal state, and only because a
|
|
37
|
+
* paused goal has no other way out of the panel: the extension's own clear
|
|
38
|
+
* command refuses without a confirmable UI, which a web session has not got.
|
|
39
|
+
* The protocol it follows is the extension's (see docs/pi-goal-integration.md).
|
|
40
|
+
*/
|
|
41
|
+
app.post(`${prefix}/projects/:projectId/workspaces/:workspaceId/goals/:goalId/archive`, async (request, reply) => {
|
|
42
|
+
try {
|
|
43
|
+
const context = await resolveWorkspaceContext(projects, workspaces, request.params.projectId, request.params.workspaceId);
|
|
44
|
+
return await archiveWorkspaceGoal(context.root, request.params.goalId);
|
|
45
|
+
}
|
|
46
|
+
catch (error) {
|
|
47
|
+
if (error instanceof GoalArchiveError)
|
|
48
|
+
return reply.code(error.code === "locked" ? 409 : 400).send({ error: error.message, code: error.code });
|
|
49
|
+
return sendWorkspaceRequestError(reply, error, 400);
|
|
50
|
+
}
|
|
51
|
+
});
|
|
52
|
+
app.get(`${prefix}/projects/:projectId/workspaces/:workspaceId/file`, async (request, reply) => {
|
|
53
|
+
try {
|
|
54
|
+
const context = await resolveWorkspaceContext(projects, workspaces, request.params.projectId, request.params.workspaceId);
|
|
55
|
+
return await readWorkspaceFile(context.root, request.query.path, await pathAccessForWorkspaceContext(context, options.config));
|
|
56
|
+
}
|
|
57
|
+
catch (error) {
|
|
58
|
+
return sendWorkspaceRequestError(reply, error, 400);
|
|
59
|
+
}
|
|
60
|
+
});
|
|
61
|
+
app.put(`${prefix}/projects/:projectId/workspaces/:workspaceId/file`, async (request, reply) => {
|
|
62
|
+
try {
|
|
63
|
+
const context = await resolveWorkspaceContext(projects, workspaces, request.params.projectId, request.params.workspaceId);
|
|
64
|
+
const writeOptions = {
|
|
65
|
+
createDirs: request.query.createDirs !== "false",
|
|
66
|
+
overwrite: request.query.overwrite !== "false",
|
|
67
|
+
};
|
|
68
|
+
return await writeWorkspaceFile(context.root, request.query.path, request.body, writeOptions);
|
|
69
|
+
}
|
|
70
|
+
catch (error) {
|
|
71
|
+
return sendWorkspaceRequestError(reply, error, 400);
|
|
72
|
+
}
|
|
73
|
+
});
|
|
74
|
+
app.delete(`${prefix}/projects/:projectId/workspaces/:workspaceId/file`, async (request, reply) => {
|
|
75
|
+
try {
|
|
76
|
+
const context = await resolveWorkspaceContext(projects, workspaces, request.params.projectId, request.params.workspaceId);
|
|
77
|
+
return await deleteWorkspaceFile(context.root, request.query.path);
|
|
78
|
+
}
|
|
79
|
+
catch (error) {
|
|
80
|
+
return sendWorkspaceRequestError(reply, error, 400);
|
|
81
|
+
}
|
|
82
|
+
});
|
|
83
|
+
app.post(`${prefix}/projects/:projectId/workspaces/:workspaceId/file/move`, async (request, reply) => {
|
|
84
|
+
try {
|
|
85
|
+
const context = await resolveWorkspaceContext(projects, workspaces, request.params.projectId, request.params.workspaceId);
|
|
86
|
+
return await moveWorkspaceFile(context.root, request.query.fromPath, request.query.toPath, {
|
|
87
|
+
createDirs: request.query.createDirs !== "false",
|
|
88
|
+
overwrite: request.query.overwrite === "true",
|
|
89
|
+
});
|
|
90
|
+
}
|
|
91
|
+
catch (error) {
|
|
92
|
+
return sendWorkspaceRequestError(reply, error, 400);
|
|
93
|
+
}
|
|
94
|
+
});
|
|
95
|
+
app.get(`${prefix}/projects/:projectId/workspaces/:workspaceId/file/preview`, async (request, reply) => {
|
|
96
|
+
try {
|
|
97
|
+
const context = await resolveWorkspaceContext(projects, workspaces, request.params.projectId, request.params.workspaceId);
|
|
98
|
+
const download = request.query.download === "1" || request.query.download === "true";
|
|
99
|
+
const preview = await readWorkspaceFilePreview(context.root, request.query.path, await pathAccessForWorkspaceContext(context, options.config), { download });
|
|
100
|
+
const policy = workspaceFilePreviewResponsePolicy(preview.path, { download });
|
|
101
|
+
return await reply
|
|
102
|
+
.header("Content-Type", policy.contentType)
|
|
103
|
+
.header("Cache-Control", "private, max-age=3600")
|
|
104
|
+
.header("Content-Length", String(preview.size))
|
|
105
|
+
.header("Content-Disposition", policy.contentDisposition)
|
|
106
|
+
.header("Content-Security-Policy", policy.contentSecurityPolicy)
|
|
107
|
+
.header("Last-Modified", new Date(preview.modifiedAt).toUTCString())
|
|
108
|
+
.header("X-Content-Type-Options", policy.contentTypeOptions)
|
|
109
|
+
.send(preview.body);
|
|
110
|
+
}
|
|
111
|
+
catch (error) {
|
|
112
|
+
applyWorkspaceFilePreviewErrorResponsePolicy(reply);
|
|
113
|
+
return sendWorkspaceRequestError(reply, error, 400);
|
|
114
|
+
}
|
|
115
|
+
});
|
|
116
|
+
app.get(`${prefix}/projects/:projectId/workspaces/:workspaceId/files`, async (request, reply) => {
|
|
117
|
+
try {
|
|
118
|
+
const context = await resolveWorkspaceContext(projects, workspaces, request.params.projectId, request.params.workspaceId);
|
|
119
|
+
const query = request.query.q ?? "";
|
|
120
|
+
const pathAccess = isAbsoluteishFileSuggestionQuery(query) ? await pathAccessForWorkspaceContext(context, options.config) : undefined;
|
|
121
|
+
if (request.query.mode === "path")
|
|
122
|
+
return await listPathSuggestions(context.root, query, pathAccess);
|
|
123
|
+
return await listFileSuggestions(context.root, query, { kind: request.query.kind, scope: request.query.scope, pathAccess });
|
|
124
|
+
}
|
|
125
|
+
catch (error) {
|
|
126
|
+
return sendWorkspaceRequestError(reply, error, 400);
|
|
127
|
+
}
|
|
128
|
+
});
|
|
129
|
+
}
|
|
130
|
+
function registerWorkspaceFileContentParsers(app) {
|
|
131
|
+
// Fastify's default parser only handles JSON; workspace file writes need to
|
|
132
|
+
// accept text and arbitrary binary payloads. This route module is registered
|
|
133
|
+
// for both local aliases, so parser registration must tolerate repeats.
|
|
134
|
+
try {
|
|
135
|
+
app.addContentTypeParser("text/plain", { parseAs: "string" }, (_request, body, done) => { done(null, Buffer.from(body)); });
|
|
136
|
+
}
|
|
137
|
+
catch { /* already registered */ }
|
|
138
|
+
try {
|
|
139
|
+
app.addContentTypeParser("application/octet-stream", { parseAs: "buffer" }, (_request, body, done) => { done(null, body); });
|
|
140
|
+
}
|
|
141
|
+
catch { /* already registered */ }
|
|
142
|
+
try {
|
|
143
|
+
app.addContentTypeParser(/^([a-z]+\/[a-z0-9.+-]+)$/u, { parseAs: "buffer" }, (_request, body, done) => { done(null, body); });
|
|
144
|
+
}
|
|
145
|
+
catch { /* already registered */ }
|
|
146
|
+
}
|
|
147
|
+
//# sourceMappingURL=workspaceExplorerRoutes.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"workspaceExplorerRoutes.js","sourceRoot":"","sources":["../../src/server/workspaceExplorerRoutes.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { loadEffectiveProjectPathAccess } from "./projectPiWebConfig.js";
|
|
2
|
+
export async function pathAccessForWorkspaceContext(context, config) {
|
|
3
|
+
if (config === undefined)
|
|
4
|
+
return undefined;
|
|
5
|
+
const response = await config.read();
|
|
6
|
+
return loadEffectiveProjectPathAccess(context.project.path, response.effectiveConfig);
|
|
7
|
+
}
|
|
8
|
+
//# sourceMappingURL=effectivePathAccess.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"effectivePathAccess.js","sourceRoot":"","sources":["../../../src/server/workspaces/effectivePathAccess.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,8BAA8B,EAAE,MAAM,yBAAyB,CAAC;AAEzE,MAAM,CAAC,KAAK,UAAU,6BAA6B,CAAC,OAAyB,EAAE,MAAoD;IACjI,IAAI,MAAM,KAAK,SAAS;QAAE,OAAO,SAAS,CAAC;IAC3C,MAAM,QAAQ,GAAG,MAAM,MAAM,CAAC,IAAI,EAAE,CAAC;IACrC,OAAO,8BAA8B,CAAC,OAAO,CAAC,OAAO,CAAC,IAAI,EAAE,QAAQ,CAAC,eAAe,CAAC,CAAC;AACxF,CAAC"}
|